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