Chromium Code Reviews| Index: Source/platform/audio/DenormalDisabler.h |
| diff --git a/Source/platform/audio/DenormalDisabler.h b/Source/platform/audio/DenormalDisabler.h |
| index d953c82138ad636c838e0a1916b07c16dff3321e..887f5c247e060bdf88678d9d469cbb36eba0f0d4 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) |
| + |
| +#if OS(WIN) && COMPILER(MSVC) && (_M_IX86_FP == 2) |
| +// Windows compiled using MSVC with SSE2 (_M_IX86_FP == 2) can flush denormals. |
|
Ken Russell (switch to Gerrit)
2014/07/18 18:46:56
A little searching indicates that _M_IX86_FP isn't
Raymond Toy
2014/07/18 20:08:34
Should just probably get rid of this check, now th
|
| #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) |
|
Ken Russell (switch to Gerrit)
2014/07/18 18:46:56
The conditions in this #elif don't match those in
|
| + 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 |