Merge branch 'master' of /media/usbdisk-11/IER/reference/romboot
[romboot.git] / _udivsi3.S
blob2cdcd48b49da28834a58569190af9b0ece84df77
1 /* # 1 "libgcc1.S" */
2 @ libgcc1 routines for ARM cpu.
3 @ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
4 dividend        .req    r0
5 divisor         .req    r1
6 result          .req    r2
7 curbit          .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         .align  0
16  __udivsi3      :
17         cmp     divisor, #0
18         beq     Ldiv0
19         mov     curbit, #1
20         mov     result, #0
21         cmp     dividend, divisor
22         bcc     Lgot_result
23 Loop1:
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
33 Lbignum:
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
41 Loop3:
42         @ Test for possible subtractions, and note which bits
43         @ are done in the result.  On the final pass, this may subtract
44         @ too much from the dividend, but the result will be ok, since the
45         @ "bit" will have been shifted out at the bottom.
46         cmp     dividend, divisor
47         subcs   dividend, dividend, divisor
48         orrcs   result, result, curbit
49         cmp     dividend, divisor, lsr #1
50         subcs   dividend, dividend, divisor, lsr #1
51         orrcs   result, result, curbit, lsr #1
52         cmp     dividend, divisor, lsr #2
53         subcs   dividend, dividend, divisor, lsr #2
54         orrcs   result, result, curbit, lsr #2
55         cmp     dividend, divisor, lsr #3
56         subcs   dividend, dividend, divisor, lsr #3
57         orrcs   result, result, curbit, lsr #3
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 Lgot_result:
63         mov     r0, result
64         mov     pc, lr
65 Ldiv0:
66         str     lr, [sp, #-4]!
67         bl       __div0       (PLT)
68         mov     r0, #0                  @ about as wrong as it could be
69         ldmia   sp!, {pc}
70         .size  __udivsi3       , . -  __udivsi3
71 /* # 235 "libgcc1.S" */
72 /* # 320 "libgcc1.S" */
73 /* # 421 "libgcc1.S" */
74 /* # 433 "libgcc1.S" */
75 /* # 456 "libgcc1.S" */
76 /* # 500 "libgcc1.S" */
77 /* # 580 "libgcc1.S" */