]> git.ipfire.org Git - people/ms/u-boot.git/blob - lib_arm/_divsi3.S
fsl_elbc_nand: redirect the pointer of bbt pattern to RAM
[people/ms/u-boot.git] / lib_arm / _divsi3.S
1
2 .macro ARM_DIV_BODY dividend, divisor, result, curbit
3
4 #if __LINUX_ARM_ARCH__ >= 5
5
6 clz \curbit, \divisor
7 clz \result, \dividend
8 sub \result, \curbit, \result
9 mov \curbit, #1
10 mov \divisor, \divisor, lsl \result
11 mov \curbit, \curbit, lsl \result
12 mov \result, #0
13
14 #else
15
16 @ Initially shift the divisor left 3 bits if possible,
17 @ set curbit accordingly. This allows for curbit to be located
18 @ at the left end of each 4 bit nibbles in the division loop
19 @ to save one loop in most cases.
20 tst \divisor, #0xe0000000
21 moveq \divisor, \divisor, lsl #3
22 moveq \curbit, #8
23 movne \curbit, #1
24
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 1: cmp \divisor, #0x10000000
30 cmplo \divisor, \dividend
31 movlo \divisor, \divisor, lsl #4
32 movlo \curbit, \curbit, lsl #4
33 blo 1b
34
35 @ For very big divisors, we must shift it a bit at a time, or
36 @ we will be in danger of overflowing.
37 1: cmp \divisor, #0x80000000
38 cmplo \divisor, \dividend
39 movlo \divisor, \divisor, lsl #1
40 movlo \curbit, \curbit, lsl #1
41 blo 1b
42
43 mov \result, #0
44
45 #endif
46
47 @ Division loop
48 1: cmp \dividend, \divisor
49 subhs \dividend, \dividend, \divisor
50 orrhs \result, \result, \curbit
51 cmp \dividend, \divisor, lsr #1
52 subhs \dividend, \dividend, \divisor, lsr #1
53 orrhs \result, \result, \curbit, lsr #1
54 cmp \dividend, \divisor, lsr #2
55 subhs \dividend, \dividend, \divisor, lsr #2
56 orrhs \result, \result, \curbit, lsr #2
57 cmp \dividend, \divisor, lsr #3
58 subhs \dividend, \dividend, \divisor, lsr #3
59 orrhs \result, \result, \curbit, lsr #3
60 cmp \dividend, #0 @ Early termination?
61 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
62 movne \divisor, \divisor, lsr #4
63 bne 1b
64
65 .endm
66
67 .macro ARM_DIV2_ORDER divisor, order
68
69 #if __LINUX_ARM_ARCH__ >= 5
70
71 clz \order, \divisor
72 rsb \order, \order, #31
73
74 #else
75
76 cmp \divisor, #(1 << 16)
77 movhs \divisor, \divisor, lsr #16
78 movhs \order, #16
79 movlo \order, #0
80
81 cmp \divisor, #(1 << 8)
82 movhs \divisor, \divisor, lsr #8
83 addhs \order, \order, #8
84
85 cmp \divisor, #(1 << 4)
86 movhs \divisor, \divisor, lsr #4
87 addhs \order, \order, #4
88
89 cmp \divisor, #(1 << 2)
90 addhi \order, \order, #3
91 addls \order, \order, \divisor, lsr #1
92
93 #endif
94
95 .endm
96
97 .align 5
98 .globl __divsi3
99 __divsi3:
100 cmp r1, #0
101 eor ip, r0, r1 @ save the sign of the result.
102 beq Ldiv0
103 rsbmi r1, r1, #0 @ loops below use unsigned.
104 subs r2, r1, #1 @ division by 1 or -1 ?
105 beq 10f
106 movs r3, r0
107 rsbmi r3, r0, #0 @ positive dividend value
108 cmp r3, r1
109 bls 11f
110 tst r1, r2 @ divisor is power of 2 ?
111 beq 12f
112
113 ARM_DIV_BODY r3, r1, r0, r2
114
115 cmp ip, #0
116 rsbmi r0, r0, #0
117 mov pc, lr
118
119 10: teq ip, r0 @ same sign ?
120 rsbmi r0, r0, #0
121 mov pc, lr
122
123 11: movlo r0, #0
124 moveq r0, ip, asr #31
125 orreq r0, r0, #1
126 mov pc, lr
127
128 12: ARM_DIV2_ORDER r1, r2
129
130 cmp ip, #0
131 mov r0, r3, lsr r2
132 rsbmi r0, r0, #0
133 mov pc, lr
134
135 Ldiv0:
136
137 str lr, [sp, #-4]!
138 bl __div0
139 mov r0, #0 @ About as wrong as it could be.
140 ldr pc, [sp], #4