1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- /* # 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
- .align 0
- __udivsi3 :
- 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
- /* # 235 "libgcc1.S" */
- /* # 320 "libgcc1.S" */
- /* # 421 "libgcc1.S" */
- /* # 433 "libgcc1.S" */
- /* # 456 "libgcc1.S" */
- /* # 500 "libgcc1.S" */
- /* # 580 "libgcc1.S" */
|