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

Copyright (C) 2017-2021 Intel Corporation

SPDX-License-Identifier: MIT

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

#ifndef _VISA_IGC_COMMON_HEADER_H_
#define _VISA_IGC_COMMON_HEADER_H_


typedef enum
{
    vISA_DEFAULT,   // default mode: input is in-memory IR or vISA binary
    vISA_ASM_WRITER,    // mode for inline asm: input is in-memory IR + inline vISA assembly, output is vISA text
    vISA_ASM_READER     // mode for visa text input
} vISABuilderMode;

typedef enum
{
    PREDEFINED_NULL             = 0,
    PREDEFINED_X                = 1,
    PREDEFINED_Y                = 2,
    PREDEFINED_GROUP_ID_X       = 3,
    PREDEFINED_GROUP_ID_Y       = 4,
    PREDEFINED_GROUP_ID_Z       = 5,
    PREDEFINED_TSC              = 6,
    PREDEFINED_R0               = 7,
    PREDEFINED_ARG              = 8,
    PREDEFINED_RET              = 9,
    PREDEFINED_FE_SP            = 10,
    PREDEFINED_FE_FP            = 11,
    PREDEFINED_HW_TID           = 12,
    PREDEFINED_SR0              = 13,
    PREDEFINED_CR0              = 14,
    PREDEFINED_CE0              = 15,
    PREDEFINED_DBG              = 16,
    PREDEFINED_COLOR            = 17,
    PREDEFINED_IMPL_ARG_BUF_PTR = 18,
    PREDEFINED_LOCAL_ID_BUF_PTR = 19,
    PREDEFINED_VAR_LAST         = PREDEFINED_LOCAL_ID_BUF_PTR
} PreDefined_Vars;

typedef enum
{
    // FIXME: why not expose PREDEF_SURF_0 etc. directly?
    PREDEFINED_SURFACE_SLM = 0,
    PREDEFINED_SURFACE_STACK = 1,
    PREDEFINED_SURFACE_SCRATCH = 3,
    PREDEFINED_SURFACE_T252 = 4,
    PREDEFINED_SURFACE_T255 = 5,
    PREDEFINED_SURFACE_LAST = PREDEFINED_SURFACE_T255
} PreDefined_Surface;

typedef enum {
    ATOMIC_ADD                     = 0x0,
    ATOMIC_SUB                     = 0x1,
    ATOMIC_INC                     = 0x2,
    ATOMIC_DEC                     = 0x3,
    ATOMIC_MIN                     = 0x4,
    ATOMIC_MAX                     = 0x5,
    ATOMIC_XCHG                    = 0x6,
    ATOMIC_CMPXCHG                 = 0x7,
    ATOMIC_AND                     = 0x8,
    ATOMIC_OR                      = 0x9,
    ATOMIC_XOR                     = 0xa,
    ATOMIC_IMIN                    = 0xb,
    ATOMIC_IMAX                    = 0xc,
    ATOMIC_PREDEC                  = 0xd,
    ATOMIC_FMAX                    = 0x10,
    ATOMIC_FMIN                    = 0x11,
    ATOMIC_FCMPWR                  = 0x12,
    ATOMIC_FADD                    = 0x13,
    ATOMIC_FSUB                    = 0x14,
    ATOMIC_UNDEF
} VISAAtomicOps;

/*
 * Various enumerations representing the binary encoding definitions for the common ISA
 *
 */
 typedef enum : unsigned char {
     ISA_TYPE_UD    = 0x0,
     ISA_TYPE_D     = 0x1,
     ISA_TYPE_UW    = 0x2,
     ISA_TYPE_W     = 0x3,
     ISA_TYPE_UB    = 0x4,
     ISA_TYPE_B     = 0x5,
     ISA_TYPE_DF    = 0x6,
     ISA_TYPE_F     = 0x7,
     ISA_TYPE_V     = 0x8,
     ISA_TYPE_VF    = 0x9,
     ISA_TYPE_BOOL  = 0xA,
     ISA_TYPE_UQ    = 0xB,
     ISA_TYPE_UV    = 0xC,
     ISA_TYPE_Q     = 0xD,
     ISA_TYPE_HF    = 0xE,
     ISA_TYPE_BF    = 0xF,
     ISA_TYPE_NUM
 } VISA_Type ;

 typedef struct {
    VISA_Type CISAType;
    const char* typeName;
    int typeSize;
} CISATypeInfo;

extern CISATypeInfo CISATypeTable[ISA_TYPE_NUM];

typedef enum {
    ALIGN_UNDEF   = 0x0,
    ALIGN_BYTE    = 0x0,
    ALIGN_WORD    = 0x1,
    ALIGN_DWORD   = 0x2,
    ALIGN_QWORD   = 0x3,
    ALIGN_OWORD   = 0x4,
    ALIGN_GRF     = 0x5,
    ALIGN_2_GRF   = 0x6,
    ALIGN_HWORD   = 0x7,
    ALIGN_32WORD  = 0x8,
    ALIGN_64WORD  = 0x9,

    ALIGN_TOTAL_NUM = 0xA
} VISA_Align;

