]> git.tdb.fi Git - ext/openal.git/blob - core/fpu_ctrl.cpp
Tweak some types to work around an MSVC compile error
[ext/openal.git] / core / fpu_ctrl.cpp
1
2 #include "config.h"
3
4 #include "fpu_ctrl.h"
5
6 #ifdef HAVE_INTRIN_H
7 #include <intrin.h>
8 #endif
9 #ifdef HAVE_SSE_INTRINSICS
10 #include <emmintrin.h>
11 #ifndef _MM_DENORMALS_ZERO_MASK
12 /* Some headers seem to be missing these? */
13 #define _MM_DENORMALS_ZERO_MASK 0x0040u
14 #define _MM_DENORMALS_ZERO_ON 0x0040u
15 #endif
16 #endif
17
18 #include "cpu_caps.h"
19
20
21 void FPUCtl::enter() noexcept
22 {
23     if(this->in_mode) return;
24
25 #if defined(HAVE_SSE_INTRINSICS)
26     this->sse_state = _mm_getcsr();
27     unsigned int sseState{this->sse_state};
28     sseState &= ~(_MM_FLUSH_ZERO_MASK | _MM_DENORMALS_ZERO_MASK);
29     sseState |= _MM_FLUSH_ZERO_ON | _MM_DENORMALS_ZERO_ON;
30     _mm_setcsr(sseState);
31
32 #elif defined(__GNUC__) && defined(HAVE_SSE)
33
34     if((CPUCapFlags&CPU_CAP_SSE))
35     {
36         __asm__ __volatile__("stmxcsr %0" : "=m" (*&this->sse_state));
37         unsigned int sseState{this->sse_state};
38         sseState |= 0x8000; /* set flush-to-zero */
39         if((CPUCapFlags&CPU_CAP_SSE2))
40             sseState |= 0x0040; /* set denormals-are-zero */
41         __asm__ __volatile__("ldmxcsr %0" : : "m" (*&sseState));
42     }
43 #endif
44
45     this->in_mode = true;
46 }
47
48 void FPUCtl::leave() noexcept
49 {
50     if(!this->in_mode) return;
51
52 #if defined(HAVE_SSE_INTRINSICS)
53     _mm_setcsr(this->sse_state);
54
55 #elif defined(__GNUC__) && defined(HAVE_SSE)
56
57     if((CPUCapFlags&CPU_CAP_SSE))
58         __asm__ __volatile__("ldmxcsr %0" : : "m" (*&this->sse_state));
59 #endif
60     this->in_mode = false;
61 }