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

Copyright (C) 2017-2021 Intel Corporation

SPDX-License-Identifier: MIT

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

#ifndef VISA_BUILDER_DEFINITION_H
#define VISA_BUILDER_DEFINITION_H

#include "VISADefines.h"
#include "VISAOptions.h"
#include "CompilerStats.h"
#include "JitterDataStruct.h"
#include "KernelInfo.h"

#include "visa/include/RelocationInfo.h"

class VISAKernel
{
public:

    /********** CREATE VARIABLE APIS START ******************/
    ///  CreateVISAGenVar - create an instance of vISA general variable and return it via decl.
    ///  varName must not be NULL, but need not be unique
    ///  numberElemetns must be [1,4096]
    ///  dataType may be one of UD, D, UW, W, UB, B, UQ, Q, DF, HF, F.
    ///  varAlign must be greater than or equal to the data type of the variable, and may be
    ///  specified only when parentDecl is NULL
    ///  parentDecl, if specified, means that this variable is an alias of another variable
    ///  starting at aliasOffset, which is in bytes.  parentDecl is permitted to be itself an
    ///  alias of another variable.  It is an error if the variable's actual offset in the root
    ///  (non-aliased) variable is not aligned to dataType
    VISA_BUILDER_API virtual int CreateVISAGenVar(VISA_GenVar *& decl, const char *varName, int numberElements, VISA_Type dataType,
                                        VISA_Align varAlign, VISA_GenVar *parentDecl = NULL, int aliasOffset = 0) = 0;

    /// CreateVISAAddrVar - create an instance of vISA address variable and return it via decl.
    /// an address variablbe must have type UW
    /// numberelements must be [1, 16]
    VISA_BUILDER_API virtual int CreateVISAAddrVar(VISA_AddrVar *& decl, const char *varName, unsigned int numberElements) = 0;

    /// AddKernelAttribute - create an attribute for the kernel.  See the vISA spec for a list
    /// of recognized attributes.
    /// name must be a ASCII string with length <=64
    VISA_BUILDER_API virtual int AddKernelAttribute(const char* name, int size, const void *value) = 0;

    /// CreateVISAPredVar - create an instance of vISA predicate variable and return it via decl.
    /// a predicate variable must have type Bool
    /// numberelements must be {1,2,4,8,16,32}
    VISA_BUILDER_API virtual int CreateVISAPredVar(VISA_PredVar *& decl, const char* varName, unsigned short numberElements) = 0;

    /// FIXME: we should have different names for them
    /// AddAttributeToVar - add an attribute for the variable.
    VISA_BUILDER_API virtual int AddAttributeToVar(VISA_PredVar *decl, const char* varName, unsigned int size, void *val) = 0;

    VISA_BUILDER_API virtual int AddAttributeToVar(VISA_SurfaceVar *decl, const char* varName, unsigned int size, void *val) = 0;

    VISA_BUILDER_API virtual int AddAttributeToVar(VISA_GenVar *decl, const char* name, unsigned int size, void *val) = 0 ;

    VISA_BUILDER_API virtual int AddAttributeToVar(VISA_AddrVar *decl, const char* name, unsigned int size, void *val) = 0 ;

    /// CreateVISASamplerVar - create an instance of vISA sampler variable and return it via decl.
    /// a sampler variable must have type UD
    /// numberElements must be [1,128]
    VISA_BUILDER_API virtual int CreateVISASamplerVar(VISA_SamplerVar *&decl, const char* name, unsigned int numberElements) = 0;

    /// CreateVISASurfaceVar - create an instance of vISA surface variable and return it via decl.
    /// a surface variable must have type UD
    /// numberElements must be [1,128]
    VISA_BUILDER_API virtual int CreateVISASurfaceVar(VISA_SurfaceVar *&decl, const char* name, unsigned int numberElements) = 0;

    /// CreateVISALabelVar - create an instance of vISA label variable and return it via decl.
    /// a label is either a block label or a subroutine label.
    /// name is for IR dump and debugging only; a fresh label is always returned even if another label with same name exists.
    /// The user should be responsible for managing the created label.
    VISA_BUILDER_API virtual int CreateVISALabelVar(VISA_LabelOpnd *& opnd, const char* name, VISA_Label_Kind kind) = 0;

    /// CreateVISAImplicitInputVar - create an input variable from a vISA general variable
    /// offset is the zero-based byte offset of the input
    /// size is in number of bytes for this variable. It must match the size of the variable
    /// kind What type of impliict argument it is
    VISA_BUILDER_API virtual int CreateVISAImplicitInputVar(VISA_GenVar *decl, unsigned short offset, unsigned short size, unsigned short kind) = 0;

    /// CreateVISAInputVar - create an input variable from a vISA general variable
    /// offset is the zero-based byte offset of the input
    /// size is in number of bytes for this variable. It must match the size of the variable
    VISA_BUILDER_API virtual int CreateVISAInputVar(VISA_GenVar *decl, unsigned short offset, unsigned short size) = 0;

    /// CreateVISAInputVar - create an input variable from a vISA sampler variable
    /// offset is the zero-based byte offset of the input
    /// size is in number of bytes for this variable. It must match the size of the variable
    VISA_BUILDER_API virtual int CreateVISAInputVar(VISA_SamplerVar *decl, unsigned short offset, unsigned short size) = 0;

    /// CreateVISAInputVar - create an input variable from a vISA surface variable
    /// offset is the zero-based byte offset of the input
    /// size is in number of bytes for this variable. It must match the size of the variable
    VISA_BUILDER_API virtual int CreateVISAInputVar(VISA_SurfaceVar *decl, unsigned short offset, unsigned short size) = 0;

    /// GetPredefinedVar - return a handle to a predefined general variable (e.g., r0)
    VISA_BUILDER_API virtual int GetPredefinedVar(VISA_GenVar *&predDcl, PreDefined_Vars varName) = 0;

    /// GetPredefinedSurface - return a handle to a predefined surface (e.g., SLM surface)
    VISA_BUILDER_API virtual int GetPredefinedSurface(VISA_SurfaceVar *&surfDcl, PreDefined_Surface surfaceName) = 0;

    /// GetBindlessSampler - return the pre-defined bindless sampler index
    VISA_BUILDER_API virtual int GetBindlessSampler(VISA_SamplerVar *&samplerDcl) = 0;
    /********** CREATE VARIALBE APIS END ******************/

    /********** CREATE OPERAND APIS START ******************/
    /// It is not permitted to use an operand in more than one instruction; fresh operands
    /// should be created from the variable for each instruction.

    /// CreateVISAAddressSrcOperand -- create a vISA address source operand (A_N(i)) from an address variable
    /// offset is the offset in number of elements
    /// width is the number of contiguous data elements accessed for this operand
    VISA_BUILDER_API virtual int CreateVISAAddressSrcOperand(VISA_VectorOpnd *&opnd, VISA_AddrVar *decl, unsigned int offset, unsigned int width) = 0;

    /// CreateVISAAddressDstOperand -- create a vISA address destination operand (A_N(i)) from an address variable
    /// offset is the offset in number of elements
    VISA_BUILDER_API virtual int CreateVISAAddressDstOperand(VISA_VectorOpnd *&opnd, VISA_AddrVar *decl, unsigned int offset) = 0;

    /// CreateVISAAddressOfOperand -- create a vISA addressof operand (&V_N+offset) from a general variable
    /// offset is the offset in bytes from the variable base
    VISA_BUILDER_API virtual int CreateVISAAddressOfOperand(VISA_VectorOpnd *&cisa_opnd, VISA_GenVar *decl, unsigned int offset) = 0;

    /// CreateVISAAddressOfOperand -- create a vISA addressof operand (&V_N+offset) from a surface variable
    /// offset is the offset in bytes from the variable base
    VISA_BUILDER_API virtual int CreateVISAAddressOfOperand(VISA_VectorOpnd *&cisa_opnd, VISA_SurfaceVar *decl, unsigned int offset) = 0;

