From 6ea328f0f1865a75fdfd16cd8cca04818facdd26 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Tue, 18 Feb 2025 16:47:41 +0000 Subject: [PATCH] arm: add div0 handler for 64-bit division on ARMv7-M Even though ARMv7-M has a hardware divider, 64-bit division is handled in software and needs a div0 handler. The libgcc routines call __aeabi_{i,l}div0 so we alias those to __div0. Change-Id: I5152c43d39e25e03f31404753f13978a614aca06 --- apps/plugins/lib/gcc-support.c | 5 +++++ firmware/export/config.h | 2 +- firmware/target/arm/system-arm-micro.c | 8 ++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/apps/plugins/lib/gcc-support.c b/apps/plugins/lib/gcc-support.c index a2b709ba50..f1fbe4ec58 100644 --- a/apps/plugins/lib/gcc-support.c +++ b/apps/plugins/lib/gcc-support.c @@ -27,6 +27,11 @@ void __attribute__((naked)) __div0(void) { asm volatile("bx %0" : : "r"(rb->__div0)); } + +#if defined(CPU_ARM_MICRO) +void __aeabi_idiv0(void) __attribute__((alias("__div0"))); +void __aeabi_ldiv0(void) __attribute__((alias("__div0"))); +#endif #endif void *memcpy(void *dest, const void *src, size_t n) diff --git a/firmware/export/config.h b/firmware/export/config.h index 8ac710267b..ad5f45c98e 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -710,7 +710,7 @@ Lyre prototype 1 */ # elif ARM_PROFILE == ARM_PROFILE_CLASSIC # define CPU_ARM_CLASSIC # endif -# if !defined(ARM_HAVE_HW_DIV) && (CONFIG_PLATFORM & PLATFORM_NATIVE) +# if (CONFIG_PLATFORM & PLATFORM_NATIVE) # define ARM_NEED_DIV0 # endif #endif diff --git a/firmware/target/arm/system-arm-micro.c b/firmware/target/arm/system-arm-micro.c index d9e1111206..9e23a9fb02 100644 --- a/firmware/target/arm/system-arm-micro.c +++ b/firmware/target/arm/system-arm-micro.c @@ -38,6 +38,14 @@ void UIE(void) while (1); } +void __div0(void) +{ + while (1); +} + +void __aeabi_idiv0(void) __attribute__((alias("__div0"))); +void __aeabi_ldiv0(void) __attribute__((alias("__div0"))); + #define ATTR_IRQ_HANDLER __attribute__((weak, alias("UIE"))) void nmi_handler(void) ATTR_IRQ_HANDLER;