.NLIST .INCLUDE /DSMAC.MAC/ .INCLUDE /MYMAC.MAC/ .LIST MODULE NAME=, REL=, VER=<01>, LIBR=, COMM= EXPORT QUALIFIED $QMUL, $DMUL, $QDIV, $DDIV ;+ ; $QMUL ; This routine multiplies a double precision multiplicand by ; a double precision multiplier and yields a quad precision result. ; ; All are unsigned. ; ; R0 = hi-order part of double precision multiplier ; R1 = lo-order part of double precision multiplier ; R2 = hi-order part of double precision multiplicand ; R3 = lo-order part of double precision multiplicand ; ; JSR PC,QDMUL ; ; C-bit = 0 ; ; R0 = hi-order part of quad precision multiplicand ; R1 = middle-hi-order part of quad precision multiplicand ; R2 = middle-lo-order part of quad precision multiplicand ; R3 = lo-order part of quad precision multiplicand ;- PROCEDURE $QMUL BEGIN PUSH <#0, #0, #0, #0> ; Initialize the result LET R4 := #0 LET R5 := #0 LOOP IF R0 EQ #0 AND R1 EQ #0 LEAVE LOOP ; If remaining multiplier is zero, then all through LET CARRY := OFF LET R0 := R0 R.ROTATE 1 ; hi part of multiplier LET R1 := R1 R.ROTATE 1 ; low part of multiplier IF RESULT IS CS THEN ; and if next bit is a one LET (SP) := (SP) + R3 ; then add in lo-order multiplicand to result LET 2(SP) := 2(SP) + CARRY + R2 ; add in carry and hi-order part LET 4(SP) := 4(SP) + CARRY + R5 ; and add in carry LET 6(SP) := 6(SP) + CARRY + R4 ; and add in carry END LET R3 := R3 L.SHIFT 1 ; In either case, double the multiplicand, LET R2 := R2 L.ROTATE 1 LET R5 := R5 L.ROTATE 1 LET R4 := R4 L.ROTATE 1 END ; and see if any more multiplier POP ; get result from stack return C-bit = 0 RETURN END $QMUL ;+ ; $DMUL ; This routine multiplies a double precision multiplicand by a single ; precision multiplier and yields a double precision result. All are ; unsigned. ; ; R0 = single precision multiplier ; R2 = hi-order part of double precision multiplicand ; R3 = lo-order part of double precision multiplicand ; ; JSR PC,$DMUL ; ; C-bit = 0 ; R0 = hi-order part of double precision multiplicand ; R1 = lo-order part of double precision multiplicand ; R2,R3 = random ;- PROCEDURE $DMUL BEGIN MOV R0,-(SP) ;Single precision multiplier CLR R0 ;Initialize the result CLR R1 ;Both words 1$: TST (SP) ;If remaining multiplier is zero, BEQ 3$ ; then all through ROR (SP) ;If next bit is a one, BCC 2$ ; ADD R3,R1 ; then add multiplicand to result ADC R0 ;Add in carry ADD R2,R0 ;Add in hi-order part 2$: ASL R3 ;In either case, double the multiplicand, ROL R2 ; BR 1$ ; and see if any more multiplier 3$: TST (SP)+ ;Clean up the stack, return C-bit = 0 RETURN END $DMUL ;+ ; $QDIV ; This routine divides a quad precision dividend by ; a double precision divisor yielding a quad precision quotient and ; a double precision remainder. ; ; All are unsigned. ; ; R0 = hi-order part of quad precision dividend ; R1 = ; R2 = ; R3 = lo-order part of quad precision dividend ; ; R4 = double precision ....... ; R4 = ................ divisor ; ; JSR PC,$QDIV ; ; R0 = hi-order part of double precision quotient ; R1 = ; R2 = ; R3 = lo-order part of double precision quotient ; ; R4 = double precision ......... ; R4 = ................ remainder ;- PROCEDURE $QDIV BEGIN PUSH #64. PUSH LET R4 := #0 LET R5 := #0 REPEAT LET R3 := R3 L.SHIFT 1 ; Shift the entire dividend... LET R2 := R2 L.ROTATE 1 ; ... LET R1 := R1 L.ROTATE 1 ; ... LET R0 := R0 L.ROTATE 1 ; ... one bit to the left and ... LET R5 := R5 L.ROTATE 1 ; ... into the remainder LET R4 := R4 L.ROTATE 1 ; ... into the remainder CMP R4, (SP) ; IF R4 HI (SP) ; Is remainder .GE. divisor? BLO 20$ BHI 10$ ; OR ( (R4 EQ (SP)) CMP R5, 2(SP) ; AND (R5 HIS 2(SP)) ) BLO 20$ 10$: LET R5 := R5 - 2(SP) ; Yes, subtract ........... LET R4 := R4 - CARRY - (SP) ; ............. divisor out LET R3 := R3 + #1 ; and increment the quotient 20$: LET 4(SP) := 4(SP) - #1 UNTIL RESULT IS LE POP <, ,> ; Purge divisor and loop counter from stack RETURN END $QDIV ;+ ; $DDIV ; This routine divides a double precision dividend by a single precision ; divisor yielding a double precision quotient and a single precision ; remainder. All are unsigned. ; ; R0 = single precision divisor ; R1 = hi-order part of double precision dividend ; R2 = lo-order part of double precision dividend ; ; JSR PC,$DDIV ; ; R0 = single precision remainder ; R1 = hi-order part of double precision quotient ; R2 = lo-order part of double precision quotient ;- PROCEDURE $DDIV BEGIN MOV R3,-(SP) ;Save R3 MOV #32.,R3 ;Set iteration count in R3 MOV R0,-(SP) ;Put divisor on stack CLR R0 ;Set remainder to zero 1$: ASL R2 ;Shift the entire dividend... ROL R1 ;... one bit to the left and ... ROL R0 ;... into the remainder CMP R0,(SP) ;Is remainder .GE. divisor? BLO 2$ ;No, skip to iteration control SUB (SP),R0 ;Yes, subtract divisor out INC R2 ; and increment the quotient 2$: DEC R3 ;Repeat as long as necessary BGT 1$ ; TST (SP)+ ;Purge divisor from stack MOV (SP)+,R3 ;Restore R3 RETURN END $DDIV END ARITH .END