[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