From: Corinna Vinschen Date: Wed, 24 Mar 2021 09:58:56 +0000 (+0100) Subject: fenv: drop Cygwin-specific implementation in favor of newlib code X-Git-Tag: cygwin-3_3_0-release~256 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=3b22d722555ab88ff4a9181220bbfc3fa59b94ee;p=newlib-cygwin.git fenv: drop Cygwin-specific implementation in favor of newlib code Drop the Cygwin-specific fenv.cc and fenv.h file and use the equivalent newlib functionality now, so we have at least one example of a user for this new mechanism. fenv.c: allow _feinitialise to be called from Cygwin startup code fenv.h: add declarations for fegetprec and fesetprec for Cygwin only. Fix a comment. Signed-off-by: Corinna Vinschen --- diff --git a/newlib/libc/machine/shared_x86/sys/fenv.h b/newlib/libc/machine/shared_x86/sys/fenv.h index 0cf152a97..e0408fe5b 100644 --- a/newlib/libc/machine/shared_x86/sys/fenv.h +++ b/newlib/libc/machine/shared_x86/sys/fenv.h @@ -163,11 +163,20 @@ int fedisableexcept (int __excepts); int fegetexcept (void); #endif /* __GNU_VISIBLE */ +#ifdef __CYGWIN__ + +#if __MISC_VISIBLE +int fegetprec (void); +int fesetprec (int __prec); +#endif + #ifdef __INSIDE_CYGWIN__ -/* This is Cygwin-custom, not from the standard, for use in the Cygwin CRT. */ +/* Cygwin-internal ONLY. */ extern void _feinitialise (); #endif +#endif /* __CYGWIN__ */ + #ifdef __cplusplus } #endif diff --git a/newlib/libm/machine/shared_x86/fenv.c b/newlib/libm/machine/shared_x86/fenv.c index ccc08e2d8..8d1f1ad7f 100644 --- a/newlib/libm/machine/shared_x86/fenv.c +++ b/newlib/libm/machine/shared_x86/fenv.c @@ -63,8 +63,10 @@ static inline bool use_sse(void) return false; } +#ifndef __CYGWIN__ /* forward declaration */ static void _feinitialise (void); +#endif /* This function enables traps for each of the exceptions as indicated by the parameter except. The individual exceptions are described in @@ -449,7 +451,10 @@ fesetprec (int prec) #endif /* Set up the FPU and SSE environment at the start of execution. */ -static void +#ifndef __CYGWIN__ +static +#endif +void _feinitialise (void) { extern fenv_t __fe_dfl_env; diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 73d9b37fd..ff6798867 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -288,7 +288,6 @@ DLL_OFILES:= \ exec.o \ external.o \ fcntl.o \ - fenv.o \ fhandler.o \ fhandler_clipboard.o \ fhandler_console.o \ diff --git a/winsup/cygwin/fenv.cc b/winsup/cygwin/fenv.cc deleted file mode 100644 index 69304b513..000000000 --- a/winsup/cygwin/fenv.cc +++ /dev/null @@ -1,466 +0,0 @@ -/* fenv.cc - -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. */ - -#include "winsup.h" -#include "fenv.h" -#include "errno.h" -#include "wincap.h" -#include - -/* x87 supports subnormal numbers so we need it below. */ -#define __FE_DENORM (1 << 1) -/* mask (= 0x3f) to disable all exceptions at initialization */ -#define __FE_ALL_EXCEPT_X86 (FE_ALL_EXCEPT | __FE_DENORM) - -/* Mask and shift amount for rounding bits. */ -#define FE_CW_ROUND_MASK (0x0c00) -#define FE_CW_ROUND_SHIFT (10) -/* Same, for SSE MXCSR. */ -#define FE_MXCSR_ROUND_MASK (0x6000) -#define FE_MXCSR_ROUND_SHIFT (13) - -/* Mask and shift amount for precision bits. */ -#define FE_CW_PREC_MASK (0x0300) -#define FE_CW_PREC_SHIFT (8) - -/* In x87, exception status bits and mask bits occupy - corresponding bit positions in the status and control - registers, respectively. In SSE, they are both located - in the control-and-status register, with the status bits - corresponding to the x87 positions, and the mask bits - shifted by this amount to the left. */ -#define FE_SSE_EXCEPT_MASK_SHIFT (7) - -/* These are writable so we can initialise them at startup. */ -static fenv_t fe_nomask_env; - -/* These pointers provide the outside world with read-only access to them. */ -const fenv_t *_fe_nomask_env = &fe_nomask_env; - -/* Although Cygwin assumes i686 or above (hence SSE available) these - days, and the compiler feels free to use it (depending on compile- - time flags of course), we should avoid needlessly breaking any - purely integer mode apps (or apps compiled with -mno-sse), so we - only manage SSE state in this fenv module if we detect that SSE - instructions are available at runtime. If we didn't do this, all - applications run on older machines would bomb out with an invalid - instruction exception right at startup; let's not be *that* WJM! */ -static bool use_sse = false; - -/* This function enables traps for each of the exceptions as indicated - by the parameter except. The individual exceptions are described in - [ ... glibc manual xref elided ...]. Only the specified exceptions are - enabled, the status of the other exceptions is not changed. - The function returns the previous enabled exceptions in case the - operation was successful, -1 otherwise. */ -int -feenableexcept (int excepts) -{ - unsigned short cw, old_cw; - unsigned int mxcsr = 0; - - if (excepts & ~FE_ALL_EXCEPT) - return -1; - - /* Get control words. */ - __asm__ volatile ("fnstcw %0" : "=m" (old_cw) : ); - if (use_sse) - __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr) : ); - - /* Enable exceptions by clearing mask bits. */ - cw = old_cw & ~excepts; - mxcsr &= ~(excepts << FE_SSE_EXCEPT_MASK_SHIFT); - - /* Store updated control words. */ - __asm__ volatile ("fldcw %0" :: "m" (cw)); - if (use_sse) - __asm__ volatile ("ldmxcsr %0" :: "m" (mxcsr)); - - /* Return old value. We assume SSE and x87 stay in sync. Note that - we are returning a mask of enabled exceptions, which is the opposite - of the flags in the register, which are set to disable (mask) their - related exceptions. */ - return (~old_cw) & FE_ALL_EXCEPT; -} - -/* This function disables traps for each of the exceptions as indicated - by the parameter except. The individual exceptions are described in - [ ... glibc manual xref elided ...]. Only the specified exceptions are - disabled, the status of the other exceptions is not changed. - The function returns the previous enabled exceptions in case the - operation was successful, -1 otherwise. */ -int -fedisableexcept (int excepts) -{ - unsigned short cw, old_cw; - unsigned int mxcsr = 0; - - if (excepts & ~FE_ALL_EXCEPT) - return -1; - - /* Get control words. */ - __asm__ volatile ("fnstcw %0" : "=m" (old_cw) : ); - if (use_sse) - __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr) : ); - - /* Disable exceptions by setting mask bits. */ - cw = old_cw | excepts; - mxcsr |= (excepts << FE_SSE_EXCEPT_MASK_SHIFT); - - /* Store updated control words. */ - __asm__ volatile ("fldcw %0" :: "m" (cw)); - if (use_sse) - __asm__ volatile ("ldmxcsr %0" :: "m" (mxcsr)); - - /* Return old value. We assume SSE and x87 stay in sync. Note that - we are returning a mask of enabled exceptions, which is the opposite - of the flags in the register, which are set to disable (mask) their - related exceptions. */ - return (~old_cw) & FE_ALL_EXCEPT; -} - -/* This function returns a bitmask of all currently enabled exceptions. It - returns -1 in case of failure. */ -int -fegetexcept (void) -{ - unsigned short cw; - - /* Get control word. We assume SSE and x87 stay in sync. */ - __asm__ volatile ("fnstcw %0" : "=m" (cw) : ); - - /* Exception is *dis*abled when mask bit is set. */ - return (~cw) & FE_ALL_EXCEPT; -} - -/* Store the floating-point environment in the variable pointed to by envp. - The function returns zero in case the operation was successful, a non-zero - value otherwise. */ -int -fegetenv (fenv_t *envp) -{ - /* fnstenv disables all exceptions in the x87 FPU; as this is not what is - desired here, reload the cfg saved from the x87 FPU, back to the FPU */ - __asm__ volatile ("fnstenv %0\n\ - fldenv %0" - : "=m" (envp->_fpu) : ); - if (use_sse) - __asm__ volatile ("stmxcsr %0" : "=m" (envp->_sse_mxcsr) : ); - return 0; -} - -/* Store the current floating-point environment in the object pointed to - by envp. Then clear all exception flags, and set the FPU to trap no - exceptions. Not all FPUs support trapping no exceptions; if feholdexcept - cannot set this mode, it returns nonzero value. If it succeeds, it - returns zero. */ -int -feholdexcept (fenv_t *envp) -{ - unsigned int mxcsr; - fegetenv (envp); - mxcsr = envp->_sse_mxcsr & ~FE_ALL_EXCEPT; - if (use_sse) - __asm__ volatile ("ldmxcsr %0" :: "m" (mxcsr)); - __asm__ volatile ("fnclex"); - fedisableexcept (FE_ALL_EXCEPT); - return 0; -} - -/* Set the floating-point environment to that described by envp. The - function returns zero in case the operation was successful, a non-zero - value otherwise. */ -int -fesetenv (const fenv_t *envp) -{ - __asm__ volatile ("fldenv %0" :: "m" (envp->_fpu) ); - if (use_sse) - __asm__ volatile ("ldmxcsr %0" :: "m" (envp->_sse_mxcsr)); - return 0; -} - -/* Like fesetenv, this function sets the floating-point environment to - that described by envp. However, if any exceptions were flagged in the - status word before feupdateenv was called, they remain flagged after - the call. In other words, after feupdateenv is called, the status - word is the bitwise OR of the previous status word and the one saved - in envp. The function returns zero in case the operation was successful, - a non-zero value otherwise. */ -int -feupdateenv (const fenv_t *envp) -{ - fenv_t envcopy; - unsigned int mxcsr = 0; - unsigned short sw; - - /* Don't want to modify *envp, but want to update environment atomically, - so take a copy and merge the existing exceptions into it. */ - memcpy (&envcopy, envp, sizeof *envp); - __asm__ volatile ("fnstsw %0" : "=m" (sw) : ); - if (use_sse) - __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr) : ); - envcopy._fpu._fpu_sw |= (sw & FE_ALL_EXCEPT); - envcopy._sse_mxcsr |= (mxcsr & FE_ALL_EXCEPT); - - return fesetenv (&envcopy); -} - -/* This function clears all of the supported exception flags indicated by - excepts. The function returns zero in case the operation was successful, - a non-zero value otherwise. */ -int -feclearexcept (int excepts) -{ - fenv_t fenv; - - if (excepts & ~FE_ALL_EXCEPT) - return EINVAL; - - /* Need to save/restore whole environment to modify status word. */ - fegetenv (&fenv); - - /* Mask undesired bits out. */ - fenv._fpu._fpu_sw &= ~excepts; - fenv._sse_mxcsr &= ~excepts; - - /* Set back into FPU state. */ - return fesetenv (&fenv); -} - -/* This function raises the supported exceptions indicated by - excepts. If more than one exception bit in excepts is set the order - in which the exceptions are raised is undefined except that overflow - (FE_OVERFLOW) or underflow (FE_UNDERFLOW) are raised before inexact - (FE_INEXACT). Whether for overflow or underflow the inexact exception - is also raised is also implementation dependent. The function returns - zero in case the operation was successful, a non-zero value otherwise. */ -int -feraiseexcept (int excepts) -{ - fenv_t fenv; - - if (excepts & ~FE_ALL_EXCEPT) - return EINVAL; - - /* Need to save/restore whole environment to modify status word. */ - __asm__ volatile ("fnstenv %0" : "=m" (fenv) : ); - - /* Set desired exception bits. */ - fenv._fpu._fpu_sw |= excepts; - - /* Set back into FPU state. */ - __asm__ volatile ("fldenv %0" :: "m" (fenv)); - - /* And trigger them - whichever are unmasked. */ - __asm__ volatile ("fwait"); - - return 0; -} - -/* Test whether the exception flags indicated by the parameter except - are currently set. If any of them are, a nonzero value is returned - which specifies which exceptions are set. Otherwise the result is zero. */ -int -fetestexcept (int excepts) -{ - unsigned short sw; - unsigned int mxcsr = 0; - - if (excepts & ~FE_ALL_EXCEPT) - return EINVAL; - - /* Get status registers. */ - __asm__ volatile ("fnstsw %0" : "=m" (sw) : ); - if (use_sse) - __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr) : ); - - /* Mask undesired bits out and return result. */ - return (sw | mxcsr) & excepts; -} -/* This function stores in the variable pointed to by flagp an - implementation-defined value representing the current setting of the - exception flags indicated by excepts. The function returns zero in - case the operation was successful, a non-zero value otherwise. */ -int -fegetexceptflag (fexcept_t *flagp, int excepts) -{ - unsigned short sw; - unsigned int mxcsr = 0; - - if (excepts & ~FE_ALL_EXCEPT) - return EINVAL; - - /* Get status registers. */ - __asm__ volatile ("fnstsw %0" : "=m" (sw) : ); - if (use_sse) - __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr) : ); - - /* Mask undesired bits out and set result. */ - *flagp = (sw | mxcsr) & excepts; - - return 0; -} - -/* This function restores the flags for the exceptions indicated by - excepts to the values stored in the variable pointed to by flagp. */ -int -fesetexceptflag (const fexcept_t *flagp, int excepts) -{ - fenv_t fenv; - - if (excepts & ~FE_ALL_EXCEPT) - return EINVAL; - - /* Need to save/restore whole environment to modify status word. */ - fegetenv (&fenv); - - /* Set/Clear desired exception bits. */ - fenv._fpu._fpu_sw &= ~excepts; - fenv._fpu._fpu_sw |= excepts & *flagp; - fenv._sse_mxcsr &= ~excepts; - fenv._sse_mxcsr |= excepts & *flagp; - - /* Set back into FPU state. */ - return fesetenv (&fenv); -} - -/* Returns the currently selected rounding mode, represented by one of the - values of the defined rounding mode macros. */ -int -fegetround (void) -{ - unsigned short cw; - - /* Get control word. We assume SSE and x87 stay in sync. */ - __asm__ volatile ("fnstcw %0" : "=m" (cw) : ); - - return (cw & FE_CW_ROUND_MASK) >> FE_CW_ROUND_SHIFT; -} - -/* Changes the currently selected rounding mode to round. If round does - not correspond to one of the supported rounding modes nothing is changed. - fesetround returns zero if it changed the rounding mode, a nonzero value - if the mode is not supported. */ -int -fesetround (int round) -{ - unsigned short cw; - unsigned int mxcsr = 0; - - /* Will succeed for any valid value of the input parameter. */ - if (round < FE_TONEAREST || round > FE_TOWARDZERO) - return EINVAL; - - /* Get control words. */ - __asm__ volatile ("fnstcw %0" : "=m" (cw) : ); - if (use_sse) - __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr) : ); - - /* Twiddle bits. */ - cw &= ~FE_CW_ROUND_MASK; - cw |= (round << FE_CW_ROUND_SHIFT); - mxcsr &= ~FE_MXCSR_ROUND_MASK; - mxcsr |= (round << FE_MXCSR_ROUND_SHIFT); - - /* Set back into FPU state. */ - __asm__ volatile ("fldcw %0" :: "m" (cw)); - if (use_sse) - __asm__ volatile ("ldmxcsr %0" :: "m" (mxcsr)); - - /* Indicate success. */ - return 0; -} - -/* Returns the currently selected precision, represented by one of the - values of the defined precision macros. */ -int -fegetprec (void) -{ - unsigned short cw; - - /* Get control word. */ - __asm__ volatile ("fnstcw %0" : "=m" (cw) : ); - - return (cw & FE_CW_PREC_MASK) >> FE_CW_PREC_SHIFT; -} - -/* 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. */ - switch (prec) - { - case FE_FLTPREC: - case FE_DBLPREC: - case FE_LDBLPREC: - break; - default: - return 0; - } - - /* Get control word. */ - __asm__ volatile ("fnstcw %0" : "=m" (cw) : ); - - /* Twiddle bits. */ - cw &= ~FE_CW_PREC_MASK; - cw |= (prec << FE_CW_PREC_SHIFT); - - /* Set back into FPU state. */ - __asm__ volatile ("fldcw %0" :: "m" (cw)); - - /* Indicate success. */ - return 1; -} - -/* Set up the FPU and SSE environment at the start of execution. */ -void -_feinitialise (void) -{ - unsigned int edx, eax; - extern fenv_t __fe_dfl_env; - - /* Check for presence of SSE: invoke CPUID #1, check EDX bit 25. */ - eax = 1; - __asm__ volatile ("cpuid" : "=d" (edx), "+a" (eax) :: "%ecx", "%ebx"); - /* If this flag isn't set we'll avoid trying to execute any SSE. */ - if ((edx & (1 << 25)) != 0) - use_sse = true; - - /* Reset FPU: extended prec, all exceptions cleared and masked off. */ - __asm__ volatile ("fninit"); - /* The default cw value, 0x37f, is rounding mode zero. The MXCSR has - no precision control, so the only thing to do is set the exception - mask bits. */ - - /* initialize the MXCSR register: mask all exceptions */ - unsigned int mxcsr = __FE_ALL_EXCEPT_X86 << FE_SSE_EXCEPT_MASK_SHIFT; - if (use_sse) - __asm__ volatile ("ldmxcsr %0" :: "m" (mxcsr)); - - /* Setup unmasked environment, but leave __FE_DENORM masked. */ - feenableexcept (FE_ALL_EXCEPT); - fegetenv (&fe_nomask_env); - - /* Restore default exception masking (all masked). */ - fedisableexcept (FE_ALL_EXCEPT); - - /* Finally cache state as default environment. */ - fegetenv (&__fe_dfl_env); -} - diff --git a/winsup/cygwin/include/fenv.h b/winsup/cygwin/include/fenv.h deleted file mode 100644 index 0f7e07445..000000000 --- a/winsup/cygwin/include/fenv.h +++ /dev/null @@ -1,177 +0,0 @@ -/* 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. */ - -#ifndef _FENV_H -#define _FENV_H 1 - -#include - -#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): - - - Intel(R) 64 and IA-32 Architectures Software Developer's Manuals: - 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 - arithmetic. */ - -typedef __uint32_t fexcept_t; - -/* The 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 header shall define the following constant, which is - simply the bitwise-inclusive OR of all floating-point exception - constants defined above: */ - -/* 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) - -/* The 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) - -/* 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 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 - header that manage the floating-point environment. */ - -extern const fenv_t *_fe_dfl_env; -#define FE_DFL_ENV (_fe_dfl_env) - -/* Additional implementation-defined environments, with macro - definitions beginning with FE_ and an uppercase letter,and having - type "pointer to const-qualified fenv_t",may also be specified by - the implementation. */ - -#if __GNU_VISIBLE -/* 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) -#endif /* __GNU_VISIBLE */ - - -/* 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); - -#if __GNU_VISIBLE -/* These are GNU extensions defined in glibc. */ -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 -} -#endif - -#endif /* _FENV_H */