u-boot/arch/arm/lib/_udivsi3.S
Simon Glass 1251d51ca5 arm: Add ENTRY/ENDPROC to private libgcc functions
When CONFIG_SYS_THUMB_BUILD is defined these functions may be called from
Thumb code. Add the required ENTRY and ENDPROC bracketing so that BLX is
used to call these ARM functions, instead of plain BL, which will fail.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reported-by: Pavel Machek <pavel@denx.de>
2015-07-07 11:39:22 +02:00

95 lines
2.4 KiB
ArmAsm

#include <linux/linkage.h>
/* # 1 "libgcc1.S" */
@ libgcc1 routines for ARM cpu.
@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
dividend .req r0
divisor .req r1
result .req r2
curbit .req r3
/* ip .req r12 */
/* sp .req r13 */
/* lr .req r14 */
/* pc .req r15 */
.text
.globl __udivsi3
.type __udivsi3 ,function
.globl __aeabi_uidiv
.type __aeabi_uidiv ,function
.align 0
__udivsi3:
__aeabi_uidiv:
cmp divisor, #0
beq Ldiv0
mov curbit, #1
mov result, #0
cmp dividend, divisor
bcc Lgot_result
Loop1:
@ Unless the divisor is very big, shift it up in multiples of
@ four bits, since this is the amount of unwinding in the main
@ division loop. Continue shifting until the divisor is
@ larger than the dividend.
cmp divisor, #0x10000000
cmpcc divisor, dividend
movcc divisor, divisor, lsl #4
movcc curbit, curbit, lsl #4
bcc Loop1
Lbignum:
@ For very big divisors, we must shift it a bit at a time, or
@ we will be in danger of overflowing.
cmp divisor, #0x80000000
cmpcc divisor, dividend
movcc divisor, divisor, lsl #1
movcc curbit, curbit, lsl #1
bcc Lbignum
Loop3:
@ Test for possible subtractions, and note which bits
@ are done in the result. On the final pass, this may subtract
@ too much from the dividend, but the result will be ok, since the
@ "bit" will have been shifted out at the bottom.
cmp dividend, divisor
subcs dividend, dividend, divisor
orrcs result, result, curbit
cmp dividend, divisor, lsr #1
subcs dividend, dividend, divisor, lsr #1
orrcs result, result, curbit, lsr #1
cmp dividend, divisor, lsr #2
subcs dividend, dividend, divisor, lsr #2
orrcs result, result, curbit, lsr #2
cmp dividend, divisor, lsr #3
subcs dividend, dividend, divisor, lsr #3
orrcs result, result, curbit, lsr #3
cmp dividend, #0 @ Early termination?
movnes curbit, curbit, lsr #4 @ No, any more bits to do?
movne divisor, divisor, lsr #4
bne Loop3
Lgot_result:
mov r0, result
mov pc, lr
Ldiv0:
str lr, [sp, #-4]!
bl __div0 (PLT)
mov r0, #0 @ about as wrong as it could be
ldmia sp!, {pc}
.size __udivsi3 , . - __udivsi3
ENTRY(__aeabi_uidivmod)
stmfd sp!, {r0, r1, ip, lr}
bl __aeabi_uidiv
ldmfd sp!, {r1, r2, ip, lr}
mul r3, r0, r2
sub r1, r1, r3
mov pc, lr
ENDPROC(__aeabi_uidivmod)
ENTRY(__aeabi_idivmod)
stmfd sp!, {r0, r1, ip, lr}
bl __aeabi_idiv
ldmfd sp!, {r1, r2, ip, lr}
mul r3, r0, r2
sub r1, r1, r3
mov pc, lr
ENDPROC(__aeabi_idivmod)