diff --git a/winsup/cygwin/fenv.cc b/winsup/cygwin/fenv.cc index 066704b40..3adc8a954 100644 --- a/winsup/cygwin/fenv.cc +++ b/winsup/cygwin/fenv.cc @@ -12,6 +12,11 @@ details. */ #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) @@ -417,7 +422,7 @@ fesetprec (int prec) void _feinitialise (void) { - unsigned int edx, eax, mxcsr; + unsigned int edx, eax; /* Check for presence of SSE: invoke CPUID #1, check EDX bit 25. */ eax = 1; @@ -431,11 +436,13 @@ _feinitialise (void) /* 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. */ - mxcsr = FE_ALL_EXCEPT << FE_SSE_EXCEPT_MASK_SHIFT; + + /* 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. */ + /* Setup unmasked environment, but leave __FE_DENORM masked. */ feenableexcept (FE_ALL_EXCEPT); fegetenv (&fe_nomask_env); diff --git a/winsup/cygwin/include/fenv.h b/winsup/cygwin/include/fenv.h index 7ec5d4d7d..7ce3a9340 100644 --- a/winsup/cygwin/include/fenv.h +++ b/winsup/cygwin/include/fenv.h @@ -87,16 +87,13 @@ typedef __uint32_t fexcept_t; #define FE_OVERFLOW (1 << 3) #define FE_UNDERFLOW (1 << 4) -/* This is not defined by Posix, but since x87 supports it we provide - a definition according to the same naming scheme used above. */ -#define FE_DENORMAL (1 << 1) - /* The header shall define the following constant, which is simply the bitwise-inclusive OR of all floating-point exception constants defined above: */ -#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID \ - | FE_OVERFLOW | FE_UNDERFLOW | FE_DENORMAL) +/* 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