home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib25.zoo / lattice / _udivmod.s < prev    next >
Text File  |  1992-06-15  |  2KB  |  65 lines

  1. ; unsigned long division and modulus routines
  2. ;
  3. ; written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  4. ;
  5. ;
  6. ; Revision 1.1, kub 03-90
  7. ; first version, replaces the appropriate routine from fixnum.s.
  8. ; Should be faster in more common cases. Division is done by 68000 divu
  9. ; operations if divisor is only 16 bits wide. Otherwise the normal division
  10. ; algorithm as described in various papers takes place. The division routine
  11. ; delivers the quotient in d0 and the remainder in d1, thus the implementation
  12. ; of the modulo operation is trivial.
  13.  
  14.     text
  15.     even
  16.     xdef    __CXD33
  17.  
  18. __CXD33:
  19.     movem.l    d0-d3,-(sp)
  20.     subq.w    #4,sp
  21.     clr.l    d0        ; prepare result
  22.     move.l    8(sp),d2    ; get divisor
  23.     beq.s    9$        ; divisor = 0 causes a division trap
  24.     move.l    4(sp),d1    ; get dividend
  25. ;== case 1) divident < divisor
  26.     cmp.l    d2,d1        ; is divident smaller then divisor ?
  27.     bcs.s    8$        ; yes, return immediately
  28. ;== case 2) divisor has <= 16 significant bits
  29.     tst.w    8(sp)
  30.     bne.s    2$        ; divisor has only 16 bits
  31.     move.w    d1,d3        ; save dividend
  32.     clr.w    d1        ; divide dvd.h by dvs
  33.     swap    d1
  34.     beq.s    1$        ; (no division necessary if dividend zero)
  35.     divu.w    d2,d1
  36. 1$:    move.w    d1,d0        ; save quotient.h
  37.     swap    d0
  38.     move.w    d3,d1        ; (d1.h = remainder of prev divu)
  39.     divu.w    d2,d1        ; divide dvd.l by dvs
  40.     move.w    d1,d0        ; save quotient.l
  41.     clr.w    d1        ; get remainder
  42.     swap    d1
  43.     bra.s    8$        ; and return
  44. ;== case 3) divisor > 16 bits (corollary is dividend > 16 bits, see case 1)
  45. 2$:
  46.     moveq.l    #31,d3        ; loop count
  47. 3$:
  48.     add.l    d1,d1        ; shift divident ...
  49.     addx.l    d0,d0        ;  ... into d0
  50.     cmp.l    d2,d0        ; compare with divisor
  51.     bcs.s    4$
  52.     sub.l    d2,d0        ; big enough, subtract
  53.     add.w    #1,d1        ; and note bit in result
  54. 4$:
  55.     dbra    d3,3$
  56.     exg    d0,d1        ; put quotient and remainder in their registers
  57. 8$:
  58.     lea    12(sp),sp
  59.     movem.l    (sp)+,d2-d3
  60.     rts
  61. 9$:
  62.     divu.w    d2,d1        ; cause division trap
  63.     bra.s    8$        ; back to user
  64.     end
  65.