    /// CreateVISAIndirectSrcOperand -- create a vISA indirect source operand
    /// (r[A_N(addrOffset), immedOffset]<verticalStride;width,horizontalStride>:type)
    /// mod is the source modifier
    /// addrOffset is in number of elements
    /// immedOffset is in byte and must be [-512, 511]
    /// verticalStride, width, and horizontalStride encode the 2D source region
    /// FIXME: should this be removed?
    VISA_BUILDER_API virtual 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) = 0;

    /// CreateVISAIndirectDstOperand -- create a vISA indirect dst operand
    /// (r[A_N(addrOffset), immedOffset]<horizontalStride>:type)
    /// addrOffset is in number of elements
    /// immedOffset is in byte and must be [-512, 511]
    /// horizontalStride encode the 1D destination region
    VISA_BUILDER_API virtual int CreateVISAIndirectDstOperand(VISA_VectorOpnd *& opnd, VISA_AddrVar *decl, unsigned int addrOffset, short immediateOffset,
                                                    unsigned short horizontalStride, VISA_Type type) = 0;

    /// CreateVISAIndirectOperandVxH -- create a vISA indirect source operand with multiple addresses
    /// (r[A_N(addrOffset), immedOffset]<1,0>:type)
    /// addrOffset is in number of elements
    /// immedOffset is in byte and must be [-512, 511]
    VISA_BUILDER_API virtual int CreateVISAIndirectOperandVxH(VISA_VectorOpnd *& cisa_opnd, VISA_AddrVar *decl, unsigned int addrOffset, short immediateOffset, VISA_Type type) = 0;

    /// CreateVISAPredicateOperand -- create a vISA predicate operand that can be used for predicated execution
    VISA_BUILDER_API virtual int CreateVISAPredicateOperand(VISA_PredOpnd *& opnd, VISA_PredVar *decl, VISA_PREDICATE_STATE state, VISA_PREDICATE_CONTROL cntrl) = 0;

    /// CreateVISASrcOperand -- create a vISA direct source operand from a general variable
    /// (V_N(offset)<vStride;widht,hStride>)
    /// FIXME: combine rowOffset and colOffsret into a single element offset
    VISA_BUILDER_API virtual 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) = 0;

    /// CreateVISADstOperand -- create a vISA direct destination operand from a general variable
    /// (V_N(offset)<hStride>)
    /// FIXME: combine rowOffset and colOffsret into a single element offset
    VISA_BUILDER_API virtual int CreateVISADstOperand(VISA_VectorOpnd *&opnd, VISA_GenVar *decl, unsigned short hStride, unsigned char rowOffset, unsigned char colOffset) = 0;

    /// CreateVISAImmediate -- create a vISA immediate operand based on val and type
    /// sizeof(type) bytes will be read from val and converted to the immediate value with the specified type
    VISA_BUILDER_API virtual int CreateVISAImmediate(VISA_VectorOpnd *&opnd, const void *val, VISA_Type type) = 0;

    /// CreateVISAStateOperand -- create a vISA state operand (S_N(offset)) from either a surface variable
    /// offset is in number of elements
    VISA_BUILDER_API virtual int CreateVISAStateOperand(VISA_VectorOpnd *&opnd, VISA_SurfaceVar *decl, unsigned char offset, bool useAsDst) = 0;

    /// CreateVISAStateOperand -- create a vISA state operand (S_N(offset)) from either a surface variable
    /// offset is in number of elements
    VISA_BUILDER_API virtual int CreateVISAStateOperand(VISA_VectorOpnd *&opnd, VISA_SurfaceVar *decl, uint8_t size, unsigned char offset, bool useAsDst) = 0;

    /// CreateVISAStateOperand -- create a vISA state operand (S_N(offset)) from either a sampler variable
    /// offset is in number of elements
    VISA_BUILDER_API virtual int CreateVISAStateOperand(VISA_VectorOpnd *&opnd, VISA_SamplerVar *decl, unsigned char offset, bool useAsDst) = 0;

    VISA_BUILDER_API virtual int CreateVISAStateOperand(VISA_VectorOpnd *&opnd, VISA_SamplerVar *decl, uint8_t size, unsigned char offset, bool useAsDst) = 0;

    VISA_BUILDER_API virtual int CreateVISAStateOperandHandle(VISA_StateOpndHandle *&opnd, VISA_SurfaceVar *decl) = 0;

    VISA_BUILDER_API virtual int CreateVISAStateOperandHandle(VISA_StateOpndHandle *&opnd, VISA_SamplerVar *decl) = 0;

    /// CreateVISARawOperand -- create a vISA raw operand (V_N + offset) from a general variable
    /// offset is in number of bytes
    /// a raw operand must be GRF (256 byte) aligned
    VISA_BUILDER_API virtual int CreateVISARawOperand(VISA_RawOpnd *&opnd, VISA_GenVar *decl, unsigned short offset) = 0;

    /// CreateVISANullRawOperand -- A short hand for createing V0<0;1,0>
    VISA_BUILDER_API virtual int CreateVISANullRawOperand(VISA_RawOpnd *&opnd, bool isDst) = 0;
    /********** CREATE OPERAND APIS END ******************/

    /********** APPEND INSTRUCTION APIS START ******************/

    /// AppendVISAArithmeticInst -- append an one-source vISA arithmetic instruction to this kernel
    /// [pred] op[.sat] (emask, execSize) dst src0
    VISA_BUILDER_API virtual int AppendVISAArithmeticInst(ISA_Opcode opcode, VISA_PredOpnd *pred, bool satMode, VISA_EMask_Ctrl emask,
                                          VISA_Exec_Size executionSize, VISA_VectorOpnd *tmpDst, VISA_VectorOpnd *src0) = 0;

    /// AppendVISAArithmeticInst -- append a two-source vISA arithmetic instruction to this kernel
    /// [pred] op[.sat] (emask, execSize) dst src0 src1
    VISA_BUILDER_API virtual int AppendVISAArithmeticInst(ISA_Opcode opcode, VISA_PredOpnd *pred, bool satMode, VISA_EMask_Ctrl emask,
                                          VISA_Exec_Size executionSize, VISA_VectorOpnd *tmpDst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1) = 0;

    /// AppendVISAArithmeticInst -- append a three-source vISA arithmetic instruction to this kernel
    /// [pred] op[.sat] (emask, execSize) dst src0 src1 src2
    VISA_BUILDER_API virtual int AppendVISAArithmeticInst(ISA_Opcode opcode, VISA_PredOpnd *pred, bool satMode, VISA_EMask_Ctrl emask,
                                          VISA_Exec_Size executionSize, VISA_VectorOpnd *tmpDst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1, VISA_VectorOpnd *src2) = 0;

    /// AppendVISAArithmeticTwoDstInst -- append a two-dst, two-source vISA arithmetic instruction to this kernel
    /// [pred] op (emask, execSize) dst0 dst1 src0 src1
    /// This is used by addc and subb
    VISA_BUILDER_API virtual int AppendVISATwoDstArithmeticInst(ISA_Opcode opcode, VISA_PredOpnd *pred, VISA_EMask_Ctrl emask,
                                          VISA_Exec_Size executionSize, VISA_VectorOpnd *dst1, VISA_VectorOpnd *carry_borrow, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1) = 0;

    /// AppendVISADpasInst -- append a DPAS instruction to this kernel.
    ///    op (execSize) dst src0 src1 src2
    /// Precision, depth, repeat count are constant and considered as fields
    /// of the inst (not operands.). Note that src0 could be null operand.
    VISA_BUILDER_API virtual int AppendVISADpasInst(ISA_Opcode opcode, VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize,
        VISA_RawOpnd *tmpDst, VISA_RawOpnd *src0, VISA_RawOpnd *src1, VISA_VectorOpnd *src2,
        GenPrecision A, GenPrecision W, uint8_t D, uint8_t C) = 0;

    /// AppendVISABfnInst -- append a BFN instruction to this kernel.
    ///    [pred] op.booleanFuncCtrl[.sat] (emask, execSize) dst src0 src1 src2
    /// <booleanFuncCtrl> is constant and is considered as a field of the inst,
    /// not as an operand.
    VISA_BUILDER_API virtual int AppendVISABfnInst(uint8_t booleanFuncCtrl, VISA_PredOpnd *pred, bool satMode, VISA_EMask_Ctrl emask,
        VISA_Exec_Size executionSize, VISA_VectorOpnd *tmpDst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1, VISA_VectorOpnd *sdrc2) = 0;

    /// AppendVISAQwordGatherInst -- append a qword scattered read instruction to this kernel
    VISA_BUILDER_API virtual int AppendVISAQwordGatherInst(VISA_PredOpnd *pred,
        VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize,
        VISA_SVM_Block_Num numBlocks, VISA_StateOpndHandle *surface,
        VISA_RawOpnd* address, VISA_RawOpnd *src) = 0;

    /// AppendVISAQwordScatterInst -- append a qword scattered write instruction to this kernel
    VISA_BUILDER_API virtual int AppendVISAQwordScatterInst(VISA_PredOpnd *pred,
        VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize,
        VISA_SVM_Block_Num numBlocks, VISA_StateOpndHandle *surface,
        VISA_RawOpnd* address, VISA_RawOpnd *dst) = 0;


    ///////////////////////////////////////////////////////////////////////////
    // LSC untyped operations
    //
    /// append an *untyped* LSC load operation
    ///
    ///  * dstData can be nullptr if the load is a prefetch only
    ///
    VISA_BUILDER_API virtual int AppendVISALscUntypedLoad(
        LSC_OP                    subOpcode,
        LSC_SFID                  sfid,
        VISA_PredOpnd            *pred,
        VISA_Exec_Size            execSize,
        VISA_EMask_Ctrl           emask,
        LSC_CACHE_OPTS            cacheOpts,
        LSC_ADDR                  addr,
        LSC_DATA_SHAPE            data,
        VISA_VectorOpnd          *surface,
        VISA_RawOpnd             *dstData,
        VISA_RawOpnd             *src0Addr) = 0;
    /// append an *untyped* LSC store operation
    VISA_BUILDER_API virtual int AppendVISALscUntypedStore(
        LSC_OP                    subOpcode,
        LSC_SFID                  sfid,
        VISA_PredOpnd            *pred,
        VISA_Exec_Size            execSize,
        VISA_EMask_Ctrl           emask,
        LSC_CACHE_OPTS            cacheOpts,
        LSC_ADDR                  addr,
        LSC_DATA_SHAPE            data,
        VISA_VectorOpnd          *surface,
        VISA_RawOpnd             *src0Addr,
        VISA_RawOpnd             *src1Data) = 0;
    /// append an *untyped* LSC atomic operation
    //
    /// atomic unary operations (e.g. lsc_atomic_iinc) take no extra data
    /// parameters and can be passed nullptr; atomic binary operations
    /// (e.g. lsc_atomic_add) takes src1AtomOpnd1 and leaves src2 nullptr.
    /// Atomic ternary (lsc_atomic_{i,f}cas) takes both extra src parameters.
    VISA_BUILDER_API virtual int AppendVISALscUntypedAtomic(
        LSC_OP                    subOpcode,
        LSC_SFID                  sfid,
        VISA_PredOpnd            *pred,
        VISA_Exec_Size            execSize,
        VISA_EMask_Ctrl           emask,
        LSC_CACHE_OPTS            cacheOpts,
        LSC_ADDR                  addr,
        LSC_DATA_SHAPE            data,
        VISA_VectorOpnd          *surface,
        VISA_RawOpnd             *dstReadBack,
        VISA_RawOpnd             *src0Addr,
        VISA_RawOpnd             *src1AtomOpnd1 = nullptr,
        VISA_RawOpnd             *src2AtomOpnd2 = nullptr) = 0;
    //
    /// A generic constructor for untyped LSC operations.  Prefer the explicit
    /// functions above when possible.  The SFID passed in must not be LSC_TGM.
    /// (use AppendVISALscTyped* for typed).
    VISA_BUILDER_API virtual int AppendVISALscUntypedInst(
        LSC_OP                    subOpcode,
        LSC_SFID                  sfid,
        VISA_PredOpnd            *pred,
        VISA_Exec_Size            execSize,
        VISA_EMask_Ctrl           emask,
        LSC_CACHE_OPTS            cacheOpts,
        LSC_ADDR                  addr,
        LSC_DATA_SHAPE            data,
        VISA_VectorOpnd          *surface,
        VISA_RawOpnd             *dst,
        VISA_RawOpnd             *src0,
        VISA_RawOpnd             *src1,
        VISA_RawOpnd             *src2) = 0;
    /// A generic constructor for lsc_load_strided and lsc_store_strided.
    ///
    VISA_BUILDER_API virtual int AppendVISALscUntypedStridedInst(
        LSC_OP                    subOpcode,
        LSC_SFID                  sfid,
        VISA_PredOpnd            *pred,
        VISA_Exec_Size            execSize,
        VISA_EMask_Ctrl           emask,
        LSC_CACHE_OPTS            cacheOpts,
        LSC_ADDR                  addrInfo,
        LSC_DATA_SHAPE            dataShape,
        VISA_VectorOpnd          *surface,
        VISA_RawOpnd             *dstData,
        VISA_RawOpnd             *src0AddrBase,
        VISA_VectorOpnd          *src0AddrPitch,
        VISA_RawOpnd             *src1Data) = 0;
    /// A generic constructor for lsc_load_strided and lsc_store_strided.
    ///
    VISA_BUILDER_API virtual int AppendVISALscUntypedBlock2DInst(
        LSC_OP                    subOpcode,
        LSC_SFID                  lscSfid,
        VISA_PredOpnd            *pred,
        VISA_Exec_Size            execSize,
        VISA_EMask_Ctrl           emask,
        LSC_CACHE_OPTS            cacheOpts,
        LSC_DATA_SHAPE_BLOCK2D    dataShape,
        VISA_RawOpnd             *dstData,
        VISA_VectorOpnd          *src0Addrs[LSC_BLOCK2D_ADDR_PARAMS],
        VISA_RawOpnd             *src1Data) = 0;
    ///////////////////////////////////////////////////////////////////////////
    // LSC typed operations
    //
    //
    /// append a *typed* LSC load to this kernel
    VISA_BUILDER_API virtual int AppendVISALscTypedLoad(
        LSC_OP                    subOpcode,
        VISA_PredOpnd            *pred,
        VISA_Exec_Size            execSize,
        VISA_EMask_Ctrl           emask,
        LSC_CACHE_OPTS            cacheOpts,
        LSC_ADDR_TYPE             addrType,
        LSC_ADDR_SIZE             addrSize,
        LSC_DATA_SHAPE            data,
        VISA_VectorOpnd          *surface,
        VISA_RawOpnd             *dstData,
        VISA_RawOpnd             *Us,
        VISA_RawOpnd             *Vs,
        VISA_RawOpnd             *Rs,
        VISA_RawOpnd             *LODs) = 0;
    /// append a *typed* LSC store to this kernel
    VISA_BUILDER_API virtual int AppendVISALscTypedStore(
        LSC_OP                    subOpcode,
        VISA_PredOpnd            *pred,
        VISA_Exec_Size            execSize,
        VISA_EMask_Ctrl           emask,
        LSC_CACHE_OPTS            cacheOpts,
        LSC_ADDR_TYPE             addrType,
        LSC_ADDR_SIZE             addrSize,
        LSC_DATA_SHAPE            data,
        VISA_VectorOpnd          *surface,
        VISA_RawOpnd             *Us,
        VISA_RawOpnd             *Vs,
        VISA_RawOpnd             *Rs,
        VISA_RawOpnd             *LODs,
        VISA_RawOpnd             *src1Data) = 0;
    /// append a *typed* LSC atomic to this kernel; src1 and src2 may be
    /// nullptr ternary atomic ops (e.g. atomic_icas/atomic_fcas take both
    /// extra parameters, binary (e.g. atomic_add) takes only src1 and unary
    /// (e.g. atomic_inc) takes neither.
    VISA_BUILDER_API virtual int AppendVISALscTypedAtomic(
        LSC_OP                    subOpcode,
        VISA_PredOpnd            *pred,
        VISA_Exec_Size            execSize,
        VISA_EMask_Ctrl           emask,
        LSC_CACHE_OPTS            cacheOpts,
        LSC_ADDR_TYPE             addrModel,
        LSC_ADDR_SIZE             addrSize,
        LSC_DATA_SHAPE            data,
        VISA_VectorOpnd          *surface,
        VISA_RawOpnd             *dstReadBack,
        VISA_RawOpnd             *Us,
        VISA_RawOpnd             *Vs,
        VISA_RawOpnd             *Rs,
        VISA_RawOpnd             *LODs,
        VISA_RawOpnd             *src1AtomicOpnd1,
        VISA_RawOpnd             *src2AtomicOpnd2) = 0;
    /// generic function to append a *typed* LSC load/store/atomic message
    /// to this kernel
    VISA_BUILDER_API virtual int AppendVISALscTypedInst(
        LSC_OP                    subOpcode,
        VISA_PredOpnd            *pred,
        VISA_Exec_Size            execSize,
        VISA_EMask_Ctrl           emask,
        LSC_CACHE_OPTS            cacheOpts,
        LSC_ADDR_TYPE             addrType,
        LSC_ADDR_SIZE             addrSize,
        LSC_DATA_SHAPE            data,
        VISA_VectorOpnd          *surface,
        VISA_RawOpnd             *dst,
        VISA_RawOpnd             *Us,
        VISA_RawOpnd             *Vs,
        VISA_RawOpnd             *Rs,
        VISA_RawOpnd             *LODs,
        VISA_RawOpnd             *src1,
        VISA_RawOpnd             *src2) = 0;

    ///////////////////////////////////////////////////////////////////////////
    // LSC fences
    //
    /// append a fence instruction to this kernel; the SFID passed in
    /// controls which unit the fence applies to
    VISA_BUILDER_API virtual int AppendVISALscFence(
        LSC_SFID                  lscSfid,
        LSC_FENCE_OP              fenceOp,
        LSC_SCOPE                 scope) = 0;


    ///////////////////////////////////////////////////////////////////////////
    // Named barriers functions
    //
    VISA_BUILDER_API virtual int AppendVISANamedBarrierWait(
        VISA_VectorOpnd* barrierId) = 0;

    VISA_BUILDER_API virtual int AppendVISANamedBarrierSignal(
        VISA_VectorOpnd* barrierId,
        VISA_VectorOpnd* barrierCount
    ) = 0;

    /// FIXME: we should probably have separate API for logic and shift instructions, as the arguments they expect are quite different
    /// AppendVISALogicOrShiftInst -- append a two-dst, two-source vISA arithmetic instruction to this kernel
    /// [pred] op[.sat] (emask, execSize) dst src0 src1 [src2 src3]
    /// src2 is used only for bfe and bfi
    /// src3 is used only for bfi
    VISA_BUILDER_API virtual int AppendVISALogicOrShiftInst(
        ISA_Opcode opcode, VISA_PredOpnd *pred, bool satMode,
        VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize,
        VISA_VectorOpnd *dst,
        VISA_VectorOpnd *src0, VISA_VectorOpnd *src1,
        VISA_VectorOpnd *src2 = NULL, VISA_VectorOpnd *src3 = NULL) = 0;

    ///AppendVISALogicOrShiftInst
    ///Used to perform logic operations on predicates.
    ///The operand is constructed internally.
    ///Enforces none matching types
    VISA_BUILDER_API virtual int AppendVISALogicOrShiftInst(
        ISA_Opcode opcode, VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize,
        VISA_PredVar *dst, VISA_PredVar *src0, VISA_PredVar *src1) = 0;
    /// FIXME: why not use the addressof_opnd if we had introduced it earlier?
    /// AppendVISAAddrAddInst -- append an address add instruction to this kernel
    /// addr_add (emask, execSize) dst src0 src1
    VISA_BUILDER_API virtual int AppendVISAAddrAddInst(
        VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize,
        VISA_VectorOpnd *dst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1) = 0;

    /// AppendVISADataMovementInst -- append a one-source data movement instruction to this kernel
    /// [pred] op[.sat] (emask, execSize) dst src0
    VISA_BUILDER_API virtual int AppendVISADataMovementInst(
        ISA_Opcode opcode, VISA_PredOpnd *pred, bool satMod, VISA_EMask_Ctrl emask,
        VISA_Exec_Size executionSize, VISA_VectorOpnd *dst, VISA_VectorOpnd *src0) = 0;

    /// AppendVISADataMovementInst -- append a two-source data movement instruction to this kernel
    /// [pred] op[.sat] (emask, execSize) dst src0 src1
    VISA_BUILDER_API virtual int AppendVISADataMovementInst(
        ISA_Opcode opcode, VISA_PredOpnd *pred, bool satMod, VISA_EMask_Ctrl emask,
        VISA_Exec_Size executionSize, VISA_VectorOpnd *dst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1) = 0;

    ///AppendVISAPredicateMove
    ///Moves the context of the Predicate in to a Vector Operand.
    ///Predicate operand is constructed internally
    VISA_BUILDER_API virtual int AppendVISAPredicateMove(VISA_VectorOpnd *dst, VISA_PredVar *src0) = 0;

    ///AppendVISASetP
    ///Moves the content from the vector operand back in to Predicate operand.
    ///Destination Predicate operand is constructed internally.
    VISA_BUILDER_API virtual int AppendVISASetP(VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize, VISA_PredVar *dst, VISA_VectorOpnd *src0) = 0;

    /// AppendVISAMinMaxInst -- append a two-source data movement instruction to this kernel
    /// min/max[.sat] (emask, execSize) dst src0 src1
    VISA_BUILDER_API virtual int AppendVISAMinMaxInst(
        CISA_MIN_MAX_SUB_OPCODE subOpcode, bool satMod, VISA_EMask_Ctrl emask,
        VISA_Exec_Size executionSize, VISA_VectorOpnd *dst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1) = 0;

    /// AppendVISAComparisonInst -- append a two-source comparison instruction to this kernel
    ///                             Destination is a flag register.
    /// cmp.sub_op.f# (emask, execSize) nullDst src0 src1
    VISA_BUILDER_API virtual int AppendVISAComparisonInst(
        VISA_Cond_Mod sub_op, VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize,
        VISA_PredVar *dst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1) = 0;

    /// AppendVISAComparisonInst -- append a two-source comparison instruction to this kernel.
    ///                             Destination is a GRF register.
    ///                             Flag register is updated but live range is only this instruction.
    /// cmp.sub_op.f# (emask, execSize) dst src0 src1
    VISA_BUILDER_API virtual int AppendVISAComparisonInst(
        VISA_Cond_Mod sub_op, VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize,
        VISA_VectorOpnd *dst, VISA_VectorOpnd *src0, VISA_VectorOpnd *src1) = 0;

    /// AppendVISACFGotoInst -- append a possibly divergent goto instruction to this kernel
    /// [pred] goto (emask, execSize) label
    VISA_BUILDER_API virtual int AppendVISACFGotoInst(VISA_PredOpnd *pred, VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize, VISA_LabelOpnd *label) = 0;

    /// AppendVISACFLabelInst -- append a label instruction to this kernel
    /// label:
    VISA_BUILDER_API virtual int AppendVISACFLabelInst(VISA_LabelOpnd *label) = 0;

    /// AppendVISACFJmpInst -- append a scalar jmp instruction to this kernel
    /// [pred] jmp (NoMask, 1) label
    VISA_BUILDER_API virtual int AppendVISACFJmpInst(VISA_PredOpnd *pred, VISA_LabelOpnd *label) = 0;

    /// AppendVISACFCallInst -- append a subroutine call instruction to this kernel
    /// [pred] call (emask, execSize) label
    VISA_BUILDER_API virtual int AppendVISACFCallInst(VISA_PredOpnd *pred, VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize, VISA_LabelOpnd *label) = 0;

    /// AppendVISACFRetInst -- append a subroutine return instruction to this kernel
    /// [pred] ret (emask, execSize)
    VISA_BUILDER_API virtual int AppendVISACFRetInst(VISA_PredOpnd *pred, VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize) = 0;

    /// AppendVISACFFunctionCallInst -- append a function call instruction to this kernel
    /// [pred] fcall (emask, execSize) function
    /// argSize must be [0, sizeof(Arg)]
    /// returnSize must be [0, sizeof(RetVal)]
    VISA_BUILDER_API virtual int AppendVISACFFunctionCallInst(VISA_PredOpnd *pred, VISA_EMask_Ctrl emask,
        VISA_Exec_Size executionSize, std::string funcName, unsigned char argSize, unsigned char returnSize) = 0;

    /// AppendVISACFIndirectFuncCallInst -- append an indirect function call to this kernel
    /// [pred] fcall (emask, execSize) funcAddr
    /// funcAddr is a 32-bit int value representing the logical address of the function
    /// argSize must be [0, sizeof(Arg)]
    /// returnSize must be [0, sizeof(RetVal)]
    VISA_BUILDER_API virtual int AppendVISACFIndirectFuncCallInst(VISA_PredOpnd *pred,
        VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize, VISA_VectorOpnd* funcAddr,
        unsigned char argSize, unsigned char returnSize) = 0;

    /// AppendVISACFFuncAddrInst -- stores the address of a symbol <symbolName> into <dst>
    /// faddr symbolName dst
    /// symbolName is the unique string to identify the symbol whose address is taken
    /// dst must have UD type with scalar region
    VISA_BUILDER_API virtual int AppendVISACFSymbolInst(std::string symbolName, VISA_VectorOpnd* dst) = 0;

    /// AppendVISACFFunctionRetInst -- append a function return instruction to this kernel
    /// [pred] fret (emask, execSize)
    VISA_BUILDER_API virtual int AppendVISACFFunctionRetInst(VISA_PredOpnd *pred, VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize) = 0;

    /// AppendVISACFSwitchJmpInst -- append a switch jump instruction to this kernel
    /// switchjmp (NoMask, 1) index (label0, label1, ... labelN-1)
    /// labelCount must be in [1,32]
    VISA_BUILDER_API virtual int AppendVISACFSwitchJMPInst(VISA_VectorOpnd *index, unsigned char labelCount, VISA_LabelOpnd **labels) = 0;

    /// AppendVISASurfAccessDWordAtomicInst -- append a dword atomic write instruction to this kernel
    /// NOTE: offsets are both in unit of BYTE!
    VISA_BUILDER_API virtual int AppendVISASurfAccessDwordAtomicInst(
        VISA_PredOpnd *pred, VISAAtomicOps subOpc, bool is16Bit,
        VISA_EMask_Ctrl eMask, VISA_Exec_Size execSize,
        VISA_StateOpndHandle *surface, VISA_RawOpnd *offsets,
        VISA_RawOpnd *src0, VISA_RawOpnd *src1, VISA_RawOpnd *dst) = 0;

    /// FIXME: why not have separate functions for them?
    /// AppendVISASurfAccessGatherScatterInst -- append gather/scatter instruction to this kernel
    /// globalOffset and elementOffset are both in unit of element size
    VISA_BUILDER_API virtual int AppendVISASurfAccessGatherScatterInst(
        ISA_Opcode opcode, VISA_EMask_Ctrl emask, GATHER_SCATTER_ELEMENT_SIZE elementSize,
        VISA_Exec_Size executionSize, VISA_StateOpndHandle *surface,
        VISA_VectorOpnd *globalOffset, VISA_RawOpnd *elementOffset, VISA_RawOpnd *srcDst) = 0;

    /// AppendVISASurfAccessGather4Scatter4TypedInst -- append a typed dword gather4/scatter4 instruction to this kernel
    /// uOffset, vOffset, and rOffset are all in unit of pixels.
    /// vOffset should be set to V0 for 1D surfaces
    /// rOffset should be set to V0 for 1D and 2D surfaces
    VISA_BUILDER_API virtual int AppendVISASurfAccessGather4Scatter4TypedInst(ISA_Opcode opcode,
                                                                            VISA_PredOpnd *pred,
                                                                            VISAChannelMask chMask,
                                                                            VISA_EMask_Ctrl emask,
                                                                            VISA_Exec_Size executionSize,
                                                                            VISA_StateOpndHandle *surface,
                                                                            VISA_RawOpnd *uOffset,
                                                                            VISA_RawOpnd *vOffset,
                                                                            VISA_RawOpnd *rOffset,
                                                                            VISA_RawOpnd *lod,
                                                                            VISA_RawOpnd *dst) = 0;

    /// AppendVISASurfAccessGather4Scatter4ScaledInst
    /// --append a dword gather4/scatter4 instruction to this kernel
    /// @globalOffset
    /// @offsets
    /// @dstSrc
    VISA_BUILDER_API virtual int
        AppendVISASurfAccessGather4Scatter4ScaledInst(ISA_Opcode                opcode,
                                                      VISA_PredOpnd             *pred,
                                                      VISA_EMask_Ctrl    eMask,
                                                      VISA_Exec_Size      execSize,
                                                      VISAChannelMask           chMask,
                                                      VISA_StateOpndHandle      *surface,
                                                      VISA_VectorOpnd           *globalOffset,
                                                      VISA_RawOpnd              *offsets,
                                                      VISA_RawOpnd              *dstSrc) = 0;

    /// AppendVISASurfAccessScatterScaledInst
    /// --append a (1/2/4) byte gather/scatter instruction to this kernel
    /// @globalOffset
    /// @offsets
    /// @dstSrc
    VISA_BUILDER_API virtual int
        AppendVISASurfAccessScatterScaledInst(ISA_Opcode                opcode,
                                              VISA_PredOpnd             *pred,
                                              VISA_EMask_Ctrl    eMask,
                                              VISA_Exec_Size      execSize,
                                              VISA_SVM_Block_Num  numBlocks,
                                              VISA_StateOpndHandle      *surface,
                                              VISA_VectorOpnd           *globalOffset,
                                              VISA_RawOpnd              *offsets,
                                              VISA_RawOpnd              *dstSrc) = 0;

    /// AppendVISASurfAccessMediaLoadStoreInst -- append a media block load/store instruction to this kernel
    /// blockWdith, blockHeight, and xOffset are in unit of bytes
    /// yOffset is in number of rows
    VISA_BUILDER_API virtual 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) = 0;

    /// AppendVISASurfAccessOWordLoadStoreInst -- append an oword load/store instruction to this kernel
    /// oword_load_aligned: offset is in unit of owords (16 bytes)
    /// oword_load_unaligned: offset is in unit of bytes, but must be dword aligned
    VISA_BUILDER_API virtual int AppendVISASurfAccessOwordLoadStoreInst(ISA_Opcode opcode, VISA_EMask_Ctrl emask, VISA_StateOpndHandle *surface, VISA_Oword_Num size, VISA_VectorOpnd *offset, VISA_RawOpnd *srcDst) = 0;

    /// AppendVISASvmBlockStoreInst -- append an A64 oword store instruction to this kernel
    /// address is in unit of owords (16 bytes)
    /// unaligned must be false
    VISA_BUILDER_API virtual int AppendVISASvmBlockStoreInst(VISA_Oword_Num size, bool unaligned, VISA_VectorOpnd* address, VISA_RawOpnd *src) = 0;

    /// AppendVISASvmBlockLoadInst -- append an A64 oword load instruction to this kernel
    /// address is in unit of owords (16 bytes)
    VISA_BUILDER_API virtual int AppendVISASvmBlockLoadInst(VISA_Oword_Num size, bool unaligned, VISA_VectorOpnd* address, VISA_RawOpnd *dst) = 0;

    /// AppendVISASvmScatterInst -- append an A64 byte scattered write instruction to this kernel
    /// address is in unit of bytes
    VISA_BUILDER_API virtual int AppendVISASvmScatterInst(VISA_PredOpnd *pred,
        VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize,
        VISA_SVM_Block_Type blockType, VISA_SVM_Block_Num numBlocks,
        VISA_RawOpnd* address, VISA_RawOpnd *src) = 0;

    /// AppendVISASvmGatherInst -- append an A64 byte scattered read instruction to this kernel
    /// address is in unit of bytes
    VISA_BUILDER_API virtual int AppendVISASvmGatherInst (VISA_PredOpnd *pred,
        VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize,
        VISA_SVM_Block_Type blockType, VISA_SVM_Block_Num numBlocks,
        VISA_RawOpnd* address, VISA_RawOpnd *dst) = 0;

    /// AppendVISASvmAtomicInst -- append an A64 untyped atomic integer instruction to this kernel
    /// address is in unit of bytes
    VISA_BUILDER_API virtual int
    AppendVISASvmAtomicInst(VISA_PredOpnd *pred, VISA_EMask_Ctrl emask,
                            VISA_Exec_Size executionSize,
                            VISAAtomicOps op, unsigned short bitwidth,
                            VISA_RawOpnd *addresses, VISA_RawOpnd *src0,
                            VISA_RawOpnd *src1, VISA_RawOpnd *dst) = 0;

    /// AppendVISASvmGather4ScaledInst -- append an A64 byte scaled read instruction to this kernel
    /// address is in unit of bytes
    VISA_BUILDER_API virtual int AppendVISASvmGather4ScaledInst(VISA_PredOpnd             *pred,
                                                              VISA_EMask_Ctrl    eMask,
                                                              VISA_Exec_Size      execSize,
                                                              VISAChannelMask           channelMask,
                                                              VISA_VectorOpnd           *address,
                                                              VISA_RawOpnd              *offsets,
                                                              VISA_RawOpnd              *dst) = 0;

    /// AppendVISASvmScatter4ScaledInst -- append an A64 byte scaled write instruction to this kernel
    /// address is in unit of bytes
    VISA_BUILDER_API virtual int AppendVISASvmScatter4ScaledInst(VISA_PredOpnd            *pred,
                                                               VISA_EMask_Ctrl   eMask,
                                                               VISA_Exec_Size     execSize,
                                                               VISAChannelMask          channelMask,
                                                               VISA_VectorOpnd          *address,
                                                               VISA_RawOpnd             *offsets,
                                                               VISA_RawOpnd             *src) = 0;

    VISA_BUILDER_API virtual int AppendVISASILoad(VISA_StateOpndHandle *surface, VISAChannelMask channel, bool isSIMD16,
        VISA_RawOpnd *uOffset, VISA_RawOpnd *vOffset, VISA_RawOpnd *rOffset, VISA_RawOpnd *dst) = 0;

    VISA_BUILDER_API virtual int AppendVISASISample(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) = 0;

    VISA_BUILDER_API virtual 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) = 0;

    /// AppendVISASyncInst -- appends one of barrier, fence, yield
    /// The optional argument is applicable only to the fence instruction
    VISA_BUILDER_API virtual int AppendVISASyncInst(ISA_Opcode opcode, unsigned char mask = 0) = 0;

    /// AppendVISASyncInst -- create a sendc fence instruction to enforce thread dependencies
    /// The mask, if not NULL, can be used to selectively disable waiting on some of the parent threads
    VISA_BUILDER_API virtual int AppendVISAWaitInst(VISA_VectorOpnd *mask) = 0;

    /// AppendVISASplitBarrierInst -- create a split-phase barrier
    /// isSignal indicates whether this is the signal or wait for the barrier
    VISA_BUILDER_API virtual int AppendVISASplitBarrierInst(bool isSignal) = 0;

    VISA_BUILDER_API virtual int AppendVISAMiscFileInst(const char *fileName) = 0;

    VISA_BUILDER_API virtual int AppendVISAMiscLOC(unsigned int lineNumber) = 0;

    VISA_BUILDER_API virtual int AppendVISADebugLinePlaceholder() = 0;

    /// AppendVISAMiscRawSend -- create a GEN send instruction
    /// [pred] send/sendc (esize) <dst> <src> <exMsgDesc> <desc> {emask}
    /// bit 0 of modifiers controls whether it's send (0) or sendc (1)
    VISA_BUILDER_API virtual int AppendVISAMiscRawSend(VISA_PredOpnd *pred, VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize, unsigned char modifiers,
                                      unsigned int exMsgDesc, unsigned char srcSize, unsigned char dstSize, VISA_VectorOpnd *desc,
                                      VISA_RawOpnd *src, VISA_RawOpnd *dst) = 0;

    /// AppendVISAMiscRawSend -- create a GEN split send instruction
    /// [pred] sends/sendsc (esize) <dst> <src0> <src1> <exMsgDesc> <desc> {emask}
    /// bit 0 of modifiers controls whether it's sends (0) or sendsc (1)
    //  bit 1 of modifiers has EOT flag for raw sends
    VISA_BUILDER_API virtual int AppendVISAMiscRawSends(VISA_PredOpnd *pred, VISA_EMask_Ctrl emask, VISA_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, bool hasEOT) = 0;

    VISA_BUILDER_API virtual int AppendVISALifetime(VISAVarLifetime startOrEnd, VISA_VectorOpnd *varId) = 0;

    /********** APPEND MEDIA Instructions START ******************/

    VISA_BUILDER_API virtual int AppendVISAMiscVME_FBR(VISA_StateOpndHandle *surface, VISA_RawOpnd *UNIInput, VISA_RawOpnd *FBRInput, VISA_VectorOpnd* FBRMbMode, VISA_VectorOpnd *FBRSubMbShape,
                                      VISA_VectorOpnd *FBRSubPredMode, VISA_RawOpnd *output) = 0;

    VISA_BUILDER_API virtual 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) = 0;

    VISA_BUILDER_API virtual int AppendVISAMiscVME_SIC(VISA_StateOpndHandle *surface, VISA_RawOpnd *UNIInput, VISA_RawOpnd *SICInput, VISA_RawOpnd *output) = 0;

    VISA_BUILDER_API virtual int AppendVISAMiscVME_IDM(VISA_StateOpndHandle *surface, VISA_RawOpnd *UNIInput, VISA_RawOpnd *IDMInput, VISA_RawOpnd *output) = 0;

    VISA_BUILDER_API virtual 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) = 0;

    VISA_BUILDER_API virtual int AppendVISAVABooleanCentroid(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
                                                            VISA_VectorOpnd *vOffset, VISA_VectorOpnd *vSize, VISA_VectorOpnd *hSize, VISA_RawOpnd *dst) = 0;

    VISA_BUILDER_API virtual int AppendVISAVACentroid(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
                                                            VISA_VectorOpnd *vOffset, VISA_VectorOpnd *vSize, VISA_RawOpnd *dst) = 0;

    VISA_BUILDER_API virtual int AppendVISAVAConvolve(VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
                                                            VISA_VectorOpnd *vOffset, CONVExecMode execMode, bool isBigKernel, VISA_RawOpnd *dst) = 0;

    VISA_BUILDER_API virtual int AppendVISAVAErodeDilate(EDMode subOp, VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
                                                            VISA_VectorOpnd *vOffset, EDExecMode execMode, VISA_RawOpnd *dst) = 0;

    VISA_BUILDER_API virtual int AppendVISAVAMinMax(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
                                                            VISA_VectorOpnd *vOffset, VISA_VectorOpnd *mmMode, VISA_RawOpnd *dst) = 0;

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

    VISA_BUILDER_API virtual 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) = 0;

    VISA_BUILDER_API virtual int AppendVISAVAFloodFill(bool is8Connect, VISA_RawOpnd *pixelMaskHDirection,
                                                            VISA_VectorOpnd *pixelMaskVDirectionLeft, VISA_VectorOpnd *pixelMaskVDirectionRight,
                                                            VISA_VectorOpnd *loopCount, VISA_RawOpnd *dst) = 0;

    VISA_BUILDER_API virtual int AppendVISAVALBPCorrelation(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
                                                            VISA_VectorOpnd *vOffset, VISA_VectorOpnd *disparity,
                                                            VISA_RawOpnd *dst) = 0;

    VISA_BUILDER_API virtual int AppendVISAVALBPCreation(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
                                                            VISA_VectorOpnd *vOffset, LBPCreationMode mode,
                                                            VISA_RawOpnd *dst) = 0;

    VISA_BUILDER_API virtual int AppendVISAVAConvolve1D(VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
                                                            VISA_VectorOpnd *vOffset, CONVExecMode mode, Convolve1DDirection direction, VISA_RawOpnd *dst) = 0;

    VISA_BUILDER_API virtual int AppendVISAVAConvolve1Pixel(VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
                                                            VISA_VectorOpnd *vOffset, CONV1PixelExecMode mode, VISA_RawOpnd *offsets, VISA_RawOpnd *dst) = 0;

    VISA_BUILDER_API virtual 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) = 0;

    VISA_BUILDER_API virtual 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) = 0;

    VISA_BUILDER_API virtual 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) = 0;

    VISA_BUILDER_API virtual int AppendVISAVAHDCLBPCorrelation(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
                                                            VISA_VectorOpnd *vOffset, VISA_VectorOpnd *disparity,
                                                            VISA_StateOpndHandle *dstSurface, VISA_VectorOpnd *xOffset, VISA_VectorOpnd *yOffset) = 0;

    VISA_BUILDER_API virtual int AppendVISAVAHDCLBPCreation(VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
                                                            VISA_VectorOpnd *vOffset, LBPCreationMode mode,
                                                            VISA_StateOpndHandle *dstSurface, VISA_VectorOpnd *xOffset, VISA_VectorOpnd *yOffset) = 0;

    VISA_BUILDER_API virtual int AppendVISAVAHDCConvolve1D(VISA_StateOpndHandle *sampler, VISA_StateOpndHandle *surface, VISA_VectorOpnd * uOffset,
                                                            VISA_VectorOpnd *vOffset, HDCReturnFormat returnFormat, Convolve1DDirection direction,
                                                            VISA_StateOpndHandle *dstSurface, VISA_VectorOpnd *xOffset, VISA_VectorOpnd *yOffset) = 0;

    VISA_BUILDER_API virtual 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) = 0;

    /********** APPEND MEDIA Instructions END ******************/

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

    /// AppendVISA3dSampler -- create a vISA sampler message
    /// @subOpcode the sampler op (sample, sample_c, sample_d, etc.)
    /// @pixelNullMask whether an extra GRF is returned for the null mask bit
    /// @cpsEnable whether CPS LOD compensation is enabled
    /// @uniformSampler whether the sampler state is uniform across all work items
    /// @pred predicate variable
    /// @emask execution mask
    /// @executionSize (8, 16)
    /// @channelMask the RGBA channel mask for the return value
    /// @aoffimmi Dx10 _aoffimmi modifier. [0:3] - R offset, [4:7] - V offset, [8:11] - U offset
    /// @sampler sampler index
    /// @surface surface index
    /// @dst return value.  Type may be either 32-bit or 16-bit
    /// @numMsgSepcificOpnds.  Number of payload arguments
    /// @opndArray.  payload arguments.  All operands must have the same type, which is either F or HF
    VISA_BUILDER_API virtual int AppendVISA3dSampler(VISASampler3DSubOpCode subOpcode,
                                                   bool pixelNullMask,
                                                   bool cpsEnable,
                                                   bool uniformSampler,
                                                   VISA_PredOpnd *pred,
                                                   VISA_EMask_Ctrl emask,
                                                   VISA_Exec_Size executionSize,
                                                   VISAChannelMask channelMask,
                                                   VISA_VectorOpnd* aoffimmi,
                                                   VISA_StateOpndHandle *sampler,
                                                   VISA_StateOpndHandle *surface,
                                                   VISA_RawOpnd *dst,
                                                   int numMsgSpecificOpnds,
                                                   VISA_RawOpnd **opndArray) = 0;

    /// AppendVISA3dLoad -- create a vISA sampler load message
    /// @subOpcode the sampler op (ld, ld_lz, etc.)
    /// @pixelNullMask whether an extra GRF is returned for the null mask bit
    /// @pred predicate variable
    /// @emask execution mask
    /// @executionSize (8, 16)
    /// @channelMask the RGBA channel mask for the return value
    /// @aoffimmi Dx10 _aoffimmi modifier. [0:3] - R offset, [4:7] - V offset, [8:11] - U offset
    /// @surface surface index
    /// @dst return value.  Type may be either 32-bit or 16-bit
    /// @numMsgSepcificOpnds.  Number of payload arguments
    /// @opndArray.  payload arguments.  All operands must have the type UD
    VISA_BUILDER_API virtual int AppendVISA3dLoad(VISASampler3DSubOpCode subOpcode,
                                                bool pixelNullMask,
                                                VISA_PredOpnd *pred,
                                                VISA_EMask_Ctrl emask,
                                                VISA_Exec_Size executionSize,
                                                VISAChannelMask channelMask,
                                                VISA_VectorOpnd* aoffimmi,
                                                VISA_StateOpndHandle *surface,
                                                VISA_RawOpnd *dst,
                                                int numMsgSpecificOpnds,
                                                VISA_RawOpnd **opndArray) = 0;

    /// AppendVISA3dGather4 -- create a vISA sampler gather4 message
    /// @subOpcode the gather4 op (gather4, gather4_c, etc.)
    /// @pixelNullMask whether an extra GRF is returned for the null mask bit
    /// @pred predicate variable
    /// @emask execution mask
    /// @executionSize (8, 16)
    /// @srcChannel one of {R,G,B,A} channel to be returned
    /// @aoffimmi Dx10 _aoffimmi modifier. [0:3] - R offset, [4:7] - V offset, [8:11] - U offset
    /// @sampler sampler index
    /// @surface surface index
    /// @dst return value.  Type may be either 32-bit or 16-bit
    /// @numMsgSepcificOpnds.  Number of payload arguments
    /// @opndArray.  payload arguments.  All operands must have the same type, which is either F or HF
    VISA_BUILDER_API virtual int AppendVISA3dGather4(VISASampler3DSubOpCode subOpcode,
                                                   bool pixelNullMask,
                                                   VISA_PredOpnd *pred,
                                                   VISA_EMask_Ctrl emask,
                                                   VISA_Exec_Size executionSize,
                                                   VISASourceSingleChannel srcChannel,
                                                   VISA_VectorOpnd* aoffimmi,
                                                   VISA_StateOpndHandle *sampler,
                                                   VISA_StateOpndHandle *surface,
                                                   VISA_RawOpnd *dst,
                                                   int numMsgSpecificOpnds,
                                                   VISA_RawOpnd **opndArray) = 0;

    VISA_BUILDER_API virtual int AppendVISA3dInfo(VISASampler3DSubOpCode subOpcode, VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize, VISAChannelMask srcChannel, VISA_StateOpndHandle *surface, VISA_RawOpnd *lod, VISA_RawOpnd *dst) = 0;

    VISA_BUILDER_API virtual int AppendVISA3dRTWrite(VISA_PredOpnd *pred, VISA_EMask_Ctrl emask, VISA_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) = 0;

    VISA_BUILDER_API virtual int AppendVISA3dRTWriteCPS(VISA_PredOpnd *pred, VISA_EMask_Ctrl emask, VISA_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) = 0;

    VISA_BUILDER_API virtual int AppendVISA3dURBWrite(VISA_PredOpnd *pred, VISA_EMask_Ctrl emask, VISA_Exec_Size executionSize, unsigned char numberOutputParams, VISA_RawOpnd *channelMask, unsigned short globalOffset,
                                                    VISA_RawOpnd *URBHandle, VISA_RawOpnd *perSLotOffset, VISA_RawOpnd *vertexData) = 0;

    VISA_BUILDER_API virtual int AppendVISA3dTypedAtomic(
        VISAAtomicOps subOp, bool is16Bit, VISA_PredOpnd *pred,
        VISA_EMask_Ctrl emask, VISA_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) = 0;

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

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

    /// GetGenxBinary -- returns the GEN binary in <buffer> and update its size in <size>
    /// This function may only be called after Compile() is called
    /// If finalization fails, buffer will be set to NULL and size will be set to 0
    /// buffer must be de-allocated using freeBLock API.
    VISA_BUILDER_API virtual int GetGenxBinary(void *&buffer, int &size) const = 0;

    /// GetJitInfo -- returns auxiliary information collected during finalization
    /// This function may only be called after Compile() is called
    /// vISA Builder is responsible for managing this memory.
    /// it will be freed when vISA builder is destroyed.
    VISA_BUILDER_API virtual int GetJitInfo(FINALIZER_INFO *&jitInfo) const = 0;
    /// GetKernelInfo -- returns metrics information about kernel
    /// This function may only be called after Compile() is called
    /// vISA Builder is responsible for managing this memory.
    /// it will be freed when vISA builder is destroyed.
    VISA_BUILDER_API virtual int GetKernelInfo(KERNEL_INFO*& kernelInfo) const = 0;
    VISA_BUILDER_API virtual int GetCompilerStats(CompilerStats &compilerStats) = 0;

    /// GetErrorMessage -- returns the error message during finalization
    VISA_BUILDER_API virtual int GetErrorMessage(const char *&errorMsg) const = 0;

    /// GetGenxDebugInfo -- returns the GEN debug info binary in <buffer>
    /// and its size in <size>.
    /// This function may only be called after Compile() is called
    /// If finalization fails, buffer will be set to NULL and size will be set to 0
    /// buffer must be de-allocated using freeBLock API.
    VISA_BUILDER_API virtual int GetGenxDebugInfo(void *&buffer, unsigned int &size) const = 0;

    /// GetGenRelocEntryBuffer -- allocate and return a buffer of all GenRelocEntry that are created by vISA
    VISA_BUILDER_API virtual int GetGenRelocEntryBuffer(void *&buffer, unsigned int &byteSize, unsigned int &numEntries) = 0;

    /// GetRelocations -- add vISA created relocations into given relocation list
    /// This get the same information as GetGenRelocEntryBuffer, but in different foramt
    typedef std::vector<vISA::ZERelocEntry> RelocListType;
    VISA_BUILDER_API virtual int GetRelocations(RelocListType &relocs) = 0;

    /// SetGTPinInit -- pass igc_init_t struct instance
    /// VISA decodes this struct and enables options accordingly
    VISA_BUILDER_API virtual int SetGTPinInit(void* buffer) = 0;

    /// GetGTPinBuffer -- returns data buffer for gtpin (eg, free GRF info)
    /// This requires reRA pass to be executed, otherwise it returs nullptr
    VISA_BUILDER_API virtual int GetGTPinBuffer(void *& buffer, unsigned int& size) = 0;

    /// GetFreeGRFInfo -- returns free GRF information for gtpin
    /// This requires reRA pass to be executed, otherwise it returs nullptr
    VISA_BUILDER_API virtual int GetFreeGRFInfo(void *& buffer, unsigned int& size) = 0;

    ///Gets declaration id GenVar
    VISA_BUILDER_API virtual int getDeclarationID(VISA_GenVar *decl) const = 0;

    ///Gets declaration id VISA_AddrVar
    VISA_BUILDER_API virtual int getDeclarationID(VISA_AddrVar *decl) const = 0;

    ///Gets declaration id VISA_PredVar
    VISA_BUILDER_API virtual int getDeclarationID(VISA_PredVar *decl) const = 0;

    ///Gets declaration id VISA_SamplerVar
    VISA_BUILDER_API virtual int getDeclarationID(VISA_SamplerVar *decl) const = 0;

    ///Gets declaration id VISA_SurfaceVar
    VISA_BUILDER_API virtual int getDeclarationID(VISA_SurfaceVar *decl) const = 0;

    ///Gets declaration id VISA_LabelVar
    VISA_BUILDER_API virtual int getDeclarationID(VISA_LabelVar *decl) const = 0;

    ///Gets visa instruction counter value
    VISA_BUILDER_API virtual unsigned getvIsaInstCount() const = 0;

    //Gets the VISA string format for the variable
    VISA_BUILDER_API virtual std::string getVarName(VISA_GenVar* decl) const = 0;
    VISA_BUILDER_API virtual std::string getVarName(VISA_PredVar* decl) const = 0;
    VISA_BUILDER_API virtual std::string getVarName(VISA_AddrVar* decl) const = 0;
    VISA_BUILDER_API virtual std::string getVarName(VISA_SurfaceVar* decl) const = 0;
    VISA_BUILDER_API virtual std::string getVarName(VISA_SamplerVar* decl) const = 0;

    //Gets the VISA string format for the operand
    VISA_BUILDER_API virtual std::string getVectorOperandName(VISA_VectorOpnd* opnd, bool showRegion) const = 0;
    VISA_BUILDER_API virtual std::string getPredicateOperandName(VISA_PredOpnd* opnd) const = 0;

    /// getGenSize -- Get gen binary size of this kernel/function
    VISA_BUILDER_API virtual int64_t getGenSize() const = 0;

    VISA_BUILDER_API virtual unsigned getNumRegTotal() const = 0;

    /// getVISAAsm -- Get the compiled .visaasm of the kernel.
    VISA_BUILDER_API virtual std::string getVISAAsm() const = 0;
};