typedef enum {
    LABEL_BLOCK = 0x0,
    LABEL_SUBROUTINE = 0x1,
    LABEL_FC = 0x2,
    LABEL_FUNCTION = 0x3
} VISA_Label_Kind;

typedef enum {
    ISA_CMP_E = 0,         /* Zero or Equal */
    ISA_CMP_NE,        /* Not Zero or Not Equal */
    ISA_CMP_G,         /* Greater-than */
    ISA_CMP_GE,        /* Greater-than-or-equal */
    ISA_CMP_L,         /* Less-than */
    ISA_CMP_LE,        /* Less-than-or-equal */
    ISA_CMP_UNDEF
} VISA_Cond_Mod;

typedef enum {
    MODIFIER_NONE = 0x0,
    MODIFIER_ABS = 0x1,
    MODIFIER_NEG = 0x2,
    MODIFIER_NEG_ABS = 0x3,
    MODIFIER_SAT = 0x4,
    MODIFIER_NOT = 0x5  //BDW only
} VISA_Modifier;

typedef enum {
    PredState_NO_INVERSE = 0,
    PredState_INVERSE = 1
} VISA_PREDICATE_STATE;

typedef enum {
    EXEC_SIZE_1 = 0x0,
    EXEC_SIZE_2 = 0x1,
    EXEC_SIZE_4 = 0x2,
    EXEC_SIZE_8 = 0x3,
    EXEC_SIZE_16 = 0x4,
    EXEC_SIZE_32 = 0x5,
    EXEC_SIZE_ILLEGAL = 0x6
} VISA_Exec_Size;

// predicate control
// Currently only support Any and all
typedef enum {
    PRED_CTRL_NON = 0x0,
    PRED_CTRL_ANY = 0x1,
    PRED_CTRL_ALL = 0x2,
    PRED_CTRL_UNDEF
} VISA_PREDICATE_CONTROL;

typedef enum {
    vISA_EMASK_M1       = 0,
    vISA_EMASK_M2       = 1,
    vISA_EMASK_M3       = 2,
    vISA_EMASK_M4       = 3,
    vISA_EMASK_M5       = 4,
    vISA_EMASK_M6       = 5,
    vISA_EMASK_M7       = 6,
    vISA_EMASK_M8       = 7,
    vISA_EMASK_M1_NM    = 8,
    vISA_EMASK_M2_NM    = 9,
    vISA_EMASK_M3_NM    = 10,
    vISA_EMASK_M4_NM    = 11,
    vISA_EMASK_M5_NM    = 12,
    vISA_EMASK_M6_NM    = 13,
    vISA_EMASK_M7_NM    = 14,
    vISA_EMASK_M8_NM    = 15,
    vISA_NUM_EMASK      = 16
} VISA_EMask_Ctrl;

typedef enum {
    OWORD_NUM_1 = 0x0,
    OWORD_NUM_2 = 0x1,
    OWORD_NUM_4 = 0x2,
    OWORD_NUM_8 = 0x3,
    OWORD_NUM_16 = 0x4,
    OWORD_NUM_ILLEGAL = 0x5
} VISA_Oword_Num;

// media load inst modifiers
typedef enum {
    MEDIA_LD_nomod = 0x0,
    MEDIA_LD_modified = 0x1,
    MEDIA_LD_top = 0x2,
    MEDIA_LD_bottom = 0x3,
    MEDIA_LD_top_mod = 0x4,
    MEDIA_LD_bottom_mod = 0x5,
    MEDIA_LD_Mod_NUM
} MEDIA_LD_mod;

typedef enum {
    VME_OP_MODE_INTER = 0x0,
    VME_OP_MODE_INTRA = 0x1,
    VME_OP_MODE_ALL = 0x2,
    VME_OP_MODE_NUM = 0x3
} COMMON_ISA_VME_OP_MODE;

typedef enum {
    VME_STREAM_DISABLE = 0,
    VME_STREAM_OUT     = 1,
    VME_STREAM_IN      = 2,
    VME_STREAM_IN_OUT  = 3
} COMMON_ISA_VME_STREAM_MODE;

typedef enum {
    VME_SEARCH_SINGLE_REF_SINGLE_REC_SINGLE_START = 0,
    VME_SEARCH_SINGLE_REF_SINGLE_REC_DUAL_START   = 1,
    VME_SEARCH_SINGLE_REF_DUAL_REC                = 3,
    VME_SEARCH_DUAL_REF_DUAL_REC                  = 7
} COMMON_ISA_VME_SEARCH_CTRL;

typedef enum
{
    CISA_DM_FMIN = 0,
    CISA_DM_FMAX = 1
} CISA_MIN_MAX_SUB_OPCODE;

