/*===================== begin_copyright_notice ==================================

Copyright (c) 2017 Intel Corporation

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


======================= end_copyright_notice ==================================*/

#ifndef VISA_KERNEL_H
#define VISA_KERNEL_H
#include "VISABuilderAPIDefinition.h"
#include "DebugInfo.h"
#include "visa_wa.h"


#define vISA_NUMBER_OF_OPNDS_IN_POOL 47

//forward declaration
namespace vISA
{
class G4_Kernel;
class IR_Builder;
class DebugInfoFormat;
class BinaryEncoding;
class BinaryEncodingBase;
}
// Class hierarchy is as follows:
// VISAKernel -> Abstract class that declares virtual functions to build a kernel object
// VISAFunction : VISAKernel -> Abstract class that declares function specific APIs
// VISAKernelImpl : VISAFunction -> Implementation for all APIs in VISAKernel and VISAFunction
class VISAKernelImpl : public VISAFunction
{
public:
    VISAKernelImpl(CM_VISA_BUILDER_OPTION buildOption, Options *option) : m_mem(4096), m_options(option)
    {
        //CisaBinary* module = NULL;
        mBuildOption = buildOption;
        m_magic_number = COMMON_ISA_MAGIC_NUM;
        m_major_version = 0;
        m_minor_version = 0;
        m_var_info_count = 0;
        m_addr_info_count = 0;
        m_pred_info_count = 0;
        m_sampler_count = 0;
        m_surface_count = 0;
        m_input_count = 0;
        m_vme_count = 0;
        m_attribute_count = 0;
        m_label_count = 0;

        m_string_pool_size = 0;
        m_var_info_size = 0;
        m_adress_info_size = 0;
        m_predicate_info_size = 0;
        m_label_info_size = 0;
        m_input_info_size = 0;
        m_attribute_info_size = 0;
        m_instruction_size = 0;
        m_genx_binary_size = 0;
        m_kernel_data_size = 0;
        m_genx_binary_buffer = NULL;
        m_genx_debug_info_size = 0;
        m_genx_debug_info_buffer = NULL;
        m_bytes_written_cisa_buffer = 0;
        m_input_offset = 0;
        m_num_pred_vars = 0;
        m_surface_info_size = 0;
        m_sampler_info_size = 0;
        m_vme_info_size = 0;
        m_isKernel = false;

        memset(&m_cisa_kernel, 0, sizeof(kernel_format_t));
        m_forward_label_count = 0;
        m_jitInfo = NULL;
        errorMessage[0] = '\0';
        m_kernel = NULL;
        m_builder = NULL;
        m_globalMem = NULL;
        m_phyRegPool = NULL;
        m_kernelID = 0;
        m_inputSize = 0;
        m_opndCounter = 0;
        m_var_info_list.reserve(200);
        m_input_info_list.reserve(20);
        m_label_info_list.reserve(50);
        m_addr_info_list.reserve(20);
        // give it some default name in case AsmName is not set
        m_asmName = "test";

        varNameCount = COMMON_ISA_NUM_PREDEFINED_VAR_VER_3;
        addressNameCount = 0;
        predicateNameCount = COMMON_ISA_NUM_PREDEFINED_PRED;
        surfaceNameCount = COMMON_ISA_NUM_PREDEFINED_SURF_VER_3_1;
        samplerNameCount = 0;
        vmeNameCount = 0;
        isRelocTablePresent = false;
        mTargetAttributeSet = false;

        m_functionId = 0;
        m_vISAInstCount = -1;

        mIsFCCallableKernel = false;
        mIsFCCallerKernel = false;
        mIsFCComposableKernel = false;
    }

    void* alloc(size_t sz) { return m_mem.alloc(sz); }

    virtual ~VISAKernelImpl();

    void *operator new(size_t sz, vISA::Mem_Manager& m){ return m.alloc(sz); };
    int InitializeKernel(const char *kernel_name);
    int CISABuildPreDefinedDecls();
    void setVersion(unsigned char major_ver, unsigned char minor_ver){
        m_major_version = major_ver;
        m_minor_version = minor_ver;
    }

    void setPWaTable(PVISA_WA_TABLE pWaTable){
        m_pWaTable = pWaTable;
    }

    void finalizeKernel();
    unsigned long writeInToCisaBinaryBuffer(const void * value, int size);
    unsigned long getBytesWritten() { return m_bytes_written_cisa_buffer; }

    void setName(const char* n);
    const char* getName() const { return m_name.c_str(); }
    string_pool_entry** new_string_pool();
    unsigned short get_hash_key(const char* str);
    bool string_pool_lookup_and_insert_branch_targets(char *str,
        Common_ISA_Var_Class type,
        VISA_Type data_type);
    void CISAPostFileParse();
    const kernel_format_t* getKernelFormat() const { return &m_cisa_kernel; }
    /***************** START HELPER FUNCTIONS ********************/
    int CreateStateInstUse(VISA_StateOpndHandle *&cisa_opnd, unsigned int index);
    int CreateStateInstUseFastPath(VISA_StateOpndHandle *&cisa_opnd, CISA_GEN_VAR *decl);
    Common_ISA_Input_Class GetInputClass(Common_ISA_Var_Class var_class);

    void addVarInfoToList(CISA_GEN_VAR * t);

    void addAddrToList(CISA_GEN_VAR * addr);

    void addPredToList(CISA_GEN_VAR * pred);

    void addSampler(CISA_GEN_VAR * state);

    void addVme(CISA_GEN_VAR * state);

    void addSurface(CISA_GEN_VAR * state);

    void addAttribute(const char *input_name, attribute_info_t *attr_temp);

    int addLabel(label_info_t * lbl, char * label_name);

    uint32_t addStringPool(std::string strng);

    void addInstructionToEnd(CisaFramework::CisaInst * inst);
    int addFunctionDirective(char * func_name);

    VISA_LabelOpnd * getLabelOperandFromFunctionName(std::string name);
    unsigned int getLabelIdFromFunctionName(std::string name);

    void setGenxBinaryBuffer(char * buffer, unsigned long size);
    void setGenxDebugInfoBuffer(char * buffer, unsigned long size);
    VISA_opnd* CreateOtherOpndHelper(int num_pred_desc_operands, int num_operands, VISA_INST_Desc *inst_desc, unsigned int value, bool hasSubOpcode = false, uint8_t subOpcode = 0);
    VISA_opnd* CreateOtherOpnd(unsigned int value, VISA_Type opndType);

    vISA::G4_Operand* CommonISABuildPreDefinedSrc(int index, uint16_t vStride, uint16_t width,
        uint16_t hStride, uint8_t rowOffset, uint8_t colOffset, VISA_Modifier modifier);
    /***************** END HELPER FUNCTIONS **********************/
    std::list<CisaFramework::CisaInst *>::iterator getInstructionListBegin() { return m_instruction_list.begin(); }
    std::list<CisaFramework::CisaInst *>::iterator getInstructionListEnd() { return m_instruction_list.end(); }

