[PATCH/QUESTION] newlib: fenv: AArch64 Cygwin linking fixes

Radek Barton radek.barton@microsoft.com
Mon Jun 16 11:31:06 GMT 2025


Hello.

This is more a question than patch submission: Without the attached changes, the Cygwin cannot be linked for AArch64 failing on:
```
ld: cannot export _fe_nomask_env: symbol not defined
ld: cannot export fedisableexcept: symbol not defined
ld: cannot export fegetexcept: symbol not defined
ld: cannot export fegetprec: symbol not defined
ld: cannot export fesetprec: symbol not defined
```
Can anybody share some insights why are those changes needed and whether there is a better way how to overcome this issue?

Note that the `feenableexcept`, `fedisableexcept`, `fegetexcept` implementations are similarly defined in `newlib/libc/machine/mips/machine/fenv-fp.h` for MIPS architecture as well.

Thank you,

Radek

---
>From 17fd8e16061ab199d111b303a44c042ea43c4018 Mon Sep 17 00:00:00 2001
From: Radek Barton <radek.barton@microsoft.com>
Date: Mon, 9 Jun 2025 08:55:18 +0200
Subject: [PATCH/QUESTION] newlib: fenv: AArch64 Cygwin linking fixes

---
 newlib/libc/machine/aarch64/machine/fenv-fp.h | 64 +++++++++++++++++++
 newlib/libc/machine/aarch64/sys/fenv.h        | 40 ------------
 newlib/libm/machine/aarch64/fenv.c            |  7 ++
 winsup/cygwin/fenv.c                          | 10 +++
 4 files changed, 81 insertions(+), 40 deletions(-)

diff --git a/newlib/libc/machine/aarch64/machine/fenv-fp.h b/newlib/libc/machine/aarch64/machine/fenv-fp.h
index d8ec3fc76..e42e2d873 100644
--- a/newlib/libc/machine/aarch64/machine/fenv-fp.h
+++ b/newlib/libc/machine/aarch64/machine/fenv-fp.h
@@ -154,3 +154,67 @@ feupdateenv(const fenv_t *__envp)
 	return (0);
 }
 
+#if __BSD_VISIBLE
+
+/* We currently provide no external definitions of the functions below. */
+
+__fenv_static inline int
+feenableexcept(int __mask)
+{
+	fenv_t __old_r, __new_r;
+
+	__mrs_fpcr(__old_r);
+	__new_r = __old_r | ((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
+	__msr_fpcr(__new_r);
+	return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+}
+
+__fenv_static inline int
+fedisableexcept(int __mask)
+{
+	fenv_t __old_r, __new_r;
+
+	__mrs_fpcr(__old_r);
+	__new_r = __old_r & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
+	__msr_fpcr(__new_r);
+	return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+}
+
+__fenv_static inline int
+fegetexcept(void)
+{
+	fenv_t __r;
+
+	__mrs_fpcr(__r);
+	return ((__r & _ENABLE_MASK) >> _FPUSW_SHIFT);
+}
+
+#endif /* __BSD_VISIBLE */
+
+#if defined(__CYGWIN__)
+
+/*  Returns the currently selected precision, represented by one of the
+   values of the defined precision macros.  */
+__fenv_static inline int
+fegetprec (void)
+{
+  return 0;
+}
+
+/* http://www.open-std.org/jtc1/sc22//WG14/www/docs/n752.htm:
+
+   The fesetprec function establishes the precision represented by its
+   argument prec.  If the argument does not match a precision macro, the
+   precision is not changed.
+
+   The fesetprec function returns a nonzero value if and only if the
+   argument matches a precision macro (that is, if and only if the requested
+   precision can be established). */
+__fenv_static inline int
+fesetprec (int prec)
+{
+  /* Indicate success.  */
+  return 1;
+}
+
+#endif /* __CYGWIN__ */
diff --git a/newlib/libc/machine/aarch64/sys/fenv.h b/newlib/libc/machine/aarch64/sys/fenv.h
index 6b0879269..1cfbeaaf4 100644
--- a/newlib/libc/machine/aarch64/sys/fenv.h
+++ b/newlib/libc/machine/aarch64/sys/fenv.h
@@ -77,44 +77,4 @@ extern const fenv_t	*_fe_dfl_env;
 #define	__mrs_fpsr(__r)	__asm __volatile("mrs %0, fpsr" : "=r" (__r))
 #define	__msr_fpsr(__r)	__asm __volatile("msr fpsr, %0" : : "r" (__r))
 
-
-#if __BSD_VISIBLE
-
-/* We currently provide no external definitions of the functions below. */
-
-static inline int
-feenableexcept(int __mask)
-{
-	fenv_t __old_r, __new_r;
-
-	__mrs_fpcr(__old_r);
-	__new_r = __old_r | ((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
-	__msr_fpcr(__new_r);
-	return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
-}
-
-static inline int
-fedisableexcept(int __mask)
-{
-	fenv_t __old_r, __new_r;
-
-	__mrs_fpcr(__old_r);
-	__new_r = __old_r & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
-	__msr_fpcr(__new_r);
-	return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
-}
-
-static inline int
-fegetexcept(void)
-{
-	fenv_t __r;
-
-	__mrs_fpcr(__r);
-	return ((__r & _ENABLE_MASK) >> _FPUSW_SHIFT);
-}
-
-#endif /* __BSD_VISIBLE */
-
-
-
 #endif	/* !_FENV_H_ */
diff --git a/newlib/libm/machine/aarch64/fenv.c b/newlib/libm/machine/aarch64/fenv.c
index 3ffe23441..86f8cd5aa 100644
--- a/newlib/libm/machine/aarch64/fenv.c
+++ b/newlib/libm/machine/aarch64/fenv.c
@@ -55,3 +55,10 @@ extern inline int feupdateenv(const fenv_t *__envp);
 extern inline int feenableexcept(int __mask);
 extern inline int fedisableexcept(int __mask);
 extern inline int fegetexcept(void);
+
+#if defined(__CYGWIN__)
+
+extern inline int fegetprec(void);
+extern inline int fesetprec(int prec);
+
+#endif /* CYGWIN */
diff --git a/winsup/cygwin/fenv.c b/winsup/cygwin/fenv.c
index 80f7cc52c..1558f76c2 100644
--- a/winsup/cygwin/fenv.c
+++ b/winsup/cygwin/fenv.c
@@ -3,3 +3,13 @@
    being called from mainCRTStartup in crt0.o. */
 void _feinitialise (void)
 {}
+
+#if defined(__aarch64__)
+
+#include <fenv.h>
+#include <stddef.h>
+
+/* _fe_nomask_env is exported by cygwin.din but not used at all for AArch64. */
+const fenv_t *_fe_nomask_env = NULL;
+
+#endif /* __aarch64__ */
-- 
2.49.0.vfs.0.3

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-newlib-fenv-AArch64-Cygwin-linking-fixes.patch
Type: application/octet-stream
Size: 4619 bytes
Desc: 0001-newlib-fenv-AArch64-Cygwin-linking-fixes.patch
URL: <https://sourceware.org/pipermail/newlib/attachments/20250616/6dded268/attachment-0001.obj>


More information about the Newlib mailing list