#include "asm.h" /* ** div_t divs64_1(int dh, int dl, int dv); ** ** This is a fairly basic signed division routine. It follows C rule that ** |q*d| <= |n|. Thus a non-zero remainder has the same sign as the dividend. */ .text .global divs64_1 divs64_1: lea -12(sp), sp moveml d2-d4, (sp) clrl d3 // Sign flag movel 24(sp), d2 // Get divisor bplb pl_dvs // Negative? movel #-1, d3 // Yep, set sign negl d2 // and take abs pl_dvs: clrw d3 // Assume positive dividend movel 20(sp), d0 // Lower word of dividend movel 16(sp), d1 // Upper word of dividend bplb pl_dvd // Negative? notl d3 // Yep, adjust sign negl d0 // and take abs negxl d1 // of dividend pl_dvd: cmpl d2, d1 // Overflow? Divide by zero? bccb ovflow movel #31, d4 // Get bitcount-1 loop: addl d0, d0 // Shift dividend addxl d1, d1 // Shift dividend, remainder cmpl d2, d1 // Trial subtraction bcsb lp_cnt // addl #1, d0 subl d2, d1 lp_cnt: subl #1, d4 // Done? bplb loop // Nope, go do another tstl d3 // Negative quotient? bplb pl_quo negl d0 // Yep, adjust bplb ovflow // Overflow? rtst: tstw d3 // Negative remainder? bplb done negl d1 // Yep, adjust done: moveml (sp), d2-d4 lea 12(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