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 mov r0,#0 41 bx lr 42#else 43ESTABLISH_FRAME 44// Set aside the sign of the quotient. 45# if defined(USE_THUMB_1) 46 movs r4, r0 47 eors r4, r1 48# else 49 eor r4, r0, r1 50# endif 51// Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). 52# if defined(USE_THUMB_1) 53 asrs r2, r0, #31 54 asrs r3, r1, #31 55 eors r0, r2 56 eors r1, r3 57 subs r0, r0, r2 58 subs r1, r1, r3 59# else 60 eor r2, r0, r0, asr #31 61 eor r3, r1, r1, asr #31 62 sub r0, r2, r0, asr #31 63 sub r1, r3, r1, asr #31 64# endif 65// abs(a) / abs(b) 66 bl SYMBOL_NAME(__udivsi3) 67// Apply sign of quotient to result and return. 68# if defined(USE_THUMB_1) 69 asrs r4, #31 70 eors r0, r4 71 subs r0, r0, r4 72# else 73 eor r0, r0, r4, asr #31 74 sub r0, r0, r4, asr #31 75# endif 76 CLEAR_FRAME_AND_RETURN 77#endif 78END_COMPILERRT_FUNCTION(__divsi3) 79 80NO_EXEC_STACK_DIRECTIVE 81 82