blob: 13098026104734f83075727b1a197f145ffb15d9 [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/* # 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
wdenkac6dbb82003-03-26 11:42:53 +00008/* ip .req r12 */
9/* sp .req r13 */
10/* lr .req r14 */
11/* pc .req r15 */
wdenkc6097192002-11-03 00:24:07 +000012 .text
13 .globl __udivsi3
Wolfgang Denk59b4d742009-08-06 21:29:59 +020014 .type __udivsi3 ,function
15 .globl __aeabi_uidiv
16 .type __aeabi_uidiv ,function
wdenkc6097192002-11-03 00:24:07 +000017 .align 0
Wolfgang Denk59b4d742009-08-06 21:29:59 +020018 __udivsi3:
19 __aeabi_uidiv:
wdenkc6097192002-11-03 00:24:07 +000020 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
Wolfgang Denk53677ef2008-05-20 16:00:29 +020067 mov pc, lr
wdenkc6097192002-11-03 00:24:07 +000068Ldiv0:
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
Wolfgang Denk59b4d742009-08-06 21:29:59 +020074
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