1*3cab2bb3Spatrick//===-- modsi3.S - 32-bit signed integer modulus --------------------------===// 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 __modsi3 (32-bit signed integer modulus) 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@ int __modsi3(int divident, int divisor) 27*3cab2bb3Spatrick@ Calculate and return the remainder of the (signed) division. 28*3cab2bb3Spatrick 29*3cab2bb3Spatrick .p2align 3 30*3cab2bb3SpatrickDEFINE_COMPILERRT_FUNCTION(__modsi3) 31*3cab2bb3Spatrick#if __ARM_ARCH_EXT_IDIV__ 32*3cab2bb3Spatrick tst r1, r1 33*3cab2bb3Spatrick beq LOCAL_LABEL(divzero) 34*3cab2bb3Spatrick sdiv r2, r0, r1 35*3cab2bb3Spatrick mls r0, r2, r1, r0 36*3cab2bb3Spatrick bx lr 37*3cab2bb3SpatrickLOCAL_LABEL(divzero): 38*3cab2bb3Spatrick mov r0, #0 39*3cab2bb3Spatrick bx lr 40*3cab2bb3Spatrick#else 41*3cab2bb3Spatrick ESTABLISH_FRAME 42*3cab2bb3Spatrick // Set aside the sign of the dividend. 43*3cab2bb3Spatrick mov r4, r0 44*3cab2bb3Spatrick // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). 45*3cab2bb3Spatrick eor r2, r0, r0, asr #31 46*3cab2bb3Spatrick eor r3, r1, r1, asr #31 47*3cab2bb3Spatrick sub r0, r2, r0, asr #31 48*3cab2bb3Spatrick sub r1, r3, r1, asr #31 49*3cab2bb3Spatrick // abs(a) % abs(b) 50*3cab2bb3Spatrick bl SYMBOL_NAME(__umodsi3) 51*3cab2bb3Spatrick // Apply sign of dividend to result and return. 52*3cab2bb3Spatrick eor r0, r0, r4, asr #31 53*3cab2bb3Spatrick sub r0, r0, r4, asr #31 54*3cab2bb3Spatrick CLEAR_FRAME_AND_RETURN 55*3cab2bb3Spatrick#endif 56*3cab2bb3SpatrickEND_COMPILERRT_FUNCTION(__modsi3) 57*3cab2bb3Spatrick 58*3cab2bb3SpatrickNO_EXEC_STACK_DIRECTIVE 59*3cab2bb3Spatrick 60