//
// Copyright 2002 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.
//

#include "compiler/translator/tree_ops/EmulatePrecision.h"

#include "compiler/translator/FunctionLookup.h"
#include "nb/cpp14oncpp11.h"

#include <memory>

namespace sh
{

namespace
{

CONSTEXPR const ImmutableString kParamXName("x");
CONSTEXPR const ImmutableString kParamYName("y");
CONSTEXPR const ImmutableString kAngleFrmString("angle_frm");
CONSTEXPR const ImmutableString kAngleFrlString("angle_frl");

class RoundingHelperWriter : angle::NonCopyable
{
  public:
    static RoundingHelperWriter *createHelperWriter(const ShShaderOutput outputLanguage);

    void writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion);
    void writeCompoundAssignmentHelper(TInfoSinkBase &sink,
                                       const char *lType,
                                       const char *rType,
                                       const char *opStr,
                                       const char *opNameStr);

    virtual ~RoundingHelperWriter() {}

  protected:
    RoundingHelperWriter(const ShShaderOutput outputLanguage) : mOutputLanguage(outputLanguage) {}
    RoundingHelperWriter() = delete;

    const ShShaderOutput mOutputLanguage;

  private:
    virtual std::string getTypeString(const char *glslType)                               = 0;
    virtual void writeFloatRoundingHelpers(TInfoSinkBase &sink)                           = 0;
    virtual void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) = 0;
    virtual void writeMatrixRoundingHelper(TInfoSinkBase &sink,
                                           const unsigned int columns,
                                           const unsigned int rows,
                                           const char *functionName)                      = 0;
};

class RoundingHelperWriterGLSL : public RoundingHelperWriter
{
  public:
    RoundingHelperWriterGLSL(const ShShaderOutput outputLanguage)
        : RoundingHelperWriter(outputLanguage)
    {}

  private:
    std::string getTypeString(const char *glslType) override;
    void writeFloatRoundingHelpers(TInfoSinkBase &sink) override;
    void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override;
    void writeMatrixRoundingHelper(TInfoSinkBase &sink,
                                   const unsigned int columns,
                                   const unsigned int rows,
                                   const char *functionName) override;
};

class RoundingHelperWriterESSL : public RoundingHelperWriterGLSL
{
  public:
    RoundingHelperWriterESSL(const ShShaderOutput outputLanguage)
        : RoundingHelperWriterGLSL(outputLanguage)
    {}

  private:
    std::string getTypeString(const char *glslType) override;
};

class RoundingHelperWriterHLSL : public RoundingHelperWriter
{
  public:
    RoundingHelperWriterHLSL(const ShShaderOutput outputLanguage)
        : RoundingHelperWriter(outputLanguage)
    {}

  private:
    std::string getTypeString(const char *glslType) override;
    void writeFloatRoundingHelpers(TInfoSinkBase &sink) override;
    void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override;
    void writeMatrixRoundingHelper(TInfoSinkBase &sink,
                                   const unsigned int columns,
                                   const unsigned int rows,
                                   const char *functionName) override;
};

RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOutput outputLanguage)
{
    ASSERT(EmulatePrecision::SupportedInLanguage(outputLanguage));
    switch (outputLanguage)
    {
        case SH_HLSL_4_1_OUTPUT:
            return new RoundingHelperWriterHLSL(outputLanguage);
        case SH_ESSL_OUTPUT:
            return new RoundingHelperWriterESSL(outputLanguage);
        default:
            return new RoundingHelperWriterGLSL(outputLanguage);
    }
}

void RoundingHelperWriter::writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion)
{
    // Write the angle_frm functions that round floating point numbers to
    // half precision, and angle_frl functions that round them to minimum lowp
    // precision.

    writeFloatRoundingHelpers(sink);
    writeVectorRoundingHelpers(sink, 2);
    writeVectorRoundingHelpers(sink, 3);
    writeVectorRoundingHelpers(sink, 4);
    if (shaderVersion > 100)
    {
        for (unsigned int columns = 2; columns <= 4; ++columns)
        {
            for (unsigned int rows = 2; rows <= 4; ++rows)
            {
                writeMatrixRoundingHelper(sink, columns, rows, "angle_frm");
                writeMatrixRoundingHelper(sink, columns, rows, "angle_frl");
            }
        }
    }
    else
    {
        for (unsigned int size = 2; size <= 4; ++size)
        {
            writeMatrixRoundingHelper(sink, size, size, "angle_frm");
            writeMatrixRoundingHelper(sink, size, size, "angle_frl");
        }
    }
}

