16bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon/*===-- divmodsi4.S - 32-bit signed integer divide and 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 __divmodsi4 (32-bit signed integer divide and 116bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * modulus) function for the ARM architecture. A naive digit-by-digit 126bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * computation is employed for simplicity. 136bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon * 146bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon *===----------------------------------------------------------------------===*/ 156bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon 166bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon#include "../assembly.h" 176bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon 186bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon#define ESTABLISH_FRAME \ 196bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon push {r4-r7, lr} ;\ 206bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon add r7, sp, #12 216bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon#define CLEAR_FRAME_AND_RETURN \ 226bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon pop {r4-r7, pc} 236bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon 245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines .syntax unified 255d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines .text 265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if __ARM_ARCH_ISA_THUMB == 2 275d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines .thumb 285d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif 295d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines .p2align 3 316bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen CanonDEFINE_COMPILERRT_FUNCTION(__divmodsi4) 323a6eb8083c342da436df8c7d1809dfeb8834bc6dStephen Hines#if __ARM_ARCH_EXT_IDIV__ 33a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik tst r1, r1 34a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik beq LOCAL_LABEL(divzero) 35a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik mov r3, r0 36a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik sdiv r0, r3, r1 37a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik mls r1, r0, r1, r3 38a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik str r1, [r2] 39a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik bx lr 40a09d09d29e250e905bdfaf819979b9c3e9adc047Nick KledzikLOCAL_LABEL(divzero): 41a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik mov r0, #0 42a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik bx lr 43a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik#else 446bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon ESTABLISH_FRAME 456bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon// Set aside the sign of the quotient and modulus, and the address for the 466bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon// modulus. 476bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon eor r4, r0, r1 486bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon mov r5, r0 496bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon mov r6, r2 506bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon// Take the absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). 516bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon eor ip, r0, r0, asr #31 526bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon eor lr, r1, r1, asr #31 536bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon sub r0, ip, r0, asr #31 546bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon sub r1, lr, r1, asr #31 556bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon// Unsigned divmod: 56647fc7336b2bc302bb51e50022b27bf9b929071cAnton Korobeynikov bl SYMBOL_NAME(__udivmodsi4) 576bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon// Apply the sign of quotient and modulus 586bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon ldr r1, [r6] 596bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon eor r0, r0, r4, asr #31 606bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon eor r1, r1, r5, asr #31 612caeeefe078e7c10170f02b717e4a5ab7623e554Stephen Canon sub r0, r0, r4, asr #31 626bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon sub r1, r1, r5, asr #31 636bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon str r1, [r6] 646bbe0bb0856f7e7cabe11bc0a10c268db034142bStephen Canon CLEAR_FRAME_AND_RETURN 65a09d09d29e250e905bdfaf819979b9c3e9adc047Nick Kledzik#endif 662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesEND_COMPILERRT_FUNCTION(__divmodsi4) 67