#ifdef mc68hc12 void _ediv(unsigned short numhi, unsigned short numlo, unsigned short den, unsigned short *res, unsigned short *mod, unsigned short *status) { __asm__ __volatile__ (" ediv\n\ tfr ccr,x" : "=x" (*status), "=y" (*res), "=d" (*mod) : "d" (numlo), "y" (numhi), "x" (den)); } #endif unsigned long __udivmodsi4 (unsigned long num, unsigned long den, unsigned long* mod) { unsigned long bit; unsigned long res; unsigned short sres; if ((unsigned short) (den >> 16) == 0) { unsigned short sden = (unsigned short) den; unsigned short smod; if ((unsigned short) (num >> 16) == 0) { /* Both numbers are 16-bit quantities, use 16-bit div/mod. */ unsigned short snum = (unsigned short) num; sres = snum / sden; smod = snum % sden; if (mod) *mod = (unsigned long) smod; return (unsigned long) sres; } #ifdef mc68hc12 else { /* num is more that 16 bits use ediv */ unsigned short status; unsigned short numhi=(unsigned short)(num>>16); unsigned short numlo=(unsigned short)(num & 0xFFFF); _ediv((unsigned short)(num>>16), (unsigned short)(num & 0xFFFF), sden, &sres, &smod, &status); // check for overflow if (!(status & 0x03)) { *mod = (unsigned long) smod; return (unsigned long) sres; } } #endif if ((unsigned short) den == 0) { if (mod) *mod = 0; return 0; } } bit = 1; res = 0; while (den < num && !((unsigned short) (den >> 16) & (1L<<15))) { den <<=1; bit <<=1; } while (bit) { if (num >= den) { num -= den; res |= bit; } bit >>=1; den >>=1; } if (mod) *mod = num; return res; } #ifdef L_udivmodsi4 unsigned long udivmodsi4 (unsigned long num, unsigned long den, int modwanted) { unsigned long mod; if (modwanted) { __udivmodsi4 (num, den, &mod); return mod; } else { return __udivmodsi4 (num, den, 0); } } #endif