Path: blob/master/libs/compiler-rt/lib/builtins/arm/divmodsi4.S
4396 views
/*===-- divmodsi4.S - 32-bit signed integer divide and modulus ------------===//1*2* The LLVM Compiler Infrastructure3*4* This file is dual licensed under the MIT and the University of Illinois Open5* Source Licenses. See LICENSE.TXT for details.6*7*===----------------------------------------------------------------------===//8*9* This file implements the __divmodsi4 (32-bit signed integer divide and10* modulus) function for the ARM architecture. A naive digit-by-digit11* computation is employed for simplicity.12*13*===----------------------------------------------------------------------===*/1415#include "../assembly.h"1617#define ESTABLISH_FRAME \18push {r4-r7, lr} ;\19add r7, sp, #1220#define CLEAR_FRAME_AND_RETURN \21pop {r4-r7, pc}2223.syntax unified24.text25DEFINE_CODE_STATE2627@ int __divmodsi4(int divident, int divisor, int *remainder)28@ Calculate the quotient and remainder of the (signed) division. The return29@ value is the quotient, the remainder is placed in the variable.3031.p2align 332DEFINE_COMPILERRT_FUNCTION(__divmodsi4)33#if __ARM_ARCH_EXT_IDIV__34tst r1, r135beq LOCAL_LABEL(divzero)36mov r3, r037sdiv r0, r3, r138mls r1, r0, r1, r339str r1, [r2]40bx lr41LOCAL_LABEL(divzero):42mov r0, #043bx lr44#else45ESTABLISH_FRAME46// Set aside the sign of the quotient and modulus, and the address for the47// modulus.48eor r4, r0, r149mov r5, r050mov r6, r251// Take the absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).52eor ip, r0, r0, asr #3153eor lr, r1, r1, asr #3154sub r0, ip, r0, asr #3155sub r1, lr, r1, asr #3156// Unsigned divmod:57bl SYMBOL_NAME(__udivmodsi4)58// Apply the sign of quotient and modulus59ldr r1, [r6]60eor r0, r0, r4, asr #3161eor r1, r1, r5, asr #3162sub r0, r0, r4, asr #3163sub r1, r1, r5, asr #3164str r1, [r6]65CLEAR_FRAME_AND_RETURN66#endif67END_COMPILERRT_FUNCTION(__divmodsi4)6869NO_EXEC_STACK_DIRECTIVE707172