[PATCH] newlib: add dummy implementations of fe{get,set}prec for Aarch64 Cygwin

Radek Barton <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <DB9PR83MB09237810256ACC7321E47D8E9243A@DB9PR83MB0923.EURPRD83.prod.outlook.com>
Hello.

Albeit Aarch64 does not support setting floating point operations precisions at runtime `cygwin1.dll` exports `fegetprec` and `fesetprec` functions leading to undefined references when linking. This patch adds their dummy implementations in a similar way how they are defined in `newlib/libc/machine/shared_x86/sys/fenv.h`, resp. in `/newlib/libm/machine/shared_x86/fenv.c`.

Alternative fix would be to modify `winsup/cygwin/scripts/mkimport` and `winsup/cygwin/scripts/gendef` scripts so they would exclude those from being exported to the DLL upon specific label in `winsup/cygwin/cygwin.din`, e.g.:

```
fegetprec NOSIGFE NOARM64
fesetprec NOSIGFE NOARM64
```

The same options applies to `_fe_nomask_env` which would be for the first option sent as a separate patch as it changes only `winsup` codebase.

Which one would you prefer?

Radek

---
From 0ea739b8eef37d433712c185e0562c9f3142b86c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Radek=20Barto=C5=88?= <[email protected]>
Date: Thu, 3 Jul 2025 12:02:03 +0200
Subject: [PATCH] newlib: add dummy implementations of fe{get,set}prec
 for Aarch64 Cygwin
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Radek Bartoň <[email protected]>
---
 newlib/libc/machine/aarch64/sys/fenv.h | 24 ++++++++++++++++++++-
 newlib/libm/machine/aarch64/fenv.c     | 30 ++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/newlib/libc/machine/aarch64/sys/fenv.h b/newlib/libc/machine/aarch64/sys/fenv.h
index 212612725..0e4e7f492 100644
--- a/newlib/libc/machine/aarch64/sys/fenv.h
+++ b/newlib/libc/machine/aarch64/sys/fenv.h
@@ -61,7 +61,14 @@ typedef	__uint64_t	fexcept_t;
 			 FE_UPWARD | FE_TOWARDZERO)
 #define	_ROUND_SHIFT	22
 
-
+/* Only Solaris and QNX implement fegetprec/fesetprec.  As Solaris, use the
+   values defined by http://www.open-std.org/jtc1/sc22//WG14/www/docs/n752.htm
+   QNX defines different values. */
+#if __MISC_VISIBLE
+#define FE_FLTPREC	(0)
+#define FE_DBLPREC	(2)
+#define FE_LDBLPREC	(3)
+#endif
 
 /* Default floating-point environment */
 extern const fenv_t	*_fe_dfl_env;
@@ -115,6 +122,21 @@ fegetexcept(void)
 
 #endif /* __BSD_VISIBLE */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
+#ifdef __CYGWIN__
+
+#if __MISC_VISIBLE
+int fegetprec (void);
+int fesetprec (int __prec);
+#endif
+
+#endif /* __CYGWIN__ */
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif	/* !_FENV_H_ */
diff --git a/newlib/libm/machine/aarch64/fenv.c b/newlib/libm/machine/aarch64/fenv.c
index 3ffe23441..3f3459e9d 100644
--- a/newlib/libm/machine/aarch64/fenv.c
+++ b/newlib/libm/machine/aarch64/fenv.c
@@ -55,3 +55,33 @@ 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__)
+
+/* Returns the currently selected precision, represented by one of the
+   values of the defined precision macros. */
+int
+fegetprec (void)
+{
+  /* AArch64 doesn't have configurable precision.
+     Return a fixed value indicating double precision (most common). */
+  return FE_DBLPREC;
+}
+
+/* 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). */
+int
+fesetprec (int prec)
+{
+  /* Aarch64 doesn't support changing precision at runtime. */
+  return 0; // return failure
+}
+
+#endif
-- 
2.49.0.vfs.0.4
0001-newlib-add-dummy-implementations-of-fe-get-set-prec-for-Aarch64-Cygwin.patch (application/octet-stream, 2.9 KB)
From 0ea739b8eef37d433712c185e0562c9f3142b86c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Radek=20Barto=C5=88?= <[email protected]>
Date: Thu, 3 Jul 2025 12:02:03 +0200
Subject: [PATCH] newlib: add dummy implementations of fe{get,set}prec
 for Aarch64 Cygwin
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Radek Bartoň <[email protected]>
---
 newlib/libc/machine/aarch64/sys/fenv.h | 24 ++++++++++++++++++++-
 newlib/libm/machine/aarch64/fenv.c     | 30 ++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/newlib/libc/machine/aarch64/sys/fenv.h b/newlib/libc/machine/aarch64/sys/fenv.h
index 212612725..0e4e7f492 100644
--- a/newlib/libc/machine/aarch64/sys/fenv.h
+++ b/newlib/libc/machine/aarch64/sys/fenv.h
@@ -61,7 +61,14 @@ typedef	__uint64_t	fexcept_t;
 			 FE_UPWARD | FE_TOWARDZERO)
 #define	_ROUND_SHIFT	22
 
-
+/* Only Solaris and QNX implement fegetprec/fesetprec.  As Solaris, use the
+   values defined by http://www.open-std.org/jtc1/sc22//WG14/www/docs/n752.htm
+   QNX defines different values. */
+#if __MISC_VISIBLE
+#define FE_FLTPREC	(0)
+#define FE_DBLPREC	(2)
+#define FE_LDBLPREC	(3)
+#endif
 
 /* Default floating-point environment */
 extern const fenv_t	*_fe_dfl_env;
@@ -115,6 +122,21 @@ fegetexcept(void)
 
 #endif /* __BSD_VISIBLE */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
+#ifdef __CYGWIN__
+
+#if __MISC_VISIBLE
+int fegetprec (void);
+int fesetprec (int __prec);
+#endif
+
+#endif /* __CYGWIN__ */
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif	/* !_FENV_H_ */
diff --git a/newlib/libm/machine/aarch64/fenv.c b/newlib/libm/machine/aarch64/fenv.c
index 3ffe23441..3f3459e9d 100644
--- a/newlib/libm/machine/aarch64/fenv.c
+++ b/newlib/libm/machine/aarch64/fenv.c
@@ -55,3 +55,33 @@ 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__)
+
+/* Returns the currently selected precision, represented by one of the
+   values of the defined precision macros. */
+int
+fegetprec (void)
+{
+  /* AArch64 doesn't have configurable precision.
+     Return a fixed value indicating double precision (most common). */
+  return FE_DBLPREC;
+}
+
+/* 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). */
+int
+fesetprec (int prec)
+{
+  /* Aarch64 doesn't support changing precision at runtime. */
+  return 0; // return failure
+}
+
+#endif
-- 
2.49.0.vfs.0.4
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.