diff --git a/sources/Helpers.h b/sources/Helpers.h index 121ac2ca..3f09a5d8 100644 --- a/sources/Helpers.h +++ b/sources/Helpers.h @@ -1,7 +1,16 @@ #pragma once +#include +#include #include #include #include +#ifdef HAVE_X86INTRIN_H +#include +#endif + +#ifdef HAVE_INTRIN_H +#include +#endif inline void trimInPlace(std::string_view& s) { @@ -168,4 +177,36 @@ private: LeakDetector leakDetector; #else #define LEAK_DETECTOR(Class) -#endif \ No newline at end of file +#endif + +class ScopedFTZ { + +public: + ScopedFTZ() + { +#if (HAVE_X86INTRIN_H || HAVE_INTRIN_H) + unsigned mask = _MM_DENORMALS_ZERO_MASK | _MM_FLUSH_ZERO_MASK; + registerState = _mm_getcsr(); + _mm_setcsr((registerState & (~mask)) | mask); +#elif HAVE_ARM_NEON_H + intptr_t mask = (1 << 24); + asm volatile("vmrs %0, fpscr" + : "=r"(registerState)); + asm volatile("vmsr fpscr, %0" + : + : "ri"((registerState & (~mask)) | mask)); +#endif + } + ~ScopedFTZ() + { +#if (HAVE_X86INTRIN_H || HAVE_INTRIN_H) + _mm_setcsr(registerState); +#elif HAVE_ARM_NEON_H + asm volatile("vmsr %0, fpscr" + : "=r"(registerState)); +#endif + } + +private: + unsigned registerState; +}; \ No newline at end of file diff --git a/sources/Synth.h b/sources/Synth.h index ebbe245b..46cdd8d0 100644 --- a/sources/Synth.h +++ b/sources/Synth.h @@ -3,6 +3,7 @@ #include "Parser.h" #include "Region.h" #include "SfzHelpers.h" +#include "Helpers.h" #include "StereoSpan.h" #include "absl/types/span.h" #include @@ -59,6 +60,7 @@ public: void renderBlock(StereoSpan buffer) { + ScopedFTZ ftz; buffer.fill(0.0f); StereoSpan tempSpan { tempBuffer, buffer.size() };