home *** CD-ROM | disk | FTP | other *** search
- ; long arithmetic routines
- ;
- ; written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
- ;
- ; Names changed and converted from MIT to Motorola syntax by Dave Gymer for SC
- ;
- ; 5/5/92 sb -- unsigned routines separated out to reduce library drag
-
- .text
- .even
- .globl lmulu
- .globl ldivu
- .globl lremu
-
- ldivu:
- move.l d2,a0 ; save registers
- move.l d3,a1
- clr.l d0 ; prepare result
- move.l 8(sp),d2 ; get divisor
- beq N9 ; divisor = 0 causes a division trap
- move.l 4(sp),d1 ; get dividend
- ;== case 1) divident < divisor
- cmp.l d2,d1 ; is divident smaller then divisor ?
- bcs N8 ; yes, return immediately
- ;== case 2) divisor has <= 16 significant bits
- tst.w 8(sp)
- bne N2 ; divisor has only 16 bits
- move.w d1,d3 ; save dividend
- clr.w d1 ; divide dvd.h by dvs
- swap d1
- beq K0 ; (no division necessary if dividend zero)
- divu d2,d1
- K0: move.w d1,d0 ; save quotient.h
- swap d0
- move.w d3,d1 ; (d1.h = remainder of prev divu)
- divu d2,d1 ; divide dvd.l by dvs
- move.w d1,d0 ; save quotient.l
- clr.w d1 ; get remainder
- swap d1
- bra N8 ; and return
- ;== case 3) divisor > 16 bits (corollary is dividend > 16 bits, see case 1)
- N2:
- moveq #31,d3 ; loop count
- N3:
- add.l d1,d1 ; shift divident ...
- addx.l d0,d0 ; ... into d0
- cmp.l d2,d0 ; compare with divisor
- bcs K1
- sub.l d2,d0 ; big enough, subtract
- add.w #1,d1 ; and note bit in result
- K1:
- dbra d3,N3
- exg d0,d1 ; put quotient and remainder in their registers
- N8:
- move.l a1,d3
- move.l a0,d2
- rts
- N9:
- divu d2,d1 ; cause division trap
- bra N8 ; back to user
-
- lremu:
- move.l 8(sp),-(sp) ; push divisor
- move.l 8(sp),-(sp) ; push dividend
- bsr ldivu
- lea 8(sp),sp
- move.l d1,d0 ; return the remainder in d0
- rts
-
- lmulu:
- move.l d2,a0 ; save registers
- move.l d3,a1
- movem.w 4(sp),d0-d3 ; get the two longs. u = d0-d1, v = d2-d3
- ext.l d0 ; u.h <> 0 ?
- beq O1
- mulu d3,d0 ; r = v.l * u.h
- O1: tst.w d2 ; v.h <> 0 ?
- beq O2
- mulu d1,d2 ; r += v.h * u.l
- add.w d2,d0
- O2: swap d0
- clr.w d0
- mulu d3,d1 ; r += v.l * u.l
- add.l d1,d0
- move.l a1,d3
- move.l a0,d2
- rts
-