//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ConstantUnion: Constant folding helper class.

#include "compiler/translator/ConstantUnion.h"

#include "common/mathutil.h"
#include "compiler/translator/Diagnostics.h"

namespace sh
{

namespace
{

float CheckedSum(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line)
{
    float result = lhs + rhs;
    if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
    {
        diag->warning(line, "Constant folded undefined addition generated NaN", "+");
    }
    else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
    {
        diag->warning(line, "Constant folded addition overflowed to infinity", "+");
    }
    return result;
}

float CheckedDiff(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line)
{
    float result = lhs - rhs;
    if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
    {
        diag->warning(line, "Constant folded undefined subtraction generated NaN", "-");
    }
    else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
    {
        diag->warning(line, "Constant folded subtraction overflowed to infinity", "-");
    }
    return result;
}

float CheckedMul(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line)
{
    float result = lhs * rhs;
    if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
    {
        diag->warning(line, "Constant folded undefined multiplication generated NaN", "*");
    }
    else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
    {
        diag->warning(line, "Constant folded multiplication overflowed to infinity", "*");
    }
    return result;
}

bool IsValidShiftOffset(const TConstantUnion &rhs)
{
    return (rhs.getType() == EbtInt && (rhs.getIConst() >= 0 && rhs.getIConst() <= 31)) ||
           (rhs.getType() == EbtUInt && rhs.getUConst() <= 31u);
}

}  // anonymous namespace

TConstantUnion::TConstantUnion()
{
    iConst = 0;
    type   = EbtVoid;
}

bool TConstantUnion::cast(TBasicType newType, const TConstantUnion &constant)
{
    switch (newType)
    {
        case EbtFloat:
            switch (constant.type)
            {
                case EbtInt:
                    setFConst(static_cast<float>(constant.getIConst()));
                    break;
                case EbtUInt:
                    setFConst(static_cast<float>(constant.getUConst()));
                    break;
                case EbtBool:
                    setFConst(static_cast<float>(constant.getBConst()));
                    break;
                case EbtFloat:
                    setFConst(static_cast<float>(constant.getFConst()));
                    break;
                default:
                    return false;
            }
            break;
        case EbtInt:
            switch (constant.type)
            {
                case EbtInt:
                    setIConst(static_cast<int>(constant.getIConst()));
                    break;
                case EbtUInt:
                    setIConst(static_cast<int>(constant.getUConst()));
                    break;
                case EbtBool:
                    setIConst(static_cast<int>(constant.getBConst()));
                    break;
                case EbtFloat:
                    setIConst(static_cast<int>(constant.getFConst()));
                    break;
                default:
                    return false;
            }
            break;
        case EbtUInt:
            switch (constant.type)
            {
                case EbtInt:
                    setUConst(static_cast<unsigned int>(constant.getIConst()));
                    break;
                case EbtUInt:
                    setUConst(static_cast<unsigned int>(constant.getUConst()));
                    break;
                case EbtBool:
                    setUConst(static_cast<unsigned int>(constant.getBConst()));
                    break;
                case EbtFloat:
                    setUConst(static_cast<unsigned int>(constant.getFConst()));
                    break;
                default:
                    return false;
            }
            break;
        case EbtBool:
            switch (constant.type)
            {
                case EbtInt:
                    setBConst(constant.getIConst() != 0);
                    break;
                case EbtUInt:
                    setBConst(constant.getUConst() != 0);
                    break;
                case EbtBool:
                    setBConst(constant.getBConst());
                    break;
                case EbtFloat:
                    setBConst(constant.getFConst() != 0.0f);
                    break;
                default:
                    return false;
            }
            break;
        case EbtStruct:  // Struct fields don't get cast
            switch (constant.type)
            {
                case EbtInt:
                    setIConst(constant.getIConst());
                    break;
                case EbtUInt:
                    setUConst(constant.getUConst());
                    break;
                case EbtBool:
                    setBConst(constant.getBConst());
                    break;
                case EbtFloat:
                    setFConst(constant.getFConst());
                    break;
                default:
                    return false;
            }
            break;
        default:
            return false;
    }

    return true;
}

bool TConstantUnion::operator==(const int i) const
{
    return i == iConst;
}

bool TConstantUnion::operator==(const unsigned int u) const
{
    return u == uConst;
}

bool TConstantUnion::operator==(const float f) const
{
    return f == fConst;
}

bool TConstantUnion::operator==(const bool b) const
{
    return b == bConst;
}

bool TConstantUnion::operator==(const TYuvCscStandardEXT s) const
{
    return s == yuvCscStandardEXTConst;
}

bool TConstantUnion::operator==(const TConstantUnion &constant) const
{
    if (constant.type != type)
        return false;

    switch (type)
    {
        case EbtInt:
            return constant.iConst == iConst;
        case EbtUInt:
            return constant.uConst == uConst;
        case EbtFloat:
            return constant.fConst == fConst;
        case EbtBool:
            return constant.bConst == bConst;
        case EbtYuvCscStandardEXT:
            return constant.yuvCscStandardEXTConst == yuvCscStandardEXTConst;
        default:
            return false;
    }
}

bool TConstantUnion::operator!=(const int i) const
{
    return !operator==(i);
}

bool TConstantUnion::operator!=(const unsigned int u) const
{
    return !operator==(u);
}

bool TConstantUnion::operator!=(const float f) const
{
    return !operator==(f);
}

bool TConstantUnion::operator!=(const bool b) const
{
    return !operator==(b);
}

bool TConstantUnion::operator!=(const TYuvCscStandardEXT s) const
{
    return !operator==(s);
}

bool TConstantUnion::operator!=(const TConstantUnion &constant) const
{
    return !operator==(constant);
}

bool TConstantUnion::operator>(const TConstantUnion &constant) const
{
    ASSERT(type == constant.type);
    switch (type)
    {
        case EbtInt:
            return iConst > constant.iConst;
        case EbtUInt:
            return uConst > constant.uConst;
        case EbtFloat:
            return fConst > constant.fConst;
        default:
            return false;  // Invalid operation, handled at semantic analysis
    }
}

bool TConstantUnion::operator<(const TConstantUnion &constant) const
{
    ASSERT(type == constant.type);
    switch (type)
    {
        case EbtInt:
            return iConst < constant.iConst;
        case EbtUInt:
            return uConst < constant.uConst;
        case EbtFloat:
            return fConst < constant.fConst;
        default:
            return false;  // Invalid operation, handled at semantic analysis
    }
}

// static
TConstantUnion TConstantUnion::add(const TConstantUnion &lhs,
                                   const TConstantUnion &rhs,
                                   TDiagnostics *diag,
                                   const TSourceLoc &line)
{
    TConstantUnion returnValue;
    ASSERT(lhs.type == rhs.type);
    switch (lhs.type)
    {
        case EbtInt:
            returnValue.setIConst(gl::WrappingSum<int>(lhs.iConst, rhs.iConst));
            break;
        case EbtUInt:
            returnValue.setUConst(gl::WrappingSum<unsigned int>(lhs.uConst, rhs.uConst));
            break;
        case EbtFloat:
            returnValue.setFConst(CheckedSum(lhs.fConst, rhs.fConst, diag, line));
            break;
        default:
            UNREACHABLE();
    }

    return returnValue;
}

// static
TConstantUnion TConstantUnion::sub(const TConstantUnion &lhs,
                                   const TConstantUnion &rhs,
                                   TDiagnostics *diag,
                                   const TSourceLoc &line)
{
    TConstantUnion returnValue;
    ASSERT(lhs.type == rhs.type);
    switch (lhs.type)
    {
        case EbtInt:
            returnValue.setIConst(gl::WrappingDiff<int>(lhs.iConst, rhs.iConst));
            break;
        case EbtUInt:
            returnValue.setUConst(gl::WrappingDiff<unsigned int>(lhs.uConst, rhs.uConst));
            break;
        case EbtFloat:
            returnValue.setFConst(CheckedDiff(lhs.fConst, rhs.fConst, diag, line));
            break;
        default:
            UNREACHABLE();
    }

    return returnValue;
}

// static
TConstantUnion TConstantUnion::mul(const TConstantUnion &lhs,
                                   const TConstantUnion &rhs,
                                   TDiagnostics *diag,
                                   const TSourceLoc &line)
{
    TConstantUnion returnValue;
    ASSERT(lhs.type == rhs.type);
    switch (lhs.type)
    {
        case EbtInt:
            returnValue.setIConst(gl::WrappingMul(lhs.iConst, rhs.iConst));
            break;
        case EbtUInt:
            // Unsigned integer math in C++ is defined to be done in modulo 2^n, so we rely on that
            // to implement wrapping multiplication.
            returnValue.setUConst(lhs.uConst * rhs.uConst);
            break;
        case EbtFloat:
            returnValue.setFConst(CheckedMul(lhs.fConst, rhs.fConst, diag, line));
            break;
        default:
            UNREACHABLE();
    }

    return returnValue;
}

TConstantUnion TConstantUnion::operator%(const TConstantUnion &constant) const
{
    TConstantUnion returnValue;
    ASSERT(type == constant.type);
    switch (type)
    {
        case EbtInt:
            returnValue.setIConst(iConst % constant.iConst);
            break;
        case EbtUInt:
            returnValue.setUConst(uConst % constant.uConst);
            break;
        default:
            UNREACHABLE();
    }

    return returnValue;
}

// static
TConstantUnion TConstantUnion::rshift(const TConstantUnion &lhs,
                                      const TConstantUnion &rhs,
                                      TDiagnostics *diag,
                                      const TSourceLoc &line)
{
    TConstantUnion returnValue;
    ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
    ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
    if (!IsValidShiftOffset(rhs))
    {
        diag->warning(line, "Undefined shift (operand out of range)", ">>");
        switch (lhs.type)
        {
            case EbtInt:
                returnValue.setIConst(0);
                break;
            case EbtUInt:
                returnValue.setUConst(0u);
                break;
            default:
                UNREACHABLE();
        }
        return returnValue;
    }

    switch (lhs.type)
    {
        case EbtInt:
        {
            unsigned int shiftOffset = 0;
            switch (rhs.type)
            {
                case EbtInt:
                    shiftOffset = static_cast<unsigned int>(rhs.iConst);
                    break;
                case EbtUInt:
                    shiftOffset = rhs.uConst;
                    break;
                default:
                    UNREACHABLE();
            }
            if (shiftOffset > 0)
            {
                // ESSL 3.00.6 section 5.9: "If E1 is a signed integer, the right-shift will extend
                // the sign bit." In C++ shifting negative integers is undefined, so we implement
                // extending the sign bit manually.
                int lhsSafe = lhs.iConst;
                if (lhsSafe == std::numeric_limits<int>::min())
                {
                    // The min integer needs special treatment because only bit it has set is the
                    // sign bit, which we clear later to implement safe right shift of negative
                    // numbers.
                    lhsSafe = -0x40000000;
                    --shiftOffset;
                }
                if (shiftOffset > 0)
                {
                    bool extendSignBit = false;
                    if (lhsSafe < 0)
                    {
                        extendSignBit = true;
                        // Clear the sign bit so that bitshift right is defined in C++.
                        lhsSafe &= 0x7fffffff;
                        ASSERT(lhsSafe > 0);
                    }
                    returnValue.setIConst(lhsSafe >> shiftOffset);

                    // Manually fill in the extended sign bit if necessary.
                    if (extendSignBit)
                    {
                        int extendedSignBit = static_cast<int>(0xffffffffu << (31 - shiftOffset));
                        returnValue.setIConst(returnValue.getIConst() | extendedSignBit);
                    }
                }
                else
                {
                    returnValue.setIConst(lhsSafe);
                }
            }
            else
            {
                returnValue.setIConst(lhs.iConst);
            }
            break;
        }
        case EbtUInt:
            switch (rhs.type)
            {
                case EbtInt:
                    returnValue.setUConst(lhs.uConst >> rhs.iConst);
                    break;
                case EbtUInt:
                    returnValue.setUConst(lhs.uConst >> rhs.uConst);
                    break;
                default:
                    UNREACHABLE();
            }
            break;

        default:
            UNREACHABLE();
    }
    return returnValue;
}

// static
TConstantUnion TConstantUnion::lshift(const TConstantUnion &lhs,
                                      const TConstantUnion &rhs,
                                      TDiagnostics *diag,
                                      const TSourceLoc &line)
{
    TConstantUnion returnValue;
    ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
    ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
    if (!IsValidShiftOffset(rhs))
    {
        diag->warning(line, "Undefined shift (operand out of range)", "<<");
        switch (lhs.type)
        {
            case EbtInt:
                returnValue.setIConst(0);
                break;
            case EbtUInt:
                returnValue.setUConst(0u);
                break;
            default:
                UNREACHABLE();
        }
        return returnValue;
    }

    switch (lhs.type)
    {
        case EbtInt:
            switch (rhs.type)
            {
                // Cast to unsigned integer before shifting, since ESSL 3.00.6 section 5.9 says that
                // lhs is "interpreted as a bit pattern". This also avoids the possibility of signed
                // integer overflow or undefined shift of a negative integer.
                case EbtInt:
                    returnValue.setIConst(
                        static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.iConst));
                    break;
                case EbtUInt:
                    returnValue.setIConst(
                        static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.uConst));
                    break;
                default:
                    UNREACHABLE();
            }
            break;

