modsi3.S revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan/*===-- modsi3.S - 32-bit signed integer modulus --------------------------===// 247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan * 347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan * The LLVM Compiler Infrastructure 447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan * 547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan * This file is dual licensed under the MIT and the University of Illinois Open 647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan * Source Licenses. See LICENSE.TXT for details. 747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan * 847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan *===----------------------------------------------------------------------===// 947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan * 1047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan * This file implements the __modsi3 (32-bit signed integer modulus) function 1147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan * for the ARM architecture as a wrapper around the unsigned routine. 1247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan * 1347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan *===----------------------------------------------------------------------===*/ 1452d0d027dd38518e4b0cfb135a5d50a6652c5dafSean Callanan 1547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan#include "../assembly.h" 1647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan 1747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan#define ESTABLISH_FRAME \ 1847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan push {r4, r7, lr} ;\ 1947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan add r7, sp, #4 2047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan#define CLEAR_FRAME_AND_RETURN \ 2147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan pop {r4, r7, pc} 2247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan 233051ed73a487e92f12f8b6062f8415781453da21Micah Villmow.syntax unified 2447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan.p2align 3 2547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean CallananDEFINE_COMPILERRT_FUNCTION(__modsi3) 2647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan#if __ARM_ARCH_EXT_IDIV__ 2747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan tst r1, r1 2847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan beq LOCAL_LABEL(divzero) 2947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan sdiv r2, r0, r1 3047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan mls r0, r2, r1, r0 3147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan bx lr 3247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean CallananLOCAL_LABEL(divzero): 3347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan mov r0, #0 3447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan bx lr 3547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan#else 3647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan ESTABLISH_FRAME 3747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan // Set aside the sign of the dividend. 3847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan mov r4, r0 3947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). 4047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan eor r2, r0, r0, asr #31 4147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan eor r3, r1, r1, asr #31 4247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan sub r0, r2, r0, asr #31 4347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan sub r1, r3, r1, asr #31 4447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan // abs(a) % abs(b) 4547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan bl SYMBOL_NAME(__umodsi3) 4647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan // Apply sign of dividend to result and return. 4747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan eor r0, r0, r4, asr #31 4847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan sub r0, r0, r4, asr #31 4947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan CLEAR_FRAME_AND_RETURN 5047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan#endif 5147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean CallananEND_COMPILERRT_FUNCTION(__modsi3) 5247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan