]>
Commit | Line | Data |
---|---|---|
a71a29de YS |
1 | #include "libgcc.h" |
2 | ||
3 | ;; This function also computes the remainder and stores it in er3. | |
4 | .global __udivsi3 | |
5 | __udivsi3: | |
6 | mov.w A1E,A1E ; denominator top word 0? | |
7 | bne DenHighNonZero | |
8 | ||
9 | ; do it the easy way, see page 107 in manual | |
10 | mov.w A0E,A2 | |
11 | extu.l A2P | |
12 | divxu.w A1,A2P | |
13 | mov.w A2E,A0E | |
14 | divxu.w A1,A0P | |
15 | mov.w A0E,A3 | |
16 | mov.w A2,A0E | |
17 | extu.l A3P | |
18 | rts | |
19 | ||
20 | ; er0 = er0 / er1 | |
21 | ; er3 = er0 % er1 | |
22 | ; trashes er1 er2 | |
23 | ; expects er1 >= 2^16 | |
24 | DenHighNonZero: | |
25 | mov.l er0,er3 | |
26 | mov.l er1,er2 | |
27 | #ifdef CONFIG_CPU_H8300H | |
28 | divmod_L21: | |
29 | shlr.l er0 | |
30 | shlr.l er2 ; make divisor < 2^16 | |
31 | mov.w e2,e2 | |
32 | bne divmod_L21 | |
33 | #else | |
34 | shlr.l #2,er2 ; make divisor < 2^16 | |
35 | mov.w e2,e2 | |
36 | beq divmod_L22A | |
37 | divmod_L21: | |
38 | shlr.l #2,er0 | |
39 | divmod_L22: | |
40 | shlr.l #2,er2 ; make divisor < 2^16 | |
41 | mov.w e2,e2 | |
42 | bne divmod_L21 | |
43 | divmod_L22A: | |
44 | rotxl.w r2 | |
45 | bcs divmod_L23 | |
46 | shlr.l er0 | |
47 | bra divmod_L24 | |
48 | divmod_L23: | |
49 | rotxr.w r2 | |
50 | shlr.l #2,er0 | |
51 | divmod_L24: | |
52 | #endif | |
53 | ;; At this point, | |
54 | ;; er0 contains shifted dividend | |
55 | ;; er1 contains divisor | |
56 | ;; er2 contains shifted divisor | |
57 | ;; er3 contains dividend, later remainder | |
58 | divxu.w r2,er0 ; r0 now contains the approximate quotient (AQ) | |
59 | extu.l er0 | |
60 | beq divmod_L25 | |
61 | subs #1,er0 ; er0 = AQ - 1 | |
62 | mov.w e1,r2 | |
63 | mulxu.w r0,er2 ; er2 = upper (AQ - 1) * divisor | |
64 | sub.w r2,e3 ; dividend - 65536 * er2 | |
65 | mov.w r1,r2 | |
66 | mulxu.w r0,er2 ; compute er3 = remainder (tentative) | |
67 | sub.l er2,er3 ; er3 = dividend - (AQ - 1) * divisor | |
68 | divmod_L25: | |
69 | cmp.l er1,er3 ; is divisor < remainder? | |
70 | blo divmod_L26 | |
71 | adds #1,er0 | |
72 | sub.l er1,er3 ; correct the remainder | |
73 | divmod_L26: | |
74 | rts | |
75 | ||
76 | .end |