1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2017-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #ifndef COMMON_ISA_OPCODE_INCLUDED
10 #define COMMON_ISA_OPCODE_INCLUDED
11 namespace vISA
12 {
13 class G4_Operand;
14 class G4_Declare;
15 }
16 
17 #include "visa_igc_common_header.h"
18 #include "IsaDescription.h"
19 #include "common.h"
20 #include <string>
21 #include <cctype>
22 
23 /*
24  * Constant literals for the common ISA
25  *
26  */
27 #define COMMON_ISA_MAGIC_NUM 0x41534943
28 
29 #define COMMON_ISA_MAJOR_VER 3
30 #define COMMON_ISA_MINOR_VER 8
31 
32 #define COMMON_ISA_MAX_ADDRESS_SIZE     16
33 #define COMMON_ISA_MAX_SURFACE_SIZE     128
34 #define COMMON_ISA_MAX_SAMPLER_SIZE     128
35 #define COMMON_ISA_MAX_VARIABLE_SIZE    (256 * getGRFSize())
36 #define COMMON_ISA_MAX_NUM_SURFACES     256
37 #define COMMON_ISA_MAX_NUM_SAMPLERS     32
38 #define COMMON_ISA_MAX_NUM_INPUTS       256
39 
40 // V0-V31 are reserved
41 #define COMMON_ISA_NUM_PREDEFINED_VAR_VER_3   32
42 // reserve p0 for the case of no predication
43 #define COMMON_ISA_NUM_PREDEFINED_PRED  1
44 
45 // Reserve T0-T5 as special surfaces
46 #define COMMON_ISA_NUM_PREDEFINED_SURF_VER_3_1  6
47 
48 // bfi can have 7 operands
49 #define COMMON_ISA_MAX_NUM_OPND_ARITH_LOGIC 7
50 #define COMMON_ISA_MAX_NUM_DST 2
51 #define COMMON_ISA_MAX_NUM_SRC 4
52 
53 #define COMMON_ISA_MAX_MEDIA_BLOCK_WIDTH_BDW_PLUS 64
54 #define COMMON_ISA_MAX_MEDIA_BLOCK_WIDTH 32
55 #define COMMON_ISA_MAX_MEDIA_BLOCK_HEIGHT 64
56 
57 #define  COMMON_ISA_GRF_REG_SIZE (getGRFSize()) /// # of bytes in a CISA GRF register
58 
59 #define COMMON_ISA_MAX_FILENAME_LENGTH   1023
60 
61 #define COMMON_ISA_MAX_KERNEL_NAME_LEN  255
62 
63 #define SEND_GT_MSG_TYPE_BIT                        14
64 #define SEND_GT_MSG_LENGTH_BIT_OFFSET               25
65 #define SEND_GT_RSP_LENGTH_BIT_OFFSET               20
66 #define SEND_GT_MAX_RESPONSE_LENGTH                 16
67 #define SEND_GT_MAX_MESSAGE_LENGTH                  15
68 #define SEND_GT_MSG_HEADER_PRESENT_BIT_OFFSET       19
69 
70 typedef enum {
71     GENERAL_VAR,
72     ADDRESS_VAR,
73     PREDICATE_VAR,
74     SAMPLER_VAR,
75     SURFACE_VAR,
76     LABEL_VAR,
77     NUM_VAR_CLASS
78 } Common_ISA_Var_Class;
79 
80 typedef enum {
81     INPUT_GENERAL   = 0x0,
82     INPUT_SAMPLER   = 0x1,
83     INPUT_SURFACE   = 0x2,
84     INPUT_UNKNOWN
85 } Common_ISA_Input_Class;
86 
87 
88 typedef enum {
89     INPUT_EXPLICIT          = 0x0,
90     LOCAL_SIZE              = 0x1,
91     GROUP_COUNT             = 0x2,
92     LOCAL_ID                = 0x3,
93     PSEUDO_INPUT            = 0x10,
94     IMPLICIT_INPUT_COUNT    = 0x5
95 } Common_ISA_Implicit_Input_Kind;
96 
97 extern const char * implictKindStrings[IMPLICIT_INPUT_COUNT];
98 
99 typedef enum {
100     OPERAND_GENERAL = 0x0,
101     OPERAND_ADDRESS = 0x1,
102     OPERAND_PREDICATE = 0x2,
103     OPERAND_INDIRECT = 0x3,
104     OPERAND_ADDRESSOF = 0x4,
105     OPERAND_IMMEDIATE = 0x5,
106     OPERAND_STATE = 0x6,
107     NUM_OPERAND_CLASS
108 } Common_ISA_Operand_Class;
109 
110 typedef enum {
111     REGION_NULL = 0x0,
112     REGION_0 = 0x1,
113     REGION_1 = 0x2,
114     REGION_2 = 0x3,
115     REGION_4 = 0x4,
116     REGION_8 = 0x5,
117     REGION_16 = 0x6,
118     REGION_32 = 0x7,
119     NUM_REGION = 0x8
120 } Common_ISA_Region_Val;
121 
122 extern const char* Rel_op_str[ISA_CMP_UNDEF + 1];
123 
124 extern const char* media_ld_mod_str[MEDIA_LD_Mod_NUM];
125 
126 // media store inst modifiers
127 typedef enum {
128     MEDIA_ST_nomod = 0x0,
129     MEDIA_ST_reserved = 0x1,
130     MEDIA_ST_top = 0x2,
131     MEDIA_ST_bottom = 0x3,
132     MEDIA_ST_Mod_NUM
133 } MEDIA_ST_mod;
134 
135 extern const char* media_st_mod_str[MEDIA_ST_Mod_NUM];
136 
137 
138 extern const char* channel_mask_str[CHANNEL_MASK_NUM];
139 
140 extern const char* channel_mask_slm_str[CHANNEL_MASK_NUM];
141 
142 extern const char* sampler_channel_output_str[4];
143 
144 extern const char* vme_op_mode_str[VME_OP_MODE_NUM];
145 
146 typedef enum {
147     S_OPND_ERROR = 0x0,
148     S_OPND_SAMPLER = 0x1,
149     S_OPND_SURFACE = 0x2,
150     S_OPND_NUM = 0x3
151 } Common_ISA_State_Opnd;
152 
153 extern const char* emask_str[];
154 
155 typedef enum {
156     NOT_A_STATE_OPND   = -1,
157     STATE_OPND_SURFACE =  0,
158     STATE_OPND_SAMPLER,
159     STATE_OPND_NUM
160 } Common_ISA_State_Opnd_Class;
161 
162 /*
163  *  Pseudo-strcutures describing the format of the symbol tables and kernel metadata in the common ISA
164  */
165 
166 struct attribute_info_t {
167     uint32_t nameIndex;
168     unsigned char size;
169     bool isInt;
170     union {
171         int intVal;
172         const char* stringVal;
173     } value;
174 
175     int getSizeInBinary() const;
176 };
177 
178 struct var_info_t {
179     uint32_t name_index;
180     unsigned char bit_properties;
181     unsigned short num_elements;
182     uint32_t alias_index;
183     unsigned short alias_offset;
184     unsigned char alias_scope_specifier;
185     unsigned char attribute_capacity;
186     unsigned char attribute_count;
187     attribute_info_t* attributes;
188     vISA::G4_Declare* dcl;  // ToDo: remove this, vISA variables should not have access to internal Gen declares
189 
getTypevar_info_t190     VISA_Type getType() const
191     {
192         return (VISA_Type) (bit_properties & 0xF);
193     }
194 
getAlignmentvar_info_t195     VISA_Align getAlignment() const
196     {
197         return (VISA_Align) ((bit_properties >> 4 ) & 0xF);
198     }
199 
getTypeAlignmentvar_info_t200     VISA_Align getTypeAlignment() const
201     {
202         VISA_Align typeAlign = ALIGN_WORD;
203         if (getSize() >= getGRFSize())
204         {
205             typeAlign = getGRFSize() == 64 ? ALIGN_32WORD : ALIGN_HWORD;
206         }
207         else
208         {
209             switch (CISATypeTable[getType()].typeSize)
210             {
211                 case 4:
212                     typeAlign = ALIGN_DWORD;
213                     break;
214                 case 8:
215                     typeAlign = ALIGN_QWORD;
216                     break;
217                 default:
218                     // nothing for other types
219                     break;
220             }
221         }
222         return typeAlign;
223     }
224 
getSizevar_info_t225     unsigned int getSize() const
226     {
227         return num_elements * CISATypeTable[getType()].typeSize;
228     }
229 
230     int getSizeInBinary() const;
231 };
232 
233 struct addr_info_t {
234     uint32_t name_index;
235     unsigned short num_elements;
236     unsigned char attribute_capacity;
237     unsigned char attribute_count;
238     attribute_info_t* attributes;
239     vISA::G4_Declare* dcl;
240 
241     int getSizeInBinary() const;
242 };
243 
244 struct pred_info_t {
245     uint32_t name_index;
246     unsigned short num_elements;
247     unsigned char attribute_capacity;
248     unsigned char attribute_count;
249     attribute_info_t* attributes;
250     vISA::G4_Declare* dcl;
251 
252     int getSizeInBinary() const;
253 };
254 
255 struct label_info_t {
256     uint32_t name_index;
257     unsigned char kind;
258     unsigned char attribute_capacity;
259     unsigned char attribute_count;
260     attribute_info_t* attributes;
261 
262     int getSizeInBinary() const;
263 };
264 
265 struct state_info_t {
266     uint32_t name_index;
267     unsigned short num_elements;
268     unsigned char attribute_capacity;
269     unsigned char attribute_count;
270     attribute_info_t* attributes;
271     vISA::G4_Declare* dcl;
272 
273     int getSizeInBinary() const;
274 };
275 
276 //work around for g++
277 namespace patch
278 {
to_string(const T & n)279     template < typename T > std::string to_string(const T& n)
280     {
281         std::ostringstream stm;
282         stm << n;
283         return stm.str();
284     }
285 }
286 
287 struct input_info_t {
288     // bits 0-2, category kind
289     // bits 3-7, implicit argument kind
290     //   0x00 explicit (default)
291     //   0x01 local size (3 x ud)
292     //   0x02 group count (3 x ud)
293     //   0x03 local id (3 x ud)
294     //   0x10 pseudo_input
295     //   others, reserved.
296     uint8_t kind;
297     uint32_t index;
298     short offset;
299     unsigned short size;
300     vISA::G4_Declare* dcl;
301 
getInputClassinput_info_t302     inline Common_ISA_Input_Class getInputClass() const
303     {
304         return (Common_ISA_Input_Class)(kind & 0x7);
305     }
306 
307     /// Get/set the implicit input kind.
setImplicitKindinput_info_t308     void setImplicitKind(uint8_t k)
309     {
310         kind = (kind & 0x7) | (k << 3);
311     }
getImplicitKindinput_info_t312     uint8_t getImplicitKind() const
313     {
314         return kind >> 3;
315     }
isPseudoInputinput_info_t316     static bool isPseudoInput(uint8_t kind)
317     {
318         return kind == PSEUDO_INPUT;
319     }
isPseudoInputinput_info_t320     bool isPseudoInput() const
321     {
322         return isPseudoInput(getImplicitKind());
323     }
getImplicitKindStringinput_info_t324     static std::string getImplicitKindString(uint16_t kind)
325     {
326         std::string kindString = ".implicit_";
327         if (kind == PSEUDO_INPUT)
328         {
329             kindString.append(implictKindStrings[4]);
330         }
331         else if (kind >= IMPLICIT_INPUT_COUNT)
332         {
333             kindString.append("UNDEFINED_");
334             kindString.append(patch::to_string(kind));
335         }
336         else
337         {
338             kindString.append(implictKindStrings[kind]);
339         }
340         return kindString;
341     }
getImplicitKindStringinput_info_t342     std::string getImplicitKindString() const
343     {
344         uint32_t kind = getImplicitKind();
345         return getImplicitKindString(kind);
346     }
347 
348     int getSizeInBinary() const;
349 };
350 
351 typedef struct {
352     char kind;
353     unsigned short id;
354     short offset;
355     unsigned short size;
356 } parameter_info_t;
357 
358 typedef struct {
359     unsigned short symbolic_index;
360     unsigned short resolved_index;
361 } reloc_sym;
362 
363 typedef struct {
364     unsigned short num_syms;
365     reloc_sym* reloc_syms;
366 } reloc_symtab;
367 
368 typedef struct {
369     unsigned char platform;
370     unsigned int binary_offset;
371     unsigned int binary_size;
372 } gen_binary_info;
373 
374 struct kernel_info_t {
375     unsigned short name_len;
376     char* name;
377     unsigned int offset;
378     unsigned int size;
379     unsigned int input_offset;
380     unsigned int binary_offset;
381     unsigned int binary_size;
382     reloc_symtab variable_reloc_symtab; // ded, but leave here to avoid breaking old vISA binary
383     reloc_symtab function_reloc_symtab; // ded, but leave here to avoid breaking old vISA binary
384     unsigned char num_gen_binaries;
385     gen_binary_info* gen_binaries;
386     // Auxillary data
387     //   for cisa binary emmission
388     char * cisa_binary_buffer;
389     char * genx_binary_buffer;
390 
391     uint32_t getSizeInBinary() const;
392 };
393 
394 struct function_info_t {
395     unsigned char linkage;
396     unsigned short name_len;
397     char* name;
398     unsigned int offset;
399     unsigned int size;
400     reloc_symtab variable_reloc_symtab; // ded, but leave here to avoid breaking old vISA binary
401     reloc_symtab function_reloc_symtab; // ded, but leave here to avoid breaking old vISA binary
402     // Auxillary data
403     //   for cisa binary emmission
404     char* cisa_binary_buffer;
405     char* genx_binary_buffer;
406 
407     uint32_t getSizeInBinary() const;
408 };
409 
410 /*
411  *  Format of the common ISA kernel binary.
412  *  We do not directly output the kernel struct because the kernel binary is a byte stream
413  *  with no padding and alignment for the fields, and because the tables have dynamic length
414  *
415  */
416 struct common_isa_header {
417     unsigned int          magic_number;
418     unsigned char         major_version;
419     unsigned char         minor_version;
420     unsigned short        num_kernels;
421     kernel_info_t*        kernels;
422     unsigned short        num_filescope_variables;
423     unsigned short        num_functions;
424     function_info_t*      functions;
425 
426     uint32_t getSizeInBinary() const;
427 };
428 
429 typedef struct {
430     uint32_t        string_count;
431     const char**          strings;
432     uint32_t        name_index;
433     uint32_t        variable_count;
434     var_info_t*           variables;
435     unsigned short        address_count;
436     addr_info_t*          addresses;
437     unsigned short        predicate_count;
438     pred_info_t*          predicates;
439     unsigned short        label_count;
440     label_info_t*         labels;
441     unsigned char         sampler_count;
442     state_info_t*         samplers;
443     unsigned char         surface_count;
444     state_info_t*         surfaces;
445     unsigned char         vme_count; // deprecated and MBZ
446     uint32_t              input_count;
447     input_info_t*         inputs;
448     unsigned char         return_type;
449     unsigned int          size;
450     unsigned int          entry;
451     unsigned char         input_size;
452     unsigned char         return_value_size;
453     unsigned short        attribute_count;
454     attribute_info_t*     attributes;
455     bool*                 surface_attrs;
456 } kernel_format_t;
457 typedef kernel_format_t function_format_t;
458 
459 typedef struct
460 {
461     GenPrecision   Prec;
462     unsigned int   BitSize;
463     const char*    Name;
464 } GenPrecision_Info_t;
465 extern GenPrecision_Info_t GenPrecisionTable[(unsigned int)GenPrecision::TOTAL_NUM];
466 
467 class print_format_provider_t {
468 public:
469     virtual uint32_t getNameIndex() const = 0;
470 
471     virtual const char* getString(uint32_t str_id) const = 0;
472     virtual uint32_t getStringCount() const = 0;
473 
474     virtual const label_info_t* getLabel(uint16_t label_id) const = 0;
475     virtual unsigned short getLabelCount() const = 0;
476 
477     virtual const var_info_t* getPredefVar(unsigned var_id) const = 0;
478     virtual const var_info_t* getVar(unsigned var_id) const = 0;
479     virtual uint32_t getVarCount() const = 0;
480 
481     virtual const attribute_info_t* getAttr(unsigned id) const = 0;
482     virtual unsigned getAttrCount() const = 0;
483 
484     virtual const addr_info_t* getAddr(unsigned id) const = 0;
485     virtual unsigned short getAddrCount() const = 0;
486 
487     virtual const pred_info_t* getPred(unsigned id) const = 0;
488     virtual unsigned short getPredCount() const = 0;
489 
490     virtual const state_info_t* getPredefSurface(unsigned id) const = 0;
491     virtual const state_info_t* getSurface(unsigned id) const = 0;
492     virtual unsigned char getSurfaceCount() const = 0;
493 
494     virtual const state_info_t* getSampler(unsigned id) const = 0;
495     virtual unsigned char getSamplerCount() const = 0;
496 
497     virtual const input_info_t* getInput(unsigned id) const = 0;
498     virtual uint32_t getInputCount() const = 0;
499 
500 };
501 
502 struct print_decl_index_t {
503     unsigned var_index = 0;
504     unsigned addr_index = 0;
505     unsigned pred_index = 0;
506     unsigned sampler_index = 0;
507     unsigned surface_index = 0;
508     unsigned input_index = 0;
509 };
510 
511 struct vector_opnd {
512     unsigned char tag;
513     union {
514         struct {
515             uint32_t index;
516             unsigned char row_offset;
517             unsigned char col_offset;
518             unsigned short region;
519         } gen_opnd;
520 
521         struct {
522             unsigned short index;
523             unsigned char offset;
524             unsigned char width;        // it uses the same def for EXEC_SIZE
525         } addr_opnd;
526 
527         struct {
528             unsigned short index;
529         } pred_opnd;
530 
531         struct {
532             unsigned short index;
533             unsigned char addr_offset;
534             short indirect_offset;
535             unsigned char bit_property;
536             unsigned short region;
537         } indirect_opnd;
538 
539         struct {
540             unsigned short index;
541             short addr_offset;
542         } addressof_opnd;
543 
544         struct {
545             unsigned char type;
546             union {
547                 unsigned int ival;
548                 unsigned long long lval;
549                 double dval;
550                 float fval;
551             } _val;
552         } const_opnd;
553 
554         struct {
555             unsigned char opnd_class;
556             unsigned short index;
557             unsigned char offset;
558         } state_opnd;
559 
560     } opnd_val;
561 
getOperandClassvector_opnd562     inline Common_ISA_Operand_Class getOperandClass() const
563     {
564         return (Common_ISA_Operand_Class)(tag & 0x7);
565     }
566 
getStateOpClassvector_opnd567     Common_ISA_State_Opnd_Class getStateOpClass() const
568     {
569         MUST_BE_TRUE(getOperandClass() == OPERAND_STATE, "state operand expected");
570         return (Common_ISA_State_Opnd_Class)opnd_val.state_opnd.opnd_class;
571     }
572 
isImmediatevector_opnd573     bool isImmediate() const
574     {
575         return getOperandClass() == OPERAND_IMMEDIATE;
576     }
577 
getImmediateTypevector_opnd578     VISA_Type getImmediateType() const
579     {
580         MUST_BE_TRUE(isImmediate(), "immediate constant expected");
581         VISA_Type type = (VISA_Type)(opnd_val.const_opnd.type & 0xF);
582         MUST_BE_TRUE(type < ISA_TYPE_NUM && type != ISA_TYPE_BOOL,
583                      "invalid immediate constant type");
584         return type;
585     }
586 
getOperandModifiervector_opnd587     inline VISA_Modifier getOperandModifier() const
588     {
589         return (VISA_Modifier)((tag >> 3 ) & 0x7);
590     }
591 
getOperandIndexvector_opnd592     inline uint32_t getOperandIndex() const
593     {
594        switch (getOperandClass())
595        {
596            case OPERAND_STATE:     return opnd_val.state_opnd     .index;
597            case OPERAND_GENERAL:   return opnd_val.gen_opnd       .index;
598            case OPERAND_ADDRESS:   return opnd_val.addr_opnd      .index;
599            case OPERAND_INDIRECT:  return opnd_val.indirect_opnd  .index;
600            case OPERAND_PREDICATE: return opnd_val.pred_opnd      .index;
601            case OPERAND_ADDRESSOF: return opnd_val.addressof_opnd .index;
602            default:                return 0; ///OPERAND_IMMEDIATE
603        }
604     }
605 
606     int getSizeInBinary() const;
607 };
608 
609 typedef struct _raw_opnd{
610     uint32_t index;
611     unsigned short offset;
612 
613    std::string toString() const;
614 } raw_opnd;
615 
616 typedef enum
617 {
618     CISA_OPND_VECTOR = 0,
619     CISA_OPND_RAW    = 1,
620     CISA_OPND_OTHER  = 2
621 } CISA_opnd_type;
622 
623 typedef struct _CISA_GEN_VAR
624 {
625     Common_ISA_Var_Class type;
626     unsigned int index; //index into respective symbol tables
627     union
628     {
629         var_info_t genVar;
630         addr_info_t addrVar;
631         pred_info_t predVar;
632         state_info_t stateVar;
633         label_info_t labelVar;
634     };
635 } CISA_GEN_VAR;
636 
637 typedef struct _VISA_GenVar     : CISA_GEN_VAR { } VISA_GenVar;
638 typedef struct _VISA_AddrVar    : CISA_GEN_VAR { } VISA_AddrVar;
639 typedef struct _VISA_PredVar    : CISA_GEN_VAR { } VISA_PredVar;
640 typedef struct _VISA_SamplerVar : CISA_GEN_VAR { } VISA_SamplerVar;
641 typedef struct _VISA_SurfaceVar : CISA_GEN_VAR { } VISA_SurfaceVar;
642 typedef struct _VISA_LabelVar   : CISA_GEN_VAR { } VISA_LabelVar;
643 
644 // unfortunately vISA binary restricts the max number of predicates to 4K so that we could pack
645 // pred id + control into 2 bytes. It seemed like a good idea at the time but our input programs now
646 // regularly exceed it. Since we don't want to touch legacy binary format the alternative is
647 // to make it work at least for vISA assembly.
648 struct PredicateOpnd
649 {
650 
651 private:
652     uint32_t predId;
653     uint16_t predInBinary; // bit[0:11] - LSB 12bit for pred id, bit[13:14] - pred control, bit[15] - pred inverse
654 
655 public:
PredicateOpndPredicateOpnd656     PredicateOpnd() : predId(0), predInBinary(0) {}
PredicateOpndPredicateOpnd657     PredicateOpnd(uint32_t id, uint16_t binaryId) : predId(id), predInBinary(binaryId) {}
PredicateOpndPredicateOpnd658     PredicateOpnd(uint32_t id, VISA_PREDICATE_STATE state, VISA_PREDICATE_CONTROL cntrl)
659     {
660         predId = id;
661         predInBinary = (id & 0xFFF) | (cntrl << 13) | (state << 15);
662     }
663 
getIdPredicateOpnd664     uint32_t getId() const { return predId; }
isNullPredPredicateOpnd665     bool isNullPred() const { return predId == 0; }
isInversePredicateOpnd666     bool isInverse() const { return predInBinary & 0x8000; }
getControlPredicateOpnd667     VISA_PREDICATE_CONTROL getControl() const
668     {
669         return (VISA_PREDICATE_CONTROL)((predInBinary & 0x6000) >> 13);
670     }
671 
getPredInBinaryPredicateOpnd672     uint16_t getPredInBinary() const { return predInBinary; }
getPredInBinarySizePredicateOpnd673     static constexpr int getPredInBinarySize() { return sizeof(predInBinary); }
674 
getNullPredPredicateOpnd675     static PredicateOpnd getNullPred()
676     {
677         return PredicateOpnd();
678     }
679 };
680 
681 typedef struct _CISA_opnd
682 {
683     CISA_opnd_type opnd_type;
684     unsigned char  tag;   // from opnd description tag
685     unsigned short size;  // size of the operand
686     uint32_t index; // this should be the same value as index in v_opnd
687 
688     union
689     {
690         vector_opnd  v_opnd;
691         raw_opnd     r_opnd;
692         unsigned int other_opnd;
693     } _opnd;
694     vISA::G4_Operand *g4opnd;
695     VISA_GenVar *decl;
696 
convertToPred_CISA_opnd697     PredicateOpnd convertToPred() const
698     {
699         assert(_opnd.v_opnd.getOperandClass() == OPERAND_PREDICATE);
700         return PredicateOpnd(index, _opnd.v_opnd.opnd_val.pred_opnd.index);
701     }
702 } VISA_opnd;
703 
704 typedef struct _CISA_INST
705 {
706     unsigned char  opcode;
707     unsigned char  execsize;
708     unsigned char  modifier; /// Mainly used for media ld/store.
709     ISA_Inst_Type  isa_type;
710     PredicateOpnd  pred;
711     VISA_opnd**    opnd_array;
712     unsigned       opnd_count;
713     unsigned       id;
714 
getExecSize_CISA_INST715     VISA_Exec_Size getExecSize() const { return (VISA_Exec_Size) (execsize & 0xF); }
getExecMask_CISA_INST716     VISA_EMask_Ctrl getExecMask() const { return (VISA_EMask_Ctrl) (execsize >> 4); }
717 
718 } CISA_INST;
719 
720 #define READ_FIELD_FROM_BUF( dst, type ) \
721     dst = *((type *) &buf[byte_pos]); \
722     byte_pos += sizeof(type);
723 
724 #define STRING_LEN  1024
725 
726 struct Common_ISA_Attribute{
727     char* name;
728     char* value;
729 };
730 
731 typedef struct _string_pool_entry {
732     Common_ISA_Var_Class type;
733     VISA_Type data_type;
734     char *value;
735     struct _string_pool_entry *next;
736 } string_pool_entry;
737 
738 extern const char* CISAAtomicOpNames[];
739 
740 typedef enum {
741     // integer operations
742     GEN_ATOMIC_CMPWR_2W                = 0x0,  // AOP_CMPWR_2W
743     GEN_ATOMIC_AND                     = 0x1,  // AOP_AND
744     GEN_ATOMIC_OR                      = 0x2,  // AOP_OR
745     GEN_ATOMIC_XOR                     = 0x3,  // AOP_XOR
746     GEN_ATOMIC_MOV                     = 0x4,  // AOP_MOV
747     GEN_ATOMIC_INC                     = 0x5,  // AOP_INC
748     GEN_ATOMIC_DEC                     = 0x6,  // AOP_DEC
749     GEN_ATOMIC_ADD                     = 0x7,  // AOP_ADD
750     GEN_ATOMIC_SUB                     = 0x8,  // AOP_SUB
751     GEN_ATOMIC_REVSUB                  = 0x9,  // AOP_REVSUB
752     GEN_ATOMIC_IMAX                    = 0xa,  // AOP_IMAX
753     GEN_ATOMIC_IMIN                    = 0xb,  // AOP_IMIN
754     GEN_ATOMIC_UMAX                    = 0xc,  // AOP_UMAX
755     GEN_ATOMIC_UMIN                    = 0xd,  // AOP_UMIN
756     GEN_ATOMIC_CMPWR                   = 0xe,  // AOP_CMPWR
757     GEN_ATOMIC_PREDEC                  = 0xf,  // AOP_PREDEC
758     // float operations
759     GEN_ATOMIC_FMAX                    = 0x1,  // FOP_FMAX
760     GEN_ATOMIC_FMIN                    = 0x2,  // FOP_FMIN
761     GEN_ATOMIC_FCMPWR                  = 0x3,  // FOP_FCMPWR
762     GEN_ATOMIC_FADD                    = 0x4,  // FOP_FADD
763     GEN_ATOMIC_FSUB                    = 0x5,  // FOP_FSUB
764     GEN7_ATOMIC_UNDEF                   = 0xFF
765 } GenAtomicOp;
766 
767 extern const char* va_sub_names[26];
768 
769 extern const char* pixel_size_str[2];
770 
771 extern const char* lbp_creation_mode[3];
772 
773 extern const char* avs_control_str[4];
774 
775 extern const char* avs_exec_mode[3];
776 
777 extern const char* mmf_exec_mode[4];
778 
779 extern const char* mmf_enable_mode[3];
780 
781 extern const char* ed_exec_mode[4];
782 
783 extern const char* conv_exec_mode[4];
784 
785 extern unsigned format_control_byteSize2[4];
786 
787 extern unsigned ed_exec_mode_byte_size[4];
788 
789 extern unsigned conv_exec_mode_size[4];
790 
791 extern unsigned mmf_exec_mode_size[4];
792 
793 extern unsigned lbp_creation_exec_mode_size[3];
794 
795 extern unsigned lbp_correlation_mode_size[3];
796 
797 extern unsigned mmf_exec_mode_bit_size[4];
798 
799 extern unsigned output_format_control_size[4];
800 
801 #define HASH_TABLE_SIZE 59
802 
803 typedef struct
804 {
805     PreDefined_Vars id;
806     VISA_Type type;
807     unsigned char majorVersion; // CISA major version when this becomes available
808     bool isInR0;  // whether the variable value is stored in r0 or is
809                   // appended after kernel input
810     short byteOffset;  // byte offset of the variable's value
811     unsigned num_elements;
812     const char* str;
813 } CISA_PreDefined_Var_Info;
814 
815 namespace vISA
816 {
817     enum class SFID
818     {
819         NULL_SFID  =  0,
820         SAMPLER    =  2,
821         GATEWAY    =  3,
822         DP_DC2     =  4,
823         DP_WRITE   =  5, //DATAPORT WRITE
824         URB        =  6, //URB
825         SPAWNER    =  7, //THREAD SPAWNER
826         VME        =  8, //VIDEO MOTION ESTIMATION
827         DP_CC      =  9, //CONSTANT CACHE DATAPORT
828         DP_DC0     = 10, //DATA CACHE DATAPORT
829         DP_PI      = 11, //PIXEL INTERPOLATOR
830         DP_DC1     = 12, //DATA CACHE DATAPORT1
831         CRE        = 13, //CHECK & REFINEMENT ENGINE
832         BTD        = 16, // bindless thread dispatcher
833         RTHW       = 17, // ray trace HW accelerator
834         TGM        = 18, // typed global memory
835         SLM        = 19, // untyped shared local memory
836         UGM        = 20, // untyped global memory
837         UGML       = 21, // untyped global memory (low bandwidth)
838     };
839 
SFIDtoInt(SFID id)840     inline int SFIDtoInt(SFID id)
841     {
842         if (id == SFID::BTD)
843         {
844             return 0x7;
845         }
846         else if (id == SFID::RTHW)
847         {
848             return 0x8;
849         }
850         else if (id == SFID::TGM)
851         {
852             return 0xD;
853         }
854         else if (id == SFID::SLM)
855         {
856             return 0xE;
857         }
858         else if (id == SFID::UGM)
859         {
860             return 0xF;
861         }
862         return static_cast<int>(id);
863     };
864 
intToSFID(int id)865     inline SFID intToSFID(int id)
866     {
867         if (getGenxPlatform() >= GENX_DG2)
868         {
869             switch (id)
870             {
871                 case 0x7:
872                     return SFID::BTD;
873                 case 0x8:
874                     return SFID::RTHW;
875                 case 0xD:
876                     return SFID::TGM;
877                 case 0xE:
878                     return SFID::SLM;
879                 case 0xF:
880                     return SFID::UGM;
881                 default:
882                     // fall through
883                     break;
884             }
885         }
886         return static_cast<SFID>(id);
887     };
LSC_SFID_To_SFID(LSC_SFID lscId)888     inline SFID LSC_SFID_To_SFID(LSC_SFID lscId)
889     {
890         switch (lscId) {
891         case LSC_UGM:  return SFID::UGM;
892         case LSC_UGML: return SFID::UGML;
893         case LSC_TGM:  return SFID::TGM;
894         case LSC_SLM:  return SFID::SLM;
895         default:
896             assert(false && "invalid SFID for untyped LSC message");
897             return SFID::NULL_SFID;
898         }
899     };
900 };
901 
902 typedef enum
903 {
904     PREDEF_SURF_0 = 254,
905     PREDEF_SURF_1 = 1,
906     PREDEF_SURF_2 = 2,
907     PREDEF_SURF_3 = 3,
908     PREDEF_SURF_1_OLD = 243,
909     PREDEF_SURF_2_OLD = 244,
910     PREDEF_SURF_3_OLD = 245,
911     PREDEF_SURF_252 = 252, // bindless surfaces
912     PREDEF_SURF_253 = 253,  // this is only used internally and should not be set by the user
913     PREDEF_SURF_255 = 255
914 } PREDEFINED_SURF;
915 
916 typedef struct
917 {
918     int vISAId;  // their id in vISA binary (0-5)
919     PREDEFINED_SURF genId;
920     const char* name;  // name in vISA asm
921 } vISAPreDefinedSurface;
922 
923 extern vISAPreDefinedSurface vISAPreDefSurf[COMMON_ISA_NUM_PREDEFINED_SURF_VER_3_1];
924 
925 // bindless sampler field
926 const int BINDLESS_SAMPLER_ID = 31;
927 static const char* BINDLESS_SAMPLER_NAME = "S31";
928 
929 const char* getSampleOp3DName(int opcode);
930 VISASampler3DSubOpCode getSampleOpFromName(const char *str);
931 
932 /// ChannelMask - Channel mask used in vISA builder.
933 /// NOTE: This class is added to discourage developers to directly manipulate
934 /// the enumeration values. Instead, developers are encouraged to use interfaces
935 /// provides in this class to access channel mask.
936 class ChannelMask {
937 public:
938   enum Encoding {   // ABGR BITCNT
939     NOMASK  = 0x0,  // 0000      0
940     R       = 0x1,  // 0001      1
941     G       = 0x2,  // 0010      1
942     RG      = 0x3,  // 0011      2
943     B       = 0x4,  // 0100      1
944     RB      = 0x5,  // 0101      2
945     GB      = 0x6,  // 0110      2
946     RGB     = 0x7,  // 0111      3
947     A       = 0x8,  // 1000      1
948     RA      = 0x9,  // 1001      2
949     GA      = 0xA,  // 1010      2
950     RGA     = 0xB,  // 1011      3
951     BA      = 0xC,  // 1100      2
952     RBA     = 0xD,  // 1101      3
953     GBA     = 0xE,  // 1110      3
954     RGBA    = 0xF   // 1111      4
955   };
956 
957 private:
958   Encoding Value;
959   static const char *Names[];
960   static const uint64_t BitCounts = 0x4332322132212110ULL;
961 
ChannelMask(Encoding val)962   ChannelMask(Encoding val) : Value(val) {}
963 
964   /// needReverseMaskForBinary - Channel mask needs reverse during vISA binary
965   /// encoding.
needReverseMaskForBinary(ISA_Opcode opc)966   static bool needReverseMaskForBinary(ISA_Opcode opc) {
967     return false;
968   }
969 
970 public:
971 
972   /// createFromString() - Create channel mask from its string representation.
973   /// If the given string is not an valid representation, NOMASK is returned
974   /// and (optional) error is set.
975     static ChannelMask createFromString(const char *name, int *pError = 0) {
976         char upperName[16];
977         size_t strSize = strlen(name);
978         memcpy_s(upperName, 16, name, strSize);
979 
980         for (unsigned i = 0; i < strSize; ++i)
981         {
982             upperName[i] = static_cast<char>(std::toupper(name[i]));
983         }
984         upperName[strSize] = '\0';
985 
986         for (unsigned i = 1; i < 16; ++i)
987         {
988             if (strcmp((const char *)upperName, Names[i]) == 0) {
989                 if (pError)
990                     *pError = 0;
991                 return ChannelMask(Encoding(i));
992             }
993         }
994         if (pError)
995             *pError = 1;
996         return ChannelMask(NOMASK);
997     }
998 
999   /// createFromAPI - Create channel mask from vISA API.
createFromAPI(VISAChannelMask mask)1000   static ChannelMask createFromAPI(VISAChannelMask mask) {
1001     return ChannelMask(Encoding(unsigned(mask)));
1002   }
1003 
1004   /// createFromBinary - Create channel mask from vISA binary.
createFromBinary(ISA_Opcode opc,unsigned mask)1005   static ChannelMask createFromBinary(ISA_Opcode opc, unsigned mask) {
1006     if (needReverseMaskForBinary(opc))
1007       mask = ~mask;
1008     mask &= 0xF;
1009     return ChannelMask(Encoding(mask));
1010   }
1011 
1012   /// createAPIFromBinary - Create channel mask API enumeration from vISA binary.
1013   /// This is helper function to shortcut the translation from vISA binary to
1014   /// vISA API enumeration.
createAPIFromBinary(ISA_Opcode opc,unsigned mask)1015   static VISAChannelMask createAPIFromBinary(ISA_Opcode opc, unsigned mask) {
1016     if (needReverseMaskForBinary(opc))
1017       mask = ~mask;
1018     mask &= 0xF;
1019     return ChannelMask(Encoding(mask)).getAPI();
1020   }
1021 
1022   /// createFromSingleChannel - Create channel mask from source single channel
1023   /// enumeration.
createFromSingleChannel(VISASourceSingleChannel single)1024   static ChannelMask createFromSingleChannel(VISASourceSingleChannel single) {
1025     switch (single) {
1026     case VISA_3D_GATHER4_CHANNEL_R: return ChannelMask(R);
1027     case VISA_3D_GATHER4_CHANNEL_G: return ChannelMask(G);
1028     case VISA_3D_GATHER4_CHANNEL_B: return ChannelMask(B);
1029     case VISA_3D_GATHER4_CHANNEL_A: return ChannelMask(A);
1030     }
1031     return ChannelMask(NOMASK);
1032   }
1033 
1034   /// getName - Get the specified channel mask's string representation.
getString()1035   const char *getString() const {
1036     return Names[unsigned(Value)];
1037   }
1038 
1039   /// getAPI - Get enumeration value defined in vISA API.
getAPI()1040   VISAChannelMask getAPI() const {
1041     return VISAChannelMask(unsigned(Value));
1042   }
1043 
convertToSrcChannel()1044   VISASourceSingleChannel convertToSrcChannel() const
1045   {
1046       switch (Value)
1047       {
1048          case R:
1049              return VISA_3D_GATHER4_CHANNEL_R;
1050          case G:
1051              return VISA_3D_GATHER4_CHANNEL_G;
1052          case B:
1053              return VISA_3D_GATHER4_CHANNEL_B;
1054          case A:
1055              return VISA_3D_GATHER4_CHANNEL_A;
1056          default:
1057              assert(false && "can't be converted to single channel");
1058              return VISA_3D_GATHER4_CHANNEL_R;
1059       }
1060   }
1061 
1062   /// getBinary() - Get vISA binary encoding.
1063   /// NOTE getBinary() is different from getHWEncoding() and should be only
1064   /// used to dump vISA binary.
getBinary(ISA_Opcode opc)1065   VISAChannelMask getBinary(ISA_Opcode opc) const {
1066     unsigned mask = unsigned(Value);
1067     if (needReverseMaskForBinary(opc))
1068       mask = ~mask;
1069     mask &= 0xF;
1070     return VISAChannelMask(mask);
1071   }
1072 
getBinary(ISA_Opcode opc,CHANNEL_OUTPUT_FORMAT out)1073   unsigned getBinary(ISA_Opcode opc, CHANNEL_OUTPUT_FORMAT out) const {
1074     unsigned mask = unsigned(Value);
1075     if (needReverseMaskForBinary(opc))
1076     {
1077       mask = ~mask;
1078     }
1079     mask &= 0xF;
1080     if ( opc != ISA_SAMPLE_UNORM )
1081     {
1082         return VISAChannelMask(mask);
1083     }
1084     return VISAChannelMask(mask) | ( (out << 4) & 0x30);
1085   }
1086 
getChannelOutputFormat(uint8_t channelOutput)1087   static unsigned getChannelOutputFormat(uint8_t channelOutput)
1088   {
1089       return (unsigned)((channelOutput >> 4) & 0x3);
1090   }
1091 
1092   /// getHWEncoding - Get HW encoding of channel mask. HW
1093   /// defines channel mask in negative logic to help remove header when all
1094   /// channels are enabled.
getHWEncoding()1095   unsigned getHWEncoding() const {
1096     return ~unsigned(Value) & 0xF;
1097   }
1098 
1099   /// getNumChannles - Get number of channels enabled.
getNumEnabledChannels()1100   unsigned getNumEnabledChannels() const {
1101     return (BitCounts >> (unsigned(Value) * 4)) & 0xF;
1102   }
1103 
1104   /// getSingleChannel() - Get the single source channel enumeration. If more
1105   /// than one channels are enabled, only the lowest one is returned, e.g. if R
1106   /// and G are enabled, getSingleChannel() will return
1107   /// VISA_3D_GATHER4_CHANNEL_R only. It's developer's response to ensure only
1108   /// one channel is enabled if ChannelMask is willing to be converted into
1109   /// single source channel.
getSingleChannel()1110   VISASourceSingleChannel getSingleChannel() const {
1111     unsigned mask = unsigned(Value);
1112     if (mask & unsigned(R))
1113       return VISA_3D_GATHER4_CHANNEL_R;
1114     if (mask & unsigned(G))
1115       return VISA_3D_GATHER4_CHANNEL_G;
1116     if (mask & unsigned(B))
1117       return VISA_3D_GATHER4_CHANNEL_B;
1118     if (mask & unsigned(A))
1119       return VISA_3D_GATHER4_CHANNEL_A;
1120     return VISASourceSingleChannel(~0);
1121   }
1122 
1123   /// Comparison operator -
1124   bool operator==(const ChannelMask &other) const {
1125     return Value == other.Value;
1126   }
1127 
1128   /// Comparison operator -
1129   bool operator==(Encoding other) const {
1130     return Value == other;
1131   }
1132 };
1133 
1134 struct VISAFenceMask
1135 {
1136     uint8_t commitEnable : 1;
1137     uint8_t flushICache : 1;
1138     uint8_t flushSCache : 1;
1139     uint8_t flushCCache : 1;
1140     uint8_t flushRWCache : 1;
1141     uint8_t isGlobal : 1;
1142     uint8_t flushL1Cache : 1;
1143     uint8_t SWFence: 1;
1144 };
1145 
1146 struct VISA3DSamplerOp
1147 {
1148     VISASampler3DSubOpCode opcode;
1149     bool pixelNullMask;
1150     bool cpsEnable;
1151     bool nonUniformSampler;
1152 
1153     // Bit 0-4: subOpcode
1154     // Bit 5  : pixelNullMask
1155     // Bit 6  : cpsEnable
1156     // Bit 7  : non-uniform sampler
extractSamplerOpVISA3DSamplerOp1157     static VISA3DSamplerOp extractSamplerOp(uint8_t val)
1158     {
1159         VISA3DSamplerOp op;
1160         op.pixelNullMask = (val & (1 << 5)) != 0;
1161         op.cpsEnable = (val & (1 << 6)) != 0;
1162         op.nonUniformSampler = (val & (1 << 7)) != 0;
1163         // val & 0b00011111
1164         op.opcode = static_cast<VISASampler3DSubOpCode>(val & 0x1F);
1165         return op;
1166     }
1167 };
1168 namespace vISA{
1169     class Mem_Manager;
1170 }
1171 
1172 extern int processCommonISAHeader(common_isa_header& cisaHdr, unsigned& byte_pos, const void* isaBuffer, vISA::Mem_Manager* mem);
1173 
1174 /// Use the following lengthOf macro ONLY for fixed size arrays (no pointers).
1175 #define lengthOf(a) (sizeof(a)/sizeof(a[0]))
1176 
1177 #endif /* COMMON_ISA_OPCODE_INCLUDED */
1178