Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/arm/gen/divsi3.S
39534 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(__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(__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(__udivsi3)
53
.L_udivide: /* r0 = r0 / r1; r1 = r0 % r1 */
54
eor r0, r1, r0
55
eor r1, r0, r1
56
eor r0, r1, r0
57
/* r0 = r1 / r0; r1 = r1 % r0 */
58
cmp r0, #1
59
bcc .L_overflow
60
beq .L_divide_l0
61
mov ip, #0
62
movs r1, r1
63
bpl .L_divide_l1
64
orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */
65
movs r1, r1, lsr #1
66
orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */
67
b .L_divide_l1
68
69
.L_divide_l0: /* r0 == 1 */
70
mov r0, r1
71
mov r1, #0
72
RET
73
END(__udivsi3)
74
75
ENTRY(__divsi3)
76
.L_divide: /* r0 = r0 / r1; r1 = r0 % r1 */
77
eor r0, r1, r0
78
eor r1, r0, r1
79
eor r0, r1, r0
80
/* r0 = r1 / r0; r1 = r1 % r0 */
81
cmp r0, #1
82
bcc .L_overflow
83
beq .L_divide_l0
84
ands ip, r0, #0x80000000
85
rsbmi r0, r0, #0
86
ands r2, r1, #0x80000000
87
eor ip, ip, r2
88
rsbmi r1, r1, #0
89
orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */
90
/* ip bit 0x80000000 = -ve remainder */
91
92
.L_divide_l1:
93
mov r2, #1
94
mov r3, #0
95
96
/*
97
* If the highest bit of the dividend is set, we have to be
98
* careful when shifting the divisor. Test this.
99
*/
100
movs r1,r1
101
bpl .L_old_code
102
103
/*
104
* At this point, the highest bit of r1 is known to be set.
105
* We abuse this below in the tst instructions.
106
*/
107
tst r1, r0 /*, lsl #0 */
108
bmi .L_divide_b1
109
tst r1, r0, lsl #1
110
bmi .L_divide_b2
111
tst r1, r0, lsl #2
112
bmi .L_divide_b3
113
tst r1, r0, lsl #3
114
bmi .L_divide_b4
115
tst r1, r0, lsl #4
116
bmi .L_divide_b5
117
tst r1, r0, lsl #5
118
bmi .L_divide_b6
119
tst r1, r0, lsl #6
120
bmi .L_divide_b7
121
tst r1, r0, lsl #7
122
bmi .L_divide_b8
123
tst r1, r0, lsl #8
124
bmi .L_divide_b9
125
tst r1, r0, lsl #9
126
bmi .L_divide_b10
127
tst r1, r0, lsl #10
128
bmi .L_divide_b11
129
tst r1, r0, lsl #11
130
bmi .L_divide_b12
131
tst r1, r0, lsl #12
132
bmi .L_divide_b13
133
tst r1, r0, lsl #13
134
bmi .L_divide_b14
135
tst r1, r0, lsl #14
136
bmi .L_divide_b15
137
tst r1, r0, lsl #15
138
bmi .L_divide_b16
139
tst r1, r0, lsl #16
140
bmi .L_divide_b17
141
tst r1, r0, lsl #17
142
bmi .L_divide_b18
143
tst r1, r0, lsl #18
144
bmi .L_divide_b19
145
tst r1, r0, lsl #19
146
bmi .L_divide_b20
147
tst r1, r0, lsl #20
148
bmi .L_divide_b21
149
tst r1, r0, lsl #21
150
bmi .L_divide_b22
151
tst r1, r0, lsl #22
152
bmi .L_divide_b23
153
tst r1, r0, lsl #23
154
bmi .L_divide_b24
155
tst r1, r0, lsl #24
156
bmi .L_divide_b25
157
tst r1, r0, lsl #25
158
bmi .L_divide_b26
159
tst r1, r0, lsl #26
160
bmi .L_divide_b27
161
tst r1, r0, lsl #27
162
bmi .L_divide_b28
163
tst r1, r0, lsl #28
164
bmi .L_divide_b29
165
tst r1, r0, lsl #29
166
bmi .L_divide_b30
167
tst r1, r0, lsl #30
168
bmi .L_divide_b31
169
/*
170
* instead of:
171
* tst r1, r0, lsl #31
172
* bmi .L_divide_b32
173
*/
174
b .L_divide_b32
175
176
.L_old_code:
177
cmp r1, r0
178
bcc .L_divide_b0
179
cmp r1, r0, lsl #1
180
bcc .L_divide_b1
181
cmp r1, r0, lsl #2
182
bcc .L_divide_b2
183
cmp r1, r0, lsl #3
184
bcc .L_divide_b3
185
cmp r1, r0, lsl #4
186
bcc .L_divide_b4
187
cmp r1, r0, lsl #5
188
bcc .L_divide_b5
189
cmp r1, r0, lsl #6
190
bcc .L_divide_b6
191
cmp r1, r0, lsl #7
192
bcc .L_divide_b7
193
cmp r1, r0, lsl #8
194
bcc .L_divide_b8
195
cmp r1, r0, lsl #9
196
bcc .L_divide_b9
197
cmp r1, r0, lsl #10
198
bcc .L_divide_b10
199
cmp r1, r0, lsl #11
200
bcc .L_divide_b11
201
cmp r1, r0, lsl #12
202
bcc .L_divide_b12
203
cmp r1, r0, lsl #13
204
bcc .L_divide_b13
205
cmp r1, r0, lsl #14
206
bcc .L_divide_b14
207
cmp r1, r0, lsl #15
208
bcc .L_divide_b15
209
cmp r1, r0, lsl #16
210
bcc .L_divide_b16
211
cmp r1, r0, lsl #17
212
bcc .L_divide_b17
213
cmp r1, r0, lsl #18
214
bcc .L_divide_b18
215
cmp r1, r0, lsl #19
216
bcc .L_divide_b19
217
cmp r1, r0, lsl #20
218
bcc .L_divide_b20
219
cmp r1, r0, lsl #21
220
bcc .L_divide_b21
221
cmp r1, r0, lsl #22
222
bcc .L_divide_b22
223
cmp r1, r0, lsl #23
224
bcc .L_divide_b23
225
cmp r1, r0, lsl #24
226
bcc .L_divide_b24
227
cmp r1, r0, lsl #25
228
bcc .L_divide_b25
229
cmp r1, r0, lsl #26
230
bcc .L_divide_b26
231
cmp r1, r0, lsl #27
232
bcc .L_divide_b27
233
cmp r1, r0, lsl #28
234
bcc .L_divide_b28
235
cmp r1, r0, lsl #29
236
bcc .L_divide_b29
237
cmp r1, r0, lsl #30
238
bcc .L_divide_b30
239
.L_divide_b32:
240
cmp r1, r0, lsl #31
241
subhs r1, r1,r0, lsl #31
242
addhs r3, r3,r2, lsl #31
243
.L_divide_b31:
244
cmp r1, r0, lsl #30
245
subhs r1, r1,r0, lsl #30
246
addhs r3, r3,r2, lsl #30
247
.L_divide_b30:
248
cmp r1, r0, lsl #29
249
subhs r1, r1,r0, lsl #29
250
addhs r3, r3,r2, lsl #29
251
.L_divide_b29:
252
cmp r1, r0, lsl #28
253
subhs r1, r1,r0, lsl #28
254
addhs r3, r3,r2, lsl #28
255
.L_divide_b28:
256
cmp r1, r0, lsl #27
257
subhs r1, r1,r0, lsl #27
258
addhs r3, r3,r2, lsl #27
259
.L_divide_b27:
260
cmp r1, r0, lsl #26
261
subhs r1, r1,r0, lsl #26
262
addhs r3, r3,r2, lsl #26
263
.L_divide_b26:
264
cmp r1, r0, lsl #25
265
subhs r1, r1,r0, lsl #25
266
addhs r3, r3,r2, lsl #25
267
.L_divide_b25:
268
cmp r1, r0, lsl #24
269
subhs r1, r1,r0, lsl #24
270
addhs r3, r3,r2, lsl #24
271
.L_divide_b24:
272
cmp r1, r0, lsl #23
273
subhs r1, r1,r0, lsl #23
274
addhs r3, r3,r2, lsl #23
275
.L_divide_b23:
276
cmp r1, r0, lsl #22
277
subhs r1, r1,r0, lsl #22
278
addhs r3, r3,r2, lsl #22
279
.L_divide_b22:
280
cmp r1, r0, lsl #21
281
subhs r1, r1,r0, lsl #21
282
addhs r3, r3,r2, lsl #21
283
.L_divide_b21:
284
cmp r1, r0, lsl #20
285
subhs r1, r1,r0, lsl #20
286
addhs r3, r3,r2, lsl #20
287
.L_divide_b20:
288
cmp r1, r0, lsl #19
289
subhs r1, r1,r0, lsl #19
290
addhs r3, r3,r2, lsl #19
291
.L_divide_b19:
292
cmp r1, r0, lsl #18
293
subhs r1, r1,r0, lsl #18
294
addhs r3, r3,r2, lsl #18
295
.L_divide_b18:
296
cmp r1, r0, lsl #17
297
subhs r1, r1,r0, lsl #17
298
addhs r3, r3,r2, lsl #17
299
.L_divide_b17:
300
cmp r1, r0, lsl #16
301
subhs r1, r1,r0, lsl #16
302
addhs r3, r3,r2, lsl #16
303
.L_divide_b16:
304
cmp r1, r0, lsl #15
305
subhs r1, r1,r0, lsl #15
306
addhs r3, r3,r2, lsl #15
307
.L_divide_b15:
308
cmp r1, r0, lsl #14
309
subhs r1, r1,r0, lsl #14
310
addhs r3, r3,r2, lsl #14
311
.L_divide_b14:
312
cmp r1, r0, lsl #13
313
subhs r1, r1,r0, lsl #13
314
addhs r3, r3,r2, lsl #13
315
.L_divide_b13:
316
cmp r1, r0, lsl #12
317
subhs r1, r1,r0, lsl #12
318
addhs r3, r3,r2, lsl #12
319
.L_divide_b12:
320
cmp r1, r0, lsl #11
321
subhs r1, r1,r0, lsl #11
322
addhs r3, r3,r2, lsl #11
323
.L_divide_b11:
324
cmp r1, r0, lsl #10
325
subhs r1, r1,r0, lsl #10
326
addhs r3, r3,r2, lsl #10
327
.L_divide_b10:
328
cmp r1, r0, lsl #9
329
subhs r1, r1,r0, lsl #9
330
addhs r3, r3,r2, lsl #9
331
.L_divide_b9:
332
cmp r1, r0, lsl #8
333
subhs r1, r1,r0, lsl #8
334
addhs r3, r3,r2, lsl #8
335
.L_divide_b8:
336
cmp r1, r0, lsl #7
337
subhs r1, r1,r0, lsl #7
338
addhs r3, r3,r2, lsl #7
339
.L_divide_b7:
340
cmp r1, r0, lsl #6
341
subhs r1, r1,r0, lsl #6
342
addhs r3, r3,r2, lsl #6
343
.L_divide_b6:
344
cmp r1, r0, lsl #5
345
subhs r1, r1,r0, lsl #5
346
addhs r3, r3,r2, lsl #5
347
.L_divide_b5:
348
cmp r1, r0, lsl #4
349
subhs r1, r1,r0, lsl #4
350
addhs r3, r3,r2, lsl #4
351
.L_divide_b4:
352
cmp r1, r0, lsl #3
353
subhs r1, r1,r0, lsl #3
354
addhs r3, r3,r2, lsl #3
355
.L_divide_b3:
356
cmp r1, r0, lsl #2
357
subhs r1, r1,r0, lsl #2
358
addhs r3, r3,r2, lsl #2
359
.L_divide_b2:
360
cmp r1, r0, lsl #1
361
subhs r1, r1,r0, lsl #1
362
addhs r3, r3,r2, lsl #1
363
.L_divide_b1:
364
cmp r1, r0
365
subhs r1, r1, r0
366
addhs r3, r3, r2
367
.L_divide_b0:
368
369
tst ip, #0x20000000
370
bne .L_udivide_l1
371
mov r0, r3
372
cmp ip, #0
373
rsbmi r1, r1, #0
374
movs ip, ip, lsl #1
375
bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */
376
rsbmi r0, r0, #0
377
RET
378
379
.L_udivide_l1:
380
tst ip, #0x10000000
381
mov r1, r1, lsl #1
382
orrne r1, r1, #1
383
mov r3, r3, lsl #1
384
cmp r1, r0
385
subhs r1, r1, r0
386
addhs r3, r3, r2
387
mov r0, r3
388
RET
389
END(__divsi3)
390
391
.section .note.GNU-stack,"",%progbits
392
393