Added dhcpcl command; Some updates in kernel/core/net/dhcp.c;
[ZeXOS.git] / kernel / lib / arm / modsi3.S
blob050732f3515f9edbafc73a28faded24c0c038a0b
1 /* # 1 "libgcc1.S" */
2 @ libgcc1 routines for ARM cpu.
3 /* # 145 "libgcc1.S" */
4 dividend        .req    r0
5 divisor         .req    r1
6 overdone        .req    r2
7 curbit          .req    r3
8 /* ip           .req    r12     */
9 /* sp           .req    r13     */
10 /* lr           .req    r14     */
11 /* pc           .req    r15     */
12         .text
13         .globl   __umodsi3
14         .type  __umodsi3       ,function
15         .align 0
16  __umodsi3      :
17         cmp     divisor, #0
18         beq     Ldiv0
19         mov     curbit, #1
20         cmp     dividend, divisor
21         movcc   pc, lr
22 Loop1:
23         @ Unless the divisor is very big, shift it up in multiples of
24         @ four bits, since this is the amount of unwinding in the main
25         @ division loop.  Continue shifting until the divisor is
26         @ larger than the dividend.
27         cmp     divisor, #0x10000000
28         cmpcc   divisor, dividend
29         movcc   divisor, divisor, lsl #4
30         movcc   curbit, curbit, lsl #4
31         bcc     Loop1
32 Lbignum:
33         @ For very big divisors, we must shift it a bit at a time, or
34         @ we will be in danger of overflowing.
35         cmp     divisor, #0x80000000
36         cmpcc   divisor, dividend
37         movcc   divisor, divisor, lsl #1
38         movcc   curbit, curbit, lsl #1
39         bcc     Lbignum
40 Loop3:
41         @ Test for possible subtractions.  On the final pass, this may
42         @ subtract too much from the dividend, so keep track of which
43         @ subtractions are done, we can fix them up afterwards...
44         mov     overdone, #0
45         cmp     dividend, divisor
46         subcs   dividend, dividend, divisor
47         cmp     dividend, divisor, lsr #1
48         subcs   dividend, dividend, divisor, lsr #1
49         orrcs   overdone, overdone, curbit, ror #1
50         cmp     dividend, divisor, lsr #2
51         subcs   dividend, dividend, divisor, lsr #2
52         orrcs   overdone, overdone, curbit, ror #2
53         cmp     dividend, divisor, lsr #3
54         subcs   dividend, dividend, divisor, lsr #3
55         orrcs   overdone, overdone, curbit, ror #3
56         mov     ip, curbit
57         cmp     dividend, #0                    @ Early termination?
58         movnes  curbit, curbit, lsr #4          @ No, any more bits to do?
59         movne   divisor, divisor, lsr #4
60         bne     Loop3
61         @ Any subtractions that we should not have done will be recorded in
62         @ the top three bits of "overdone".  Exactly which were not needed
63         @ are governed by the position of the bit, stored in ip.
64         @ If we terminated early, because dividend became zero,
65         @ then none of the below will match, since the bit in ip will not be
66         @ in the bottom nibble.
67         ands    overdone, overdone, #0xe0000000
68         moveq   pc, lr                          @ No fixups needed
69         tst     overdone, ip, ror #3
70         addne   dividend, dividend, divisor, lsr #3
71         tst     overdone, ip, ror #2
72         addne   dividend, dividend, divisor, lsr #2
73         tst     overdone, ip, ror #1
74         addne   dividend, dividend, divisor, lsr #1
75         mov     pc, lr
76 Ldiv0:
77         str     lr, [sp, #-4]!
78         bl       __div0       (PLT)
79         mov     r0, #0                  @ about as wrong as it could be
80         ldmia   sp!, {pc}
81         .size  __umodsi3       , . -  __umodsi3