arm: Enable FPU for M-profile

Message ID 20260611212519.100477-1-christophe.lyon@arm.com
State New
Headers
Series arm: Enable FPU for M-profile |

Commit Message

Christophe Lyon June 11, 2026, 9:25 p.m. UTC
  Before using the FPU, we must grant access to it.  This helps when
running the GCC testsuite on a simluator where FPU access is not
granted by default.

This patch grants full access, we may want to consider granting only
unpriviledged access later.

2026-05-29  Christophe Lyon  <christophe.lyon@arm.com>

	* libgloss/arm/crt0.S: Enable full FPU access on M-profile.
	* newlib/libc/sys/arm/crt0.S: Likewise.
---
 libgloss/arm/crt0.S        | 13 +++++++++++++
 newlib/libc/sys/arm/crt0.S | 13 +++++++++++++
 2 files changed, 26 insertions(+)
  

Comments

Christophe Lyon June 16, 2026, 12:21 p.m. UTC | #1
Hi!

On 6/11/26 23:25, Christophe Lyon wrote:
> Before using the FPU, we must grant access to it.  This helps when
> running the GCC testsuite on a simluator where FPU access is not
> granted by default.
> 
> This patch grants full access, we may want to consider granting only
> unpriviledged access later.
> 
> 2026-05-29  Christophe Lyon  <christophe.lyon@arm.com>
> 
> 	* libgloss/arm/crt0.S: Enable full FPU access on M-profile.
> 	* newlib/libc/sys/arm/crt0.S: Likewise.

I have sent v2 of this patch in 
https://sourceware.org/pipermail/newlib/2026/022486.html to move the FPU 
initialization code to  libgloss/arm/cpu-init/rdimon-aem.S so that it's 
present only when using aem (and thus not interfere with e.g. qemu-arm 
which would otherwise crash).

Thanks,

Christophe

> ---
>   libgloss/arm/crt0.S        | 13 +++++++++++++
>   newlib/libc/sys/arm/crt0.S | 13 +++++++++++++
>   2 files changed, 26 insertions(+)
> 
> diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S
> index b9e768007..0bec14e91 100644
> --- a/libgloss/arm/crt0.S
> +++ b/libgloss/arm/crt0.S
> @@ -366,6 +366,19 @@
>   
>   #endif
>   #endif
> +
> +	/* Enable FPU for M-profile only .  */
> +#if defined (THUMB_VXM) && __ARM_FP
> +	/* Read CPACR */
> +	ldr r0, =0xE000ED88
> +	ldr r1, [R0]
> +	/* Enable full access to CP10 and CP11.  */
> +	orr r1, r1, #(0xF << 20)
> +	str r1, [R0]
> +	dsb
> +	isb
> +#endif
> +
>   	/* Zero the memory in the .bss section.  */
>   	movs 	a2, #0			/* Second arg: fill value.  */
>   	mov	fp, a2			/* Null frame pointer.  */
> diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S
> index 51e86d549..4c775fbbb 100644
> --- a/newlib/libc/sys/arm/crt0.S
> +++ b/newlib/libc/sys/arm/crt0.S
> @@ -353,6 +353,19 @@
>   
>   #endif
>   #endif
> +
> +	/* Enable FPU for M-profile only .  */
> +#if defined (THUMB_VXM) && __ARM_FP
> +	/* Read CPACR */
> +	ldr r0, =0xE000ED88
> +	ldr r1, [R0]
> +	/* Enable full access to CP10 and CP11.  */
> +	orr r1, r1, #(0xF << 20)
> +	str r1, [R0]
> +	dsb
> +	isb
> +#endif
> +
>   	/* Zero the memory in the .bss section.  */
>   	movs 	a2, #0			/* Second arg: fill value.  */
>   	mov	fp, a2			/* Null frame pointer.  */
  

Patch

diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S
index b9e768007..0bec14e91 100644
--- a/libgloss/arm/crt0.S
+++ b/libgloss/arm/crt0.S
@@ -366,6 +366,19 @@ 
 
 #endif
 #endif
+
+	/* Enable FPU for M-profile only .  */
+#if defined (THUMB_VXM) && __ARM_FP
+	/* Read CPACR */
+	ldr r0, =0xE000ED88
+	ldr r1, [R0]
+	/* Enable full access to CP10 and CP11.  */
+	orr r1, r1, #(0xF << 20)
+	str r1, [R0]
+	dsb
+	isb
+#endif
+
 	/* Zero the memory in the .bss section.  */
 	movs 	a2, #0			/* Second arg: fill value.  */
 	mov	fp, a2			/* Null frame pointer.  */
diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S
index 51e86d549..4c775fbbb 100644
--- a/newlib/libc/sys/arm/crt0.S
+++ b/newlib/libc/sys/arm/crt0.S
@@ -353,6 +353,19 @@ 
 
 #endif
 #endif
+
+	/* Enable FPU for M-profile only .  */
+#if defined (THUMB_VXM) && __ARM_FP
+	/* Read CPACR */
+	ldr r0, =0xE000ED88
+	ldr r1, [R0]
+	/* Enable full access to CP10 and CP11.  */
+	orr r1, r1, #(0xF << 20)
+	str r1, [R0]
+	dsb
+	isb
+#endif
+
 	/* Zero the memory in the .bss section.  */
 	movs 	a2, #0			/* Second arg: fill value.  */
 	mov	fp, a2			/* Null frame pointer.  */