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.
20 movel
%d2
,%a0 | save registers
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
31 bne L_2 | divisor has only
16 bits
32 movew
%d1
,%d3 | save dividend
33 clrw
%d1 | divide dvd.h by dvs
35 beq L_00 |
(no division necessary if dividend zero
)
37 L_00
: movew
%d1
,%d0 | save quotient.h
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
45 |
== case
3) divisor
> 16 bits
(corollary is dividend
> 16 bits
, see case
1)
47 moveq
#31,%d3 | loop count
49 addl
%d1
,%d1 | shift divident
...
50 addxl
%d0
,%d0 |
... into %d0
51 cmpl %d2
,%d0 | compare with divisor
53 subl
%d2
,%d0 | big enough
, subtract
54 addw
#1,%d1 | and note bit in result
57 exg
%d0
,%d1 | put quotient
and remainder in their registers
63 divu
%d2
,%d1 | cause division
trap
64 bra L_8 | back to user
68 movel
%sp@
(8),%sp@
- | push divisor
69 movel
%sp@
(8),%sp@
- | push dividend
72 movel
%d1
,%d0 | return the remainder in
%d0