winsup/cygwin/ChangeLog:
* Makefile.in (DLL_OFILES): Add new fenv.o module.
(fenv_CFLAGS): New flags definition for fenv.o compile.
* autoload.cc (std_dll_init): Use fenv.h functions instead of direct
manipulation of x87 FPU registers.
* crt0.c (mainCRTStartup): Likewise.
* cygwin.din (feclearexcept, fegetexceptflag, feraiseexcept,
fesetexceptflag, fetestexcept, fegetround, fesetround, fegetenv,
feholdexcept, fesetenv, feupdateenv, fegetprec, fesetprec,
feenableexcept, fedisableexcept, fegetexcept, _feinitialise,
_fe_dfl_env, _fe_nomask_env): Export new functions and data items.
* fenv.cc: New file.
* posix.sgml: Update status of newly-implemented APIs.
* include/fenv.h: Likewise related header.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
2010-09-11 14:53:28 +08:00
|
|
|
/* fenv.h
|
|
|
|
|
|
|
|
This file is part of Cygwin.
|
|
|
|
|
|
|
|
This software is a copyrighted work licensed under the terms of the
|
|
|
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|
|
|
details. */
|
|
|
|
|
2016-03-30 06:12:22 +08:00
|
|
|
#ifndef _FENV_H
|
|
|
|
#define _FENV_H 1
|
winsup/cygwin/ChangeLog:
* Makefile.in (DLL_OFILES): Add new fenv.o module.
(fenv_CFLAGS): New flags definition for fenv.o compile.
* autoload.cc (std_dll_init): Use fenv.h functions instead of direct
manipulation of x87 FPU registers.
* crt0.c (mainCRTStartup): Likewise.
* cygwin.din (feclearexcept, fegetexceptflag, feraiseexcept,
fesetexceptflag, fetestexcept, fegetround, fesetround, fegetenv,
feholdexcept, fesetenv, feupdateenv, fegetprec, fesetprec,
feenableexcept, fedisableexcept, fegetexcept, _feinitialise,
_fe_dfl_env, _fe_nomask_env): Export new functions and data items.
* fenv.cc: New file.
* posix.sgml: Update status of newly-implemented APIs.
* include/fenv.h: Likewise related header.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
2010-09-11 14:53:28 +08:00
|
|
|
|
2016-03-15 10:24:29 +08:00
|
|
|
#include <sys/cdefs.h>
|
|
|
|
|
winsup/cygwin/ChangeLog:
* Makefile.in (DLL_OFILES): Add new fenv.o module.
(fenv_CFLAGS): New flags definition for fenv.o compile.
* autoload.cc (std_dll_init): Use fenv.h functions instead of direct
manipulation of x87 FPU registers.
* crt0.c (mainCRTStartup): Likewise.
* cygwin.din (feclearexcept, fegetexceptflag, feraiseexcept,
fesetexceptflag, fetestexcept, fegetround, fesetround, fegetenv,
feholdexcept, fesetenv, feupdateenv, fegetprec, fesetprec,
feenableexcept, fedisableexcept, fegetexcept, _feinitialise,
_fe_dfl_env, _fe_nomask_env): Export new functions and data items.
* fenv.cc: New file.
* posix.sgml: Update status of newly-implemented APIs.
* include/fenv.h: Likewise related header.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
2010-09-11 14:53:28 +08:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* Primary sources:
|
|
|
|
|
|
|
|
The Open Group Base Specifications Issue 6:
|
|
|
|
http://www.opengroup.org/onlinepubs/000095399/basedefs/fenv.h.html
|
|
|
|
|
|
|
|
C99 Language spec (draft n1256):
|
|
|
|
<url unknown>
|
|
|
|
|
2018-08-14 17:48:29 +08:00
|
|
|
Intel(R) 64 and IA-32 Architectures Software Developer's Manuals:
|
winsup/cygwin/ChangeLog:
* Makefile.in (DLL_OFILES): Add new fenv.o module.
(fenv_CFLAGS): New flags definition for fenv.o compile.
* autoload.cc (std_dll_init): Use fenv.h functions instead of direct
manipulation of x87 FPU registers.
* crt0.c (mainCRTStartup): Likewise.
* cygwin.din (feclearexcept, fegetexceptflag, feraiseexcept,
fesetexceptflag, fetestexcept, fegetround, fesetround, fegetenv,
feholdexcept, fesetenv, feupdateenv, fegetprec, fesetprec,
feenableexcept, fedisableexcept, fegetexcept, _feinitialise,
_fe_dfl_env, _fe_nomask_env): Export new functions and data items.
* fenv.cc: New file.
* posix.sgml: Update status of newly-implemented APIs.
* include/fenv.h: Likewise related header.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
2010-09-11 14:53:28 +08:00
|
|
|
http://www.intel.com/products/processor/manuals/
|
|
|
|
|
|
|
|
GNU C library manual pages:
|
|
|
|
http://www.gnu.org/software/libc/manual/html_node/Control-Functions.html
|
|
|
|
http://www.gnu.org/software/libc/manual/html_node/Rounding.html
|
|
|
|
http://www.gnu.org/software/libc/manual/html_node/FP-Exceptions.html
|
|
|
|
http://www.gnu.org/software/libc/manual/html_node/Status-bit-operations.html
|
|
|
|
|
|
|
|
Linux online man page(s):
|
|
|
|
http://linux.die.net/man/3/fegetexcept
|
|
|
|
|
|
|
|
The documentation quotes these sources for reference. All definitions and
|
|
|
|
code have been developed solely based on the information from these specs.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Represents the entire floating-point environment. The floating-point
|
|
|
|
environment refers collectively to any floating-point status flags and
|
|
|
|
control modes supported by the implementation.
|
|
|
|
In this implementation, the struct contains the state information from
|
|
|
|
the fstenv/fnstenv instructions and a copy of the SSE MXCSR, since GCC
|
|
|
|
uses SSE for a lot of floating-point operations. (Cygwin assumes i686
|
|
|
|
or above these days, as does the compiler.) */
|
|
|
|
|
|
|
|
typedef struct _fenv_t
|
|
|
|
{
|
|
|
|
struct _fpu_env_info {
|
|
|
|
unsigned int _fpu_cw; /* low 16 bits only. */
|
|
|
|
unsigned int _fpu_sw; /* low 16 bits only. */
|
|
|
|
unsigned int _fpu_tagw; /* low 16 bits only. */
|
|
|
|
unsigned int _fpu_ipoff;
|
|
|
|
unsigned int _fpu_ipsel;
|
|
|
|
unsigned int _fpu_opoff;
|
|
|
|
unsigned int _fpu_opsel; /* low 16 bits only. */
|
|
|
|
} _fpu;
|
|
|
|
unsigned int _sse_mxcsr;
|
|
|
|
} fenv_t;
|
|
|
|
|
|
|
|
/* Represents the floating-point status flags collectively, including
|
|
|
|
any status the implementation associates with the flags. A floating-point
|
|
|
|
status flag is a system variable whose value is set (but never cleared)
|
|
|
|
when a floating-point exception is raised, which occurs as a side effect
|
|
|
|
of exceptional floating-point arithmetic to provide auxiliary information.
|
|
|
|
A floating-point control mode is a system variable whose value may be
|
|
|
|
set by the user to affect the subsequent behavior of floating-point
|
2016-03-30 06:12:22 +08:00
|
|
|
arithmetic. */
|
winsup/cygwin/ChangeLog:
* Makefile.in (DLL_OFILES): Add new fenv.o module.
(fenv_CFLAGS): New flags definition for fenv.o compile.
* autoload.cc (std_dll_init): Use fenv.h functions instead of direct
manipulation of x87 FPU registers.
* crt0.c (mainCRTStartup): Likewise.
* cygwin.din (feclearexcept, fegetexceptflag, feraiseexcept,
fesetexceptflag, fetestexcept, fegetround, fesetround, fegetenv,
feholdexcept, fesetenv, feupdateenv, fegetprec, fesetprec,
feenableexcept, fedisableexcept, fegetexcept, _feinitialise,
_fe_dfl_env, _fe_nomask_env): Export new functions and data items.
* fenv.cc: New file.
* posix.sgml: Update status of newly-implemented APIs.
* include/fenv.h: Likewise related header.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
2010-09-11 14:53:28 +08:00
|
|
|
|
2016-03-30 06:12:22 +08:00
|
|
|
typedef __uint32_t fexcept_t;
|
winsup/cygwin/ChangeLog:
* Makefile.in (DLL_OFILES): Add new fenv.o module.
(fenv_CFLAGS): New flags definition for fenv.o compile.
* autoload.cc (std_dll_init): Use fenv.h functions instead of direct
manipulation of x87 FPU registers.
* crt0.c (mainCRTStartup): Likewise.
* cygwin.din (feclearexcept, fegetexceptflag, feraiseexcept,
fesetexceptflag, fetestexcept, fegetround, fesetround, fegetenv,
feholdexcept, fesetenv, feupdateenv, fegetprec, fesetprec,
feenableexcept, fedisableexcept, fegetexcept, _feinitialise,
_fe_dfl_env, _fe_nomask_env): Export new functions and data items.
* fenv.cc: New file.
* posix.sgml: Update status of newly-implemented APIs.
* include/fenv.h: Likewise related header.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
2010-09-11 14:53:28 +08:00
|
|
|
|
|
|
|
/* The <fenv.h> header shall define the following constants if and only
|
|
|
|
if the implementation supports the floating-point exception by means
|
|
|
|
of the floating-point functions feclearexcept(), fegetexceptflag(),
|
|
|
|
feraiseexcept(), fesetexceptflag(), and fetestexcept(). Each expands to
|
|
|
|
an integer constant expression with values such that bitwise-inclusive
|
|
|
|
ORs of all combinations of the constants result in distinct values. */
|
|
|
|
|
|
|
|
#define FE_DIVBYZERO (1 << 2)
|
|
|
|
#define FE_INEXACT (1 << 5)
|
|
|
|
#define FE_INVALID (1 << 0)
|
|
|
|
#define FE_OVERFLOW (1 << 3)
|
|
|
|
#define FE_UNDERFLOW (1 << 4)
|
|
|
|
|
|
|
|
/* The <fenv.h> header shall define the following constant, which is
|
|
|
|
simply the bitwise-inclusive OR of all floating-point exception
|
|
|
|
constants defined above: */
|
|
|
|
|
Keep the denormal-operand exception masked; modify FE_ALL_EXCEPT accordingly.
By excluding the denormal-operand exception from FE_ALL_EXCEPT, it will not
be possible anymore to UNmask this exception by means of the API defined by
/usr/include/fenv.h
Note: terminology has changed since IEEE Std 854-1987; denormalized numbers
are called subnormal numbers nowadays.
This modification has basically been motivated by the fact that it is also
not possible on Linux to manipulate the denormal-operand exception by means
of the interface as defined by /usr/include/fenv.h. This has been the state
of affairs on Linux since 2001 (Andreas Jaeger).
The exceptions required by the standard (IEEE Std 754), in case they can be
supported by the implementation, are:
FE_INEXACT, FE_UNDERFLOW, FE_OVERFLOW, FE_DIVBYZERO and FE_INVALID.
Although it is allowed to define additional exceptions, there is no reason
to support the "denormal-operand exception" in this case (fenv.h), because
the subnormal numbers can be handled almost as fast the normalized numbers
by the hardware of the x86/x86_64 architecture. Said differently, a reason
to trap on the input of subnormal numbers does not exist. At least that is
what William Kahan and others at Intel asserted around 2000.
(that is William Kahan of the K-C-S draft, the precursor to the standard)
This commit modifies winsup/cygwin/include/fenv.h as follows:
- redefines FE_ALL_EXCEPT from 0x3f to 0x3d
- removes the definition for FE_DENORMAL
- introduces __FE_DENORM (0x2) (enum in Linux also uses __FE_DENORM)
- introduces FE_ALL_EXCEPT_X86 (0x3f), i.e. ALL x86/x86_64 FP exceptions
2018-08-15 18:59:23 +08:00
|
|
|
/* in agreement w/ Linux the subnormal exception will always be masked */
|
|
|
|
#define FE_ALL_EXCEPT \
|
|
|
|
(FE_INEXACT | FE_UNDERFLOW | FE_OVERFLOW | FE_DIVBYZERO | FE_INVALID)
|
winsup/cygwin/ChangeLog:
* Makefile.in (DLL_OFILES): Add new fenv.o module.
(fenv_CFLAGS): New flags definition for fenv.o compile.
* autoload.cc (std_dll_init): Use fenv.h functions instead of direct
manipulation of x87 FPU registers.
* crt0.c (mainCRTStartup): Likewise.
* cygwin.din (feclearexcept, fegetexceptflag, feraiseexcept,
fesetexceptflag, fetestexcept, fegetround, fesetround, fegetenv,
feholdexcept, fesetenv, feupdateenv, fegetprec, fesetprec,
feenableexcept, fedisableexcept, fegetexcept, _feinitialise,
_fe_dfl_env, _fe_nomask_env): Export new functions and data items.
* fenv.cc: New file.
* posix.sgml: Update status of newly-implemented APIs.
* include/fenv.h: Likewise related header.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
2010-09-11 14:53:28 +08:00
|
|
|
|
|
|
|
/* The <fenv.h> header shall define the following constants if and only
|
|
|
|
if the implementation supports getting and setting the represented
|
|
|
|
rounding direction by means of the fegetround() and fesetround()
|
|
|
|
functions. Each expands to an integer constant expression whose values
|
|
|
|
are distinct non-negative vales. */
|
|
|
|
|
|
|
|
#define FE_DOWNWARD (1)
|
|
|
|
#define FE_TONEAREST (0)
|
|
|
|
#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)
|
|
|
|
|
|
|
|
/* The <fenv.h> header shall define the following constant, which
|
|
|
|
represents the default floating-point environment (that is, the one
|
|
|
|
installed at program startup) and has type pointer to const-qualified
|
|
|
|
fenv_t. It can be used as an argument to the functions within the
|
|
|
|
<fenv.h> header that manage the floating-point environment. */
|
|
|
|
|
|
|
|
extern const fenv_t *_fe_dfl_env;
|
|
|
|
#define FE_DFL_ENV (_fe_dfl_env)
|
|
|
|
|
2011-12-18 07:39:47 +08:00
|
|
|
/* Additional implementation-defined environments, with macro
|
winsup/cygwin/ChangeLog:
* Makefile.in (DLL_OFILES): Add new fenv.o module.
(fenv_CFLAGS): New flags definition for fenv.o compile.
* autoload.cc (std_dll_init): Use fenv.h functions instead of direct
manipulation of x87 FPU registers.
* crt0.c (mainCRTStartup): Likewise.
* cygwin.din (feclearexcept, fegetexceptflag, feraiseexcept,
fesetexceptflag, fetestexcept, fegetround, fesetround, fegetenv,
feholdexcept, fesetenv, feupdateenv, fegetprec, fesetprec,
feenableexcept, fedisableexcept, fegetexcept, _feinitialise,
_fe_dfl_env, _fe_nomask_env): Export new functions and data items.
* fenv.cc: New file.
* posix.sgml: Update status of newly-implemented APIs.
* include/fenv.h: Likewise related header.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
2010-09-11 14:53:28 +08:00
|
|
|
definitions beginning with FE_ and an uppercase letter,and having
|
|
|
|
type "pointer to const-qualified fenv_t",may also be specified by
|
|
|
|
the implementation. */
|
|
|
|
|
2016-03-15 10:24:29 +08:00
|
|
|
#if __GNU_VISIBLE
|
winsup/cygwin/ChangeLog:
* Makefile.in (DLL_OFILES): Add new fenv.o module.
(fenv_CFLAGS): New flags definition for fenv.o compile.
* autoload.cc (std_dll_init): Use fenv.h functions instead of direct
manipulation of x87 FPU registers.
* crt0.c (mainCRTStartup): Likewise.
* cygwin.din (feclearexcept, fegetexceptflag, feraiseexcept,
fesetexceptflag, fetestexcept, fegetround, fesetround, fegetenv,
feholdexcept, fesetenv, feupdateenv, fegetprec, fesetprec,
feenableexcept, fedisableexcept, fegetexcept, _feinitialise,
_fe_dfl_env, _fe_nomask_env): Export new functions and data items.
* fenv.cc: New file.
* posix.sgml: Update status of newly-implemented APIs.
* include/fenv.h: Likewise related header.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
2010-09-11 14:53:28 +08:00
|
|
|
/* If possible, the GNU C Library defines a macro FE_NOMASK_ENV which
|
|
|
|
represents an environment where every exception raised causes a trap
|
|
|
|
to occur. You can test for this macro using #ifdef. It is only defined
|
|
|
|
if _GNU_SOURCE is defined. */
|
|
|
|
extern const fenv_t *_fe_nomask_env;
|
|
|
|
#define FE_NOMASK_ENV (_fe_nomask_env)
|
2016-03-15 10:24:29 +08:00
|
|
|
#endif /* __GNU_VISIBLE */
|
winsup/cygwin/ChangeLog:
* Makefile.in (DLL_OFILES): Add new fenv.o module.
(fenv_CFLAGS): New flags definition for fenv.o compile.
* autoload.cc (std_dll_init): Use fenv.h functions instead of direct
manipulation of x87 FPU registers.
* crt0.c (mainCRTStartup): Likewise.
* cygwin.din (feclearexcept, fegetexceptflag, feraiseexcept,
fesetexceptflag, fetestexcept, fegetround, fesetround, fegetenv,
feholdexcept, fesetenv, feupdateenv, fegetprec, fesetprec,
feenableexcept, fedisableexcept, fegetexcept, _feinitialise,
_fe_dfl_env, _fe_nomask_env): Export new functions and data items.
* fenv.cc: New file.
* posix.sgml: Update status of newly-implemented APIs.
* include/fenv.h: Likewise related header.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
2010-09-11 14:53:28 +08:00
|
|
|
|
|
|
|
|
|
|
|
/* 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 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);
|
|
|
|
|
|
|
|
/* These are GNU extensions defined in glibc. */
|
|
|
|
extern int feenableexcept (int excepts);
|
|
|
|
extern int fedisableexcept (int excepts);
|
|
|
|
extern int fegetexcept (void);
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-03-30 06:12:22 +08:00
|
|
|
#endif /* _FENV_H */
|