1 /* $NetBSD: divsi3.S,v 1.4 2003/04/05 23:27:15 bjh21 Exp $ */
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
17 #include <machine/asm.h>
18 __FBSDID("$FreeBSD$");
21 * stack is aligned as there's a possibility of branching to L_overflow
22 * which makes a C call
27 sub sp, sp, #4 /* align stack */
29 add sp, sp, #4 /* unalign stack */
36 sub sp, sp, #4 /* align stack */
38 add sp, sp, #4 /* unalign stack */
43 #if !defined(_KERNEL) && !defined(_STANDALONE)
44 mov r0, #8 /* SIGFPE */
45 bl PIC_SYM(_C_LABEL(raise), PLT) /* raise it */
48 /* XXX should cause a fatal error */
55 EENTRY_NP(__aeabi_uidiv)
56 EENTRY_NP(__aeabi_uidivmod)
57 .L_udivide: /* r0 = r0 / r1; r1 = r0 % r1 */
61 /* r0 = r1 / r0; r1 = r1 % r0 */
68 orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */
70 orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */
73 .L_divide_l0: /* r0 == 1 */
78 EEND(__aeabi_uidivmod)
82 EENTRY_NP(__aeabi_idiv)
83 EENTRY_NP(__aeabi_idivmod)
84 .L_divide: /* r0 = r0 / r1; r1 = r0 % r1 */
88 /* r0 = r1 / r0; r1 = r1 % r0 */
92 ands ip, r0, #0x80000000
94 ands r2, r1, #0x80000000
97 orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */
98 /* ip bit 0x80000000 = -ve remainder */
105 * If the highest bit of the dividend is set, we have to be
106 * careful when shifting the divisor. Test this.
112 * At this point, the highest bit of r1 is known to be set.
113 * We abuse this below in the tst instructions.
115 tst r1, r0 /*, lsl #0 */
179 * tst r1, r0, lsl #31
249 subhs r1, r1,r0, lsl #31
250 addhs r3, r3,r2, lsl #31
253 subhs r1, r1,r0, lsl #30
254 addhs r3, r3,r2, lsl #30
257 subhs r1, r1,r0, lsl #29
258 addhs r3, r3,r2, lsl #29
261 subhs r1, r1,r0, lsl #28
262 addhs r3, r3,r2, lsl #28
265 subhs r1, r1,r0, lsl #27
266 addhs r3, r3,r2, lsl #27
269 subhs r1, r1,r0, lsl #26
270 addhs r3, r3,r2, lsl #26
273 subhs r1, r1,r0, lsl #25
274 addhs r3, r3,r2, lsl #25
277 subhs r1, r1,r0, lsl #24
278 addhs r3, r3,r2, lsl #24
281 subhs r1, r1,r0, lsl #23
282 addhs r3, r3,r2, lsl #23
285 subhs r1, r1,r0, lsl #22
286 addhs r3, r3,r2, lsl #22
289 subhs r1, r1,r0, lsl #21
290 addhs r3, r3,r2, lsl #21
293 subhs r1, r1,r0, lsl #20
294 addhs r3, r3,r2, lsl #20
297 subhs r1, r1,r0, lsl #19
298 addhs r3, r3,r2, lsl #19
301 subhs r1, r1,r0, lsl #18
302 addhs r3, r3,r2, lsl #18
305 subhs r1, r1,r0, lsl #17
306 addhs r3, r3,r2, lsl #17
309 subhs r1, r1,r0, lsl #16
310 addhs r3, r3,r2, lsl #16
313 subhs r1, r1,r0, lsl #15
314 addhs r3, r3,r2, lsl #15
317 subhs r1, r1,r0, lsl #14
318 addhs r3, r3,r2, lsl #14
321 subhs r1, r1,r0, lsl #13
322 addhs r3, r3,r2, lsl #13
325 subhs r1, r1,r0, lsl #12
326 addhs r3, r3,r2, lsl #12
329 subhs r1, r1,r0, lsl #11
330 addhs r3, r3,r2, lsl #11
333 subhs r1, r1,r0, lsl #10
334 addhs r3, r3,r2, lsl #10
337 subhs r1, r1,r0, lsl #9
338 addhs r3, r3,r2, lsl #9
341 subhs r1, r1,r0, lsl #8
342 addhs r3, r3,r2, lsl #8
345 subhs r1, r1,r0, lsl #7
346 addhs r3, r3,r2, lsl #7
349 subhs r1, r1,r0, lsl #6
350 addhs r3, r3,r2, lsl #6
353 subhs r1, r1,r0, lsl #5
354 addhs r3, r3,r2, lsl #5
357 subhs r1, r1,r0, lsl #4
358 addhs r3, r3,r2, lsl #4
361 subhs r1, r1,r0, lsl #3
362 addhs r3, r3,r2, lsl #3
365 subhs r1, r1,r0, lsl #2
366 addhs r3, r3,r2, lsl #2
369 subhs r1, r1,r0, lsl #1
370 addhs r3, r3,r2, lsl #1
383 bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */
398 EEND(__aeabi_idivmod)