typedef enum
{
    CISA_PLANE_Y = 0,
    CISA_PLANE_UV = 1,
    CISA_PLANE_V = 2
} CISA_PLANE_ID;

typedef enum {
    /* 0x0 reserved -- used for illegal/nop op? */
    ISA_RESERVED_0         = 0x0 ,
    ISA_ADD                = 0x1 ,
    ISA_AVG                = 0x2 ,
    ISA_DIV                = 0x3 ,
    ISA_DP2                = 0x4 ,
    ISA_DP3                = 0x5 ,
    ISA_DP4                = 0x6 ,
    ISA_DPH                = 0x7 ,
    ISA_EXP                = 0x8 ,
    ISA_FRC                = 0x9 ,
    ISA_LINE               = 0xA ,
    ISA_LOG                = 0xB ,
    ISA_MAD                = 0xC ,
    ISA_MULH               = 0xD ,
    ISA_LRP                = 0xE ,
    ISA_MOD                = 0xF ,
    ISA_MUL                = 0x10,
    ISA_POW                = 0x11,
    ISA_RNDD               = 0x12,
    ISA_RNDU               = 0x13,
    ISA_RNDE               = 0x14,
    ISA_RNDZ               = 0x15,
    ISA_SAD2               = 0x16,
    ISA_SIN                = 0x17,
    ISA_COS                = 0x18,
    ISA_SQRT               = 0x19,
    ISA_RSQRT              = 0x1A,
    ISA_INV                = 0x1B,
    ISA_DPASW              = 0x1C,
    ISA_FCVT               = 0x1D,
    ISA_QF_CVT             = ISA_FCVT,  // temp for cmc
    ISA_SRND               = 0x1E,
    ISA_LZD                = 0x1F,
    ISA_AND                = 0x20,
    ISA_OR                 = 0x21,
    ISA_XOR                = 0x22,
    ISA_NOT                = 0x23,
    ISA_SHL                = 0x24,
    ISA_SHR                = 0x25,
    ISA_ASR                = 0x26,
    ISA_CBIT               = 0x27,
    ISA_ADDR_ADD           = 0x28,
    ISA_MOV                = 0x29,
    ISA_SEL                = 0x2A,
    ISA_SETP               = 0x2B,
    ISA_CMP                = 0x2C,
    ISA_MOVS               = 0x2D,
    ISA_FBL                = 0x2E,
    ISA_FBH                = 0x2F,
    ISA_SUBROUTINE         = 0x30,
    ISA_LABEL              = 0x31,
    ISA_JMP                = 0x32,
    ISA_CALL               = 0x33,
    ISA_RET                = 0x34,
    ISA_OWORD_LD           = 0x35,
    ISA_OWORD_ST           = 0x36,
    ISA_MEDIA_LD           = 0x37,
    ISA_MEDIA_ST           = 0x38,
    ISA_GATHER             = 0x39,
    ISA_SCATTER            = 0x3A,
    ISA_RESERVED_3B        = 0x3B,
    ISA_OWORD_LD_UNALIGNED = 0x3C,
    ISA_RESERVED_3D        = 0x3D,
    ISA_RESERVED_3E        = 0x3E,
    ISA_RESERVED_3F        = 0x3F,
    ISA_SAMPLE             = 0x40,
    ISA_SAMPLE_UNORM       = 0x41,
    ISA_LOAD               = 0x42,
    ISA_AVS                = 0x43,
    ISA_VA                 = 0x44,
    ISA_FMINMAX            = 0x45,
    ISA_BFE                = 0x46,
    ISA_BFI                = 0x47,
    ISA_BFREV              = 0x48,
    ISA_ADDC               = 0x49,
    ISA_SUBB               = 0x4A,
    ISA_GATHER4_TYPED      = 0x4B,
    ISA_SCATTER4_TYPED     = 0x4C,
    ISA_VA_SKL_PLUS        = 0x4D,
    ISA_SVM                = 0x4E,
    ISA_IFCALL             = 0x4F,
    ISA_FADDR              = 0x50,
    ISA_FILE               = 0x51,
    ISA_LOC                = 0x52,
    ISA_RESERVED_53        = 0x53,
    ISA_VME_IME            = 0x54,
    ISA_VME_SIC            = 0x55,
    ISA_VME_FBR            = 0x56,
    ISA_VME_IDM            = 0x57,
    ISA_RESERVED_58        = 0x58,
    ISA_BARRIER            = 0x59,
    ISA_SAMPLR_CACHE_FLUSH = 0x5A,
    ISA_WAIT               = 0x5B,
    ISA_FENCE              = 0x5C,
    ISA_RAW_SEND           = 0x5D,
    ISA_RESERVED_5E        = 0x5E,
    ISA_YIELD              = 0x5F,
    ISA_NBARRIER           = 0x60,
    ISA_RESERVED_61        = 0x61,
    ISA_RESERVED_62        = 0x62,
    ISA_RESERVED_63        = 0x63,
    ISA_RESERVED_64        = 0x64,
    ISA_RESERVED_65        = 0x65,
    ISA_RESERVED_66        = 0x66,
    ISA_FCALL              = 0x67,
    ISA_FRET               = 0x68,
    ISA_SWITCHJMP          = 0x69,
    ISA_SAD2ADD            = 0x6A,
    ISA_PLANE              = 0x6B,
    ISA_GOTO               = 0x6C,
    ISA_3D_SAMPLE          = 0x6D,
    ISA_3D_LOAD            = 0x6E,
    ISA_3D_GATHER4         = 0x6F,
    ISA_3D_INFO            = 0x70,
    ISA_3D_RT_WRITE        = 0x71,
    ISA_3D_URB_WRITE       = 0x72,
    ISA_3D_TYPED_ATOMIC    = 0x73,
    ISA_GATHER4_SCALED     = 0x74,
    ISA_SCATTER4_SCALED    = 0x75,
    ISA_RESERVED_76        = 0x76,
    ISA_RESERVED_77        = 0x77,
    ISA_GATHER_SCALED      = 0x78,
    ISA_SCATTER_SCALED     = 0x79,
    ISA_RAW_SENDS          = 0x7A,
    ISA_LIFETIME           = 0x7B,
    ISA_SBARRIER           = 0x7C,
    ISA_DWORD_ATOMIC       = 0x7D,
    ISA_SQRTM              = 0x7E,
    ISA_DIVM               = 0x7F,
    ISA_ROL                = 0x80,
    ISA_ROR                = 0x81,
    ISA_DP4A               = 0x82,
    ISA_DPAS               = 0x83,
    ISA_ADD3               = 0x84,
    ISA_BFN                = 0x85,
    ISA_QW_GATHER          = 0x86,
    ISA_QW_SCATTER         = 0x87,
    ISA_BF_CVT             = 0x88,
    ISA_LSC_UNTYPED        = 0x89,
    ISA_LSC_TYPED          = 0x8A,
    ISA_LSC_FENCE          = 0x8B,
    ISA_RESERVED_8C        = 0x8C,
    ISA_RESERVED_8D        = 0x8D,
    ISA_RESERVED_8E        = 0x8E,
    ISA_RESERVED_8F        = 0x8F,
    ISA_RESERVED_90        = 0x90,
    ISA_MADW               = 0x91,
    ISA_ADD3O              = 0x92,
    ISA_NUM_OPCODE,
    ISA_OPCODE_ENUM_SIZE   = 0xFF
} ISA_Opcode;

