1/* # 1 "libgcc1.S" */ 2@ libgcc1 routines for ARM cpu. 3@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk) 4dividend .req r0 5divisor .req r1 6result .req r2 7curbit .req r3 8/* ip .req r12 */ 9/* sp .req r13 */ 10/* lr .req r14 */ 11/* pc .req r15 */ 12 .text 13 .globl __udivsi3 14 .type __udivsi3 ,function 15 .globl __aeabi_uidiv 16 .type __aeabi_uidiv ,function 17 .align 0 18 __udivsi3: 19 __aeabi_uidiv: 20 cmp divisor, #0 21 beq Ldiv0 22 mov curbit, #1 23 mov result, #0 24 cmp dividend, divisor 25 bcc Lgot_result 26Loop1: 27 @ Unless the divisor is very big, shift it up in multiples of 28 @ four bits, since this is the amount of unwinding in the main 29 @ division loop. Continue shifting until the divisor is 30 @ larger than the dividend. 31 cmp divisor, #0x10000000 32 cmpcc divisor, dividend 33 movcc divisor, divisor, lsl #4 34 movcc curbit, curbit, lsl #4 35 bcc Loop1 36Lbignum: 37 @ For very big divisors, we must shift it a bit at a time, or 38 @ we will be in danger of overflowing. 39 cmp divisor, #0x80000000 40 cmpcc divisor, dividend 41 movcc divisor, divisor, lsl #1 42 movcc curbit, curbit, lsl #1 43 bcc Lbignum 44Loop3: 45 @ Test for possible subtractions, and note which bits 46 @ are done in the result. On the final pass, this may subtract 47 @ too much from the dividend, but the result will be ok, since the 48 @ "bit" will have been shifted out at the bottom. 49 cmp dividend, divisor 50 subcs dividend, dividend, divisor 51 orrcs result, result, curbit 52 cmp dividend, divisor, lsr #1 53 subcs dividend, dividend, divisor, lsr #1 54 orrcs result, result, curbit, lsr #1 55 cmp dividend, divisor, lsr #2 56 subcs dividend, dividend, divisor, lsr #2 57 orrcs result, result, curbit, lsr #2 58 cmp dividend, divisor, lsr #3 59 subcs dividend, dividend, divisor, lsr #3 60 orrcs result, result, curbit, lsr #3 61 cmp dividend, #0 @ Early termination? 62 movnes curbit, curbit, lsr #4 @ No, any more bits to do? 63 movne divisor, divisor, lsr #4 64 bne Loop3 65Lgot_result: 66 mov r0, result 67 mov pc, lr 68Ldiv0: 69 str lr, [sp, #-4]! 70 bl __div0 (PLT) 71 mov r0, #0 @ about as wrong as it could be 72 ldmia sp!, {pc} 73 .size __udivsi3 , . - __udivsi3 74 75.globl __aeabi_uidivmod 76__aeabi_uidivmod: 77 78 stmfd sp!, {r0, r1, ip, lr} 79 bl __aeabi_uidiv 80 ldmfd sp!, {r1, r2, ip, lr} 81 mul r3, r0, r2 82 sub r1, r1, r3 83 mov pc, lr 84 85.globl __aeabi_idivmod 86__aeabi_idivmod: 87 88 stmfd sp!, {r0, r1, ip, lr} 89 bl __aeabi_idiv 90 ldmfd sp!, {r1, r2, ip, lr} 91 mul r3, r0, r2 92 sub r1, r1, r3 93 mov pc, lr 94