mirror of
https://github.com/glest/glest-source.git
synced 2025-08-13 11:54:00 +02:00
Fixed the god-awful indentation
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
streflop: STandalone REproducible FLOating-Point
|
||||
Copyright 2006 Nicolas Brodu
|
||||
2012 Mark Vejvoda
|
||||
Code released according to the GNU Lesser General Public License
|
||||
streflop: STandalone REproducible FLOating-Point
|
||||
Copyright 2006 Nicolas Brodu
|
||||
2012 Mark Vejvoda
|
||||
Code released according to the GNU Lesser General Public License
|
||||
|
||||
Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib.
|
||||
Uses SoftFloat too.
|
||||
Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib.
|
||||
Uses SoftFloat too.
|
||||
|
||||
Please read the history and copyright information in the documentation provided with the source code
|
||||
Please read the history and copyright information in the documentation provided with the source code
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -53,13 +53,13 @@
|
||||
|
||||
namespace streflop {
|
||||
|
||||
// We do not use libm, so let's copy a few flags and C99 functions
|
||||
// Give warning in case these flags would be defined already, this is indication
|
||||
// of potential confusion!
|
||||
// We do not use libm, so let's copy a few flags and C99 functions
|
||||
// Give warning in case these flags would be defined already, this is indication
|
||||
// of potential confusion!
|
||||
|
||||
#if defined(FE_INVALID) || defined(FE_DENORMAL) || defined(FE_DIVBYZERO) || defined(FE_OVERFLOW) || defined(FE_UNDERFLOW) || defined(FE_INEXACT) || defined(FE_DOWNWARD) || defined(FE_TONEAREST) || defined(FE_TOWARDZERO) || defined(FE_UPWARD)
|
||||
|
||||
#warning STREFLOP: FE_XXX flags were already defined and will be redefined! Check you do not use the system libm.
|
||||
#warning STREFLOP : FE_XXX flags were already defined and will be redefined!Check you do not use the system libm.
|
||||
#undef FE_INVALID
|
||||
#undef FE_DENORMAL
|
||||
#undef FE_DIVBYZERO
|
||||
@@ -75,74 +75,74 @@ namespace streflop {
|
||||
#endif // defined(FE_INVALID) || ...
|
||||
|
||||
|
||||
// Flags for FPU exceptions
|
||||
enum FPU_Exceptions {
|
||||
// Flags for FPU exceptions
|
||||
enum FPU_Exceptions {
|
||||
|
||||
// Invalid operation. If not signaling, gives NaN instead
|
||||
FE_INVALID = 0x0001,
|
||||
#define FE_INVALID FE_INVALID
|
||||
// Invalid operation. If not signaling, gives NaN instead
|
||||
FE_INVALID = 0x0001,
|
||||
#define FE_INVALID FE_INVALID
|
||||
|
||||
// Extension: for x86 and SSE
|
||||
// Denormal operand. If not signaling, use denormal arithmetic as usual
|
||||
FE_DENORMAL = 0x0002,
|
||||
#define FE_DENORMAL FE_DENORMAL
|
||||
// Extension: for x86 and SSE
|
||||
// Denormal operand. If not signaling, use denormal arithmetic as usual
|
||||
FE_DENORMAL = 0x0002,
|
||||
#define FE_DENORMAL FE_DENORMAL
|
||||
|
||||
// Division by zero. If not signaling, uses +/- infinity
|
||||
FE_DIVBYZERO = 0x0004,
|
||||
#define FE_DIVBYZERO FE_DIVBYZERO
|
||||
// Division by zero. If not signaling, uses +/- infinity
|
||||
FE_DIVBYZERO = 0x0004,
|
||||
#define FE_DIVBYZERO FE_DIVBYZERO
|
||||
|
||||
// Overflow. If not signaling, round to nearest (including infinity) according to rounding mode
|
||||
FE_OVERFLOW = 0x0008,
|
||||
#define FE_OVERFLOW FE_OVERFLOW
|
||||
// Overflow. If not signaling, round to nearest (including infinity) according to rounding mode
|
||||
FE_OVERFLOW = 0x0008,
|
||||
#define FE_OVERFLOW FE_OVERFLOW
|
||||
|
||||
// Underflow. If not signaling, use 0 instead
|
||||
FE_UNDERFLOW = 0x0010,
|
||||
#define FE_UNDERFLOW FE_UNDERFLOW
|
||||
// Underflow. If not signaling, use 0 instead
|
||||
FE_UNDERFLOW = 0x0010,
|
||||
#define FE_UNDERFLOW FE_UNDERFLOW
|
||||
|
||||
// Rounding was not exact (ex: sqrt(2) is never exact) or when overflow causes rounding
|
||||
FE_INEXACT = 0x0020,
|
||||
#define FE_INEXACT FE_INEXACT
|
||||
// Rounding was not exact (ex: sqrt(2) is never exact) or when overflow causes rounding
|
||||
FE_INEXACT = 0x0020,
|
||||
#define FE_INEXACT FE_INEXACT
|
||||
|
||||
// Combination of all the above
|
||||
FE_ALL_EXCEPT = 0x003F
|
||||
#define FE_ALL_EXCEPT FE_ALL_EXCEPT
|
||||
};
|
||||
// Combination of all the above
|
||||
FE_ALL_EXCEPT = 0x003F
|
||||
#define FE_ALL_EXCEPT FE_ALL_EXCEPT
|
||||
};
|
||||
|
||||
// Flags for FPU rounding modes
|
||||
enum FPU_RoundMode {
|
||||
FE_TONEAREST = 0x0000,
|
||||
#define FE_TONEAREST FE_TONEAREST
|
||||
// Flags for FPU rounding modes
|
||||
enum FPU_RoundMode {
|
||||
FE_TONEAREST = 0x0000,
|
||||
#define FE_TONEAREST FE_TONEAREST
|
||||
|
||||
FE_DOWNWARD = 0x0400,
|
||||
#define FE_DOWNWARD FE_DOWNWARD
|
||||
FE_DOWNWARD = 0x0400,
|
||||
#define FE_DOWNWARD FE_DOWNWARD
|
||||
|
||||
FE_UPWARD = 0x0800,
|
||||
#define FE_UPWARD FE_UPWARD
|
||||
FE_UPWARD = 0x0800,
|
||||
#define FE_UPWARD FE_UPWARD
|
||||
|
||||
FE_TOWARDZERO = 0x0C00
|
||||
#define FE_TOWARDZERO FE_TOWARDZERO
|
||||
};
|
||||
FE_TOWARDZERO = 0x0C00
|
||||
#define FE_TOWARDZERO FE_TOWARDZERO
|
||||
};
|
||||
|
||||
/* Note: SSE control word, bits 0..15
|
||||
0->5: Run-time status flags
|
||||
6: DAZ (denormals are zero, i.e. don't use denormals if bit is 1)
|
||||
7->12: Exception flags, same meaning as for the x87 ones
|
||||
13,14: Rounding flags, same meaning as for the x87 ones
|
||||
15: Flush to zero (FTZ) for automatic handling of underflow (default is NO)
|
||||
*/
|
||||
/* Note: SSE control word, bits 0..15
|
||||
0->5: Run-time status flags
|
||||
6: DAZ (denormals are zero, i.e. don't use denormals if bit is 1)
|
||||
7->12: Exception flags, same meaning as for the x87 ones
|
||||
13,14: Rounding flags, same meaning as for the x87 ones
|
||||
15: Flush to zero (FTZ) for automatic handling of underflow (default is NO)
|
||||
*/
|
||||
|
||||
// plan for portability
|
||||
// plan for portability
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#if _WIN64
|
||||
|
||||
// No fldcw intrinsics on Windows x64, punt to external asm
|
||||
// Seems like using unsigned is better on windows x64: http://www.virtualdub.org/blog/pivot/entry.php?id=340
|
||||
extern "C" { void streflop_winx64_fldcw(unsigned short mode); }
|
||||
extern "C" { unsigned short streflop_winx64_fstcw(); }
|
||||
extern "C" { void streflop_winx64_fclex(void); }
|
||||
extern "C" { void streflop_winx64_stmxcsr(unsigned int mode); }
|
||||
extern "C" { void streflop_winx64_ldmxcsr(unsigned int mode); }
|
||||
extern "C" { void streflop_winx64_fldcw(unsigned short mode); }
|
||||
extern "C" { unsigned short streflop_winx64_fstcw(); }
|
||||
extern "C" { void streflop_winx64_fclex(void); }
|
||||
extern "C" { void streflop_winx64_stmxcsr(unsigned int mode); }
|
||||
extern "C" { void streflop_winx64_ldmxcsr(unsigned int mode); }
|
||||
|
||||
#define STREFLOP_FSTCW(cw) do { short tmp = 0; tmp = streflop_winx64_fstcw(); (cw) = tmp; } while (0)
|
||||
#define STREFLOP_FLDCW(cw) do { short tmp = (cw); streflop_winx64_fldcw(tmp); } while (0)
|
||||
@@ -172,381 +172,382 @@ extern "C" { void streflop_winx64_ldmxcsr(unsigned int mode); }
|
||||
#if defined(STREFLOP_X87)
|
||||
|
||||
/// Raise exception for these flags
|
||||
inline int feraiseexcept(FPU_Exceptions excepts) {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
fpu_mode &= ~( excepts ); // generate error for selection
|
||||
STREFLOP_FLDCW(fpu_mode);
|
||||
return 0;
|
||||
}
|
||||
inline int feraiseexcept(FPU_Exceptions excepts) {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
fpu_mode &= ~(excepts); // generate error for selection
|
||||
STREFLOP_FLDCW(fpu_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Clear exceptions for these flags
|
||||
inline int feclearexcept(int excepts) {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
fpu_mode |= excepts;
|
||||
STREFLOP_FLDCW(fpu_mode);
|
||||
return 0;
|
||||
}
|
||||
/// Clear exceptions for these flags
|
||||
inline int feclearexcept(int excepts) {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
fpu_mode |= excepts;
|
||||
STREFLOP_FLDCW(fpu_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Get current rounding mode
|
||||
inline int fegetround() {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
return fpu_mode & 0x0C00;
|
||||
}
|
||||
/// Get current rounding mode
|
||||
inline int fegetround() {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
return fpu_mode & 0x0C00;
|
||||
}
|
||||
|
||||
/// Set a new rounding mode
|
||||
inline int fesetround(FPU_RoundMode roundMode) {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
fpu_mode &= 0xF3FF; // clear current mode
|
||||
fpu_mode |= roundMode; // sets new mode
|
||||
STREFLOP_FLDCW(fpu_mode);
|
||||
return 0;
|
||||
}
|
||||
/// Set a new rounding mode
|
||||
inline int fesetround(FPU_RoundMode roundMode) {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
fpu_mode &= 0xF3FF; // clear current mode
|
||||
fpu_mode |= roundMode; // sets new mode
|
||||
STREFLOP_FLDCW(fpu_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef short int fenv_t;
|
||||
typedef short int fenv_t;
|
||||
|
||||
/// Default env. Defined in Math.cpp to be 0, and initalized on first use to the permanent holder
|
||||
extern fenv_t FE_DFL_ENV;
|
||||
/// Default env. Defined in Math.cpp to be 0, and initalized on first use to the permanent holder
|
||||
extern fenv_t FE_DFL_ENV;
|
||||
|
||||
/// Get FP env into the given structure
|
||||
inline int fegetenv(fenv_t *envp) {
|
||||
// check that default env exists, otherwise save it now
|
||||
if (!FE_DFL_ENV) STREFLOP_FSTCW(FE_DFL_ENV);
|
||||
// Now store env into argument
|
||||
STREFLOP_FSTCW(*envp);
|
||||
return 0;
|
||||
}
|
||||
/// Get FP env into the given structure
|
||||
inline int fegetenv(fenv_t *envp) {
|
||||
// check that default env exists, otherwise save it now
|
||||
if (!FE_DFL_ENV) STREFLOP_FSTCW(FE_DFL_ENV);
|
||||
// Now store env into argument
|
||||
STREFLOP_FSTCW(*envp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Sets FP env from the given structure
|
||||
inline int fesetenv(const fenv_t *envp) {
|
||||
// check that default env exists, otherwise save it now
|
||||
if (!FE_DFL_ENV) STREFLOP_FSTCW(FE_DFL_ENV);
|
||||
// Now overwrite current env by argument
|
||||
STREFLOP_FLDCW(*envp);
|
||||
return 0;
|
||||
}
|
||||
/// Sets FP env from the given structure
|
||||
inline int fesetenv(const fenv_t *envp) {
|
||||
// check that default env exists, otherwise save it now
|
||||
if (!FE_DFL_ENV) STREFLOP_FSTCW(FE_DFL_ENV);
|
||||
// Now overwrite current env by argument
|
||||
STREFLOP_FLDCW(*envp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// get env and clear exceptions
|
||||
inline int feholdexcept(fenv_t *envp) {
|
||||
fegetenv(envp);
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
return 0;
|
||||
}
|
||||
/// get env and clear exceptions
|
||||
inline int feholdexcept(fenv_t *envp) {
|
||||
fegetenv(envp);
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template<typename T> inline void streflop_init() {
|
||||
struct X {};
|
||||
X Unknown_numeric_type;
|
||||
// unknown types do not compile
|
||||
T error = Unknown_numeric_type;
|
||||
}
|
||||
template<typename T> inline void streflop_init() {
|
||||
struct X {
|
||||
};
|
||||
X Unknown_numeric_type;
|
||||
// unknown types do not compile
|
||||
T error = Unknown_numeric_type;
|
||||
}
|
||||
|
||||
/// Initialize the FPU for the different types
|
||||
/// this may also be called to switch between code sections using
|
||||
/// different precisions
|
||||
template<> inline void streflop_init<Simple>() {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
fpu_mode &= 0xFCFF; // 32 bits internal operations
|
||||
STREFLOP_FLDCW(fpu_mode);
|
||||
/// Initialize the FPU for the different types
|
||||
/// this may also be called to switch between code sections using
|
||||
/// different precisions
|
||||
template<> inline void streflop_init<Simple>() {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
fpu_mode &= 0xFCFF; // 32 bits internal operations
|
||||
STREFLOP_FLDCW(fpu_mode);
|
||||
|
||||
// Enable signaling nans if compiled with this option.
|
||||
// Enable signaling nans if compiled with this option.
|
||||
#if defined(__SUPPORT_SNAN__) && !defined(USE_GML)
|
||||
feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW));
|
||||
feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<> inline void streflop_init<Double>() {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
fpu_mode &= 0xFCFF;
|
||||
fpu_mode |= 0x0200; // 64 bits internal operations
|
||||
STREFLOP_FLDCW(fpu_mode);
|
||||
template<> inline void streflop_init<Double>() {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
fpu_mode &= 0xFCFF;
|
||||
fpu_mode |= 0x0200; // 64 bits internal operations
|
||||
STREFLOP_FLDCW(fpu_mode);
|
||||
|
||||
#if defined(__SUPPORT_SNAN__) && !defined(USE_GML)
|
||||
feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW));
|
||||
feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(Extended)
|
||||
template<> inline void streflop_init<Extended>() {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
fpu_mode &= 0xFCFF;
|
||||
fpu_mode |= 0x0300; // 80 bits internal operations
|
||||
STREFLOP_FLDCW(fpu_mode);
|
||||
template<> inline void streflop_init<Extended>() {
|
||||
unsigned short fpu_mode;
|
||||
STREFLOP_FSTCW(fpu_mode);
|
||||
fpu_mode &= 0xFCFF;
|
||||
fpu_mode |= 0x0300; // 80 bits internal operations
|
||||
STREFLOP_FLDCW(fpu_mode);
|
||||
|
||||
#if defined(__SUPPORT_SNAN__) && !defined(USE_GML)
|
||||
feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW));
|
||||
feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // defined(Extended)
|
||||
|
||||
#elif defined(STREFLOP_SSE)
|
||||
|
||||
/// Raise exception for these flags
|
||||
inline int feraiseexcept(FPU_Exceptions excepts) {
|
||||
// Just in case the compiler would store a value on the st(x) registers
|
||||
unsigned short x87_mode;
|
||||
STREFLOP_FSTCW(x87_mode);
|
||||
x87_mode &= ~( excepts ); // generate error for selection
|
||||
STREFLOP_FLDCW(x87_mode);
|
||||
inline int feraiseexcept(FPU_Exceptions excepts) {
|
||||
// Just in case the compiler would store a value on the st(x) registers
|
||||
unsigned short x87_mode;
|
||||
STREFLOP_FSTCW(x87_mode);
|
||||
x87_mode &= ~(excepts); // generate error for selection
|
||||
STREFLOP_FLDCW(x87_mode);
|
||||
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
sse_mode &= ~( excepts << 7 ); // generate error for selection
|
||||
STREFLOP_LDMXCSR(sse_mode);
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
sse_mode &= ~(excepts << 7); // generate error for selection
|
||||
STREFLOP_LDMXCSR(sse_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Clear exceptions for these flags
|
||||
inline int feclearexcept(int excepts) {
|
||||
// Just in case the compiler would store a value on the st(x) registers
|
||||
unsigned short x87_mode;
|
||||
STREFLOP_FSTCW(x87_mode);
|
||||
x87_mode |= excepts;
|
||||
STREFLOP_FLDCW(x87_mode);
|
||||
/// Clear exceptions for these flags
|
||||
inline int feclearexcept(int excepts) {
|
||||
// Just in case the compiler would store a value on the st(x) registers
|
||||
unsigned short x87_mode;
|
||||
STREFLOP_FSTCW(x87_mode);
|
||||
x87_mode |= excepts;
|
||||
STREFLOP_FLDCW(x87_mode);
|
||||
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
sse_mode |= excepts << 7;
|
||||
STREFLOP_LDMXCSR(sse_mode);
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
sse_mode |= excepts << 7;
|
||||
STREFLOP_LDMXCSR(sse_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Get current rounding mode
|
||||
inline int fegetround() {
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
return (sse_mode>>3) & 0x00000C00;
|
||||
}
|
||||
/// Get current rounding mode
|
||||
inline int fegetround() {
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
return (sse_mode >> 3) & 0x00000C00;
|
||||
}
|
||||
|
||||
/// Set a new rounding mode
|
||||
inline int fesetround(FPU_RoundMode roundMode) {
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
sse_mode &= 0xFFFF9FFF; // clear current mode
|
||||
sse_mode |= roundMode<<3; // sets new mode
|
||||
STREFLOP_LDMXCSR(sse_mode);
|
||||
return 0;
|
||||
}
|
||||
/// Set a new rounding mode
|
||||
inline int fesetround(FPU_RoundMode roundMode) {
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
sse_mode &= 0xFFFF9FFF; // clear current mode
|
||||
sse_mode |= roundMode << 3; // sets new mode
|
||||
STREFLOP_LDMXCSR(sse_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// stores both x87 and SSE words
|
||||
struct fenv_t {
|
||||
int sse_mode;
|
||||
short int x87_mode;
|
||||
};
|
||||
/// stores both x87 and SSE words
|
||||
struct fenv_t {
|
||||
int sse_mode;
|
||||
short int x87_mode;
|
||||
};
|
||||
|
||||
/// Default env. Defined in Math.cpp, structs are initialized to 0
|
||||
extern fenv_t FE_DFL_ENV;
|
||||
/// Default env. Defined in Math.cpp, structs are initialized to 0
|
||||
extern fenv_t FE_DFL_ENV;
|
||||
|
||||
/// Get FP env into the given structure
|
||||
inline int fegetenv(fenv_t *envp) {
|
||||
// check that default env exists, otherwise save it now
|
||||
if (!FE_DFL_ENV.x87_mode) STREFLOP_FSTCW(FE_DFL_ENV.x87_mode);
|
||||
// Now store env into argument
|
||||
STREFLOP_FSTCW(envp->x87_mode);
|
||||
/// Get FP env into the given structure
|
||||
inline int fegetenv(fenv_t *envp) {
|
||||
// check that default env exists, otherwise save it now
|
||||
if (!FE_DFL_ENV.x87_mode) STREFLOP_FSTCW(FE_DFL_ENV.x87_mode);
|
||||
// Now store env into argument
|
||||
STREFLOP_FSTCW(envp->x87_mode);
|
||||
|
||||
// For SSE
|
||||
if (!FE_DFL_ENV.sse_mode) STREFLOP_STMXCSR(FE_DFL_ENV.sse_mode);
|
||||
// Now store env into argument
|
||||
STREFLOP_STMXCSR(envp->sse_mode);
|
||||
return 0;
|
||||
}
|
||||
// For SSE
|
||||
if (!FE_DFL_ENV.sse_mode) STREFLOP_STMXCSR(FE_DFL_ENV.sse_mode);
|
||||
// Now store env into argument
|
||||
STREFLOP_STMXCSR(envp->sse_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Sets FP env from the given structure
|
||||
inline int fesetenv(const fenv_t *envp) {
|
||||
// check that default env exists, otherwise save it now
|
||||
if (!FE_DFL_ENV.x87_mode) STREFLOP_FSTCW(FE_DFL_ENV.x87_mode);
|
||||
// Now overwrite current env by argument
|
||||
STREFLOP_FLDCW(envp->x87_mode);
|
||||
/// Sets FP env from the given structure
|
||||
inline int fesetenv(const fenv_t *envp) {
|
||||
// check that default env exists, otherwise save it now
|
||||
if (!FE_DFL_ENV.x87_mode) STREFLOP_FSTCW(FE_DFL_ENV.x87_mode);
|
||||
// Now overwrite current env by argument
|
||||
STREFLOP_FLDCW(envp->x87_mode);
|
||||
|
||||
// For SSE
|
||||
if (!FE_DFL_ENV.sse_mode) STREFLOP_STMXCSR(FE_DFL_ENV.sse_mode);
|
||||
// Now overwrite current env by argument
|
||||
STREFLOP_LDMXCSR(envp->sse_mode);
|
||||
return 0;
|
||||
}
|
||||
// For SSE
|
||||
if (!FE_DFL_ENV.sse_mode) STREFLOP_STMXCSR(FE_DFL_ENV.sse_mode);
|
||||
// Now overwrite current env by argument
|
||||
STREFLOP_LDMXCSR(envp->sse_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// get env and clear exceptions
|
||||
inline int feholdexcept(fenv_t *envp) {
|
||||
fegetenv(envp);
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
return 0;
|
||||
}
|
||||
/// get env and clear exceptions
|
||||
inline int feholdexcept(fenv_t *envp) {
|
||||
fegetenv(envp);
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template<typename T> inline void streflop_init() {
|
||||
// Do nothing by default, or for unknown types
|
||||
}
|
||||
template<typename T> inline void streflop_init() {
|
||||
// Do nothing by default, or for unknown types
|
||||
}
|
||||
|
||||
/// Initialize the FPU for the different types
|
||||
/// this may also be called to switch between code sections using
|
||||
/// different precisions
|
||||
template<> inline void streflop_init<Simple>() {
|
||||
// Just in case the compiler would store a value on the st(x) registers
|
||||
unsigned short x87_mode;
|
||||
STREFLOP_FSTCW(x87_mode);
|
||||
x87_mode &= 0xFCFF; // 32 bits internal operations
|
||||
STREFLOP_FLDCW(x87_mode);
|
||||
/// Initialize the FPU for the different types
|
||||
/// this may also be called to switch between code sections using
|
||||
/// different precisions
|
||||
template<> inline void streflop_init<Simple>() {
|
||||
// Just in case the compiler would store a value on the st(x) registers
|
||||
unsigned short x87_mode;
|
||||
STREFLOP_FSTCW(x87_mode);
|
||||
x87_mode &= 0xFCFF; // 32 bits internal operations
|
||||
STREFLOP_FLDCW(x87_mode);
|
||||
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
#if defined(STREFLOP_NO_DENORMALS)
|
||||
sse_mode |= 0x8040; // set DAZ and FTZ
|
||||
sse_mode |= 0x8040; // set DAZ and FTZ
|
||||
#else
|
||||
sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ
|
||||
sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ
|
||||
#endif
|
||||
STREFLOP_LDMXCSR(sse_mode);
|
||||
}
|
||||
STREFLOP_LDMXCSR(sse_mode);
|
||||
}
|
||||
|
||||
template<> inline void streflop_init<Double>() {
|
||||
// Just in case the compiler would store a value on the st(x) registers
|
||||
unsigned short x87_mode;
|
||||
STREFLOP_FSTCW(x87_mode);
|
||||
x87_mode &= 0xFCFF;
|
||||
x87_mode |= 0x0200; // 64 bits internal operations
|
||||
STREFLOP_FLDCW(x87_mode);
|
||||
template<> inline void streflop_init<Double>() {
|
||||
// Just in case the compiler would store a value on the st(x) registers
|
||||
unsigned short x87_mode;
|
||||
STREFLOP_FSTCW(x87_mode);
|
||||
x87_mode &= 0xFCFF;
|
||||
x87_mode |= 0x0200; // 64 bits internal operations
|
||||
STREFLOP_FLDCW(x87_mode);
|
||||
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
#if defined(STREFLOP_NO_DENORMALS)
|
||||
sse_mode |= 0x8040; // set DAZ and FTZ
|
||||
sse_mode |= 0x8040; // set DAZ and FTZ
|
||||
#else
|
||||
sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ
|
||||
sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ
|
||||
#endif
|
||||
STREFLOP_LDMXCSR(sse_mode);
|
||||
}
|
||||
STREFLOP_LDMXCSR(sse_mode);
|
||||
}
|
||||
|
||||
#if defined(Extended)
|
||||
template<> inline void streflop_init<Extended>() {
|
||||
// Just in case the compiler would store a value on the st(x) registers
|
||||
unsigned short x87_mode;
|
||||
STREFLOP_FSTCW(x87_mode);
|
||||
x87_mode &= 0xFCFF;
|
||||
x87_mode |= 0x0300; // 80 bits internal operations
|
||||
STREFLOP_FLDCW(x87_mode);
|
||||
template<> inline void streflop_init<Extended>() {
|
||||
// Just in case the compiler would store a value on the st(x) registers
|
||||
unsigned short x87_mode;
|
||||
STREFLOP_FSTCW(x87_mode);
|
||||
x87_mode &= 0xFCFF;
|
||||
x87_mode |= 0x0300; // 80 bits internal operations
|
||||
STREFLOP_FLDCW(x87_mode);
|
||||
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
int sse_mode;
|
||||
STREFLOP_STMXCSR(sse_mode);
|
||||
#if defined(STREFLOP_NO_DENORMALS)
|
||||
sse_mode |= 0x8040; // set DAZ and FTZ
|
||||
sse_mode |= 0x8040; // set DAZ and FTZ
|
||||
#else
|
||||
sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ
|
||||
sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ
|
||||
#endif
|
||||
STREFLOP_LDMXCSR(sse_mode);
|
||||
}
|
||||
STREFLOP_LDMXCSR(sse_mode);
|
||||
}
|
||||
#endif // defined(Extended)
|
||||
|
||||
|
||||
#elif defined(STREFLOP_SOFT)
|
||||
/// Raise exception for these flags
|
||||
inline int feraiseexcept(FPU_Exceptions excepts) {
|
||||
// Use positive logic
|
||||
SoftFloat::float_exception_realtraps |= excepts;
|
||||
return 0;
|
||||
}
|
||||
inline int feraiseexcept(FPU_Exceptions excepts) {
|
||||
// Use positive logic
|
||||
SoftFloat::float_exception_realtraps |= excepts;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Clear exceptions for these flags
|
||||
inline int feclearexcept(int excepts) {
|
||||
// Use positive logic
|
||||
SoftFloat::float_exception_realtraps &= ~( excepts );
|
||||
return 0;
|
||||
}
|
||||
/// Clear exceptions for these flags
|
||||
inline int feclearexcept(int excepts) {
|
||||
// Use positive logic
|
||||
SoftFloat::float_exception_realtraps &= ~(excepts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Get current rounding mode
|
||||
inline int fegetround() {
|
||||
// see softfloat.h for the definition
|
||||
switch (SoftFloat::float_rounding_mode) {
|
||||
case SoftFloat::float_round_down: return FE_DOWNWARD;
|
||||
case SoftFloat::float_round_up: return FE_UPWARD;
|
||||
case SoftFloat::float_round_to_zero: return FE_TOWARDZERO;
|
||||
default:; // is also initial mode
|
||||
}
|
||||
// case SoftFloat::float_round_nearest_even:
|
||||
return FE_TONEAREST;
|
||||
}
|
||||
/// Get current rounding mode
|
||||
inline int fegetround() {
|
||||
// see softfloat.h for the definition
|
||||
switch (SoftFloat::float_rounding_mode) {
|
||||
case SoftFloat::float_round_down: return FE_DOWNWARD;
|
||||
case SoftFloat::float_round_up: return FE_UPWARD;
|
||||
case SoftFloat::float_round_to_zero: return FE_TOWARDZERO;
|
||||
default:; // is also initial mode
|
||||
}
|
||||
// case SoftFloat::float_round_nearest_even:
|
||||
return FE_TONEAREST;
|
||||
}
|
||||
|
||||
/// Set a new rounding mode
|
||||
inline int fesetround(FPU_RoundMode roundMode) {
|
||||
// see softfloat.h for the definition
|
||||
switch (roundMode) {
|
||||
case FE_DOWNWARD: SoftFloat::float_rounding_mode = SoftFloat::float_round_down; return 0;
|
||||
case FE_UPWARD: SoftFloat::float_rounding_mode = SoftFloat::float_round_up; return 0;
|
||||
case FE_TOWARDZERO: SoftFloat::float_rounding_mode = SoftFloat::float_round_to_zero; return 0;
|
||||
case FE_TONEAREST: SoftFloat::float_rounding_mode = SoftFloat::float_round_nearest_even; return 0;
|
||||
}
|
||||
// Error, invalid mode
|
||||
return 1;
|
||||
}
|
||||
/// Set a new rounding mode
|
||||
inline int fesetround(FPU_RoundMode roundMode) {
|
||||
// see softfloat.h for the definition
|
||||
switch (roundMode) {
|
||||
case FE_DOWNWARD: SoftFloat::float_rounding_mode = SoftFloat::float_round_down; return 0;
|
||||
case FE_UPWARD: SoftFloat::float_rounding_mode = SoftFloat::float_round_up; return 0;
|
||||
case FE_TOWARDZERO: SoftFloat::float_rounding_mode = SoftFloat::float_round_to_zero; return 0;
|
||||
case FE_TONEAREST: SoftFloat::float_rounding_mode = SoftFloat::float_round_nearest_even; return 0;
|
||||
}
|
||||
// Error, invalid mode
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// SoftFloat environment comprises non-volatile state variables
|
||||
struct fenv_t {
|
||||
char tininess;
|
||||
char rounding_mode;
|
||||
int exception_realtraps;
|
||||
};
|
||||
/// SoftFloat environment comprises non-volatile state variables
|
||||
struct fenv_t {
|
||||
char tininess;
|
||||
char rounding_mode;
|
||||
int exception_realtraps;
|
||||
};
|
||||
|
||||
/// Default env. Defined in Math.cpp, initialized to some invalid value for detection
|
||||
extern fenv_t FE_DFL_ENV;
|
||||
/// Default env. Defined in Math.cpp, initialized to some invalid value for detection
|
||||
extern fenv_t FE_DFL_ENV;
|
||||
|
||||
/// Get FP env into the given structure
|
||||
inline int fegetenv(fenv_t *envp) {
|
||||
// check that default env exists, otherwise save it now
|
||||
if (FE_DFL_ENV.tininess==42) {
|
||||
// First use: save default environment now
|
||||
FE_DFL_ENV.tininess = SoftFloat::float_detect_tininess;
|
||||
FE_DFL_ENV.rounding_mode = SoftFloat::float_rounding_mode;
|
||||
FE_DFL_ENV.exception_realtraps = SoftFloat::float_exception_realtraps;
|
||||
}
|
||||
// Now get the current env in the given argument
|
||||
envp->tininess = SoftFloat::float_detect_tininess;
|
||||
envp->rounding_mode = SoftFloat::float_rounding_mode;
|
||||
envp->exception_realtraps = SoftFloat::float_exception_realtraps;
|
||||
return 0;
|
||||
}
|
||||
/// Get FP env into the given structure
|
||||
inline int fegetenv(fenv_t *envp) {
|
||||
// check that default env exists, otherwise save it now
|
||||
if (FE_DFL_ENV.tininess == 42) {
|
||||
// First use: save default environment now
|
||||
FE_DFL_ENV.tininess = SoftFloat::float_detect_tininess;
|
||||
FE_DFL_ENV.rounding_mode = SoftFloat::float_rounding_mode;
|
||||
FE_DFL_ENV.exception_realtraps = SoftFloat::float_exception_realtraps;
|
||||
}
|
||||
// Now get the current env in the given argument
|
||||
envp->tininess = SoftFloat::float_detect_tininess;
|
||||
envp->rounding_mode = SoftFloat::float_rounding_mode;
|
||||
envp->exception_realtraps = SoftFloat::float_exception_realtraps;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Sets FP env from the given structure
|
||||
inline int fesetenv(const fenv_t *envp) {
|
||||
// check that default env exists, otherwise save it now
|
||||
if (FE_DFL_ENV.tininess==42) {
|
||||
// First use: save default environment now
|
||||
FE_DFL_ENV.tininess = SoftFloat::float_detect_tininess;
|
||||
FE_DFL_ENV.rounding_mode = SoftFloat::float_rounding_mode;
|
||||
FE_DFL_ENV.exception_realtraps = SoftFloat::float_exception_realtraps;
|
||||
}
|
||||
// Now get the current env in the given argument
|
||||
SoftFloat::float_detect_tininess = envp->tininess;
|
||||
SoftFloat::float_rounding_mode = envp->rounding_mode;
|
||||
SoftFloat::float_exception_realtraps = envp->exception_realtraps;
|
||||
return 0;
|
||||
}
|
||||
/// Sets FP env from the given structure
|
||||
inline int fesetenv(const fenv_t *envp) {
|
||||
// check that default env exists, otherwise save it now
|
||||
if (FE_DFL_ENV.tininess == 42) {
|
||||
// First use: save default environment now
|
||||
FE_DFL_ENV.tininess = SoftFloat::float_detect_tininess;
|
||||
FE_DFL_ENV.rounding_mode = SoftFloat::float_rounding_mode;
|
||||
FE_DFL_ENV.exception_realtraps = SoftFloat::float_exception_realtraps;
|
||||
}
|
||||
// Now get the current env in the given argument
|
||||
SoftFloat::float_detect_tininess = envp->tininess;
|
||||
SoftFloat::float_rounding_mode = envp->rounding_mode;
|
||||
SoftFloat::float_exception_realtraps = envp->exception_realtraps;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// get env and clear exceptions
|
||||
inline int feholdexcept(fenv_t *envp) {
|
||||
fegetenv(envp);
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
return 0;
|
||||
}
|
||||
/// get env and clear exceptions
|
||||
inline int feholdexcept(fenv_t *envp) {
|
||||
fegetenv(envp);
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T> inline void streflop_init() {
|
||||
// Do nothing by default, or for unknown types
|
||||
}
|
||||
template<typename T> inline void streflop_init() {
|
||||
// Do nothing by default, or for unknown types
|
||||
}
|
||||
|
||||
/// Initialize the FPU for the different types
|
||||
/// this may also be called to switch between code sections using
|
||||
/// different precisions
|
||||
template<> inline void streflop_init<Simple>() {
|
||||
}
|
||||
template<> inline void streflop_init<Double>() {
|
||||
}
|
||||
template<> inline void streflop_init<Extended>() {
|
||||
}
|
||||
/// Initialize the FPU for the different types
|
||||
/// this may also be called to switch between code sections using
|
||||
/// different precisions
|
||||
template<> inline void streflop_init<Simple>() {
|
||||
}
|
||||
template<> inline void streflop_init<Double>() {
|
||||
}
|
||||
template<> inline void streflop_init<Extended>() {
|
||||
}
|
||||
|
||||
#else // defined(STREFLOP_X87)
|
||||
#error STREFLOP: Invalid combination or unknown FPU type.
|
||||
|
Reference in New Issue
Block a user