1//===-- divsi3.S - 32-bit signed integer divide ---------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the __divsi3 (32-bit signed integer divide) function
10// for the ARM architecture as a wrapper around the unsigned routine.
11//
12//===----------------------------------------------------------------------===//
13
14#include "../assembly.h"
15
16#define ESTABLISH_FRAME \
17 push {r4, r7, lr} ;\
18 add r7, sp, #4
19#define CLEAR_FRAME_AND_RETURN \
20 pop {r4, r7, pc}
21
22 .syntax unified
23 .text
24 DEFINE_CODE_STATE
25
26 .p2align 3
27// Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine.
28DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_idiv, __divsi3)
29
30@ int __divsi3(int divident, int divisor)
31@ Calculate and return the quotient of the (signed) division.
32
33DEFINE_COMPILERRT_FUNCTION(__divsi3)
34#if __ARM_ARCH_EXT_IDIV__
35 tst r1,r1
36 beq LOCAL_LABEL(divzero)
37 sdiv r0, r0, r1
38 bx lr
39LOCAL_LABEL(divzero):
40 // Use movs for compatibility with v8-m.base.
41 movs r0,#0
42 bx lr
43#else
44ESTABLISH_FRAME
45// Set aside the sign of the quotient.
46# if defined(USE_THUMB_1)
47 movs r4, r0
48 eors r4, r1
49# else
50 eor r4, r0, r1
51# endif
52// Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
53# if defined(USE_THUMB_1)
54 asrs r2, r0, #31
55 asrs r3, r1, #31
56 eors r0, r2
57 eors r1, r3
58 subs r0, r0, r2
59 subs r1, r1, r3
60# else
61 eor r2, r0, r0, asr #31
62 eor r3, r1, r1, asr #31
63 sub r0, r2, r0, asr #31
64 sub r1, r3, r1, asr #31
65# endif
66// abs(a) / abs(b)
67 bl SYMBOL_NAME(__udivsi3)
68// Apply sign of quotient to result and return.
69# if defined(USE_THUMB_1)
70 asrs r4, #31
71 eors r0, r4
72 subs r0, r0, r4
73# else
74 eor r0, r0, r4, asr #31
75 sub r0, r0, r4, asr #31
76# endif
77 CLEAR_FRAME_AND_RETURN
78#endif
79END_COMPILERRT_FUNCTION(__divsi3)
80
81NO_EXEC_STACK_DIRECTIVE
82
83

source code of compiler-rt/lib/builtins/arm/divsi3.S