typedef enum
{
    VISA_3D_SAMPLE          = 0,
    VISA_3D_SAMPLE_B        = 1,
    VISA_3D_SAMPLE_L        = 2,
    VISA_3D_SAMPLE_C        = 3,
    VISA_3D_SAMPLE_D        = 4,
    VISA_3D_SAMPLE_B_C      = 5,
    VISA_3D_SAMPLE_L_C      = 6,
    VISA_3D_LD              = 7,
    VISA_3D_GATHER4         = 8,
    VISA_3D_LOD             = 9,
    VISA_3D_RESINFO         = 10,
    VISA_3D_SAMPLEINFO      = 11,
    VISA_3D_SAMPLE_KILLPIX  = 12,
    VISA_3D_GATHER4_C       = 16,
    VISA_3D_GATHER4_PO      = 17,
    VISA_3D_GATHER4_PO_C    = 18,
    VISA_3D_SAMPLE_D_C      = 20,
    VISA_3D_SAMPLE_LZ       = 24,
    VISA_3D_SAMPLE_C_LZ     = 25,
    VISA_3D_LD_LZ           = 26,
    VISA_3D_LD2DMS_W        = 28,
    VISA_3D_LD_MCS          = 29,
    // positional offsets
    VISA_3D_TOTAL_NUM_OPS,
} VISASampler3DSubOpCode;

typedef enum {
    CHANNEL_MASK_NOMASK = 0x0,
    CHANNEL_MASK_R = 0x1,
    CHANNEL_MASK_G = 0x2,
    CHANNEL_MASK_RG = 0x3,
    CHANNEL_MASK_B = 0x4,
    CHANNEL_MASK_RB = 0x5,
    CHANNEL_MASK_GB = 0x6,
    CHANNEL_MASK_RGB = 0x7,
    CHANNEL_MASK_A = 0x8,
    CHANNEL_MASK_RA = 0x9,
    CHANNEL_MASK_GA = 0xa,
    CHANNEL_MASK_RGA = 0xb,
    CHANNEL_MASK_BA = 0xc,
    CHANNEL_MASK_RBA = 0xd,
    CHANNEL_MASK_GBA = 0xe,
    CHANNEL_MASK_RGBA = 0xf,
    CHANNEL_MASK_NUM
} VISAChannelMask;

