16bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon/*===-- modsi3.S - 32-bit signed integer modulus --------------------------===// 26bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * 36bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * The LLVM Compiler Infrastructure 46bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * 56bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * This file is dual licensed under the MIT and the University of Illinois Open 66bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * Source Licenses. See LICENSE.TXT for details. 76bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * 86bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon *===----------------------------------------------------------------------===// 96bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * 106bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * This file implements the __modsi3 (32-bit signed integer modulus) function 116bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * for the ARM architecture as a wrapper around the unsigned routine. 126bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * 136bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon *===----------------------------------------------------------------------===*/ 14dada27592510a7f922a3198fd1dff1e391734182Nick Kledzik 15dada27592510a7f922a3198fd1dff1e391734182Nick Kledzik#include "../assembly.h" 16dada27592510a7f922a3198fd1dff1e391734182Nick Kledzik 176bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon#define ESTABLISH_FRAME \ 186bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon push {r4, r7, lr} ;\ 196bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon add r7, sp, #4 206bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon#define CLEAR_FRAME_AND_RETURN \ 216bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon pop {r4, r7, pc} 22dada27592510a7f922a3198fd1dff1e391734182Nick Kledzik 236bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon.syntax unified 246bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon.align 3 256bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen CanonDEFINE_COMPILERRT_FUNCTION(__modsi3) 26a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik#if __ARM_ARCH_7S__ 27a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik tst r1, r1 28a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik beq LOCAL_LABEL(divzero) 29a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik sdiv r2, r0, r1 30a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik mls r0, r2, r1, r0 31a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik bx lr 32a09d09d29e250e905bdfaf819979b9c3e9adc047Nick KledzikLOCAL_LABEL(divzero): 33a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik mov r0, #0 34a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik bx lr 35a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik#else 366bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon ESTABLISH_FRAME 376bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon // Set aside the sign of the dividend. 386bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon mov r4, r0 396bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). 406bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon eor r2, r0, r0, asr #31 416bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon eor r3, r1, r1, asr #31 426bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon sub r0, r2, r0, asr #31 436bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon sub r1, r3, r1, asr #31 446bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon // abs(a) % abs(b) 45647fc7336b2bc302bb51e50022b27bf9b929071cAnton Korobeynikov bl SYMBOL_NAME(__umodsi3) 466bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon // Apply sign of dividend to result and return. 476bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon eor r0, r0, r4, asr #31 486bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon sub r0, r0, r4, asr #31 496bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon CLEAR_FRAME_AND_RETURN 50a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik#endif 51