#include "asm.h" /* ** divu_t divu64_2(unsigned dh, unsigned dl, unsigned dv); ** ** This routine is similar to divu64_1, but uses Coldfires sole conditional ** data instruction, Scc, to eliminate the conditional branches within the ** loop. This also eliminates the double-loop structure. */ .text .global divu64_2 divu64_2: lea -16(sp), sp moveml d2-d5, (sp) movel 28(sp), d2 // Get divisor movel 24(sp), d0 // Lower word of dividend movel 20(sp), d1 // Upper word of dividend cmpl d2, d1 // Overflow? Divide by zero? bccb ovflow movel d2, d3 lsrl #1, d3 // floor(divisor/2) subl d2, d3 // floor(-divisor/2) subl a0, a0 subl d3, a0 // ceil(divisor/2) movel #31, d5 // Get bitcount-1 movel d2, d4 lsll d5, d4 // Use count to shift low bit into place loop: addl d4, d0 // Trial subtraction, low bit addxl d3, d1 // Trial subtraction (or add back) scc d3 // Clear byte on success addxl d0, d0 // Set next quotient bit, shift dividend addxl d1, d1 // Shift dividend, remainder extbl d3 // Extend flag byte andl d2, d3 // Either 0 or divisor subl a0, d3 // transform into subtract or add back! subl #1, d5 // Done? bplb loop // Nope, go do another tstl d3 // Need to correct the remainder? bmib done // Nope addl d2, d1 // Yep, fix it up done: moveml (sp), d2-d5 lea 16(sp), sp rts ovflow: movel #-1, d0 // Return all ones movel d0, d1 // and impossible remainder brab done