Files
Frank Dischner ef45c12f9e [compiler-rt][builtins] Support builtins for armv8m.base
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
2023-03-14 17:20:54 -07:00

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