Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/libkern/arm/divsi3.S
35067 views
1
/* $NetBSD: divsi3.S,v 1.4 2003/04/05 23:27:15 bjh21 Exp $ */
2
3
/*-
4
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
5
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
8
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
9
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
10
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
11
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
12
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
14
* SUCH DAMAGE.
15
*/
16
17
#include <machine/asm.h>
18
/*
19
* stack is aligned as there's a possibility of branching to L_overflow
20
* which makes a C call
21
*/
22
23
ENTRY_NP(__umodsi3)
24
stmfd sp!, {lr}
25
sub sp, sp, #4 /* align stack */
26
bl .L_udivide
27
add sp, sp, #4 /* unalign stack */
28
mov r0, r1
29
ldmfd sp!, {pc}
30
END(__umodsi3)
31
32
ENTRY_NP(__modsi3)
33
stmfd sp!, {lr}
34
sub sp, sp, #4 /* align stack */
35
bl .L_divide
36
add sp, sp, #4 /* unalign stack */
37
mov r0, r1
38
ldmfd sp!, {pc}
39
40
.L_overflow:
41
#if !defined(_KERNEL) && !defined(_STANDALONE)
42
mov r0, #8 /* SIGFPE */
43
bl PIC_SYM(_C_LABEL(raise), PLT) /* raise it */
44
mov r0, #0
45
#else
46
/* XXX should cause a fatal error */
47
mvn r0, #0
48
#endif
49
RET
50
END(__modsi3)
51
52
ENTRY_NP(__udivsi3)
53
EENTRY_NP(__aeabi_uidiv)
54
EENTRY_NP(__aeabi_uidivmod)
55
.L_udivide: /* r0 = r0 / r1; r1 = r0 % r1 */
56
eor r0, r1, r0
57
eor r1, r0, r1
58
eor r0, r1, r0
59
/* r0 = r1 / r0; r1 = r1 % r0 */
60
cmp r0, #1
61
bcc .L_overflow
62
beq .L_divide_l0
63
mov ip, #0
64
movs r1, r1
65
bpl .L_divide_l1
66
orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */
67
movs r1, r1, lsr #1
68
orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */
69
b .L_divide_l1
70
71
.L_divide_l0: /* r0 == 1 */
72
mov r0, r1
73
mov r1, #0
74
RET
75
EEND(__aeabi_uidiv)
76
EEND(__aeabi_uidivmod)
77
END(__udivsi3)
78
79
ENTRY_NP(__divsi3)
80
EENTRY_NP(__aeabi_idiv)
81
EENTRY_NP(__aeabi_idivmod)
82
.L_divide: /* r0 = r0 / r1; r1 = r0 % r1 */
83
eor r0, r1, r0
84
eor r1, r0, r1
85
eor r0, r1, r0
86
/* r0 = r1 / r0; r1 = r1 % r0 */
87
cmp r0, #1
88
bcc .L_overflow
89
beq .L_divide_l0
90
ands ip, r0, #0x80000000
91
rsbmi r0, r0, #0
92
ands r2, r1, #0x80000000
93
eor ip, ip, r2
94
rsbmi r1, r1, #0
95
orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */
96
/* ip bit 0x80000000 = -ve remainder */
97
98
.L_divide_l1:
99
mov r2, #1
100
mov r3, #0
101
102
/*
103
* If the highest bit of the dividend is set, we have to be
104
* careful when shifting the divisor. Test this.
105
*/
106
movs r1,r1
107
bpl .L_old_code
108
109
/*
110
* At this point, the highest bit of r1 is known to be set.
111
* We abuse this below in the tst instructions.
112
*/
113
tst r1, r0 /*, lsl #0 */
114
bmi .L_divide_b1
115
tst r1, r0, lsl #1
116
bmi .L_divide_b2
117
tst r1, r0, lsl #2
118
bmi .L_divide_b3
119
tst r1, r0, lsl #3
120
bmi .L_divide_b4
121
tst r1, r0, lsl #4
122
bmi .L_divide_b5
123
tst r1, r0, lsl #5
124
bmi .L_divide_b6
125
tst r1, r0, lsl #6
126
bmi .L_divide_b7
127
tst r1, r0, lsl #7
128
bmi .L_divide_b8
129
tst r1, r0, lsl #8
130
bmi .L_divide_b9
131
tst r1, r0, lsl #9
132
bmi .L_divide_b10
133
tst r1, r0, lsl #10
134
bmi .L_divide_b11
135
tst r1, r0, lsl #11
136
bmi .L_divide_b12
137
tst r1, r0, lsl #12
138
bmi .L_divide_b13
139
tst r1, r0, lsl #13
140
bmi .L_divide_b14
141
tst r1, r0, lsl #14
142
bmi .L_divide_b15
143
tst r1, r0, lsl #15
144
bmi .L_divide_b16
145
tst r1, r0, lsl #16
146
bmi .L_divide_b17
147
tst r1, r0, lsl #17
148
bmi .L_divide_b18
149
tst r1, r0, lsl #18
150
bmi .L_divide_b19
151
tst r1, r0, lsl #19
152
bmi .L_divide_b20
153
tst r1, r0, lsl #20
154
bmi .L_divide_b21
155
tst r1, r0, lsl #21
156
bmi .L_divide_b22
157
tst r1, r0, lsl #22
158
bmi .L_divide_b23
159
tst r1, r0, lsl #23
160
bmi .L_divide_b24
161
tst r1, r0, lsl #24
162
bmi .L_divide_b25
163
tst r1, r0, lsl #25
164
bmi .L_divide_b26
165
tst r1, r0, lsl #26
166
bmi .L_divide_b27
167
tst r1, r0, lsl #27
168
bmi .L_divide_b28
169
tst r1, r0, lsl #28
170
bmi .L_divide_b29
171
tst r1, r0, lsl #29
172
bmi .L_divide_b30
173
tst r1, r0, lsl #30
174
bmi .L_divide_b31
175
/*
176
* instead of:
177
* tst r1, r0, lsl #31
178
* bmi .L_divide_b32
179
*/
180
b .L_divide_b32
181
182
.L_old_code:
183
cmp r1, r0
184
bcc .L_divide_b0
185
cmp r1, r0, lsl #1
186
bcc .L_divide_b1
187
cmp r1, r0, lsl #2
188
bcc .L_divide_b2
189
cmp r1, r0, lsl #3
190
bcc .L_divide_b3
191
cmp r1, r0, lsl #4
192
bcc .L_divide_b4
193
cmp r1, r0, lsl #5
194
bcc .L_divide_b5
195
cmp r1, r0, lsl #6
196
bcc .L_divide_b6
197
cmp r1, r0, lsl #7
198
bcc .L_divide_b7
199
cmp r1, r0, lsl #8
200
bcc .L_divide_b8
201
cmp r1, r0, lsl #9
202
bcc .L_divide_b9
203
cmp r1, r0, lsl #10
204
bcc .L_divide_b10
205
cmp r1, r0, lsl #11
206
bcc .L_divide_b11
207
cmp r1, r0, lsl #12
208
bcc .L_divide_b12
209
cmp r1, r0, lsl #13
210
bcc .L_divide_b13
211
cmp r1, r0, lsl #14
212
bcc .L_divide_b14
213
cmp r1, r0, lsl #15
214
bcc .L_divide_b15
215
cmp r1, r0, lsl #16
216
bcc .L_divide_b16
217
cmp r1, r0, lsl #17
218
bcc .L_divide_b17
219
cmp r1, r0, lsl #18
220
bcc .L_divide_b18
221
cmp r1, r0, lsl #19
222
bcc .L_divide_b19
223
cmp r1, r0, lsl #20
224
bcc .L_divide_b20
225
cmp r1, r0, lsl #21
226
bcc .L_divide_b21
227
cmp r1, r0, lsl #22
228
bcc .L_divide_b22
229
cmp r1, r0, lsl #23
230
bcc .L_divide_b23
231
cmp r1, r0, lsl #24
232
bcc .L_divide_b24
233
cmp r1, r0, lsl #25
234
bcc .L_divide_b25
235
cmp r1, r0, lsl #26
236
bcc .L_divide_b26
237
cmp r1, r0, lsl #27
238
bcc .L_divide_b27
239
cmp r1, r0, lsl #28
240
bcc .L_divide_b28
241
cmp r1, r0, lsl #29
242
bcc .L_divide_b29
243
cmp r1, r0, lsl #30
244
bcc .L_divide_b30
245
.L_divide_b32:
246
cmp r1, r0, lsl #31
247
subhs r1, r1,r0, lsl #31
248
addhs r3, r3,r2, lsl #31
249
.L_divide_b31:
250
cmp r1, r0, lsl #30
251
subhs r1, r1,r0, lsl #30
252
addhs r3, r3,r2, lsl #30
253
.L_divide_b30:
254
cmp r1, r0, lsl #29
255
subhs r1, r1,r0, lsl #29
256
addhs r3, r3,r2, lsl #29
257
.L_divide_b29:
258
cmp r1, r0, lsl #28
259
subhs r1, r1,r0, lsl #28
260
addhs r3, r3,r2, lsl #28
261
.L_divide_b28:
262
cmp r1, r0, lsl #27
263
subhs r1, r1,r0, lsl #27
264
addhs r3, r3,r2, lsl #27
265
.L_divide_b27:
266
cmp r1, r0, lsl #26
267
subhs r1, r1,r0, lsl #26
268
addhs r3, r3,r2, lsl #26
269
.L_divide_b26:
270
cmp r1, r0, lsl #25
271
subhs r1, r1,r0, lsl #25
272
addhs r3, r3,r2, lsl #25
273
.L_divide_b25:
274
cmp r1, r0, lsl #24
275
subhs r1, r1,r0, lsl #24
276
addhs r3, r3,r2, lsl #24
277
.L_divide_b24:
278
cmp r1, r0, lsl #23
279
subhs r1, r1,r0, lsl #23
280
addhs r3, r3,r2, lsl #23
281
.L_divide_b23:
282
cmp r1, r0, lsl #22
283
subhs r1, r1,r0, lsl #22
284
addhs r3, r3,r2, lsl #22
285
.L_divide_b22:
286
cmp r1, r0, lsl #21
287
subhs r1, r1,r0, lsl #21
288
addhs r3, r3,r2, lsl #21
289
.L_divide_b21:
290
cmp r1, r0, lsl #20
291
subhs r1, r1,r0, lsl #20
292
addhs r3, r3,r2, lsl #20
293
.L_divide_b20:
294
cmp r1, r0, lsl #19
295
subhs r1, r1,r0, lsl #19
296
addhs r3, r3,r2, lsl #19
297
.L_divide_b19:
298
cmp r1, r0, lsl #18
299
subhs r1, r1,r0, lsl #18
300
addhs r3, r3,r2, lsl #18
301
.L_divide_b18:
302
cmp r1, r0, lsl #17
303
subhs r1, r1,r0, lsl #17
304
addhs r3, r3,r2, lsl #17
305
.L_divide_b17:
306
cmp r1, r0, lsl #16
307
subhs r1, r1,r0, lsl #16
308
addhs r3, r3,r2, lsl #16
309
.L_divide_b16:
310
cmp r1, r0, lsl #15
311
subhs r1, r1,r0, lsl #15
312
addhs r3, r3,r2, lsl #15
313
.L_divide_b15:
314
cmp r1, r0, lsl #14
315
subhs r1, r1,r0, lsl #14
316
addhs r3, r3,r2, lsl #14
317
.L_divide_b14:
318
cmp r1, r0, lsl #13
319
subhs r1, r1,r0, lsl #13
320
addhs r3, r3,r2, lsl #13
321
.L_divide_b13:
322
cmp r1, r0, lsl #12
323
subhs r1, r1,r0, lsl #12
324
addhs r3, r3,r2, lsl #12
325
.L_divide_b12:
326
cmp r1, r0, lsl #11
327
subhs r1, r1,r0, lsl #11
328
addhs r3, r3,r2, lsl #11
329
.L_divide_b11:
330
cmp r1, r0, lsl #10
331
subhs r1, r1,r0, lsl #10
332
addhs r3, r3,r2, lsl #10
333
.L_divide_b10:
334
cmp r1, r0, lsl #9
335
subhs r1, r1,r0, lsl #9
336
addhs r3, r3,r2, lsl #9
337
.L_divide_b9:
338
cmp r1, r0, lsl #8
339
subhs r1, r1,r0, lsl #8
340
addhs r3, r3,r2, lsl #8
341
.L_divide_b8:
342
cmp r1, r0, lsl #7
343
subhs r1, r1,r0, lsl #7
344
addhs r3, r3,r2, lsl #7
345
.L_divide_b7:
346
cmp r1, r0, lsl #6
347
subhs r1, r1,r0, lsl #6
348
addhs r3, r3,r2, lsl #6
349
.L_divide_b6:
350
cmp r1, r0, lsl #5
351
subhs r1, r1,r0, lsl #5
352
addhs r3, r3,r2, lsl #5
353
.L_divide_b5:
354
cmp r1, r0, lsl #4
355
subhs r1, r1,r0, lsl #4
356
addhs r3, r3,r2, lsl #4
357
.L_divide_b4:
358
cmp r1, r0, lsl #3
359
subhs r1, r1,r0, lsl #3
360
addhs r3, r3,r2, lsl #3
361
.L_divide_b3:
362
cmp r1, r0, lsl #2
363
subhs r1, r1,r0, lsl #2
364
addhs r3, r3,r2, lsl #2
365
.L_divide_b2:
366
cmp r1, r0, lsl #1
367
subhs r1, r1,r0, lsl #1
368
addhs r3, r3,r2, lsl #1
369
.L_divide_b1:
370
cmp r1, r0
371
subhs r1, r1, r0
372
addhs r3, r3, r2
373
.L_divide_b0:
374
375
tst ip, #0x20000000
376
bne .L_udivide_l1
377
mov r0, r3
378
cmp ip, #0
379
rsbmi r1, r1, #0
380
movs ip, ip, lsl #1
381
bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */
382
rsbmi r0, r0, #0
383
RET
384
385
.L_udivide_l1:
386
tst ip, #0x10000000
387
mov r1, r1, lsl #1
388
orrne r1, r1, #1
389
mov r3, r3, lsl #1
390
cmp r1, r0
391
subhs r1, r1, r0
392
addhs r3, r3, r2
393
mov r0, r3
394
RET
395
EEND(__aeabi_idiv)
396
EEND(__aeabi_idivmod)
397
END(__divsi3)
398
399
400