#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 


