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
  http://www.open-std.org/jtc1/sc22//WG14/www/docs/n752.htm
  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
  functions

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2019-02-28 15:05:13 +01:00
parent 166913fb23
commit 40958b0d86
3 changed files with 52 additions and 33 deletions

View File

@ -391,18 +391,30 @@ fegetprec (void)
return (cw & FE_CW_PREC_MASK) >> FE_CW_PREC_SHIFT; return (cw & FE_CW_PREC_MASK) >> FE_CW_PREC_SHIFT;
} }
/* Changes the currently selected precision to prec. If prec does not /* http://www.open-std.org/jtc1/sc22//WG14/www/docs/n752.htm:
correspond to one of the supported rounding modes nothing is changed.
fesetprec returns zero if it changed the precision, or a nonzero value The fesetprec function establishes the precision represented by its
if the mode is not supported. */ 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 int
fesetprec (int prec) fesetprec (int prec)
{ {
unsigned short cw; unsigned short cw;
/* Will succeed for any valid value of the input parameter. */ /* Will succeed for any valid value of the input parameter. */
if (prec < FE_SINGLEPREC || prec > FE_EXTENDEDPREC) switch (prec)
return EINVAL; {
case FE_FLTPREC:
case FE_DBLPREC:
case FE_LDBLPREC:
break;
default:
return 0;
}
/* Get control word. */ /* Get control word. */
__asm__ volatile ("fnstcw %0" : "=m" (cw) : ); __asm__ volatile ("fnstcw %0" : "=m" (cw) : );
@ -415,7 +427,7 @@ fesetprec (int prec)
__asm__ volatile ("fldcw %0" :: "m" (cw)); __asm__ volatile ("fldcw %0" :: "m" (cw));
/* Indicate success. */ /* Indicate success. */
return 0; return 1;
} }
/* Set up the FPU and SSE environment at the start of execution. */ /* Set up the FPU and SSE environment at the start of execution. */

View File

@ -106,11 +106,14 @@ typedef __uint32_t fexcept_t;
#define FE_TOWARDZERO (3) #define FE_TOWARDZERO (3)
#define FE_UPWARD (2) #define FE_UPWARD (2)
/* Precision bit values. Not defined by Posix, but follow logically. */ /* Only Solaris and QNX implement fegetprec/fesetprec. As Solaris, use the
#define FE_SINGLEPREC (0) values defined by http://www.open-std.org/jtc1/sc22//WG14/www/docs/n752.htm
#define FE_RESERVEDPREC (1) QNX defines different values. */
#define FE_DOUBLEPREC (2) #if __MISC_VISIBLE
#define FE_EXTENDEDPREC (3) #define FE_FLTPREC (0)
#define FE_DBLPREC (2)
#define FE_LDBLPREC (3)
#endif
/* The <fenv.h> header shall define the following constant, which /* The <fenv.h> header shall define the following constant, which
represents the default floating-point environment (that is, the one 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 /* The following shall be declared as functions and may also be
defined as macros. Function prototypes shall be provided. */ defined as macros. Function prototypes shall be provided. */
extern int feclearexcept (int excepts); extern int feclearexcept (int __excepts);
extern int fegetexceptflag (fexcept_t *flagp, int excepts); extern int fegetexceptflag (fexcept_t *__flagp, int __excepts);
extern int feraiseexcept (int excepts); extern int feraiseexcept (int __excepts);
extern int fesetexceptflag (const fexcept_t *flagp, int excepts); extern int fesetexceptflag (const fexcept_t *__flagp, int __excepts);
extern int fetestexcept (int excepts); extern int fetestexcept (int __excepts);
extern int fegetround (void); extern int fegetround (void);
extern int fesetround (int round); extern int fesetround (int __round);
extern int fegetenv (fenv_t *envp); extern int fegetenv (fenv_t *__envp);
extern int feholdexcept (fenv_t *envp); extern int feholdexcept (fenv_t *__envp);
extern int fesetenv (const fenv_t *envp); extern int fesetenv (const fenv_t *__envp);
extern int feupdateenv (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);
#if __GNU_VISIBLE
/* These are GNU extensions defined in glibc. */ /* These are GNU extensions defined in glibc. */
extern int feenableexcept (int excepts); extern int feenableexcept (int __excepts);
extern int fedisableexcept (int excepts); extern int fedisableexcept (int __excepts);
extern int fegetexcept (void); extern int fegetexcept (void);
#endif
#if __MISC_VISIBLE
extern int fegetprec (void);
extern int fesetprec (int __prec);
#endif
#ifdef __INSIDE_CYGWIN__
/* This is Cygwin-custom, not from the standard, for use in the Cygwin CRT. */
extern void _feinitialise ();
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1319,8 +1319,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
fedisableexcept fedisableexcept
feenableexcept feenableexcept
fegetexcept fegetexcept
fegetprec
fesetprec
ffsl ffsl
ffsll ffsll
fgets_unlocked fgets_unlocked
@ -1443,6 +1441,8 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
acltotext acltotext
endmntent endmntent
facl facl
fegetprec
fesetprec
futimesat futimesat
getmntent getmntent
memalign memalign