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