1 #include <linux/linkage.h>
4 @ libgcc1 routines for ARM cpu.
5 @ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
6 /* # 145 "libgcc1.S" */
16 .type __umodsi3 ,function
25 @ Unless the divisor is very big, shift it up in multiples of
26 @ four bits, since this is the amount of unwinding in the main
27 @ division loop. Continue shifting until the divisor is
28 @ larger than the dividend.
29 cmp divisor, #0x10000000
30 cmpcc divisor, dividend
31 movcc divisor, divisor, lsl #4
32 movcc curbit, curbit, lsl #4
35 @ For very big divisors, we must shift it a bit at a time, or
36 @ we will be in danger of overflowing.
37 cmp divisor, #0x80000000
38 cmpcc divisor, dividend
39 movcc divisor, divisor, lsl #1
40 movcc curbit, curbit, lsl #1
43 @ Test for possible subtractions. On the final pass, this may
44 @ subtract too much from the dividend, so keep track of which
45 @ subtractions are done, we can fix them up afterwards...
48 subcs dividend, dividend, divisor
49 cmp dividend, divisor, lsr #1
50 subcs dividend, dividend, divisor, lsr #1
51 orrcs overdone, overdone, curbit, ror #1
52 cmp dividend, divisor, lsr #2
53 subcs dividend, dividend, divisor, lsr #2
54 orrcs overdone, overdone, curbit, ror #2
55 cmp dividend, divisor, lsr #3
56 subcs dividend, dividend, divisor, lsr #3
57 orrcs overdone, overdone, curbit, ror #3
59 cmp dividend, #0 @ Early termination?
60 movnes curbit, curbit, lsr #4 @ No, any more bits to do?
61 movne divisor, divisor, lsr #4
63 @ Any subtractions that we should not have done will be recorded in
64 @ the top three bits of "overdone". Exactly which were not needed
65 @ are governed by the position of the bit, stored in ip.
66 @ If we terminated early, because dividend became zero,
67 @ then none of the below will match, since the bit in ip will not be
68 @ in the bottom nibble.
69 ands overdone, overdone, #0xe0000000
70 moveq pc, lr @ No fixups needed
71 tst overdone, ip, ror #3
72 addne dividend, dividend, divisor, lsr #3
73 tst overdone, ip, ror #2
74 addne dividend, dividend, divisor, lsr #2
75 tst overdone, ip, ror #1
76 addne dividend, dividend, divisor, lsr #1
81 mov r0, #0 @ about as wrong as it could be
83 .size __umodsi3 , . - __umodsi3
84 /* # 320 "libgcc1.S" */
85 /* # 421 "libgcc1.S" */
86 /* # 433 "libgcc1.S" */
87 /* # 456 "libgcc1.S" */
88 /* # 500 "libgcc1.S" */
89 /* # 580 "libgcc1.S" */