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 A. Kollasch
|
||||||
Jonathan Neuschäfer
|
Jonathan Neuschäfer
|
||||||
Jordan Crouse
|
Jordan Crouse
|
||||||
|
Jörg Mische
|
||||||
Joseph Smith
|
Joseph Smith
|
||||||
Keith Hui
|
Keith Hui
|
||||||
Keith Packard
|
Keith Packard
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
## SPDX-License-Identifier: GPL-2.0-only
|
## 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
|
libgcc_files += udivmoddi4.c umoddi3.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_ARCH_BOOTBLOCK_ARM),y)
|
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