typedef enum {
    CHANNEL_16_BIT_FULL        = 0,
    CHANNEL_16_BIT_DOWNSAMPLED = 1,
    CHANNEL_8_BIT_FULL         = 2,
    CHANNEL_8_BIT_DOWNSAMPLED  = 3,
    CHANNEL_OUTPUT_NUM         = 4
} CHANNEL_OUTPUT_FORMAT ;

typedef enum
{
    VISA_3D_GATHER4_CHANNEL_R = 0,
    VISA_3D_GATHER4_CHANNEL_G = 1,
    VISA_3D_GATHER4_CHANNEL_B = 2,
    VISA_3D_GATHER4_CHANNEL_A = 3
} VISASourceSingleChannel;

typedef enum {
    GENX_NONE = -1,
    GENX_BDW,
    GENX_CHV,
    GENX_SKL,
    GENX_BXT,
    GENX_CNL,
    GENX_ICLLP,
    GENX_TGLLP,
    Xe_XeHPSDV,
    Xe_DG2,
    Xe_PVC,
    Xe_PVCXT,
    ALL
} TARGET_PLATFORM;

// gather/scatter element size
typedef enum {
    GATHER_SCATTER_BYTE = 0x0,
    GATHER_SCATTER_WORD = 0x1,
    GATHER_SCATTER_DWORD = 0x2,
    GATHER_SCATTER_BYTE_UNDEF
} GATHER_SCATTER_ELEMENT_SIZE;

/// Sampler8x8 DevBDW+ Functionality Opcodes
typedef enum VA_fopcode
{
    AVS_FOPCODE                       = 0x00,
    Convolve_FOPCODE                  = 0x01,
    MINMAX_FOPCODE                    = 0x02,
    MINMAXFILTER_FOPCODE              = 0x03,
    ERODE_FOPCODE                     = 0x04,
    Dilate_FOPCODE                    = 0x05,
    BoolCentroid_FOPCODE              = 0x06,
    Centroid_FOPCODE                  = 0x07,
    VA_OP_CODE_1D_CONVOLVE_VERTICAL   = 0x08,
    VA_OP_CODE_1D_CONVOLVE_HORIZONTAL = 0x09,
    VA_OP_CODE_1PIXEL_CONVOLVE        = 0x0A,
    VA_OP_CODE_FLOOD_FILL             = 0x0B,
    VA_OP_CODE_LBP_CREATION           = 0x0C,
    VA_OP_CODE_LBP_CORRELATION        = 0x0D,
    VA_OP_CODE_NONE                   = 0x0E,
    VA_OP_CODE_CORRELATION_SEARCH     = 0x0F,
    ISA_HDC_CONV                      = 0x10,
    ISA_HDC_MMF                       = 0x11,
    ISA_HDC_ERODE                     = 0x12,
    ISA_HDC_DILATE                    = 0x13,
    ISA_HDC_LBPCORRELATION            = 0x14,
    ISA_HDC_LBPCREATION               = 0x15,
    ISA_HDC_1DCONV_H                  = 0x16,
    ISA_HDC_1DCONV_V                  = 0x17,
    ISA_HDC_1PIXELCONV                = 0x18,
    VA_OP_CODE_UNDEFINED              = 0x19
} ISA_VA_Sub_Opcode;

typedef enum _OutputFormatControl_
{   AVS_16_FULL        = 0,
    AVS_16_DOWN_SAMPLE = 1,
    AVS_8_FULL         = 2,
    AVS_8_DOWN_SAMPLE  = 3
} OutputFormatControl;

typedef enum _AVSExecMode_
{   AVS_16x4 = 0,
    AVS_8x4  = 1,
    AVS_16x8 = 2,
    AVS_4x4  = 3
} AVSExecMode;

typedef enum _MMFExecMode_
{   VA_MMF_16x4 = 0,
    VA_MMF_16x1 = 2,
    VA_MMF_1x1  = 3
} MMFExecMode;

typedef enum _MMFEnableMode_
{   VA_MINMAX_ENABLE = 0,
    VA_MAX_ENABLE    = 1,
    VA_MIN_ENABLE    = 2
} MMFEnableMode;

typedef enum _CONVExecMode_
{   VA_CONV_16x4 = 0,
    VA_CONV_16x1 = 2
} CONVExecMode;

typedef enum _EDExecMode_
{   VA_ED_64x4 = 0,
    VA_ED_32x4 = 1,
    VA_ED_64x1 = 2,
    VA_ED_32x1 = 3
} EDExecMode;

typedef enum _EDMode_
{   VA_ERODE  = 4,
    VA_DILATE = 5
} EDMode;

typedef enum _LBPCreationMode_
{
    VA_3x3_AND_5x5  = 0,
    VA_3x3          = 1,
    VA_5x5          = 2
} LBPCreationMode;

typedef enum _Convolve1DDirection_
{
    VA_H_DIRECTION = 0,
    VA_V_DIRECTION = 1
} Convolve1DDirection;

typedef enum _CONV1PixelExecMode_
{   VA_CONV1P_16x4 = 0,
    VA_CONV1P_16x1 = 2,
    VA_CONV1P_1x1  = 3
} CONV1PixelExecMode;