class VISAFunction : public VISAKernel
{
public:
    /// SetFunctionInputSize -- Set only for VISAFunction objects.
    /// This value should be set to size of arg pre-defined register.
    VISA_BUILDER_API virtual int SetFunctionInputSize(unsigned int size) = 0;

    /// SetFunctionReturnSize -- Set only for VISAFunction objects.
    /// This value should be set to size of ret pre-defined register.
    VISA_BUILDER_API virtual int SetFunctionReturnSize(unsigned int size) = 0;

    /// GetFunctionId -- Get function id for a stack call function VISAFunction instance.
    /// This id is used by API client for invoking correct stack function using fcall.
    VISA_BUILDER_API virtual int GetFunctionId(unsigned int& id) const = 0;

    /// getGenOffset -- Get gen binary offset of this function
    VISA_BUILDER_API virtual int64_t getGenOffset() const = 0;

    /// getFunctionName -- Get function name.
    VISA_BUILDER_API virtual const char* getFunctionName() const = 0;
};

typedef enum
{
    VISA_BUILDER_VISA,
    VISA_BUILDER_GEN,
    VISA_BUILDER_BOTH
} VISA_BUILDER_OPTION;

class VISABuilder
{
public:
    VISA_BUILDER_API virtual int AddKernel(VISAKernel *& kernel, const char* kernelName) = 0;
    VISA_BUILDER_API virtual int SetPrevKernel(VISAKernel*& prevKernel) = 0;
    VISA_BUILDER_API virtual int AddFunction(VISAFunction *& function, const char* functionName) = 0;
    VISA_BUILDER_API virtual int AddPayloadSection(VISAFunction *& function, const char* functionName) = 0;
    VISA_BUILDER_API virtual int Compile(const char * isaFileNameint, std::ostream* os = nullptr, bool emit_visa_only = false) = 0;

    VISA_BUILDER_API virtual void SetOption(vISAOptions option, bool val) = 0;
    VISA_BUILDER_API virtual void SetOption(vISAOptions option, uint32_t val) = 0;
    VISA_BUILDER_API virtual void SetOption(vISAOptions option, const char *val) = 0;

    // For inline asm code generation
    VISA_BUILDER_API virtual int ParseVISAText(const std::string& visaText, const std::string& visaTextFile) = 0;
    VISA_BUILDER_API virtual int ParseVISAText(const std::string& visaFile) = 0;
    VISA_BUILDER_API virtual std::stringstream& GetAsmTextStream() = 0;
    VISA_BUILDER_API virtual VISAKernel* GetVISAKernel(const std::string& kernelName = "") const = 0;
    VISA_BUILDER_API virtual int ClearAsmTextStreams() = 0;
    VISA_BUILDER_API virtual std::string GetCriticalMsg() = 0;
};
#endif