    unsigned long getGenxBinarySize() { return m_genx_binary_size; }

    char * getGenxBinaryBuffer() { return m_genx_binary_buffer; }

    unsigned long getCisaBinarySize() { return m_cisa_binary_size; }

    char * getCisaBinaryBuffer() { return m_cisa_binary_buffer; }

    unsigned long getInputOffset() { return m_input_offset; }
    void setNumPredVars(unsigned int val) { m_num_pred_vars = val; }
    unsigned int getNumPredVars() { return m_num_pred_vars; }

    unsigned long getKernelDataSize() { return m_kernel_data_size; }
    void addPendingLabels(VISA_opnd * opnd) { m_pending_labels.push_back(opnd); }
    void addPendingLabelNames(std::string name) { m_pending_label_names.push_back(name); }
    void setIsKernel(bool isKernel) { m_isKernel = isKernel; };
    bool getIsKernel() const { return m_isKernel; }
    void setReturnType(VISA_Type type) { m_return_type = type; }
    VISA_Type getReturnType(){ return m_return_type; }
    unsigned long getCodeOffset(){ return m_cisa_kernel.entry; }

    unsigned int getIndexFromName(const std::string &name);
    CISA_GEN_VAR * getDeclFromName(const std::string &name);
    bool setNameIndexMap(const std::string &name, CISA_GEN_VAR *, bool unique = true);

    unsigned int getIndexFromLabelName(const std::string &label_name);
    VISA_LabelOpnd * getLabelOpndFromLabelName(const std::string &label_name);
    bool setLabelNameIndexMap(const std::string &label_name, VISA_LabelOpnd * lbl);
    int patchLastInst(VISA_LabelOpnd *label);
    vISA::G4_Kernel* getKernel() { return m_kernel; }
    vISA::IR_Builder* getIRBuilder() { return m_builder; }

    int getVISAOffset() const;

    /***************** START EXPOSED APIS *************************/
    CM_BUILDER_API int CreateVISAGenVar(VISA_GenVar *& decl, const char *varName, int numberElements, VISA_Type dataType,
        VISA_Align varAlign, VISA_GenVar *parentDecl = NULL, int aliasOffset = 0);

    CM_BUILDER_API int CreateVISAGenVar(VISA_GenVar *& decl, const char *varName, int numberElements, VISA_Type dataType,
        VISA_Align varAlign, VISA_FileVar *parentDecl, int aliasOffset);

    CM_BUILDER_API int CreateVISAAddrVar(VISA_AddrVar *& decl, const char *varName, unsigned int numberElements);

    CM_BUILDER_API int AddKernelAttribute(const char* name, int size, const void *value);

    CM_BUILDER_API int CreateVISAPredVar(VISA_PredVar *& decl, const char* varName, unsigned short numberElements);

    CM_BUILDER_API int AddAttributeToVar(VISA_PredVar *decl, const char* varName, unsigned int size, void *val);

    CM_BUILDER_API int AddAttributeToVar(VISA_SurfaceVar *decl, const char* varName, unsigned int size, void *val);

    CM_BUILDER_API int AddAttributeToVar(VISA_GenVar *decl, const char* name, unsigned int size, void *val);

    CM_BUILDER_API int AddAttributeToVar(VISA_AddrVar *decl, const char* name, unsigned int size, void *val);

    CM_BUILDER_API int CreateVISASamplerVar(VISA_SamplerVar *&decl, const char* name, unsigned int numberElements);

    CM_BUILDER_API int CreateVISASurfaceVar(VISA_SurfaceVar *&decl, const char* name, unsigned int numberElements);

    CM_BUILDER_API int CreateVISALabelVar(VISA_LabelOpnd *& opnd, const char* name, VISA_Label_Kind kind);

    CM_BUILDER_API int CreateVISAImplicitInputVar(VISA_GenVar *decl, unsigned short offset, unsigned short size, unsigned short kind);

    CM_BUILDER_API int CreateVISAInputVar(VISA_GenVar *decl, unsigned short offset, unsigned short size);

    CM_BUILDER_API int CreateVISAInputVar(VISA_SamplerVar *decl, unsigned short offset, unsigned short size);

    CM_BUILDER_API int CreateVISAInputVar(VISA_SurfaceVar *decl, unsigned short offset, unsigned short size);

    CM_BUILDER_API int CreateVISAInputVar(VISA_VMEVar *decl, unsigned short offset, unsigned short size);

    CM_BUILDER_API int CreateVISAAddressSrcOperand(VISA_VectorOpnd *&opnd, VISA_AddrVar *decl, unsigned int offset, unsigned int width);

    CM_BUILDER_API int CreateVISAAddressDstOperand(VISA_VectorOpnd *&opnd, VISA_AddrVar *decl, unsigned int offset);

    CM_BUILDER_API int CreateVISAAddressOfOperand(VISA_VectorOpnd *&cisa_opnd, VISA_GenVar *decl, unsigned int offset);

    CM_BUILDER_API int CreateVISAAddressOfOperand(VISA_VectorOpnd *&cisa_opnd, VISA_SurfaceVar *decl, unsigned int offset);

    CM_BUILDER_API int CreateVISAIndirectSrcOperand(VISA_VectorOpnd *& opnd, VISA_AddrVar *cisa_decl, VISA_Modifier mod, unsigned int addrOffset, short immediateOffset,
        unsigned short verticalStride, unsigned short width, unsigned short horizontalStride, VISA_Type type);

    CM_BUILDER_API int CreateVISAIndirectDstOperand(VISA_VectorOpnd *& opnd, VISA_AddrVar *decl, unsigned int addrOffset, short immediateOffset,
        unsigned short horizontalStride, VISA_Type type);

    CM_BUILDER_API int CreateVISAIndirectOperandVxH(VISA_VectorOpnd *& cisa_opnd, VISA_AddrVar *decl, unsigned int addrOffset, short immediateOffset, VISA_Type type);

    CM_BUILDER_API int CreateVISAPredicateOperand(VISA_PredOpnd *& opnd, VISA_PredVar *decl, VISA_PREDICATE_STATE state, VISA_PREDICATE_CONTROL cntrl);

    CM_BUILDER_API int CreateVISASrcOperand(VISA_VectorOpnd *& opnd, VISA_GenVar *cisa_decl, VISA_Modifier mod, unsigned short vStride, unsigned short width, unsigned short hStride,
        unsigned char rowOffset, unsigned char colOffset);

    CM_BUILDER_API int CreateVISADstOperand(VISA_VectorOpnd *&opnd, VISA_GenVar *decl, unsigned short hStride, unsigned char rowOffset, unsigned char colOffset);

