content/media/webaudio/blink/DenormalDisabler.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/media/webaudio/blink/DenormalDisabler.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,125 @@
     1.4 +/*
     1.5 + * Copyright (C) 2011, Google Inc. All rights reserved.
     1.6 + *
     1.7 + * Redistribution and use in source and binary forms, with or without
     1.8 + * modification, are permitted provided that the following conditions
     1.9 + * are met:
    1.10 + * 1.  Redistributions of source code must retain the above copyright
    1.11 + *    notice, this list of conditions and the following disclaimer.
    1.12 + * 2.  Redistributions in binary form must reproduce the above copyright
    1.13 + *    notice, this list of conditions and the following disclaimer in the
    1.14 + *    documentation and/or other materials provided with the distribution.
    1.15 + *
    1.16 + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
    1.17 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    1.18 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    1.19 + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
    1.20 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    1.21 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    1.22 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
    1.23 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.24 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    1.25 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.26 + */
    1.27 +
    1.28 +#ifndef DenormalDisabler_h
    1.29 +#define DenormalDisabler_h
    1.30 +
    1.31 +#define _USE_MATH_DEFINES
    1.32 +#include <cmath>
    1.33 +#include <float.h>
    1.34 +
    1.35 +namespace WebCore {
    1.36 +
    1.37 +// Deal with denormals. They can very seriously impact performance on x86.
    1.38 +
    1.39 +// Define HAVE_DENORMAL if we support flushing denormals to zero.
    1.40 +#if defined(XP_WIN) && defined(_MSC_VER)
    1.41 +#define HAVE_DENORMAL
    1.42 +#endif
    1.43 +
    1.44 +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
    1.45 +#define HAVE_DENORMAL
    1.46 +#endif
    1.47 +
    1.48 +#ifdef HAVE_DENORMAL
    1.49 +class DenormalDisabler {
    1.50 +public:
    1.51 +    DenormalDisabler()
    1.52 +            : m_savedCSR(0)
    1.53 +    {
    1.54 +#if defined(XP_WIN) && defined(_MSC_VER)
    1.55 +        // Save the current state, and set mode to flush denormals.
    1.56 +        //
    1.57 +        // http://stackoverflow.com/questions/637175/possible-bug-in-controlfp-s-may-not-restore-control-word-correctly
    1.58 +        _controlfp_s(&m_savedCSR, 0, 0);
    1.59 +        unsigned int unused;
    1.60 +        _controlfp_s(&unused, _DN_FLUSH, _MCW_DN);
    1.61 +#else
    1.62 +        m_savedCSR = getCSR();
    1.63 +        setCSR(m_savedCSR | 0x8040);
    1.64 +#endif
    1.65 +    }
    1.66 +
    1.67 +    ~DenormalDisabler()
    1.68 +    {
    1.69 +#if defined(XP_WIN) && defined(_MSC_VER)
    1.70 +        unsigned int unused;
    1.71 +        _controlfp_s(&unused, m_savedCSR, _MCW_DN);
    1.72 +#else
    1.73 +        setCSR(m_savedCSR);
    1.74 +#endif
    1.75 +    }
    1.76 +
    1.77 +    // This is a nop if we can flush denormals to zero in hardware.
    1.78 +    static inline float flushDenormalFloatToZero(float f)
    1.79 +    {
    1.80 +#if defined(XP_WIN) && defined(_MSC_VER) && _M_IX86_FP
    1.81 +        // For systems using x87 instead of sse, there's no hardware support
    1.82 +        // to flush denormals automatically. Hence, we need to flush
    1.83 +        // denormals to zero manually.
    1.84 +        return (fabs(f) < FLT_MIN) ? 0.0f : f;
    1.85 +#else
    1.86 +        return f;
    1.87 +#endif
    1.88 +    }
    1.89 +private:
    1.90 +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
    1.91 +    inline int getCSR()
    1.92 +    {
    1.93 +        int result;
    1.94 +        asm volatile("stmxcsr %0" : "=m" (result));
    1.95 +        return result;
    1.96 +    }
    1.97 +
    1.98 +    inline void setCSR(int a)
    1.99 +    {
   1.100 +        int temp = a;
   1.101 +        asm volatile("ldmxcsr %0" : : "m" (temp));
   1.102 +    }
   1.103 +
   1.104 +#endif
   1.105 +
   1.106 +    unsigned int m_savedCSR;
   1.107 +};
   1.108 +
   1.109 +#else
   1.110 +// FIXME: add implementations for other architectures and compilers
   1.111 +class DenormalDisabler {
   1.112 +public:
   1.113 +    DenormalDisabler() { }
   1.114 +
   1.115 +    // Assume the worst case that other architectures and compilers
   1.116 +    // need to flush denormals to zero manually.
   1.117 +    static inline float flushDenormalFloatToZero(float f)
   1.118 +    {
   1.119 +        return (fabs(f) < FLT_MIN) ? 0.0f : f;
   1.120 +    }
   1.121 +};
   1.122 +
   1.123 +#endif
   1.124 +
   1.125 +} // WebCore
   1.126 +
   1.127 +#undef HAVE_DENORMAL
   1.128 +#endif // DenormalDisabler_h

mercurial