aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/fpu_ctrl.cpp21
-rw-r--r--core/fpu_ctrl.h23
2 files changed, 25 insertions, 19 deletions
diff --git a/core/fpu_ctrl.cpp b/core/fpu_ctrl.cpp
index 435855ad..28e60c04 100644
--- a/core/fpu_ctrl.cpp
+++ b/core/fpu_ctrl.cpp
@@ -64,29 +64,24 @@ void reset_fpu(unsigned int state [[maybe_unused]])
} // namespace
-void FPUCtl::enter() noexcept
+unsigned int FPUCtl::Set() noexcept
{
- if(this->in_mode) return;
-
+ unsigned int state{};
#if defined(HAVE_SSE_INTRINSICS)
- disable_denormals(&this->sse_state);
+ disable_denormals(&state);
#elif defined(HAVE_SSE)
if((CPUCapFlags&CPU_CAP_SSE))
- disable_denormals(&this->sse_state);
+ disable_denormals(&state);
#endif
-
- this->in_mode = true;
+ return state;
}
-void FPUCtl::leave() noexcept
+void FPUCtl::Reset(unsigned int state [[maybe_unused]]) noexcept
{
- if(!this->in_mode) return;
-
#if defined(HAVE_SSE_INTRINSICS)
- reset_fpu(this->sse_state);
+ reset_fpu(state);
#elif defined(HAVE_SSE)
if((CPUCapFlags&CPU_CAP_SSE))
- reset_fpu(this->sse_state);
+ reset_fpu(state);
#endif
- this->in_mode = false;
}
diff --git a/core/fpu_ctrl.h b/core/fpu_ctrl.h
index 9554313a..d4f75ec3 100644
--- a/core/fpu_ctrl.h
+++ b/core/fpu_ctrl.h
@@ -2,20 +2,31 @@
#define CORE_FPU_CTRL_H
class FPUCtl {
-#if defined(HAVE_SSE_INTRINSICS) || (defined(__GNUC__) && defined(HAVE_SSE))
unsigned int sse_state{};
-#endif
bool in_mode{};
+ static unsigned int Set() noexcept;
+ static void Reset(unsigned int state) noexcept;
+
public:
- FPUCtl() noexcept { enter(); in_mode = true; }
- ~FPUCtl() { if(in_mode) leave(); }
+ FPUCtl() noexcept : sse_state{Set()}, in_mode{true} { }
+ ~FPUCtl() { if(in_mode) Reset(sse_state); }
FPUCtl(const FPUCtl&) = delete;
FPUCtl& operator=(const FPUCtl&) = delete;
- void enter() noexcept;
- void leave() noexcept;
+ void enter() noexcept
+ {
+ if(!in_mode)
+ sse_state = Set();
+ in_mode = true;
+ }
+ void leave() noexcept
+ {
+ if(in_mode)
+ Reset(sse_state);
+ in_mode = false;
+ }
};
#endif /* CORE_FPU_CTRL_H */