[newlib-cygwin] Cygwin: fenv.h: Add feature test macros, fix values

Corinna Vinschen corinna@sourceware.org
Sat Mar 2 11:48:00 GMT 2019


commit 40958b0d867849199b38e2e2f04b3b9131a1e322
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Thu Feb 28 15:05:13 2019 +0100

    Cygwin: fenv.h: Add feature test macros, fix values
    - feenableexcept,fedisableexcept, fegetexcept are GNU-only
    - fegetprec, fesetprec are Solaris, use __MISC_VISIBLE
    - _feinitialise is Cygwin-internal only
    - Replace self-named FP precision values to values from
      as used by Solaris.
    - Change return value of fesetprec to adhere to the above document
      and Solaris.
    - Document fegetprec, fesetprec as Solaris functions, not as GNU
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

 winsup/cygwin/fenv.cc        | 26 +++++++++++++++------
 winsup/cygwin/include/fenv.h | 55 +++++++++++++++++++++++++-------------------
 winsup/doc/posix.xml         |  4 ++--
 3 files changed, 52 insertions(+), 33 deletions(-)

diff --git a/winsup/cygwin/fenv.cc b/winsup/cygwin/fenv.cc
index 3adc8a9..ebd93e8 100644
--- a/winsup/cygwin/fenv.cc
+++ b/winsup/cygwin/fenv.cc
@@ -391,18 +391,30 @@ fegetprec (void)
   return (cw & FE_CW_PREC_MASK) >> FE_CW_PREC_SHIFT;
-/*  Changes the currently selected precision to prec. If prec does not
-   correspond to one of the supported rounding modes nothing is changed.
-   fesetprec returns zero if it changed the precision, or a nonzero value
-   if the mode is not supported.  */
+/* 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). */
 fesetprec (int prec)
   unsigned short cw;
   /* Will succeed for any valid value of the input parameter.  */
-  if (prec < FE_SINGLEPREC || prec > FE_EXTENDEDPREC)
-    return EINVAL;
+  switch (prec)
+    {
+    case FE_FLTPREC:
+    case FE_DBLPREC:
+    case FE_LDBLPREC:
+      break;
+    default:
+      return 0;
+    }
   /* Get control word.  */
   __asm__ volatile ("fnstcw %0" : "=m" (cw) : );
@@ -415,7 +427,7 @@ fesetprec (int prec)
   __asm__ volatile ("fldcw %0" :: "m" (cw));
   /* Indicate success.  */
-  return 0;
+  return 1;
 /*  Set up the FPU and SSE environment at the start of execution.  */
diff --git a/winsup/cygwin/include/fenv.h b/winsup/cygwin/include/fenv.h
index 7ce3a93..0f7e074 100644
--- a/winsup/cygwin/include/fenv.h
+++ b/winsup/cygwin/include/fenv.h
@@ -106,11 +106,14 @@ typedef __uint32_t fexcept_t;
 #define FE_TOWARDZERO	(3)
 #define FE_UPWARD	(2)
-/*  Precision bit values.  Not defined by Posix, but follow logically.  */
-#define FE_SINGLEPREC	(0)
-#define FE_RESERVEDPREC	(1)
-#define FE_DOUBLEPREC	(2)
-#define FE_EXTENDEDPREC	(3)
+/* 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. */
+#define FE_FLTPREC	(0)
+#define FE_DBLPREC	(2)
+#define FE_LDBLPREC	(3)
 /*  The <fenv.h> header shall define the following constant, which
    represents the default floating-point environment (that is, the one
@@ -138,30 +141,34 @@ extern const fenv_t *_fe_nomask_env;
 /*  The following shall be declared as functions and may also be
    defined as macros. Function prototypes shall be provided.  */
-extern int feclearexcept (int excepts);
-extern int fegetexceptflag (fexcept_t *flagp, int excepts);
-extern int feraiseexcept (int excepts);
-extern int fesetexceptflag (const fexcept_t *flagp, int excepts);
-extern int fetestexcept (int excepts);
+extern int feclearexcept (int __excepts);
+extern int fegetexceptflag (fexcept_t *__flagp, int __excepts);
+extern int feraiseexcept (int __excepts);
+extern int fesetexceptflag (const fexcept_t *__flagp, int __excepts);
+extern int fetestexcept (int __excepts);
 extern int fegetround (void);
-extern int fesetround (int round);
-extern int fegetenv (fenv_t *envp);
-extern int feholdexcept (fenv_t *envp);
-extern int fesetenv (const fenv_t *envp);
-extern int feupdateenv (const fenv_t *envp);
-/* These are not defined in Posix, but make sense by obvious extension.  */
-extern int fegetprec (void);
-extern int fesetprec (int prec);
-/* This is Cygwin-custom, not from the standard, for use in the Cygwin CRT.  */
-extern void _feinitialise (void);
+extern int fesetround (int __round);
+extern int fegetenv (fenv_t *__envp);
+extern int feholdexcept (fenv_t *__envp);
+extern int fesetenv (const fenv_t *__envp);
+extern int feupdateenv (const fenv_t *__envp);
 /* These are GNU extensions defined in glibc.  */
-extern int feenableexcept (int excepts);
-extern int fedisableexcept (int excepts);
+extern int feenableexcept (int __excepts);
+extern int fedisableexcept (int __excepts);
 extern int fegetexcept (void);
+extern int fegetprec (void);
+extern int fesetprec (int __prec);
+#ifdef __INSIDE_CYGWIN__
+/* This is Cygwin-custom, not from the standard, for use in the Cygwin CRT.  */
+extern void _feinitialise ();
 #ifdef __cplusplus
diff --git a/winsup/doc/posix.xml b/winsup/doc/posix.xml
index 0755bed..d49cf55 100644
--- a/winsup/doc/posix.xml
+++ b/winsup/doc/posix.xml
@@ -1319,8 +1319,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
-    fegetprec
-    fesetprec
@@ -1443,6 +1441,8 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
+    fegetprec
+    fesetprec

More information about the Cygwin-cvs mailing list