From 2ac2a39a214decb16ec5193eaafdb4a30bc976c1 Mon Sep 17 00:00:00 2001 From: hogliux Date: Tue, 17 Oct 2017 09:57:39 +0100 Subject: [PATCH] Added disableDenormalisedNumberSupport to query if denormals are disabled and improved documentation --- .../buffers/juce_FloatVectorOperations.cpp | 21 +++++++++++++++++-- .../buffers/juce_FloatVectorOperations.h | 15 +++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp index 86933ba6c4..4dc3a86d85 100644 --- a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp @@ -1084,7 +1084,7 @@ void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnab #endif } -void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport() noexcept +void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport (bool shouldDisable) noexcept { #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__)) #if JUCE_USE_SSE_INTRINSICS @@ -1093,14 +1093,31 @@ void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport() noe intptr_t mask = (1 << 24 /* FZ */); #endif - setFpStatusRegister (getFpStatusRegister() | mask); + setFpStatusRegister ((getFpStatusRegister() & (~mask)) | (shouldDisable ? mask : 0)); #else + ignoreUnused (shouldDisable); + #if ! (defined (JUCE_INTEL) || defined (JUCE_ARM)) jassertfalse; // No support for disable denormals mode on your platform #endif #endif } +bool JUCE_CALLTYPE FloatVectorOperations::areDenormalsDisabled() noexcept +{ + #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__)) + #if JUCE_USE_SSE_INTRINSICS + intptr_t mask = 0x8040; + #else /*JUCE_USE_ARM_NEON*/ + intptr_t mask = (1 << 24 /* FZ */); + #endif + + return ((getFpStatusRegister() & mask) == mask); + #else + return false; + #endif +} + ScopedNoDenormals::ScopedNoDenormals() noexcept { #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__)) diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h index ca5d734691..18f840414d 100644 --- a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h @@ -210,16 +210,19 @@ public: /** Finds the maximum value in the given array. */ static double JUCE_CALLTYPE findMaximum (const double* src, int numValues) noexcept; - /** On Intel CPUs, this method enables or disables the SSE flush-to-zero mode. - Effectively, this is a wrapper around a call to _MM_SET_FLUSH_ZERO_MODE - */ + /** This method enables or disables the SSE/NEON flush-to-zero mode. */ static void JUCE_CALLTYPE enableFlushToZeroMode (bool shouldEnable) noexcept; /** On Intel CPUs, this method enables the SSE flush-to-zero and denormalised-are-zero modes. - This effectively sets the DAZ and FZ bits of the MXCSR register. It's a convenient thing to - call before audio processing code where you really want to avoid denormalisation performance hits. + This effectively sets the DAZ and FZ bits of the MXCSR register. On arm CPUs this will + enable flush to zero mode. + It's a convenient thing to call before audio processing code where you really want to + avoid denormalisation performance hits. */ - static void JUCE_CALLTYPE disableDenormalisedNumberSupport() noexcept; + static void JUCE_CALLTYPE disableDenormalisedNumberSupport (bool shouldDisable = true) noexcept; + + /** This method returns true if denormals are currently disabled. */ + static bool JUCE_CALLTYPE areDenormalsDisabled() noexcept; private: friend ScopedNoDenormals;