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