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;
}
/* 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). */
int
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. */

View File

@ -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. */
#if __MISC_VISIBLE
#define FE_FLTPREC (0)
#define FE_DBLPREC (2)
#define FE_LDBLPREC (3)
#endif
/* 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);
#if __GNU_VISIBLE
/* 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);
#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
}

View File

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