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 /*
10 * ISA Byte Code Reader
11 *
12 * This library is designed to be extremely reusable and general in nature, and as a result
13 * the following byte code reader code primarily uses the following IR and data types:
14 *
15 * - common_isa_header
16 * - kernel_format_t
17 * - attribute_info_t
18 * - CISA_opnd
19 * - vector_opnd
20 * - raw_opnd
21 * - CISA_INST
22 * - std::list<CISA_INST*>
23 * - primitives (please use stdint.h types)
24 *
25 * which are used to load the byte code from a buffer into a simple structured IR.
26 *
27 * Use of any other data types should be discussed by several members of the CM jitter team before hand.
28 *
29 */
30 
31 
32 #include "JitterDataStruct.h"
33 #include "visa_igc_common_header.h"
34 #include "common.h"
35 #include "Attributes.hpp"
36 #include "Mem_Manager.h"
37 #include "Common_ISA.h"
38 #include "Common_ISA_framework.h"
39 #include "Common_ISA_util.h"
40 #include "VISADefines.h"
41 #include "IsaDisassembly.h"
42 
43 #include "VISAKernel.h"
44 
45 #include <list>
46 
47 using namespace vISA;
48 
49 struct RoutineContainer
50 {
RoutineContainerRoutineContainer51     RoutineContainer():
52         generalVarDecls(NULL),   generalVarsCount(0),
53         addressVarDecls(NULL),   addressVarsCount(0),
54         predicateVarDecls(NULL), predicateVarsCount(0),
55         samplerVarDecls(NULL),   samplerVarsCount(0),
56         surfaceVarDecls(NULL),   surfaceVarsCount(0),
57         labelVarDecls(NULL),     labelVarsCount(0),
58         inputVarDecls(NULL),     inputVarsCount(0),
59         majorVersion(0),
60         minorVersion(0) { }
61 
~RoutineContainerRoutineContainer62     ~RoutineContainer()
63     {
64         stringPool.clear();
65     }
66     VISA_GenVar**       generalVarDecls; unsigned   generalVarsCount;
67     VISA_AddrVar**      addressVarDecls; unsigned   addressVarsCount;
68     VISA_PredVar**    predicateVarDecls; unsigned predicateVarsCount;
69     VISA_SamplerVar**   samplerVarDecls; unsigned   samplerVarsCount;
70     VISA_SurfaceVar**   surfaceVarDecls; unsigned   surfaceVarsCount;
71     VISA_LabelOpnd**      labelVarDecls; unsigned     labelVarsCount;
72     CISA_GEN_VAR**        inputVarDecls; unsigned     inputVarsCount;
73 
74     std::vector<std::string> stringPool;
75 
76     CISA_IR_Builder* builder = nullptr;
77     VISAKernel*      kernelBuilder = nullptr;
78     uint8_t majorVersion;
79     uint8_t minorVersion;
80 
81 };
82 
83 /// Assumming buf is start of the CISA byte code.
84 #define GET_MAJOR_VERSION(buf) (*((unsigned char*) &buf[4]))
85 #define GET_MINOR_VERSION(buf) (*((unsigned char*) &buf[5]))
86 
87 #define READ_CISA_FIELD(dst, type, bytePos, buf) \
88     do {                                             \
89     dst = *((type *) &buf[bytePos]);             \
90     bytePos += sizeof(type);                     \
91     } while (0)
92 
93 #define PEAK_CISA_FIELD(dst, type, bytePos, buf) \
94     do {                                             \
95     dst = *((type *) &buf[bytePos]);             \
96     } while (0)
97 
98 typedef enum {
99     CISA_EMASK_M0,
100     CISA_EMASK_M1,
101     CISA_EMASK_M2,
102     CISA_EMASK_M3,
103     CISA_EMASK_M4,
104     CISA_EMASK_M5,
105     CISA_EMASK_M6,
106     CISA_EMASK_M7,
107     CISA_NO_EMASK,
108     CISA_DEF_EMASK
109 } Common_ISA_EMask_Ctrl_3_0;
110 
111 enum class FIELD_TYPE
112 {
113     DECL,
114     INPUT
115 };
116 
117 // vISA 3.4+ supports 32-bit general variable IDs
118 // vISA 3.5+ supports 32-bit input count
119 template <typename T>
readVarBytes(uint8_t major,uint8_t minor,T & dst,uint32_t & bytePos,const char * buf,FIELD_TYPE field=FIELD_TYPE::DECL)120 inline void readVarBytes(uint8_t major, uint8_t minor, T& dst, uint32_t& bytePos, const char* buf, FIELD_TYPE field = FIELD_TYPE::DECL)
121 {
122     static_assert(std::is_integral<T>::value && (sizeof(T) == 2 || sizeof(T) == 4), "T should be short or int");
123     uint32_t version = getVersionAsInt(major, minor);
124     uintptr_t ptrval = reinterpret_cast<uintptr_t>(&buf[bytePos]);
125     bool get4Bytes = false;
126     if (field == FIELD_TYPE::DECL)
127     {
128         get4Bytes = (version >= getVersionAsInt(3, 4));
129     }
130     else if (field == FIELD_TYPE::INPUT)
131     {
132         get4Bytes = (version >= getVersionAsInt(3, 5));
133     }
134 
135     if (get4Bytes)
136     {
137         dst = *(reinterpret_cast<uint32_t*>(ptrval));
138         bytePos += sizeof(uint32_t);
139     }
140     else if (field == FIELD_TYPE::INPUT)
141     {
142         dst = *(reinterpret_cast<uint8_t*>(ptrval));
143         bytePos += sizeof(uint8_t);
144     }
145     else
146     {
147         dst = *(reinterpret_cast<uint16_t*>(ptrval));
148         bytePos += sizeof(uint16_t);
149     }
150 }
151 
transformMask(RoutineContainer & container,uint8_t maskVal)152 static VISA_EMask_Ctrl transformMask(
153     RoutineContainer& container, uint8_t maskVal)
154 {
155     VISA_EMask_Ctrl mask = vISA_EMASK_M1;
156     if (container.majorVersion == 3 && container.minorVersion == 0)
157     {
158         Common_ISA_EMask_Ctrl_3_0 tMask = Common_ISA_EMask_Ctrl_3_0(maskVal);
159         switch (tMask)
160         {
161         case CISA_EMASK_M0:
162             {
163                 mask = vISA_EMASK_M1;
164                 break;
165             }
166         case CISA_EMASK_M1:
167             {
168                 mask = vISA_EMASK_M2;
169                 break;
170             }
171         case CISA_EMASK_M2:
172             {
173                 mask = vISA_EMASK_M3;
174                 break;
175             }
176         case CISA_EMASK_M3:
177             {
178                 mask = vISA_EMASK_M4;
179                 break;
180             }
181         case CISA_EMASK_M4:
182             {
183                 mask = vISA_EMASK_M5;
184                 break;
185             }
186         case CISA_EMASK_M5:
187             {
188                 mask = vISA_EMASK_M6;
189                 break;
190             }
191         case CISA_EMASK_M6:
192             {
193                 mask = vISA_EMASK_M7;
194                 break;
195             }
196         case CISA_EMASK_M7:
197             {
198                 mask = vISA_EMASK_M8;
199                 break;
200             }
201         case CISA_NO_EMASK:
202             {
203                 mask = vISA_EMASK_M1_NM;
204                 break;
205             }
206         case CISA_DEF_EMASK:
207             {
208                 mask = vISA_EMASK_M1;
209                 break;
210             }
211         default:
212             break;
213         }
214     }else
215     {
216         mask = VISA_EMask_Ctrl(maskVal);
217     }
218 
219     return mask;
220 }
readExecSizeNG(unsigned & bytePos,const char * buf,VISA_Exec_Size & size,VISA_EMask_Ctrl & mask,RoutineContainer & container)221 static void readExecSizeNG(unsigned& bytePos, const char* buf, VISA_Exec_Size& size, VISA_EMask_Ctrl& mask, RoutineContainer& container)
222 {
223     uint8_t execSize = 0;
224     READ_CISA_FIELD(execSize, uint8_t, bytePos, buf);
225     uint8_t maskVal = (execSize >> 0x4) & 0xF;
226 
227     mask = transformMask(container, maskVal);
228 
229     size = (VISA_Exec_Size)((execSize) & 0xF);
230 }
231 
readPrimitiveOperandNG(unsigned & bytePos,const char * buf)232 template <typename T> T readPrimitiveOperandNG(unsigned& bytePos, const char* buf)
233 {
234     MUST_BE_TRUE(buf, "Argument Exception: argument buf  is NULL.");
235     T data = 0;
236     READ_CISA_FIELD(data, T, bytePos, buf);
237     return data;
238 }
239 
readPredicateOperandNG(unsigned & bytePos,const char * buf,RoutineContainer & container)240 static VISA_PredOpnd* readPredicateOperandNG(unsigned& bytePos, const char* buf, RoutineContainer& container)
241 {
242     uint16_t predOpnd = 0;
243     READ_CISA_FIELD(predOpnd, uint16_t, bytePos, buf);
244 
245     if (0 == predOpnd) return nullptr;
246 
247     VISAKernel* kernelBuilder = container.kernelBuilder;
248     unsigned predID = (predOpnd & 0xfff);
249     VISA_PREDICATE_CONTROL control = (VISA_PREDICATE_CONTROL)((predOpnd & 0x6000) >> 13);
250     VISA_PREDICATE_STATE   state   = (VISA_PREDICATE_STATE)((predOpnd & 0x8000) >> 15);
251     VISA_PredVar*  decl = container.predicateVarDecls[predID];
252     VISA_PredOpnd* opnd = nullptr;
253 
254     kernelBuilder->CreateVISAPredicateOperand(opnd, decl, state, control);
255 
256     return opnd;
257 }
258 
readRawOperandNG(unsigned & bytePos,const char * buf,RoutineContainer & container)259 static VISA_RawOpnd* readRawOperandNG(unsigned& bytePos, const char* buf, RoutineContainer& container)
260 {
261     MUST_BE_TRUE(buf, "Argument Exception: argument buf  is NULL.");
262     uint8_t majorVersion = container.majorVersion;
263     uint8_t minorVersion = container.minorVersion;
264 
265     uint32_t index  = 0;
266     uint16_t offset = 0;
267     readVarBytes(majorVersion, minorVersion, index, bytePos, buf);
268     READ_CISA_FIELD(offset, uint16_t, bytePos, buf);
269 
270     VISAKernelImpl* kernelBuilderImpl = ((VISAKernelImpl*)container.kernelBuilder);
271 
272 
273     unsigned numPreDefinedVars = Get_CISA_PreDefined_Var_Count();
274     VISA_GenVar* decl = NULL;
275     VISA_RawOpnd* opnd = NULL;
276 
277     /**
278         Null register is treated differently now. There is special operand NullReg created.
279         In it field isNullReg is set to true.
280 
281         TODO:? To make things more generic need to mark decl created during initialization as
282         null register, then when CreateVisaRawOperand is called check that decl passed in is
283         null register decl, and mark operand is nullReg, also create region <0;1,0>
284     */
285     if (index == 0)
286     {
287        kernelBuilderImpl->CreateVISANullRawOperand(opnd, true); //dst
288     }
289     else
290     {
291         if (index >= numPreDefinedVars)
292             decl = container.generalVarDecls[index];
293         else
294             kernelBuilderImpl->GetPredefinedVar(decl, (PreDefined_Vars)index);
295 
296         kernelBuilderImpl->CreateVISARawOperand(opnd, decl, offset);
297     }
298 
299     return opnd;
300 }
301 
readPreVarNG(unsigned & bytePos,const char * buf,RoutineContainer & container)302 static VISA_PredVar* readPreVarNG(unsigned& bytePos, const char* buf, RoutineContainer& container)
303 {
304     MUST_BE_TRUE(buf, "Argument Exception: argument buf  is NULL.");
305 
306     uint8_t tag = 0;
307     READ_CISA_FIELD(tag, uint8_t, bytePos, buf);
308 
309     uint16_t index = 0;
310     READ_CISA_FIELD(index, uint16_t, bytePos, buf);
311 
312     uint16_t predIndex = index & 0xfff;
313     VISA_PredVar*  decl = NULL;
314 
315     if (predIndex >= COMMON_ISA_NUM_PREDEFINED_PRED)
316         decl = container.predicateVarDecls[predIndex];
317     return decl;
318 }
319 
readOtherOperandNG(unsigned & bytePos,const char * buf,VISA_Type visatype)320 static uint32_t readOtherOperandNG(unsigned& bytePos, const char* buf, VISA_Type visatype)
321 {
322     union {
323         uint32_t other_opnd;
324         struct {
325             uint8_t b[4];
326         };
327     } v;
328 
329     unsigned bsize = CISATypeTable[visatype].typeSize;
330     assert(bsize <= 4 && " Unsupported other_opnd whose size > 4 bytes!");
331     v.other_opnd = 0;
332     for (int i = 0; i < (int)bsize; ++i)
333     {
334         v.b[i] = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
335     }
336     return v.other_opnd;
337 }
338 
readVectorOperandNG(unsigned & bytePos,const char * buf,uint8_t & tag,RoutineContainer & container,unsigned int size,bool isDst,bool isAddressoff=false)339 static VISA_VectorOpnd* readVectorOperandNG(unsigned& bytePos, const char* buf, uint8_t& tag, RoutineContainer& container, unsigned int size, bool isDst, bool isAddressoff = false)
340 {
341     MUST_BE_TRUE(buf, "Argument Exception: argument buf  is NULL.");
342 
343     VISAKernelImpl* kernelBuilderImpl = ((VISAKernelImpl*)container.kernelBuilder);
344 
345     uint8_t majorVersion = container.majorVersion;
346     uint8_t minorVersion = container.minorVersion;
347 
348     READ_CISA_FIELD(tag, uint8_t, bytePos, buf);
349     VISA_Modifier modifier = ((VISA_Modifier)((tag >> 3) & 0x7));
350 
351     switch ((Common_ISA_Operand_Class)(tag & 0x7)) /// getOperandClass
352     {
353     case OPERAND_GENERAL:
354         {
355             uint32_t index     = 0;
356             uint8_t  rowOffset = 0;
357             uint8_t  colOffset = 0;
358             uint16_t region    = 0;
359 
360             readVarBytes(majorVersion, minorVersion, index, bytePos, buf);
361             READ_CISA_FIELD(rowOffset , uint8_t , bytePos, buf);
362             READ_CISA_FIELD(colOffset , uint8_t , bytePos, buf);
363             READ_CISA_FIELD(region    , uint16_t, bytePos, buf);
364 
365             uint16_t v_stride = Get_Common_ISA_Region_Value((Common_ISA_Region_Val)(region & 0xF));
366             uint16_t width    = Get_Common_ISA_Region_Value((Common_ISA_Region_Val)((region >> 4) & 0xF));
367             uint16_t h_stride = Get_Common_ISA_Region_Value((Common_ISA_Region_Val)((region >> 8) & 0xF));
368 
369             unsigned numPreDefinedVars = Get_CISA_PreDefined_Var_Count();
370 
371             VISA_Modifier     mod = modifier;
372             VISA_VectorOpnd* opnd = NULL;
373             VISA_GenVar*     decl = NULL;
374 
375             if (index >= numPreDefinedVars)
376                 decl = container.generalVarDecls[index];
377             else
378                 kernelBuilderImpl->GetPredefinedVar(decl, (PreDefined_Vars)index);
379 
380             if (isDst)
381                 kernelBuilderImpl->CreateVISADstOperand(opnd, decl, h_stride, rowOffset, colOffset);
382             else if (isAddressoff)
383             {
384                 VISA_Type vType = decl->genVar.getType();
385                 G4_Type gType = GetGenTypeFromVISAType(vType);
386                 unsigned int offset  = colOffset * TypeSize(gType) + rowOffset * numEltPerGRF<Type_UB>();
387                 kernelBuilderImpl->CreateVISAAddressOfOperand(opnd, decl, offset);
388             }
389             else
390             {
391                 kernelBuilderImpl->CreateVISASrcOperand(opnd, decl, mod, v_stride, width, h_stride, rowOffset, colOffset);
392             }
393 
394             return opnd;
395         }
396     case OPERAND_ADDRESS:
397         {
398             uint16_t index  = 0;
399             uint8_t  offset = 0;
400             uint16_t width  = 0;
401 
402             READ_CISA_FIELD(index , uint16_t, bytePos, buf);
403             READ_CISA_FIELD(offset, uint8_t , bytePos, buf);
404             READ_CISA_FIELD(width , uint8_t , bytePos, buf);
405 
406             VISA_VectorOpnd* opnd = NULL;
407             VISA_AddrVar*    decl = container.addressVarDecls[index];
408             kernelBuilderImpl->CreateVISAAddressOperand(opnd, decl, offset, Get_VISA_Exec_Size((VISA_Exec_Size)width), isDst);
409 
410             return opnd;
411         }
412     case OPERAND_PREDICATE:
413         {
414             uint16_t index = 0;
415             READ_CISA_FIELD(index, uint16_t, bytePos, buf);
416 
417             uint16_t predIndex = index & 0xfff;
418             VISA_PredVar*  decl = NULL;
419 
420             if (predIndex >= COMMON_ISA_NUM_PREDEFINED_PRED)
421                 decl = container.predicateVarDecls[predIndex];
422 
423             VISA_VectorOpnd* opnd = nullptr;
424             if (isDst)
425             {
426                 kernelBuilderImpl->CreateVISAPredicateDstOperand(opnd, decl, size);
427                 return opnd;
428             }
429             else
430             {
431                 kernelBuilderImpl->CreateVISAPredicateSrcOperand(opnd, decl, size);
432                 return opnd;
433             }
434         }
435     case OPERAND_INDIRECT:
436         {
437             uint16_t index           = 0;
438             uint8_t  addr_offset     = 0;
439             int16_t  indirect_offset = 0;
440             uint8_t  bit_property    = 0;
441             uint16_t region          = 0;
442 
443             READ_CISA_FIELD(index          , uint16_t, bytePos, buf);
444             READ_CISA_FIELD(addr_offset    , uint8_t , bytePos, buf);
445             READ_CISA_FIELD(indirect_offset, int16_t , bytePos, buf);
446             READ_CISA_FIELD(bit_property   , uint8_t , bytePos, buf);
447             READ_CISA_FIELD(region         , uint16_t, bytePos, buf);
448 
449             uint16_t v_stride = Get_Common_ISA_Region_Value((Common_ISA_Region_Val)((region) & 0xF));
450             uint16_t width    = Get_Common_ISA_Region_Value((Common_ISA_Region_Val)((region >> 4) & 0xF));
451             uint16_t h_stride = Get_Common_ISA_Region_Value((Common_ISA_Region_Val)((region >> 8) & 0xF));
452 
453             VISA_Modifier       mod = modifier;
454             VISA_VectorOpnd*   opnd = NULL;
455             VISA_AddrVar*      decl = container.addressVarDecls[index];
456 
457             kernelBuilderImpl->CreateVISAIndirectGeneralOperand(
458                 opnd, decl, mod, addr_offset, indirect_offset, v_stride, width, h_stride,
459                 (VISA_Type)(bit_property & 0xF), isDst);
460 
461             return opnd;
462         }
463     case OPERAND_IMMEDIATE:
464         {
465             uint8_t type = 0;
466             READ_CISA_FIELD(type, uint8_t, bytePos, buf);
467             VISA_Type immedType = (VISA_Type)(type & 0xF);
468 
469             VISA_VectorOpnd* opnd = NULL;
470 
471             if (immedType == ISA_TYPE_DF)
472             {
473                 double val = 0;
474                 READ_CISA_FIELD(val, double, bytePos, buf);
475                 kernelBuilderImpl->CreateVISAImmediate(opnd, &val, immedType);
476             }
477             else if (immedType == ISA_TYPE_Q || immedType == ISA_TYPE_UQ)
478             {
479                 uint64_t val = 0;
480                 READ_CISA_FIELD(val, uint64_t, bytePos, buf);
481                 kernelBuilderImpl->CreateVISAImmediate(opnd, &val, immedType);
482             }
483             else /// Immediate operands are at least 4 bytes.
484             {
485                 unsigned val = 0;
486                 READ_CISA_FIELD(val, unsigned, bytePos, buf);
487                 kernelBuilderImpl->CreateVISAImmediate(opnd, &val, immedType);
488 
489             }
490 
491             return opnd;
492         }
493     case OPERAND_STATE:
494         {
495             uint8_t  opnd_class = 0;
496             uint16_t index      = 0;
497             uint8_t  offset     = 0;
498 
499             READ_CISA_FIELD(opnd_class, uint8_t , bytePos, buf);
500             READ_CISA_FIELD(index     , uint16_t, bytePos, buf);
501             READ_CISA_FIELD(offset    , uint8_t , bytePos, buf);
502 
503             VISA_VectorOpnd* opnd = NULL;
504 
505             switch ((Common_ISA_State_Opnd_Class)opnd_class)
506             {
507             case STATE_OPND_SURFACE:
508                 {
509                     if (isAddressoff)
510                     {
511                         VISA_SurfaceVar* decl = container.surfaceVarDecls[index];
512                         unsigned int offsetB = offset * TypeSize(Type_UW);
513                         kernelBuilderImpl->CreateVISAAddressOfOperand(opnd, decl, offsetB);
514                     }
515                     else
516                     {
517                         VISA_SurfaceVar* decl = container.surfaceVarDecls[index];
518                         kernelBuilderImpl->CreateVISAStateOperand(opnd, decl, (uint8_t) size, offset, isDst);
519                     }
520                     break;
521                 }
522             case STATE_OPND_SAMPLER:
523                 {
524                     VISA_SamplerVar* decl = container.samplerVarDecls[index];
525                     if (isAddressoff)
526                     {
527                         unsigned int offsetB = offset * TypeSize(Type_UW);
528                         kernelBuilderImpl->CreateVISAAddressOfOperandGeneric(opnd, decl, offsetB);
529                     }
530                     else
531                     {
532                         kernelBuilderImpl->CreateVISAStateOperand(opnd, decl, (uint8_t)size, offset, isDst);
533                     }
534                     break;
535                 }
536             default:
537                 {
538                     MUST_BE_TRUE(false, "Invalid state operand class: only surface and sampler are supported.");
539                     break;
540                 }
541             }
542 
543             return opnd;
544         }
545     default:
546         MUST_BE_TRUE(false, "Operand class not recognized");
547         return NULL;
548     }
549 }
550 
readVectorOperandNG(unsigned & bytePos,const char * buf,RoutineContainer & container,unsigned int size)551 static VISA_VectorOpnd* readVectorOperandNG(unsigned& bytePos, const char* buf, RoutineContainer& container, unsigned int size)
552 {
553     uint8_t tag = 0;
554     bool isDst = false;
555     return readVectorOperandNG(bytePos, buf, tag, container, size, isDst);
556 }
557 
readVectorOperandNG(unsigned & bytePos,const char * buf,RoutineContainer & container,bool isDst)558 static VISA_VectorOpnd* readVectorOperandNG(unsigned& bytePos, const char* buf, RoutineContainer& container,  bool isDst)
559 {
560     uint8_t tag = 0;
561     return readVectorOperandNG(bytePos, buf, tag, container, 1, isDst);
562 }
563 
readVectorOperandNGAddressOf(unsigned & bytePos,const char * buf,RoutineContainer & container)564 static VISA_VectorOpnd * readVectorOperandNGAddressOf(unsigned& bytePos, const char* buf, RoutineContainer& container)
565 {
566     uint8_t tag = 0;
567     bool isDst = false;
568     bool isAddressOff = true;
569     return readVectorOperandNG(bytePos, buf, tag, container, 1, isDst, isAddressOff);
570 }
571 
readInstructionCommonNG(unsigned & bytePos,const char * buf,ISA_Opcode opcode,RoutineContainer & container)572 static void readInstructionCommonNG(unsigned& bytePos, const char* buf, ISA_Opcode opcode, RoutineContainer& container)
573 {
574     VISA_EMask_Ctrl emask = vISA_EMASK_M1;
575     VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
576 
577     VISA_INST_Desc* inst_desc = &CISA_INST_table[opcode];
578     unsigned opnd_count = inst_desc->opnd_num;
579     unsigned opnd_skip = 0;
580 
581     for (unsigned i = 0; i < 2; i++)
582     {
583         if ((opnd_count-opnd_skip) > 0 &&
584             (inst_desc->opnd_desc[i].opnd_type == OPND_EXECSIZE ||
585             inst_desc->opnd_desc[i].opnd_type == OPND_PRED))
586         {
587             opnd_skip++;
588         }
589     }
590 
591     VISAKernel* kernelBuilder = container.kernelBuilder;
592 
593     switch (ISA_Inst_Table[opcode].type)
594     {
595     case ISA_Inst_Mov:
596     case ISA_Inst_Arith:
597     case ISA_Inst_Logic:
598     case ISA_Inst_Address:
599     case ISA_Inst_Compare:
600         {
601             VISA_VectorOpnd* opnds[COMMON_ISA_MAX_NUM_OPND_ARITH_LOGIC];
602             ASSERT_USER(opnd_count <= COMMON_ISA_MAX_NUM_OPND_ARITH_LOGIC, "Insturction operand count exceeds maximum supported operands.");
603             memset(opnds, 0, sizeof(VISA_VectorOpnd*) * COMMON_ISA_MAX_NUM_OPND_ARITH_LOGIC);
604 
605             readExecSizeNG(bytePos, buf, esize, emask, container);
606             VISA_PredOpnd* pred = hasPredicate(opcode) ? readPredicateOperandNG(bytePos, buf, container) : NULL;
607 
608             uint8_t opSpec = 0;
609             if (ISA_FMINMAX == opcode || ISA_CMP == opcode)
610             {
611                 opSpec = readPrimitiveOperandNG<uint8_t>(bytePos, buf); /// rel_Op or opext
612                 opnd_skip++;
613             }
614             uint8_t bfn_func_ctrl = 0;
615 
616             uint32_t exSize = Get_VISA_Exec_Size(esize);
617             uint8_t tag = 0;
618             VISA_PredVar* dstDcl = NULL;
619             bool cmpHasDst = false;
620             for (unsigned i = 0; i < opnd_count-opnd_skip; i++)
621             {
622                 bool isDst = i == 0;
623 
624                 if ((OPND_DST_GEN & inst_desc->opnd_desc[i+opnd_skip].opnd_type) != 0)
625                 {
626                     isDst = true;
627                 }
628 
629                 if (isDst)
630                 {
631                     if (ISA_Inst_Table[opcode].type == ISA_Inst_Compare)
632                     {
633                         opnds[i] = NULL;
634                         PEAK_CISA_FIELD(tag, uint8_t, bytePos, buf);
635 
636                         if ((tag & 0x7) == OPERAND_GENERAL)
637                         {
638                             opnds[i] = readVectorOperandNG(bytePos, buf, tag, container, Get_VISA_Exec_Size(esize), true);
639                             cmpHasDst = true;
640 
641                         }else
642                         {
643                             dstDcl = readPreVarNG(bytePos, buf, container);
644                         }
645                     }
646                     else
647                         opnds[i] = readVectorOperandNG(bytePos, buf, tag, container, exSize, isDst);
648                 }
649                 else if (ISA_Inst_Table[opcode].type == ISA_Inst_Address && i == 1)
650                 {
651                     //for first source of address add instruction.
652                     opnds[i] = readVectorOperandNGAddressOf(bytePos, buf, container);
653                 }
654                 else if (i == 4 && opcode == ISA_BFN)
655                 {
656                     // read bfn booleanFuncCtrl from the last opnd
657                     int opnd_ix = i + opnd_skip;
658                     assert(inst_desc->opnd_desc[opnd_ix].opnd_type == OPND_OTHER &&
659                            "BFN: FuncCtrl opnd_desc's type should be OPND_OTHER!");
660                     VISA_Type visatype = (VISA_Type)inst_desc->opnd_desc[opnd_ix].data_type;
661                     bfn_func_ctrl = readOtherOperandNG(bytePos, buf, visatype);
662                 }
663                 else
664                 {
665                     opnds[i] = readVectorOperandNG(bytePos, buf, container, exSize);
666                 }
667 
668             }
669 
670             opnd_count -= opnd_skip;
671 
672             // skip booleanFuncCtrl, which is the last opnd
673             if (opcode == ISA_BFN)
674                 --opnd_count;
675 
676             bool             saturate = (((VISA_Modifier)((tag >> 3) & 0x7)) == MODIFIER_SAT);
677             VISA_VectorOpnd*      dst = opnds[0];
678             VISA_VectorOpnd*     src0 = opnds[1];
679             VISA_VectorOpnd*     src1 = opnd_count > 2 ? opnds[2] : NULL;
680             VISA_VectorOpnd*     src2 = opnd_count > 3 ? opnds[3] : NULL;
681             VISA_VectorOpnd*     src3 = opnd_count > 4 ? opnds[4] : NULL;
682 
683             switch (ISA_Inst_Table[opcode].type)
684             {
685             case ISA_Inst_Mov:
686                 if (opcode == ISA_FMINMAX)
687                     kernelBuilder->AppendVISAMinMaxInst((CISA_MIN_MAX_SUB_OPCODE)opSpec, saturate, emask, esize, dst, src0, src1);
688                 else
689                     kernelBuilder->AppendVISADataMovementInst(opcode, pred, saturate, emask, esize, dst, src0, src1);
690                 break;
691             case ISA_Inst_Arith:
692                 if (opcode == ISA_ADDC || opcode == ISA_SUBB)
693                 {
694                     kernelBuilder->AppendVISATwoDstArithmeticInst(opcode, pred, emask, esize, dst, src0, src1, src2);
695                 }
696                 else
697                 {
698                     kernelBuilder->AppendVISAArithmeticInst(opcode, pred, saturate, emask, esize, dst, src0, src1, src2);
699                 }
700                 break;
701             case ISA_Inst_Logic:
702                 if (opcode == ISA_BFN)
703                     kernelBuilder->AppendVISABfnInst(bfn_func_ctrl, pred, saturate, emask, esize, dst, src0, src1, src2);
704                 else
705                     kernelBuilder->AppendVISALogicOrShiftInst(opcode, pred, saturate, emask, esize, dst, src0, src1, src2, src3);
706                 break;
707             case ISA_Inst_Address:
708                 kernelBuilder->AppendVISAAddrAddInst(emask, esize, dst, src0, src1);
709                 break;
710             case ISA_Inst_Compare:
711                 if (dstDcl)
712                     kernelBuilder->AppendVISAComparisonInst((VISA_Cond_Mod)(opSpec & 0x7), emask, esize, dstDcl, src0, src1);
713                 else if (cmpHasDst)
714                     kernelBuilder->AppendVISAComparisonInst((VISA_Cond_Mod)(opSpec & 0x7), emask, esize, dst, src0, src1);
715                 else
716                     ASSERT_USER(true, "DST doesn't have valid GRF or FLAG dst.");
717                 break;
718             default:
719                 break;
720             }
721 
722             break;
723         }
724     case ISA_Inst_SIMD_Flow:
725         {
726             assert(opcode == ISA_GOTO && "expect goto instruction");
727             readExecSizeNG(bytePos, buf, esize, emask, container);
728             VISA_PredOpnd* pred = hasPredicate(opcode) ? readPredicateOperandNG(bytePos, buf, container) : nullptr;
729             VISA_LabelOpnd* label = opcode == ISA_GOTO ?
730                 container.labelVarDecls[readPrimitiveOperandNG<uint16_t>(bytePos, buf)] : nullptr;
731             kernelBuilder->AppendVISACFGotoInst(pred, emask, esize, label);
732             break;
733         }
734     case ISA_Inst_Sync:
735         {
736             if (opcode == ISA_WAIT)
737             {
738                 VISA_VectorOpnd* mask = NULL;
739                 if (getVersionAsInt(container.majorVersion, container.minorVersion) >=
740                     getVersionAsInt(3, 1))
741                 {
742                     // additional vector operand
743                     mask = readVectorOperandNG(bytePos, buf, container, false);
744                 }
745                 else
746                 {
747                     // set mask to 0
748                     uint16_t value = 0;
749                     kernelBuilder->CreateVISAImmediate(mask, &value, ISA_TYPE_UW);
750                 }
751                 kernelBuilder->AppendVISAWaitInst(mask);
752             }
753             else if (opcode == ISA_SBARRIER)
754             {
755                 uint32_t mode = readOtherOperandNG(bytePos, buf, ISA_TYPE_UB);
756                 kernelBuilder->AppendVISASplitBarrierInst(mode != 0);
757             }
758             else if (opcode == ISA_NBARRIER)
759             {
760                 uint32_t mode = readOtherOperandNG(bytePos, buf, ISA_TYPE_UB);
761                 auto barrierId = readVectorOperandNG(bytePos, buf, container, false);
762                 VISA_VectorOpnd* threadCount = readVectorOperandNG(bytePos, buf, container, false);
763                 bool isWait = (mode & 1) == 0;
764                 if (isWait)
765                 {
766                     kernelBuilder->AppendVISANamedBarrierWait(barrierId);
767                 }
768                 else
769                 {
770                     kernelBuilder->AppendVISANamedBarrierSignal(barrierId, threadCount);
771                 }
772             }
773             else
774             {
775                 bool hasMask = (opcode == ISA_FENCE);
776                 uint8_t mask = hasMask ? readPrimitiveOperandNG<uint8_t>(bytePos, buf) : 0;
777                 kernelBuilder->AppendVISASyncInst(opcode, mask);
778             }
779             break;
780         }
781     default:
782         {
783             assert(false && "Invalid common instruction type.");
784         }
785     }
786 }
787 
788 /// Read a byte which encodes the atomic opcode and a flag indicating whether
789 /// this is a 16bit atomic operation.
getAtomicOpAndBitwidth(unsigned & bytePos,const char * buf)790 std::tuple<VISAAtomicOps, unsigned short> getAtomicOpAndBitwidth(unsigned &bytePos,
791                                                                  const char *buf)
792 {
793     // bits 0-4 atomic op and bit 5-6 encode the bitwidth
794     uint8_t data = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
795     VISAAtomicOps op = static_cast<VISAAtomicOps>(data & 0x1F);
796     unsigned short bitwidth;
797     if (data >> 5 == 1)
798         bitwidth = 16;
799     else if (data >> 6 == 1)
800         bitwidth = 64;
801     else
802         bitwidth = 32;
803     return std::tie(op, bitwidth);
804 }
805 
readInstructionDataportNG(unsigned & bytePos,const char * buf,ISA_Opcode opcode,RoutineContainer & container)806 static void readInstructionDataportNG(unsigned& bytePos, const char* buf, ISA_Opcode opcode, RoutineContainer& container)
807 {
808     VISAKernel*     kernelBuilder     = container.kernelBuilder;
809     VISAKernelImpl* kernelBuilderImpl = ((VISAKernelImpl*)kernelBuilder);
810 
811     switch (opcode)
812     {
813     case ISA_MEDIA_ST:
814     case ISA_MEDIA_LD:
815         {
816             uint8_t      modifier = (ISA_MEDIA_LD == opcode || ISA_MEDIA_ST == opcode) ? readPrimitiveOperandNG<uint8_t>(bytePos, buf) : 0;
817             uint8_t       surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
818             uint8_t         plane = (ISA_MEDIA_LD == opcode || ISA_MEDIA_ST == opcode) ? readPrimitiveOperandNG<uint8_t>(bytePos, buf) : 0;
819             uint8_t         width = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
820             uint8_t        height = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
821             VISA_opnd*    xoffset = readVectorOperandNG(bytePos, buf, container, false);
822             VISA_opnd*    yoffset = readVectorOperandNG(bytePos, buf, container, false);
823             VISA_RawOpnd*     msg = readRawOperandNG(bytePos, buf, container);
824 
825             VISA_StateOpndHandle* surfaceHnd = NULL;
826             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
827 
828             kernelBuilder->AppendVISASurfAccessMediaLoadStoreInst(opcode, (MEDIA_LD_mod)modifier, surfaceHnd, width, height, (VISA_VectorOpnd*)xoffset, (VISA_VectorOpnd*)yoffset, msg, (CISA_PLANE_ID)plane);
829             break;
830         }
831     case ISA_OWORD_ST:
832     case ISA_OWORD_LD:
833     case ISA_OWORD_LD_UNALIGNED:
834         {
835             uint8_t              size = readPrimitiveOperandNG<uint8_t>(bytePos, buf) & 0x7;
836             if (ISA_OWORD_ST != opcode)
837             {
838                 readPrimitiveOperandNG<uint8_t>(bytePos, buf);
839             }  // modifier
840             uint8_t           surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
841             VISA_VectorOpnd*   offset = readVectorOperandNG(bytePos, buf, container, false);
842             VISA_RawOpnd*         msg = readRawOperandNG(bytePos, buf, container);
843 
844             VISA_StateOpndHandle* surfaceHnd = NULL;
845             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
846             kernelBuilder->AppendVISASurfAccessOwordLoadStoreInst(opcode, vISA_EMASK_M1, surfaceHnd, (VISA_Oword_Num)size, (VISA_VectorOpnd*)offset, msg);
847 
848             break;
849         }
850     case ISA_GATHER:
851     case ISA_SCATTER:
852         {
853             uint8_t elt_size = (ISA_SCATTER  == opcode || ISA_GATHER  == opcode) ? readPrimitiveOperandNG<uint8_t>(bytePos, buf) : 0;
854             if (ISA_GATHER == opcode)
855             {
856                 readPrimitiveOperandNG<uint8_t>(bytePos, buf);
857             } // modifier
858             uint8_t num_elts = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
859             uint8_t surface  = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
860 
861             VISA_VectorOpnd*  globalOffset = readVectorOperandNG(bytePos, buf, container, false);
862             VISA_RawOpnd*    elementOffset = readRawOperandNG(bytePos, buf, container);
863             VISA_RawOpnd*              msg = readRawOperandNG(bytePos, buf, container);
864 
865             VISA_StateOpndHandle* surfaceHnd = NULL;
866             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
867 
868             VISA_EMask_Ctrl emask = vISA_EMASK_M1;
869             VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
870 
871             /// TODO: Conversions like these make using vISA builder cumbersome.
872             switch (num_elts & 0x3)
873             {
874             case 0:
875                 esize = EXEC_SIZE_8;
876                 break;
877             case 1:
878                 esize = EXEC_SIZE_16;
879                 break;
880             case 2:
881                 esize = EXEC_SIZE_1;
882                 break;
883             default:
884                 MUST_BE_TRUE(false, "Invalid Number of Elements for Gather/Scatter.");
885             }
886 
887             emask = transformMask(container, num_elts >> 4);
888 
889             kernelBuilderImpl->AppendVISASurfAccessGatherScatterInst(opcode, emask, (GATHER_SCATTER_ELEMENT_SIZE)(elt_size & 0x3), esize, surfaceHnd, globalOffset, elementOffset, msg);
890             break;
891         }
892     case ISA_GATHER4_TYPED:
893     case ISA_SCATTER4_TYPED:
894         {
895             if (getVersionAsInt(container.majorVersion, container.minorVersion) >=
896                     getVersionAsInt(3, 2))
897             {
898                 VISA_EMask_Ctrl emask = vISA_EMASK_M1;
899                 VISA_Exec_Size esize = EXEC_SIZE_ILLEGAL;
900                 readExecSizeNG(bytePos, buf, esize, emask, container);
901 
902                 VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
903                 unsigned ch_mask = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
904                 uint8_t surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
905 
906                 VISA_RawOpnd* uOffset = readRawOperandNG(bytePos, buf, container);
907                 VISA_RawOpnd* vOffset = readRawOperandNG(bytePos, buf, container);
908                 VISA_RawOpnd* rOffset = readRawOperandNG(bytePos, buf, container);
909                 VISA_RawOpnd* lod = readRawOperandNG(bytePos, buf, container);
910                 VISA_RawOpnd* msg = readRawOperandNG(bytePos, buf, container);
911 
912                 VISA_StateOpndHandle* surfaceHnd = NULL;
913                 kernelBuilderImpl->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
914                 kernelBuilderImpl->AppendVISASurfAccessGather4Scatter4TypedInst(opcode, pred, ChannelMask::createAPIFromBinary(opcode, ch_mask), emask, esize, surfaceHnd, uOffset, vOffset, rOffset, lod, msg);
915             }
916             else
917             {
918                 uint8_t ch_mask = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
919 
920                 VISA_EMask_Ctrl emask = vISA_EMASK_M1;
921                 VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
922                 readExecSizeNG(bytePos, buf, esize, emask, container);
923 
924                 MUST_BE_TRUE(esize == 0, "Unsupported number of elements for ISA_SCATTER4_TYPED/ISA_GATHER4_TYPED.");
925                 esize = EXEC_SIZE_8;
926 
927                 uint8_t surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
928 
929                 VISA_RawOpnd* uOffset = readRawOperandNG(bytePos, buf, container);
930                 VISA_RawOpnd* vOffset = readRawOperandNG(bytePos, buf, container);
931                 VISA_RawOpnd* rOffset = readRawOperandNG(bytePos, buf, container);
932                 VISA_RawOpnd* lod = NULL;
933                 kernelBuilderImpl->CreateVISANullRawOperand(lod, false);
934                 VISA_RawOpnd*     msg = readRawOperandNG(bytePos, buf, container);
935 
936                 VISA_StateOpndHandle* surfaceHnd = NULL;
937                 kernelBuilderImpl->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
938                 ch_mask = ~ch_mask;
939                 kernelBuilderImpl->AppendVISASurfAccessGather4Scatter4TypedInst(opcode, NULL, ChannelMask::createAPIFromBinary(opcode, ch_mask), emask, esize, surfaceHnd, uOffset, vOffset, rOffset, lod, msg);
940             }
941             break;
942         }
943     case ISA_3D_RT_WRITE:
944         {
945             VISA_EMask_Ctrl emask = vISA_EMASK_M1;
946             VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
947             readExecSizeNG(bytePos, buf, esize, emask, container);
948 
949             VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
950 
951             uint16_t    mode = readPrimitiveOperandNG<uint16_t>(bytePos, buf);
952             uint8_t surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
953             VISA_RawOpnd *r1HeaderOpnd = readRawOperandNG(bytePos, buf, container);
954 
955             vISA_RT_CONTROLS cntrls;
956             cntrls.s0aPresent   = (mode & (0x1 << 3))?true:false;
957             cntrls.oMPresent    = (mode & (0x1 << 4))?true:false;
958             cntrls.zPresent     = (mode & (0x1 << 5))?true:false;
959             cntrls.isStencil    = (mode & (0x1 << 6))?true:false;
960             cntrls.isLastWrite  = (mode & (0x1 << 7))?true:false;
961             bool CPSEnable      = (mode & (0x1 << 8))?true:false;
962             cntrls.isPerSample   = (mode & (0x1 << 9))?true:false;
963             cntrls.isCoarseMode  = (mode & (0x1 << 10))? true:false;
964             cntrls.isSampleIndex = (mode & (0x1 << 11)) ? true : false;
965             cntrls.RTIndexPresent = (mode & (0x1 << 2)) ? true : false;
966             cntrls.isNullRT = (mode & (0x1 << 12)) ? true : false;
967             cntrls.isHeaderMaskfromCe0 = 0;
968 
969             VISA_VectorOpnd *sampleIndex = cntrls.isSampleIndex ? readVectorOperandNG(bytePos, buf, container, false) : NULL;
970             VISA_VectorOpnd *cpsCounter = CPSEnable ? readVectorOperandNG(bytePos, buf, container, false) : NULL;
971             VISA_VectorOpnd* rti = cntrls.RTIndexPresent ? readVectorOperandNG(bytePos, buf, container, false) : NULL;
972             VISA_RawOpnd* s0a = cntrls.s0aPresent ? readRawOperandNG(bytePos, buf, container) : NULL;
973             VISA_RawOpnd*  oM = cntrls.oMPresent  ? readRawOperandNG(bytePos, buf, container) : NULL;
974             VISA_RawOpnd*   R = readRawOperandNG(bytePos, buf, container);
975             VISA_RawOpnd*   G = readRawOperandNG(bytePos, buf, container);
976             VISA_RawOpnd*   B = readRawOperandNG(bytePos, buf, container);
977             VISA_RawOpnd*   A = readRawOperandNG(bytePos, buf, container);
978             VISA_RawOpnd*   Z = cntrls.zPresent ? readRawOperandNG(bytePos, buf, container) : NULL;
979             VISA_RawOpnd*   S = cntrls.isStencil ? readRawOperandNG(bytePos, buf, container) : NULL;
980 
981 
982             std::vector<VISA_RawOpnd*> rawOpndVector;
983             if (s0a) rawOpndVector.push_back(s0a);
984             if (oM) rawOpndVector.push_back(oM);
985             if (R) rawOpndVector.push_back(R);
986             if (G) rawOpndVector.push_back(G);
987             if (B) rawOpndVector.push_back(B);
988             if (A) rawOpndVector.push_back(A);
989             if (Z) rawOpndVector.push_back(Z);
990             if (S) rawOpndVector.push_back(S);
991 
992             VISA_StateOpndHandle* surfaceHnd = NULL;
993             kernelBuilderImpl->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
994             kernelBuilderImpl->AppendVISA3dRTWriteCPS(pred, emask, esize, rti, cntrls, surfaceHnd, r1HeaderOpnd, sampleIndex, cpsCounter, (uint8_t)rawOpndVector.size(), rawOpndVector.data());
995             break;
996         }
997     case ISA_GATHER4_SCALED:
998     case ISA_SCATTER4_SCALED: {
999         VISA_EMask_Ctrl eMask = vISA_EMASK_M1;
1000         VISA_Exec_Size exSize = EXEC_SIZE_ILLEGAL;
1001         readExecSizeNG(bytePos, buf, exSize, eMask, container);
1002 
1003         VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1004         unsigned channelMask = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1005         // scale is ignored and must be zero
1006         (void) readPrimitiveOperandNG<uint16_t>(bytePos, buf);
1007         uint8_t surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1008         VISA_VectorOpnd*  globalOffset
1009             = readVectorOperandNG(bytePos, buf, container, false);
1010         VISA_RawOpnd* offsets = readRawOperandNG(bytePos, buf, container);
1011         VISA_RawOpnd* dstOrSrc = readRawOperandNG(bytePos, buf, container);
1012 
1013         VISA_StateOpndHandle* surfaceHnd = NULL;
1014         kernelBuilderImpl
1015             ->CreateVISAStateOperandHandle(surfaceHnd,
1016                                            container.surfaceVarDecls[surface]);
1017         kernelBuilderImpl
1018             ->AppendVISASurfAccessGather4Scatter4ScaledInst(opcode, pred,
1019                                                             eMask, exSize,
1020                                                             ChannelMask::createAPIFromBinary(opcode,
1021                                                                                              channelMask),
1022                                                             surfaceHnd,
1023                                                             globalOffset,
1024                                                             offsets, dstOrSrc);
1025         break;
1026     }
1027     case ISA_GATHER_SCALED:
1028     case ISA_SCATTER_SCALED: {
1029         VISA_EMask_Ctrl eMask = vISA_EMASK_M1;
1030         VISA_Exec_Size exSize = EXEC_SIZE_ILLEGAL;
1031         readExecSizeNG(bytePos, buf, exSize, eMask, container);
1032 
1033         VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1034         // block size is ignored (MBZ)
1035         (void) readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1036         VISA_SVM_Block_Num  numBlocks =
1037             VISA_SVM_Block_Num(readPrimitiveOperandNG<uint8_t>(bytePos, buf));
1038         // scale is ignored (MBZ)
1039         (void) readPrimitiveOperandNG<uint16_t>(bytePos, buf);
1040         uint8_t surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1041         VISA_VectorOpnd*  globalOffset
1042             = readVectorOperandNG(bytePos, buf, container, false);
1043         VISA_RawOpnd* offsets = readRawOperandNG(bytePos, buf, container);
1044         VISA_RawOpnd* dstOrSrc = readRawOperandNG(bytePos, buf, container);
1045 
1046         VISA_StateOpndHandle* surfaceHnd = NULL;
1047         kernelBuilderImpl
1048             ->CreateVISAStateOperandHandle(surfaceHnd,
1049                                            container.surfaceVarDecls[surface]);
1050         kernelBuilderImpl
1051             ->AppendVISASurfAccessScatterScaledInst(opcode, pred,
1052                                                     eMask, exSize,
1053                                                     numBlocks,
1054                                                     surfaceHnd,
1055                                                     globalOffset,
1056                                                     offsets, dstOrSrc);
1057         break;
1058     }
1059     case ISA_DWORD_ATOMIC: {
1060         VISAAtomicOps subOpc;
1061         unsigned short bitwidth;
1062         std::tie(subOpc, bitwidth) = getAtomicOpAndBitwidth(bytePos, buf);
1063 
1064         VISA_EMask_Ctrl eMask = vISA_EMASK_M1;
1065         VISA_Exec_Size exSize = EXEC_SIZE_ILLEGAL;
1066         readExecSizeNG(bytePos, buf, exSize, eMask, container);
1067 
1068         VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1069         unsigned surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1070         VISA_RawOpnd* offsets = readRawOperandNG(bytePos, buf, container);
1071         VISA_RawOpnd* src0 = readRawOperandNG(bytePos, buf, container);
1072         VISA_RawOpnd* src1 = readRawOperandNG(bytePos, buf, container);
1073         VISA_RawOpnd* dst = readRawOperandNG(bytePos, buf, container);
1074 
1075         VISA_StateOpndHandle* surfaceHnd = NULL;
1076         kernelBuilderImpl
1077             ->CreateVISAStateOperandHandle(surfaceHnd,
1078                                            container.surfaceVarDecls[surface]);
1079         kernelBuilderImpl->AppendVISASurfAccessDwordAtomicInst(
1080             pred, subOpc, bitwidth == 16, eMask, exSize, surfaceHnd, offsets, src0,
1081             src1, dst);
1082         break;
1083     }
1084     case ISA_3D_TYPED_ATOMIC: {
1085         VISAAtomicOps subOpc;
1086         unsigned short bitwidth;
1087         std::tie(subOpc, bitwidth) = getAtomicOpAndBitwidth(bytePos, buf);
1088 
1089         VISA_EMask_Ctrl eMask = vISA_EMASK_M1;
1090         VISA_Exec_Size exSize = EXEC_SIZE_ILLEGAL;
1091         readExecSizeNG(bytePos, buf, exSize, eMask, container);
1092 
1093         VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1094         unsigned surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1095         VISA_RawOpnd* u = readRawOperandNG(bytePos, buf, container);
1096         VISA_RawOpnd* v = readRawOperandNG(bytePos, buf, container);
1097         VISA_RawOpnd* r = readRawOperandNG(bytePos, buf, container);
1098         VISA_RawOpnd* lod = readRawOperandNG(bytePos, buf, container);
1099         VISA_RawOpnd* src0 = readRawOperandNG(bytePos, buf, container);
1100         VISA_RawOpnd* src1 = readRawOperandNG(bytePos, buf, container);
1101         VISA_RawOpnd* dst = readRawOperandNG(bytePos, buf, container);
1102 
1103         VISA_StateOpndHandle* surfaceHnd = NULL;
1104         kernelBuilderImpl->CreateVISAStateOperandHandle(
1105             surfaceHnd, container.surfaceVarDecls[surface]);
1106         kernelBuilderImpl->AppendVISA3dTypedAtomic(subOpc, bitwidth == 16, pred, eMask,
1107                                                    exSize, surfaceHnd, u, v, r,
1108                                                    lod, src0, src1, dst);
1109         break;
1110     }
1111     case ISA_QW_GATHER:
1112     case ISA_QW_SCATTER:
1113     {
1114         VISA_EMask_Ctrl eMask = vISA_EMASK_M1;
1115         VISA_Exec_Size exSize = EXEC_SIZE_ILLEGAL;
1116         readExecSizeNG(bytePos, buf, exSize, eMask, container);
1117 
1118         VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1119         VISA_SVM_Block_Num  numBlocks =
1120             VISA_SVM_Block_Num(readPrimitiveOperandNG<uint8_t>(bytePos, buf));
1121         uint8_t surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1122         VISA_RawOpnd* offsets = readRawOperandNG(bytePos, buf, container);
1123         VISA_RawOpnd* dstOrSrc = readRawOperandNG(bytePos, buf, container);
1124 
1125         VISA_StateOpndHandle* surfaceHnd = nullptr;
1126         kernelBuilderImpl->CreateVISAStateOperandHandle(surfaceHnd,
1127                 container.surfaceVarDecls[surface]);
1128 
1129         if (opcode == ISA_QW_GATHER)
1130         {
1131             kernelBuilderImpl->AppendVISAQwordGatherInst(pred, eMask, exSize, numBlocks,
1132                 surfaceHnd, offsets, dstOrSrc);
1133         }
1134         else
1135         {
1136             kernelBuilderImpl->AppendVISAQwordScatterInst(pred, eMask, exSize, numBlocks,
1137                 surfaceHnd, offsets, dstOrSrc);
1138         }
1139         break;
1140     }
1141     default:
1142         {
1143             MUST_BE_TRUE(false, "Unimplemented or Illegal DataPort Opcode.");
1144         }
1145     }
1146 }
1147 
readInstructionControlFlow(unsigned & bytePos,const char * buf,ISA_Opcode opcode,RoutineContainer & container)1148 static void readInstructionControlFlow(unsigned& bytePos, const char* buf, ISA_Opcode opcode, RoutineContainer& container)
1149 {
1150     VISAKernel* kernelBuilder = container.kernelBuilder;
1151 
1152     VISA_EMask_Ctrl emask = vISA_EMASK_M1;
1153     VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
1154 
1155     switch (opcode)
1156     {
1157     case ISA_SUBROUTINE:
1158     case ISA_LABEL:
1159         {
1160             uint16_t labelId = readPrimitiveOperandNG<uint16_t>(bytePos, buf);
1161             VISA_LabelOpnd* label = container.labelVarDecls[labelId];
1162             kernelBuilder->AppendVISACFLabelInst(label);
1163             return;
1164         }
1165     case ISA_JMP:
1166     case ISA_RET:
1167     case ISA_CALL:
1168     case ISA_FRET:
1169     case ISA_FCALL:
1170         {
1171             readExecSizeNG(bytePos, buf, esize, emask, container);
1172             VISA_PredOpnd* pred = hasPredicate(opcode) ? readPredicateOperandNG(bytePos, buf, container) : NULL;
1173 
1174             uint16_t labelId = (opcode == ISA_JMP  || opcode == ISA_CALL || opcode == ISA_FCALL) ?
1175                 readPrimitiveOperandNG<uint16_t>(bytePos, buf) : 0;
1176 
1177             if (opcode == ISA_FCALL)
1178             {
1179                 uint8_t argSize = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1180                 uint8_t retSize = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1181                 kernelBuilder->AppendVISACFFunctionCallInst(pred, emask, esize, container.stringPool[labelId], argSize, retSize);
1182                 return;
1183             }
1184 
1185             switch (opcode)
1186             {
1187             case ISA_JMP  : kernelBuilder->AppendVISACFJmpInst (pred,               container.labelVarDecls[labelId]); return;
1188             case ISA_CALL : kernelBuilder->AppendVISACFCallInst(pred, emask, esize, container.labelVarDecls[labelId]); return;
1189 
1190             case ISA_RET  : kernelBuilder->AppendVISACFRetInst        (pred, emask, esize); return;
1191             case ISA_FRET : kernelBuilder->AppendVISACFFunctionRetInst(pred, emask, esize); return;
1192 
1193             default:
1194                 MUST_BE_TRUE(false, "Unimplemented or Illegal Control Flow Opcode.");
1195                 return;
1196 
1197             }
1198 
1199             return;
1200         }
1201     case ISA_IFCALL:
1202     {
1203         readExecSizeNG(bytePos, buf, esize, emask, container);
1204         VISA_PredOpnd* pred = hasPredicate(opcode) ? readPredicateOperandNG(bytePos, buf, container) : nullptr;
1205 
1206         VISA_VectorOpnd* funcAddr = readVectorOperandNG(bytePos, buf, container, false);
1207         uint8_t argSize = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1208         uint8_t retSize = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1209         kernelBuilder->AppendVISACFIndirectFuncCallInst(pred, emask, esize, funcAddr, argSize, retSize);
1210         return;
1211     }
1212     case ISA_FADDR:
1213     {
1214         uint16_t sym_name_idx = readPrimitiveOperandNG<uint16_t>(bytePos, buf);
1215         VISA_VectorOpnd* dst = readVectorOperandNG(bytePos, buf, container, true);
1216         kernelBuilder->AppendVISACFSymbolInst(container.stringPool[sym_name_idx], dst);
1217         return;
1218     }
1219     case ISA_SWITCHJMP:
1220         {
1221             VISA_EMask_Ctrl emask = vISA_EMASK_M1;
1222             VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
1223             readExecSizeNG(bytePos, buf, esize, emask, container);
1224 
1225             uint8_t numLabels = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1226             MUST_BE_TRUE(0 < numLabels && numLabels < 33, "Number of labels in SWITCHJMP must be between 1 and 32.");
1227 
1228             VISA_VectorOpnd* index = readVectorOperandNG(bytePos, buf, container, false);
1229 
1230             VISA_LabelOpnd* labels[32]; /// 32 is max
1231             for (unsigned i = 0; i < numLabels; i++)
1232                 labels[i] = container.labelVarDecls[readPrimitiveOperandNG<uint16_t>(bytePos, buf)];
1233 
1234             kernelBuilder->AppendVISACFSwitchJMPInst(index, numLabels, labels);
1235             break;
1236         }
1237     default:
1238         MUST_BE_TRUE(false, "Unimplemented or Illegal Control Flow Opcode.");
1239     }
1240 }
1241 
readInstructionMisc(unsigned & bytePos,const char * buf,ISA_Opcode opcode,RoutineContainer & container)1242 static void readInstructionMisc(unsigned& bytePos, const char* buf, ISA_Opcode opcode, RoutineContainer& container)
1243 {
1244     VISAKernel*     kernelBuilder     = container.kernelBuilder;
1245 
1246     switch (opcode)
1247     {
1248     case ISA_FILE:
1249         {
1250             uint32_t versionInt = getVersionAsInt(container.majorVersion, container.minorVersion);
1251             bool is3Dot4Plus = versionInt >= getVersionAsInt(3, 4);
1252             uint32_t filenameIndex = is3Dot4Plus ? readPrimitiveOperandNG<uint32_t>(bytePos, buf) :
1253                 readPrimitiveOperandNG<uint16_t>(bytePos, buf);
1254             const char* filename = container.stringPool[filenameIndex].c_str();
1255             kernelBuilder->AppendVISAMiscFileInst((char*)filename);
1256             break;
1257         }
1258     case ISA_LOC:
1259         {
1260             unsigned lineNumber = readPrimitiveOperandNG<unsigned>(bytePos, buf);
1261             kernelBuilder->AppendVISAMiscLOC(lineNumber);
1262             break;
1263         }
1264     case ISA_RAW_SEND:
1265         {
1266             uint8_t modifier = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1267 
1268             VISA_EMask_Ctrl emask = vISA_EMASK_M1;
1269             VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
1270             readExecSizeNG(bytePos, buf, esize, emask, container);
1271 
1272             VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1273 
1274             unsigned exMsgDesc = readPrimitiveOperandNG<unsigned>(bytePos, buf);
1275             uint8_t     numSrc = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1276             uint8_t     numDst = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1277 
1278             VISA_VectorOpnd* desc = readVectorOperandNG(bytePos, buf, container, false);
1279             VISA_RawOpnd*     src = readRawOperandNG   (bytePos, buf, container);
1280             VISA_RawOpnd*     dst = readRawOperandNG   (bytePos, buf, container);
1281 
1282             kernelBuilder->AppendVISAMiscRawSend(pred, emask, esize, modifier, exMsgDesc, numSrc, numDst, desc, src, dst);
1283             break;
1284         }
1285     case ISA_RAW_SENDS:
1286         {
1287             uint8_t modifier = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1288             bool hasEOT = modifier & 0x2;
1289 
1290             VISA_EMask_Ctrl emask = vISA_EMASK_M1;
1291             VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
1292             readExecSizeNG(bytePos, buf, esize, emask, container);
1293 
1294             VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1295 
1296             uint8_t     numSrc0 = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1297             uint8_t     numSrc1 = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1298             uint8_t     numDst = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1299             uint8_t     ffid = 0;
1300             if (getVersionAsInt(container.majorVersion, container.minorVersion) >
1301                     getVersionAsInt(3, 5))
1302             {
1303                 ffid = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1304             }
1305             VISA_VectorOpnd* exMsgDesc = readVectorOperandNG(bytePos, buf, container, false);
1306 
1307             VISA_VectorOpnd* desc = readVectorOperandNG(bytePos, buf, container, false);
1308             VISA_RawOpnd*     src0 = readRawOperandNG   (bytePos, buf, container);
1309             VISA_RawOpnd*     src1 = readRawOperandNG   (bytePos, buf, container);
1310             VISA_RawOpnd*     dst = readRawOperandNG   (bytePos, buf, container);
1311 
1312             kernelBuilder->AppendVISAMiscRawSends(pred, emask, esize, modifier, ffid, exMsgDesc, numSrc0, numSrc1, numDst, desc, src0, src1, dst, hasEOT);
1313             break;
1314 
1315         }
1316     case ISA_VME_FBR:
1317         {
1318             VISA_RawOpnd*    UNIInput       = readRawOperandNG(bytePos, buf, container);
1319             VISA_RawOpnd*    FBRInput       = readRawOperandNG(bytePos, buf, container);
1320             uint8_t          surface        = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1321             VISA_VectorOpnd* FBRMbMode      = readVectorOperandNG(bytePos, buf, container,false);
1322             VISA_VectorOpnd* FBRSubMbShape  = readVectorOperandNG(bytePos, buf, container,false);
1323             VISA_VectorOpnd* FBRSubPredMode = readVectorOperandNG(bytePos, buf, container,false);
1324             VISA_RawOpnd*    output         = readRawOperandNG(bytePos, buf, container);
1325 
1326             VISA_StateOpndHandle* surfaceHnd = NULL;
1327             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
1328             kernelBuilder->AppendVISAMiscVME_FBR(surfaceHnd, UNIInput, FBRInput, FBRMbMode, FBRSubMbShape, FBRSubPredMode, output);
1329             break;
1330         }
1331     case ISA_VME_IME:
1332         {
1333             uint8_t       streamMode = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1334             uint8_t       searchCtrl = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1335 
1336             VISA_RawOpnd* UNIInput   = readRawOperandNG(bytePos, buf, container);
1337 
1338             VISA_RawOpnd* IMEInput   = readRawOperandNG(bytePos, buf, container);
1339 
1340             uint8_t       surface    = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1341             VISA_RawOpnd* ref0       = readRawOperandNG(bytePos, buf, container); //, 2);
1342             VISA_RawOpnd* ref1       = readRawOperandNG(bytePos, buf, container); //, 2);
1343             VISA_RawOpnd* costCenter = readRawOperandNG(bytePos, buf, container); //, 4);
1344             VISA_RawOpnd* output     = readRawOperandNG(bytePos, buf, container);
1345 
1346             VISA_StateOpndHandle* surfaceHnd = NULL;
1347             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
1348             kernelBuilder->AppendVISAMiscVME_IME(surfaceHnd, streamMode, searchCtrl, UNIInput, IMEInput, ref0, ref1, costCenter, output);
1349             break;
1350         }
1351     case ISA_VME_SIC:
1352         {
1353             VISA_RawOpnd* UNIInput = readRawOperandNG(bytePos, buf, container);
1354             VISA_RawOpnd* SICInput = readRawOperandNG(bytePos, buf, container); //, 128); //SICInput
1355             uint8_t       surface  = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1356             VISA_RawOpnd* output   = readRawOperandNG(bytePos, buf, container);
1357 
1358             VISA_StateOpndHandle* surfaceHnd = NULL;
1359             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
1360 
1361             kernelBuilder->AppendVISAMiscVME_SIC(surfaceHnd, UNIInput, SICInput, output);
1362             break;
1363         }
1364     case ISA_VME_IDM:
1365         {
1366             VISA_RawOpnd* UNIInput = readRawOperandNG(bytePos, buf, container); //, 4*32);
1367             VISA_RawOpnd* IDMInput = readRawOperandNG(bytePos, buf, container); //, 32); //DMInput
1368             uint8_t       surface  = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1369             VISA_RawOpnd* output   = readRawOperandNG(bytePos, buf, container);
1370 
1371             VISA_StateOpndHandle* surfaceHnd = NULL;
1372             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
1373 
1374             kernelBuilder->AppendVISAMiscVME_IDM(surfaceHnd, UNIInput, IDMInput, output);
1375             break;
1376         }
1377     case ISA_3D_URB_WRITE:
1378         {
1379             VISA_EMask_Ctrl emask = vISA_EMASK_M1;
1380             VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
1381             readExecSizeNG(bytePos, buf, esize, emask, container);
1382 
1383             VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1384 
1385             uint8_t        numOut = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1386             VISA_RawOpnd*  channelMask = readRawOperandNG(bytePos, buf, container);
1387             uint16_t globalOffset = readPrimitiveOperandNG<uint16_t>(bytePos, buf);
1388 
1389             VISA_RawOpnd*     urbHandle = readRawOperandNG(bytePos, buf, container);
1390             VISA_RawOpnd* perSlotOffset = readRawOperandNG(bytePos, buf, container);
1391 
1392             VISA_RawOpnd* vertexData = readRawOperandNG(bytePos, buf, container);
1393 
1394             kernelBuilder->AppendVISA3dURBWrite(pred, emask, esize, numOut, channelMask, globalOffset, urbHandle, perSlotOffset, vertexData);
1395             break;
1396         }
1397     case ISA_DPAS:
1398     case ISA_DPASW:
1399     {
1400         GenPrecision A = GenPrecision::INVALID, W = GenPrecision::INVALID;
1401         uint8_t D = 0;
1402         uint8_t C = 0;
1403 
1404         VISA_EMask_Ctrl emask = vISA_EMASK_M1;
1405         VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
1406         readExecSizeNG(bytePos, buf, esize, emask, container);
1407 
1408         VISA_RawOpnd* dst = readRawOperandNG(bytePos, buf, container);
1409         VISA_RawOpnd* src0 = readRawOperandNG(bytePos, buf, container);
1410         VISA_RawOpnd* src1 = readRawOperandNG(bytePos, buf, container);
1411 
1412         uint8_t tag = 0;
1413         VISA_VectorOpnd* src2 = readVectorOperandNG(
1414             bytePos, buf, tag, container,
1415             Get_VISA_Exec_Size(esize), false);
1416 
1417         VISA_INST_Desc* inst_desc = &CISA_INST_table[opcode];
1418 
1419         // sanity check
1420         assert(inst_desc->opnd_desc[5].opnd_type == OPND_OTHER &&
1421             "opnd_desc's type at index = 5 should be OPND_OTHER!");
1422 
1423         VISA_Type visatype = (VISA_Type)inst_desc->opnd_desc[5].data_type;
1424         uint32_t dpasOtherOpnd = readOtherOperandNG(bytePos, buf, visatype);
1425         UI32ToDpasInfo(dpasOtherOpnd, A, W, D, C);
1426 
1427         kernelBuilder->AppendVISADpasInst(opcode, emask, esize, dst, src0, src1, src2, A, W, D, C);
1428         break;
1429     }
1430     case ISA_LIFETIME:
1431     {
1432         VISA_VectorOpnd* opnd = NULL;
1433         Common_ISA_Operand_Class opndClass;
1434         VISAVarLifetime lifetime;
1435 
1436         unsigned char properties = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1437         uint32_t versionInt = getVersionAsInt(container.majorVersion, container.minorVersion);
1438         uint32_t varId = versionInt >= getVersionAsInt(3, 4) ? readPrimitiveOperandNG<uint32_t>(bytePos, buf) :
1439             readPrimitiveOperandNG<uint16_t>(bytePos, buf);
1440 
1441         opndClass = (Common_ISA_Operand_Class)(properties >> 4);
1442         lifetime = (VISAVarLifetime)(properties & 0x1);
1443 
1444         if (opndClass == OPERAND_GENERAL)
1445         {
1446             VISA_GenVar* decl;
1447 
1448             decl = container.generalVarDecls[varId];
1449 
1450             if (lifetime == LIFETIME_START)
1451             {
1452                 kernelBuilder->CreateVISADstOperand(opnd, decl, 1, 0, 0);
1453             }
1454             else
1455             {
1456                 kernelBuilder->CreateVISASrcOperand(opnd, decl, MODIFIER_NONE, 0, 1, 0, 0, 0);
1457             }
1458         }
1459         else if (opndClass == OPERAND_ADDRESS)
1460         {
1461             VISA_AddrVar* decl;
1462             decl = container.addressVarDecls[varId];
1463 
1464             if (lifetime == LIFETIME_START)
1465             {
1466                 kernelBuilder->CreateVISAAddressDstOperand(opnd, decl, 0);
1467             }
1468             else
1469             {
1470                 kernelBuilder->CreateVISAAddressSrcOperand(opnd, decl, 0, 1);
1471             }
1472         }
1473         else if (opndClass == OPERAND_PREDICATE)
1474         {
1475             VISA_PredVar* decl;
1476 
1477             decl = container.predicateVarDecls[varId];
1478             VISA_PredOpnd* predOpnd;
1479             kernelBuilder->CreateVISAPredicateOperand(predOpnd, decl, PredState_NO_INVERSE, PRED_CTRL_NON);
1480             opnd = (VISA_VectorOpnd*)predOpnd;
1481         }
1482 
1483         kernelBuilder->AppendVISALifetime(lifetime, opnd);
1484         break;
1485     }
1486     default:
1487         {
1488             MUST_BE_TRUE(false, "Unimplemented or Illegal Misc Opcode.");
1489         }
1490     }
1491 }
1492 
readInstructionSVM(unsigned & bytePos,const char * buf,ISA_Opcode opcode,RoutineContainer & container)1493 static void readInstructionSVM(unsigned& bytePos, const char* buf, ISA_Opcode opcode, RoutineContainer& container)
1494 {
1495     VISA_EMask_Ctrl emask = vISA_EMASK_M1;
1496     VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
1497 
1498     VISAKernel*     kernelBuilder     = container.kernelBuilder;
1499 
1500     SVMSubOpcode subOpcode = (SVMSubOpcode)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1501     switch (subOpcode)
1502     {
1503     case SVM_BLOCK_ST:
1504     case SVM_BLOCK_LD:
1505         {
1506             uint8_t          numOWords = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1507             bool             unaligned = (numOWords & 8) != 0;
1508             numOWords &= 7;
1509             VISA_VectorOpnd*   address = readVectorOperandNG(bytePos, buf, container,false);
1510             VISA_RawOpnd*          dst = readRawOperandNG(bytePos, buf, container);
1511 
1512             if (subOpcode == SVM_BLOCK_LD)
1513             {
1514                 kernelBuilder->AppendVISASvmBlockLoadInst(VISA_Oword_Num(numOWords), unaligned, address, dst);
1515             }
1516             else
1517             {
1518                 kernelBuilder->AppendVISASvmBlockStoreInst(VISA_Oword_Num(numOWords), unaligned, address, dst);
1519             }
1520             break;
1521         }
1522     case SVM_GATHER:
1523     case SVM_SCATTER:
1524         {
1525             readExecSizeNG(bytePos, buf, esize, emask, container);
1526             VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1527 
1528             VISA_SVM_Block_Type blockSize = VISA_SVM_Block_Type(readPrimitiveOperandNG<uint8_t>(bytePos, buf) & 0x3);
1529             VISA_SVM_Block_Num  numBlocks = VISA_SVM_Block_Num(readPrimitiveOperandNG<uint8_t>(bytePos, buf) & 0x3);
1530             VISA_RawOpnd* addresses = readRawOperandNG(bytePos, buf, container);
1531             VISA_RawOpnd*       dst = readRawOperandNG(bytePos, buf, container);
1532 
1533             if (subOpcode == SVM_GATHER)
1534             {
1535                 kernelBuilder->AppendVISASvmGatherInst(pred, emask, esize, blockSize, numBlocks, addresses, dst);
1536             }
1537             else
1538             {
1539                 kernelBuilder->AppendVISASvmScatterInst(pred, emask, esize, blockSize, numBlocks, addresses, dst);
1540             }
1541             break;
1542         }
1543     case SVM_ATOMIC:
1544         {
1545             readExecSizeNG(bytePos, buf, esize, emask, container);
1546             VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1547 
1548             VISAAtomicOps op;
1549             unsigned short bitwidth;
1550             std::tie(op, bitwidth) = getAtomicOpAndBitwidth(bytePos, buf);
1551 
1552             VISA_RawOpnd* addresses = readRawOperandNG(bytePos, buf, container);
1553             VISA_RawOpnd*      src0 = readRawOperandNG(bytePos, buf, container);
1554             VISA_RawOpnd*      src1 = readRawOperandNG(bytePos, buf, container);
1555             VISA_RawOpnd*       dst = readRawOperandNG(bytePos, buf, container);
1556 
1557             kernelBuilder->AppendVISASvmAtomicInst(
1558                 pred, emask, esize, op, bitwidth, addresses, src0, src1, dst);
1559             break;
1560         }
1561     case SVM_GATHER4SCALED: {
1562         readExecSizeNG(bytePos, buf, esize, emask, container);
1563         VISA_PredOpnd *pred = readPredicateOperandNG(bytePos, buf, container);
1564         unsigned channelMask = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1565         // scale is ignored and MBZ
1566         (void) readPrimitiveOperandNG<uint16_t>(bytePos, buf);
1567         VISA_VectorOpnd* address = readVectorOperandNG(bytePos, buf, container, false);
1568         VISA_RawOpnd* offsets = readRawOperandNG(bytePos, buf, container);
1569         VISA_RawOpnd* dst = readRawOperandNG(bytePos, buf, container);
1570         kernelBuilder
1571             ->AppendVISASvmGather4ScaledInst(pred, emask, esize,
1572                                              ChannelMask::createAPIFromBinary(ISA_SVM,
1573                                                                               channelMask),
1574                                              address,
1575                                              offsets, dst);
1576         break;
1577     }
1578     case SVM_SCATTER4SCALED: {
1579         readExecSizeNG(bytePos, buf, esize, emask, container);
1580         VISA_PredOpnd *pred = readPredicateOperandNG(bytePos, buf, container);
1581         unsigned channelMask = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1582         // scale is ignored and MBZ
1583         (void) readPrimitiveOperandNG<uint16_t>(bytePos, buf);
1584         VISA_VectorOpnd* address = readVectorOperandNG(bytePos, buf, container, false);
1585         VISA_RawOpnd* offsets = readRawOperandNG(bytePos, buf, container);
1586         VISA_RawOpnd* dst = readRawOperandNG(bytePos, buf, container);
1587         kernelBuilder
1588             ->AppendVISASvmScatter4ScaledInst(pred, emask, esize,
1589                                               ChannelMask::createAPIFromBinary(ISA_SVM,
1590                                                                                channelMask),
1591                                               address,
1592                                               offsets, dst);
1593         break;
1594     }
1595     default:
1596         MUST_BE_TRUE(false, "Unimplemented or Illegal SVM Sub Opcode.");
1597     }
1598 }
1599 
1600 static VISA3DSamplerOp
readSubOpcodeByteNG(unsigned & bytePos,const char * buf)1601 readSubOpcodeByteNG(unsigned& bytePos, const char* buf)
1602 {
1603     uint8_t val = 0;
1604     READ_CISA_FIELD(val, uint8_t, bytePos, buf);
1605     return VISA3DSamplerOp::extractSamplerOp(val);
1606 }
1607 
readAoffimmi(uint32_t & bytePos,const char * buf,RoutineContainer & container)1608 static VISA_VectorOpnd* readAoffimmi(uint32_t& bytePos, const char* buf, RoutineContainer& container)
1609 {
1610     VISAKernel*     kernelBuilder = container.kernelBuilder;
1611     uint32_t versionInt = getVersionAsInt(container.majorVersion, container.minorVersion);
1612     bool is3Dot4Plus = versionInt >= getVersionAsInt(3, 4);
1613     VISA_VectorOpnd* aoffimmi = nullptr;
1614     if (is3Dot4Plus)
1615     {
1616         aoffimmi = readVectorOperandNG(bytePos, buf, container, false);
1617     }
1618     else
1619     {
1620         uint16_t aoffimmiVal = readPrimitiveOperandNG<uint16_t>(bytePos, buf);
1621         kernelBuilder->CreateVISAImmediate(aoffimmi, &aoffimmiVal, ISA_TYPE_UW);
1622     }
1623     return aoffimmi;
1624 }
1625 
1626 
readInstructionSampler(unsigned & bytePos,const char * buf,ISA_Opcode opcode,RoutineContainer & container)1627 static void readInstructionSampler(unsigned& bytePos, const char* buf, ISA_Opcode opcode, RoutineContainer& container)
1628 {
1629     VISAKernel*     kernelBuilder     = container.kernelBuilder;
1630     VISAKernelImpl* kernelBuilderImpl = ((VISAKernelImpl*)kernelBuilder);
1631 
1632     switch (opcode)
1633     {
1634     case ISA_AVS:
1635         {
1636             uint8_t chanelMask = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1637             VISAChannelMask channel =  ChannelMask::createAPIFromBinary(ISA_AVS, chanelMask);
1638             uint8_t sampler = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1639             uint8_t surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1640 
1641             VISA_VectorOpnd* uOffset = readVectorOperandNG(bytePos, buf, container,false);
1642             VISA_VectorOpnd* vOffset = readVectorOperandNG(bytePos, buf, container,false);
1643             VISA_VectorOpnd*   deltaU = readVectorOperandNG(bytePos, buf, container,false);
1644             VISA_VectorOpnd*   deltaV = readVectorOperandNG(bytePos, buf, container,false);
1645             VISA_VectorOpnd*      u2d = readVectorOperandNG(bytePos, buf, container,false);
1646 
1647             VISA_VectorOpnd*           groupID = readVectorOperandNG(bytePos, buf, container,false);
1648             VISA_VectorOpnd* verticalBlockNumber = readVectorOperandNG(bytePos, buf, container,false);
1649             uint8_t                      cntrl = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1650             VISA_VectorOpnd*       v2d = readVectorOperandNG(bytePos, buf, container,false);
1651             uint8_t           execMode = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1652             VISA_VectorOpnd* IEFBypass = readVectorOperandNG(bytePos, buf, container,false);
1653             VISA_RawOpnd* dst = readRawOperandNG(bytePos, buf, container);
1654 
1655             VISA_StateOpndHandle* surfaceHnd = NULL;
1656             VISA_StateOpndHandle* samplerHnd = NULL;
1657             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
1658             kernelBuilder->CreateVISAStateOperandHandle(samplerHnd, container.samplerVarDecls[sampler]);
1659 
1660             kernelBuilder->AppendVISAMEAVS(surfaceHnd, samplerHnd, channel, uOffset, vOffset, deltaU,
1661                 deltaV, u2d, v2d, groupID, verticalBlockNumber, (OutputFormatControl)cntrl, (AVSExecMode)execMode, IEFBypass, dst);
1662             break;
1663         }
1664     case ISA_LOAD:
1665     case ISA_SAMPLE:
1666         {
1667             uint8_t mode = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1668             uint8_t sampler = (ISA_SAMPLE == opcode) ? readPrimitiveOperandNG<uint8_t>(bytePos, buf) : 0;
1669             uint8_t surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1670 
1671             VISA_RawOpnd* uOffset = readRawOperandNG(bytePos, buf, container);
1672             VISA_RawOpnd* vOffset = readRawOperandNG(bytePos, buf, container);
1673             VISA_RawOpnd* roffset = readRawOperandNG(bytePos, buf, container);
1674             VISA_RawOpnd*     dst = readRawOperandNG(bytePos, buf, container);
1675 
1676             uint8_t  channel = mode & 0xF;
1677             bool    isSimd16 = 0x0 != ((mode >> 4) & 0x3);
1678 
1679             VISA_StateOpndHandle* surfaceHnd = NULL;
1680             VISA_StateOpndHandle* samplerHnd = NULL;
1681             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
1682 
1683             if (opcode == ISA_SAMPLE)
1684             {
1685                 kernelBuilderImpl->CreateVISAStateOperandHandle(samplerHnd, container.samplerVarDecls[sampler]);
1686                 kernelBuilderImpl->AppendVISASISample(vISA_EMASK_M1, surfaceHnd, samplerHnd, ChannelMask::createAPIFromBinary(opcode, channel), isSimd16, uOffset, vOffset, roffset, dst);
1687             }
1688             else
1689                 kernelBuilderImpl->AppendVISASILoad(surfaceHnd, ChannelMask::createAPIFromBinary(opcode, channel), isSimd16, uOffset, vOffset, roffset, dst);
1690             break;
1691         }
1692     case ISA_SAMPLE_UNORM:
1693         {
1694             uint8_t channelMask = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1695             uint8_t     sampler = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1696             uint8_t     surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1697             CHANNEL_OUTPUT_FORMAT channelOutput = (CHANNEL_OUTPUT_FORMAT)ChannelMask::getChannelOutputFormat(channelMask);
1698 
1699             VISA_VectorOpnd* uOffset = readVectorOperandNG(bytePos, buf, container,false);
1700             VISA_VectorOpnd* vOffset = readVectorOperandNG(bytePos, buf, container,false);
1701             VISA_VectorOpnd*  deltaU = readVectorOperandNG(bytePos, buf, container,false);
1702             VISA_VectorOpnd*  deltaV = readVectorOperandNG(bytePos, buf, container,false);
1703 
1704             VISA_RawOpnd* dst = readRawOperandNG(bytePos, buf, container);
1705 
1706             VISA_StateOpndHandle* surfaceHnd = NULL;
1707             VISA_StateOpndHandle* samplerHnd = NULL;
1708             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
1709             kernelBuilderImpl->CreateVISAStateOperandHandle(samplerHnd, container.samplerVarDecls[sampler]);
1710             kernelBuilderImpl->AppendVISASISampleUnorm(surfaceHnd, samplerHnd, ChannelMask::createAPIFromBinary(opcode, channelMask), uOffset, vOffset, deltaU, deltaV, dst, channelOutput);
1711             break;
1712         }
1713     case ISA_3D_SAMPLE:
1714         {
1715             // 0x6D <op> <pixel_null_mask> <cps_enable> <exec_size> <pred>
1716             // <channels> <aoffimmi> <sampler> <surface> <dst> <numParams> <params>
1717             auto op = readSubOpcodeByteNG(bytePos, buf);
1718 
1719             VISA_EMask_Ctrl emask = vISA_EMASK_M1;
1720             VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
1721             readExecSizeNG(bytePos, buf, esize, emask, container);
1722 
1723             VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1724             uint8_t channelMask = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1725             VISA_VectorOpnd* aoffimmi = readAoffimmi(bytePos, buf, container);
1726             uint8_t sampler = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1727             uint8_t surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1728 
1729             VISA_RawOpnd*     dst = readRawOperandNG(bytePos, buf, container);
1730             uint8_t numParams = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1731 
1732             MUST_BE_TRUE(numParams < 16, "number of parameters for 3D_Sample should be < 16");
1733 
1734             VISA_RawOpnd* params[16];
1735             for (int i = 0; i < numParams; ++i)
1736             {
1737                 params[i] = readRawOperandNG(bytePos, buf, container);
1738             }
1739             VISA_StateOpndHandle* surfaceHnd = NULL;
1740             VISA_StateOpndHandle* samplerHnd = NULL;
1741             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
1742             kernelBuilderImpl->CreateVISAStateOperandHandle(samplerHnd, container.samplerVarDecls[sampler]);
1743             kernelBuilderImpl->AppendVISA3dSampler(op.opcode, op.pixelNullMask, op.cpsEnable, !op.nonUniformSampler, pred, emask, esize,
1744                 ChannelMask::createAPIFromBinary(opcode, channelMask), aoffimmi, samplerHnd, surfaceHnd,
1745                 dst, numParams, params);
1746             break;
1747         }
1748     case ISA_3D_LOAD:
1749         {
1750             // 0x6E <op> <pixel_null_mask> <exec_size> <pred> <channels>
1751             // <aoffimmi> <surface> <dst> <numParams> <params>
1752             // same as 3D_SAMPLE, except that sampler is missing.
1753             auto op = readSubOpcodeByteNG(bytePos, buf);
1754 
1755             VISA_EMask_Ctrl emask = vISA_EMASK_M1;
1756             VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
1757             readExecSizeNG(bytePos, buf, esize, emask, container);
1758 
1759             VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1760             uint8_t channelMask = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1761             VISA_VectorOpnd* aoffimmi = readAoffimmi(bytePos, buf, container);
1762             uint8_t surface = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1763 
1764             VISA_RawOpnd*     dst = readRawOperandNG(bytePos, buf, container);
1765             uint8_t numParams = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1766 
1767             MUST_BE_TRUE(numParams < 16, "number of parameters for 3D_Load should be < 16");
1768 
1769             VISA_RawOpnd* params[16];
1770             for (int i = 0; i < numParams; ++i)
1771             {
1772                 params[i] = readRawOperandNG(bytePos, buf, container);
1773             }
1774             VISA_StateOpndHandle* surfaceHnd = NULL;
1775             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
1776             kernelBuilderImpl->AppendVISA3dLoad(op.opcode, op.pixelNullMask, pred, emask, esize,
1777                 ChannelMask::createAPIFromBinary(opcode, channelMask), aoffimmi, surfaceHnd,
1778                 dst, numParams, params);
1779             break;
1780         }
1781     case ISA_3D_GATHER4:
1782         {
1783             auto op = readSubOpcodeByteNG(bytePos, buf);
1784 
1785             VISA_EMask_Ctrl emask = vISA_EMASK_M1;
1786             VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
1787             readExecSizeNG(bytePos, buf, esize, emask, container);
1788 
1789             VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
1790 
1791             uint8_t   channel = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1792             VISA_VectorOpnd* aoffimmi = readAoffimmi(bytePos, buf, container);
1793             uint8_t   sampler = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1794             uint8_t   surface = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1795 
1796             VISA_RawOpnd* dst = readRawOperandNG(bytePos, buf, container);
1797             uint8_t numParams = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1798 
1799             MUST_BE_TRUE(numParams < 8, "number of parameters for 3D_Gather4 should be < 8");
1800 
1801             VISA_RawOpnd* params[16];
1802             for (int i = 0; i < numParams; ++i)
1803             {
1804                 params[i] = readRawOperandNG(bytePos, buf, container);
1805             }
1806             VISA_StateOpndHandle* surfaceHnd = NULL;
1807             VISA_StateOpndHandle* samplerHnd = NULL;
1808             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
1809             kernelBuilderImpl->CreateVISAStateOperandHandle(samplerHnd, container.samplerVarDecls[sampler]);
1810             kernelBuilder->AppendVISA3dGather4(op.opcode, op.pixelNullMask, pred, emask, esize,
1811                 (VISASourceSingleChannel)channel, aoffimmi, samplerHnd, surfaceHnd,
1812                 dst, numParams, params);
1813             break;
1814         }
1815     case ISA_3D_INFO:
1816         {
1817             VISASampler3DSubOpCode subOpcode = (VISASampler3DSubOpCode)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1818 
1819             VISA_EMask_Ctrl emask = vISA_EMASK_M1;
1820             VISA_Exec_Size  esize = EXEC_SIZE_ILLEGAL;
1821             readExecSizeNG(bytePos, buf, esize, emask, container);
1822             uint8_t channelMask = 0xF;
1823             channelMask = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1824             uint8_t surface = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1825 
1826             VISA_RawOpnd* lod = subOpcode == VISA_3D_RESINFO ? readRawOperandNG(bytePos, buf, container) : NULL;
1827             VISA_RawOpnd* dst = readRawOperandNG(bytePos, buf, container);
1828 
1829             VISA_StateOpndHandle* surfaceHnd = NULL;
1830             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
1831             kernelBuilder->AppendVISA3dInfo(subOpcode, emask, esize, ChannelMask::createAPIFromBinary(opcode, channelMask), surfaceHnd, lod, dst);
1832 
1833             break;
1834         }
1835     case ISA_VA:
1836         {
1837             /// subOpcode
1838             ISA_VA_Sub_Opcode subOpcode = (ISA_VA_Sub_Opcode)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1839 
1840             VISA_StateOpndHandle* surfaceHnd = NULL;
1841             VISA_StateOpndHandle* samplerHnd = NULL;
1842             uint8_t sampler = 0;
1843 
1844             switch (subOpcode)
1845             {
1846                 case MINMAXFILTER_FOPCODE:
1847                 case Convolve_FOPCODE:
1848                 case Dilate_FOPCODE:
1849                 case ERODE_FOPCODE:
1850                     {
1851                         sampler = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1852                         kernelBuilderImpl->CreateVISAStateOperandHandle(samplerHnd, container.samplerVarDecls[sampler]);
1853                         break;
1854                     }
1855                 default:
1856                     break; // Prevent gcc warning
1857             }
1858 
1859             uint8_t surface = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1860             kernelBuilder->CreateVISAStateOperandHandle(surfaceHnd, container.surfaceVarDecls[surface]);
1861 
1862             VISA_VectorOpnd* uOffset = readVectorOperandNG(bytePos, buf, container, false);
1863             VISA_VectorOpnd* vOffset = readVectorOperandNG(bytePos, buf, container,false);
1864 
1865             switch (subOpcode)
1866             {
1867             case MINMAX_FOPCODE:
1868                 {
1869                     /// mmf mode
1870                     VISA_VectorOpnd* mmfMode = readVectorOperandNG(bytePos, buf, container, false);
1871 
1872                     /// dst
1873                     VISA_RawOpnd* dst = readRawOperandNG(bytePos, buf, container);
1874                     kernelBuilder->AppendVISAVAMinMax(surfaceHnd, uOffset, vOffset, mmfMode, dst);
1875                     break;
1876                 }
1877             case MINMAXFILTER_FOPCODE:
1878                 {
1879 
1880                     /// cntrl
1881                     OutputFormatControl cntrl = (OutputFormatControl)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1882 
1883                     /// execMode
1884                     MMFExecMode execMode = (MMFExecMode)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1885 
1886                     /// mmf mode
1887                     VISA_VectorOpnd* mmfMode = readVectorOperandNG(bytePos, buf, container, false);
1888 
1889                     /// dst
1890                     VISA_RawOpnd *dst = readRawOperandNG(bytePos, buf, container);
1891                     kernelBuilder->AppendVISAVAMinMaxFilter(samplerHnd, surfaceHnd, uOffset, vOffset, cntrl, execMode, mmfMode, dst);
1892                     break;
1893                 }
1894             case BoolCentroid_FOPCODE:
1895             case Centroid_FOPCODE:
1896                 {
1897                     /// v size
1898                     VISA_VectorOpnd* vSize = readVectorOperandNG(bytePos, buf, container,false);
1899 
1900                     if (subOpcode == BoolCentroid_FOPCODE)
1901                     {
1902                         /// h size
1903                         VISA_VectorOpnd* hSize = readVectorOperandNG(bytePos, buf, container,false);
1904                         VISA_RawOpnd *dst = readRawOperandNG(bytePos, buf, container);
1905                         kernelBuilder->AppendVISAVABooleanCentroid(surfaceHnd, uOffset, vOffset, vSize, hSize, dst);
1906                     }else
1907                     {
1908                         VISA_RawOpnd *dst = readRawOperandNG(bytePos, buf, container);
1909                         kernelBuilder->AppendVISAVACentroid(surfaceHnd, uOffset, vOffset, vSize, dst);
1910 
1911                     }
1912 
1913                     break;
1914                 }
1915             case Convolve_FOPCODE:
1916                 {
1917                     /// size for convolve, execMode for erode/dilate
1918                     uint8_t properties = readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1919 
1920                     bool isBigKernel = (bool)((properties >> 4) & 0x1);
1921                     CONVExecMode execMode = (CONVExecMode)(properties & 0x3);
1922 
1923                     /// dst
1924                     VISA_RawOpnd *dst = readRawOperandNG(bytePos, buf, container);
1925                     kernelBuilder->AppendVISAVAConvolve(samplerHnd, surfaceHnd, uOffset, vOffset, execMode, isBigKernel, dst);
1926                     break;
1927                 }
1928             case Dilate_FOPCODE:
1929             case ERODE_FOPCODE:
1930                 {
1931                     /// size for convolve, execMode for erode/dilate
1932                     EDExecMode execMode = (EDExecMode)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1933                     EDMode mode = (subOpcode == Dilate_FOPCODE) ? VA_DILATE : VA_ERODE;
1934                     /// dst
1935                     VISA_RawOpnd *dst = readRawOperandNG(bytePos, buf, container);
1936                     kernelBuilder->AppendVISAVAErodeDilate(mode, samplerHnd, surfaceHnd, uOffset, vOffset, execMode, dst);
1937                     break;
1938                 }
1939             default:
1940             break; // Prevent gcc warning
1941             }
1942 
1943             break;
1944         }
1945     case ISA_VA_SKL_PLUS:
1946         {
1947             VISA_INST_Desc *instDesc = &CISA_INST_table[opcode];
1948 
1949             /// subOpcode
1950             ISA_VA_Sub_Opcode subOpcode = (ISA_VA_Sub_Opcode)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
1951 
1952             if ((subOpcode < VA_OP_CODE_1D_CONVOLVE_VERTICAL) ||
1953                 (subOpcode >= VA_OP_CODE_UNDEFINED))
1954             {
1955                 ASSERT_USER(false, "Invalid VA sub-opcode");
1956                 return;
1957             }
1958 
1959 #define MAX_NUM_VOPNDS 10
1960             VISA_VectorOpnd *vOpnds[MAX_NUM_VOPNDS];
1961             uint8_t numVSrcs = 0;
1962             memset(vOpnds, 0, sizeof(VISA_VectorOpnd*) * MAX_NUM_VOPNDS);
1963 
1964 #define MAX_NUM_MOPNDS 10
1965             unsigned int miscOpnds[MAX_NUM_MOPNDS];
1966             uint8_t numMiscOpnds = 0;
1967             memset(miscOpnds, 0, sizeof(uint32_t) * MAX_NUM_MOPNDS);
1968 
1969             VISA_RawOpnd* dst = NULL;
1970 
1971 #define MAX_NUM_RSRCS 5
1972             VISA_RawOpnd* rawSrcs[MAX_NUM_RSRCS];
1973             uint8_t numRawSrcs = 0;
1974             memset(rawSrcs, 0, sizeof(VISA_RawOpnd*) * MAX_NUM_RSRCS);
1975 
1976 #define MAX_NUM_SOPNDS 4
1977             VISA_StateOpndHandle *stateOpnds[MAX_NUM_SOPNDS];
1978             uint8_t numStateOpnds = 0;
1979             memset(stateOpnds, 0, sizeof(VISA_StateOpndHandle*) * MAX_NUM_SOPNDS);
1980 
1981 
1982             int numTotalOperands = instDesc->getSubInstDesc(subOpcode).opnd_num;
1983 
1984             for (int i = 0; i < numTotalOperands; i++)
1985             {
1986                 const OpndDesc * opndDesc = &(instDesc->getSubInstDesc(subOpcode).opnd_desc[i]);
1987 
1988                 if (opndDesc->opnd_type == OPND_SAMPLE)
1989                 {
1990                     uint8_t sampler = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1991                     kernelBuilderImpl->CreateVISAStateOperandHandle(stateOpnds[numStateOpnds++], container.samplerVarDecls[sampler]);
1992                 } else if (opndDesc->opnd_type == OPND_SURFACE) {
1993                     uint8_t surface = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
1994                     kernelBuilderImpl->CreateVISAStateOperandHandle(stateOpnds[numStateOpnds++], container.surfaceVarDecls[surface]);
1995                 } else if ((opndDesc->opnd_type & OPND_SRC_GEN) == OPND_SRC_GEN)
1996                 {
1997                     vOpnds[numVSrcs++] = readVectorOperandNG(bytePos, buf, container, false);
1998                 } else if (opndDesc->opnd_type == OPND_RAW_SRC)
1999                 {
2000                     rawSrcs[numRawSrcs++] = readRawOperandNG(bytePos, buf, container);
2001                 } else if (opndDesc->opnd_type == OPND_RAW_DST)
2002                 {
2003                     dst = readRawOperandNG(bytePos, buf, container);
2004                 }
2005                 else if (opndDesc->opnd_type == OPND_OTHER)
2006                 {
2007                     //in theory this is not necessary since all of them will be UB
2008                     //but to demonstrate usage model
2009                     if (opndDesc->data_type == ISA_TYPE_UB)
2010                     {
2011                         miscOpnds[numMiscOpnds++] = readPrimitiveOperandNG<uint8_t> (bytePos, buf);
2012                     }else if (opndDesc->data_type == ISA_TYPE_UW)
2013                     {
2014                         miscOpnds[numMiscOpnds++] = readPrimitiveOperandNG<uint16_t> (bytePos, buf);
2015                     }else if (opndDesc->data_type == ISA_TYPE_UD)
2016                     {
2017                         miscOpnds[numMiscOpnds++] = readPrimitiveOperandNG<unsigned int> (bytePos, buf);
2018                     }else
2019                     {
2020                         ASSERT_USER(false, "Invalid misc opnd data type");
2021                     return;
2022                     }
2023                 } else {
2024                     ASSERT_USER(false, "Invalid opnd type");
2025                     return;
2026                 }
2027             }
2028             numVSrcs = 0;
2029             numRawSrcs = 0;
2030             numMiscOpnds = 0;
2031             numStateOpnds = 0;
2032 
2033             switch (subOpcode)
2034             {
2035             case VA_OP_CODE_FLOOD_FILL:
2036                 kernelBuilderImpl->AppendVISAVAFloodFill(miscOpnds[0] != 0, rawSrcs[0],
2037                                                         vOpnds[0], vOpnds[1],
2038                                                         vOpnds[2], dst);
2039                 break;
2040             case VA_OP_CODE_1D_CONVOLVE_VERTICAL:
2041                 kernelBuilderImpl->AppendVISAVAConvolve1D(stateOpnds[0], stateOpnds[1], vOpnds[0], vOpnds[1], (CONVExecMode)miscOpnds[0], VA_V_DIRECTION, dst);
2042                 break;
2043             case VA_OP_CODE_1D_CONVOLVE_HORIZONTAL:
2044                 kernelBuilderImpl->AppendVISAVAConvolve1D(stateOpnds[0], stateOpnds[1], vOpnds[0], vOpnds[1], (CONVExecMode)miscOpnds[0], VA_H_DIRECTION, dst);
2045                 break;
2046             case VA_OP_CODE_1PIXEL_CONVOLVE:
2047                 kernelBuilderImpl->AppendVISAVAConvolve1Pixel(stateOpnds[0], stateOpnds[1], vOpnds[0], vOpnds[1], (CONV1PixelExecMode)miscOpnds[0], rawSrcs[0], dst);
2048                 break;
2049             case VA_OP_CODE_LBP_CORRELATION:
2050                 kernelBuilderImpl->AppendVISAVALBPCorrelation(stateOpnds[0], vOpnds[0], vOpnds[1],
2051                                                         vOpnds[2], dst);
2052                 break;
2053             case VA_OP_CODE_LBP_CREATION:
2054                 kernelBuilderImpl->AppendVISAVALBPCreation(stateOpnds[0], vOpnds[0], vOpnds[1], (LBPCreationMode)miscOpnds[0], dst);
2055                 break;
2056             case VA_OP_CODE_CORRELATION_SEARCH:
2057                 kernelBuilderImpl->AppendVISAVACorrelationSearch(stateOpnds[0], vOpnds[0],vOpnds[1],
2058                                                         vOpnds[2], vOpnds[3], vOpnds[4],
2059                                                         vOpnds[5], vOpnds[6], vOpnds[7],
2060                                                         dst);
2061                 break;
2062             case ISA_HDC_ERODE:
2063                 kernelBuilderImpl->AppendVISAVAHDCErodeDilate(VA_ERODE, stateOpnds[0], stateOpnds[1],
2064                                                         vOpnds[0], vOpnds[1], stateOpnds[2],vOpnds[2], vOpnds[3]);
2065                 break;
2066             case ISA_HDC_DILATE:
2067                 kernelBuilderImpl->AppendVISAVAHDCErodeDilate(VA_DILATE, stateOpnds[0], stateOpnds[1],
2068                                                         vOpnds[0], vOpnds[1], stateOpnds[2],vOpnds[2], vOpnds[3]);
2069                 break;
2070             case ISA_HDC_LBPCORRELATION:
2071                 kernelBuilderImpl->AppendVISAVAHDCLBPCorrelation(stateOpnds[0], vOpnds[0], vOpnds[1],
2072                                                         vOpnds[2], stateOpnds[1],
2073                                                         vOpnds[3], vOpnds[4]);
2074                 break;
2075             case ISA_HDC_LBPCREATION:
2076                 kernelBuilderImpl->AppendVISAVAHDCLBPCreation(stateOpnds[0], vOpnds[0], vOpnds[1],
2077                                                         (LBPCreationMode)miscOpnds[0],
2078                                                         stateOpnds[1], vOpnds[2], vOpnds[3]);
2079                 break;
2080             case ISA_HDC_MMF:
2081                 kernelBuilderImpl->AppendVISAVAHDCMinMaxFilter(stateOpnds[0], stateOpnds[1],
2082                                                         vOpnds[0], vOpnds[1], (HDCReturnFormat)miscOpnds[0],
2083                                                         (MMFEnableMode)miscOpnds[1], stateOpnds[2],
2084                                                         vOpnds[2], vOpnds[3]);
2085                 break;
2086             case ISA_HDC_1PIXELCONV:
2087                 kernelBuilderImpl->AppendVISAVAHDCConvolve1Pixel(stateOpnds[0], stateOpnds[1], vOpnds[0], vOpnds[1],
2088                                                         (HDCReturnFormat)miscOpnds[0], rawSrcs[0], stateOpnds[2],
2089                                                         vOpnds[2], vOpnds[3]);
2090                 break;
2091             case ISA_HDC_CONV:
2092                 kernelBuilderImpl->AppendVISAVAHDCConvolve(stateOpnds[0], stateOpnds[1], vOpnds[0],
2093                                                         vOpnds[1], (HDCReturnFormat)(miscOpnds[0]&0xF),
2094                                                         (CONVHDCRegionSize)(miscOpnds[0]>>4), stateOpnds[2],
2095                                                         vOpnds[2], vOpnds[3]);
2096                 break;
2097             case ISA_HDC_1DCONV_H:
2098                 kernelBuilderImpl->AppendVISAVAHDCConvolve1D(stateOpnds[0], stateOpnds[1], vOpnds[0],
2099                     vOpnds[1], (HDCReturnFormat)miscOpnds[0], VA_H_DIRECTION,
2100                     stateOpnds[2], vOpnds[2], vOpnds[3]);
2101                 break;
2102             case ISA_HDC_1DCONV_V:
2103                 kernelBuilderImpl->AppendVISAVAHDCConvolve1D(stateOpnds[0], stateOpnds[1], vOpnds[0],
2104                     vOpnds[1], (HDCReturnFormat)miscOpnds[0], VA_V_DIRECTION,
2105                     stateOpnds[2], vOpnds[2], vOpnds[3]);
2106                 break;
2107             default:
2108                 ASSERT_USER(false, "Invalid VA sub-opcode");
2109             }
2110 
2111 
2112             break;
2113         }
2114     default:
2115         {
2116             MUST_BE_TRUE(false, "Unimplemented or Illegal Sampler Opcode.");
2117         }
2118     }
2119 }
2120 
readLscCacheOpts(unsigned & bytePos,const char * buf)2121 static LSC_CACHE_OPTS readLscCacheOpts(unsigned& bytePos, const char* buf) {
2122     LSC_CACHE_OPTS caching {};
2123     caching.l1 = (LSC_CACHE_OPT)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2124     caching.l3 = (LSC_CACHE_OPT)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2125     return caching;
2126 }
2127 
readLscAddr(unsigned & bytePos,const char * buf)2128 static LSC_ADDR readLscAddr(unsigned& bytePos, const char* buf) {
2129     LSC_ADDR addrInfo {};
2130     addrInfo.type = (LSC_ADDR_TYPE)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2131     addrInfo.immScale = readPrimitiveOperandNG<uint16_t>(bytePos, buf);
2132     addrInfo.immOffset = readPrimitiveOperandNG<int32_t>(bytePos, buf);
2133     addrInfo.size = (LSC_ADDR_SIZE)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2134     return addrInfo;
2135 }
2136 
readLscDataShape(unsigned & bytePos,const char * buf,bool useChMask)2137 static LSC_DATA_SHAPE readLscDataShape(
2138     unsigned& bytePos, const char* buf, bool useChMask)
2139 {
2140     LSC_DATA_SHAPE dataInfo {};
2141     dataInfo.size = (LSC_DATA_SIZE)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2142     dataInfo.order = (LSC_DATA_ORDER)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2143     // even though both chmask and elems are a sum type, the binary holds both
2144     auto dataElems =
2145         (LSC_DATA_ELEMS)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2146     int chMask = (int)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2147     if (useChMask) {
2148         dataInfo.chmask = chMask;
2149     } else {
2150         dataInfo.elems = dataElems;
2151     }
2152     return dataInfo;
2153 }
2154 
readInstructionLscUntyped(LSC_OP subOpcode,unsigned & bytePos,const char * buf,RoutineContainer & container)2155 static void readInstructionLscUntyped(
2156     LSC_OP subOpcode,
2157     unsigned& bytePos, const char* buf,
2158     RoutineContainer& container)
2159 {
2160     const LscOpInfo opInfo = LscOpInfoGet(subOpcode);
2161 
2162     VISA_EMask_Ctrl execMask = vISA_EMASK_M1;
2163     VISA_Exec_Size  execSize = EXEC_SIZE_ILLEGAL;
2164 
2165     readExecSizeNG(bytePos, buf, execSize, execMask, container);
2166     VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
2167 
2168     auto lscSfid =
2169         (LSC_SFID)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2170     LSC_CACHE_OPTS caching = readLscCacheOpts(bytePos, buf);
2171     LSC_ADDR addrInfo = readLscAddr(bytePos, buf);
2172     LSC_DATA_SHAPE dataInfo = readLscDataShape(
2173         bytePos,
2174         buf,
2175         subOpcode == LSC_LOAD_QUAD || subOpcode == LSC_STORE_QUAD);
2176 
2177     VISA_VectorOpnd *surface =
2178         readVectorOperandNG(bytePos, buf, container, false);
2179     VISA_RawOpnd *dst = readRawOperandNG(bytePos, buf, container);
2180     VISA_RawOpnd *src0 = readRawOperandNG(bytePos, buf, container);
2181     VISA_VectorOpnd *src0Pitch = nullptr;
2182     if (opInfo.isStrided()) {
2183         src0Pitch = readVectorOperandNG(bytePos, buf, container, false);
2184     }
2185     VISA_RawOpnd *src1 = readRawOperandNG(bytePos, buf, container);
2186     VISA_RawOpnd *src2 = nullptr;
2187     if (!opInfo.isStrided()) {
2188          src2 = readRawOperandNG(bytePos, buf, container);
2189     }
2190 
2191     if (opInfo.isStrided()) {
2192         container.kernelBuilder->AppendVISALscUntypedStridedInst(
2193             subOpcode, lscSfid,
2194             pred, execSize, execMask,
2195             caching, addrInfo, dataInfo,
2196             surface, dst, src0, src0Pitch, src1);
2197     } else {
2198         container.kernelBuilder->AppendVISALscUntypedInst(
2199             subOpcode, lscSfid,
2200             pred, execSize, execMask,
2201             caching, addrInfo, dataInfo,
2202             surface, dst, src0, src1, src2);
2203     }
2204 }
2205 
readInstructionLscUntypedBlock2D(LSC_OP subOpcode,unsigned & bytePos,const char * buf,RoutineContainer & container)2206 static void readInstructionLscUntypedBlock2D(
2207     LSC_OP subOpcode,
2208     unsigned& bytePos, const char* buf,
2209     RoutineContainer& container)
2210 {
2211     VISA_EMask_Ctrl execMask = vISA_EMASK_M1;
2212     VISA_Exec_Size  execSize = EXEC_SIZE_ILLEGAL;
2213 
2214     readExecSizeNG(bytePos, buf, execSize, execMask, container);
2215     VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
2216     //
2217     auto sfid = (LSC_SFID)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2218     //
2219     LSC_CACHE_OPTS caching = readLscCacheOpts(bytePos, buf);
2220     //
2221     LSC_DATA_SHAPE_BLOCK2D dataShape2D { };
2222     dataShape2D.size =
2223         (LSC_DATA_SIZE)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2224     dataShape2D.order =
2225         (LSC_DATA_ORDER)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2226     dataShape2D.blocks = (int)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2227     dataShape2D.width = (int)readPrimitiveOperandNG<uint16_t>(bytePos, buf);
2228     dataShape2D.height = (int)readPrimitiveOperandNG<uint16_t>(bytePos, buf);
2229     dataShape2D.vnni = readPrimitiveOperandNG<uint8_t>(bytePos, buf) != 0;
2230     //
2231     VISA_RawOpnd *dstData = readRawOperandNG(bytePos, buf, container);
2232     VISA_VectorOpnd *src0Addrs[LSC_BLOCK2D_ADDR_PARAMS] { };
2233     for (size_t i = 0; i < LSC_BLOCK2D_ADDR_PARAMS; i++) {
2234         src0Addrs[i] = readVectorOperandNG(bytePos, buf, container, false);
2235     }
2236     VISA_RawOpnd *src1Data = readRawOperandNG(bytePos, buf, container);
2237     //
2238     container.kernelBuilder->AppendVISALscUntypedBlock2DInst(
2239         subOpcode,
2240         sfid,
2241         pred, execSize, execMask,
2242         caching,
2243         dataShape2D,
2244         dstData,
2245         src0Addrs,
2246         src1Data);
2247 }
2248 
readInstructionLscTyped(LSC_OP subOpcode,unsigned & bytePos,const char * buf,RoutineContainer & container)2249 static void readInstructionLscTyped(
2250     LSC_OP subOpcode,
2251     unsigned& bytePos, const char* buf,
2252     RoutineContainer& container)
2253 {
2254     VISA_EMask_Ctrl execMask = vISA_EMASK_M1;
2255     VISA_Exec_Size  execSize = EXEC_SIZE_ILLEGAL;
2256 
2257     readExecSizeNG(bytePos, buf, execSize, execMask, container);
2258     VISA_PredOpnd* pred = readPredicateOperandNG(bytePos, buf, container);
2259 
2260     // LSC_SFID lscSfid = ... always TGM
2261     LSC_CACHE_OPTS caching = readLscCacheOpts(bytePos, buf);
2262     auto addrModel =
2263         (LSC_ADDR_TYPE)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2264     auto addrSize =
2265         (LSC_ADDR_SIZE)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2266     //
2267     auto dataSize =
2268         (LSC_DATA_SIZE)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2269     auto dataOrder =
2270         (LSC_DATA_ORDER)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2271     auto dataElems =
2272         (LSC_DATA_ELEMS)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2273     auto chMask =
2274         (int)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2275     LSC_DATA_SHAPE dataInfo { };
2276     dataInfo.size = dataSize;
2277     dataInfo.order = dataOrder;
2278     if (subOpcode == LSC_LOAD_QUAD || subOpcode == LSC_STORE_QUAD) {
2279         dataInfo.chmask = chMask;
2280     } else {
2281         dataInfo.elems = dataElems;
2282     }
2283 
2284     VISA_VectorOpnd *surface =
2285         readVectorOperandNG(bytePos, buf, container, false);
2286     VISA_RawOpnd *dstData = readRawOperandNG(bytePos, buf, container);
2287     VISA_RawOpnd *src0AddrsU = readRawOperandNG(bytePos, buf, container);
2288     VISA_RawOpnd *src0AddrsV = readRawOperandNG(bytePos, buf, container);
2289     VISA_RawOpnd *src0AddrsR = readRawOperandNG(bytePos, buf, container);
2290     VISA_RawOpnd *src0AddrsLOD = readRawOperandNG(bytePos, buf, container);
2291     VISA_RawOpnd *src1Data = readRawOperandNG(bytePos, buf, container);
2292     VISA_RawOpnd *src2Data = readRawOperandNG(bytePos, buf, container);
2293 
2294     container.kernelBuilder->AppendVISALscTypedInst(
2295         subOpcode,
2296         pred, execSize, execMask,
2297         caching, addrModel, addrSize, dataInfo,
2298         surface,
2299         dstData,
2300         src0AddrsU, src0AddrsV, src0AddrsR, src0AddrsLOD,
2301         src1Data, src2Data);
2302 }
readInstructionLscFence(unsigned & bytePos,const char * buf,RoutineContainer & container)2303 static void readInstructionLscFence(
2304     unsigned& bytePos, const char* buf,
2305     RoutineContainer& container)
2306 {
2307     VISA_EMask_Ctrl execMask = vISA_EMASK_M1;
2308     VISA_Exec_Size  execSize = EXEC_SIZE_1;
2309 
2310     readExecSizeNG(bytePos, buf, execSize, execMask, container);
2311     (void)readPredicateOperandNG(bytePos, buf, container);
2312     LSC_SFID sfid =
2313         (LSC_SFID)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2314     LSC_FENCE_OP fenceOp =
2315         (LSC_FENCE_OP)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2316     LSC_SCOPE scope =
2317         (LSC_SCOPE)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2318 
2319     container.kernelBuilder->AppendVISALscFence(sfid, fenceOp, scope);
2320 }
readInstructionLSC(unsigned & bytePos,const char * buf,ISA_Opcode opcode,RoutineContainer & container)2321 static void readInstructionLSC(
2322     unsigned& bytePos, const char* buf,
2323     ISA_Opcode opcode,
2324     RoutineContainer& container)
2325 {
2326     if (opcode == ISA_Opcode::ISA_LSC_FENCE) {
2327         readInstructionLscFence(bytePos, buf, container);
2328     } else if (opcode == ISA_Opcode::ISA_LSC_UNTYPED) {
2329         auto subOpcode = (LSC_OP)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2330         if (subOpcode == LSC_LOAD_BLOCK2D || subOpcode == LSC_STORE_BLOCK2D) {
2331             readInstructionLscUntypedBlock2D(
2332                 subOpcode, bytePos, buf, container);
2333         } else {
2334             readInstructionLscUntyped(subOpcode, bytePos, buf, container);
2335         }
2336     } else if (opcode == ISA_Opcode::ISA_LSC_TYPED) {
2337         auto subOpcode = (LSC_OP)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2338         {
2339             readInstructionLscTyped(
2340                 subOpcode, bytePos, buf, container);
2341         }
2342     } else {
2343         MUST_BE_TRUE(false,"invalid LSC op");
2344     }
2345 }
2346 
readInstructionNG(unsigned & bytePos,const char * buf,RoutineContainer & container,unsigned instID)2347 void readInstructionNG(
2348     unsigned& bytePos, const char* buf, RoutineContainer& container, unsigned instID)
2349 {
2350     ISA_Opcode opcode = (ISA_Opcode)readPrimitiveOperandNG<uint8_t>(bytePos, buf);
2351     MUST_BE_TRUE(opcode < ISA_NUM_OPCODE, "Illegal or unimplemented CISA opcode.");
2352 
2353     //cout << "Opcode: " << ISA_Inst_Table[opcode].str << endl;
2354 
2355     switch (ISA_Inst_Table[opcode].type)
2356     {
2357     case ISA_Inst_Mov:
2358     case ISA_Inst_Sync:
2359     case ISA_Inst_Arith:
2360     case ISA_Inst_Logic:
2361     case ISA_Inst_Address:
2362     case ISA_Inst_Compare:
2363     case ISA_Inst_SIMD_Flow: readInstructionCommonNG   (bytePos, buf, (ISA_Opcode)opcode, container); break;
2364     case ISA_Inst_Data_Port: readInstructionDataportNG (bytePos, buf, (ISA_Opcode)opcode, container); break;
2365     case ISA_Inst_Flow:      readInstructionControlFlow(bytePos, buf, (ISA_Opcode)opcode, container); break;
2366     case ISA_Inst_Misc:      readInstructionMisc       (bytePos, buf, (ISA_Opcode)opcode, container); break;
2367     case ISA_Inst_SVM:       readInstructionSVM        (bytePos, buf, (ISA_Opcode)opcode, container); break;
2368     case ISA_Inst_Sampler:   readInstructionSampler    (bytePos, buf, (ISA_Opcode)opcode, container); break;
2369     case ISA_Inst_LSC:       readInstructionLSC        (bytePos, buf, (ISA_Opcode)opcode, container); break;
2370     default:
2371         {
2372             std::stringstream sstr;
2373             sstr << "Illegal or unimplemented ISA opcode "
2374                 << ISA_Inst_Table[opcode].str
2375                 << " (" << (unsigned)opcode << ")"
2376                 << " at byte position " << bytePos-1
2377                 << "(0x" <<  std::hex   << bytePos-1
2378                 << ")"   << ".";
2379             MUST_BE_TRUE(false, sstr.str());
2380         }
2381     }
2382 }
2383 
readAttributesNG(uint8_t major,uint8_t minor,unsigned & bytePos,const char * buf,kernel_format_t & header,attribute_info_t * attributes,int numAttributes,vISA::Mem_Manager & mem)2384 static void readAttributesNG(uint8_t major, uint8_t minor, unsigned& bytePos, const char* buf, kernel_format_t& header,
2385     attribute_info_t* attributes, int numAttributes, vISA::Mem_Manager& mem)
2386 {
2387     MUST_BE_TRUE(buf    , "Argument Exception: argument buf    is NULL.");
2388 
2389     for (int i = 0; i < numAttributes; i++)
2390     {
2391         ASSERT_USER(attributes, "Argument Exception: argument 'attributes' is NULL");
2392 
2393         readVarBytes(major, minor, attributes[i].nameIndex, bytePos, buf);
2394         READ_CISA_FIELD(attributes[i].size, uint8_t, bytePos, buf);
2395 
2396         const char* attrName = header.strings[attributes[i].nameIndex];
2397         char* valueBuffer = (char*)mem.alloc(sizeof(char) * (attributes[i].size + 1));
2398         memcpy_s(valueBuffer, attributes[i].size, &buf[bytePos], attributes[i].size);
2399         bytePos += attributes[i].size;
2400         vISA::Attributes::ID attrID = vISA::Attributes::getAttributeID(attrName);
2401         if (vISA::Attributes::isInt32(attrID) || vISA::Attributes::isBool(attrID))
2402         {
2403             attributes[i].isInt = true;
2404             switch (attributes[i].size)
2405             {
2406             case 0:
2407                 // No value attribute, treat it as boolean internally.
2408                 attributes[i].value.intVal = 1;
2409                 break;
2410             case 1:
2411                 attributes[i].value.intVal = *valueBuffer;
2412                 break;
2413             case 2:
2414                 attributes[i].value.intVal = *((short*)valueBuffer);
2415                 break;
2416             case 4:
2417                 attributes[i].value.intVal = *((int*)valueBuffer);
2418                 break;
2419             default:
2420                 MUST_BE_TRUE(false, "Unsupported attribute size.");
2421                 break;
2422             }
2423         }
2424         else if (vISA::Attributes::isCStr(attrID))
2425         {
2426             valueBuffer[attributes[i].size] = '\0';
2427             attributes[i].isInt = false;    //by default assume attributes have string value
2428             attributes[i].value.stringVal = valueBuffer;
2429         }
2430         else
2431         {
2432             std::string errMsg(attrName);
2433             errMsg += " : unsupported attribute!";
2434             MUST_BE_TRUE(false, errMsg);
2435         }
2436     }
2437 }
2438 
getDeclLabelString(const char * prefix,uint32_t index,kernel_format_t & header,VISA_Label_Kind kind)2439 static std::string getDeclLabelString(const char* prefix, uint32_t index, kernel_format_t& header, VISA_Label_Kind kind)
2440 {
2441     if (index) {
2442         if (kind == LABEL_FC)
2443           return header.strings[index];
2444         std::stringstream sstr;
2445         sstr << header.strings[index] << "_" << index;
2446         return sstr.str();
2447     }
2448     return prefix;
2449 }
2450 
addAllAttributesNG(kernel_format_t & Header,VISAKernelImpl * KBImpl,CISA_GEN_VAR * GenVar,const uint32_t AttrsCount,attribute_info_t * Attrs)2451 static void addAllAttributesNG(
2452     kernel_format_t& Header, VISAKernelImpl* KBImpl,
2453     CISA_GEN_VAR* GenVar, const uint32_t AttrsCount, attribute_info_t* Attrs)
2454 {
2455     if (AttrsCount > 0)
2456     {
2457         KBImpl->resizeAttribute(GenVar, AttrsCount);
2458 
2459         for (unsigned ai = 0; ai < AttrsCount; ai++)
2460         {
2461             attribute_info_t* attribute = &Attrs[ai];
2462             KBImpl->AddAttributeToVarGeneric(GenVar, Header.strings[attribute->nameIndex], attribute->size,
2463                 attribute->isInt ? (const char*)&attribute->value.intVal : attribute->value.stringVal);
2464         }
2465     }
2466 }
2467 
readRoutineNG(unsigned & bytePos,const char * buf,vISA::Mem_Manager & mem,RoutineContainer & container)2468 static void readRoutineNG(unsigned& bytePos, const char* buf, vISA::Mem_Manager& mem, RoutineContainer& container)
2469 {
2470     kernel_format_t header;
2471     uint8_t majorVersion = container.majorVersion;
2472     uint8_t minorVersion = container.minorVersion;
2473 
2474     VISAKernelImpl* kernelBuilderImpl = ((VISAKernelImpl*)container.kernelBuilder);
2475     bool isKernel = kernelBuilderImpl->getIsKernel();
2476 
2477     unsigned kernelStart = bytePos;
2478 
2479     readVarBytes(majorVersion, minorVersion, header.string_count, bytePos, buf);
2480     header.strings = (const char**)mem.alloc(header.string_count * sizeof(char*));
2481     container.stringPool.resize(header.string_count);
2482     for (unsigned i = 0; i < header.string_count; i++)
2483     {
2484         char* str = (char*)mem.alloc(STRING_LEN);
2485         unsigned j = 0;
2486         while (buf[bytePos] != '\0' && j < STRING_LEN)
2487         {
2488             str[j++] = buf[bytePos++];
2489         }
2490         ASSERT_USER(j < STRING_LEN, "string exceeds the maximum length allowed");
2491         str[j] = '\0';
2492         bytePos++;
2493         header.strings[i] = str;
2494         container.stringPool[i] = str;
2495     }
2496     readVarBytes(majorVersion, minorVersion, header.name_index, bytePos, buf);
2497 
2498     /// read general variables
2499     unsigned numPreDefinedVars = Get_CISA_PreDefined_Var_Count();
2500     readVarBytes(majorVersion, minorVersion, header.variable_count, bytePos, buf);
2501     header.variables = (var_info_t*)mem.alloc(sizeof(var_info_t) * (header.variable_count + numPreDefinedVars));
2502     container.generalVarDecls = (VISA_GenVar**)mem.alloc(sizeof(VISA_GenVar*) * (header.variable_count + numPreDefinedVars));
2503     container.generalVarsCount = (header.variable_count + numPreDefinedVars);
2504 
2505     for (unsigned i = numPreDefinedVars; i < header.variable_count + numPreDefinedVars; i++)
2506     {
2507         unsigned declID = i;
2508         readVarBytes(majorVersion, minorVersion, header.variables[declID].name_index, bytePos, buf);
2509         READ_CISA_FIELD(header.variables[declID].bit_properties, uint8_t , bytePos, buf);
2510         READ_CISA_FIELD(header.variables[declID].num_elements,   uint16_t, bytePos, buf);
2511         readVarBytes(majorVersion, minorVersion, header.variables[declID].alias_index, bytePos, buf);
2512         READ_CISA_FIELD(header.variables[declID].alias_offset,   uint16_t, bytePos, buf);
2513 
2514         READ_CISA_FIELD(header.variables[declID].alias_scope_specifier, uint8_t, bytePos, buf);
2515 
2516         READ_CISA_FIELD(header.variables[declID].attribute_count, uint8_t, bytePos, buf);
2517 
2518         header.variables[declID].attributes = (attribute_info_t*)mem.alloc(sizeof(attribute_info_t) * header.variables[declID].attribute_count);
2519         readAttributesNG(majorVersion, minorVersion, bytePos, buf, header, header.variables[declID].attributes, header.variables[declID].attribute_count, mem);
2520         header.variables[declID].dcl = NULL;
2521 
2522         /// VISA Builder Call
2523         var_info_t* var = &header.variables[declID];
2524         VISA_GenVar* decl = NULL;
2525         VISA_Type  varType  = (VISA_Type)  ((var->bit_properties) & 0xF);
2526         VISA_Align varAlign = (VISA_Align) ((var->bit_properties >> 4) & 0xF);
2527         uint8_t aliasScopeSpecifier = header.variables[declID].alias_scope_specifier;
2528         int status = VISA_SUCCESS;
2529 
2530         assert(aliasScopeSpecifier == 0 && "file scope variables are no longer supported");
2531 
2532         {
2533             VISA_GenVar* parentDecl = NULL;
2534             uint16_t aliasOffset = 0;
2535             uint32_t aliasIndex  = header.variables[declID].alias_index;
2536             if (aliasIndex > 0)
2537             {
2538                 if (aliasIndex < numPreDefinedVars)
2539                 {
2540                    status = kernelBuilderImpl->GetPredefinedVar(parentDecl, (PreDefined_Vars) aliasIndex);
2541                    ASSERT_USER(status == VISA_SUCCESS, "Invalid index for pre-defined variables");
2542                 }
2543                 else
2544                 {
2545                     parentDecl = container.generalVarDecls[aliasIndex];
2546                 }
2547                 aliasOffset = header.variables[declID].alias_offset;
2548             }
2549 
2550             status = kernelBuilderImpl->CreateVISAGenVar(
2551                 decl, header.strings[var->name_index], var->num_elements, varType,
2552                 varAlign, parentDecl, aliasOffset);
2553             ASSERT_USER(VISA_SUCCESS == status,
2554                 "Failed to add VISA general variable.");
2555         }
2556 
2557         addAllAttributesNG(header, kernelBuilderImpl, decl, var->attribute_count, var->attributes);
2558         container.generalVarDecls[i] = decl;
2559     }
2560 
2561     /// read address variables
2562     READ_CISA_FIELD(header.address_count, uint16_t, bytePos, buf);
2563     header.addresses = (addr_info_t*) mem.alloc(sizeof(addr_info_t) * header.address_count);
2564     container.addressVarDecls = (VISA_AddrVar**)mem.alloc(sizeof(VISA_AddrVar*) * (header.address_count));
2565     container.addressVarsCount = (header.address_count);
2566     for (unsigned i = 0; i < header.address_count; i++)
2567     {
2568         unsigned declID = i;
2569         readVarBytes(majorVersion, minorVersion, header.addresses[declID].name_index, bytePos, buf);
2570         READ_CISA_FIELD(header.addresses[declID].num_elements   , uint16_t, bytePos, buf);
2571         READ_CISA_FIELD(header.addresses[declID].attribute_count, uint8_t , bytePos, buf);
2572         header.addresses[declID].attributes =
2573             (attribute_info_t*)mem.alloc(sizeof(attribute_info_t) * header.addresses[declID].attribute_count);
2574         readAttributesNG(majorVersion, minorVersion, bytePos, buf, header,
2575             header.addresses[declID].attributes, header.addresses[declID].attribute_count, mem);
2576         header.addresses[declID].dcl = NULL;
2577 
2578         /// VISA Builder Call
2579         addr_info_t* var = &header.addresses[declID];
2580         VISA_AddrVar* decl = NULL;
2581         int status = kernelBuilderImpl->CreateVISAAddrVar(
2582             decl, header.strings[var->name_index], var->num_elements);
2583         ASSERT_USER(VISA_SUCCESS == status,
2584             "Failed to add VISA address variable.");
2585 
2586         addAllAttributesNG(header, kernelBuilderImpl, decl, var->attribute_count, var->attributes);
2587         container.addressVarDecls[i] = decl;
2588     }
2589 
2590     // read predicate variables
2591     READ_CISA_FIELD(header.predicate_count, uint16_t, bytePos, buf);
2592     header.predicates =
2593         (pred_info_t *)mem.alloc(sizeof(pred_info_t) * (header.predicate_count + COMMON_ISA_NUM_PREDEFINED_PRED));
2594     container.predicateVarDecls =
2595         (VISA_PredVar**)mem.alloc(sizeof(VISA_PredVar*) * (header.predicate_count + COMMON_ISA_NUM_PREDEFINED_PRED));
2596     container.predicateVarsCount =  (header.predicate_count + COMMON_ISA_NUM_PREDEFINED_PRED);
2597     for (unsigned i = COMMON_ISA_NUM_PREDEFINED_PRED; i <
2598         (unsigned)(header.predicate_count + COMMON_ISA_NUM_PREDEFINED_PRED); i++)
2599     {
2600         unsigned declID = i;
2601         readVarBytes(majorVersion, minorVersion, header.predicates[declID].name_index, bytePos, buf);
2602         READ_CISA_FIELD(header.predicates[declID].num_elements   , uint16_t, bytePos, buf);
2603         READ_CISA_FIELD(header.predicates[declID].attribute_count, uint8_t , bytePos, buf);
2604         header.predicates[declID].attributes =
2605             (attribute_info_t*)mem.alloc(sizeof(attribute_info_t) * header.predicates[declID].attribute_count);
2606         readAttributesNG(majorVersion, minorVersion, bytePos, buf, header,
2607             header.predicates[declID].attributes, header.predicates[declID].attribute_count, mem);
2608         header.predicates[declID].dcl = NULL;
2609 
2610         /// VISA Builder Call
2611         pred_info_t* var = &header.predicates[declID];
2612         VISA_PredVar* decl = NULL;
2613         int status = kernelBuilderImpl->CreateVISAPredVar(
2614             decl, header.strings[var->name_index], var->num_elements);
2615         ASSERT_USER(VISA_SUCCESS == status,
2616             "Failed to add VISA predicate vairable.");
2617 
2618         addAllAttributesNG(header, kernelBuilderImpl, decl, var->attribute_count, var->attributes);
2619         container.predicateVarDecls[i] = decl;
2620     }
2621 
2622     // read label variables
2623     READ_CISA_FIELD(header.label_count, uint16_t, bytePos, buf);
2624     header.labels = (label_info_t*) mem.alloc(sizeof(label_info_t) * header.label_count);
2625     container.labelVarDecls = (VISA_LabelOpnd**)mem.alloc(sizeof(VISA_LabelOpnd*) * (header.label_count));
2626     container.labelVarsCount = header.label_count;
2627     for (unsigned i = 0; i < header.label_count; i++)
2628     {
2629         readVarBytes(majorVersion, minorVersion, header.labels[i].name_index, bytePos, buf);
2630         READ_CISA_FIELD(header.labels[i].kind, uint8_t, bytePos, buf);
2631         READ_CISA_FIELD(header.labels[i].attribute_count, uint8_t, bytePos, buf);
2632         header.labels[i].attributes =
2633             (attribute_info_t*)mem.alloc(sizeof(attribute_info_t) * header.labels[i].attribute_count);
2634         readAttributesNG(majorVersion, minorVersion, bytePos, buf,
2635             header, header.labels[i].attributes, header.labels[i].attribute_count, mem);
2636 
2637         /// VISA Builder Call
2638         unsigned declID = i;
2639         label_info_t* var = &header.labels[declID];
2640         VISA_LabelOpnd* decl = NULL;
2641         int status = kernelBuilderImpl->CreateVISALabelVar(decl,
2642             getDeclLabelString("L", var->name_index, header, VISA_Label_Kind(var->kind)).c_str(),
2643             VISA_Label_Kind(var->kind));
2644         ASSERT_USER(VISA_SUCCESS == status,
2645             "Failed to add VISA label variable.");
2646 
2647         for (unsigned ai = 0; ai < var->attribute_count; ai++)
2648         {
2649             /// TODO: How to Add label decls and attributes correctly.
2650             ///kernelBuilderImpl->AddAttributeToVar(decl, header.strings[attribute->nameIndex], attribute->size, attribute->value.stringVal);
2651             ASSERT_USER(false, "Currently the builder API does not support label attributes. Please file a bug.");
2652         }
2653 
2654         container. labelVarDecls[i] = decl;
2655     }
2656 
2657     // read sampler variables
2658     READ_CISA_FIELD(header.sampler_count, uint8_t, bytePos, buf);
2659     // up to 31 pre-defined samplers are allowed
2660     MUST_BE_TRUE(header.sampler_count < COMMON_ISA_MAX_NUM_SAMPLERS, "number of vISA samplers exceeds the max");
2661     header.samplers = (state_info_t*) mem.alloc(sizeof(state_info_t) * COMMON_ISA_MAX_NUM_SAMPLERS);
2662     container.samplerVarDecls = (VISA_SamplerVar**)mem.alloc(sizeof(VISA_SamplerVar*)* COMMON_ISA_MAX_NUM_SAMPLERS);
2663     container.samplerVarsCount = header.sampler_count;
2664     for (unsigned i = 0; i < header.sampler_count; i++)
2665     {
2666         readVarBytes(majorVersion, minorVersion, header.samplers[i].name_index, bytePos, buf);
2667         READ_CISA_FIELD(header.samplers[i].num_elements, uint16_t, bytePos, buf);
2668         READ_CISA_FIELD(header.samplers[i].attribute_count, uint8_t, bytePos, buf);
2669         header.samplers[i].attributes =
2670             (attribute_info_t *)mem.alloc(sizeof(attribute_info_t) * header.samplers[i].attribute_count);
2671         readAttributesNG(majorVersion, minorVersion, bytePos, buf,
2672             header, header.samplers[i].attributes, header.samplers[i].attribute_count, mem);
2673 
2674         /// VISA Builder Call
2675         unsigned declID = i;
2676         state_info_t* var = &header.samplers[declID];
2677         VISA_SamplerVar* decl = NULL;
2678         int status = kernelBuilderImpl->CreateVISASamplerVar(
2679             decl, header.strings[var->name_index], var->num_elements);
2680         ASSERT_USER(VISA_SUCCESS == status,
2681             "Failed to add VISA sampler variable.");
2682 
2683         addAllAttributesNG(header, kernelBuilderImpl, decl, var->attribute_count, var->attributes);
2684         container.samplerVarDecls[i] = decl;
2685     }
2686 
2687     kernelBuilderImpl->GetBindlessSampler(container.samplerVarDecls[BINDLESS_SAMPLER_ID]);
2688 
2689     // read surface variables
2690     READ_CISA_FIELD(header.surface_count, uint8_t, bytePos, buf);
2691     unsigned num_pred_surf = Get_CISA_PreDefined_Surf_Count();
2692     header.surface_count += (uint8_t) num_pred_surf;
2693     header.surface_attrs = (bool*)mem.alloc(sizeof(bool) * header.surface_count);
2694     memset(header.surface_attrs, 0, sizeof(bool) * header.surface_count);
2695     header.surfaces = (state_info_t*) mem.alloc(sizeof(state_info_t) * header.surface_count);
2696     container.surfaceVarDecls = (VISA_SurfaceVar**)mem.alloc(sizeof(VISA_SurfaceVar*) * (header.surface_count));
2697     container.surfaceVarsCount = header.surface_count;
2698 
2699     /// Populate the predefined surfaces.
2700     for (unsigned i = 0; i < num_pred_surf; i++)
2701     {
2702         VISA_SurfaceVar* surfaceHnd = NULL;
2703         kernelBuilderImpl->GetPredefinedSurface(surfaceHnd, (PreDefined_Surface)i);
2704         container.surfaceVarDecls[i] = surfaceHnd;
2705     }
2706 
2707     /// Populate the rest of the surfaces.
2708     for (unsigned i = num_pred_surf; i < header.surface_count; i++)
2709     {
2710         readVarBytes(majorVersion, minorVersion, header.surfaces[i].name_index, bytePos, buf);
2711         READ_CISA_FIELD(header.surfaces[i].num_elements, uint16_t, bytePos, buf);
2712         READ_CISA_FIELD(header.surfaces[i].attribute_count, uint8_t, bytePos, buf);
2713         header.surfaces[i].attributes =
2714             (attribute_info_t *)mem.alloc(sizeof(attribute_info_t) * header.surfaces[i].attribute_count);
2715         readAttributesNG(majorVersion, minorVersion, bytePos, buf,
2716             header, header.surfaces[i].attributes, header.surfaces[i].attribute_count, mem);
2717 
2718         /// VISA Builder Call
2719         unsigned declID = i;
2720         state_info_t* var = &header.surfaces[declID];
2721         VISA_SurfaceVar* decl = NULL;
2722         int status = kernelBuilderImpl->CreateVISASurfaceVar(
2723             decl, header.strings[var->name_index], var->num_elements);
2724         ASSERT_USER(VISA_SUCCESS == status,
2725             "Failed to add VISA surface variable.");
2726 
2727         addAllAttributesNG(header, kernelBuilderImpl, decl, var->attribute_count, var->attributes);
2728 
2729         for (unsigned ai = 0; ai < var->attribute_count; ai++)
2730         {
2731             attribute_info_t* attribute = &var->attributes[ai];
2732 
2733             /// TODO: Does this code even make sense anymore???
2734             const char* attrName = header.strings[attribute->nameIndex];
2735             if (Attributes::isAttribute(Attributes::ATTR_SurfaceUsage, attrName))
2736             {
2737                 header.surface_attrs[i] = (attribute->value.intVal == 2);
2738                 break;
2739             }
2740         }
2741 
2742         container.surfaceVarDecls[i] = decl;
2743     }
2744 
2745     int vmeCount = 0;
2746     READ_CISA_FIELD(vmeCount, uint8_t, bytePos, buf);
2747     assert(vmeCount == 0 && "VME variable is no longer supported");
2748     header.vme_count = 0;
2749 
2750     // read input variables
2751     if (isKernel)
2752     {
2753         readVarBytes(container.majorVersion, container.minorVersion, header.input_count, bytePos, buf, FIELD_TYPE::INPUT);
2754 
2755         header.inputs = (input_info_t*)mem.alloc(sizeof(input_info_t) * header.input_count);
2756         container.inputVarDecls = (CISA_GEN_VAR**)mem.alloc(sizeof(CISA_GEN_VAR*) * (header.input_count));
2757         container.inputVarsCount = header.input_count;
2758         for (unsigned i = 0; i < header.input_count; i++)
2759         {
2760             READ_CISA_FIELD(header.inputs[i].kind, uint8_t, bytePos, buf);
2761             readVarBytes(majorVersion, minorVersion, header.inputs[i].index, bytePos, buf);
2762             READ_CISA_FIELD(header.inputs[i].offset, int16_t, bytePos, buf);
2763             READ_CISA_FIELD(header.inputs[i].size, uint16_t, bytePos, buf);
2764 
2765             unsigned declID = i;
2766             input_info_t* var = &header.inputs[declID];
2767             CISA_GEN_VAR* decl = NULL;
2768 
2769             switch (var->getInputClass())
2770             {
2771             case INPUT_GENERAL : decl = container.generalVarDecls[var->index]; break;
2772             case INPUT_SAMPLER : decl = container.samplerVarDecls[var->index]; break;
2773             case INPUT_SURFACE : decl = container.surfaceVarDecls[var->index]; break;
2774             default:
2775                 ASSERT_USER(false, "Incorrect input variable type.");
2776             }
2777 
2778             int status = kernelBuilderImpl->CreateVISAInputVar(decl, var->offset, var->size, var->getImplicitKind());
2779             ASSERT_USER(VISA_SUCCESS == status, "Failed to add VISA input variable.");
2780 
2781             container.inputVarDecls[i] = decl;
2782         }
2783     }
2784 
2785     READ_CISA_FIELD(header.size , unsigned, bytePos, buf);
2786     READ_CISA_FIELD(header.entry, unsigned, bytePos, buf);
2787 
2788     if (!isKernel)
2789     {
2790         READ_CISA_FIELD(header.input_size       , uint8_t, bytePos, buf);
2791         READ_CISA_FIELD(header.return_value_size, uint8_t, bytePos, buf);
2792 
2793         // Store size of arg/ret registers for stack call functions
2794         kernelBuilderImpl->setInputSize(header.input_size);
2795         kernelBuilderImpl->setReturnSize(header.return_value_size);
2796     }
2797 
2798     /// read kernel attributes
2799     READ_CISA_FIELD(header.attribute_count, uint16_t, bytePos, buf);
2800     header.attributes = (attribute_info_t*)mem.alloc(sizeof(attribute_info_t) * header.attribute_count);
2801     readAttributesNG(majorVersion, minorVersion, bytePos, buf, header, header.attributes, header.attribute_count, mem);
2802 
2803     for (unsigned ai = 0; ai < header.attribute_count; ai++)
2804     {
2805         attribute_info_t* attribute = &header.attributes[ai];
2806         /// TODO: This parameter ordering is inconsistent.
2807         kernelBuilderImpl->AddKernelAttribute(header.strings[attribute->nameIndex], attribute->size,
2808             attribute->isInt ? (char*)&attribute->value.intVal : attribute->value.stringVal);
2809     }
2810     if (!kernelBuilderImpl->getKernelAttributes()->isKernelAttrSet(vISA::Attributes::ATTR_Target))
2811     {
2812         VISATarget target = kernelBuilderImpl->getOptions()->getTarget();
2813         kernelBuilderImpl->AddKernelAttribute("Target", 1, &target);
2814     }
2815 
2816     unsigned kernelEntry = kernelStart + header.entry;
2817     unsigned kernelEnd   = kernelEntry + header.size;
2818 
2819     bytePos = kernelEntry;
2820 
2821     for (unsigned i = 0; bytePos < kernelEnd; i++)
2822     {
2823         readInstructionNG(bytePos, buf, container, i);
2824     }
2825 }
2826 
2827 //
2828 // buf -- vISA binary to be processed.  For offline compile it's always the entire vISA object.
2829 //     For JIT mode it's the entire isa file for 3.0, the kernel isa only for 2.x
2830 // builder -- the vISA builder
2831 // kernels -- IR for the vISA kernel
2832 //      if kernelName is specified, return that kernel only in kernels[0]
2833 //      otherwise, all kernels in the isa are processed and returned in kernel
2834 // kernelName -- name of the kernel to be processed.  If null, all kernels will be built
2835 // majorVerion/minorVersion -- version of the vISA binary
2836 // returns true if IR build succeeds, false otherwise
2837 //
readIsaBinaryNG(const char * buf,CISA_IR_Builder * builder,std::vector<VISAKernel * > & kernels,const char * kernelName,unsigned int majorVersion,unsigned int minorVersion)2838 bool readIsaBinaryNG(
2839     const char* buf, CISA_IR_Builder* builder, std::vector<VISAKernel*> &kernels,
2840     const char* kernelName, unsigned int majorVersion, unsigned int minorVersion)
2841 {
2842     MUST_BE_TRUE(buf, "Argument Exception: argument buf  is NULL.");
2843 
2844     unsigned bytePos = 0;
2845     vISA::Mem_Manager mem(4096);
2846     common_isa_header isaHeader;
2847     isaHeader.num_functions = 0;
2848 
2849     processCommonISAHeader(isaHeader, bytePos, buf, &mem);
2850 
2851 
2852 
2853     // we have to set the CISA builder version to the binary version,
2854     // or some instructions that behave differently based on vISA version (e.g., unaligned oword read)
2855     // would not work correctly
2856     builder->CISA_IR_setVersion(isaHeader.major_version, isaHeader.minor_version);
2857 
2858     if (kernelName)
2859     {
2860         int kernelIndex = -1;
2861         for (unsigned i = 0; i < isaHeader.num_kernels; i++)
2862         {
2863             if (!strcmp(isaHeader.kernels[i].name, kernelName))
2864             {
2865                 kernelIndex = i;
2866                 break;
2867             }
2868         }
2869 
2870         if (kernelIndex == -1)
2871         {
2872             return false;
2873         }
2874 
2875         bytePos = isaHeader.kernels[kernelIndex].offset;
2876 
2877         RoutineContainer container;
2878         container.builder = builder;
2879         container.kernelBuilder = NULL;
2880         container.majorVersion = isaHeader.major_version;
2881         container.minorVersion = isaHeader.minor_version;
2882 
2883         builder->AddKernel(container.kernelBuilder, isaHeader.kernels[kernelIndex].name);
2884         kernels.push_back(container.kernelBuilder);
2885 
2886         readRoutineNG(bytePos, buf, mem, container);
2887 
2888         for (unsigned int i = 0; i < isaHeader.num_functions; i++)
2889         {
2890             bytePos = isaHeader.functions[i].offset;
2891 
2892             VISAFunction* funcPtr = NULL;
2893             builder->AddFunction(funcPtr, isaHeader.functions[i].name);
2894 
2895             container.kernelBuilder = (VISAKernel*)funcPtr;
2896             kernels.push_back(container.kernelBuilder);
2897 
2898             readRoutineNG(bytePos, buf, mem, container);
2899         }
2900     }
2901     else
2902     {
2903         for (unsigned int k = 0; k < isaHeader.num_kernels; k++)
2904         {
2905             bytePos = isaHeader.kernels[k].offset;
2906 
2907             RoutineContainer container;
2908             container.builder = builder;
2909             container.kernelBuilder = NULL;
2910             container.majorVersion = isaHeader.major_version;
2911             container.minorVersion = isaHeader.minor_version;
2912 
2913             builder->AddKernel(container.kernelBuilder, isaHeader.kernels[k].name);
2914             kernels.push_back(container.kernelBuilder);
2915 
2916             readRoutineNG(bytePos, buf, mem, container);
2917         }
2918 
2919         for (unsigned int i = 0; i < isaHeader.num_functions; i++)
2920         {
2921             RoutineContainer container;
2922 
2923             container.builder = builder;
2924             container.majorVersion = isaHeader.major_version;
2925             container.minorVersion = isaHeader.minor_version;
2926 
2927             bytePos = isaHeader.functions[i].offset;
2928 
2929             VISAFunction* funcPtr = NULL;
2930             builder->AddFunction(funcPtr, isaHeader.functions[i].name);
2931 
2932             container.kernelBuilder = (VISAKernel*)funcPtr;
2933             kernels.push_back(container.kernelBuilder);
2934 
2935             readRoutineNG(bytePos, buf, mem, container);
2936         }
2937     }
2938 
2939     return true;
2940 }
2941 
2942