        case EbtUInt:
            switch (rhs.type)
            {
                case EbtInt:
                    returnValue.setUConst(lhs.uConst << rhs.iConst);
                    break;
                case EbtUInt:
                    returnValue.setUConst(lhs.uConst << rhs.uConst);
                    break;
                default:
                    UNREACHABLE();
            }
            break;

        default:
            UNREACHABLE();
    }
    return returnValue;
}

TConstantUnion TConstantUnion::operator&(const TConstantUnion &constant) const
{
    TConstantUnion returnValue;
    ASSERT(constant.type == EbtInt || constant.type == EbtUInt);
    switch (type)
    {
        case EbtInt:
            returnValue.setIConst(iConst & constant.iConst);
            break;
        case EbtUInt:
            returnValue.setUConst(uConst & constant.uConst);
            break;
        default:
            UNREACHABLE();
    }

    return returnValue;
}

TConstantUnion TConstantUnion::operator|(const TConstantUnion &constant) const
{
    TConstantUnion returnValue;
    ASSERT(type == constant.type);
    switch (type)
    {
        case EbtInt:
            returnValue.setIConst(iConst | constant.iConst);
            break;
        case EbtUInt:
            returnValue.setUConst(uConst | constant.uConst);
            break;
        default:
            UNREACHABLE();
    }

    return returnValue;
}

TConstantUnion TConstantUnion::operator^(const TConstantUnion &constant) const
{
    TConstantUnion returnValue;
    ASSERT(type == constant.type);
    switch (type)
    {
        case EbtInt:
            returnValue.setIConst(iConst ^ constant.iConst);
            break;
        case EbtUInt:
            returnValue.setUConst(uConst ^ constant.uConst);
            break;
        default:
            UNREACHABLE();
    }

    return returnValue;
}

TConstantUnion TConstantUnion::operator&&(const TConstantUnion &constant) const
{
    TConstantUnion returnValue;
    ASSERT(type == constant.type);
    switch (type)
    {
        case EbtBool:
            returnValue.setBConst(bConst && constant.bConst);
            break;
        default:
            UNREACHABLE();
    }

    return returnValue;
}

TConstantUnion TConstantUnion::operator||(const TConstantUnion &constant) const
{
    TConstantUnion returnValue;
    ASSERT(type == constant.type);
    switch (type)
    {
        case EbtBool:
            returnValue.setBConst(bConst || constant.bConst);
            break;
        default:
            UNREACHABLE();
    }

    return returnValue;
}

}  // namespace sh
