1/* # 1 "libgcc1.S" */ 2@ libgcc1 routines for ARM cpu. 3@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk) 4/* # 145 "libgcc1.S" */ 5dividend .req r0 6divisor .req r1 7overdone .req r2 8curbit .req r3 9/* ip .req r12 */ 10/* sp .req r13 */ 11/* lr .req r14 */ 12/* pc .req r15 */ 13 .text 14 .globl __umodsi3 15 .type __umodsi3 ,function 16 .align 0 17 __umodsi3 : 18 cmp divisor, #0 19 beq Ldiv0 20 mov curbit, #1 21 cmp dividend, divisor 22 movcc pc, lr 23Loop1: 24 @ Unless the divisor is very big, shift it up in multiples of 25 @ four bits, since this is the amount of unwinding in the main 26 @ division loop. Continue shifting until the divisor is 27 @ larger than the dividend. 28 cmp divisor, #0x10000000 29 cmpcc divisor, dividend 30 movcc divisor, divisor, lsl #4 31 movcc curbit, curbit, lsl #4 32 bcc Loop1 33Lbignum: 34 @ For very big divisors, we must shift it a bit at a time, or 35 @ we will be in danger of overflowing. 36 cmp divisor, #0x80000000 37 cmpcc divisor, dividend 38 movcc divisor, divisor, lsl #1 39 movcc curbit, curbit, lsl #1 40 bcc Lbignum 41Loop3: 42 @ Test for possible subtractions. On the final pass, this may 43 @ subtract too much from the dividend, so keep track of which 44 @ subtractions are done, we can fix them up afterwards... 45 mov overdone, #0 46 cmp dividend, divisor 47 subcs dividend, dividend, divisor 48 cmp dividend, divisor, lsr #1 49 subcs dividend, dividend, divisor, lsr #1 50 orrcs overdone, overdone, curbit, ror #1 51 cmp dividend, divisor, lsr #2 52 subcs dividend, dividend, divisor, lsr #2 53 orrcs overdone, overdone, curbit, ror #2 54 cmp dividend, divisor, lsr #3 55 subcs dividend, dividend, divisor, lsr #3 56 orrcs overdone, overdone, curbit, ror #3 57 mov ip, curbit 58 cmp dividend, #0 @ Early termination? 59 movnes curbit, curbit, lsr #4 @ No, any more bits to do? 60 movne divisor, divisor, lsr #4 61 bne Loop3 62 @ Any subtractions that we should not have done will be recorded in 63 @ the top three bits of "overdone". Exactly which were not needed 64 @ are governed by the position of the bit, stored in ip. 65 @ If we terminated early, because dividend became zero, 66 @ then none of the below will match, since the bit in ip will not be 67 @ in the bottom nibble. 68 ands overdone, overdone, #0xe0000000 69 moveq pc, lr @ No fixups needed 70 tst overdone, ip, ror #3 71 addne dividend, dividend, divisor, lsr #3 72 tst overdone, ip, ror #2 73 addne dividend, dividend, divisor, lsr #2 74 tst overdone, ip, ror #1 75 addne dividend, dividend, divisor, lsr #1 76 mov pc, lr 77Ldiv0: 78 str lr, [sp, #-4]! 79 bl __div0 (PLT) 80 mov r0, #0 @ about as wrong as it could be 81 ldmia sp!, {pc} 82 .size __umodsi3 , . - __umodsi3 83/* # 320 "libgcc1.S" */ 84/* # 421 "libgcc1.S" */ 85/* # 433 "libgcc1.S" */ 86/* # 456 "libgcc1.S" */ 87/* # 500 "libgcc1.S" */ 88/* # 580 "libgcc1.S" */ 89