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-" 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