Article 2805 of vmsnet.internals:
Path: jac.zko.dec.com!nntpd.lkg.dec.com!pa.dec.com!decwrl!pagesat.net!news.cerf.net!mvb.saic.com!macro32
From: "Brian Schenkenberger, VAXman-" <brians@advsyscon.com>
Newsgroups: vmsnet.internals
Subject: RE: 64 bit integers
Message-ID: <0099243D.A7E46AE0.2@AdvSysCon.COM>
Date: Thu, 22 Jun 1995 15:31:06 EST
Organization: Macro32<==>Vmsnet.Internals Gateway
X-Gateway-Source-Info: Mailing List
Lines: 88

.... and just for fun, while my fellow office mates are winding their
propeller beenies with all the rest of the PC weenies at NYC's Javits
Center's PC Expo, I decided to recode the Macro-32 divide routine in 
Macro-64.  I figure it's high time we upgraded the Macro32 list to a
full 64 bits! :-)
-------
VAXman-

	.TITLE	"DIVDEMO"
	.IDENT	"bjs"

	.SBTTL	"DECLARATIONS AND DEFINITIONS"
;++
; included macro64 prefix libraries
;--
	.INCLUDE	"SYS$SHARE:STARLET.PREFIX"

;++
; included macro32 symbol definitions
;--
        $SSDEF

;++
; local register defininitions across all routines
;--
	.DEFINE_IREG	DIVD	R16
	.DEFINE_IREG	DIVR	R17
	.DEFINE_IREG	QUOT	R18
	.DEFINE_IREG	QTMP	R22
	.DEFINE_IREG	RA	R26
	.DEFINE_IREG	PV	R27

	.SBTTL	"PROCEDURE SECTION"
;++
; Divide-64 routine  
;--
	$ROUTINE DIV64,	KIND=NULL

	$LINKAGE_SECTION	; declare LINKAGE SECTION psect
SIGNAL:	.LONG	SS$_INTDIV

	$CODE_SECTION		; declare CODE SECTION psect
	.BASE	PV, $LS		; define PV as LINKAGE POINTER

	BIS	R31,R31,R1	; result (+) or (-); initially (+)

	LDQ	DIVD,(DIVD)	; get the dividend
	BGE	DIVD,10$	; dividend negative? branch if (+)

;;;	ORNOT	R31,DIVD,DIVD	; compliment DIVD\ quadword integer
;;;	ADDQ	DIVD,#1,DIVD	; add one to DIVD/ two's compliment
	SUBQ	R31,DIVD,DIVD	; negate the negative to positive
	XOR	R1,#1,R1	; mark result (-)

10$:	LDQ	DIVR,(DIVR)	; get the divisor
	BGT	DIVR,20$	; divisor negative? branch if (+)
	BEQ	DIVR,60$	; division by zero is illegal

;;;	ORNOT	R31,DIVR,DIVR	; compliment DIVR\ quadword integer
;;;	ADDQ	DIVR,#1,DIVR	; add one to DIVR/ two's compliment
	SUBQ	R31,DIVD,DIVD	; negate the negative to positive
	XOR	R1,#1,R1	; mark result conditionally (-)

20$:	BIS	R31,R31,QTMP	; clear register for quotient
	BIS	R31,#63,R0	; 64 bits for multiplier

30$:	SLL	DIVR,R0,R24	; multiply DIVR by R0 -> DIVR
	BLE	R24,40$		; too big, try again
	CMPLE	R24,DIVD,R23	; is DIVR too big to subtract?
	BEQ	R23,40$		; too big, try again
	SUBQ	DIVD,R24,DIVD	; subtract DIVR put remainder in DIVD
	SLL	R23,R0,R23	; convert bit R0 to mask R23
	BIS	QTMP,R23,QTMP	; set multiplier bit in quotient
40$:	SUBQ	R0,#1,R0	; decrement the multiplier
	BGE	R0,30$		; try again...

	BLBC	R1,50$
;;;	ORNOT	R31,QTMP,QTMP	; compliment QTMP\ quadword integer
;;;	ADDQ	QTMP,#1,QTMP	; add one to QTMP/ two's compliment
	SUBQ	R31,QTMP,QTMP	; negate the negative to positive

50$:	STQ	QTMP,(QUOT)
	RET	RA		; return to address in RA

60$:	$CALL	NAME=LIB$SIGNAL,ARGS=SIGNAL/L,NONSTANDARD=TRUE

	$END_ROUTINE		; end of routine
	.END