    CM_BUILDER_API int CreateVISAImmediate(VISA_VectorOpnd *&opnd, const void *val, VISA_Type type);

    CM_BUILDER_API int CreateRelocVISAImmediate(VISA_VectorOpnd *&opnd, const void *val, VISA_Type type, SuperRelocEntry& reloc);

    CM_BUILDER_API int CreateVISAStateOperand(VISA_VectorOpnd *&opnd, VISA_SurfaceVar *decl, unsigned char offset, bool useAsDst);

    CM_BUILDER_API int CreateVISAStateOperand(VISA_VectorOpnd *&opnd, VISA_SurfaceVar *decl, uint8_t size, unsigned char offset, bool useAsDst);

    CM_BUILDER_API int CreateVISAStateOperand(VISA_VectorOpnd *&opnd, VISA_SamplerVar *decl, unsigned char offset, bool useAsDst);

    CM_BUILDER_API int CreateVISAStateOperand(VISA_VectorOpnd *&opnd, VISA_SamplerVar *decl, uint8_t size, unsigned char offset, bool useAsDst);

    CM_BUILDER_API int CreateVISAStateOperand(VISA_VectorOpnd *&opnd, VISA_VMEVar *decl, unsigned char offset, bool useAsDst);


    CM_BUILDER_API int CreateVISAStateOperandHandle(VISA_StateOpndHandle *&opnd, VISA_SurfaceVar *decl);

    CM_BUILDER_API int CreateVISAStateOperandHandle(VISA_StateOpndHandle *&opnd, VISA_SamplerVar *decl);

    CM_BUILDER_API int CreateVISAStateOperandHandle(VISA_StateOpndHandle *&opnd, VISA_VMEVar *decl);

    CM_BUILDER_API int CreateVISARawOperand(VISA_RawOpnd *& opnd, VISA_GenVar *decl, unsigned short offset);

    CM_BUILDER_API int CreateVISANullRawOperand(VISA_RawOpnd *& opnd);

    CM_BUILDER_API int GetPredefinedVar(VISA_GenVar *&predDcl, PreDefined_Vars varName);

    CM_BUILDER_API int GetPredefinedSurface(VISA_SurfaceVar *&surfDcl, PreDefined_Surface surfaceName);

    CM_BUILDER_API int GetBindlessSampler(VISA_SamplerVar *&samplerDcl);

    CM_BUILDER_API int SetFunctionInputSize(unsigned int size);

    CM_BUILDER_API int SetFunctionReturnSize(unsigned int size);

    /********** APPEND INSTRUCTION APIS START ******************/
    CM_BUILDER_API int AppendVISAArithmeticInst(ISA_Opcode opcode, VISA_PredOpnd *pred, bool satMode, Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize, VISA_VectorOpnd *tmpDst, VISA_VectorOpnd *src0);

    CM_BUILDER_API int AppendVISAArithmeticInst(ISA_Opcode opcode, VISA_PredOpnd *pred, bool satMode, Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize, VISA_VectorOpnd *tmpDst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1);

    CM_BUILDER_API int AppendVISAArithmeticInst(ISA_Opcode opcode, VISA_PredOpnd *pred, bool satMode, Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize, VISA_VectorOpnd *tmpDst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1, VISA_VectorOpnd *src2);

    CM_BUILDER_API int AppendVISAArithmeticInst(ISA_Opcode opcode, VISA_PredOpnd *pred, Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize, VISA_VectorOpnd *dst1, VISA_VectorOpnd *carry_borrow, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1);

    CM_BUILDER_API int AppendVISALogicOrShiftInst(ISA_Opcode opcode, VISA_PredOpnd *pred, bool satMode, Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize, VISA_VectorOpnd *dst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1, VISA_VectorOpnd *src2 = NULL,
        VISA_VectorOpnd *src3 = NULL);

    CM_BUILDER_API int AppendVISALogicOrShiftInst(ISA_Opcode opcode, Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize, VISA_PredVar *dst, VISA_PredVar *src0, VISA_PredVar *src1);

    CM_BUILDER_API int AppendVISAAddrAddInst(Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize, VISA_VectorOpnd *dst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1);

    CM_BUILDER_API int AppendVISADataMovementInst(ISA_Opcode opcode, VISA_PredOpnd *pred, bool satMod, Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize, VISA_VectorOpnd *dst, VISA_VectorOpnd *src0);

    CM_BUILDER_API int AppendVISADataMovementInst(ISA_Opcode opcode, VISA_PredOpnd *pred, bool satMod, Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize, VISA_VectorOpnd *dst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1);

    CM_BUILDER_API int AppendVISAPredicateMove(VISA_VectorOpnd *dst, VISA_PredVar *src0);

    CM_BUILDER_API int AppendVISASetP(Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize, VISA_PredVar *dst, VISA_VectorOpnd *src0);

    CM_BUILDER_API int AppendVISAMinMaxInst(CISA_MIN_MAX_SUB_OPCODE subOpcode, bool satMod, Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize, VISA_VectorOpnd *dst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1);

    CM_BUILDER_API int AppendVISAComparisonInst(Common_ISA_Cond_Mod sub_op, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize, VISA_PredVar *dst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1);

    CM_BUILDER_API int AppendVISAComparisonInst(Common_ISA_Cond_Mod sub_op, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize, VISA_VectorOpnd *dst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1);

    CM_BUILDER_API int AppendVISACFSIMDInst(ISA_Opcode opcode, VISA_PredOpnd *pred, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize, VISA_LabelOpnd *label = NULL);

    CM_BUILDER_API int AppendVISACFLabelInst(VISA_LabelOpnd *label);

    CM_BUILDER_API int AppendVISACFJmpInst(VISA_PredOpnd *pred, VISA_LabelOpnd *label);

    CM_BUILDER_API int AppendVISACFCallInst(VISA_PredOpnd *pred, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize, VISA_LabelOpnd *label);

    CM_BUILDER_API int AppendVISACFRetInst(VISA_PredOpnd *pred, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize);

    CM_BUILDER_API int AppendVISACFFunctionCallInst(VISA_PredOpnd *pred, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize, unsigned short functionID, unsigned char argSize, unsigned char returnSize);

    CM_BUILDER_API int AppendVISACFFunctionRetInst(VISA_PredOpnd *pred, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize);

    CM_BUILDER_API int AppendVISACFSwitchJMPInst(VISA_VectorOpnd *index, unsigned char labelCount, VISA_LabelOpnd **labels);

