| Index: Source/platform/audio/DenormalDisabler.h
|
| diff --git a/Source/platform/audio/DenormalDisabler.h b/Source/platform/audio/DenormalDisabler.h
|
| index d953c82138ad636c838e0a1916b07c16dff3321e..38af14da1bf852223e5977ae27c7cf4149bfcec4 100644
|
| --- a/Source/platform/audio/DenormalDisabler.h
|
| +++ b/Source/platform/audio/DenormalDisabler.h
|
| @@ -34,11 +34,18 @@ namespace WebCore {
|
| // Deal with denormals. They can very seriously impact performance on x86.
|
|
|
| // Define HAVE_DENORMAL if we support flushing denormals to zero.
|
| +
|
| #if OS(WIN) && COMPILER(MSVC)
|
| +// Windows compiled using MSVC with SSE2
|
| #define HAVE_DENORMAL 1
|
| #endif
|
|
|
| #if COMPILER(GCC) && (CPU(X86) || CPU(X86_64))
|
| +// X86 chips can flush denormals
|
| +#define HAVE_DENORMAL 1
|
| +#endif
|
| +
|
| +#if CPU(ARM) || CPU(ARM64)
|
| #define HAVE_DENORMAL 1
|
| #endif
|
|
|
| @@ -48,43 +55,34 @@ public:
|
| DenormalDisabler()
|
| : m_savedCSR(0)
|
| {
|
| -#if OS(WIN) && COMPILER(MSVC)
|
| - // Save the current state, and set mode to flush denormals.
|
| - //
|
| - // http://stackoverflow.com/questions/637175/possible-bug-in-controlfp-s-may-not-restore-control-word-correctly
|
| - _controlfp_s(&m_savedCSR, 0, 0);
|
| - unsigned unused;
|
| - _controlfp_s(&unused, _DN_FLUSH, _MCW_DN);
|
| -#else
|
| - m_savedCSR = getCSR();
|
| - setCSR(m_savedCSR | 0x8040);
|
| -#endif
|
| + disableDenormals();
|
| }
|
|
|
| ~DenormalDisabler()
|
| {
|
| -#if OS(WIN) && COMPILER(MSVC)
|
| - unsigned unused;
|
| - _controlfp_s(&unused, m_savedCSR, _MCW_DN);
|
| -#else
|
| - setCSR(m_savedCSR);
|
| -#endif
|
| + restoreState();
|
| }
|
|
|
| // This is a nop if we can flush denormals to zero in hardware.
|
| static inline float flushDenormalFloatToZero(float f)
|
| {
|
| -#if OS(WIN) && COMPILER(MSVC) && (!_M_IX86_FP)
|
| - // For systems using x87 instead of sse, there's no hardware support
|
| - // to flush denormals automatically. Hence, we need to flush
|
| - // denormals to zero manually.
|
| - return (fabs(f) < FLT_MIN) ? 0.0f : f;
|
| -#else
|
| return f;
|
| -#endif
|
| }
|
| private:
|
| + unsigned m_savedCSR;
|
| +
|
| #if COMPILER(GCC) && (CPU(X86) || CPU(X86_64))
|
| + inline void disableDenormals()
|
| + {
|
| + m_savedCSR = getCSR();
|
| + setCSR(m_savedCSR | 0x8040);
|
| + }
|
| +
|
| + inline void restoreState()
|
| + {
|
| + setCSR(m_savedCSR);
|
| + }
|
| +
|
| inline int getCSR()
|
| {
|
| int result;
|
| @@ -98,9 +96,57 @@ private:
|
| asm volatile("ldmxcsr %0" : : "m" (temp));
|
| }
|
|
|
| +#elif OS(WIN) && COMPILER(MSVC)
|
| + inline void disableDenormals()
|
| + {
|
| + // Save the current state, and set mode to flush denormals.
|
| + //
|
| + // http://stackoverflow.com/questions/637175/possible-bug-in-controlfp-s-may-not-restore-control-word-correctly
|
| + _controlfp_s(&m_savedCSR, 0, 0);
|
| + unsigned unused;
|
| + _controlfp_s(&unused, _DN_FLUSH, _MCW_DN);
|
| + }
|
| +
|
| + inline void restoreState()
|
| + {
|
| + unsigned unused;
|
| + _controlfp_s(&unused, m_savedCSR, _MCW_DN);
|
| + }
|
| +#elif CPU(ARM) || CPU(ARM64)
|
| + inline void disableDenormals()
|
| + {
|
| + m_savedCSR = getStatusWord();
|
| + // Bit 24 is the flush-to-zero mode control bit. Setting it to 1 flushes denormals to 0.
|
| + setStatusWord(m_savedCSR | (1 << 24));
|
| + }
|
| +
|
| + inline void restoreState()
|
| + {
|
| + setStatusWord(m_savedCSR);
|
| + }
|
| +
|
| + inline int getStatusWord()
|
| + {
|
| + int result;
|
| +#if CPU(ARM64)
|
| + asm volatile("mrs %[result], FPCR" : [result] "=r" (result));
|
| +#else
|
| + asm volatile("vmrs %[result], FPSCR" : [result] "=r" (result));
|
| +#endif
|
| + return result;
|
| + }
|
| +
|
| + inline void setStatusWord(int a)
|
| + {
|
| +#if CPU(ARM64)
|
| + asm volatile("msr FPCR, %[src]" : : [src] "r" (a));
|
| +#else
|
| + asm volatile("vmsr FPSCR, %[src]" : : [src] "r" (a));
|
| +#endif
|
| + }
|
| +
|
| #endif
|
|
|
| - unsigned m_savedCSR;
|
| };
|
|
|
| #else
|
|
|