diff --git a/AUTHORS b/AUTHORS index 8b1cb226085c..169d2b44010a 100644 --- a/AUTHORS +++ b/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 diff --git a/src/arch/arm/libgcc/Makefile.inc b/src/arch/arm/libgcc/Makefile.inc index 0da655ea98fc..c6ca45e24c28 100644 --- a/src/arch/arm/libgcc/Makefile.inc +++ b/src/arch/arm/libgcc/Makefile.inc @@ -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) diff --git a/src/arch/arm/libgcc/ldivmod.S b/src/arch/arm/libgcc/ldivmod.S new file mode 100644 index 000000000000..39b89434cda2 --- /dev/null +++ b/src/arch/arm/libgcc/ldivmod.S @@ -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 + + +@ {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}