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