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 #include "BinaryCISAEmission.h"
10 #include "JitterDataStruct.h"
11 #include "VISAKernel.h"
12
13 #include <fstream>
14
15 #define SIZE_VALUE cisa_kernel->getBytesWritten()
16 #define SIZE_VALUE_INST cisa_kernel->getBytesWritten() - cisa_kernel->getKernelDataSize()
17
18 using namespace vISA;
19
Emit(VISAKernelImpl * cisa_kernel,unsigned int & binarySize)20 int CBinaryCISAEmitter::Emit(VISAKernelImpl * cisa_kernel, unsigned int& binarySize)
21 {
22 cisa_kernel->finalizeKernel();
23 const kernel_format_t * kernelInfo = cisa_kernel->getKernelFormat();
24
25 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->string_count, sizeof(kernelInfo->string_count));
26
27 for (uint32_t i = 0; i < kernelInfo->string_count; i++)
28 {
29 cisa_kernel->writeInToCisaBinaryBuffer(kernelInfo->strings[i], (int) strlen(kernelInfo->strings[i])+1);
30 }
31
32 DEBUG_PRINT_SIZE("size after string_count: ", SIZE_VALUE);
33
34 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->name_index, sizeof(kernelInfo->name_index));
35
36 DEBUG_PRINT_SIZE("size after name_index: ", SIZE_VALUE);
37
38 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->variable_count, sizeof(kernelInfo->variable_count));
39
40 for (uint32_t i = 0; i < kernelInfo->variable_count; i++)
41 {
42 emitVarInfo(cisa_kernel, &kernelInfo->variables[i]);
43 }
44
45 DEBUG_PRINT_SIZE("size after variables: ", SIZE_VALUE);
46
47 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->address_count, sizeof(kernelInfo->address_count));
48
49 for (int i = 0; i < kernelInfo->address_count; i++)
50 {
51 emitAddressInfo(cisa_kernel, &kernelInfo->addresses[i]);
52 }
53
54 DEBUG_PRINT_SIZE("size after addresses: ", SIZE_VALUE);
55
56 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->predicate_count, sizeof(kernelInfo->predicate_count));
57
58 for (int i = 0; i < kernelInfo->predicate_count; i++)
59 {
60 emitPredicateInfo(cisa_kernel, &kernelInfo->predicates[i]);
61 }
62
63 DEBUG_PRINT_SIZE("size after predicates: ", SIZE_VALUE);
64
65 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->label_count, sizeof(kernelInfo->label_count));
66
67 for (int i = 0; i < kernelInfo->label_count; i++)
68 {
69 emitLabelInfo(cisa_kernel, &kernelInfo->labels[i]);
70 }
71
72 DEBUG_PRINT_SIZE("size after labels: ", SIZE_VALUE);
73
74 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->sampler_count, sizeof(kernelInfo->sampler_count));
75
76 for (int i = 0; i <kernelInfo->sampler_count; i++)
77 {
78 emitStateInfo(cisa_kernel, &kernelInfo->samplers[i]);
79 }
80
81 DEBUG_PRINT_SIZE("size after samplers: ", SIZE_VALUE);
82
83 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->surface_count, sizeof(kernelInfo->surface_count));
84
85 for (int i = 0; i <kernelInfo->surface_count; i++)
86 {
87 emitStateInfo(cisa_kernel, &kernelInfo->surfaces[i]);
88 }
89
90 DEBUG_PRINT_SIZE("size after surfaces: ", SIZE_VALUE);
91
92 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->vme_count, sizeof(kernelInfo->vme_count));
93
94 DEBUG_PRINT_SIZE("size after VMEs: ", SIZE_VALUE);
95
96 if (cisa_kernel->getIsKernel())
97 {
98 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->input_count, sizeof(kernelInfo->input_count));
99
100 for (uint32_t i = 0; i < kernelInfo->input_count; i++)
101 {
102 emitInputInfo(cisa_kernel, &kernelInfo->inputs[i]);
103 }
104
105 DEBUG_PRINT_SIZE("size after inputs: ", SIZE_VALUE);
106 }
107
108 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->size, sizeof(kernelInfo->size));
109
110 DEBUG_PRINT_SIZE("size after size: ", SIZE_VALUE);
111
112 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->entry, sizeof(kernelInfo->entry));
113
114 DEBUG_PRINT_SIZE("size after entry: ", SIZE_VALUE);
115
116 if (!cisa_kernel->getIsKernel())
117 {
118 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->input_size, sizeof(kernelInfo->input_size));
119 DEBUG_PRINT_SIZE("size after input size: ", SIZE_VALUE);
120
121 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->return_type, sizeof(kernelInfo->return_type));
122 DEBUG_PRINT_SIZE("size after return type: ", SIZE_VALUE);
123 }
124
125 cisa_kernel->writeInToCisaBinaryBuffer(&kernelInfo->attribute_count, sizeof(kernelInfo->attribute_count));
126
127 for (int i = 0; i < kernelInfo->attribute_count; i++)
128 {
129 this->emitAttributeInfo(cisa_kernel, &kernelInfo->attributes[i]);
130 }
131
132 DEBUG_PRINT_SIZE("size after attributes: ", SIZE_VALUE);
133
134 std::list<CisaFramework::CisaInst *>::iterator inst_iter = cisa_kernel->getInstructionListBegin();
135 std::list<CisaFramework::CisaInst *>::iterator inst_iter_end = cisa_kernel->getInstructionListEnd();
136
137 int status = VISA_SUCCESS;
138 for (; inst_iter != inst_iter_end; inst_iter++)
139 {
140 CisaFramework::CisaInst * inst = *inst_iter;
141
142 const CISA_INST * cisa_inst = inst->getCISAInst();
143 const VISA_INST_Desc * inst_desc = inst->getCISAInstDesc();
144 status = emitCisaInst(cisa_kernel, cisa_inst, inst_desc);
145 if (status != VISA_SUCCESS)
146 {
147 break;
148 }
149 }
150
151 return status;
152 }
153
emitCisaInst(VISAKernelImpl * cisa_kernel,const CISA_INST * inst,const VISA_INST_Desc * desc)154 int CBinaryCISAEmitter::emitCisaInst(
155 VISAKernelImpl* cisa_kernel, const CISA_INST* inst, const VISA_INST_Desc* desc)
156 {
157 bool useSubDesc = false;
158 uint8_t subOpcode = 0;
159 unsigned reverseOffset = 0;
160
161 cisa_kernel->writeInToCisaBinaryBuffer(&desc->opcode, sizeof(desc->opcode));
162
163 unsigned opndCount = desc->opnd_num;
164
165 for (unsigned i = 0; i < opndCount; i++)
166 {
167 unsigned currendOpndIndex = i - reverseOffset;
168
169 if (inst->opnd_array != NULL && inst->opnd_array[currendOpndIndex] == NULL)
170 {
171 assert(0);
172 return VISA_FAILURE;
173 }
174
175 if (!useSubDesc && desc->opnd_desc[i].opnd_type == OPND_SUBOPCODE)
176 {
177 useSubDesc = true;
178 subOpcode = getPrimitiveOperand<uint8_t>(inst, i);
179 cisa_kernel->writeInToCisaBinaryBuffer(&subOpcode, sizeof(subOpcode));
180 opndCount += desc->getSubInstDesc(subOpcode).opnd_num;
181 }
182 else if ((useSubDesc == false && desc->opnd_desc[i].opnd_type == OPND_EXECSIZE) ||
183 (useSubDesc == true && desc->getSubInstDesc(subOpcode).opnd_desc[i-1].opnd_type == OPND_EXECSIZE))
184 {
185 cisa_kernel->writeInToCisaBinaryBuffer(&inst->execsize, sizeof(inst->execsize));
186 reverseOffset++;
187 }
188 else if ((useSubDesc == false && desc->opnd_desc[i ].opnd_type == OPND_PRED) ||
189 (useSubDesc == true && desc->getSubInstDesc(subOpcode).opnd_desc[i-1].opnd_type == OPND_PRED))
190
191 {
192 auto predInBinary = inst->pred.getPredInBinary();
193 cisa_kernel->writeInToCisaBinaryBuffer(&predInBinary, inst->pred.getPredInBinarySize());
194 reverseOffset++;
195 }
196 else if (inst->opnd_array != NULL && inst->opnd_array[currendOpndIndex]->opnd_type == CISA_OPND_OTHER)
197 {
198 cisa_kernel->writeInToCisaBinaryBuffer(&inst->opnd_array[currendOpndIndex]->_opnd.other_opnd, inst->opnd_array[currendOpndIndex]->size);
199 }
200 else if (inst->opnd_array != NULL && inst->opnd_array[currendOpndIndex]->opnd_type == CISA_OPND_VECTOR)
201 {
202 emitVectorOpnd(cisa_kernel, &inst->opnd_array[currendOpndIndex]->_opnd.v_opnd);
203 }
204 else if (inst->opnd_array != NULL && inst->opnd_array[currendOpndIndex]->opnd_type == CISA_OPND_RAW)
205 {
206 emitRawOpnd(cisa_kernel, &inst->opnd_array[currendOpndIndex]->_opnd.r_opnd);
207 }
208 }
209
210 DEBUG_PRINT_SIZE_INSTRUCTION("size after instruction: ", desc->opcode, SIZE_VALUE_INST);
211 return VISA_SUCCESS;
212 }
213
emitVarInfo(VISAKernelImpl * cisa_kernel,var_info_t * var)214 void CBinaryCISAEmitter::emitVarInfo(VISAKernelImpl * cisa_kernel, var_info_t * var)
215 {
216 cisa_kernel->writeInToCisaBinaryBuffer(&var->name_index, sizeof(var->name_index));
217 cisa_kernel->writeInToCisaBinaryBuffer(&var->bit_properties, sizeof(var->bit_properties));
218 cisa_kernel->writeInToCisaBinaryBuffer(&var->num_elements, sizeof(var->num_elements));
219 cisa_kernel->writeInToCisaBinaryBuffer(&var->alias_index, sizeof(var->alias_index));
220 cisa_kernel->writeInToCisaBinaryBuffer(&var->alias_offset, sizeof(var->alias_offset));
221
222 cisa_kernel->writeInToCisaBinaryBuffer(&var->alias_scope_specifier, sizeof(var->alias_scope_specifier));
223
224 cisa_kernel->writeInToCisaBinaryBuffer(&var->attribute_count, sizeof(var->attribute_count));
225
226 for (int i = 0; i < var->attribute_count; i++)
227 {
228 emitAttributeInfo(cisa_kernel, &var->attributes[i]);
229 }
230 }
231
emitStateInfo(VISAKernelImpl * cisa_kernel,state_info_t * var)232 void CBinaryCISAEmitter::emitStateInfo(VISAKernelImpl * cisa_kernel, state_info_t * var)
233 {
234 cisa_kernel->writeInToCisaBinaryBuffer(&var->name_index, sizeof(var->name_index));
235 cisa_kernel->writeInToCisaBinaryBuffer(&var->num_elements, sizeof(var->num_elements));
236 cisa_kernel->writeInToCisaBinaryBuffer(&var->attribute_count, sizeof(var->attribute_count));
237
238 for (int i = 0; i < var->attribute_count; i++)
239 {
240 emitAttributeInfo(cisa_kernel, &var->attributes[i]);
241 }
242 }
243
emitAddressInfo(VISAKernelImpl * cisa_kernel,addr_info_t * addr)244 void CBinaryCISAEmitter::emitAddressInfo(VISAKernelImpl * cisa_kernel, addr_info_t * addr)
245 {
246 cisa_kernel->writeInToCisaBinaryBuffer(&addr->name_index, sizeof(addr->name_index));
247 cisa_kernel->writeInToCisaBinaryBuffer(&addr->num_elements, sizeof(addr->num_elements));
248 cisa_kernel->writeInToCisaBinaryBuffer(&addr->attribute_count, sizeof(addr->attribute_count));
249
250 for (int i = 0; i < addr->attribute_count; i++)
251 {
252 emitAttributeInfo(cisa_kernel, &addr->attributes[i]);
253 }
254 }
255
emitPredicateInfo(VISAKernelImpl * cisa_kernel,pred_info_t * pred)256 void CBinaryCISAEmitter::emitPredicateInfo(VISAKernelImpl * cisa_kernel, pred_info_t * pred)
257 {
258 cisa_kernel->writeInToCisaBinaryBuffer(&pred->name_index, sizeof(pred->name_index));
259 cisa_kernel->writeInToCisaBinaryBuffer(&pred->num_elements, sizeof(pred->num_elements));
260 cisa_kernel->writeInToCisaBinaryBuffer(&pred->attribute_count, sizeof(pred->attribute_count));
261
262 for (int i = 0; i < pred->attribute_count; i++)
263 {
264 emitAttributeInfo(cisa_kernel, &pred->attributes[i]);
265 }
266 }
267
emitLabelInfo(VISAKernelImpl * cisa_kernel,label_info_t * lbl)268 void CBinaryCISAEmitter::emitLabelInfo(VISAKernelImpl * cisa_kernel, label_info_t * lbl)
269 {
270 cisa_kernel->writeInToCisaBinaryBuffer(&lbl->name_index, sizeof(lbl->name_index));
271 cisa_kernel->writeInToCisaBinaryBuffer(&lbl->kind, sizeof(lbl->kind));
272 cisa_kernel->writeInToCisaBinaryBuffer(&lbl->attribute_count, sizeof(lbl->attribute_count));
273
274 for (int i = 0; i < lbl->attribute_count; i++)
275 {
276 emitAttributeInfo(cisa_kernel, &lbl->attributes[i]);
277 }
278 }
279
emitInputInfo(VISAKernelImpl * cisa_kernel,input_info_t * in)280 void CBinaryCISAEmitter::emitInputInfo(VISAKernelImpl * cisa_kernel, input_info_t * in)
281 {
282 cisa_kernel->writeInToCisaBinaryBuffer(&in->kind, sizeof(in->kind));
283 cisa_kernel->writeInToCisaBinaryBuffer(&in->index, sizeof(in->index));
284 cisa_kernel->writeInToCisaBinaryBuffer(&in->offset, sizeof(in->offset));
285 cisa_kernel->writeInToCisaBinaryBuffer(&in->size, sizeof(in->size));
286 }
287
emitAttributeInfo(VISAKernelImpl * cisa_kernel,attribute_info_t * attr)288 void CBinaryCISAEmitter::emitAttributeInfo(VISAKernelImpl *cisa_kernel, attribute_info_t * attr)
289 {
290 cisa_kernel->writeInToCisaBinaryBuffer(&attr->nameIndex, sizeof(attr->nameIndex));
291 cisa_kernel->writeInToCisaBinaryBuffer(&attr->size, sizeof(attr->size));
292
293 if (attr->isInt)
294 {
295 switch (attr->size)
296 {
297 case 0: break; // Attribute without Value
298 case sizeof(int8_t): cisa_kernel->writeInToCisaBinaryBuffer((int8_t *)(&attr->value.intVal), attr->size); break;
299 case sizeof(int16_t): cisa_kernel->writeInToCisaBinaryBuffer((int16_t*)(&attr->value.intVal), attr->size); break;
300 case sizeof(int32_t): cisa_kernel->writeInToCisaBinaryBuffer((int32_t*)(&attr->value.intVal), attr->size); break;
301 default:
302 assert(0);
303 break;
304 }
305 }
306 else
307 cisa_kernel->writeInToCisaBinaryBuffer(attr->value.stringVal, attr->size);
308 }
309
emitVectorOpnd(VISAKernelImpl * cisa_kernel,vector_opnd * cisa_opnd)310 void CBinaryCISAEmitter::emitVectorOpnd(VISAKernelImpl * cisa_kernel, vector_opnd * cisa_opnd)
311 {
312 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->tag, sizeof(cisa_opnd->tag));
313
314 switch (cisa_opnd->tag & 0x7)
315 {
316 case OPERAND_GENERAL:
317 {
318 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.gen_opnd.index, sizeof(cisa_opnd->opnd_val.gen_opnd.index));
319 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.gen_opnd.row_offset, sizeof(cisa_opnd->opnd_val.gen_opnd.row_offset));
320 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.gen_opnd.col_offset, sizeof(cisa_opnd->opnd_val.gen_opnd.col_offset));
321 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.gen_opnd.region, sizeof(cisa_opnd->opnd_val.gen_opnd.region));
322 break;
323 }
324 case OPERAND_ADDRESS:
325 {
326 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.addr_opnd.index, sizeof(cisa_opnd->opnd_val.addr_opnd.index));
327 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.addr_opnd.offset, sizeof(cisa_opnd->opnd_val.addr_opnd.offset));
328 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.addr_opnd.width, sizeof(cisa_opnd->opnd_val.addr_opnd.width));
329 break;
330 }
331 case OPERAND_INDIRECT:
332 {
333 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.indirect_opnd.index, sizeof(cisa_opnd->opnd_val.indirect_opnd.index));
334 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.indirect_opnd.addr_offset, sizeof(cisa_opnd->opnd_val.indirect_opnd.addr_offset));
335 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.indirect_opnd.indirect_offset, sizeof(cisa_opnd->opnd_val.indirect_opnd.indirect_offset));
336 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.indirect_opnd.bit_property, sizeof(cisa_opnd->opnd_val.indirect_opnd.bit_property));
337 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.indirect_opnd.region, sizeof(cisa_opnd->opnd_val.indirect_opnd.region));
338 break;
339 }
340 case OPERAND_PREDICATE:
341 {
342 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.pred_opnd.index, sizeof(cisa_opnd->opnd_val.pred_opnd.index));
343 break;
344 }
345 case OPERAND_IMMEDIATE:
346 {
347 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.const_opnd.type, sizeof(cisa_opnd->opnd_val.const_opnd.type));
348 if (cisa_opnd->opnd_val.const_opnd.type == ISA_TYPE_DF)
349 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.const_opnd._val.dval, sizeof(double));
350 else if (cisa_opnd->opnd_val.const_opnd.type == ISA_TYPE_Q || cisa_opnd->opnd_val.const_opnd.type == ISA_TYPE_UQ)
351 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.const_opnd._val.lval, sizeof(unsigned long long));
352 else
353 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.const_opnd._val.ival, sizeof(unsigned int));
354 break;
355 }
356 case OPERAND_STATE:
357 {
358 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.state_opnd.opnd_class, sizeof(cisa_opnd->opnd_val.state_opnd.opnd_class));
359 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.state_opnd.index, sizeof(cisa_opnd->opnd_val.state_opnd.index));
360 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->opnd_val.state_opnd.offset, sizeof(cisa_opnd->opnd_val.state_opnd.offset));
361 break;
362 }
363 default:
364 {
365 MUST_BE_TRUE(0, "Invalid Vector Operand Class. Size cannot be determined.");
366 break;
367 }
368 }
369 }
emitRawOpnd(VISAKernelImpl * cisa_kernel,raw_opnd * cisa_opnd)370 void CBinaryCISAEmitter::emitRawOpnd(VISAKernelImpl * cisa_kernel, raw_opnd * cisa_opnd)
371 {
372 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->index, sizeof(cisa_opnd->index));
373 cisa_kernel->writeInToCisaBinaryBuffer(&cisa_opnd->offset, sizeof(cisa_opnd->offset));
374 }
375