]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - lib/libc/arm/gen/divsi3.S
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / lib / libc / arm / gen / divsi3.S
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 __FBSDID("$FreeBSD$");
19
20 /* 
21  * stack is aligned as there's a possibility of branching to L_overflow
22  * which makes a C call
23  */
24
25 ENTRY(__umodsi3)
26         stmfd   sp!, {lr}
27         sub     sp, sp, #4      /* align stack */
28         bl      .L_udivide
29         add     sp, sp, #4      /* unalign stack */
30         mov     r0, r1
31         ldmfd   sp!, {pc}
32 END(__umodsi3)
33
34 ENTRY(__modsi3)
35         stmfd   sp!, {lr}
36         sub     sp, sp, #4      /* align stack */
37         bl      .L_divide
38         add     sp, sp, #4      /* unalign stack */
39         mov     r0, r1
40         ldmfd   sp!, {pc}
41
42 .L_overflow:
43 #if !defined(_KERNEL) && !defined(_STANDALONE)
44         mov     r0, #8                  /* SIGFPE */
45         bl      PIC_SYM(_C_LABEL(raise), PLT)   /* raise it */
46         mov     r0, #0
47 #else
48         /* XXX should cause a fatal error */
49         mvn     r0, #0
50 #endif
51         RET
52 END(__modsi3)
53
54 ENTRY(__udivsi3)
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 END(__udivsi3)
76
77 ENTRY(__divsi3)
78 .L_divide:                              /* r0 = r0 / r1; r1 = r0 % r1 */
79         eor     r0, r1, r0 
80         eor     r1, r0, r1 
81         eor     r0, r1, r0 
82                                         /* r0 = r1 / r0; r1 = r1 % r0 */
83         cmp     r0, #1
84         bcc     .L_overflow
85         beq     .L_divide_l0
86         ands    ip, r0, #0x80000000
87         rsbmi   r0, r0, #0
88         ands    r2, r1, #0x80000000
89         eor     ip, ip, r2
90         rsbmi   r1, r1, #0
91         orr     ip, r2, ip, lsr #1      /* ip bit 0x40000000 = -ve division */
92                                         /* ip bit 0x80000000 = -ve remainder */
93
94 .L_divide_l1:
95         mov     r2, #1
96         mov     r3, #0
97
98         /*
99          * If the highest bit of the dividend is set, we have to be
100          * careful when shifting the divisor. Test this. 
101          */
102         movs    r1,r1
103         bpl     .L_old_code
104
105         /*
106          * At this point, the highest bit of r1 is known to be set.
107          * We abuse this below in the tst instructions.
108          */
109         tst     r1, r0 /*, lsl #0 */
110         bmi     .L_divide_b1
111         tst     r1, r0, lsl #1
112         bmi     .L_divide_b2
113         tst     r1, r0, lsl #2
114         bmi     .L_divide_b3
115         tst     r1, r0, lsl #3
116         bmi     .L_divide_b4
117         tst     r1, r0, lsl #4
118         bmi     .L_divide_b5
119         tst     r1, r0, lsl #5
120         bmi     .L_divide_b6
121         tst     r1, r0, lsl #6
122         bmi     .L_divide_b7
123         tst     r1, r0, lsl #7
124         bmi     .L_divide_b8
125         tst     r1, r0, lsl #8
126         bmi     .L_divide_b9
127         tst     r1, r0, lsl #9
128         bmi     .L_divide_b10
129         tst     r1, r0, lsl #10
130         bmi     .L_divide_b11
131         tst     r1, r0, lsl #11
132         bmi     .L_divide_b12
133         tst     r1, r0, lsl #12
134         bmi     .L_divide_b13
135         tst     r1, r0, lsl #13
136         bmi     .L_divide_b14
137         tst     r1, r0, lsl #14
138         bmi     .L_divide_b15
139         tst     r1, r0, lsl #15
140         bmi     .L_divide_b16
141         tst     r1, r0, lsl #16
142         bmi     .L_divide_b17
143         tst     r1, r0, lsl #17
144         bmi     .L_divide_b18
145         tst     r1, r0, lsl #18
146         bmi     .L_divide_b19
147         tst     r1, r0, lsl #19
148         bmi     .L_divide_b20
149         tst     r1, r0, lsl #20
150         bmi     .L_divide_b21
151         tst     r1, r0, lsl #21
152         bmi     .L_divide_b22
153         tst     r1, r0, lsl #22
154         bmi     .L_divide_b23
155         tst     r1, r0, lsl #23
156         bmi     .L_divide_b24
157         tst     r1, r0, lsl #24
158         bmi     .L_divide_b25
159         tst     r1, r0, lsl #25
160         bmi     .L_divide_b26
161         tst     r1, r0, lsl #26
162         bmi     .L_divide_b27
163         tst     r1, r0, lsl #27
164         bmi     .L_divide_b28
165         tst     r1, r0, lsl #28
166         bmi     .L_divide_b29
167         tst     r1, r0, lsl #29
168         bmi     .L_divide_b30
169         tst     r1, r0, lsl #30
170         bmi     .L_divide_b31
171 /*
172  * instead of:
173  *      tst     r1, r0, lsl #31
174  *      bmi     .L_divide_b32
175  */
176         b       .L_divide_b32
177
178 .L_old_code:
179         cmp     r1, r0
180         bcc     .L_divide_b0
181         cmp     r1, r0, lsl #1
182         bcc     .L_divide_b1
183         cmp     r1, r0, lsl #2
184         bcc     .L_divide_b2
185         cmp     r1, r0, lsl #3
186         bcc     .L_divide_b3
187         cmp     r1, r0, lsl #4
188         bcc     .L_divide_b4
189         cmp     r1, r0, lsl #5
190         bcc     .L_divide_b5
191         cmp     r1, r0, lsl #6
192         bcc     .L_divide_b6
193         cmp     r1, r0, lsl #7
194         bcc     .L_divide_b7
195         cmp     r1, r0, lsl #8
196         bcc     .L_divide_b8
197         cmp     r1, r0, lsl #9
198         bcc     .L_divide_b9
199         cmp     r1, r0, lsl #10
200         bcc     .L_divide_b10
201         cmp     r1, r0, lsl #11
202         bcc     .L_divide_b11
203         cmp     r1, r0, lsl #12
204         bcc     .L_divide_b12
205         cmp     r1, r0, lsl #13
206         bcc     .L_divide_b13
207         cmp     r1, r0, lsl #14
208         bcc     .L_divide_b14
209         cmp     r1, r0, lsl #15
210         bcc     .L_divide_b15
211         cmp     r1, r0, lsl #16
212         bcc     .L_divide_b16
213         cmp     r1, r0, lsl #17
214         bcc     .L_divide_b17
215         cmp     r1, r0, lsl #18
216         bcc     .L_divide_b18
217         cmp     r1, r0, lsl #19
218         bcc     .L_divide_b19
219         cmp     r1, r0, lsl #20
220         bcc     .L_divide_b20
221         cmp     r1, r0, lsl #21
222         bcc     .L_divide_b21
223         cmp     r1, r0, lsl #22
224         bcc     .L_divide_b22
225         cmp     r1, r0, lsl #23
226         bcc     .L_divide_b23
227         cmp     r1, r0, lsl #24
228         bcc     .L_divide_b24
229         cmp     r1, r0, lsl #25
230         bcc     .L_divide_b25
231         cmp     r1, r0, lsl #26
232         bcc     .L_divide_b26
233         cmp     r1, r0, lsl #27
234         bcc     .L_divide_b27
235         cmp     r1, r0, lsl #28
236         bcc     .L_divide_b28
237         cmp     r1, r0, lsl #29
238         bcc     .L_divide_b29
239         cmp     r1, r0, lsl #30
240         bcc     .L_divide_b30
241 .L_divide_b32:
242         cmp     r1, r0, lsl #31
243         subhs   r1, r1,r0, lsl #31
244         addhs   r3, r3,r2, lsl #31
245 .L_divide_b31:
246         cmp     r1, r0, lsl #30
247         subhs   r1, r1,r0, lsl #30
248         addhs   r3, r3,r2, lsl #30
249 .L_divide_b30:
250         cmp     r1, r0, lsl #29
251         subhs   r1, r1,r0, lsl #29
252         addhs   r3, r3,r2, lsl #29
253 .L_divide_b29:
254         cmp     r1, r0, lsl #28
255         subhs   r1, r1,r0, lsl #28
256         addhs   r3, r3,r2, lsl #28
257 .L_divide_b28:
258         cmp     r1, r0, lsl #27
259         subhs   r1, r1,r0, lsl #27
260         addhs   r3, r3,r2, lsl #27
261 .L_divide_b27:
262         cmp     r1, r0, lsl #26
263         subhs   r1, r1,r0, lsl #26
264         addhs   r3, r3,r2, lsl #26
265 .L_divide_b26:
266         cmp     r1, r0, lsl #25
267         subhs   r1, r1,r0, lsl #25
268         addhs   r3, r3,r2, lsl #25
269 .L_divide_b25:
270         cmp     r1, r0, lsl #24
271         subhs   r1, r1,r0, lsl #24
272         addhs   r3, r3,r2, lsl #24
273 .L_divide_b24:
274         cmp     r1, r0, lsl #23
275         subhs   r1, r1,r0, lsl #23
276         addhs   r3, r3,r2, lsl #23
277 .L_divide_b23:
278         cmp     r1, r0, lsl #22
279         subhs   r1, r1,r0, lsl #22
280         addhs   r3, r3,r2, lsl #22
281 .L_divide_b22:
282         cmp     r1, r0, lsl #21
283         subhs   r1, r1,r0, lsl #21
284         addhs   r3, r3,r2, lsl #21
285 .L_divide_b21:
286         cmp     r1, r0, lsl #20
287         subhs   r1, r1,r0, lsl #20
288         addhs   r3, r3,r2, lsl #20
289 .L_divide_b20:
290         cmp     r1, r0, lsl #19
291         subhs   r1, r1,r0, lsl #19
292         addhs   r3, r3,r2, lsl #19
293 .L_divide_b19:
294         cmp     r1, r0, lsl #18
295         subhs   r1, r1,r0, lsl #18
296         addhs   r3, r3,r2, lsl #18
297 .L_divide_b18:
298         cmp     r1, r0, lsl #17
299         subhs   r1, r1,r0, lsl #17
300         addhs   r3, r3,r2, lsl #17
301 .L_divide_b17:
302         cmp     r1, r0, lsl #16
303         subhs   r1, r1,r0, lsl #16
304         addhs   r3, r3,r2, lsl #16
305 .L_divide_b16:
306         cmp     r1, r0, lsl #15
307         subhs   r1, r1,r0, lsl #15
308         addhs   r3, r3,r2, lsl #15
309 .L_divide_b15:
310         cmp     r1, r0, lsl #14
311         subhs   r1, r1,r0, lsl #14
312         addhs   r3, r3,r2, lsl #14
313 .L_divide_b14:
314         cmp     r1, r0, lsl #13
315         subhs   r1, r1,r0, lsl #13
316         addhs   r3, r3,r2, lsl #13
317 .L_divide_b13:
318         cmp     r1, r0, lsl #12
319         subhs   r1, r1,r0, lsl #12
320         addhs   r3, r3,r2, lsl #12
321 .L_divide_b12:
322         cmp     r1, r0, lsl #11
323         subhs   r1, r1,r0, lsl #11
324         addhs   r3, r3,r2, lsl #11
325 .L_divide_b11:
326         cmp     r1, r0, lsl #10
327         subhs   r1, r1,r0, lsl #10
328         addhs   r3, r3,r2, lsl #10
329 .L_divide_b10:
330         cmp     r1, r0, lsl #9
331         subhs   r1, r1,r0, lsl #9
332         addhs   r3, r3,r2, lsl #9
333 .L_divide_b9:
334         cmp     r1, r0, lsl #8
335         subhs   r1, r1,r0, lsl #8
336         addhs   r3, r3,r2, lsl #8
337 .L_divide_b8:
338         cmp     r1, r0, lsl #7
339         subhs   r1, r1,r0, lsl #7
340         addhs   r3, r3,r2, lsl #7
341 .L_divide_b7:
342         cmp     r1, r0, lsl #6
343         subhs   r1, r1,r0, lsl #6
344         addhs   r3, r3,r2, lsl #6
345 .L_divide_b6:
346         cmp     r1, r0, lsl #5
347         subhs   r1, r1,r0, lsl #5
348         addhs   r3, r3,r2, lsl #5
349 .L_divide_b5:
350         cmp     r1, r0, lsl #4
351         subhs   r1, r1,r0, lsl #4
352         addhs   r3, r3,r2, lsl #4
353 .L_divide_b4:
354         cmp     r1, r0, lsl #3
355         subhs   r1, r1,r0, lsl #3
356         addhs   r3, r3,r2, lsl #3
357 .L_divide_b3:
358         cmp     r1, r0, lsl #2
359         subhs   r1, r1,r0, lsl #2
360         addhs   r3, r3,r2, lsl #2
361 .L_divide_b2:
362         cmp     r1, r0, lsl #1
363         subhs   r1, r1,r0, lsl #1
364         addhs   r3, r3,r2, lsl #1
365 .L_divide_b1:
366         cmp     r1, r0
367         subhs   r1, r1, r0
368         addhs   r3, r3, r2
369 .L_divide_b0:
370
371         tst     ip, #0x20000000
372         bne     .L_udivide_l1
373         mov     r0, r3
374         cmp     ip, #0
375         rsbmi   r1, r1, #0
376         movs    ip, ip, lsl #1
377         bicmi   r0, r0, #0x80000000     /* Fix incase we divided 0x80000000 */
378         rsbmi   r0, r0, #0
379         RET
380
381 .L_udivide_l1:
382         tst     ip, #0x10000000
383         mov     r1, r1, lsl #1
384         orrne   r1, r1, #1
385         mov     r3, r3, lsl #1
386         cmp     r1, r0
387         subhs   r1, r1, r0
388         addhs   r3, r3, r2
389         mov     r0, r3
390         RET
391 END(__divsi3)