1156cd587Sjoerg/*===-- divmodsi4.S - 32-bit signed integer divide and modulus ------------===// 2156cd587Sjoerg * 3156cd587Sjoerg * The LLVM Compiler Infrastructure 4156cd587Sjoerg * 5156cd587Sjoerg * This file is dual licensed under the MIT and the University of Illinois Open 6156cd587Sjoerg * Source Licenses. See LICENSE.TXT for details. 7156cd587Sjoerg * 8156cd587Sjoerg *===----------------------------------------------------------------------===// 9156cd587Sjoerg * 10156cd587Sjoerg * This file implements the __divmodsi4 (32-bit signed integer divide and 11156cd587Sjoerg * modulus) function for the ARM architecture. A naive digit-by-digit 12156cd587Sjoerg * computation is employed for simplicity. 13156cd587Sjoerg * 14156cd587Sjoerg *===----------------------------------------------------------------------===*/ 15156cd587Sjoerg 16156cd587Sjoerg#include "../assembly.h" 17156cd587Sjoerg 18156cd587Sjoerg#define ESTABLISH_FRAME \ 19*f6e43b31Sskrll push {r4-r6, lr} 20156cd587Sjoerg#define CLEAR_FRAME_AND_RETURN \ 21*f6e43b31Sskrll pop {r4-r6, pc} 22156cd587Sjoerg 23156cd587Sjoerg .syntax unified 24190e92d8Sjoerg .text 25190e92d8Sjoerg#if __ARM_ARCH_ISA_THUMB == 2 26190e92d8Sjoerg .thumb 27190e92d8Sjoerg#endif 28190e92d8Sjoerg 29190e92d8Sjoerg@ int __divmodsi4(int divident, int divisor, int *remainder) 30190e92d8Sjoerg@ Calculate the quotient and remainder of the (signed) division. The return 31190e92d8Sjoerg@ value is the quotient, the remainder is placed in the variable. 32190e92d8Sjoerg 3361f2f256Sjoerg .p2align 3 34ef84fd3bSjoerg#if __ARM_ARCH_ISA_THUMB == 2 35ef84fd3bSjoergDEFINE_COMPILERRT_THUMB_FUNCTION(__divmodsi4) 36ef84fd3bSjoerg#else 37156cd587SjoergDEFINE_COMPILERRT_FUNCTION(__divmodsi4) 38ef84fd3bSjoerg#endif 39156cd587Sjoerg#if __ARM_ARCH_EXT_IDIV__ 40156cd587Sjoerg tst r1, r1 41156cd587Sjoerg beq LOCAL_LABEL(divzero) 42156cd587Sjoerg mov r3, r0 43156cd587Sjoerg sdiv r0, r3, r1 44156cd587Sjoerg mls r1, r0, r1, r3 45156cd587Sjoerg str r1, [r2] 46156cd587Sjoerg bx lr 47156cd587SjoergLOCAL_LABEL(divzero): 48156cd587Sjoerg mov r0, #0 49156cd587Sjoerg bx lr 50156cd587Sjoerg#else 51156cd587Sjoerg ESTABLISH_FRAME 52156cd587Sjoerg// Set aside the sign of the quotient and modulus, and the address for the 53156cd587Sjoerg// modulus. 54156cd587Sjoerg eor r4, r0, r1 55156cd587Sjoerg mov r5, r0 56156cd587Sjoerg mov r6, r2 57156cd587Sjoerg// Take the absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). 58156cd587Sjoerg eor ip, r0, r0, asr #31 59156cd587Sjoerg eor lr, r1, r1, asr #31 60156cd587Sjoerg sub r0, ip, r0, asr #31 61156cd587Sjoerg sub r1, lr, r1, asr #31 62156cd587Sjoerg// Unsigned divmod: 63156cd587Sjoerg bl SYMBOL_NAME(__udivmodsi4) 64156cd587Sjoerg// Apply the sign of quotient and modulus 65156cd587Sjoerg ldr r1, [r6] 66156cd587Sjoerg eor r0, r0, r4, asr #31 67156cd587Sjoerg eor r1, r1, r5, asr #31 68156cd587Sjoerg sub r0, r0, r4, asr #31 69156cd587Sjoerg sub r1, r1, r5, asr #31 70156cd587Sjoerg str r1, [r6] 71156cd587Sjoerg CLEAR_FRAME_AND_RETURN 72156cd587Sjoerg#endif 73156cd587SjoergEND_COMPILERRT_FUNCTION(__divmodsi4) 74