.TITLE DIV64 .IDENT /V1.0/ .SBTTL 64-BIT BY 64-BIT DIVISION ROUTINE ; ROUTINE TO DIVIDE A 64 BIT NUMBER BY A 64 BIT NUMBER AND ; RETURN A 64 BIT RESULT AND 64 BIT REMAINDER ; ; LAST EDIT: 6-NOV-1987 12:53:40 ; ; AUTHOR: PETER STADICK ; CARGILL INC ; P.O. DRAWER AR ; RESERVE, LA 70084 ; ; EDIT HISTORY: CREATED MAY-87 PJS ; MADE SEPERATE MODULE OCT-87 PJS ; ; CALLING PARAMETER LIST ; 2(R5) = DIVIDEND ( INPUT PRESERVED ) ; 4(R5) = DIVISOR ( INPUT PRESERVED ) ; 6(R5) = REMAINDER ( OUTPUT ) ; 10(R5) = QUOTIENT (OUTPUT) ; 12(R5) = STATUS 1=SUCCESS OR -3=OVERFLOW ( OUTPUT ) ; ; THIS ROUTINE WILL DIVIDE THE DIVIDEND BY THE DIVISOR TO YEILD ; A QUOTIENT AND A REMAINDER. IF YOU TRY TO DIVIDE BY ZERO THE ; STATUS OF -3 WILL BE RETURNED. ; ; THIS ROUTINE UTILIZES THE BIT SHIFT AND TEST SUBTRACT METHOD OF ; DIVISION. A WORST CASE DIVISION WILL TAKE APPROX 15,000 INSTRUCTIONS. ; ; 2(R5) / 4(R5) = 10(R5) R 6(R5) ; OR ; (R0) / (R1) = (R3) R (R2) ; ; CARRY BIT SET ON RETURN INDICATES OVERFLOW ; ; REGISTER USAGE AFTER THIS POINT ; (R0) = DIVIDEND ; (R1) = DIVISOR ; (R2) = REMAINDER ; (R3) = QUOTIENT ; R4 = DIVIDEND SHIFT COUNT OR STATUS ; (R5) = DIVISOR BIT SET BUFFER ; ; ALL REGISTERS ARE PRESERVED .PSECT CLUNK,RO,I,LCL,REL DIV64:: MOV R0, -(SP) ; PRESERVE ALL REGISTERS MOV R1, -(SP) MOV R2, -(SP) MOV R3, -(SP) MOV R4, -(SP) MOV R5, -(SP) MOV 2(R5),R0 ; DIVIDEND MOV 4(R5),R1 ; DIVISOR MOV 6(R5),R2 ; REMAINDER MOV 10(R5),R3 ; QUOTIENT TST (R0) ; CHECK FOR ZERO DIVIDEND BNE D10 TST 2(R0) BNE D10 TST 4(R0) BNE D10 TST 6(R0) BNE D10 CLR (R3) ; DIVIDEND IS ZERO SO RESULT IS ZERO AND CLR 2(R3) CLR 4(R3) CLR 6(R3) CLR (R2) ; REMAINDER IS ZERO AS WELL CLR 2(R2) CLR 4(R2) CLR 6(R2) MOV #1,R4 ; ALL DONE SO EXIT WITH GOOD STATUS CLC JMP D99 D10: TST (R1) ; TEST FOR DIVIDE BY ZERO BNE D20 TST 2(R1) BNE D20 TST 4(R1) BNE D20 TST 6(R1) BNE D20 ; IF ZERO EXIT WITH OVERFLOW STATUS MOV #-3,R4 ; OVERFLOW CONDITION PRESENT SEC JMP D99 D20: MOV (R0),-(SP) ; PRESERVE DIVIDEND MOV 2(R0),-(SP) MOV 4(R0),-(SP) MOV 6(R0),-(SP) MOV (R1),-(SP) ; PRESERVE DIVISOR MOV 2(R1),-(SP) MOV 4(R1),-(SP) MOV 6(R1),-(SP) CLR (R3) ; CLEAR QUOTIENT CLR 2(R3) CLR 4(R3) CLR 6(R3) CLR R4 ; DIVIDEND SHIFT COUNTER MOV #0,-(SP) ; QUOTIENT SET WORD STORAGE ON STACK MOV #0,-(SP) MOV #0,-(SP) MOV #1,-(SP) MOV SP,R5 ; QUOITENT SET WORD LOCATION ON STACK ; ALL SET TO START DIVIDE LOOP OPERATION D40: ; SHIFT DIVISOR INTO LEFT MOST PART OF BUFFER TST 6(R1) ; CHECK IF ALREADY IN LEFT MOST PART BMI D50 D41: ASL (R5) ; SHIFT BIT SET WORD ROL 2(R5) ROL 4(R5) ROL 6(R5) ASL (R1) ; SHIFT DIVISOR ROL 2(R1) ROL 4(R1) ROL 6(R1) BPL D41 D50: ; SHIFT DIVIDEND TO THE LEFT MOST PART OF BUFFER ; COMPENSATE QUOITENT BIT SET IN PROCESS TST 6(R0) ; CHECK IF ALREADY IN LEFT MOST PART BMI D60 D51: CLC ; CLEAR CARRY ROR 6(R5) ; COMPENSATE QUOITENT BIT SET ROR 4(R5) ROR 2(R5) ROR (R5) BCS D80 ; ALL DONE WITH DIVISION, SHIFTED QUOITENT ; BIT SET UNDER ONE INC R4 ; DIVIDEND SHIFT COUNT ASL (R0) ; SHIFT DIVIDEND LEFT ROL 2(R0) ROL 4(R0) ROL 6(R0) BPL D51 D60: ; BUILD DEC STANDARD CALL SITE MOV R5,-(SP) ; SAVE R5 TO STACK MOV R5,-(SP) ; IDS VALUE LOCATION MOV SP,R5 MOV R5,-(SP) ; ADDRESS OF IDS MOV R2,-(SP) MOV R1,-(SP) MOV R0,-(SP) MOV SP,R5 SUB #2,R5 ; ADJUST ADDRESS JSR PC,SUB64 ; TEST SUBTRACT TO CHECK FOR SIGN CHANGE MOV (SP)+,R5 ; ADJUST SPACK BACK MOV (SP)+,R5 MOV (SP)+,R5 MOV (SP)+,R5 MOV (SP)+,R5 MOV (SP)+,R5 ; RESTORE R5 BCC D70 ; BRANCH IF NO SIGN CHANGE ; SUBTRACTION RESULT NEGITIVE SO DIVIDE DIVISOR BY 2 AND TRY AGAIN CLC ; ADJUST DIVISOR ROR 6(R1) ROR 4(R1) ROR 2(R1) ROR (R1) CLC ; ADJUST QUOITENT BIT SET ROR 6(R5) ROR 4(R5) ROR 2(R5) ROR (R5) BCS D80 ; ALL DONE WITH DIVISION, SHIFTED QUOITENT ; BIT SET UNDER ONE BR D60 D70: ; SUBTRACTION POSITIVE BIS (R5),(R3) ; SET BIT IN QUOITENT BIS 2(R5),2(R3) BIS 4(R5),4(R3) BIS 6(R5),6(R3) MOV (R2),(R0) ; MOVE RESULT OF SUBTRACTION TO NEW DIVIDEND MOV 2(R2),2(R0) MOV 4(R2),4(R0) MOV 6(R2),6(R0) TST (R0) ; CHECK THAT DIVIDEND IS NOT ZERO BNE D40 TST 2(R0) BNE D40 TST 4(R0) BNE D40 TST 6(R0) BNE D40 D80: ; ALL DONE. JUST CLEAN SOME STUFF UP NOW MOV (R0),(R2) ; MOVE DIVIDEND TO REMAINDER MOV 2(R0),2(R2) MOV 4(R0),4(R2) MOV 6(R0),6(R2) TST R4 BEQ D89 D88: CLC ; ADJUST REMAINDER BACK TO RIGHT ROR 6(R2) ROR 4(R2) ROR 2(R2) ROR (R2) SOB R4,D88 D89: MOV #1,R4 ; SET GOOD STATUS CLC MOV (SP)+,R5 ; CLEAN UP QUOITENT SET BUFFER ON STACK MOV (SP)+,R5 MOV (SP)+,R5 MOV (SP)+,R5 MOV (SP)+,6(R1) ; RESTORE DIVISOR MOV (SP)+,4(R1) MOV (SP)+,2(R1) MOV (SP)+,(R1) MOV (SP)+,6(R0) ; RESTORE DIVIDEND MOV (SP)+,4(R0) MOV (SP)+,2(R0) MOV (SP)+,(R0) D99: MOV (SP)+,R5 ; RESTORE R5 MOV R4,@12(R5) ; PUT STATUS IN IDS RETURN MOV (SP)+,R4 ; RESTORE THE OTHER REGISTERS MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 RTS PC .END