void RoundingHelperWriter::writeCompoundAssignmentHelper(TInfoSinkBase &sink,
                                                         const char *lType,
                                                         const char *rType,
                                                         const char *opStr,
                                                         const char *opNameStr)
{
    std::string lTypeStr = getTypeString(lType);
    std::string rTypeStr = getTypeString(rType);

    // Note that y should be passed through angle_frm at the function call site,
    // but x can't be passed through angle_frm there since it is an inout parameter.
    // So only pass x and the result through angle_frm here.
    // clang-format off
    sink <<
        lTypeStr << " angle_compound_" << opNameStr << "_frm(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
        "    x = angle_frm(angle_frm(x) " << opStr << " y);\n"
        "    return x;\n"
        "}\n";
    sink <<
        lTypeStr << " angle_compound_" << opNameStr << "_frl(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
        "    x = angle_frl(angle_frl(x) " << opStr << " y);\n"
        "    return x;\n"
        "}\n";
    // clang-format on
}

std::string RoundingHelperWriterGLSL::getTypeString(const char *glslType)
{
    return glslType;
}

std::string RoundingHelperWriterESSL::getTypeString(const char *glslType)
{
    std::stringstream typeStrStr = sh::InitializeStream<std::stringstream>();
    typeStrStr << "highp " << glslType;
    return typeStrStr.str();
}

void RoundingHelperWriterGLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink)
{
    // Unoptimized version of angle_frm for single floats:
    //
    // int webgl_maxNormalExponent(in int exponentBits)
    // {
    //     int possibleExponents = int(exp2(float(exponentBits)));
    //     int exponentBias = possibleExponents / 2 - 1;
    //     int allExponentBitsOne = possibleExponents - 1;
    //     return (allExponentBitsOne - 1) - exponentBias;
    // }
    //
    // float angle_frm(in float x)
    // {
    //     int mantissaBits = 10;
    //     int exponentBits = 5;
    //     float possibleMantissas = exp2(float(mantissaBits));
    //     float mantissaMax = 2.0 - 1.0 / possibleMantissas;
    //     int maxNE = webgl_maxNormalExponent(exponentBits);
    //     float max = exp2(float(maxNE)) * mantissaMax;
    //     if (x > max)
    //     {
    //         return max;
    //     }
    //     if (x < -max)
    //     {
    //         return -max;
    //     }
    //     float exponent = floor(log2(abs(x)));
    //     if (abs(x) == 0.0 || exponent < -float(maxNE))
    //     {
    //         return 0.0 * sign(x)
    //     }
    //     x = x * exp2(-(exponent - float(mantissaBits)));
    //     x = sign(x) * floor(abs(x));
    //     return x * exp2(exponent - float(mantissaBits));
    // }

    // All numbers with a magnitude less than 2^-15 are subnormal, and are
    // flushed to zero.

    // Note the constant numbers below:
    // a) 65504 is the maximum possible mantissa (1.1111111111 in binary) times
    //    2^15, the maximum normal exponent.
    // b) 10.0 is the number of mantissa bits.
    // c) -25.0 is the minimum normal half-float exponent -15.0 minus the number
    //    of mantissa bits.
    // d) + 1e-30 is to make sure the argument of log2() won't be zero. It can
    //    only affect the result of log2 on x where abs(x) < 1e-22. Since these
    //    numbers will be flushed to zero either way (2^-15 is the smallest
    //    normal positive number), this does not introduce any error.

    std::string floatType = getTypeString("float");

    // clang-format off
    sink <<
        floatType << " angle_frm(in " << floatType << " x) {\n"
        "    x = clamp(x, -65504.0, 65504.0);\n"
        "    " << floatType << " exponent = floor(log2(abs(x) + 1e-30)) - 10.0;\n"
        "    bool isNonZero = (exponent >= -25.0);\n"
        "    x = x * exp2(-exponent);\n"
        "    x = sign(x) * floor(abs(x));\n"
        "    return x * exp2(exponent) * float(isNonZero);\n"
        "}\n";

    sink <<
        floatType << " angle_frl(in " << floatType << " x) {\n"
        "    x = clamp(x, -2.0, 2.0);\n"
        "    x = x * 256.0;\n"
        "    x = sign(x) * floor(abs(x));\n"
        "    return x * 0.00390625;\n"
        "}\n";
    // clang-format on
}

void RoundingHelperWriterGLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink,
                                                          const unsigned int size)
{
    std::stringstream vecTypeStrStr = sh::InitializeStream<std::stringstream>();
    vecTypeStrStr << "vec" << size;
    std::string vecType = getTypeString(vecTypeStrStr.str().c_str());

    // clang-format off
    sink <<
        vecType << " angle_frm(in " << vecType << " v) {\n"
        "    v = clamp(v, -65504.0, 65504.0);\n"
        "    " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
        "    bvec" << size << " isNonZero = greaterThanEqual(exponent, vec" << size << "(-25.0));\n"
        "    v = v * exp2(-exponent);\n"
        "    v = sign(v) * floor(abs(v));\n"
        "    return v * exp2(exponent) * vec" << size << "(isNonZero);\n"
        "}\n";

    sink <<
        vecType << " angle_frl(in " << vecType << " v) {\n"
        "    v = clamp(v, -2.0, 2.0);\n"
        "    v = v * 256.0;\n"
        "    v = sign(v) * floor(abs(v));\n"
        "    return v * 0.00390625;\n"
        "}\n";
    // clang-format on
}

void RoundingHelperWriterGLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink,
                                                         const unsigned int columns,
                                                         const unsigned int rows,
                                                         const char *functionName)
{
    std::stringstream matTypeStrStr = sh::InitializeStream<std::stringstream>();
    matTypeStrStr << "mat" << columns;
    if (rows != columns)
    {
        matTypeStrStr << "x" << rows;
    }
    std::string matType = getTypeString(matTypeStrStr.str().c_str());

    sink << matType << " " << functionName << "(in " << matType << " m) {\n"
         << "    " << matType << " rounded;\n";

    for (unsigned int i = 0; i < columns; ++i)
    {
        sink << "    rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
    }

    sink << "    return rounded;\n"
            "}\n";
}

static const char *GetHLSLTypeStr(const char *floatTypeStr)
{
    if (strcmp(floatTypeStr, "float") == 0)
    {
        return "float";
    }
    if (strcmp(floatTypeStr, "vec2") == 0)
    {
        return "float2";
    }
    if (strcmp(floatTypeStr, "vec3") == 0)
    {
        return "float3";
    }
    if (strcmp(floatTypeStr, "vec4") == 0)
    {
        return "float4";
    }
    if (strcmp(floatTypeStr, "mat2") == 0)
    {
        return "float2x2";
    }
    if (strcmp(floatTypeStr, "mat3") == 0)
    {
        return "float3x3";
    }
    if (strcmp(floatTypeStr, "mat4") == 0)
    {
        return "float4x4";
    }
    if (strcmp(floatTypeStr, "mat2x3") == 0)
    {
        return "float2x3";
    }
    if (strcmp(floatTypeStr, "mat2x4") == 0)
    {
        return "float2x4";
    }
    if (strcmp(floatTypeStr, "mat3x2") == 0)
    {
        return "float3x2";
    }
    if (strcmp(floatTypeStr, "mat3x4") == 0)
    {
        return "float3x4";
    }
    if (strcmp(floatTypeStr, "mat4x2") == 0)
    {
        return "float4x2";
    }
    if (strcmp(floatTypeStr, "mat4x3") == 0)
    {
        return "float4x3";
    }
    UNREACHABLE();
    return nullptr;
}

std::string RoundingHelperWriterHLSL::getTypeString(const char *glslType)
{
    return GetHLSLTypeStr(glslType);
}

void RoundingHelperWriterHLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink)
{
    // In HLSL scalars are the same as 1-vectors.
    writeVectorRoundingHelpers(sink, 1);
}

void RoundingHelperWriterHLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink,
                                                          const unsigned int size)
{
    std::stringstream vecTypeStrStr = sh::InitializeStream<std::stringstream>();
    vecTypeStrStr << "float" << size;
    std::string vecType = vecTypeStrStr.str();

    // clang-format off
    sink <<
        vecType << " angle_frm(" << vecType << " v) {\n"
        "    v = clamp(v, -65504.0, 65504.0);\n"
        "    " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
        "    bool" << size << " isNonZero = exponent < -25.0;\n"
        "    v = v * exp2(-exponent);\n"
        "    v = sign(v) * floor(abs(v));\n"
        "    return v * exp2(exponent) * (float" << size << ")(isNonZero);\n"
        "}\n";

    sink <<
        vecType << " angle_frl(" << vecType << " v) {\n"
        "    v = clamp(v, -2.0, 2.0);\n"
        "    v = v * 256.0;\n"
        "    v = sign(v) * floor(abs(v));\n"
        "    return v * 0.00390625;\n"
        "}\n";
    // clang-format on
}

void RoundingHelperWriterHLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink,
                                                         const unsigned int columns,
                                                         const unsigned int rows,
                                                         const char *functionName)
{
    std::stringstream matTypeStrStr = sh::InitializeStream<std::stringstream>();
    matTypeStrStr << "float" << columns << "x" << rows;
    std::string matType = matTypeStrStr.str();

    sink << matType << " " << functionName << "(" << matType << " m) {\n"
         << "    " << matType << " rounded;\n";

    for (unsigned int i = 0; i < columns; ++i)
    {
        sink << "    rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
    }

    sink << "    return rounded;\n"
            "}\n";
}

bool canRoundFloat(const TType &type)
{
    return type.getBasicType() == EbtFloat && !type.isArray() &&
           (type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium);
}

bool ParentUsesResult(TIntermNode *parent, TIntermTyped *node)
{
    if (!parent)
    {
        return false;
    }

    TIntermBlock *blockParent = parent->getAsBlock();
    // If the parent is a block, the result is not assigned anywhere,
    // so rounding it is not needed. In particular, this can avoid a lot of
    // unnecessary rounding of unused return values of assignment.
    if (blockParent)
    {
        return false;
    }
    TIntermBinary *binaryParent = parent->getAsBinaryNode();
    if (binaryParent && binaryParent->getOp() == EOpComma && (binaryParent->getRight() != node))
    {
        return false;
    }
    return true;
}

bool ParentConstructorTakesCareOfRounding(TIntermNode *parent, TIntermTyped *node)
{
    if (!parent)
    {
        return false;
    }
    TIntermAggregate *parentConstructor = parent->getAsAggregate();
    if (!parentConstructor || parentConstructor->getOp() != EOpConstruct)
    {
        return false;
    }
    if (parentConstructor->getPrecision() != node->getPrecision())
    {
        return false;
    }
    return canRoundFloat(parentConstructor->getType());
}

}  // namespace

EmulatePrecision::EmulatePrecision(TSymbolTable *symbolTable)
    : TLValueTrackingTraverser(true, true, true, symbolTable), mDeclaringVariables(false)
{}

void EmulatePrecision::visitSymbol(TIntermSymbol *node)
{
    TIntermNode *parent = getParentNode();
    if (canRoundFloat(node->getType()) && ParentUsesResult(parent, node) &&
        !ParentConstructorTakesCareOfRounding(parent, node) && !mDeclaringVariables &&
        !isLValueRequiredHere())
    {
        TIntermNode *replacement = createRoundingFunctionCallNode(node);
        queueReplacement(replacement, OriginalNode::BECOMES_CHILD);
    }
}

bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
{
    bool visitChildren = true;

    TOperator op = node->getOp();

    // RHS of initialize is not being declared.
    if (op == EOpInitialize && visit == InVisit)
        mDeclaringVariables = false;

    if ((op == EOpIndexDirectStruct) && visit == InVisit)
        visitChildren = false;

    if (visit != PreVisit)
        return visitChildren;

    const TType &type = node->getType();
    bool roundFloat   = canRoundFloat(type);

    if (roundFloat)
    {
        switch (op)
        {
            // Math operators that can result in a float may need to apply rounding to the return
            // value. Note that in the case of assignment, the rounding is applied to its return
            // value here, not the value being assigned.
            case EOpAssign:
            case EOpAdd:
            case EOpSub:
            case EOpMul:
            case EOpDiv:
            case EOpVectorTimesScalar:
            case EOpVectorTimesMatrix:
            case EOpMatrixTimesVector:
            case EOpMatrixTimesScalar:
            case EOpMatrixTimesMatrix:
            {
                TIntermNode *parent = getParentNode();
                if (!ParentUsesResult(parent, node) ||
                    ParentConstructorTakesCareOfRounding(parent, node))
                {
                    break;
                }
                TIntermNode *replacement = createRoundingFunctionCallNode(node);
                queueReplacement(replacement, OriginalNode::BECOMES_CHILD);
                break;
            }

            // Compound assignment cases need to replace the operator with a function call.
            case EOpAddAssign:
            {
                mEmulateCompoundAdd.insert(
                    TypePair(type.getBuiltInTypeNameString(),
                             node->getRight()->getType().getBuiltInTypeNameString()));
                TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
                    node->getLeft(), node->getRight(), "add");
                queueReplacement(replacement, OriginalNode::IS_DROPPED);
                break;
            }
            case EOpSubAssign:
            {
                mEmulateCompoundSub.insert(
                    TypePair(type.getBuiltInTypeNameString(),
                             node->getRight()->getType().getBuiltInTypeNameString()));
                TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
                    node->getLeft(), node->getRight(), "sub");
                queueReplacement(replacement, OriginalNode::IS_DROPPED);
                break;
            }
            case EOpMulAssign:
            case EOpVectorTimesMatrixAssign:
            case EOpVectorTimesScalarAssign:
            case EOpMatrixTimesScalarAssign:
            case EOpMatrixTimesMatrixAssign:
            {
                mEmulateCompoundMul.insert(
                    TypePair(type.getBuiltInTypeNameString(),
                             node->getRight()->getType().getBuiltInTypeNameString()));
                TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
                    node->getLeft(), node->getRight(), "mul");
                queueReplacement(replacement, OriginalNode::IS_DROPPED);
                break;
            }
            case EOpDivAssign:
            {
                mEmulateCompoundDiv.insert(
                    TypePair(type.getBuiltInTypeNameString(),
                             node->getRight()->getType().getBuiltInTypeNameString()));
                TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
                    node->getLeft(), node->getRight(), "div");
                queueReplacement(replacement, OriginalNode::IS_DROPPED);
                break;
            }
            default:
                // The rest of the binary operations should not need precision emulation.
                break;
        }
    }
    return visitChildren;
}

bool EmulatePrecision::visitDeclaration(Visit visit, TIntermDeclaration *node)
{
    // Variable or interface block declaration.
    if (visit == PreVisit)
    {
        mDeclaringVariables = true;
    }
    else if (visit == InVisit)
    {
        mDeclaringVariables = true;
    }
    else
    {
        mDeclaringVariables = false;
    }
    return true;
}

bool EmulatePrecision::visitGlobalQualifierDeclaration(Visit visit,
                                                       TIntermGlobalQualifierDeclaration *node)
{
    return false;
}

bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
{
    if (visit != PreVisit)
        return true;

    // User-defined function return values are not rounded. The calculations that produced
    // the value inside the function definition should have been rounded.
    TOperator op = node->getOp();
    if (op == EOpCallInternalRawFunction || op == EOpCallFunctionInAST ||
        (op == EOpConstruct && node->getBasicType() == EbtStruct))
    {
        return true;
    }

    TIntermNode *parent = getParentNode();
    if (canRoundFloat(node->getType()) && ParentUsesResult(parent, node) &&
        !ParentConstructorTakesCareOfRounding(parent, node))
    {
        TIntermNode *replacement = createRoundingFunctionCallNode(node);
        queueReplacement(replacement, OriginalNode::BECOMES_CHILD);
    }
    return true;
}

bool EmulatePrecision::visitUnary(Visit visit, TIntermUnary *node)
{
    switch (node->getOp())
    {
        case EOpNegative:
        case EOpLogicalNot:
        case EOpPostIncrement:
        case EOpPostDecrement:
        case EOpPreIncrement:
        case EOpPreDecrement:
        case EOpLogicalNotComponentWise:
            break;
        default:
            if (canRoundFloat(node->getType()) && visit == PreVisit)
            {
                TIntermNode *replacement = createRoundingFunctionCallNode(node);
                queueReplacement(replacement, OriginalNode::BECOMES_CHILD);
            }
            break;
    }

    return true;
}

