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