//
//Copyright (C) 2014-2015 LunarG, 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:
//
//    Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
//    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.
//
//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE
//COPYRIGHT HOLDERS OR 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.

//
// Author: John Kessenich, LunarG
//

//
// Parameterize the SPIR-V enumerants.
//

#include "spirv.hpp"

#include <vector>

namespace spv {

// Fill in all the parameters
void Parameterize();

// Return the English names of all the enums.
const char* SourceString(int);
const char* AddressingString(int);
const char* MemoryString(int);
const char* ExecutionModelString(int);
const char* ExecutionModeString(int);
const char* StorageClassString(int);
const char* DecorationString(int);
const char* BuiltInString(int);
const char* DimensionString(int);
const char* SelectControlString(int);
const char* LoopControlString(int);
const char* FunctionControlString(int);
const char* SamplerAddressingModeString(int);
const char* SamplerFilterModeString(int);
const char* ImageFormatString(int);
const char* ImageChannelOrderString(int);
const char* ImageChannelTypeString(int);
const char* ImageOperands(int);
const char* FPFastMathString(int);
const char* FPRoundingModeString(int);
const char* LinkageTypeString(int);
const char* FuncParamAttrString(int);
const char* AccessQualifierString(int);
const char* MemorySemanticsString(int);
const char* MemoryAccessString(int);
const char* ExecutionScopeString(int);
const char* GroupOperationString(int);
const char* KernelEnqueueFlagsString(int);
const char* KernelProfilingInfoString(int);
const char* CapabilityString(int);
const char* OpcodeString(int);

// For grouping opcodes into subsections
enum OpcodeClass {
    OpClassMisc,
    OpClassDebug,
    OpClassAnnotate,
    OpClassExtension,
    OpClassMode,
    OpClassType,
    OpClassConstant,
    OpClassMemory,
    OpClassFunction,
    OpClassImage,
    OpClassConvert,
    OpClassComposite,
    OpClassArithmetic,
    OpClassBit,
    OpClassRelationalLogical,
    OpClassDerivative,
    OpClassFlowControl,
    OpClassAtomic,
    OpClassPrimitive,
    OpClassBarrier,
    OpClassGroup,
    OpClassDeviceSideEnqueue,
    OpClassPipe,

    OpClassCount,
    OpClassMissing             // all instructions start out as missing
};

// For parameterizing operands.
enum OperandClass {
    OperandNone,
    OperandId,
    OperandOptionalId,
    OperandOptionalImage,
    OperandVariableIds,
    OperandOptionalLiteral,
    OperandVariableLiterals,
    OperandVariableIdLiteral,
    OperandVariableLiteralId,
    OperandLiteralNumber,
    OperandLiteralString,
    OperandSource,
    OperandExecutionModel,
    OperandAddressing,
    OperandMemory,
    OperandExecutionMode,
    OperandStorage,
    OperandDimensionality,
    OperandSamplerAddressingMode,
    OperandSamplerFilterMode,
    OperandSamplerImageFormat,
    OperandImageChannelOrder,
    OperandImageChannelDataType,
    OperandImageOperands,
    OperandFPFastMath,
    OperandFPRoundingMode,
    OperandLinkageType,
    OperandAccessQualifier,
    OperandFuncParamAttr,
    OperandDecoration,
    OperandBuiltIn,
    OperandSelect,
    OperandLoop,
    OperandFunction,
    OperandMemorySemantics,
    OperandMemoryAccess,
    OperandScope,
	OperandGroupOperation,
    OperandKernelEnqueueFlags,
    OperandKernelProfilingInfo,
    OperandCapability,

    OperandOpcode,

    OperandCount
};

// Any specific enum can have a set of capabilities that allow it:
typedef std::vector<Capability> EnumCaps;

// Parameterize a set of operands with their OperandClass(es) and descriptions.
class OperandParameters {
public:
    OperandParameters() { }
    void push(OperandClass oc, const char* d)
    {
        opClass.push_back(oc);
        desc.push_back(d);
    }
    OperandClass getClass(int op) const { return opClass[op]; }
    const char* getDesc(int op) const { return desc[op]; }
    int getNum() const { return (int)opClass.size(); }

protected:
    std::vector<OperandClass> opClass;
    std::vector<const char*> desc;
};

// Parameterize an enumerant
class EnumParameters {
public:
    EnumParameters() : desc(0) { }
    EnumCaps caps;
    const char* desc;
};

// Parameterize a set of enumerants that form an enum
class EnumDefinition : public EnumParameters {
public:
    EnumDefinition() : 
        ceiling(0), bitmask(false), getName(0), enumParams(0), operandParams(0) { }
    void set(int ceil, const char* (*name)(int), EnumParameters* ep, bool mask = false)
    {
        ceiling = ceil;
        getName = name;
        bitmask = mask;
        enumParams = ep;
    }
    void setOperands(OperandParameters* op) { operandParams = op; }
    int ceiling;   // ceiling of enumerants
    bool bitmask;  // true if these enumerants combine into a bitmask
    const char* (*getName)(int);      // a function that returns the name for each enumerant value (or shift)
    EnumParameters* enumParams;       // parameters for each individual enumerant
    OperandParameters* operandParams; // sets of operands
};

// Parameterize an instruction's logical format, including its known set of operands,
// per OperandParameters above.
class InstructionParameters {
public:
    InstructionParameters() :
        opDesc("TBD"),
        opClass(OpClassMissing),
        typePresent(true),         // most normal, only exceptions have to be spelled out
        resultPresent(true)        // most normal, only exceptions have to be spelled out
    { }

    void setResultAndType(bool r, bool t)
    {
        resultPresent = r;
        typePresent = t;
    }

    bool hasResult() const { return resultPresent != 0; }
    bool hasType()   const { return typePresent != 0; }

    const char* opDesc;
    EnumCaps capabilities;
    OpcodeClass opClass;
    OperandParameters operands;

protected:
    int typePresent   : 1;
    int resultPresent : 1;
};

const int OpcodeCeiling = 305;

// The set of objects that hold all the instruction/operand
// parameterization information.
extern InstructionParameters InstructionDesc[];

// These hold definitions of the enumerants used for operands
extern EnumDefinition OperandClassParams[];

const char* GetOperandDesc(OperandClass operand);
void PrintImmediateRow(int imm, const char* name, const EnumParameters* enumParams, bool caps, bool hex = false);
const char* AccessQualifierString(int attr);

void PrintOperands(const OperandParameters& operands, int reservedOperands);

};  // end namespace spv
