24 #ifndef PPL_fpu_ia32_inlines_hh
25 #define PPL_fpu_ia32_inlines_hh 1
30 #define FPU_INVALID 0x01
31 #define FPU_DIVBYZERO 0x04
32 #define FPU_OVERFLOW 0x08
33 #define FPU_UNDERFLOW 0x10
34 #define FPU_INEXACT 0x20
36 #define FPU_ALL_EXCEPT \
37 (FPU_INEXACT | FPU_DIVBYZERO | FPU_UNDERFLOW | FPU_OVERFLOW | FPU_INVALID)
39 #define PPL_FPU_TONEAREST 0
40 #define PPL_FPU_DOWNWARD 0x400
41 #define PPL_FPU_UPWARD 0x800
42 #define PPL_FPU_TOWARDZERO 0xc00
44 #define FPU_ROUNDING_MASK 0xc00
46 #define SSE_INEXACT 0x20
48 #define PPL_FPU_CONTROL_DEFAULT_BASE 0x37f
49 #define PPL_SSE_CONTROL_DEFAULT_BASE 0x1f80
52 #define PPL_FPU_CONTROL_DEFAULT \
53 (PPL_FPU_CONTROL_DEFAULT_BASE | PPL_FPU_UPWARD)
54 #define PPL_SSE_CONTROL_DEFAULT \
55 (PPL_SSE_CONTROL_DEFAULT_BASE | (PPL_FPU_UPWARD << 3))
68 unsigned int opcode:11;
69 unsigned int unused4:5;
78 __asm__ __volatile__ (
"fnstcw %0" :
"=m" (*&cw) : :
"memory");
84 unsigned short cw =
static_cast<unsigned short>(
c);
85 __asm__ __volatile__ (
"fldcw %0" : :
"m" (*&cw) :
"memory");
91 __asm__ __volatile__ (
"fnstsw %0" :
"=a" (sw) : :
"memory");
99 __asm__ __volatile__ (
"fnstenv %0" :
"=m" (env));
101 __asm__ __volatile__ (
"fldenv %0" : :
"m" (env) :
"memory");
106 __asm__ __volatile__ (
"fnclex" : : :
"memory");
109 #ifdef PPL_FPMATH_MAY_USE_SSE
111 sse_set_control(
unsigned int cw) {
112 __asm__ __volatile__ (
"ldmxcsr %0" : :
"m" (*&cw) :
"memory");
118 __asm__ __volatile__ (
"stmxcsr %0" :
"=m" (*&cw) : :
"memory");
125 #ifdef PPL_FPMATH_MAY_USE_SSE
126 extern void detect_sse_unit();
138 #ifdef PPL_FPMATH_MAY_USE_387
141 #ifdef PPL_FPMATH_MAY_USE_SSE
142 extern bool have_sse_unit;
150 #ifdef PPL_FPMATH_MAY_USE_387
153 #ifdef PPL_FPMATH_MAY_USE_SSE
154 extern bool have_sse_unit;
163 #ifdef PPL_FPMATH_MAY_USE_387
166 #ifdef PPL_FPMATH_MAY_USE_SSE
169 extern bool have_sse_unit;
178 #ifdef PPL_FPMATH_MAY_USE_387
181 #ifdef PPL_FPMATH_MAY_USE_SSE
182 extern bool have_sse_unit;
191 #ifdef PPL_FPMATH_MAY_USE_387
196 #ifdef PPL_FPMATH_MAY_USE_SSE
197 extern bool have_sse_unit;
198 if (have_sse_unit && (sse_get_control() &
SSE_INEXACT)) {
207 #endif // !defined(PPL_fpu_ia32_inlines_hh)
#define PPL_FPU_CONTROL_DEFAULT_BASE
void fpu_set_control(int c)
fpu_rounding_direction_type
fpu_rounding_control_word_type fpu_save_rounding_direction(fpu_rounding_direction_type dir)
Sets the FPU rounding direction to dir and returns the rounding control word previously in use...
int fpu_check_inexact()
Queries the inexact computation status.
fpu_rounding_direction_type fpu_get_rounding_direction()
Returns the current FPU rounding direction.
#define FPU_ROUNDING_MASK
void fpu_reset_inexact()
Clears the inexact computation status.
#define PPL_FPU_CONTROL_DEFAULT
unsigned short status_word
unsigned short data_selector
#define PPL_SSE_CONTROL_DEFAULT_BASE
void fpu_restore_rounding_direction(fpu_rounding_control_word_type)
Restores the FPU rounding rounding control word to cw.
#define PPL_SSE_CONTROL_DEFAULT
The entire library is confined to this namespace.
void fpu_initialize_control_functions()
Initializes the FPU control functions.
unsigned short control_word
void fpu_clear_exceptions()
void fpu_set_rounding_direction(fpu_rounding_direction_type dir)
Sets the FPU rounding direction to dir.
fpu_rounding_control_word_type
void fpu_clear_status(unsigned short bits)
unsigned short cs_selector