83 lines · plain
1//===-- divsi3.S - 32-bit signed integer divide ---------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the __divsi3 (32-bit signed integer divide) function10// for the ARM architecture as a wrapper around the unsigned routine.11//12//===----------------------------------------------------------------------===//13 14#include "../assembly.h"15 16#define ESTABLISH_FRAME \17 push {r4, r7, lr} ;\18 add r7, sp, #419#define CLEAR_FRAME_AND_RETURN \20 pop {r4, r7, pc}21 22 .syntax unified23 .text24 DEFINE_CODE_STATE25 26 .p2align 327// Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine.28DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_idiv, __divsi3)29 30@ int __divsi3(int divident, int divisor)31@ Calculate and return the quotient of the (signed) division.32 33DEFINE_COMPILERRT_FUNCTION(__divsi3)34#if __ARM_ARCH_EXT_IDIV__35 tst r1,r136 beq LOCAL_LABEL(divzero)37 sdiv r0, r0, r138 bx lr39LOCAL_LABEL(divzero):40 // Use movs for compatibility with v8-m.base.41 movs r0,#042 bx lr43#else44ESTABLISH_FRAME45// Set aside the sign of the quotient.46# if defined(USE_THUMB_1)47 movs r4, r048 eors r4, r149# else50 eor r4, r0, r151# endif52// Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).53# if defined(USE_THUMB_1)54 asrs r2, r0, #3155 asrs r3, r1, #3156 eors r0, r257 eors r1, r358 subs r0, r0, r259 subs r1, r1, r360# else61 eor r2, r0, r0, asr #3162 eor r3, r1, r1, asr #3163 sub r0, r2, r0, asr #3164 sub r1, r3, r1, asr #3165# endif66// abs(a) / abs(b)67 bl SYMBOL_NAME(__udivsi3)68// Apply sign of quotient to result and return.69# if defined(USE_THUMB_1)70 asrs r4, #3171 eors r0, r472 subs r0, r0, r473# else74 eor r0, r0, r4, asr #3175 sub r0, r0, r4, asr #3176# endif77 CLEAR_FRAME_AND_RETURN78#endif79END_COMPILERRT_FUNCTION(__divsi3)80 81NO_EXEC_STACK_DIRECTIVE82 83