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