home *** CD-ROM | disk | FTP | other *** search
- | unsigned long division and modulus routines
- |
- | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
- |
- |
- | Revision 1.1, kub 03-90
- | first version, replaces the appropriate routine from fixnum.s.
- | Should be faster in more common cases. Division is done by 68000 divu
- | operations if divisor is only 16 bits wide. Otherwise the normal division
- | algorithm as described in various papers takes place. The division routine
- | delivers the quotient in d0 and the remainder in d1, thus the implementation
- | of the modulo operation is trivial.
-
- .text
- .even
- .globl __udivsi3, ___udivsi3
- .globl __umodsi3, ___umodsi3
-
- __udivsi3:
- ___udivsi3:
- movel d2,a0 | save registers
- movel d3,a1
- clrl d0 | prepare result
- movel sp@(8),d2 | get divisor
- beq 9f | divisor = 0 causes a division trap
- movel sp@(4),d1 | get dividend
- |== case 1) divident < divisor
- cmpl d2,d1 | is divident smaller then divisor ?
- bcs 8f | yes, return immediately
- |== case 2) divisor has <= 16 significant bits
- tstw sp@(8)
- bne 2f | divisor has only 16 bits
- movew d1,d3 | save dividend
- clrw d1 | divide dvd.h by dvs
- swap d1
- beq 0f | (no division necessary if dividend zero)
- divu d2,d1
- 0: movew d1,d0 | save quotient.h
- swap d0
- movew d3,d1 | (d1.h = remainder of prev divu)
- divu d2,d1 | divide dvd.l by dvs
- movew d1,d0 | save quotient.l
- clrw d1 | get remainder
- swap d1
- bra 8f | and return
- |== case 3) divisor > 16 bits (corollary is dividend > 16 bits, see case 1)
- 2:
- moveq #31,d3 | loop count
- 3:
- addl d1,d1 | shift divident ...
- addxl d0,d0 | ... into d0
- cmpl d2,d0 | compare with divisor
- bcs 0f
- subl d2,d0 | big enough, subtract
- addw #1,d1 | and note bit in result
- 0:
- dbra d3,3b
- exg d0,d1 | put quotient and remainder in their registers
- 8:
- movel a1,d3
- movel a0,d2
- rts
- 9:
- divu d2,d1 | cause division trap
- bra 8b | back to user
-
-
- __umodsi3:
- ___umodsi3:
- movel sp@(8),sp@- | push divisor
- movel sp@(8),sp@- | push dividend
- jbsr __udivsi3
- addql #8,sp
- movel d1,d0 | return the remainder in d0
- rts
-