arm/libgcc: Support signed 64-bit division
Add support for signed 64-bit division. The implementation mostly relies on __aeabi_uldivmod, which is already implemented. ldivmod.S was adapted from CrOS EC version of ldivmod.S: https://chromium.googlesource.com/chromiumos/platform/ec/+/main/third_party/libaeabi-cortexm0/core/cortex-m0/ldivmod.S The CrOS EC version was adapted from: https://github.com/bobbl/libaeabi-cortexm0/blob/master/ldivmod.S BUG=b:240316722 BRANCH=None TEST=Signed division works in PSP verstage (runs on ARM) Change-Id: I53785c732b0fa35a4809bc054f1482c5461ada7b Signed-off-by: Rob Barnes <robbarnes@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/66207 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-by: Tim Van Patten <timvp@google.com>
This commit is contained in:
parent
b11f9f7e16
commit
f6bb293f1c
1
AUTHORS
1
AUTHORS
|
@ -108,6 +108,7 @@ Jonas 'Sortie' Termansen
|
|||
Jonathan A. Kollasch
|
||||
Jonathan Neuschäfer
|
||||
Jordan Crouse
|
||||
Jörg Mische
|
||||
Joseph Smith
|
||||
Keith Hui
|
||||
Keith Packard
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
libgcc_files = ashldi3.S lib1funcs.S lshrdi3.S muldi3.S ucmpdi2.S uldivmod.S
|
||||
libgcc_files = ashldi3.S lib1funcs.S lshrdi3.S muldi3.S ucmpdi2.S uldivmod.S ldivmod.S
|
||||
libgcc_files += udivmoddi4.c umoddi3.c
|
||||
|
||||
ifeq ($(CONFIG_ARCH_BOOTBLOCK_ARM),y)
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/* SPDX-License-Identifier: ISC OR GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* ldivmod.S: signed 64 bit division (quotient and remainder)
|
||||
*
|
||||
* Taken from CrOS EC: third_party/libaeabi-cortexm0/core/cortex-m0/ldivmod.S
|
||||
*/
|
||||
|
||||
#include <arch/asm.h>
|
||||
|
||||
|
||||
@ {long long quotient, long long remainder}
|
||||
@ __aeabi_ldivmod(long long numerator, long long denominator)
|
||||
@
|
||||
@ Divide r1:r0 by r3:r2 and return the quotient in r1:r0 and the remainder in
|
||||
@ r3:r2 (all signed)
|
||||
@
|
||||
|
||||
ENTRY(__aeabi_ldivmod)
|
||||
|
||||
cmp r1, #0
|
||||
bge L_num_pos
|
||||
|
||||
push {r4, lr}
|
||||
movs r4, #0 @ num = -num
|
||||
rsbs r0, r0, #0
|
||||
sbcs r4, r1
|
||||
mov r1, r4
|
||||
|
||||
cmp r3, #0
|
||||
bge L_neg_both
|
||||
|
||||
movs r4, #0 @ den = -den
|
||||
rsbs r2, r2, #0
|
||||
sbcs r4, r3
|
||||
mov r3, r4
|
||||
bl __aeabi_uldivmod
|
||||
movs r4, #0 @ rem = -rem
|
||||
rsbs r2, r2, #0
|
||||
sbcs r4, r3
|
||||
mov r3, r4
|
||||
pop {r4, pc}
|
||||
|
||||
L_neg_both:
|
||||
bl __aeabi_uldivmod
|
||||
movs r4, #0 @ quot = -quot
|
||||
rsbs r0, r0, #0
|
||||
sbcs r4, r1
|
||||
mov r1, r4
|
||||
movs r4, #0 @ rem = -rem
|
||||
rsbs r2, r2, #0
|
||||
sbcs r4, r3
|
||||
mov r3, r4
|
||||
pop {r4, pc}
|
||||
|
||||
L_num_pos:
|
||||
cmp r3, #0
|
||||
blt L_den_neg
|
||||
push {r4, lr}
|
||||
bl __aeabi_uldivmod @ offset too big for b / bge
|
||||
pop {r4, pc}
|
||||
|
||||
L_den_neg:
|
||||
push {r4, lr}
|
||||
movs r4, #0 @ den = -den
|
||||
rsbs r2, r2, #0
|
||||
sbcs r4, r3
|
||||
mov r3, r4
|
||||
bl __aeabi_uldivmod
|
||||
movs r4, #0 @ quot = -quot
|
||||
rsbs r0, r0, #0
|
||||
sbcs r4, r1
|
||||
mov r1, r4
|
||||
pop {r4, pc}
|
Loading…
Reference in New Issue