typedef enum _HDCReturnFormat_
{
    VA_HDC_CONVOVLE_Y16 = 0,
    VA_HDC_CONVOLVE_Y8  = 1
} HDCReturnFormat;

typedef enum _CONVHDCRegionSize_
{
    VA_HDC_CONVOLVE_15x15 = 0,
    VA_HDC_CONVOLVE_31x31 = 1
} CONVHDCRegionSize;

typedef enum
{
    SVM_BLOCK_NUM_1 = 0x0,
    SVM_BLOCK_NUM_2 = 0x1,
    SVM_BLOCK_NUM_4 = 0x2,
    SVM_BLOCK_NUM_8 = 0x3
} VISA_SVM_Block_Num;

typedef enum
{
    SVM_BLOCK_TYPE_BYTE  = 0x0,
    SVM_BLOCK_TYPE_DWORD = 0x1,
    SVM_BLOCK_TYPE_QWORD = 0x2
} VISA_SVM_Block_Type;


typedef struct _vISA_RT_CONTROLS
{
    unsigned s0aPresent:1;  //src0 Alpha
    unsigned oMPresent:1;   //oMask
    unsigned zPresent:1;    //depth
    unsigned RTIndexPresent : 1; // Whether need to set RTIndex in header
    unsigned isLastWrite:1; //is last RT Write, sets Last Render Target Select bit
    unsigned isPerSample:1;  //Enables Per Sample Render Target Write
    unsigned isStencil:1;
    unsigned isCoarseMode:1; //controls coasrse mode bit inmsg descriptor
    unsigned isSampleIndex : 1; //controls whether sampleIndex is used.
    unsigned isHeaderMaskfromCe0 : 1;
    unsigned isNullRT : 1;   // null render target
} vISA_RT_CONTROLS;

typedef enum
{
    LIFETIME_START = 0,
    LIFETIME_END = 1
} VISAVarLifetime;

enum class GenPrecision : unsigned char
{
    INVALID = 0,

    U1 = 1,
    S1 = 2,
    U2 = 3,
    S2 = 4,
    U4 = 5,
    S4 = 6,
    U8 = 7,
    S8 = 8,
    BF16 = 9,   // bfloat16 (1, 8, 7)
    FP16 = 10,  // half (1, 5, 10)
    TF32 = 12,  // TensorFloat (1, 8, 10), 19 bits
    TOTAL_NUM
};

///////////////////////////////////////////////////////////////////////////////
// Data types to support LSC load/store messages.
//

// The size of each data element
enum LSC_DATA_SIZE {
    LSC_DATA_SIZE_INVALID,
    LSC_DATA_SIZE_8b,       // DATA:u8...
    LSC_DATA_SIZE_16b,      // DATA:u16...
    LSC_DATA_SIZE_32b,      // DATA:u32...
    LSC_DATA_SIZE_64b,      // DATA:u64...
    // data types supporting conversion on load
    // 8c32b reads load (8) bits, (c)onvert to (32) bits (zero extending)
    // store truncates
    //
    // In DG2 and PVC the upper bits are undefined.
    LSC_DATA_SIZE_8c32b,    // DATA:u8c32...   (zero-extend / truncate)
    LSC_DATA_SIZE_16c32b,   // DATA:u16c32..   (zero-extend / truncate)
    LSC_DATA_SIZE_16c32bH,  // DATA:u16c32h..  h means load to (h)igh 16
                            // data stored in upper 16; zero-fills bottom 16
                            // (bfloat raw conversion to 32b float)
};

// The number of elements per address ("vector" size)
enum LSC_DATA_ELEMS {
    LSC_DATA_ELEMS_INVALID,
    LSC_DATA_ELEMS_1,       // DATA:..x1
    LSC_DATA_ELEMS_2,       // DATA:..x2
    LSC_DATA_ELEMS_3,       // DATA:..x3
    LSC_DATA_ELEMS_4,       // DATA:..x4
    LSC_DATA_ELEMS_8,       // DATA:..x8
    LSC_DATA_ELEMS_16,      // DATA:..x16
    LSC_DATA_ELEMS_32,      // DATA:..x32
    LSC_DATA_ELEMS_64,      // DATA:..x64
};

enum LSC_DATA_ORDER {
    LSC_DATA_ORDER_INVALID,
    LSC_DATA_ORDER_NONTRANSPOSE,
    LSC_DATA_ORDER_TRANSPOSE,     // DATA:...t
};

enum LSC_DATA_CHMASK {
  LSC_DATA_CHMASK_INVALID,
  LSC_DATA_CHMASK_X = 1 << 0,
  LSC_DATA_CHMASK_Y = 1 << 1,
  LSC_DATA_CHMASK_Z = 1 << 2,
  LSC_DATA_CHMASK_W = 1 << 3,
};

