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:
		| @@ -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); | ||||||
|   | |||||||
| @@ -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> | ||||||
|  |  | ||||||
| @@ -74,11 +74,7 @@ typedef struct _fenv_t | |||||||
|    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 */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user