fenv.h: Change fexcept_t to integral type for compatibility

On Linux and in Mingw-w64, fexcept_t is defined as type unsigned short.
There are packages in the wild which rely on the fact that fexcept_t is
an integral type.  We're changing the internal handling to use the bits
just as in GLibc, so only the 6 lowest bits are used to reflect the hw
bits.  We even change the header file guard to reflect GLibc for compatibility.

	* include/fenv.h (_FENV_H): Rename from _FENV_H_ and set to 1 as in
	GLibc's header.
	(fexcept_t): Change to __uint16_t to be an integral type as in GLibc.
	* fenv.cc (fegetexceptflag): Align to the *flagp's type change.
	(fesetexceptflag): Ditto.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2016-03-30 00:12:22 +02:00
parent fbc4a0827b
commit 279aaeb5c7
2 changed files with 9 additions and 14 deletions

View File

@ -295,9 +295,8 @@ fegetexceptflag (fexcept_t *flagp, int excepts)
if (use_sse) if (use_sse)
__asm__ volatile ("stmxcsr %0" : "=m" (mxcsr) : ); __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr) : );
/* Mask undesired bits out and set result struct. */ /* Mask undesired bits out and set result. */
flagp->_fpu_exceptions = (sw & excepts); *flagp = (sw | mxcsr) & excepts;
flagp->_sse_exceptions = (mxcsr & excepts);
return 0; return 0;
} }
@ -317,9 +316,9 @@ fesetexceptflag (const fexcept_t *flagp, int excepts)
/* Set/Clear desired exception bits. */ /* Set/Clear desired exception bits. */
fenv._fpu._fpu_sw &= ~excepts; fenv._fpu._fpu_sw &= ~excepts;
fenv._fpu._fpu_sw |= (excepts & flagp->_fpu_exceptions); fenv._fpu._fpu_sw |= excepts & *flagp;
fenv._sse_mxcsr &= ~excepts; fenv._sse_mxcsr &= ~excepts;
fenv._sse_mxcsr |= (excepts & flagp->_sse_exceptions); fenv._sse_mxcsr |= excepts & *flagp;
/* Set back into FPU state. */ /* Set back into FPU state. */
return fesetenv (&fenv); return fesetenv (&fenv);

View File

@ -8,8 +8,8 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */ details. */
#ifndef _FENV_H_ #ifndef _FENV_H
#define _FENV_H_ #define _FENV_H 1
#include <sys/cdefs.h> #include <sys/cdefs.h>
@ -72,13 +72,9 @@ typedef struct _fenv_t
of exceptional floating-point arithmetic to provide auxiliary information. of exceptional floating-point arithmetic to provide auxiliary information.
A floating-point control mode is a system variable whose value may be 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 set by the user to affect the subsequent behavior of floating-point
arithmetic. */ arithmetic. */
typedef struct _fexcept_t typedef __uint32_t fexcept_t;
{
unsigned short _fpu_exceptions;
unsigned short _sse_exceptions;
} fexcept_t;
/* The <fenv.h> header shall define the following constants if and only /* The <fenv.h> header shall define the following constants if and only
if the implementation supports the floating-point exception by means if the implementation supports the floating-point exception by means
@ -176,4 +172,4 @@ extern int fegetexcept (void);
} }
#endif #endif
#endif /* _FENV_H_ */ #endif /* _FENV_H */