/* # 1 "libgcc1.S" */
@ libgcc1 routines for ARM cpu.
@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
dividend . r e q r0
divisor . r e q r1
result . r e q r2
curbit . r e q r3
/* ip .req r12 */
/* sp .req r13 */
/* lr .req r14 */
/* pc .req r15 */
.text
.globl __udivsi3
.type __udivsi3 , function
.align 0
_ _ udivsi3 :
cmp d i v i s o r , #0
beq L d i v0
mov c u r b i t , #1
mov r e s u l t , #0
cmp d i v i d e n d , d i v i s o r
bcc L g o t _ r e s u l t
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 d i v i s o r , #0x10000000
cmpcc d i v i s o r , d i v i d e n d
movcc d i v i s o r , d i v i s o r , l s l #4
movcc c u r b i t , c u r b i t , l s l #4
bcc L o o p1
Lbignum :
@ For very big divisors, we must shift it a bit at a time, or
@ we will be in danger of overflowing.
cmp d i v i s o r , #0x80000000
cmpcc d i v i s o r , d i v i d e n d
movcc d i v i s o r , d i v i s o r , l s l #1
movcc c u r b i t , c u r b i t , l s l #1
bcc L b i g n u m
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 d i v i d e n d , d i v i s o r
subcs d i v i d e n d , d i v i d e n d , d i v i s o r
orrcs r e s u l t , r e s u l t , c u r b i t
cmp d i v i d e n d , d i v i s o r , l s r #1
subcs d i v i d e n d , d i v i d e n d , d i v i s o r , l s r #1
orrcs r e s u l t , r e s u l t , c u r b i t , l s r #1
cmp d i v i d e n d , d i v i s o r , l s r #2
subcs d i v i d e n d , d i v i d e n d , d i v i s o r , l s r #2
orrcs r e s u l t , r e s u l t , c u r b i t , l s r #2
cmp d i v i d e n d , d i v i s o r , l s r #3
subcs d i v i d e n d , d i v i d e n d , d i v i s o r , l s r #3
orrcs r e s u l t , r e s u l t , c u r b i t , l s r #3
cmp d i v i d e n d , #0 @ Early termination?
movnes c u r b i t , c u r b i t , l s r #4 @ No, any more bits to do?
movne d i v i s o r , d i v i s o r , l s r #4
bne L o o p3
Lgot_result :
mov r0 , r e s u l t
mov p c , l r
Ldiv0 :
str l r , [ s p , #- 4 ] !
bl _ _ d i v0 ( P L T )
mov r0 , #0 @ about as wrong as it could be
ldmia s p ! , { p c }
.size __udivsi3 , . - _ _ udivsi3
/* # 235 "libgcc1.S" */
/* # 320 "libgcc1.S" */
/* # 421 "libgcc1.S" */
/* # 433 "libgcc1.S" */
/* # 456 "libgcc1.S" */
/* # 500 "libgcc1.S" */
/* # 580 "libgcc1.S" */