.TITLE MTH_QUAD_DIV Quadword integer division routines .IDENT /V03.01/ ;++MTHQDIV.MAR ; ; FACILITY: ; Quadword integer Mathematics subroutines. ; ; ABSTRACT: ; This module contains the routines to divide one quadword integer ; by another quadword integer (returning quadword quotients and ; remainders) or to divide a quadword integer by a longword integer ; and return a longword quotient (and remainder). ; ; ENVIRONMENT: ; Called from high-level language (FORTRAN or PASCAL) programs. ; User mode. ; ;-- ; ; MODIFICATION HISTORY: ; ; Gotten from Fall 1980 DECUS VAX/VMS SIG tape. ; ; V01.02 21-Aug-81 FJN Commented and names changed. Added QUAD_EMUL. ; V02.00 08-Jun-82 FJN Names changed yet again. ; V03.00 03-Oct-82 FJN Split package into separate modules, added ; EDIV routine ; V03.01 15-Apr-83 FJN Standardize help comments ; ; Copyright (C) 1979 ; Management Science Associates, Inc. ; 5100 Centre Avenue ; Pittsburgh, Pennsylvania 15232 ; ; This software is distributed without cost, and may be ; reproduced only with the inclusion of this copyright ; statement. Management Science Associates assumes no ; responsibility for the performance of this software. ; ; ; EQUATED SYMBOLS: ; LOW = 0 ;Offset to low-order longword HIGH = 4 ;Offset to high-ordr longword ; ; Argument offsets ; NARGS = 0 ;Offset to number of arguments NUMERATOR = 4 ;Offset to address of numerator quadword DENOMINATOR = 8 ;offset to address of denominator quadword QUOTIENT = 12 ;Offset to address of quotient quadword REMAINDER = 16 ;offset to address of optional ; remainder quadword ; ; Program section for code ; .PSECT _MTH_CODE,PIC,USR,CON,REL,LCL,SHR,EXE,NOWRT,RD .SHOW BINARY .PAGE .SBTTL MTH_QUAD_DIV Divide two quadword integers ;+ MTH_QUAD_DIV ; Divide one quadword integer by another and return their quadword ; quotient and (optionally) the quadword remainder. ; ; CALL MTH_QUAD_DIV( divd.rq.r, divr.rq.r, quot.wq.r [,rem.wq.r] ) ; ; divd quadword containing the dividend to be divided by the ; divisor. Passed by reference. ; ; divr quadword containing the divisor. Passed by reference. ; ; quot quadword in which the quotient of the division is ; returned. Passed by reference. ; ; rem optional quadword in which the remainder from the ; division may be returned. Passed by reference. ; ;- ;+0MTH_QUAD_DIV ; ; FUNCTIONAL DESCRIPTION: ; Divide two quadword integers and return their quotient and ; (optionally) their remainder. ; ; CALLING SEQUENCE: ; CALL MTH_QUAD_DIV(numerator,denominator,quotient [,remainder] ) ; ; INPUT PARAMETERS: ; numerator(AP) address of the numerator quadword ; denominator(AP) address of the denominator quadword ; ; OUTPUT PARAMETERS: ; quotient(AP) address of quadword in which the quotient of ; numerator divided by denominator is returned. ; remainder(AP) zero or non-existant if remainder not needed, ; else the address of the quadword in which the ; remainder is returned. ; ;- .ENTRY MTH_QUAD_DIV ^M CLRB R6 ;presume pos num and den MOVL QUOTIENT(AP),R8 ;get quotient address MOVQ @NUMERATOR(AP),(R8) ;get the numerator BGEQ 1$ ;xfer if positive MCOML LOW(R8),LOW(R8) ;make two's complement MCOML HIGH(R8),HIGH(R8) ; INCL LOW(R8) ; ADWC #0,HIGH(R8) ; MOVB #3,R6 ;flag the sign switch 1$: MOVQ @DENOMINATOR(AP),R0 ;get the denominator BGEQ 2$ ;xfer if positive MCOML R0,R0 ;make two's complement MCOML R1,R1 ; INCL R0 ; ADWC #0,R1 ; XORB #1,R6 ;flag the sign switch 2$: CLRQ R2 ;clear quotient CLRQ R4 ;clear remainder MOVZBL #63,R7 ;set count and bit pointer 3$: ASHQ #1,r2,r2 ;room for next quotient bit ASHQ #1,r4,r4 ;room for next numerator bit BBC R7,(R8),4$ ;check next numerator bit INCB R4 ;move it to the remainder 4$: CMPL R5,R1 ;compare remainder and denom BLSS 6$ ;no subtract if remainder less BGTR 5$ ;certain subtract if larger CMPL R4,R0 ;high parts equal so compare low BLSSU 6$ ;no subtract if remainder less 5$: SUBL R0,R4 ;subtract denom from remainder SBWC R1,R5 ; INCB R2 ;increment the quotient 6$: SOBGEQ R7,3$ ;loop for each bit BLBC R6,7$ ;check quotient sign switch MCOML R2,R2 ;make quotient negative MCOML R3,R3 ; INCL R2 ; ADWC #0,R3 ; 7$: MOVQ R2,(R8) ;return the quotient BBC #2,NARGS(AP),9$ ;check for four args TSTL REMAINDER(AP) ;check for address of remainder BEQL 9$ ; BBC #1,R6,8$ ;check remainder sign switch MCOML R4,R4 ;make remainder negative MCOML R5,R5 ; INCL R4 ; ADWC #0,R5 ; 8$: MOVQ R4,@REMAINDER(AP) ;return the remainder 9$: RET ;return to caller .PAGE .SBTTL MTH_QUAD_EDIV Divide quadword integer by longword integer ;+ MTH_QUAD_EDIV ; Divide a quadword integer by a longword and return the longword ; quotient and (optionally) the longword remainder. ; ; CALL MTH_QUAD_EDIV( divd.rq.r, divr.rl.r, quot.wl.r [,rem.wl.r] ) ; ; divd quadword containing the dividend to be divided by the ; divisor. Passed by reference. ; ; divr longword containing the divisor. Passed by reference. ; ; quot longword in which the quotient of the division is returned. ; Passed by reference. ; ; rem optional longword in which the remainder from the division ; may be returned. Passed by reference. ; ;- ;+0MTH_QUAD_DIV ; ; FUNCTIONAL DESCRIPTION: ; Divide a quadword integer by a longword and return the quotient and ; (optionally) the remainder. ; ; CALLING SEQUENCE: ; CALL MTH_QUAD_DIV(numerator,denominator,quotient [,remainder] ) ; ; INPUT PARAMETERS: ; numerator(AP) address of the numerator quadword ; denominator(AP) address of the denominator longword ; ; OUTPUT PARAMETERS: ; quotient(AP) address of longword in which the quotient of ; numerator divided by denominator is returned. ; remainder(AP) zero or non-existant if remainder not needed, ; else the address of the longword in which the ; remainder is returned. ; ;- .ENTRY MTH_QUAD_EDIV,^M<> ; ; Perform the extended division directly from the inputs and return ; the quotient directly into its argument ; EDIV @denominator(AP),@numerator(AP),@quotient(AP),R1 CMPB (AP),#4 ;Is there a remainder argument? BLSSU 10$ ;If not, just exit TSTL remainder(AP) ;Yes, is it defaulted? BEQL 10$ ;If so, again just exit MOVL R1,@remainder(AP) ;Return remainder in argument 10$: RET .END