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