]> git.sur5r.net Git - u-boot/blob - arch/arm/lib/_udivsi3.S
Merge branch 'master' of git://git.denx.de/u-boot-video
[u-boot] / arch / arm / lib / _udivsi3.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 dividend        .req    r0
7 divisor         .req    r1
8 result          .req    r2
9 curbit          .req    r3
10 /* ip           .req    r12     */
11 /* sp           .req    r13     */
12 /* lr           .req    r14     */
13 /* pc           .req    r15     */
14         .text
15         .globl   __udivsi3
16         .type   __udivsi3 ,function
17         .globl  __aeabi_uidiv
18         .type   __aeabi_uidiv ,function
19         .align  0
20  __udivsi3:
21  __aeabi_uidiv:
22         cmp     divisor, #0
23         beq     Ldiv0
24         mov     curbit, #1
25         mov     result, #0
26         cmp     dividend, divisor
27         bcc     Lgot_result
28 Loop1:
29         @ Unless the divisor is very big, shift it up in multiples of
30         @ four bits, since this is the amount of unwinding in the main
31         @ division loop.  Continue shifting until the divisor is
32         @ larger than the dividend.
33         cmp     divisor, #0x10000000
34         cmpcc   divisor, dividend
35         movcc   divisor, divisor, lsl #4
36         movcc   curbit, curbit, lsl #4
37         bcc     Loop1
38 Lbignum:
39         @ For very big divisors, we must shift it a bit at a time, or
40         @ we will be in danger of overflowing.
41         cmp     divisor, #0x80000000
42         cmpcc   divisor, dividend
43         movcc   divisor, divisor, lsl #1
44         movcc   curbit, curbit, lsl #1
45         bcc     Lbignum
46 Loop3:
47         @ Test for possible subtractions, and note which bits
48         @ are done in the result.  On the final pass, this may subtract
49         @ too much from the dividend, but the result will be ok, since the
50         @ "bit" will have been shifted out at the bottom.
51         cmp     dividend, divisor
52         subcs   dividend, dividend, divisor
53         orrcs   result, result, curbit
54         cmp     dividend, divisor, lsr #1
55         subcs   dividend, dividend, divisor, lsr #1
56         orrcs   result, result, curbit, lsr #1
57         cmp     dividend, divisor, lsr #2
58         subcs   dividend, dividend, divisor, lsr #2
59         orrcs   result, result, curbit, lsr #2
60         cmp     dividend, divisor, lsr #3
61         subcs   dividend, dividend, divisor, lsr #3
62         orrcs   result, result, curbit, lsr #3
63         cmp     dividend, #0                    @ Early termination?
64         movnes  curbit, curbit, lsr #4          @ No, any more bits to do?
65         movne   divisor, divisor, lsr #4
66         bne     Loop3
67 Lgot_result:
68         mov     r0, result
69         mov     pc, lr
70 Ldiv0:
71         str     lr, [sp, #-4]!
72         bl       __div0       (PLT)
73         mov     r0, #0                  @ about as wrong as it could be
74         ldmia   sp!, {pc}
75         .size  __udivsi3       , . -  __udivsi3
76
77 ENTRY(__aeabi_uidivmod)
78
79         stmfd   sp!, {r0, r1, ip, lr}
80         bl      __aeabi_uidiv
81         ldmfd   sp!, {r1, r2, ip, lr}
82         mul     r3, r0, r2
83         sub     r1, r1, r3
84         mov     pc, lr
85 ENDPROC(__aeabi_uidivmod)
86
87 ENTRY(__aeabi_idivmod)
88
89         stmfd   sp!, {r0, r1, ip, lr}
90         bl      __aeabi_idiv
91         ldmfd   sp!, {r1, r2, ip, lr}
92         mul     r3, r0, r2
93         sub     r1, r1, r3
94         mov     pc, lr
95 ENDPROC(__aeabi_idivmod)