xref: /DragonStub/lib/arm/uldiv.S (revision 803b49c40bb0b720b90d9c31d372911f1b946aa7)
1//------------------------------------------------------------------------------
2//
3// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
4//
5// This program and the accompanying materials
6// are licensed and made available under the terms and conditions of the BSD License
7// which accompanies this distribution.  The full text of the license may be found at
8// http://opensource.org/licenses/bsd-license.php
9//
10// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12//
13//------------------------------------------------------------------------------
14
15#include "edk2asm.h"
16
17  .text
18  .align 2
19  GCC_ASM_EXPORT(__aeabi_uldivmod)
20
21//
22//UINT64
23//EFIAPI
24//__aeabi_uldivmod (
25//  IN  UINT64   Dividend
26//  IN  UINT64   Divisor
27//  )
28//
29ASM_PFX(__aeabi_uldivmod):
30  stmdb   sp!, {r4, r5, r6, lr}
31  mov     r4, r1
32  mov     r5, r0
33  mov     r6, #0  // 0x0
34  orrs    ip, r3, r2, lsr #31
35  bne     ASM_PFX(__aeabi_uldivmod_label1)
36  tst     r2, r2
37  beq     ASM_PFX(_ll_div0)
38  movs    ip, r2, lsr #15
39  addeq   r6, r6, #16     // 0x10
40  mov     ip, r2, lsl r6
41  movs    lr, ip, lsr #23
42  moveq   ip, ip, lsl #8
43  addeq   r6, r6, #8      // 0x8
44  movs    lr, ip, lsr #27
45  moveq   ip, ip, lsl #4
46  addeq   r6, r6, #4      // 0x4
47  movs    lr, ip, lsr #29
48  moveq   ip, ip, lsl #2
49  addeq   r6, r6, #2      // 0x2
50  movs    lr, ip, lsr #30
51  moveq   ip, ip, lsl #1
52  addeq   r6, r6, #1      // 0x1
53  b       ASM_PFX(_ll_udiv_small)
54ASM_PFX(__aeabi_uldivmod_label1):
55  tst     r3, #-2147483648        // 0x80000000
56  bne     ASM_PFX(__aeabi_uldivmod_label2)
57  movs    ip, r3, lsr #15
58  addeq   r6, r6, #16     // 0x10
59  mov     ip, r3, lsl r6
60  movs    lr, ip, lsr #23
61  moveq   ip, ip, lsl #8
62  addeq   r6, r6, #8      // 0x8
63  movs    lr, ip, lsr #27
64  moveq   ip, ip, lsl #4
65  addeq   r6, r6, #4      // 0x4
66  movs    lr, ip, lsr #29
67  moveq   ip, ip, lsl #2
68  addeq   r6, r6, #2      // 0x2
69  movs    lr, ip, lsr #30
70  addeq   r6, r6, #1      // 0x1
71  rsb     r3, r6, #32     // 0x20
72  moveq   ip, ip, lsl #1
73  orr     ip, ip, r2, lsr r3
74  mov     lr, r2, lsl r6
75  b       ASM_PFX(_ll_udiv_big)
76ASM_PFX(__aeabi_uldivmod_label2):
77  mov     ip, r3
78  mov     lr, r2
79  b       ASM_PFX(_ll_udiv_ginormous)
80
81ASM_PFX(_ll_udiv_small):
82  cmp     r4, ip, lsl #1
83  mov     r3, #0  // 0x0
84  subcs   r4, r4, ip, lsl #1
85  addcs   r3, r3, #2      // 0x2
86  cmp     r4, ip
87  subcs   r4, r4, ip
88  adcs    r3, r3, #0      // 0x0
89  add     r2, r6, #32     // 0x20
90  cmp     r2, #32 // 0x20
91  rsb     ip, ip, #0      // 0x0
92  bcc     ASM_PFX(_ll_udiv_small_label1)
93  orrs    r0, r4, r5, lsr #30
94  moveq   r4, r5
95  moveq   r5, #0  // 0x0
96  subeq   r2, r2, #32     // 0x20
97ASM_PFX(_ll_udiv_small_label1):
98  mov     r1, #0  // 0x0
99  cmp     r2, #16 // 0x10
100  bcc     ASM_PFX(_ll_udiv_small_label2)
101  movs    r0, r4, lsr #14
102  moveq   r4, r4, lsl #16
103  addeq   r1, r1, #16     // 0x10
104ASM_PFX(_ll_udiv_small_label2):
105  sub     lr, r2, r1
106  cmp     lr, #8  // 0x8
107  bcc     ASM_PFX(_ll_udiv_small_label3)
108  movs    r0, r4, lsr #22
109  moveq   r4, r4, lsl #8
110  addeq   r1, r1, #8      // 0x8
111ASM_PFX(_ll_udiv_small_label3):
112  rsb     r0, r1, #32     // 0x20
113  sub     r2, r2, r1
114  orr     r4, r4, r5, lsr r0
115  mov     r5, r5, lsl r1
116  cmp     r2, #1  // 0x1
117  bcc     ASM_PFX(_ll_udiv_small_label5)
118  sub     r2, r2, #1      // 0x1
119  and     r0, r2, #7      // 0x7
120  eor     r0, r0, #7      // 0x7
121  adds    r0, r0, r0, lsl #1
122  add     pc, pc, r0, lsl #2
123  nop                     // (mov r0,r0)
124ASM_PFX(_ll_udiv_small_label4):
125  adcs    r5, r5, r5
126  adcs    r4, ip, r4, lsl #1
127  rsbcc   r4, ip, r4
128  adcs    r5, r5, r5
129  adcs    r4, ip, r4, lsl #1
130  rsbcc   r4, ip, r4
131  adcs    r5, r5, r5
132  adcs    r4, ip, r4, lsl #1
133  rsbcc   r4, ip, r4
134  adcs    r5, r5, r5
135  adcs    r4, ip, r4, lsl #1
136  rsbcc   r4, ip, r4
137  adcs    r5, r5, r5
138  adcs    r4, ip, r4, lsl #1
139  rsbcc   r4, ip, r4
140  adcs    r5, r5, r5
141  adcs    r4, ip, r4, lsl #1
142  rsbcc   r4, ip, r4
143  adcs    r5, r5, r5
144  adcs    r4, ip, r4, lsl #1
145  rsbcc   r4, ip, r4
146  adcs    r5, r5, r5
147  adcs    r4, ip, r4, lsl #1
148  sub     r2, r2, #8      // 0x8
149  tst     r2, r2
150  rsbcc   r4, ip, r4
151  bpl     ASM_PFX(_ll_udiv_small_label4)
152ASM_PFX(_ll_udiv_small_label5):
153  mov     r2, r4, lsr r6
154  bic     r4, r4, r2, lsl r6
155  adcs    r0, r5, r5
156  adc     r1, r4, r4
157  add     r1, r1, r3, lsl r6
158  mov     r3, #0  // 0x0
159  ldmia   sp!, {r4, r5, r6, pc}
160
161ASM_PFX(_ll_udiv_big):
162  subs    r0, r5, lr
163  mov     r3, #0  // 0x0
164  sbcs    r1, r4, ip
165  movcs   r5, r0
166  movcs   r4, r1
167  adcs    r3, r3, #0      // 0x0
168  subs    r0, r5, lr
169  sbcs    r1, r4, ip
170  movcs   r5, r0
171  movcs   r4, r1
172  adcs    r3, r3, #0      // 0x0
173  subs    r0, r5, lr
174  sbcs    r1, r4, ip
175  movcs   r5, r0
176  movcs   r4, r1
177  adcs    r3, r3, #0      // 0x0
178  mov     r1, #0  // 0x0
179  rsbs    lr, lr, #0      // 0x0
180  rsc     ip, ip, #0      // 0x0
181  cmp     r6, #16 // 0x10
182  bcc     ASM_PFX(_ll_udiv_big_label1)
183  movs    r0, r4, lsr #14
184  moveq   r4, r4, lsl #16
185  addeq   r1, r1, #16     // 0x10
186ASM_PFX(_ll_udiv_big_label1):
187  sub     r2, r6, r1
188  cmp     r2, #8  // 0x8
189  bcc     ASM_PFX(_ll_udiv_big_label2)
190  movs    r0, r4, lsr #22
191  moveq   r4, r4, lsl #8
192  addeq   r1, r1, #8      // 0x8
193ASM_PFX(_ll_udiv_big_label2):
194  rsb     r0, r1, #32     // 0x20
195  sub     r2, r6, r1
196  orr     r4, r4, r5, lsr r0
197  mov     r5, r5, lsl r1
198  cmp     r2, #1  // 0x1
199  bcc     ASM_PFX(_ll_udiv_big_label4)
200  sub     r2, r2, #1      // 0x1
201  and     r0, r2, #3      // 0x3
202  rsb     r0, r0, #3      // 0x3
203  adds    r0, r0, r0, lsl #1
204  add     pc, pc, r0, lsl #3
205  nop                     // (mov r0,r0)
206ASM_PFX(_ll_udiv_big_label3):
207  adcs    r5, r5, r5
208  adcs    r4, r4, r4
209  adcs    r0, lr, r5
210  adcs    r1, ip, r4
211  movcs   r5, r0
212  movcs   r4, r1
213  adcs    r5, r5, r5
214  adcs    r4, r4, r4
215  adcs    r0, lr, r5
216  adcs    r1, ip, r4
217  movcs   r5, r0
218  movcs   r4, r1
219  adcs    r5, r5, r5
220  adcs    r4, r4, r4
221  adcs    r0, lr, r5
222  adcs    r1, ip, r4
223  movcs   r5, r0
224  movcs   r4, r1
225  sub     r2, r2, #4      // 0x4
226  adcs    r5, r5, r5
227  adcs    r4, r4, r4
228  adcs    r0, lr, r5
229  adcs    r1, ip, r4
230  tst     r2, r2
231  movcs   r5, r0
232  movcs   r4, r1
233  bpl     ASM_PFX(_ll_udiv_big_label3)
234ASM_PFX(_ll_udiv_big_label4):
235  mov     r1, #0  // 0x0
236  mov     r2, r5, lsr r6
237  bic     r5, r5, r2, lsl r6
238  adcs    r0, r5, r5
239  adc     r1, r1, #0      // 0x0
240  movs    lr, r3, lsl r6
241  mov     r3, r4, lsr r6
242  bic     r4, r4, r3, lsl r6
243  adc     r1, r1, #0      // 0x0
244  adds    r0, r0, lr
245  orr     r2, r2, r4, ror r6
246  adc     r1, r1, #0      // 0x0
247  ldmia   sp!, {r4, r5, r6, pc}
248
249ASM_PFX(_ll_udiv_ginormous):
250  subs    r2, r5, lr
251  mov     r1, #0  // 0x0
252  sbcs    r3, r4, ip
253  adc     r0, r1, r1
254  movcc   r2, r5
255  movcc   r3, r4
256  ldmia   sp!, {r4, r5, r6, pc}
257
258ASM_PFX(_ll_div0):
259  ldmia   sp!, {r4, r5, r6, lr}
260  mov     r0, #0  // 0x0
261  mov     r1, #0  // 0x0
262  b       ASM_PFX(__aeabi_ldiv0)
263
264ASM_PFX(__aeabi_ldiv0):
265  bx      r14
266
267#if defined(__ELF__) && defined(__linux__)
268	.section .note.GNU-stack,"",%progbits
269#endif
270