From 639b587fc7fd92dca18d0298864561de295cea99 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Fri, 10 Jan 2025 16:30:22 +0000 Subject: [PATCH] arm: add support for processors with hardware division ARMv7-M has hardware division, so it doesn't require __div0 or any support functions for 32-bit division. Change-Id: I840683a1a77d737f378899ca4bcf858216b81014 --- apps/codecs.c | 2 +- apps/plugin.c | 2 +- apps/plugin.h | 2 +- apps/plugins/lib/gcc-support.c | 2 +- apps/plugins/test_codec.c | 2 +- firmware/export/config.h | 6 ++++++ firmware/target/arm/system-arm.h | 2 ++ lib/arm_support/support-arm.S | 9 +++++---- lib/rbcodec/codecs/codec_crt0.c | 2 +- lib/rbcodec/codecs/codecs.h | 2 +- lib/rbcodec/codecs/demac/libdemac/SOURCES | 6 ++++-- lib/rbcodec/codecs/demac/libdemac/demac_config.h | 2 +- 12 files changed, 25 insertions(+), 14 deletions(-) diff --git a/apps/codecs.c b/apps/codecs.c index 9f34d26e14..3593501cbd 100644 --- a/apps/codecs.c +++ b/apps/codecs.c @@ -91,7 +91,7 @@ struct codec_api ci = { NULL, /* loop_track */ /* kernel/ system */ -#if defined(CPU_ARM) && CONFIG_PLATFORM & PLATFORM_NATIVE +#if defined(ARM_NEED_DIV0) __div0, #endif sleep, diff --git a/apps/plugin.c b/apps/plugin.c index 6b86afe97f..f1f44c680f 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -463,7 +463,7 @@ static const struct plugin_api rockbox_api = { talk_force_enqueue_next, /* kernel/ system */ -#if defined(CPU_ARM) && CONFIG_PLATFORM & PLATFORM_NATIVE +#if defined(ARM_NEED_DIV0) __div0, #endif sleep, diff --git a/apps/plugin.h b/apps/plugin.h index f8e4bb5134..e7a91cd9c0 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -537,7 +537,7 @@ struct plugin_api { void (*talk_force_enqueue_next)(void); /* kernel/ system */ -#if defined(CPU_ARM) && CONFIG_PLATFORM & PLATFORM_NATIVE +#if defined(ARM_NEED_DIV0) void (*__div0)(void); #endif unsigned (*sleep)(unsigned ticks); diff --git a/apps/plugins/lib/gcc-support.c b/apps/plugins/lib/gcc-support.c index 09a08fa9f5..a2b709ba50 100644 --- a/apps/plugins/lib/gcc-support.c +++ b/apps/plugins/lib/gcc-support.c @@ -22,7 +22,7 @@ ****************************************************************************/ #include "plugin.h" -#if defined(CPU_ARM) && (CONFIG_PLATFORM & PLATFORM_NATIVE) +#if defined(ARM_NEED_DIV0) void __attribute__((naked)) __div0(void) { asm volatile("bx %0" : : "r"(rb->__div0)); diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c index 91599bfc5d..9594e78f96 100644 --- a/apps/plugins/test_codec.c +++ b/apps/plugins/test_codec.c @@ -593,7 +593,7 @@ static void init_ci(void) ci.semaphore_release = rb->semaphore_release; #endif -#if defined(CPU_ARM) && (CONFIG_PLATFORM & PLATFORM_NATIVE) +#if defined(ARM_NEED_DIV0) ci.__div0 = rb->__div0; #endif } diff --git a/firmware/export/config.h b/firmware/export/config.h index b7ba0dc86f..15f4950e95 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -700,9 +700,15 @@ Lyre prototype 1 */ #define ARM_PROFILE ARCH_PROFILE /* Classic, Microcontroller */ # if ARM_PROFILE == ARM_PROFILE_MICRO # define CPU_ARM_MICRO +# if (ARM_ARCH >= 7) +# define ARM_HAVE_HW_DIV +# endif # elif ARM_PROFILE == ARM_PROFILE_CLASSIC # define CPU_ARM_CLASSIC # endif +# if !defined(ARM_HAVE_HW_DIV) && (CONFIG_PLATFORM & PLATFORM_NATIVE) +# define ARM_NEED_DIV0 +# endif #endif #if ARCH == ARCH_MIPS diff --git a/firmware/target/arm/system-arm.h b/firmware/target/arm/system-arm.h index 2695c77cd3..a6ffc07716 100644 --- a/firmware/target/arm/system-arm.h +++ b/firmware/target/arm/system-arm.h @@ -25,7 +25,9 @@ #define nop \ asm volatile ("nop") +#if defined(ARM_NEED_DIV0) void __div0(void); +#endif #define IRQ_ENABLED 0x00 #define IRQ_DISABLED 0x80 diff --git a/lib/arm_support/support-arm.S b/lib/arm_support/support-arm.S index d12392eeb3..37687ef272 100644 --- a/lib/arm_support/support-arm.S +++ b/lib/arm_support/support-arm.S @@ -219,7 +219,7 @@ .endif .endm -#else +#else /* ARM_ARCH >= 5 */ .macro ARMV5_UDIV32_BODY numerator, divisor, quotient, remainder, bits, inv, neg, div0label, return cmp \numerator, \divisor clz \bits, \divisor @@ -398,7 +398,7 @@ .else b 99f .endif -#endif +#endif /* ARM_ARCH >= 6 */ 99: .endm @@ -594,7 +594,7 @@ .endif 99: .endm -#endif +#endif /* ARM_ARCH */ .section .text @@ -671,7 +671,7 @@ __aeabi_idivmod: .size __aeabi_idivmod, . - __aeabi_idivmod #endif -#else +#elif !defined(ARM_HAVE_HW_DIV) /* && ARM_ARCH >= 5 */ #ifndef __ARM_EABI__ __udivsi3: ARMV5_UDIV32_BODY r0, r1, r0, "", r2, r3, ip, __div0_wrap, 1 @@ -717,6 +717,7 @@ __aeabi_idivmod: .global __popcountdi2 .type __popcountdi2, %function .set __popcountdi2, __popcountsi2 + .align 2 __popcountsi2: ldr r2, .L2 @ r2 = 0x55555555 diff --git a/lib/rbcodec/codecs/codec_crt0.c b/lib/rbcodec/codecs/codec_crt0.c index e3c3321e54..0f9749ddb8 100644 --- a/lib/rbcodec/codecs/codec_crt0.c +++ b/lib/rbcodec/codecs/codec_crt0.c @@ -66,7 +66,7 @@ enum codec_status codec_start(enum codec_entry_call_reason reason) return codec_main(reason); } -#if defined(CPU_ARM) && (CONFIG_PLATFORM & PLATFORM_NATIVE) +#if defined(ARM_NEED_DIV0) void __attribute__((naked)) __div0(void) { asm volatile("bx %0" : : "r"(ci->__div0)); diff --git a/lib/rbcodec/codecs/codecs.h b/lib/rbcodec/codecs/codecs.h index 18416afba8..7a1a83044e 100644 --- a/lib/rbcodec/codecs/codecs.h +++ b/lib/rbcodec/codecs/codecs.h @@ -154,7 +154,7 @@ struct codec_api { bool (*loop_track)(void); /* kernel/ system */ -#if defined(CPU_ARM) && CONFIG_PLATFORM & PLATFORM_NATIVE +#if defined(ARM_NEED_DIV0) void (*__div0)(void); #endif unsigned (*sleep)(unsigned ticks); diff --git a/lib/rbcodec/codecs/demac/libdemac/SOURCES b/lib/rbcodec/codecs/demac/libdemac/SOURCES index 018f35a73c..d7a6dbeedb 100644 --- a/lib/rbcodec/codecs/demac/libdemac/SOURCES +++ b/lib/rbcodec/codecs/demac/libdemac/SOURCES @@ -1,8 +1,10 @@ predictor.c -#ifdef CPU_ARM +#if defined(CPU_ARM) predictor-arm.S +#if !defined(ARM_HAVE_HW_DIV) udiv32_arm.S -#elif defined CPU_COLDFIRE +#endif +#elif defined(CPU_COLDFIRE) predictor-cf.S #endif entropy.c diff --git a/lib/rbcodec/codecs/demac/libdemac/demac_config.h b/lib/rbcodec/codecs/demac/libdemac/demac_config.h index 8ff4719923..5c0c9d774b 100644 --- a/lib/rbcodec/codecs/demac/libdemac/demac_config.h +++ b/lib/rbcodec/codecs/demac/libdemac/demac_config.h @@ -125,7 +125,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA #ifndef __ASSEMBLER__ -#if defined(CPU_ARM) && (ARM_ARCH < 5 || defined(USE_IRAM)) +#if defined(CPU_ARM) && (ARM_ARCH < 5 || defined(USE_IRAM)) && !defined(ARM_HAVE_HW_DIV) /* optimised unsigned integer division for ARMv4, in IRAM */ unsigned udiv32_arm(unsigned a, unsigned b); #define UDIV32(a, b) udiv32_arm(a, b)