xref: /netbsd-src/sys/external/bsd/compiler_rt/dist/lib/builtins/arm/divsi3.S (revision f6e43b3179e19718c2af5950ddbd1384060c23e7)
1156cd587Sjoerg/*===-- divsi3.S - 32-bit signed integer divide ---------------------------===//
2156cd587Sjoerg *
3156cd587Sjoerg *                     The LLVM Compiler Infrastructure
4156cd587Sjoerg *
5156cd587Sjoerg * This file is dual licensed under the MIT and the University of Illinois Open
6156cd587Sjoerg * Source Licenses. See LICENSE.TXT for details.
7156cd587Sjoerg *
8156cd587Sjoerg *===----------------------------------------------------------------------===//
9156cd587Sjoerg *
10156cd587Sjoerg * This file implements the __divsi3 (32-bit signed integer divide) function
11156cd587Sjoerg * for the ARM architecture as a wrapper around the unsigned routine.
12156cd587Sjoerg *
13156cd587Sjoerg *===----------------------------------------------------------------------===*/
14156cd587Sjoerg
15156cd587Sjoerg#include "../assembly.h"
16156cd587Sjoerg
17156cd587Sjoerg#define ESTABLISH_FRAME \
18*f6e43b31Sskrll    push   {r4, lr}
19156cd587Sjoerg#define CLEAR_FRAME_AND_RETURN \
20*f6e43b31Sskrll    pop    {r4, pc}
21156cd587Sjoerg
22156cd587Sjoerg	.syntax unified
23190e92d8Sjoerg	.text
24190e92d8Sjoerg#if __ARM_ARCH_ISA_THUMB == 2
25190e92d8Sjoerg	.thumb
26190e92d8Sjoerg#endif
27190e92d8Sjoerg
2861f2f256Sjoerg	.p2align 3
29156cd587Sjoerg// Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine.
30156cd587SjoergDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_idiv, __divsi3)
31190e92d8Sjoerg
32190e92d8Sjoerg@ int __divsi3(int divident, int divisor)
33190e92d8Sjoerg@   Calculate and return the quotient of the (signed) division.
34190e92d8Sjoerg
35ef84fd3bSjoerg#if __ARM_ARCH_ISA_THUMB == 2
36ef84fd3bSjoergDEFINE_COMPILERRT_THUMB_FUNCTION(__divsi3)
37ef84fd3bSjoerg#else
38156cd587SjoergDEFINE_COMPILERRT_FUNCTION(__divsi3)
39ef84fd3bSjoerg#endif
40156cd587Sjoerg#if __ARM_ARCH_EXT_IDIV__
41156cd587Sjoerg   tst     r1,r1
42156cd587Sjoerg   beq     LOCAL_LABEL(divzero)
43156cd587Sjoerg   sdiv    r0, r0, r1
44156cd587Sjoerg   bx      lr
45156cd587SjoergLOCAL_LABEL(divzero):
46156cd587Sjoerg   mov     r0,#0
47156cd587Sjoerg   bx      lr
48156cd587Sjoerg#else
49156cd587SjoergESTABLISH_FRAME
50156cd587Sjoerg//  Set aside the sign of the quotient.
51156cd587Sjoerg    eor     r4,     r0, r1
52156cd587Sjoerg//  Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
53156cd587Sjoerg    eor     r2,     r0, r0, asr #31
54156cd587Sjoerg    eor     r3,     r1, r1, asr #31
55156cd587Sjoerg    sub     r0,     r2, r0, asr #31
56156cd587Sjoerg    sub     r1,     r3, r1, asr #31
57156cd587Sjoerg//  abs(a) / abs(b)
58156cd587Sjoerg    bl      SYMBOL_NAME(__udivsi3)
59156cd587Sjoerg//  Apply sign of quotient to result and return.
60156cd587Sjoerg    eor     r0,     r0, r4, asr #31
61156cd587Sjoerg    sub     r0,     r0, r4, asr #31
62156cd587Sjoerg    CLEAR_FRAME_AND_RETURN
63156cd587Sjoerg#endif
64156cd587SjoergEND_COMPILERRT_FUNCTION(__divsi3)
65