/*
 * Copyright (C) 2011, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1.  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef DenormalDisabler_h
#define DenormalDisabler_h

#include "wtf/CPU.h"
#include "wtf/MathExtras.h"
#include <float.h>

namespace blink {

// 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

#if HAVE(DENORMAL)
class DenormalDisabler {
public:
    DenormalDisabler()
            : m_savedCSR(0)
    {
        disableDenormals();
    }

    ~DenormalDisabler()
    {
        restoreState();
    }

    // This is a nop if we can flush denormals to zero in hardware.
    static inline float flushDenormalFloatToZero(float f)
    {
        return f;
    }
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;
        asm volatile("stmxcsr %0" : "=m" (result));
        return result;
    }

    inline void setCSR(int a)
    {
        int temp = a;
        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

};

#else
// FIXME: add implementations for other architectures and compilers
class DenormalDisabler {
public:
    DenormalDisabler() { }

    // Assume the worst case that other architectures and compilers
    // need to flush denormals to zero manually.
    static inline float flushDenormalFloatToZero(float f)
    {
        return (fabs(f) < FLT_MIN) ? 0.0f : f;
    }
};

#endif

} // namespace blink

#undef HAVE_DENORMAL
#endif // DenormalDisabler_h
