1 --- a/arch/arm/lib/Makefile
2 +++ b/arch/arm/lib/Makefile
3 @@ -26,7 +26,6 @@ include $(TOPDIR)/config.mk
4 LIB = $(obj)lib$(ARCH).o
5 LIBGCC = $(obj)libgcc.o
7 -ifndef CONFIG_SPL_BUILD
11 @@ -34,9 +33,11 @@ GLSOBJS += _lshrdi3.o
15 +GLSOBJS += uldivmod.o
19 +ifndef CONFIG_SPL_BUILD
22 COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o
24 +++ b/arch/arm/lib/uldivmod.S
27 + * Copyright 2010, Google Inc.
29 + * Brought in from coreboot uldivmod.S
31 + * SPDX-License-Identifier: GPL-2.0
34 +#include <linux/linkage.h>
35 +#include <asm/assembler.h>
38 + * A, Q = r0 + (r1 << 32)
39 + * B, R = r2 + (r3 << 32)
64 +.pushsection .text.__aeabi_uldivmod, "ax"
65 +ENTRY(__aeabi_uldivmod)
67 + stmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) lr}
69 + orrs ip, B_0, B_1 @ Z set -> B == 0
71 + @ Test if B is power of 2: (B & (B - 1)) == 0
77 + @ Test if A_1 == B_1 == 0
82 +/* CLZ only exists in ARM architecture version 5 and above. */
96 + @ if clz B - clz A > 0
99 + @ B <<= (clz B - clz A)
102 + movmi B_1, B_1, lsl D_0
103 +ARM( orrmi B_1, B_1, B_0, lsr ip )
104 +THUMB( lsrmi TMP, B_0, ip )
105 +THUMB( orrmi B_1, B_1, TMP )
106 + movpl B_1, B_0, lsl D_1
107 + mov B_0, B_0, lsl D_0
108 + @ C = 1 << (clz B - clz A)
109 + movmi C_1, C_1, lsl D_0
110 +ARM( orrmi C_1, C_1, C_0, lsr ip )
111 +THUMB( lsrmi TMP, C_0, ip )
112 +THUMB( orrmi C_1, C_1, TMP )
113 + movpl C_1, C_0, lsl D_1
114 + mov C_0, C_0, lsl D_0
118 + @ C: current bit; D: result
120 + @ C: current bit; D: result
126 + cmp B_1, #0x10000000
131 + mov B_1, B_1, lsl #4
132 + orr B_1, B_1, B_0, lsr #28
133 + mov B_0, B_0, lsl #4
135 + mov C_1, C_1, lsl #4
136 + orr C_1, C_1, C_0, lsr #28
137 + mov C_0, C_0, lsl #4
140 + cmp B_1, #0x80000000
145 + mov B_1, B_1, lsl #1
146 + orr B_1, B_1, B_0, lsr #31
147 + mov B_0, B_0, lsl #1
149 + mov C_1, C_1, lsl #1
150 + orr C_1, C_1, C_0, lsr #31
151 + mov C_0, C_0, lsl #1
170 + movs C_1, C_1, lsr #1
176 + movs B_1, B_1, lsr #1
180 + @ Note: A, B & Q, R are aliases
185 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc}
188 + @ Note: A_0 & r0 are aliases
191 + bl __aeabi_uidivmod
195 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc}
199 + @ Note: A, B and Q, R are aliases
204 + @ Note: B must not be 0 here!
211 + mov A_0, A_1, lsr D_0
214 + movpl A_0, A_0, lsr D_0
215 +ARM( orrpl A_0, A_0, A_1, lsl D_1 )
216 +THUMB( lslpl TMP, A_1, D_1 )
217 +THUMB( orrpl A_0, A_0, TMP )
218 + mov A_1, A_1, lsr D_0
222 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc}
224 + @ Note: A, B and Q, R are aliases
229 + @ Note: B must not be 0 here!
230 + @ Count the leading zeroes in B.
233 + @ If B is greater than 1 << 31, divide A and B by 1 << 32.
237 + @ Count the remaining leading zeroes in B.
238 + movs B_1, B_0, lsl #16
240 + moveq B_0, B_0, lsr #16
243 + moveq B_0, B_0, lsr #8
246 + moveq B_0, B_0, lsr #4
249 + moveq B_0, B_0, lsr #2
252 + @ Shift A to the right by the appropriate amount.
254 + mov Q_0, A_0, lsr D_0
255 + ARM( orr Q_0, Q_0, A_1, lsl D_1 )
256 + THUMB( lsl A_1, D_1 )
257 + THUMB( orr Q_0, A_1 )
258 + mov Q_1, A_1, lsr D_0
262 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc}
267 + @ As wrong as it could be
272 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc}
273 +ENDPROC(__aeabi_uldivmod)