struct LSC_DATA_SHAPE {
    LSC_DATA_SIZE       size;
    LSC_DATA_ORDER      order;
    union {
        LSC_DATA_ELEMS  elems; // all other operations use the regular vector
        int             chmask; // for LSC_*_QUAD; bitmask of LSC_DATA_CHMASK
    };
};

struct LSC_DATA_SHAPE_BLOCK2D {
    LSC_DATA_SIZE   size;
    LSC_DATA_ORDER  order;
    int             blocks; // the count of 2d blocks to load (array len)
    int             width; // the width (in elems) of the 2d region
    int             height; // the height (in elems) of the 2d region
    bool            vnni;  // perform a vnni transform on load
};
static const unsigned LSC_BLOCK2D_ADDR_PARAMS = 6;

enum LSC_ADDR_SIZE {
    LSC_ADDR_SIZE_INVALID,
    LSC_ADDR_SIZE_16b,  // [ADDR]:a16
    LSC_ADDR_SIZE_32b,  // [ADDR]:a32
    LSC_ADDR_SIZE_64b,  // [ADDR]:a64
};
enum LSC_ADDR_TYPE {
    LSC_ADDR_TYPE_INVALID,
    LSC_ADDR_TYPE_FLAT, // aka "stateless"
    LSC_ADDR_TYPE_BSS,  // bindless surface state offset
    LSC_ADDR_TYPE_SS,   // surface state offset
    LSC_ADDR_TYPE_BTI,  // binding table interface (legacy)
    //
    // Pseudo address types
    LSC_ADDR_TYPE_ARG,  // built-in surface access to kernel arguments
};

//
// Caching override behavior
//
// We support all combinations in IR, though not all are supported in hardware
// https://gfxspecs.intel.com/Predator/Home/Index/53560
typedef enum {
    LSC_CACHING_DEFAULT,        // .df
    LSC_CACHING_UNCACHED,       // .uc
    LSC_CACHING_CACHED,         // .ca
    LSC_CACHING_WRITEBACK,      // .wb
    LSC_CACHING_WRITETHROUGH,   // .wt
    LSC_CACHING_STREAMING,      // .st
    LSC_CACHING_READINVALIDATE, // .ri last use / invalidate after read

} LSC_CACHE_OPT;
// Only some combinations are legal (per platform)
struct LSC_CACHE_OPTS {
    LSC_CACHE_OPT l1;
    LSC_CACHE_OPT l3;
};

// L1,L3 available cache policies combinations
// Auxiliary enums for cache options translation from intrinsics into
// vISA representation.
typedef enum {
    LSC_L1DEF_L3DEF = 0,
    LSC_L1UC_L3UC,          //  Load: L1 uncached   L3 uncached # Store: L1 uncached      L3 uncached
    LSC_L1UC_L3C_WB,        //  Load: L1 uncached   L3 cached   # Store: L1 uncached      L3 write-back
    LSC_L1C_WT_L3UC,        //  Load: L1 cached     L3 uncached # Store: L1 write-through L3 uncached
    LSC_L1C_WT_L3C_WB,      //  Load: L1 cached     L3 cached   # Store: L1 write-through L3 write-back
    LSC_L1S_L3UC,           //  Load: L1 streaming  L3 uncached # Store: L1 streaming     L3 uncached
    LSC_L1S_L3C_WB,         //  Load: L1 streaming  L3 cached   # Store: L1 streaming     L3 write-back

    LSC_L1IAR_WB_L3C_WB,    //  Load: L1 invalidate after read L3 cached # Store: L1 write-back L3 write-back
    LSC_CC_INVALID,
} LSC_L1_L3_CC;

// Groups all the necessary address into a product type
struct LSC_ADDR {
    // The address model being used (e.g. flat, bti, bss, ss)
    LSC_ADDR_TYPE       type;

    // An optional uniform immediate scale.  Default this to 1 if
    // scaling is not desired (or supported).  0 is an illegal value here.
    int                 immScale;

    // An optional uniform immediate offset; for the given address model,
    // if hardware supports this and the value is small enough to fit in the
    // descriptor, then it can be fused into the operation.  Conversely, if the
    // immediate value is too big or immediate offsets are not supported for
    // the given address type or device, codegen will generate separate adds
    // to the address.
    //
    // This value is intended to be pre-scaled and 'immScale'
    // doesn't impact it. I.e. the effective address is
    //   EA = immScale * ADDR + immOffset (result in bytes)
    int                 immOffset; // [...+0x100] (can be 0)

    // The number of bits per address; not all address models support all sizes
    LSC_ADDR_SIZE       size; // e.g. :a64, :a32, ...
};

