Path: blob/main/contrib/llvm-project/compiler-rt/lib/builtins/arm/divmodsi4.S
35291 views
//===-- divmodsi4.S - 32-bit signed integer divide and modulus ------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the __divmodsi4 (32-bit signed integer divide and9// modulus) function for the ARM architecture. A naive digit-by-digit10// computation is employed for simplicity.11//12//===----------------------------------------------------------------------===//1314#include "../assembly.h"1516#define ESTABLISH_FRAME \17push {r4-r7, lr} ;\18add r7, sp, #1219#define CLEAR_FRAME_AND_RETURN \20pop {r4-r7, pc}2122.syntax unified23.text24DEFINE_CODE_STATE2526@ int __divmodsi4(int divident, int divisor, int *remainder)27@ Calculate the quotient and remainder of the (signed) division. The return28@ value is the quotient, the remainder is placed in the variable.2930.p2align 331DEFINE_COMPILERRT_FUNCTION(__divmodsi4)32#if __ARM_ARCH_EXT_IDIV__33tst r1, r134beq LOCAL_LABEL(divzero)35mov r3, r036sdiv r0, r3, r137mls r1, r0, r1, r338str r1, [r2]39bx lr40LOCAL_LABEL(divzero):41mov r0, #042bx lr43#else44ESTABLISH_FRAME45// Set aside the sign of the quotient and modulus, and the address for the46// modulus.47eor r4, r0, r148mov r5, r049mov r6, r250// Take the absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).51eor ip, r0, r0, asr #3152eor lr, r1, r1, asr #3153sub r0, ip, r0, asr #3154sub r1, lr, r1, asr #3155// Unsigned divmod:56bl SYMBOL_NAME(__udivmodsi4)57// Apply the sign of quotient and modulus58ldr r1, [r6]59eor r0, r0, r4, asr #3160eor r1, r1, r5, asr #3161sub r0, r0, r4, asr #3162sub r1, r1, r5, asr #3163str r1, [r6]64CLEAR_FRAME_AND_RETURN65#endif66END_COMPILERRT_FUNCTION(__divmodsi4)6768NO_EXEC_STACK_DIRECTIVE69707172