This allows building the compiler builtins library for the Armv8-M Baseline architecture. It can be built in the same way as other baremetal targets using the appropriate '--target' flag (e.g. --target=armv8m.base-eabi). NOTE: As with the other Cortex-M targets, only the builtins library is supported. There is no support for sanitizers, etc. The armv8m.base architecture is a superset of armv6m, so adding it to the cmake files using thumb1_SOURCES is almost enough for it to compile. Minor changes are needed to divsi3 and udivsi3, because armv8m.base does have support for div instructions but not mov with an immediate operand. Reviewed By: MaskRay, peter.smith Differential Revision: https://reviews.llvm.org/D143297
83 lines
2.3 KiB
ArmAsm
83 lines
2.3 KiB
ArmAsm
//===-- divsi3.S - 32-bit signed integer divide ---------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the __divsi3 (32-bit signed integer divide) function
|
|
// for the ARM architecture as a wrapper around the unsigned routine.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "../assembly.h"
|
|
|
|
#define ESTABLISH_FRAME \
|
|
push {r4, r7, lr} ;\
|
|
add r7, sp, #4
|
|
#define CLEAR_FRAME_AND_RETURN \
|
|
pop {r4, r7, pc}
|
|
|
|
.syntax unified
|
|
.text
|
|
DEFINE_CODE_STATE
|
|
|
|
.p2align 3
|
|
// Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine.
|
|
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_idiv, __divsi3)
|
|
|
|
@ int __divsi3(int divident, int divisor)
|
|
@ Calculate and return the quotient of the (signed) division.
|
|
|
|
DEFINE_COMPILERRT_FUNCTION(__divsi3)
|
|
#if __ARM_ARCH_EXT_IDIV__
|
|
tst r1,r1
|
|
beq LOCAL_LABEL(divzero)
|
|
sdiv r0, r0, r1
|
|
bx lr
|
|
LOCAL_LABEL(divzero):
|
|
// Use movs for compatibility with v8-m.base.
|
|
movs r0,#0
|
|
bx lr
|
|
#else
|
|
ESTABLISH_FRAME
|
|
// Set aside the sign of the quotient.
|
|
# if defined(USE_THUMB_1)
|
|
movs r4, r0
|
|
eors r4, r1
|
|
# else
|
|
eor r4, r0, r1
|
|
# endif
|
|
// Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
|
|
# if defined(USE_THUMB_1)
|
|
asrs r2, r0, #31
|
|
asrs r3, r1, #31
|
|
eors r0, r2
|
|
eors r1, r3
|
|
subs r0, r0, r2
|
|
subs r1, r1, r3
|
|
# else
|
|
eor r2, r0, r0, asr #31
|
|
eor r3, r1, r1, asr #31
|
|
sub r0, r2, r0, asr #31
|
|
sub r1, r3, r1, asr #31
|
|
# endif
|
|
// abs(a) / abs(b)
|
|
bl SYMBOL_NAME(__udivsi3)
|
|
// Apply sign of quotient to result and return.
|
|
# if defined(USE_THUMB_1)
|
|
asrs r4, #31
|
|
eors r0, r4
|
|
subs r0, r0, r4
|
|
# else
|
|
eor r0, r0, r4, asr #31
|
|
sub r0, r0, r4, asr #31
|
|
# endif
|
|
CLEAR_FRAME_AND_RETURN
|
|
#endif
|
|
END_COMPILERRT_FUNCTION(__divsi3)
|
|
|
|
NO_EXEC_STACK_DIRECTIVE
|
|
|