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

Radek Barton <[email protected]>
Newsgroups gmane.comp.lib.newlib,gmane.os.cygwin.patches
Message-ID <GV4PR83MB0941761524523870C31AC5BD9270A@GV4PR83MB0941.EURPRD83.prod.outlook.com>
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 <[email protected]>
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
0001-newlib-fenv-AArch64-Cygwin-linking-fixes.patch (application/octet-stream, 4.5 KB)
From 17fd8e16061ab199d111b303a44c042ea43c4018 Mon Sep 17 00:00:00 2001
From: Radek Barton <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.