mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] [PATCH v2] aarch64: rewrite fenv routines in C using inline asm
@ 2026-01-28  2:07 Bill Roberts
  2026-01-29 21:18 ` Szabolcs Nagy
  0 siblings, 1 reply; 3+ messages in thread
From: Bill Roberts @ 2026-01-28  2:07 UTC (permalink / raw)
  To: musl; +Cc: dalias, dalias, Bill Roberts

Rewrite the AArch64 floating-point environment routines (fegetround,
__fesetround, fetestexcept, feclearexcept, feraiseexcept, fegetenv,
fesetenv) from assembly into C implementations using inline assembly.

This change eliminates the need for handwritten function prologues and
epilogues in fenv.s, which simplifies maintenance and allows the compiler
to automatically insert architecture features such as BTI landing pads and
pointer authentication (PAC) sequences where applicable.

The new implementations mirror the original assembly semantics exactly:
- access FPCR/FPSR using `mrs`/`msr` inline asm
- preserve the same FE_* masks and return conventions
- retain `__fesetround` as a hidden internal symbol
- support the special FE_DFL_ENV case in fesetenv

Moving to C also enables the compiler to manage register allocation,
stack usage, and ABI compliance automatically while keeping the low-level
behavior (bitmasks and register accesses) explicit and verifiable.

No functional changes intended.

Signed-off-by: Bill Roberts <bill.roberts@arm.com>
---
Changes since v1:
 - drop the global asm changes with tabs
 - remove unneeded casts
 - use hidden from features.h 

 src/fenv/aarch64/fenv.c | 96 +++++++++++++++++++++++++++++++++++++++++
 src/fenv/aarch64/fenv.s | 68 -----------------------------
 2 files changed, 96 insertions(+), 68 deletions(-)
 create mode 100644 src/fenv/aarch64/fenv.c
 delete mode 100644 src/fenv/aarch64/fenv.s

diff --git a/src/fenv/aarch64/fenv.c b/src/fenv/aarch64/fenv.c
new file mode 100644
index 00000000..f10eb269
--- /dev/null
+++ b/src/fenv/aarch64/fenv.c
@@ -0,0 +1,96 @@
+#include <fenv.h>
+#include <stdint.h>
+
+#define FE_RMODE_MASK 0x00C00000u  // FPCR RMode bits [23:22]
+#define FE_EXC_MASK   0x0000001Fu  // FPSR exception flags [4:0]
+
+static inline uint32_t read_fpcr_u32(void)
+{
+	uint64_t x;
+	__asm__ volatile ("mrs %0, fpcr" : "=r"(x));
+	return (uint32_t)x;
+}
+
+static inline void write_fpcr_u32(uint32_t v)
+{
+	uint64_t x = v;
+	__asm__ volatile ("msr fpcr, %0" :: "r"(x) : "memory");
+}
+
+static inline uint32_t read_fpsr_u32(void)
+{
+	uint64_t x;
+	__asm__ volatile ("mrs %0, fpsr" : "=r"(x));
+	return (uint32_t)x;
+}
+
+static inline void write_fpsr_u32(uint32_t v)
+{
+	uint64_t x = v;
+	__asm__ volatile ("msr fpsr, %0" :: "r"(x) : "memory");
+}
+
+int fegetround(void)
+{
+	uint32_t fpcr = read_fpcr_u32();
+	return (int)(fpcr & FE_RMODE_MASK);
+}
+
+__attribute__((__visibility__("hidden")))
+int __fesetround(int rm)
+{
+	uint32_t fpcr = read_fpcr_u32();
+	fpcr &= ~FE_RMODE_MASK;
+	fpcr |= (uint32_t)rm;
+	write_fpcr_u32(fpcr);
+	return 0;
+}
+
+int fetestexcept(int mask)
+{
+	uint32_t m   = (uint32_t)mask & FE_EXC_MASK;
+	uint32_t fpsr = read_fpsr_u32();
+	return (int)(m & fpsr);
+}
+
+int feclearexcept(int mask)
+{
+	uint32_t m    = (uint32_t)mask & FE_EXC_MASK;
+	uint32_t fpsr = read_fpsr_u32();
+	fpsr &= ~m;
+	write_fpsr_u32(fpsr);
+	return 0;
+}
+
+int feraiseexcept(int mask)
+{
+	uint32_t m    = (uint32_t)mask & FE_EXC_MASK;
+	uint32_t fpsr = read_fpsr_u32();
+	fpsr |= m;
+	write_fpsr_u32(fpsr);
+	return 0;
+}
+
+int fegetenv(fenv_t *env)
+{
+	uint32_t fpcr = read_fpcr_u32();
+	uint32_t fpsr = read_fpsr_u32();
+	env->__fpcr = fpcr;
+	env->__fpsr = fpsr;
+	return 0;
+}
+
+int fesetenv(const fenv_t *env)
+{
+	uint32_t fpcr = 0;
+	uint32_t fpsr = 0;
+
+	if (env != FE_DFL_ENV) {
+		fpcr = env->__fpcr;
+		fpsr = env->__fpsr;
+	}
+
+	write_fpcr_u32(fpcr);
+	write_fpsr_u32(fpsr);
+	return 0;
+}
diff --git a/src/fenv/aarch64/fenv.s b/src/fenv/aarch64/fenv.s
deleted file mode 100644
index 8f3ec965..00000000
--- a/src/fenv/aarch64/fenv.s
+++ /dev/null
@@ -1,68 +0,0 @@
-.global fegetround
-.type fegetround,%function
-fegetround:
-	mrs x0, fpcr
-	and w0, w0, #0xc00000
-	ret
-
-.global __fesetround
-.hidden __fesetround
-.type __fesetround,%function
-__fesetround:
-	mrs x1, fpcr
-	bic w1, w1, #0xc00000
-	orr w1, w1, w0
-	msr fpcr, x1
-	mov w0, #0
-	ret
-
-.global fetestexcept
-.type fetestexcept,%function
-fetestexcept:
-	and w0, w0, #0x1f
-	mrs x1, fpsr
-	and w0, w0, w1
-	ret
-
-.global feclearexcept
-.type feclearexcept,%function
-feclearexcept:
-	and w0, w0, #0x1f
-	mrs x1, fpsr
-	bic w1, w1, w0
-	msr fpsr, x1
-	mov w0, #0
-	ret
-
-.global feraiseexcept
-.type feraiseexcept,%function
-feraiseexcept:
-	and w0, w0, #0x1f
-	mrs x1, fpsr
-	orr w1, w1, w0
-	msr fpsr, x1
-	mov w0, #0
-	ret
-
-.global fegetenv
-.type fegetenv,%function
-fegetenv:
-	mrs x1, fpcr
-	mrs x2, fpsr
-	stp w1, w2, [x0]
-	mov w0, #0
-	ret
-
-// TODO preserve some bits
-.global fesetenv
-.type fesetenv,%function
-fesetenv:
-	mov x1, #0
-	mov x2, #0
-	cmn x0, #1
-	b.eq 1f
-	ldp w1, w2, [x0]
-1:	msr fpcr, x1
-	msr fpsr, x2
-	mov w0, #0
-	ret
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [musl] [PATCH v2] aarch64: rewrite fenv routines in C using inline asm
  2026-01-28  2:07 [musl] [PATCH v2] aarch64: rewrite fenv routines in C using inline asm Bill Roberts
@ 2026-01-29 21:18 ` Szabolcs Nagy
  2026-01-29 21:41   ` Bill Roberts
  0 siblings, 1 reply; 3+ messages in thread
From: Szabolcs Nagy @ 2026-01-29 21:18 UTC (permalink / raw)
  To: Bill Roberts; +Cc: musl, dalias, dalias

* Bill Roberts <bill.roberts@arm.com> [2026-01-27 20:07:25 -0600]:
> +
> +__attribute__((__visibility__("hidden")))

musl has its own hidden definition, use that.

> +int __fesetround(int rm)
> +{

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [musl] [PATCH v2] aarch64: rewrite fenv routines in C using inline asm
  2026-01-29 21:18 ` Szabolcs Nagy
@ 2026-01-29 21:41   ` Bill Roberts
  0 siblings, 0 replies; 3+ messages in thread
From: Bill Roberts @ 2026-01-29 21:41 UTC (permalink / raw)
  To: Bill Roberts, musl, dalias, dalias



On 1/29/26 3:18 PM, Szabolcs Nagy wrote:
> * Bill Roberts <bill.roberts@arm.com> [2026-01-27 20:07:25 -0600]:
>> +
>> +__attribute__((__visibility__("hidden")))
> 
> musl has its own hidden definition, use that.

Ahh, I thought I lost my mind. I accidentally git stashed that
with an abort I threw in there to ensure the testsuite was
running the right code. SMH. V3....

> 
>> +int __fesetround(int rm)
>> +{


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-01-29 21:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-28  2:07 [musl] [PATCH v2] aarch64: rewrite fenv routines in C using inline asm Bill Roberts
2026-01-29 21:18 ` Szabolcs Nagy
2026-01-29 21:41   ` Bill Roberts

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).