- Removed unnecessary casts.
[AROS.git] / arch / m68k-all / libgcc1 / _udivmodsi3.s
blobfb4aecb1b1550d5f850d297e8fb7e78069dd6db0
1 | unsigned long division and modulus routines
3 | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
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.
14 .text
15 .even
16 .globl __udivsi3
17 .globl __umodsi3
19 __udivsi3:
20 movel %d2,%a0 | save registers
21 movel %d3,%a1
22 clrl %d0 | prepare result
23 movel %sp@(8),%d2 | get divisor
24 beq L_9 | divisor = 0 causes a division trap
25 movel %sp@(4),%d1 | get dividend
26 |== case 1) divident < divisor
27 cmpl %d2,%d1 | is divident smaller then divisor ?
28 bcs L_8 | yes, return immediately
29 |== case 2) divisor has <= 16 significant bits
30 tstw %sp@(8)
31 bne L_2 | divisor has only 16 bits
32 movew %d1,%d3 | save dividend
33 clrw %d1 | divide dvd.h by dvs
34 swap %d1
35 beq L_00 | (no division necessary if dividend zero)
36 divu %d2,%d1
37 L_00: movew %d1,%d0 | save quotient.h
38 swap %d0
39 movew %d3,%d1 | (%d1.h = remainder of prev divu)
40 divu %d2,%d1 | divide dvd.l by dvs
41 movew %d1,%d0 | save quotient.l
42 clrw %d1 | get remainder
43 swap %d1
44 bra L_8 | and return
45 |== case 3) divisor > 16 bits (corollary is dividend > 16 bits, see case 1)
46 L_2:
47 moveq #31,%d3 | loop count
48 L_3:
49 addl %d1,%d1 | shift divident ...
50 addxl %d0,%d0 | ... into %d0
51 cmpl %d2,%d0 | compare with divisor
52 bcs L_01
53 subl %d2,%d0 | big enough, subtract
54 addw #1,%d1 | and note bit in result
55 L_01:
56 dbra %d3,L_3
57 exg %d0,%d1 | put quotient and remainder in their registers
58 L_8:
59 movel %a1,%d3
60 movel %a0,%d2
61 rts
62 L_9:
63 divu %d2,%d1 | cause division trap
64 bra L_8 | back to user
67 __umodsi3:
68 movel %sp@(8),%sp@- | push divisor
69 movel %sp@(8),%sp@- | push dividend
70 jbsr __udivsi3
71 addql #8,%sp
72 movel %d1,%d0 | return the remainder in %d0
73 rts