// The specific fence op
enum LSC_FENCE_OP {
    LSC_FENCE_OP_NONE,    // .none
    LSC_FENCE_OP_EVICT,   // .evict (dirty lines evicted and invalided;
                          // clean lines are invalidated)
    LSC_FENCE_OP_INVALIDATE, // .invalidate (inv. all clean lines; don't evict)
    LSC_FENCE_OP_DISCARD, // .discard (dirty and clean lines written,
                          // but stay in cache)
    LSC_FENCE_OP_CLEAN,   // .clean
    LSC_FENCE_OP_FLUSHL3, // .flushl3 (flush L3 only, but not L1)
    LSC_FENCE_OP_TYPE6    // .flushtype6
};

// The scope of a given IO operation (typically fence)
enum LSC_SCOPE {
    LSC_SCOPE_GROUP,  // .group  (thread group)
    LSC_SCOPE_LOCAL,  // .local (dss?)
    LSC_SCOPE_TILE,   // .tile
    LSC_SCOPE_GPU,    // .gpu
    LSC_SCOPE_GPUS,   // .gpus
    LSC_SCOPE_SYSREL, // .sysrel
    LSC_SCOPE_SYSACQ, // .sysacq
};

// The subset of SFIDs that are permitted for LSC messages
enum LSC_SFID {
    LSC_UGM,  // .ugm
    LSC_UGML, // .ugml
    LSC_TGM,  // .tgm
    LSC_SLM,  // .slm
};

enum LSC_OP {
  LSC_LOAD          = 0x00,
  LSC_LOAD_STRIDED  = 0x01, // aka "load_block"
  LSC_LOAD_QUAD     = 0x02, // aka "load_cmask"
  LSC_LOAD_BLOCK2D  = 0x03,
  LSC_STORE         = 0x04,
  LSC_STORE_STRIDED = 0x05, // aka "load_block"
  LSC_STORE_QUAD    = 0x06, // aka "store_cmask"
  LSC_STORE_BLOCK2D = 0x07,
  //
  LSC_ATOMIC_IINC  = 0x08,
  LSC_ATOMIC_IDEC  = 0x09,
  LSC_ATOMIC_LOAD  = 0x0A,
  LSC_ATOMIC_STORE = 0x0B,
  LSC_ATOMIC_IADD  = 0x0C,
  LSC_ATOMIC_ISUB  = 0x0D,
  LSC_ATOMIC_SMIN  = 0x0E,
  LSC_ATOMIC_SMAX  = 0x0F,
  LSC_ATOMIC_UMIN  = 0x10,
  LSC_ATOMIC_UMAX  = 0x11,
  LSC_ATOMIC_ICAS  = 0x12,
  LSC_ATOMIC_FADD  = 0x13,
  LSC_ATOMIC_FSUB  = 0x14,
  LSC_ATOMIC_FMIN  = 0x15,
  LSC_ATOMIC_FMAX  = 0x16,
  LSC_ATOMIC_FCAS  = 0x17,
  LSC_ATOMIC_AND   = 0x18,
  LSC_ATOMIC_OR    = 0x19,
  LSC_ATOMIC_XOR   = 0x1A,
  //
  LSC_LOAD_STATUS        = 0x1B,
  LSC_STORE_UNCOMPRESSED = 0x1C,
  LSC_CCS_UPDATE         = 0x1D,
  LSC_READ_STATE_INFO    = 0x1E,
  LSC_FENCE              = 0x1F,
  //

  LSC_INVALID = 0xFFFFFFFF,
};
static_assert(LSC_LOAD == 0x0,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_FENCE == 0x1F,
    "vISA binary encoding depends on enum ordinal value");

/////////////////////////////////////////////////////////////////////
// The vISA spec depends on the enum values assigned.  If you really
// need to change then, fix any consumers encoders dependent on the
// encoding (e.g. CM binary encoder) as well as the vISA spec.
//
static_assert(LSC_DATA_ELEMS_8 == 5,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_ADDR_SIZE_16b == 1,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_DATA_SIZE_8b == 1,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_DATA_SIZE_16b == 2,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_DATA_SIZE_32b == 3,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_DATA_SIZE_64b == 4,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_DATA_SIZE_16c32bH == 7,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_DATA_ORDER_NONTRANSPOSE == 1,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_DATA_ORDER_TRANSPOSE == 2,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_ADDR_TYPE_FLAT == 1,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_ADDR_TYPE_BTI == 4,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_CACHING_DEFAULT == 0,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_CACHING_READINVALIDATE == 6,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_FENCE_OP_NONE == 0,
    "vISA binary encoding depends on enum ordinal value");
static_assert(LSC_FENCE_OP_FLUSHL3 == 5,
    "vISA binary encoding depends on enum ordinal value");

// FixedFunctionID: these are hardware FFID values
enum FFID
{
    FFID_NULL = 0x0,
    FFID_VSR  = 0x3,
    FFID_HS   = 0x4,
    FFID_DS   = 0x5,
    FFID_TS   = 0x6,
    FFID_GP   = 0x7,
    FFID_GP1  = 0x8,
    FFID_VS   = 0x9,
    FFID_GS   = 0xC,
    FFID_PS   = 0xF,

    FFID_INVALID = 0xFF
};

#endif
