Improve performance calculating reverb panning
[openal-soft.git] / core / fpu_ctrl.cpp
blob0cf0d6e72d107c0132681f714811910da30cd80d
2 #include "config.h"
4 #include "fpu_ctrl.h"
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
18 #include "cpu_caps.h"
21 void FPUCtl::enter() noexcept
23 if(this->in_mode) return;
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);
32 #elif defined(__GNUC__) && defined(HAVE_SSE)
34 if((CPUCapFlags&CPU_CAP_SSE))
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));
43 #endif
45 this->in_mode = true;
48 void FPUCtl::leave() noexcept
50 if(!this->in_mode) return;
52 #if defined(HAVE_SSE_INTRINSICS)
53 _mm_setcsr(this->sse_state);
55 #elif defined(__GNUC__) && defined(HAVE_SSE)
57 if((CPUCapFlags&CPU_CAP_SSE))
58 __asm__ __volatile__("ldmxcsr %0" : : "m" (*&this->sse_state));
59 #endif
60 this->in_mode = false;