1222625Sed/*===-- divmodsi4.S - 32-bit signed integer divide and modulus ------------===// 2222625Sed * 3222625Sed * The LLVM Compiler Infrastructure 4222625Sed * 5222625Sed * This file is dual licensed under the MIT and the University of Illinois Open 6222625Sed * Source Licenses. See LICENSE.TXT for details. 7222625Sed * 8222625Sed *===----------------------------------------------------------------------===// 9222625Sed * 10222625Sed * This file implements the __divmodsi4 (32-bit signed integer divide and 11222625Sed * modulus) function for the ARM architecture. A naive digit-by-digit 12222625Sed * computation is employed for simplicity. 13222625Sed * 14222625Sed *===----------------------------------------------------------------------===*/ 15222625Sed 16222625Sed#include "../assembly.h" 17222625Sed 18222625Sed#define ESTABLISH_FRAME \ 19222625Sed push {r4-r7, lr} ;\ 20222625Sed add r7, sp, #12 21222625Sed#define CLEAR_FRAME_AND_RETURN \ 22222625Sed pop {r4-r7, pc} 23222625Sed 24222625Sed.syntax unified 25222625Sed.align 3 26222625SedDEFINE_COMPILERRT_FUNCTION(__divmodsi4) 27222625Sed ESTABLISH_FRAME 28222625Sed// Set aside the sign of the quotient and modulus, and the address for the 29222625Sed// modulus. 30222625Sed eor r4, r0, r1 31222625Sed mov r5, r0 32222625Sed mov r6, r2 33222625Sed// Take the absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). 34222625Sed eor ip, r0, r0, asr #31 35222625Sed eor lr, r1, r1, asr #31 36222625Sed sub r0, ip, r0, asr #31 37222625Sed sub r1, lr, r1, asr #31 38222625Sed// Unsigned divmod: 39222625Sed bl SYMBOL_NAME(__udivmodsi4) 40222625Sed// Apply the sign of quotient and modulus 41222625Sed ldr r1, [r6] 42222625Sed eor r0, r0, r4, asr #31 43222625Sed eor r1, r1, r5, asr #31 44222625Sed sub r0, r0, r4, asr #31 45222625Sed sub r1, r1, r5, asr #31 46222625Sed str r1, [r6] 47222625Sed CLEAR_FRAME_AND_RETURN 48