void EmulatePrecision::writeEmulationHelpers(TInfoSinkBase &sink,
                                             const int shaderVersion,
                                             const ShShaderOutput outputLanguage)
{
    std::unique_ptr<RoundingHelperWriter> roundingHelperWriter(
        RoundingHelperWriter::createHelperWriter(outputLanguage));

    roundingHelperWriter->writeCommonRoundingHelpers(sink, shaderVersion);

    EmulationSet::const_iterator it;
    for (it = mEmulateCompoundAdd.begin(); it != mEmulateCompoundAdd.end(); it++)
        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "+", "add");
    for (it = mEmulateCompoundSub.begin(); it != mEmulateCompoundSub.end(); it++)
        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "-", "sub");
    for (it = mEmulateCompoundDiv.begin(); it != mEmulateCompoundDiv.end(); it++)
        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "/", "div");
    for (it = mEmulateCompoundMul.begin(); it != mEmulateCompoundMul.end(); it++)
        roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "*", "mul");
}

// static
bool EmulatePrecision::SupportedInLanguage(const ShShaderOutput outputLanguage)
{
    switch (outputLanguage)
    {
        case SH_HLSL_4_1_OUTPUT:
        case SH_ESSL_OUTPUT:
            return true;
        default:
            // Other languages not yet supported
            return (outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
                    sh::IsGLSL130OrNewer(outputLanguage));
    }
}

const TFunction *EmulatePrecision::getInternalFunction(const ImmutableString &functionName,
                                                       const TType &returnType,
                                                       TIntermSequence *arguments,
                                                       const TVector<const TVariable *> &parameters,
                                                       bool knownToNotHaveSideEffects)
{
    ImmutableString mangledName = TFunctionLookup::GetMangledName(functionName.data(), *arguments);
    if (mInternalFunctions.find(mangledName) == mInternalFunctions.end())
    {
        TFunction *func = new TFunction(mSymbolTable, functionName, SymbolType::AngleInternal,
                                        new TType(returnType), knownToNotHaveSideEffects);
        ASSERT(parameters.size() == arguments->size());
        for (size_t i = 0; i < parameters.size(); ++i)
        {
            func->addParameter(parameters[i]);
        }
        mInternalFunctions[mangledName] = func;
    }
    return mInternalFunctions[mangledName];
}

TIntermAggregate *EmulatePrecision::createRoundingFunctionCallNode(TIntermTyped *roundedChild)
{
    const ImmutableString *roundFunctionName = &kAngleFrmString;
    if (roundedChild->getPrecision() == EbpLow)
        roundFunctionName = &kAngleFrlString;
    TIntermSequence *arguments = new TIntermSequence();
    arguments->push_back(roundedChild);

    TVector<const TVariable *> parameters;
    TType *paramType = new TType(roundedChild->getType());
    paramType->setPrecision(EbpHigh);
    paramType->setQualifier(EvqIn);
    parameters.push_back(new TVariable(mSymbolTable, kParamXName,
                                       static_cast<const TType *>(paramType),
                                       SymbolType::AngleInternal));

    return TIntermAggregate::CreateRawFunctionCall(
        *getInternalFunction(*roundFunctionName, roundedChild->getType(), arguments, parameters,
                             true),
        arguments);
}

TIntermAggregate *EmulatePrecision::createCompoundAssignmentFunctionCallNode(TIntermTyped *left,
                                                                             TIntermTyped *right,
                                                                             const char *opNameStr)
{
    std::stringstream strstr = sh::InitializeStream<std::stringstream>();
    if (left->getPrecision() == EbpMedium)
        strstr << "angle_compound_" << opNameStr << "_frm";
    else
        strstr << "angle_compound_" << opNameStr << "_frl";
    ImmutableString functionName = ImmutableString(strstr.str());
    TIntermSequence *arguments   = new TIntermSequence();
    arguments->push_back(left);
    arguments->push_back(right);

    TVector<const TVariable *> parameters;
    TType *leftParamType = new TType(left->getType());
    leftParamType->setPrecision(EbpHigh);
    leftParamType->setQualifier(EvqOut);
    parameters.push_back(new TVariable(mSymbolTable, kParamXName,
                                       static_cast<const TType *>(leftParamType),
                                       SymbolType::AngleInternal));
    TType *rightParamType = new TType(right->getType());
    rightParamType->setPrecision(EbpHigh);
    rightParamType->setQualifier(EvqIn);
    parameters.push_back(new TVariable(mSymbolTable, kParamYName,
                                       static_cast<const TType *>(rightParamType),
                                       SymbolType::AngleInternal));

    return TIntermAggregate::CreateRawFunctionCall(
        *getInternalFunction(functionName, left->getType(), arguments, parameters, false),
        arguments);
}

}  // namespace sh
