[PATCH v4 3/3] arm: Enable FPU for M-profile
Christophe Lyon <[email protected]> Wed, 24 Jun 2026 21:58:35 +0200
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
Before using the FPU, we must grant access to it. This helps when running the GCC testsuite on a simulator where FPU access is not granted by default. This patch grants full access, we may want to consider granting only unprivileged access later. While updating crt0.S, include arm-acle-compat.h and stop using __ARM_ARCH_7A__. 2026-05-29 Christophe Lyon <[email protected]> * libgloss/arm/cpu-init/rdimon-aem-m.S: Enable full FPU access on M-profile. * libgloss/arm/crt0.S: Call _rdimon_hw_init_hook for M profile too. --- libgloss/arm/cpu-init/rdimon-aem-m.S | 29 +++++++++++++++++++++++++++- libgloss/arm/crt0.S | 9 +++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/libgloss/arm/cpu-init/rdimon-aem-m.S b/libgloss/arm/cpu-init/rdimon-aem-m.S index 611849077..c495efc2d 100644 --- a/libgloss/arm/cpu-init/rdimon-aem-m.S +++ b/libgloss/arm/cpu-init/rdimon-aem-m.S @@ -28,9 +28,36 @@ We define a hardfault handler, required to prevent the simulator from entering into an infinite loop. This handler is located at address 0xc by default when linking with mprofile-mps2.specs which - uses --section-start=.hardfault_handler_addr=0xc. */ + uses --section-start=.hardfault_handler_addr=0xc. + + Enable the FPU when __ARM_FP is set. */ #if (__ARM_ARCH_PROFILE == 'M') + .syntax unified + .thumb + + @ CPU Initialisation + .globl _rdimon_hw_init_hook + .type _rdimon_hw_init_hook, %function + +_rdimon_hw_init_hook: + /* Enable FPU for M-profile only . */ +#if __ARM_FP + /* Read CPACR */ + ldr r0, =0xE000ED88 + ldr r1, [R0] + /* Enable full access to CP10 and CP11. */ + orr r1, r1, #(0xFF << 20) + str r1, [R0] +#if __ARM_ARCH >= 800 + ldr r0, =0xE002ED88 + str r1, [R0] +#endif + dsb + isb +#endif + bx lr + /* On M-profile, call abort in case of hardfault: this causes the simulator to abort execution instead of going into an infinite loop. */ diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S index b9e768007..cad002d2b 100644 --- a/libgloss/arm/crt0.S +++ b/libgloss/arm/crt0.S @@ -1,6 +1,7 @@ #include "newlib.h" #include "arm.h" #include "swi.h" +#include "arm-acle-compat.h" /* ANSI concatenation macros. */ #define CONCAT(a, b) CONCAT2(a, b) @@ -250,12 +251,8 @@ FUNC_START _start FN_EH_START - /* __ARM_ARCH_PROFILE is defined from GCC 4.8 onwards, however __ARM_ARCH_7A - has been defined since 4.2 onwards, which is when v7-a support was added - and hence 'A' profile support was added in the compiler. Allow for this - file to be built with older compilers. We only call this for A profile - cores. */ -#if defined (__ARM_ARCH_7A__) || (__ARM_ARCH_PROFILE == 'A') + /* We only call this for A and M profile cores. */ +#if (__ARM_ARCH_PROFILE == 'A') || (__ARM_ARCH_PROFILE == 'M') /* The init hook does not use the stack and is called before the stack has been set up. */ #ifdef ARM_RDI_MONITOR bl _rdimon_hw_init_hook -- 2.34.1