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