    CM_BUILDER_API int AppendVISASurfAccessDwordAtomicInst(
        CMAtomicOperations subOp, bool is16Bit, Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize, VISA_StateOpndHandle *surface,
        VISA_VectorOpnd *globalOffset, VISA_RawOpnd *elementOffset,
        VISA_RawOpnd *src0, VISA_RawOpnd *src1, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISASurfAccessDwordAtomicInst(
        VISA_PredOpnd *pred, CMAtomicOperations subOpc, bool is16Bit,
        Common_VISA_EMask_Ctrl eMask, Common_ISA_Exec_Size execSize,
        VISA_StateOpndHandle *surface, VISA_RawOpnd *offsets,
        VISA_RawOpnd *src0, VISA_RawOpnd *src1, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISASurfAccessGatherScatterInst(ISA_Opcode opcode, Common_VISA_EMask_Ctrl emask, GATHER_SCATTER_ELEMENT_SIZE elementSize,
        Common_ISA_Exec_Size executionSize, VISA_StateOpndHandle *surface, VISA_VectorOpnd *globalOffset, VISA_RawOpnd *elementOffset, VISA_RawOpnd *srcDst);

    CM_BUILDER_API int AppendVISASurfAccessGather4Scatter4Inst(ISA_Opcode opcode, VISAChannelMask chMask, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize,
        VISA_StateOpndHandle *surface, VISA_VectorOpnd *globalOffset, VISA_RawOpnd *elementOffset, VISA_RawOpnd *srcDst);

    CM_BUILDER_API int AppendVISASurfAccessGather4Scatter4TypedInst(ISA_Opcode opcode,
        VISA_PredOpnd *pred,
        VISAChannelMask chMask,
        Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize,
        VISA_StateOpndHandle *surface,
        VISA_RawOpnd *uOffset,
        VISA_RawOpnd *vOffset,
        VISA_RawOpnd *rOffset,
        VISA_RawOpnd *lod,
        VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISASurfAccessGather4Scatter4ScaledInst(ISA_Opcode             opcode,
        VISA_PredOpnd          *pred,
        Common_VISA_EMask_Ctrl eMask,
        Common_ISA_Exec_Size   execSize,
        VISAChannelMask        chMask,
        VISA_StateOpndHandle   *surface,
        VISA_VectorOpnd        *globalOffset,
        VISA_RawOpnd           *offsets,
        VISA_RawOpnd           *dstSrc);

    CM_BUILDER_API int AppendVISASurfAccessStrBufLdStInst(ISA_Opcode             opcode,
        VISA_PredOpnd          *pred,
        Common_VISA_EMask_Ctrl eMask,
        Common_ISA_Exec_Size   execSize,
        VISAChannelMask        chMask,
        VISA_StateOpndHandle   *surface,
        VISA_RawOpnd           *uOffsets,
        VISA_RawOpnd           *vOffsets,
        VISA_RawOpnd           *dstSrc);

    CM_BUILDER_API int AppendVISASurfAccessScatterScaledInst(ISA_Opcode                opcode,
        VISA_PredOpnd             *pred,
        Common_VISA_EMask_Ctrl    eMask,
        Common_ISA_Exec_Size      execSize,
        Common_ISA_SVM_Block_Num  numBlocks,
        VISA_StateOpndHandle      *surface,
        VISA_VectorOpnd           *globalOffset,
        VISA_RawOpnd              *offsets,
        VISA_RawOpnd              *dstSrc);

    CM_BUILDER_API int AppendVISASurfAccessMediaLoadStoreInst(ISA_Opcode opcode, MEDIA_LD_mod modifier, VISA_StateOpndHandle *surface, unsigned char blockWidth,
        unsigned char blockHeight, VISA_VectorOpnd *xOffset, VISA_VectorOpnd *yOffset, VISA_RawOpnd *srcDst,
        CISA_PLANE_ID plane = CISA_PLANE_Y);

    CM_BUILDER_API int AppendVISASurfAccessOwordLoadStoreInst(ISA_Opcode opcode, Common_VISA_EMask_Ctrl emask, VISA_StateOpndHandle *surface, Common_ISA_Oword_Num size, VISA_VectorOpnd *offset, VISA_RawOpnd *srcDst);


    CM_BUILDER_API int AppendVISASvmBlockStoreInst(Common_ISA_Oword_Num size, bool unaligned, VISA_VectorOpnd* address, VISA_RawOpnd *srcDst);

    CM_BUILDER_API int AppendVISASvmBlockLoadInst(Common_ISA_Oword_Num size, bool unaligned, VISA_VectorOpnd* address, VISA_RawOpnd *srcDst);

    CM_BUILDER_API int AppendVISASvmScatterInst(VISA_PredOpnd *pred,
        Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize,
        Common_ISA_SVM_Block_Type blockType, Common_ISA_SVM_Block_Num numBlocks,
        VISA_RawOpnd* address, VISA_RawOpnd *srcDst);

    CM_BUILDER_API int AppendVISASvmGatherInst(VISA_PredOpnd *pred,
        Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize,
        Common_ISA_SVM_Block_Type blockType, Common_ISA_SVM_Block_Num numBlocks,
        VISA_RawOpnd* address, VISA_RawOpnd *srcDst);

    CM_BUILDER_API int
    AppendVISASvmAtomicInst(VISA_PredOpnd *pred, Common_VISA_EMask_Ctrl emask,
                            Common_ISA_Exec_Size executionSize,
                            CMAtomicOperations op, bool is16Bit,
                            VISA_RawOpnd *addresses, VISA_RawOpnd *src0,
                            VISA_RawOpnd *src1, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISASvmGather4ScaledInst(VISA_PredOpnd             *pred,
        Common_VISA_EMask_Ctrl    eMask,
        Common_ISA_Exec_Size      execSize,
        VISAChannelMask           channelMask,
        VISA_VectorOpnd           *address,
        VISA_RawOpnd              *offsets,
        VISA_RawOpnd              *dst);

    CM_BUILDER_API int AppendVISASvmScatter4ScaledInst(VISA_PredOpnd            *pred,
        Common_VISA_EMask_Ctrl   eMask,
        Common_ISA_Exec_Size     execSize,
        VISAChannelMask          channelMask,
        VISA_VectorOpnd          *address,
        VISA_RawOpnd             *offsets,
        VISA_RawOpnd             *src);

    CM_BUILDER_API int AppendVISASurfAccessTransposeLoadInst(VISA_StateOpndHandle *surface, unsigned char blockWidth, unsigned char blockHeight,
        VISA_VectorOpnd *xOffset, VISA_VectorOpnd *yOffset, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISASILoad(VISA_StateOpndHandle *surface, VISAChannelMask channel, bool isSIMD16,
        VISA_RawOpnd *uOffset, VISA_RawOpnd *vOffset, VISA_RawOpnd *rOffset, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISASISample(Common_VISA_EMask_Ctrl emask, VISA_StateOpndHandle *surface, VISA_StateOpndHandle *sampler, VISAChannelMask channel, bool isSIMD16,
        VISA_RawOpnd *uOffset, VISA_RawOpnd *vOffset, VISA_RawOpnd *rOffset, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISASISampleUnorm(VISA_StateOpndHandle *surface, VISA_StateOpndHandle *sampler, VISAChannelMask channel,
        VISA_VectorOpnd *uOffset, VISA_VectorOpnd *vOffset, VISA_VectorOpnd *deltaU, VISA_VectorOpnd *deltaV, VISA_RawOpnd *dst, CHANNEL_OUTPUT_FORMAT out);

    CM_BUILDER_API int AppendVISASyncInst(ISA_Opcode opcode, unsigned char mask = 0);
    CM_BUILDER_API int AppendVISAWaitInst(VISA_VectorOpnd* mask);

    CM_BUILDER_API int AppendVISAPredBarrierInst(VISA_VectorOpnd *mask, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAMiscFileInst(char *fileName);

    CM_BUILDER_API int AppendVISAMiscLOC(unsigned int lineNumber);

    CM_BUILDER_API int AppendVISAMiscRawSend(VISA_PredOpnd *pred, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize, unsigned char modifiers,
        unsigned int exMsgDesc, unsigned char srcSize, unsigned char dstSize, VISA_VectorOpnd *desc,
        VISA_RawOpnd *src, VISA_RawOpnd *dst);
    CM_BUILDER_API int AppendVISAMiscRawSends(VISA_PredOpnd *pred, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize, unsigned char modifiers,
        unsigned ffid, VISA_VectorOpnd *exMsgDesc, unsigned char src0Size, unsigned char src1Size, unsigned char dstSize, VISA_VectorOpnd *desc,
        VISA_RawOpnd *src0, VISA_RawOpnd *src1, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAMiscVME_FBR(VISA_StateOpndHandle *surface, VISA_RawOpnd *UNIInput, VISA_RawOpnd *FBRInput, VISA_VectorOpnd* FBRMbMode, VISA_VectorOpnd *FBRSubMbShape,
        VISA_VectorOpnd *FBRSubPredMode, VISA_RawOpnd *output);

    CM_BUILDER_API int AppendVISAMiscVME_IME(VISA_StateOpndHandle *surface, unsigned char streamMode, unsigned char searchControlMode, VISA_RawOpnd *UNIInput,
        VISA_RawOpnd *IMEInput, VISA_RawOpnd *ref0, VISA_RawOpnd *ref1, VISA_RawOpnd *costCenter, VISA_RawOpnd *output);

    CM_BUILDER_API int AppendVISAMiscVME_SIC(VISA_StateOpndHandle *surface, VISA_RawOpnd *UNIInput, VISA_RawOpnd *SICInput, VISA_RawOpnd *output);

    CM_BUILDER_API int AppendVISAMiscVME_IDM(VISA_StateOpndHandle *surface, VISA_RawOpnd *UNIInput, VISA_RawOpnd *IDMInput, VISA_RawOpnd *output);

    CM_BUILDER_API int AppendVISAMEAVS(VISA_StateOpndHandle *surface, VISA_StateOpndHandle *sampler, VISAChannelMask channel, VISA_VectorOpnd *uOffset,
        VISA_VectorOpnd *vOffset, VISA_VectorOpnd *deltaU, VISA_VectorOpnd *deltaV, VISA_VectorOpnd *u2d,
        VISA_VectorOpnd *v2d, VISA_VectorOpnd *groupID, VISA_VectorOpnd *verticalBlockNumber, OutputFormatControl cntrl,
        AVSExecMode execMode, VISA_VectorOpnd *iefBypass, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAVABooleanCentroid(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, VISA_VectorOpnd *vSize, VISA_VectorOpnd *hSize, VISA_RawOpnd *dst);
    CM_BUILDER_API int AppendVISAVACentroid(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, VISA_VectorOpnd *vSize, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAVAConvolve(VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, CONVExecMode execMode, bool isBigKernel, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAVAErodeDilate(EDMode subOp, VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, EDExecMode execMode, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAVAMinMax(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, VISA_VectorOpnd *mmMode, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAVAMinMaxFilter(VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, OutputFormatControl cntrl, MMFExecMode execMode, VISA_VectorOpnd *mmfMode, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAVACorrelationSearch(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, VISA_VectorOpnd *vOrigin, VISA_VectorOpnd *hOrigin,
        VISA_VectorOpnd *xDirectionSize, VISA_VectorOpnd *yDirectionSize,
        VISA_VectorOpnd *xDirectionSearchSize, VISA_VectorOpnd *yDirectionSearchSize,
        VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAVAFloodFill(bool is8Connect, VISA_RawOpnd *pixelMaskHDirection,
        VISA_VectorOpnd *pixelMaskVDirectionLeft, VISA_VectorOpnd *pixelMaskVDirectionRight,
        VISA_VectorOpnd *loopCount, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAVALBPCorrelation(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, VISA_VectorOpnd *disparity,
        VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAVALBPCreation(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, LBPCreationMode mode,
        VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAVAConvolve1D(VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, CONVExecMode mode, Convovle1DDirection direction, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAVAConvolve1Pixel(VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, CONV1PixelExecMode mode, VISA_RawOpnd *offsets, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISAVAHDCConvolve(VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, HDCReturnFormat returnFormat, CONVHDCRegionSize regionSize,
        VISA_StateOpndHandle *dstSurface, VISA_VectorOpnd *xOffset, VISA_VectorOpnd *yOffset);

    CM_BUILDER_API int AppendVISAVAHDCErodeDilate(EDMode subOp, VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, VISA_StateOpndHandle *dstSurface, VISA_VectorOpnd *xOffset,
        VISA_VectorOpnd *yOffset);

    CM_BUILDER_API int AppendVISAVAHDCMinMaxFilter(VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, HDCReturnFormat returnFormat, MMFEnableMode mmfMode,
        VISA_StateOpndHandle *dstSurface, VISA_VectorOpnd *xOffset, VISA_VectorOpnd *yOffset);

    CM_BUILDER_API int AppendVISAVAHDCLBPCorrelation(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, VISA_VectorOpnd *disparity,
        VISA_StateOpndHandle *dstSurface, VISA_VectorOpnd *xOffset, VISA_VectorOpnd *yOffset);

    CM_BUILDER_API int AppendVISAVAHDCLBPCreation(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, LBPCreationMode mode,
        VISA_StateOpndHandle *dstSurface, VISA_VectorOpnd *xOffset, VISA_VectorOpnd *yOffset);

    CM_BUILDER_API int AppendVISAVAHDCConvolve1D(VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, HDCReturnFormat returnFormat, Convovle1DDirection direction,
        VISA_StateOpndHandle *dstSurface, VISA_VectorOpnd *xOffset, VISA_VectorOpnd *yOffset);

    CM_BUILDER_API int AppendVISAVAHDCConvolve1Pixel(VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
        VISA_VectorOpnd *vOffset, HDCReturnFormat returnFormat, VISA_RawOpnd *offsets,
        VISA_StateOpndHandle *dstSurface, VISA_VectorOpnd *xOffset, VISA_VectorOpnd *yOffset);

    CM_BUILDER_API int AppendVISALifetime(VISAVarLifetime startOrEnd, VISA_VectorOpnd *varId);


    /********** APPEND INSTRUCTION APIS END   ******************/

    /********** APPEND 3D Instructions START ******************/

    CM_BUILDER_API int AppendVISA3dSampler(VISASampler3DSubOpCode subOpcode,
        bool pixelNullMask,
        bool cpsEnable,
        bool uniformSampler,
        VISA_PredOpnd *pred,
        Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize,
        VISAChannelMask srcChannel,
        VISA_VectorOpnd *aoffimmi,
        VISA_StateOpndHandle *sampler,
        VISA_StateOpndHandle *surface,
        VISA_RawOpnd *dst,
        int numMsgSpecificOpnds,
        VISA_RawOpnd **opndArray);

    CM_BUILDER_API int AppendVISA3dLoad(VISASampler3DSubOpCode subOpcode,
        bool pixelNullMask,
        VISA_PredOpnd *pred,
        Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize,
        VISAChannelMask srcChannel,
        VISA_VectorOpnd *aoffimmi,
        VISA_StateOpndHandle *surface,
        VISA_RawOpnd *dst,
        int numMsgSpecificOpnds,
        VISA_RawOpnd ** opndArray);

    CM_BUILDER_API int AppendVISA3dGather4(VISASampler3DSubOpCode subOpcode,
        bool pixelNullMask,
        VISA_PredOpnd *pred,
        Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize,
        VISASourceSingleChannel srcChannel,
        VISA_VectorOpnd *aoffimmi,
        VISA_StateOpndHandle *sampler,
        VISA_StateOpndHandle *surface,
        VISA_RawOpnd *dst,
        int numMsgSpecificOpnds,
        VISA_RawOpnd ** opndArray);

    CM_BUILDER_API int AppendVISA3dInfo(VISASampler3DSubOpCode subOpcode, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize, VISAChannelMask srcChannel, VISA_StateOpndHandle *surface, VISA_RawOpnd *lod, VISA_RawOpnd *dst);

    CM_BUILDER_API int AppendVISA3dRTWrite(VISA_PredOpnd *pred, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize, VISA_VectorOpnd* renderTargetIndex, vISA_RT_CONTROLS cntrls,
        VISA_StateOpndHandle *surface, VISA_RawOpnd *r1HeaderOpnd, VISA_VectorOpnd *sampleIndex,
        uint8_t numMsgSpecificOpnds, VISA_RawOpnd **opndArray);

    CM_BUILDER_API int AppendVISA3dRTWriteCPS(VISA_PredOpnd *pred, Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize, VISA_VectorOpnd* renderTargetIndex, vISA_RT_CONTROLS cntrls,
        VISA_StateOpndHandle *surface, VISA_RawOpnd *r1HeaderOpnd, VISA_VectorOpnd *sampleIndex,
        VISA_VectorOpnd *cPSCounter, uint8_t numMsgSpecificOpnds, VISA_RawOpnd **opndArray);

    CM_BUILDER_API int AppendVISA3dURBWrite(VISA_PredOpnd *pred, Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize, unsigned char numberOutputParams,
        VISA_RawOpnd *channelMask, unsigned short globalOffset, VISA_RawOpnd *URBHandle,
        VISA_RawOpnd *perSLotOffset, VISA_RawOpnd *vertexData);

    CM_BUILDER_API int AppendVISA3dTypedAtomic(
        CMAtomicOperations subOp, bool is16Bit, VISA_PredOpnd *pred,
        Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size executionSize,
        VISA_StateOpndHandle *surface, VISA_RawOpnd *u, VISA_RawOpnd *v,
        VISA_RawOpnd *r, VISA_RawOpnd *lod, VISA_RawOpnd *src0,
        VISA_RawOpnd *src1, VISA_RawOpnd *dst);

    /********** APPEND 3D Instructions END ******************/

    /********** MISC APIs START *************************/
    CM_BUILDER_API int GetGenxBinary(void *&buffer, int &size);
    CM_BUILDER_API int GetJitInfo(FINALIZER_INFO *&jitInfo);
    CM_BUILDER_API int GetErrorMessage(const char *&errorMsg);
    CM_BUILDER_API virtual int GetGenxDebugInfo(void *&buffer, unsigned int &size, void*&, unsigned int&);
    CM_BUILDER_API int GetGenReloc(BasicRelocEntry*& relocs, unsigned int& numRelocs);
    CM_BUILDER_API int GetFreeGRFInfo(void*& buffer, unsigned int& size);

    CM_BUILDER_API int GetFunctionId(unsigned int& id);

    ///Gets declaration id GenVar
    CM_BUILDER_API int getDeclarationID(VISA_GenVar *decl);

    ///Gets declaration id VISA_AddrVar
    CM_BUILDER_API int getDeclarationID(VISA_AddrVar *decl);

    ///Gets declaration id VISA_PredVar
    CM_BUILDER_API int getDeclarationID(VISA_PredVar *decl);

    ///Gets declaration id VISA_SamplerVar
    CM_BUILDER_API int getDeclarationID(VISA_SamplerVar *decl);

    ///Gets declaration id VISA_SurfaceVar
    CM_BUILDER_API int getDeclarationID(VISA_SurfaceVar *decl);

    ///Gets declaration id VISA_VMEVar
    CM_BUILDER_API int getDeclarationID(VISA_VMEVar *decl);

    ///Gets declaration id VISA_LabelVar
    CM_BUILDER_API int getDeclarationID(VISA_LabelVar *decl);

    ///Gets declaration id VISA_FileVar
    CM_BUILDER_API int getDeclarationID(VISA_FileVar *decl);

    /********** MISC APIs END *************************/
    int CreateVISAPredicateSrcOperand(VISA_VectorOpnd *& opnd, VISA_PredVar *decl, unsigned int size);

    int CreateVISAPredicateDstOperand(VISA_VectorOpnd *& opnd, VISA_PredVar *decl, uint32_t size);

    int CreateVISAAddressOperand(VISA_VectorOpnd *&opnd, VISA_AddrVar *decl, unsigned int offset, unsigned int width, bool isDst);

    int CreateVISAPredicateOperandvISA(VISA_PredOpnd *& opnd, VISA_PredVar *decl, VISA_PREDICATE_STATE state, VISA_PREDICATE_CONTROL cntrl);

    int CreateGenNullRawOperand(VISA_RawOpnd *& opnd, bool isDst);

    //VME violates our vISA assumption that raw operand is grf aligned, so... adding this for now
    //if anyone actually uses vISA builder externally to call VME we can expose it.
    int CreateGenRawSrcOperand(VISA_RawOpnd *& cisa_opnd, uint8_t size);
    int CreateGenRawDstOperand(VISA_RawOpnd *& cisa_opnd);

    int CreateVISAIndirectGeneralOperand(VISA_VectorOpnd *& opnd, VISA_AddrVar *cisa_decl, VISA_Modifier mod, unsigned int addrOffset, unsigned short immediateOffset,
        unsigned short verticalStride, unsigned short width, unsigned short horizontalStride, VISA_Type type, bool isDst);

    int AppendVISA3dSamplerMsgGeneric(ISA_Opcode opcode,
        VISASampler3DSubOpCode subOpcode,
        bool pixelNullMask,
        bool cpsEnable,
        bool uniformSampler,
        VISA_PredOpnd *pred,
        Common_VISA_EMask_Ctrl emask,
        Common_ISA_Exec_Size executionSize,
        ChannelMask srcChannel,
        VISA_VectorOpnd *aoffimmi,
        VISA_StateOpndHandle *sampler,
        VISA_StateOpndHandle *surface,
        VISA_RawOpnd *dst,
        unsigned int numMsgSpecificOpnds,
        VISA_RawOpnd **opndArray);

    int AddAttributeToVarGeneric(CISA_GEN_VAR *decl, const char* varName, unsigned int size, void *val);

    int CreateStateVar(CISA_GEN_VAR *&decl, Common_ISA_Var_Class type, const char* name, unsigned int numberElements);

    int CreateVISAInputVar(CISA_GEN_VAR *decl, uint16_t offset, uint16_t size, uint8_t implicitKind);

    int CreateVISAAddressOfOperandGeneric(VISA_VectorOpnd *&cisa_opnd, CISA_GEN_VAR *decl, unsigned int offset);

    int CreateVISAStateOperand(VISA_VectorOpnd *& opnd, CISA_GEN_VAR *decl, Common_ISA_State_Opnd_Class opnd_class, uint8_t size, unsigned char offset, bool useAsDst);

    int CreateDummyLabelOperand(VISA_LabelOpnd *& opnd, char *name, VISA_Label_Kind kind);

    void setGenxBinaryBuffer(void *buffer, int size){ m_genx_binary_buffer = (char *)buffer; m_genx_binary_size = size; }
    void setJitInfo(FINALIZER_INFO* jitInfo){ m_jitInfo = jitInfo; }
    char * getErrorMsgPtr(){ return errorMessage; }

    std::string getAsmName() { return m_asmName; }

    int compileFastPath();

    unsigned int m_magic_number;
    unsigned char m_major_version;
    unsigned char m_minor_version;

    PVISA_WA_TABLE m_pWaTable;

    void* compilePostOptimize(unsigned int& binarySize);

    void addVarRelocEntry(unsigned int symIdx, unsigned int resIdx) { isRelocTablePresent = true; varRelocTable.push_back(std::make_pair(symIdx, resIdx)); }
    void addFuncRelocEntry(unsigned int symIdx, unsigned int resIdx) { isRelocTablePresent = true; funcRelocTable.push_back(std::make_pair(symIdx, resIdx)); }

    unsigned int getVarRelocSize() { return (uint32_t)varRelocTable.size(); }
    unsigned int getFuncRelocSize() { return (uint32_t)funcRelocTable.size(); }

    void getVarRelocEntry(unsigned int idx, unsigned int& symIdx, unsigned int& resIdx) { symIdx = varRelocTable[idx].first; resIdx = varRelocTable[idx].second; }
    void getFuncRelocEntry(unsigned int idx, unsigned int& symIdx, unsigned int& resIdx) { symIdx = funcRelocTable[idx].first; resIdx = funcRelocTable[idx].second; }

    bool getRelocTablePresent() { return isRelocTablePresent; }

    void setupRelocTable();

    void setInputSize(uint8_t size);
    void setReturnSize(unsigned int size);

    void addFileScopeVar(VISA_FileVar* filescopeVar, unsigned int index);

    bool getIsGenBothPath() {
        return (mBuildOption == CM_CISA_BUILDER_GEN ||
            mBuildOption == CM_CISA_BUILDER_BOTH);
    }

    // This member holds symbolic index of function when invoked via
    // API path. Builder client can use this id when invoking this
    // stack call function. For a kernel instance, this is not useful.
    unsigned int m_functionId;

    unsigned getvIsaInstCount() { return m_vISAInstCount; };


    bool isFCCallableKernel() { return mIsFCCallableKernel; }
    void setFCCallableKernel(bool value) { mIsFCCallableKernel = value; }

    bool isFCCallerKernel() { return mIsFCCallerKernel; }
    void setFCCallerKernel(bool value) { mIsFCCallerKernel = value; }

    bool isFCComposableKernel() { return mIsFCComposableKernel; }
    void setFCComposableKernel(bool value) { mIsFCComposableKernel = value; }

    unsigned int getGenVarCount()
    {
        return (uint32_t)m_var_info_list.size();
    }

    CISA_GEN_VAR* getGenVar(unsigned int index)
    {
        return m_var_info_list[index];
    }

    unsigned int getAddrVarCount()
    {
        return (uint32_t)m_addr_info_list.size();
    }

    CISA_GEN_VAR* getAddrVar(unsigned int index)
    {
        return m_addr_info_list[index];
    }

    unsigned int getPredVarCount()
    {
        return (uint32_t)m_pred_info_list.size();
    }

    CISA_GEN_VAR* getPredVar(unsigned int index)
    {
        auto it = m_pred_info_list.begin();
        std::advance(it, index);

        return (*it);
    }

    unsigned int getSamplerVarCount()
    {
        return (uint32_t)m_sampler_info_list.size();
    }

    CISA_GEN_VAR* getSamplerVar(unsigned int index)
    {
        auto it = m_sampler_info_list.begin();
        std::advance(it, index);

        return (*it);
    }

    unsigned int getSurfaceVarCount()
    {
        return (uint32_t)m_surface_info_list.size();
    }

    CISA_GEN_VAR* getSurfaceVar(unsigned int index)
    {
        auto it = m_surface_info_list.begin();
        std::advance(it, index);

        return (*it);
    }

    unsigned int getVmeVarCount()
    {
        return (uint32_t)m_vme_info_list.size();
    }

    CISA_GEN_VAR* getVmeVar(unsigned int index)
    {
        auto it = m_vme_info_list.begin();
        std::advance(it, index);

        return (*it);
    }

    Options * getOptions() { return m_options; }

    void computeAndEmitDebugInfo(std::list<VISAKernelImpl*>& functions);
    void computeAndEmitGenRelocs();
    void computeAllRelocs(unsigned int& numRelocs, BasicRelocEntry*& output);
    void emitAllRelocs(unsigned int numRelocs, BasicRelocEntry* relocs);

private:
    void setDefaultVariableName(Common_ISA_Var_Class Ty, const char *&varName);
    void dumpDebugFormatFile(std::vector<vISA::DebugInfoFormat>& debugSymbols, std::string filename);
    void patchLabels();
    int InitializeFastPath();
    int predefinedVarRegAssignment();
    int calculateTotalInputSize();
    int compileTillOptimize();
    void getHeightWidth(G4_Type type, unsigned int numberElements, unsigned short &dclWidth, unsigned short &dclHeight, int &totalByteSize);
    CisaFramework::CisaInst* AppendVISASvmGeneralScatterInst(VISA_PredOpnd* pred,
        Common_VISA_EMask_Ctrl emask, Common_ISA_Exec_Size execSize, unsigned char blockSize,
        unsigned char numBlocks, VISA_RawOpnd* address, VISA_RawOpnd *srcDst, bool isRead);

    CisaFramework::CisaInst *
        PackCisaInsnForSVMGather4Scatter4Scaled(unsigned subOpc,
        VISA_PredOpnd *pred,
        Common_VISA_EMask_Ctrl eMask,
        Common_ISA_Exec_Size executionSize,
        ChannelMask chMask,
        VISA_VectorOpnd *address,
        VISA_RawOpnd *offsets,
        VISA_RawOpnd *srcOrDst);

    VISA_opnd * getOpndFromPool();

    void AppendVISAInstCommon();

    void createBindlessSampler();

    kernel_format_t m_cisa_kernel;


    bool mTargetAttributeSet;
    unsigned int m_num_pred_vars;
    //size of various arrays in kernel header.
    //used for buffer size allocation.
    unsigned int m_string_pool_size; //done
    unsigned int m_var_info_size; //done
    unsigned int m_adress_info_size;
    unsigned int m_predicate_info_size; //done
    unsigned int m_label_info_size; //done
    unsigned int m_input_info_size; //done
    unsigned int m_attribute_info_size; //done
    unsigned int m_instruction_size; //done
    unsigned int m_surface_info_size;
    unsigned int m_sampler_info_size;
    unsigned int m_vme_info_size;

    unsigned long m_genx_binary_size;
    char * m_genx_binary_buffer;
    unsigned long m_genx_debug_info_size;
    char * m_genx_debug_info_buffer;
    FINALIZER_INFO* m_jitInfo;

    unsigned long m_cisa_binary_size;
    char * m_cisa_binary_buffer;

    unsigned long m_kernel_data_size;

    unsigned long m_bytes_written_cisa_buffer;

    unsigned long m_input_offset;

    string_pool_entry** m_branch_targets;
    std::vector<std::string> m_string_pool;
    CisaFramework::CisaInst * m_lastInst;
    bool m_isKernel;
    unsigned int m_resolvedIndex;
    VISA_Type m_return_type;

    vISA::Mem_Manager m_mem;
    std::string m_name;
    std::string m_asmName;
    std::string m_sanitizedName;

    std::list<CisaFramework::CisaInst *> m_instruction_list;

    unsigned int m_var_info_count;
    std::vector<CISA_GEN_VAR*> m_var_info_list;

    unsigned int m_addr_info_count;
    std::vector<CISA_GEN_VAR *> m_addr_info_list;

    unsigned int m_pred_info_count;
    std::vector<CISA_GEN_VAR *> m_pred_info_list;

    unsigned int m_forward_label_count;
    std::map<unsigned int, std::string> m_forward_label_pool;

    unsigned int m_sampler_count;
    std::vector<CISA_GEN_VAR*> m_sampler_info_list;

    unsigned int m_surface_count;
    std::vector<CISA_GEN_VAR*> m_surface_info_list;

    VISA_SamplerVar* m_bindlessSampler;

    std::map<unsigned int, unsigned int> m_declID_to_PredefinedSurfaceID_map;

    unsigned int m_vme_count;
    std::vector<CISA_GEN_VAR*> m_vme_info_list;

    unsigned int m_input_count;
    std::vector<input_info_t *> m_input_info_list;
    //std::map<unsigned int, unsigned int> m_declID_to_inputID_map;

    unsigned int m_attribute_count;
    std::list<attribute_info_t *> m_attribute_info_list;

    unsigned int m_label_count;
    std::vector<label_info_t *> m_label_info_list;

    //list of cisa operands representing labels that need to be resolved
    std::list<VISA_opnd *> m_pending_labels;
    std::list<std::string> m_pending_label_names;

    //maps name, must be unique, to various declaraion tables, genera, surface, sampler, etc.
    std::map<std::string, CISA_GEN_VAR *> m_var_name_to_index_map;

    std::map<std::string, VISA_LabelOpnd *> m_label_name_to_index_map;
    std::map<std::string, VISA_LabelOpnd *> m_funcName_to_labelID_map;

    //used for fast path filescope vars
    //used to make srue the decl is created only once.
    std::map<unsigned int, vISA::G4_Declare *> fileScopeMap;
    char errorMessage[MAX_ERROR_MSG_LEN];

    CM_VISA_BUILDER_OPTION mBuildOption;
    vISA::G4_Kernel* m_kernel;
    vISA::IR_Builder* m_builder;
    vISA::Mem_Manager *m_globalMem;
    vISA::Mem_Manager *m_kernelMem;
    vISA::PhyRegPool *m_phyRegPool;
    //customized allocator for allocating
    //It is very important that the same allocator is used by all instruction lists
    //that might be joined/spliced.
    INST_LIST_NODE_ALLOCATOR m_instListNodeAllocator;
    unsigned int m_kernelID;
    unsigned int m_inputSize;
    VISA_opnd m_fastPathOpndPool[vISA_NUMBER_OF_OPNDS_IN_POOL];
    unsigned int m_opndCounter;

    unsigned int varNameCount;
    unsigned int addressNameCount;
    unsigned int predicateNameCount;
    unsigned int surfaceNameCount;
    unsigned int samplerNameCount;
    unsigned int vmeNameCount;
    bool isRelocTablePresent;
    std::vector< std::pair<unsigned int, unsigned int> > varRelocTable;
    std::vector< std::pair<unsigned int, unsigned int> > funcRelocTable;

    int m_vISAInstCount;

    bool mIsFCCallableKernel;
    bool mIsFCCallerKernel;
    bool mIsFCComposableKernel;

    void computeFCInfo(vISA::BinaryEncodingBase* binEncodingInstance);
    void computeFCInfo();
    //memory managed by the entity that creates vISA Kernel object
    Options *m_options;

    bool getIntKernelAttributeValue(const char* attrName, int& value);
};
#endif //VISA_KERNEL_H
