LCOV - code coverage report
Current view: top level - dom/media/webaudio/blink - DenormalDisabler.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 24 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2011, Google Inc. All rights reserved.
       3             :  *
       4             :  * Redistribution and use in source and binary forms, with or without
       5             :  * modification, are permitted provided that the following conditions
       6             :  * are met:
       7             :  * 1.  Redistributions of source code must retain the above copyright
       8             :  *    notice, this list of conditions and the following disclaimer.
       9             :  * 2.  Redistributions in binary form must reproduce the above copyright
      10             :  *    notice, this list of conditions and the following disclaimer in the
      11             :  *    documentation and/or other materials provided with the distribution.
      12             :  *
      13             :  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
      14             :  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      15             :  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      16             :  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
      17             :  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      18             :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      19             :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
      20             :  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      21             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      22             :  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      23             :  */
      24             : 
      25             : #ifndef DenormalDisabler_h
      26             : #define DenormalDisabler_h
      27             : 
      28             : #include <cmath>
      29             : #include <float.h>
      30             : 
      31             : namespace WebCore {
      32             : 
      33             : // Deal with denormals. They can very seriously impact performance on x86.
      34             : 
      35             : // Define HAVE_DENORMAL if we support flushing denormals to zero.
      36             : 
      37             : #if defined (XP_WIN) && defined(_MSC_VER)
      38             : // Windows compiled using MSVC with SSE2
      39             : #define HAVE_DENORMAL 1
      40             : #endif
      41             : 
      42             : #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
      43             : // X86 chips can flush denormals
      44             : #define HAVE_DENORMAL 1
      45             : #endif
      46             : 
      47             : #if defined(__arm__) || defined(__aarch64__)
      48             : #define HAVE_DENORMAL 1
      49             : #endif
      50             : 
      51             : #ifdef HAVE_DENORMAL
      52             : class DenormalDisabler {
      53             : public:
      54           0 :     DenormalDisabler()
      55           0 :             : m_savedCSR(0)
      56             :     {
      57           0 :         disableDenormals();
      58           0 :     }
      59             : 
      60           0 :     ~DenormalDisabler()
      61           0 :     {
      62           0 :         restoreState();
      63           0 :     }
      64             : 
      65             :     // This is a nop if we can flush denormals to zero in hardware.
      66           0 :     static inline float flushDenormalFloatToZero(float f)
      67             :     {
      68           0 :         return f;
      69             :     }
      70             : private:
      71             :     unsigned m_savedCSR;
      72             : 
      73             : #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
      74           0 :     inline void disableDenormals()
      75             :     {
      76           0 :         m_savedCSR = getCSR();
      77           0 :         setCSR(m_savedCSR | 0x8040);
      78           0 :     }
      79             : 
      80           0 :     inline void restoreState()
      81             :     {
      82           0 :         setCSR(m_savedCSR);
      83           0 :     }
      84             : 
      85           0 :     inline int getCSR()
      86             :     {
      87             :         int result;
      88           0 :         asm volatile("stmxcsr %0" : "=m" (result));
      89           0 :         return result;
      90             :     }
      91             : 
      92           0 :     inline void setCSR(int a)
      93             :     {
      94           0 :         int temp = a;
      95           0 :         asm volatile("ldmxcsr %0" : : "m" (temp));
      96           0 :     }
      97             : 
      98             : #elif defined (XP_WIN) && defined(_MSC_VER)
      99             :     inline void disableDenormals()
     100             :     {
     101             :         // Save the current state, and set mode to flush denormals.
     102             :         //
     103             :         // http://stackoverflow.com/questions/637175/possible-bug-in-controlfp-s-may-not-restore-control-word-correctly
     104             :         _controlfp_s(&m_savedCSR, 0, 0);
     105             :         unsigned unused;
     106             :         _controlfp_s(&unused, _DN_FLUSH, _MCW_DN);
     107             :     }
     108             : 
     109             :     inline void restoreState()
     110             :     {
     111             :         unsigned unused;
     112             :         _controlfp_s(&unused, m_savedCSR, _MCW_DN);
     113             :     }
     114             : #elif defined(__arm__) || defined(__aarch64__)
     115             :     inline void disableDenormals()
     116             :     {
     117             :         m_savedCSR = getStatusWord();
     118             :         // Bit 24 is the flush-to-zero mode control bit. Setting it to 1 flushes denormals to 0.
     119             :         setStatusWord(m_savedCSR | (1 << 24));
     120             :     }
     121             : 
     122             :     inline void restoreState()
     123             :     {
     124             :         setStatusWord(m_savedCSR);
     125             :     }
     126             : 
     127             :     inline int getStatusWord()
     128             :     {
     129             :         int result;
     130             : #if defined(__aarch64__)
     131             :         asm volatile("mrs %x[result], FPCR" : [result] "=r" (result));
     132             : #else
     133             :         asm volatile("vmrs %[result], FPSCR" : [result] "=r" (result));
     134             : #endif
     135             :         return result;
     136             :     }
     137             : 
     138             :     inline void setStatusWord(int a)
     139             :     {
     140             : #if defined(__aarch64__)
     141             :         asm volatile("msr FPCR, %x[src]" : : [src] "r" (a));
     142             : #else
     143             :         asm volatile("vmsr FPSCR, %[src]" : : [src] "r" (a));
     144             : #endif
     145             :     }
     146             : 
     147             : #endif
     148             : 
     149             : };
     150             : 
     151             : #else
     152             : // FIXME: add implementations for other architectures and compilers
     153             : class DenormalDisabler {
     154             : public:
     155             :     DenormalDisabler() { }
     156             : 
     157             :     // Assume the worst case that other architectures and compilers
     158             :     // need to flush denormals to zero manually.
     159             :     static inline float flushDenormalFloatToZero(float f)
     160             :     {
     161             :         return (fabs(f) < FLT_MIN) ? 0.0f : f;
     162             :     }
     163             : };
     164             : 
     165             : #endif
     166             : 
     167             : } // namespace WebCore
     168             : #endif // DenormalDisabler_h

Generated by: LCOV version 1.13