1353358Sdim//===-- divsi3.S - 32-bit signed integer divide ---------------------------===// 2353358Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6353358Sdim// 7353358Sdim//===----------------------------------------------------------------------===// 8353358Sdim// 9353358Sdim// This file implements the __divsi3 (32-bit signed integer divide) function 10353358Sdim// for the ARM architecture as a wrapper around the unsigned routine. 11353358Sdim// 12353358Sdim//===----------------------------------------------------------------------===// 13276789Sdim 14276789Sdim#include "../assembly.h" 15276789Sdim 16276789Sdim#define ESTABLISH_FRAME \ 17276789Sdim push {r4, r7, lr} ;\ 18276789Sdim add r7, sp, #4 19276789Sdim#define CLEAR_FRAME_AND_RETURN \ 20276789Sdim pop {r4, r7, pc} 21276789Sdim 22316005Sdim .syntax unified 23316005Sdim .text 24327952Sdim DEFINE_CODE_STATE 25276789Sdim 26276789Sdim .p2align 3 27276789Sdim// Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine. 28276789SdimDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_idiv, __divsi3) 29276789Sdim 30276789Sdim@ int __divsi3(int divident, int divisor) 31276789Sdim@ Calculate and return the quotient of the (signed) division. 32276789Sdim 33276789SdimDEFINE_COMPILERRT_FUNCTION(__divsi3) 34276789Sdim#if __ARM_ARCH_EXT_IDIV__ 35276789Sdim tst r1,r1 36276789Sdim beq LOCAL_LABEL(divzero) 37276789Sdim sdiv r0, r0, r1 38276789Sdim bx lr 39276789SdimLOCAL_LABEL(divzero): 40276789Sdim mov r0,#0 41276789Sdim bx lr 42276789Sdim#else 43276789SdimESTABLISH_FRAME 44276789Sdim// Set aside the sign of the quotient. 45327952Sdim# if defined(USE_THUMB_1) 46314564Sdim movs r4, r0 47314564Sdim eors r4, r1 48314564Sdim# else 49276789Sdim eor r4, r0, r1 50314564Sdim# endif 51276789Sdim// Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). 52327952Sdim# if defined(USE_THUMB_1) 53314564Sdim asrs r2, r0, #31 54314564Sdim asrs r3, r1, #31 55314564Sdim eors r0, r2 56314564Sdim eors r1, r3 57314564Sdim subs r0, r0, r2 58314564Sdim subs r1, r1, r3 59314564Sdim# else 60276789Sdim eor r2, r0, r0, asr #31 61276789Sdim eor r3, r1, r1, asr #31 62276789Sdim sub r0, r2, r0, asr #31 63276789Sdim sub r1, r3, r1, asr #31 64314564Sdim# endif 65276789Sdim// abs(a) / abs(b) 66276789Sdim bl SYMBOL_NAME(__udivsi3) 67276789Sdim// Apply sign of quotient to result and return. 68316005Sdim# if defined(USE_THUMB_1) 69314564Sdim asrs r4, #31 70314564Sdim eors r0, r4 71314564Sdim subs r0, r0, r4 72314564Sdim# else 73276789Sdim eor r0, r0, r4, asr #31 74276789Sdim sub r0, r0, r4, asr #31 75314564Sdim# endif 76276789Sdim CLEAR_FRAME_AND_RETURN 77276789Sdim#endif 78276789SdimEND_COMPILERRT_FUNCTION(__divsi3) 79309124Sdim 80309124SdimNO_EXEC_STACK_DIRECTIVE 81309124Sdim 82