#include "asm.h" /* ** div_t divs64_2(int dh, int dl, int dv); ** ** This routine uses the same sign logic as divs64_1, and combines it with ** the double subtract/add loop of divu64_1. It builds the quotient up in a ** seperate register. It uses a bit primed in the quotient register to count ** the iterations. */ .text .global divs64_2 divs64_2: lea -16(sp), sp moveml d2-d5, (sp) clrl d5 // Sign flag movel 28(sp), d2 // Get divisor bplb pl_dvs // Negative? movel #-1, d5 // Yep, set sign negl d2 // and take abs pl_dvs: clrw d5 // Assume positive dividend movel 24(sp), d3 // Lower word of dividend movel 20(sp), d1 // Upper word of dividend bplb pl_dvd // Negative? notl d5 // Yep, adjust sign negl d3 // and take abs negxl d1 // of dividend pl_dvd: cmpl d2, d1 // Overflow? Divide by zero? bccb ovflow movel #1, d0 // Prime quotient register movel d2, d4 negl d4 // -divisor for trial subtractions sub_lp: addl d3, d3 // Shift dividend addxl d1, d1 // Shift dividend, remainder addl d4, d1 // Trial subtraction bccb clr_q // set_q: addxl d0, d0 bccb sub_lp // Nope, go do another brab sgn_chk add_lp: addl d3, d3 // Shift dividend addxl d1, d1 // Shift dividend, remainder addl d2, d1 // Trial subtraction (add back) bcsb set_q // clr_q: addxl d0, d0 bccb add_lp // Nope, go do another addl d2, d1 // Adjust remainder sgn_chk:tstl d5 // Negative quotient? bplb pl_quo negl d0 // Yep, adjust bplb ovflow // Overflow? rtst: tstw d5 // Negative remainder? bplb done negl d1 // Yep, adjust done: moveml (sp), d2-d5 lea 16(sp), sp rts pl_quo: tstl d0 // Overflow? bplb rtst // No, go check remainder ovflow: movel #0x80000000, d0 // Return MAX + 1 movel d0, d1 // and impossible remainder brab done