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 "BinaryEncoding.h"
10 #include "BuildIR.h"
11
12 using namespace vISA;
13
14 // Initlaize the platform dependent bit positions to some illegal value
15 // They will be set to the correct value by the Init() function
16 // Technically these should be TLS, but I'm counting on the fact that
17 // these values will be fixed for a given platform, and an application
18 // should never invoke the jitter twice with different platform strings.
19 // Initlaize the platform dependent bit positions to some illegal value
20 // They will be set to the correct value by the Init() function
21 // Technically these should be TLS, but I'm counting on the fact that
22 // these values will be fixed for a given platform, and an application
23 // should never invoke the jitter twice with different platform strings.
24 unsigned long bitsFlagSubRegNum[] = {128, 128};
25 unsigned long bitsNibCtrl[] = {128, 128};
26 unsigned long bits3SrcFlagSubRegNum[] = {128, 128};
27 unsigned long bits3SrcSrcType[] = {128, 128};
28 unsigned long bits3SrcDstType[] = {128, 128};
29 unsigned long bits3SrcNibCtrl[] = {128, 128};
30 unsigned long bits3SrcDstRegFile[] = {128, 128};
31
32 unsigned long bitsDepCtrl[] = {128, 128};
33 unsigned long bitsWECtrl[] = {128, 128};
34 unsigned long bitsDstRegFile[] = {128, 128};
35 unsigned long bitsDstType[] = {128, 128};
36 unsigned long bitsDstIdxRegNum[] = {128, 128};
37 unsigned long bitsDstIdxImmOWord[] = {128, 128};
38 unsigned long bitsDstIdxImmByte[] = {128, 128};
39 unsigned long bitsDstIdxImmMSB[] = {128, 128};
40 unsigned long bitsSrcType[] = {128, 128, 128, 128};
41 unsigned long bitsSrcIdxRegNum[] = {128, 128, 128, 128};
42 unsigned long bitsSrcIdxImmOWord[] = {128, 128, 128, 128};
43 unsigned long bitsSrcIdxImmByte[] = {128, 128, 128, 128};
44 unsigned long bitsSrcIdxImmMSB[] = {128, 128, 128, 128};
45 unsigned long bitsJIP[] = {128, 128};
46 unsigned long bitsUIP[] = {128, 128};
47 unsigned long bits3SrcSrcMod[] = {128, 128, 128, 128, 128, 128};
48
49 /************************************************************************/
50 /* Auxiliary */
51 /************************************************************************/
52
SetOpCode(BinInst * mybin,uint32_t value)53 inline void SetOpCode(BinInst *mybin, uint32_t value)
54 {
55 mybin->SetBits(bitsOpCode_0, bitsOpCode_1, value);
56 }
57
EncodeOpCode(G4_INST * inst)58 inline void BinaryEncoding::EncodeOpCode(G4_INST* inst)
59 {
60 BinInst *mybin = inst->getBinInst();
61 G4_opcode opcode = inst->opcode();
62 uint32_t euopc = getEUOpcode(opcode);
63 SetOpCode(mybin, euopc);
64 }
65
EncodeExecSize(G4_INST * inst)66 inline void BinaryEncoding::EncodeExecSize(G4_INST* inst)
67 {
68 BinInst *mybin = inst->getBinInst();
69 mybin->SetBits(bitsExecSize_0, bitsExecSize_1, GetEncodeExecSize(inst));
70 }
71
EncodeAccessMode(G4_INST * inst)72 inline void BinaryEncoding::EncodeAccessMode(G4_INST* inst)
73 {
74 BinInst *mybin = inst->getBinInst();
75
76 if (inst->isAligned1Inst()) {
77 mybin->SetBits(bitsAccessMode_0, bitsAccessMode_1, ACCESS_MODE_ALIGN1);
78 }
79 else if (inst->isAligned16Inst()) {
80 mybin->SetBits(bitsAccessMode_0, bitsAccessMode_1, ACCESS_MODE_ALIGN16);
81 }
82 else
83 {
84 }
85 }
86
87 static const unsigned PREDICATE_STATE[3] =
88 {
89 (unsigned)PREDICATE_STATE_NORMAL, // plus and undef are normal
90 (unsigned)PREDICATE_STATE_INVERT << 4, // minus is invert
91 (unsigned)PREDICATE_STATE_NORMAL // plus and undef are normal
92 };
93
EncodeFlagRegPredicate(G4_INST * inst)94 inline void BinaryEncoding::EncodeFlagRegPredicate(G4_INST* inst)
95 {
96 BinInst *mybin = inst->getBinInst();
97 G4_Predicate *pred = inst->getPredicate();
98 uint32_t flagState = 0, flagSwizzle;
99 if (pred)
100 {
101 unsigned pState = (unsigned)pred->getState();
102 MUST_BE_TRUE(pState <= (unsigned)PredState_undef,
103 "BinaryEncoding: invalid prediate state");
104 flagState = PREDICATE_STATE[pState];
105
106 flagSwizzle = inst->isAligned16Inst() ?
107 PREDICATE_ALIGN16_SEQUENTIAL : PREDICATE_ALIGN1_SEQUENTIAL;
108
109 if (inst->isAligned16Inst())
110 {
111 flagSwizzle = pred->getAlign16PredicateControl();
112 }
113 else
114 {
115 auto predCtrl = pred->getControl();
116 if (predCtrl != PRED_DEFAULT)
117 flagSwizzle = (uint32_t) GetAlign1PredCtrl(predCtrl);
118 }
119
120 mybin->SetBits(bitsPredicate_0, bitsPredicate_1, flagState | flagSwizzle);
121 }
122 }
123
SetFlagSubRegNum(BinInst * mybin,uint32_t value)124 inline void SetFlagSubRegNum(BinInst *mybin, uint32_t value)
125 {
126 if (mybin->GetIs3Src())
127 mybin->SetBits(bits3SrcFlagSubRegNum[0], bits3SrcFlagSubRegNum[1], value);
128 else
129 mybin->SetBits(bitsFlagSubRegNum[0], bitsFlagSubRegNum[1], value);
130 }
131
132
EncodeFlagReg(G4_INST * inst)133 inline void BinaryEncoding::EncodeFlagReg(G4_INST* inst)
134 {
135 bool flagRegNumValid = false;
136 unsigned FlagRegNumValue = 0;
137 unsigned FlagRegSubNumValue = 0;
138 BinInst *mybin = inst->getBinInst();
139
140 G4_Predicate *pred = inst->getPredicate();
141 if (pred) {
142 FlagRegNumValue = pred->getBase()->ExRegNum(flagRegNumValid);
143 FlagRegSubNumValue = pred->getBase()->asRegVar()->getPhyRegOff();
144 }
145
146 G4_CondMod *cModifier = inst->getCondMod();
147 if (cModifier) { // cond modifier
148 G4_VarBase* flagReg = cModifier->getBase();
149 if (flagReg != NULL)
150 {
151 FlagRegNumValue = flagReg->ExRegNum(flagRegNumValid);
152 FlagRegSubNumValue = flagReg->asRegVar()->getPhyRegOff();
153 }
154 else
155 {
156 FlagRegNumValue = 0;
157 FlagRegSubNumValue = 0;
158 }
159 }
160
161 if (pred || cModifier) {
162 if (flagRegNumValid) {
163 switch (FlagRegNumValue) {
164 case 0:
165 // flag reg num is always zero prior to Gen7
166 break;
167 case 1:
168 SetFlagRegNum(mybin, FlagRegNumValue);
169 break;
170 default:
171 MUST_BE_TRUE(false, "Invalid flag register number");
172 break;
173 }
174 }
175 if (FlagRegSubNumValue != UNDEFINED_SHORT) {
176 switch (FlagRegSubNumValue) {
177 case 0:
178 case 1:
179 SetFlagSubRegNum(mybin, FlagRegSubNumValue);
180 break;
181 default:
182 MUST_BE_TRUE(false, "invalid flag register sub-number");
183 }
184 }
185 }
186 }
187
188 static const unsigned CONDITION_MODIFIER[11] =
189 {
190 (unsigned)COND_CODE_Z,
191 (unsigned)COND_CODE_Z,
192 (unsigned)COND_CODE_NZ,
193 (unsigned)COND_CODE_NZ,
194 (unsigned)COND_CODE_G,
195 (unsigned)COND_CODE_GE,
196 (unsigned)COND_CODE_L,
197 (unsigned)COND_CODE_LE,
198 (unsigned)COND_CODE_ANY,
199 (unsigned)COND_CODE_O,
200 (unsigned)COND_CODE_ALL
201 };
202
EncodeCondModifier(G4_INST * inst)203 inline void BinaryEncoding::EncodeCondModifier(G4_INST* inst)
204 {
205 BinInst *mybin = inst->getBinInst();
206 G4_CondMod *cModifier = inst->getCondMod();
207 uint32_t value;
208 if (cModifier) {
209 value = (unsigned)cModifier->getMod();
210 MUST_BE_TRUE(value < Mod_cond_undef,
211 "[Verifying]:[ERR]: Invalid conditional modifier:\t");
212 mybin->SetBits(bitsCondModifier_0, bitsCondModifier_1, CONDITION_MODIFIER[value]);
213 }
214 }
215
EncodeQtrControl(G4_INST * inst)216 inline void BinaryEncoding::EncodeQtrControl(G4_INST* inst)
217 {
218 BinInst *mybin = inst->getBinInst();
219
220 unsigned int emaskOffset = inst->getMaskOffset();
221 mybin->SetBits(bitsQtrCtrl_0, bitsQtrCtrl_1, emaskOffset / 8);
222 mybin->SetBits(bitsNibCtrl[0], bitsNibCtrl[1], (emaskOffset % 8 != 0) ? 1 : 0);
223 }
224
EncodeInstModifier(G4_INST * inst)225 inline void BinaryEncoding::EncodeInstModifier(G4_INST* inst)
226 {
227 BinInst *mybin = inst->getBinInst();
228 if (inst->getSaturate()) {
229 mybin->SetBits(bitsInstModifier_0, bitsInstModifier_1, INST_MOD_SAT);
230 }
231 else {
232 mybin->SetBits(bitsInstModifier_0, bitsInstModifier_1, INST_MOD_NONE);
233 }
234 }
235
EncodeMathControl(G4_INST * inst)236 inline void BinaryEncoding::EncodeMathControl(G4_INST* inst)
237 {
238 MUST_BE_TRUE(inst->isMath(), "BinaryEncoding::EncodeMathControl called on non-math instruction.");
239 BinInst *mybin = inst->getBinInst();
240
241 unsigned int MathControlValue = inst->asMathInst()->getMathCtrl();
242 unsigned MathFunction = MathControlValue & 0xf;
243 unsigned MathPartPrec = (MathControlValue >> 4) & 1;
244
245 if (!mybin->GetIs3Src()) {
246 mybin->SetBits(bitsMathFunction_0, bitsMathFunction_1, MathFunction);
247 mybin->SetBits(bitsMathPartPrec_0, bitsMathPartPrec_1, MathPartPrec);
248 }
249
250 }
251
EncodeAccWrCtrlInst(G4_INST * inst)252 inline void EncodeAccWrCtrlInst(G4_INST *inst)
253 {
254 BinInst *mybin = inst->getBinInst();
255 //Jmpi does not support BranchControl
256 if (inst->isAccWrCtrlInst() || (inst->isFlowControl() && inst->asCFInst()->isBackward() && inst->opcode() != G4_jmpi))
257 {
258 mybin->SetBits(bitsAccWrCtrl_0, bitsAccWrCtrl_1, 1);
259 return;
260 }
261 }
262
263 // set bit 29/30 (FP16 input/return) if message descriptor is indirect
264 // This is to work around a HW bug where only bit[0:28] of a0 is copied
EncodeSendMsgDesc29_30(G4_INST * inst)265 inline void BinaryEncoding::EncodeSendMsgDesc29_30(G4_INST* inst)
266 {
267 MUST_BE_TRUE(inst->isSend(), "must be a send inst");
268
269 BinInst *mybin = inst->getBinInst();
270 G4_SendDescRaw* msgDesc = inst->getMsgDescRaw();
271 MUST_BE_TRUE(msgDesc, "expected raw descriptor");
272 G4_Operand* descOpnd = inst->isSplitSend() ? inst->getSrc(2) : inst->getSrc(1);
273 if (!descOpnd->isImm())
274 {
275 uint32_t bitValue = (msgDesc->is16BitReturn() << 1) + msgDesc->is16BitInput();
276 mybin->SetBits(bitsSendDesc_30, bitsSendDesc_29, bitValue);
277 }
278 }
279
EncodeInstOptionsString(G4_INST * inst)280 inline void BinaryEncoding::EncodeInstOptionsString(G4_INST* inst)
281 {
282 BinInst *mybin = inst->getBinInst();
283
284 EncodeAccessMode(inst);
285 EncodeQtrControl(inst);
286 EncodeAccWrCtrlInst(inst);
287
288 mybin->SetBits(bitsCompactCtrl_0, bitsCompactCtrl_1,
289 inst->isCompactedInst());
290
291 if (inst->opcode() == G4_if ||
292 inst->opcode() == G4_else ||
293 inst->opcode() == G4_endif)
294 {
295
296 }
297 else
298 {
299 mybin->SetBits(bitsThreadCtrl_0, bitsThreadCtrl_1,
300 inst->isAtomicInst()? THREAD_CTRL_ATOMIC :
301 // CHAI: Add Switch InstOpt support
302 (inst->isYieldInst()? THREAD_CTRL_SWITCH : THREAD_CTRL_NORMAL));
303 }
304
305
306 if (inst->isNoDDChkInst())
307 {
308 if (inst->isNoDDClrInst())
309 {
310 mybin->SetBits(bitsDepCtrl[0], bitsDepCtrl[1],
311 DEP_CTRL_DIS_CHECK_CLEAR_DEST);
312 } else {
313 mybin->SetBits(bitsDepCtrl[0], bitsDepCtrl[1],
314 DEP_CTRL_DIS_CHECK);
315 }
316 }
317 else {
318 if (inst->isNoDDClrInst())
319 {
320 mybin->SetBits(bitsDepCtrl[0], bitsDepCtrl[1],
321 DEP_CTRL_DIS_CLEAR);
322 } else {
323 mybin->SetBits(bitsDepCtrl[0], bitsDepCtrl[1],
324 DEP_CTRL_NORMAL);
325 }
326 }
327
328 if (inst->isWriteEnableInst())
329 mybin->SetBits(bitsWECtrl[0], bitsWECtrl[1], 1);
330
331 if (inst->opcode()==G4_jmpi)
332 mybin->SetBits(bitsWECtrl[0], bitsWECtrl[1], 1);
333
334 if (inst->isBreakPointInst())
335 mybin->SetBits(bitsDebugCtrl_0, bitsDebugCtrl_1, 1);
336
337 if (inst->isNoSrcDepSet())
338 {
339 mybin->SetBits(bitsNoSrcDepSet_0, bitsNoSrcDepSet_1, 1);
340 }
341
342 if (!mybin->GetIs3Src())
343 {
344 if (inst->isEOT())
345 mybin->SetBits(bitsEndOfThread_0, bitsEndOfThread_1, 1);
346 }
347
348 }
349
350 ///////////////////////////////////////////////////////////////////////////////
351 // Generic Src Utilities
352 ///////////////////////////////////////////////////////////////////////////////
353
GetOperandSrcType(G4_Operand * src)354 inline uint32_t GetOperandSrcType(G4_Operand *src)
355 {
356 uint32_t type;
357 G4_Type regType;
358
359 if (src->isSrcRegRegion())
360 {
361 regType = src->asSrcRegRegion()->getType();
362 }
363 else
364 {
365 regType = src->getType();
366 }
367
368 switch (regType) {
369 case Type_UD:
370 case Type_D:
371 case Type_UW:
372 case Type_W:
373 case Type_UB:
374 case Type_B:
375 type = regType;
376 break;
377 case Type_DF:
378 type = SRC_TYPE_DF;
379 break;
380 case Type_F:
381 type = SRC_TYPE_F;
382 break;
383 case Type_UQ:
384 type = SRC_TYPE_UQ;
385 break;
386 case Type_Q:
387 type = SRC_TYPE_Q;
388 break;
389 case Type_HF:
390 type = SRC_TYPE_HF;
391 break;
392 default:
393 type = SRC_TYPE_UNDEF;
394 MUST_BE_TRUE(false, "Binary code emission error: unknown type");
395 }
396 return type;
397 }
398
GetOperandSrcImmType(G4_Operand * src)399 inline uint32_t GetOperandSrcImmType(G4_Operand *src)
400 {
401 uint32_t type;
402 switch (src->getType()) {
403 case Type_UD:
404 case Type_D:
405 case Type_UW:
406 case Type_W:
407 type = src->getType();
408 break;
409 case Type_UV:
410 type = SRC_IMM_TYPE_UV;
411 break;
412 case Type_VF:
413 type = SRC_IMM_TYPE_VF;
414 break;
415 case Type_V:
416 type = SRC_IMM_TYPE_V;
417 break;
418 case Type_F:
419 type = SRC_IMM_TYPE_F;
420 break;
421 case Type_UQ:
422 type = SRC_IMM_TYPE_UQ;
423 break;
424 case Type_Q:
425 type = SRC_IMM_TYPE_Q;
426 break;
427 case Type_DF:
428 type = SRC_IMM_TYPE_DF;
429 break;
430 case Type_HF:
431 type = SRC_IMM_TYPE_HF;
432 break;
433 default:
434 type = SRC_TYPE_UNDEF;
435 break;
436 }
437 return type;
438 }
439
440 static const unsigned SOURCE_MODIFIER[5] =
441 {
442 (unsigned)SRC_MOD_NEGATE,
443 (unsigned)SRC_MOD_ABSOLUTE,
444 (unsigned)SRC_MOD_NEGATE_OF_ABSOLUTE,
445 (unsigned)SRC_MOD_NEGATE,
446 (unsigned)SRC_MOD_NONE
447 };
448
GetSrcMod(G4_SrcRegRegion * srcRegion)449 inline uint32_t GetSrcMod(G4_SrcRegRegion *srcRegion)
450 {
451 unsigned mod = (unsigned)srcRegion->getModifier();
452 MUST_BE_TRUE(mod <= (unsigned)Mod_src_undef,
453 "BinaryEncoding: Unexpected source modifier");
454 return SOURCE_MODIFIER[mod];
455 }
456
457
458 ///////////////////////////////////////////////////////////////////////////////
459 // Dst
460 ///////////////////////////////////////////////////////////////////////////////
461
462
463
SetDstRegFile(BinInst * mybin,uint32_t value)464 inline void SetDstRegFile(BinInst *mybin, uint32_t value)
465 {
466 if (!mybin->GetIs3Src())
467 {
468 mybin->SetBits(bitsDstRegFile[0], bitsDstRegFile[1], value);
469 }
470 }
471
SetDstType(BinInst * mybin,uint32_t value)472 inline void SetDstType(BinInst *mybin, uint32_t value)
473 {
474 if (mybin->GetIs3Src())
475 // handled by Set3SrcDstType
476 return;
477 else
478 mybin->SetBits(bitsDstType[0], bitsDstType[1], value);
479 }
480
SetDstAddrMode(BinInst * mybin,uint32_t value)481 inline void SetDstAddrMode(BinInst *mybin, uint32_t value)
482 {
483 if (mybin->GetIs3Src())
484 return;
485 else
486 mybin->SetBits(bitsDstAddrMode_0, bitsDstAddrMode_1, value);
487 }
488
SetDstRegNumOWord(BinInst * mybin,uint32_t value)489 inline void SetDstRegNumOWord(BinInst *mybin, uint32_t value)
490 {
491 if (mybin->GetIs3Src())
492 mybin->SetBits(bits3SrcDstRegNumOWord_0,
493 bits3SrcDstRegNumOWord_1, value);
494 else
495 mybin->SetBits(bitsDstRegNumOWord_0,
496 bitsDstRegNumOWord_1, value);
497 }
498
SetDstRegNumByte(BinInst * mybin,uint32_t value)499 inline void SetDstRegNumByte(BinInst *mybin, uint32_t value)
500 {
501 if (mybin->GetIs3Src())
502 mybin->SetBits(bits3SrcDstRegNumDWord_0, bits3SrcDstRegNumDWord_1, (value >> 2));
503 else
504 mybin->SetBits(bitsDstRegNumByte_0, bitsDstRegNumByte_1, value);
505 }
506
SetDstChanEn(BinInst * mybin,uint32_t value)507 inline void SetDstChanEn(BinInst *mybin, uint32_t value)
508 {
509 if (mybin->GetIs3Src())
510 mybin->SetBits(bits3SrcDstChanEn_0,
511 bits3SrcDstChanEn_1, value);
512 else
513 mybin->SetBits(bitsDstChanEn_0,
514 bitsDstChanEn_1, value);
515 }
516
517 /**
518 * Below three functions set dst's indirect register number
519 */
SetDstIdxRegNum(BinInst * mybin,uint32_t value)520 inline void SetDstIdxRegNum(BinInst *mybin, uint32_t value)
521 {
522 if (mybin->GetIs3Src())
523 return;
524 else
525 mybin->SetBits(bitsDstIdxRegNum[0], bitsDstIdxRegNum[1], value);
526 }
527
SetDstIdxImmOWord(BinInst * mybin,uint32_t value)528 inline void SetDstIdxImmOWord(BinInst *mybin, uint32_t value)
529 {
530 if (mybin->GetIs3Src())
531 return;
532
533 mybin->SetBits(bitsDstIdxImmOWord[0], bitsDstIdxImmOWord[1], value);
534 mybin->SetBits(bitsDstIdxImmMSB[0], bitsDstIdxImmMSB[1], (value >> 5));
535 }
536
SetDstIdxImmByte(BinInst * mybin,uint32_t value)537 inline void SetDstIdxImmByte(BinInst *mybin, uint32_t value)
538 {
539 if (mybin->GetIs3Src())
540 return;
541
542 mybin->SetBits(bitsDstIdxImmByte[0], bitsDstIdxImmByte[1], value);
543 mybin->SetBits(bitsDstIdxImmMSB[0], bitsDstIdxImmMSB[1], (value >> 9));
544 }
545
SetDstArchRegFile(BinInst * mybin,uint32_t value)546 inline void SetDstArchRegFile(BinInst *mybin, uint32_t value)
547 {
548 if (mybin->GetIs3Src())
549 return;
550 else
551 mybin->SetBits(bitsDstArchRegFile_0, bitsDstArchRegFile_1, value);
552 }
553
SetDstArchRegNum(BinInst * mybin,uint32_t value)554 inline void SetDstArchRegNum(BinInst *mybin, uint32_t value)
555 {
556 if (mybin->GetIs3Src())
557 return;
558 else
559 mybin->SetBits(bitsDstArchRegNum_0, bitsDstArchRegNum_1, value);
560 }
561
SetDstArchSubRegNumOWord(BinInst * mybin,uint32_t value)562 inline void SetDstArchSubRegNumOWord(BinInst *mybin, uint32_t value)
563 {
564 if (mybin->GetIs3Src())
565 return;
566 else
567 mybin->SetBits(bitsDstArchSubRegNumOWord_0, bitsDstArchSubRegNumOWord_1, value);
568 }
569
SetDstArchSubRegNumWord(BinInst * mybin,uint32_t value)570 inline void SetDstArchSubRegNumWord(BinInst *mybin, uint32_t value)
571 {
572 if (mybin->GetIs3Src())
573 return;
574 else
575 mybin->SetBits(bitsDstArchSubRegNumWord_0, bitsDstArchSubRegNumWord_1, value);
576 }
577
SetDstArchSubRegNumByte(BinInst * mybin,uint32_t value)578 inline void SetDstArchSubRegNumByte(BinInst *mybin, uint32_t value)
579 {
580 if (mybin->GetIs3Src())
581 return;
582 else
583 mybin->SetBits(bitsDstArchSubRegNumByte_0, bitsDstArchSubRegNumByte_1, value);
584 }
585
SetOperandDstType(BinInst * mybin,G4_DstRegRegion * dst)586 inline void SetOperandDstType(BinInst *mybin, G4_DstRegRegion *dst)
587 {
588 G4_Type regType;
589
590 regType = dst->getType();
591
592 switch (regType)
593 {
594 case Type_UD:
595 case Type_D:
596 case Type_UW:
597 case Type_W:
598 case Type_UB:
599 case Type_B:
600 SetDstType(mybin, regType);
601 break;
602 case Type_DF:
603 SetDstType(mybin, DST_TYPE_DF);
604 break;
605 case Type_F:
606 SetDstType(mybin, DST_TYPE_F);
607 break;
608 case Type_UQ:
609 SetDstType(mybin, DST_TYPE_UQ);
610 break;
611 case Type_Q:
612 SetDstType(mybin, DST_TYPE_Q);
613 break;
614 case Type_HF:
615 SetDstType(mybin, DST_TYPE_HF);
616 break;
617 default:
618 MUST_BE_TRUE(false, "Encoding error: destination type unknown");
619 break;
620 }
621 }
622
623
EncodeDstRegFile(BinInst * mybin,G4_DstRegRegion * dst)624 inline void EncodeDstRegFile(BinInst *mybin, G4_DstRegRegion *dst)
625 {
626 SetDstRegFile(mybin, EncodingHelper::GetDstRegFile(dst));
627 if (EncodingHelper::GetDstRegFile(dst) == REG_FILE_A)
628 {
629 SetDstArchRegFile(mybin, EncodingHelper::GetDstArchRegType(dst));
630 }
631 }
632
633
EncodeDstAddrMode(BinInst * mybin,G4_DstRegRegion * dst)634 inline void EncodeDstAddrMode(BinInst *mybin, G4_DstRegRegion *dst)
635 {
636 SetDstAddrMode(mybin, EncodingHelper::GetDstAddrMode(dst));
637 }
638
SetDstHorzStride(BinInst * mybin,uint32_t value)639 inline void SetDstHorzStride(BinInst *mybin, uint32_t value)
640 {
641 if (mybin->GetIs3Src())
642 return;
643 else
644 mybin->SetBits(bitsDstHorzStride_0, bitsDstHorzStride_1, value);
645 }
646
EncodeDstHorzStride(G4_INST * inst,BinInst * mybin,G4_DstRegRegion * dst)647 inline void EncodeDstHorzStride(G4_INST *inst, BinInst *mybin, G4_DstRegRegion *dst)
648 {
649 switch (dst->getHorzStride())
650 {
651 case 1:
652 if (inst->isAligned16Inst())
653 {
654 SetDstHorzStride(mybin, HORZ_STRIDE_0);
655 }
656 else
657 {
658 SetDstHorzStride(mybin, HORZ_STRIDE_1);
659 }
660 break;
661 case 2: SetDstHorzStride(mybin, HORZ_STRIDE_2); break;
662 case 4: SetDstHorzStride(mybin, HORZ_STRIDE_4); break;
663 case UNDEFINED_SHORT: SetDstHorzStride(mybin, HORZ_STRIDE_1); break;
664 default: MUST_BE_TRUE(false, "wrong dst horizontal stride " << dst->getHorzStride()); break;
665 }
666 }
667
668
EncodeDstChanEn(G4_INST * inst,BinInst * mybin,G4_DstRegRegion * dst)669 inline void EncodeDstChanEn(G4_INST* inst, BinInst *mybin, G4_DstRegRegion *dst)
670 {
671
672 if (dst->isAccRegValid())
673 {
674 SetDstChanEn(mybin, dst->getAccRegSel());
675 return;
676 }
677
678 SetDstChanEn(mybin, dst->getWriteMask());
679
680 }
681
EncodeDstRegNum(G4_INST * inst,BinInst * mybin,G4_DstRegRegion * dst)682 inline void BinaryEncoding::EncodeDstRegNum(G4_INST* inst, BinInst *mybin, G4_DstRegRegion *dst)
683 {
684 if (EncodingHelper::GetDstRegFile(dst) != REG_FILE_A &&
685 EncodingHelper::GetDstAddrMode(dst) == ADDR_MODE_IMMED)
686 {
687 uint32_t byteAddress = dst->getLinearizedStart();
688
689 MUST_BE_TRUE(byteAddress < kernel.getNumRegTotal() * numEltPerGRF<Type_UB>(), "dst exceeds total GRF number");
690
691 if (inst->isAligned1Inst())
692 {
693 SetDstRegNumByte(mybin, byteAddress);
694 } else {
695 SetDstRegNumOWord(mybin, byteAddress/BYTES_PER_OWORD);
696 }
697 }
698 }
699
EncodeDstArchRegNum(G4_INST * inst,BinInst * mybin,G4_DstRegRegion * dst)700 inline void EncodeDstArchRegNum(G4_INST* inst, BinInst *mybin, G4_DstRegRegion *dst)
701 {
702 unsigned short RegNumValue = 0, RegSubNumValue = 0;
703 bool valid, subValid;
704 uint32_t regOffset;
705
706 if (EncodingHelper::GetDstRegFile(dst) == REG_FILE_A &&
707 EncodingHelper::GetDstAddrMode(dst) == ADDR_MODE_IMMED)
708 {
709 if (EncodingHelper::GetDstArchRegType(dst) != ARCH_REG_FILE_NULL)
710 {
711 RegNumValue = dst->ExRegNum(valid);
712 RegSubNumValue = dst->ExSubRegNum(subValid);
713
714 SetDstArchRegNum(mybin, RegNumValue);
715
716 unsigned short ElementSizeValue = EncodingHelper::GetElementSizeValue(dst);
717 regOffset = RegSubNumValue * ElementSizeValue;
718 if (inst->isAligned1Inst()) {
719 SetDstArchSubRegNumByte(mybin, regOffset);
720 } else {
721 SetDstArchSubRegNumOWord(mybin, regOffset/BYTES_PER_OWORD);
722 }
723 }
724 }
725 }
726
EncodeDstIndirectRegNum(G4_INST * inst,BinInst * mybin,G4_DstRegRegion * dst)727 inline void EncodeDstIndirectRegNum(G4_INST* inst, BinInst *mybin, G4_DstRegRegion *dst)
728 {
729 bool subValid;
730 unsigned short IndAddrRegSubNumValue = 0;
731 short IndAddrImmedValue = 0;
732
733 if (EncodingHelper::GetDstRegFile(dst)==REG_FILE_R ||
734 EncodingHelper::GetDstRegFile(dst)==REG_FILE_M)
735 {
736 if (EncodingHelper::GetDstAddrMode(dst) == ADDR_MODE_INDIR)
737 { // Indirect
738 IndAddrRegSubNumValue = dst->ExIndSubRegNum(subValid);
739 IndAddrImmedValue = dst->ExIndImmVal();
740
741 SetDstIdxRegNum(mybin, IndAddrRegSubNumValue);
742 /* Set the indirect address immediate value. */
743 if (inst->isAligned1Inst())
744 {
745 SetDstIdxImmByte(mybin, IndAddrImmedValue);
746 } else {
747 SetDstIdxImmOWord(mybin, IndAddrImmedValue / BYTES_PER_OWORD);
748 }
749 }
750 }
751 }
752
753
754 ///////////////////////////////////////////////////////////////////////////////
755 // Src0
756 ///////////////////////////////////////////////////////////////////////////////
757
758
SetSrc0RegFile(BinInst * mybin,uint32_t value)759 inline void SetSrc0RegFile(BinInst *mybin, uint32_t value)
760 {
761 if (mybin->GetIs3Src())
762 return;
763 else
764 mybin->SetBits(bitsSrcRegFile[0],bitsSrcRegFile[1],value);
765 }
766
SetSrc0Type(BinInst * mybin,uint32_t value)767 inline void SetSrc0Type(BinInst *mybin, uint32_t value)
768 {
769 if (mybin->GetIs3Src())
770 // handled by Set3SrcSrcType
771 return;
772 else
773 mybin->SetBits(bitsSrcType[0],bitsSrcType[1],value);
774 }
775
SetSrc0AddrMode(BinInst * mybin,uint32_t value)776 inline void SetSrc0AddrMode(BinInst *mybin, uint32_t value)
777 {
778 if (mybin->GetIs3Src())
779 return;
780 else
781 mybin->SetBits(bitsSrcAddrMode_0,bitsSrcAddrMode_1,value);
782 }
783
SetSrc0SrcMod(BinInst * mybin,uint32_t value)784 inline void SetSrc0SrcMod(BinInst *mybin, uint32_t value)
785 {
786 if (mybin->GetIs3Src())
787 mybin->SetBits(bits3SrcSrcMod[0], bits3SrcSrcMod[1], value);
788 else
789 mybin->SetBits(bitsSrcSrcMod_0, bitsSrcSrcMod_1,value);
790 }
791
SetSrc0RepCtrl(BinInst * mybin,uint32_t value)792 inline void SetSrc0RepCtrl(BinInst *mybin, uint32_t value)
793 {
794 if (mybin->GetIs3Src())
795 mybin->SetBits(bits3SrcRepCtrl_0, bits3SrcRepCtrl_1, value);
796 else
797 return;
798 }
799
SetSrc0Swizzle(BinInst * mybin,uint32_t value)800 inline void SetSrc0Swizzle(BinInst *mybin, uint32_t value)
801 {
802 if (mybin->GetIs3Src())
803 mybin->SetBits(bits3SrcSwizzle_0, bits3SrcSwizzle_1, value);
804 else
805 return;
806 }
807
SetSrc0RegNumOWord(BinInst * mybin,uint32_t value)808 inline void SetSrc0RegNumOWord(BinInst *mybin, uint32_t value)
809 {
810 if (mybin->GetIs3Src())
811 mybin->SetBits(bits3SrcSrcRegNumOWord_0,
812 bits3SrcSrcRegNumOWord_1, value);
813 else
814 mybin->SetBits(bitsSrcRegNumOWord_0,
815 bitsSrcRegNumOWord_1, value);
816 }
817
SetSrc0RegNumByte(BinInst * mybin,uint32_t value)818 inline void SetSrc0RegNumByte(BinInst *mybin, uint32_t value)
819 {
820 mybin->SetBits(bitsSrcRegNumByte_0,
821 bitsSrcRegNumByte_1, value);
822 }
823
SetSrc0ChanSel_0(BinInst * mybin,uint32_t value)824 inline void SetSrc0ChanSel_0(BinInst *mybin, uint32_t value)
825 {
826 if (mybin->GetIs3Src())
827 mybin->SetBits(bits3SrcChanSel_0_0,
828 bits3SrcChanSel_0_1, value);
829 else
830 mybin->SetBits(bitsSrcChanSel_0_0,
831 bitsSrcChanSel_0_1,value);
832 }
833
834
SetSrc0ChanSel_1(BinInst * mybin,uint32_t value)835 inline void SetSrc0ChanSel_1(BinInst *mybin, uint32_t value)
836 {
837 if (mybin->GetIs3Src())
838 mybin->SetBits(bits3SrcChanSel_1_0,
839 bits3SrcChanSel_1_1, value);
840 else
841 mybin->SetBits(bitsSrcChanSel_1_0,
842 bitsSrcChanSel_1_1,value);
843 }
844
SetSrc0ChanSel_2(BinInst * mybin,uint32_t value)845 inline void SetSrc0ChanSel_2(BinInst *mybin, uint32_t value)
846 {
847 if (mybin->GetIs3Src())
848 mybin->SetBits(bits3SrcChanSel_2_0,
849 bits3SrcChanSel_2_1, value);
850 else
851 mybin->SetBits(bitsSrcChanSel_2_0,
852 bitsSrcChanSel_2_1,value);
853 }
854
SetSrc0ChanSel_3(BinInst * mybin,uint32_t value)855 inline void SetSrc0ChanSel_3(BinInst *mybin, uint32_t value)
856 {
857 if (mybin->GetIs3Src())
858 mybin->SetBits(bits3SrcChanSel_3_0,
859 bits3SrcChanSel_3_1, value);
860 else
861 mybin->SetBits(bitsSrcChanSel_3_0,
862 bitsSrcChanSel_3_1, value);
863 }
864
SetSrc0VertStride(BinInst * mybin,uint32_t value)865 inline void SetSrc0VertStride(BinInst *mybin, uint32_t value)
866 {
867 if (mybin->GetIs3Src())
868 return;
869 else
870 mybin->SetBits(bitsSrcVertStride_0,bitsSrcVertStride_1,value);
871 }
872
SetSrc0Width(BinInst * mybin,uint32_t value)873 inline void SetSrc0Width(BinInst *mybin, uint32_t value)
874 {
875 if (mybin->GetIs3Src())
876 return;
877 else
878 mybin->SetBits(bitsSrcWidth_0,bitsSrcWidth_1,value);
879 }
880
SetSrc0HorzStride(BinInst * mybin,uint32_t value)881 inline void SetSrc0HorzStride(BinInst *mybin, uint32_t value)
882 {
883 if (mybin->GetIs3Src())
884 return;
885 else
886 mybin->SetBits(bitsSrcHorzStride_0,bitsSrcHorzStride_1,value);
887 }
888
889 /**
890 * Below three functions set src0's indirect register number
891 */
SetSrc0IdxRegNum(BinInst * mybin,uint32_t value)892 inline void SetSrc0IdxRegNum(BinInst *mybin, uint32_t value)
893 {
894 if (mybin->GetIs3Src())
895 return;
896 else
897 mybin->SetBits(bitsSrcIdxRegNum[0],bitsSrcIdxRegNum[1],value);
898 }
899
SetSrc0IdxImmOWord(BinInst * mybin,uint32_t value)900 inline void SetSrc0IdxImmOWord(BinInst *mybin, uint32_t value)
901 {
902 if (mybin->GetIs3Src())
903 return;
904 mybin->SetBits(bitsSrcIdxImmOWord[0], bitsSrcIdxImmOWord[1], value);
905 mybin->SetBits(bitsSrcIdxImmMSB[0], bitsSrcIdxImmMSB[1], (value >> 5));
906 }
907
SetSrc0IdxImmByte(BinInst * mybin,uint32_t value)908 inline void SetSrc0IdxImmByte(BinInst *mybin, uint32_t value)
909 {
910 if (mybin->GetIs3Src())
911 return;
912 mybin->SetBits(bitsSrcIdxImmByte[0], bitsSrcIdxImmByte[1], value);
913 mybin->SetBits(bitsSrcIdxImmMSB[0], bitsSrcIdxImmMSB[1], (value >> 9));
914
915 }
916
SetSrc0ArchRegFile(BinInst * mybin,uint32_t value)917 inline void SetSrc0ArchRegFile(BinInst *mybin, uint32_t value)
918 {
919 if (mybin->GetIs3Src())
920 return;
921 else
922 mybin->SetBits(bitsSrcArchRegFile_0,bitsSrcArchRegFile_1,value);
923 }
924
SetSrc0ArchRegNum(BinInst * mybin,uint32_t value)925 inline void SetSrc0ArchRegNum(BinInst *mybin, uint32_t value)
926 {
927 if (mybin->GetIs3Src())
928 return;
929 else
930 mybin->SetBits(bitsSrcArchRegNum_0,bitsSrcArchRegNum_1,value);
931 }
932
SetSrc0ArchSubRegNumOWord(BinInst * mybin,uint32_t value)933 inline void SetSrc0ArchSubRegNumOWord(BinInst *mybin, uint32_t value)
934 {
935 if (mybin->GetIs3Src())
936 return;
937 else
938 mybin->SetBits(bitsSrcArchSubRegNumOWord_0,bitsSrcArchSubRegNumOWord_1,value);
939 }
940
SetSrc0ArchSubRegNumWord(BinInst * mybin,uint32_t value)941 inline void SetSrc0ArchSubRegNumWord(BinInst *mybin, uint32_t value)
942 {
943 if (mybin->GetIs3Src())
944 return;
945 else
946 mybin->SetBits(bitsSrcArchSubRegNumWord_0,bitsSrcArchSubRegNumWord_1,value);
947 }
948
SetSrc0ArchSubRegNumByte(BinInst * mybin,uint32_t value)949 inline void SetSrc0ArchSubRegNumByte(BinInst *mybin, uint32_t value)
950 {
951 if (mybin->GetIs3Src())
952 return;
953 else
954 mybin->SetBits(bitsSrcArchSubRegNumByte_0,bitsSrcArchSubRegNumByte_1,value);
955 }
956
SetSrc0Imm32(BinInst * mybin,uint32_t value,G4_Operand * src)957 inline void SetSrc0Imm32(BinInst *mybin, uint32_t value, G4_Operand* src)
958 {
959 if (mybin->GetIs3Src())
960 return;
961 else
962 mybin->SetBits(bitsSrcImm32_0,bitsSrcImm32_1,value);
963 }
964
SetSrc0Imm64(BinInst * mybin,uint64_t value,G4_Operand * src)965 inline void SetSrc0Imm64(BinInst *mybin, uint64_t value, G4_Operand* src)
966 {
967 uint32_t low = value & 0xFFFFFFFF;
968 uint32_t high = value >> 32;
969 mybin->SetBits(bitsSrcImm64_2, bitsSrcImm64_3, low);
970 mybin->SetBits(bitsSrcImm64_0, bitsSrcImm64_1, high);
971 }
972
EncodeSrc0RegFile(BinInst * mybin,G4_Operand * src0)973 inline void EncodeSrc0RegFile(BinInst *mybin, G4_Operand *src0)
974 {
975 RegFile refFile = EncodingHelper::GetSrcRegFile(src0);
976 SetSrc0RegFile(mybin, refFile);
977 if (refFile == REG_FILE_A) {
978 SetSrc0ArchRegFile(mybin, EncodingHelper::GetSrcArchRegType(src0));
979 }
980 }
981
EncodeSrc0Type(G4_INST * inst,BinInst * mybin,G4_Operand * src0)982 inline void EncodeSrc0Type(G4_INST *inst, BinInst *mybin, G4_Operand *src0)
983 {
984 if (src0->isImm())
985 {
986 SetSrc0Type(mybin, GetOperandSrcImmType(src0));
987 } else {
988 //no need to force to F anymore.
989 //Also need actual type for IGA.
990 //So that through binary to binary path I can figure out
991 //whether I need to set bits 29/30 in msgDescriptor
992 //due to HW Bug on SKL.
993 if (inst->getPlatform() >= GENX_CHV)
994 {
995 SetSrc0Type(mybin, GetOperandSrcType(src0));
996 }
997 else
998 {
999 if (inst->isSend())
1000 SetSrc0Type(mybin, SRC_TYPE_F);
1001 else
1002 SetSrc0Type(mybin, GetOperandSrcType(src0));
1003 }
1004 }
1005 }
1006
SetSrc1Imm32(BinInst * mybin,uint32_t value,G4_Operand * src)1007 inline void SetSrc1Imm32(BinInst *mybin, uint32_t value, G4_Operand* src)
1008 {
1009 if (mybin->GetIs3Src())
1010 return;
1011 else
1012 mybin->SetBits(bitsSrcImm32_2,bitsSrcImm32_3,value);
1013 }
1014
EncodeSrcImmData(BinInst * mybin,G4_Operand * src)1015 inline void EncodeSrcImmData(BinInst *mybin, G4_Operand *src)
1016 {
1017 G4_Imm *isrc = (G4_Imm *)src->asImm();
1018 if (IS_WTYPE(src->getType()))
1019 {
1020 uint32_t val = (uint32_t) isrc->getInt();
1021 uint32_t data = (val << 16) | (val & 0xffff);
1022 SetSrc1Imm32(mybin, data, src);
1023 }
1024 else if (src->getType() == Type_F)
1025 {
1026 // Cannot use getFloat() as it will change sNAN to qNAN (bug1892)
1027 SetSrc1Imm32(mybin, (uint32_t)isrc->getImm(), src);
1028 }
1029 else if (src->getType() == Type_DF)
1030 {
1031 SetSrc0Imm64(mybin, (uint64_t)isrc->getImm(), src);
1032 }
1033 else if (src->getType() == Type_Q || src->getType() == Type_UQ)
1034 {
1035 int64_t val = isrc->getInt();
1036 SetSrc0Imm64(mybin, *(uint64_t*)&(val), src);
1037 }
1038 else {
1039 SetSrc1Imm32(mybin, (uint32_t)isrc->getInt(), src);
1040 }
1041 }
1042
EncodeSrc0AddrMode(BinInst * mybin,G4_Operand * src0)1043 inline void EncodeSrc0AddrMode(BinInst *mybin, G4_Operand *src0)
1044 {
1045 SetSrc0AddrMode(mybin, EncodingHelper::GetSrcAddrMode(src0));
1046 }
1047
EncodeSrc0ChanSelect(G4_INST * inst,BinInst * mybin,G4_Operand * src0,G4_SrcRegRegion * srcRegion)1048 inline void EncodeSrc0ChanSelect(G4_INST *inst,
1049 BinInst *mybin,
1050 G4_Operand *src0,
1051 G4_SrcRegRegion *srcRegion)
1052 {
1053 // encode acc2~acc9 if it is valid
1054 if (src0->isAccRegValid())
1055 {
1056 if (inst->opcode() == G4_madm ||
1057 (inst->isMath() && inst->asMathInst()->getMathCtrl() == MATH_INVM) ||
1058 (inst->isMath() && inst->asMathInst()->getMathCtrl() == MATH_RSQRTM))
1059 {
1060 uint32_t value = src0->getAccRegSel();
1061 SetSrc0ChanSel_0(mybin, value & 0x3);
1062 SetSrc0ChanSel_1(mybin, value >> 2 & 0x3);
1063 SetSrc0ChanSel_2(mybin, 0);
1064 SetSrc0ChanSel_3(mybin, 0);
1065 return;
1066 }
1067 ASSERT_USER(false, "acc2~acc7 were set on wrong instruction");
1068 }
1069
1070 const char *swizzle = srcRegion->getSwizzle();
1071 if (swizzle[0] != '\0' && swizzle[0] != 'r') {
1072 ChanSel ch0 = EncodingHelper::GetSrcChannelSelectValue(srcRegion, 0);
1073 ChanSel ch1 = EncodingHelper::GetSrcChannelSelectValue(srcRegion, 1);
1074 ChanSel ch2 = EncodingHelper::GetSrcChannelSelectValue(srcRegion, 2);
1075 ChanSel ch3 = EncodingHelper::GetSrcChannelSelectValue(srcRegion, 3);
1076 if (ch0 != CHAN_SEL_UNDEF)
1077 SetSrc0ChanSel_0(mybin, ch0);
1078 if (ch1 != CHAN_SEL_UNDEF)
1079 SetSrc0ChanSel_1(mybin, ch1);
1080 if (ch2 != CHAN_SEL_UNDEF)
1081 SetSrc0ChanSel_2(mybin, ch2);
1082 if (ch3 != CHAN_SEL_UNDEF)
1083 SetSrc0ChanSel_3(mybin, ch3);
1084 }
1085
1086 if (swizzle[0] == '\0')
1087 {
1088 if (inst->isAligned16Inst())
1089 {
1090 SetSrc0ChanSel_0(mybin, CHAN_SEL_X);
1091 SetSrc0ChanSel_1(mybin, CHAN_SEL_Y);
1092 SetSrc0ChanSel_2(mybin, CHAN_SEL_Z);
1093 SetSrc0ChanSel_3(mybin, CHAN_SEL_W);
1094 }
1095 }
1096 else if (inst->getNumSrc() == 3 && !inst->isSend())
1097 {
1098 if (swizzle[0] == 'r')
1099 {
1100 if (inst->isAligned16Inst())
1101 {
1102 SetSrc0ChanSel_0(mybin, CHAN_SEL_X);
1103 SetSrc0ChanSel_1(mybin, CHAN_SEL_Y);
1104 SetSrc0ChanSel_2(mybin, CHAN_SEL_Z);
1105 SetSrc0ChanSel_3(mybin, CHAN_SEL_W);
1106 }
1107 }
1108 }
1109 }
1110
EncodeSrc0RepCtrl(BinInst * mybin,G4_SrcRegRegion * srcRegion)1111 inline void EncodeSrc0RepCtrl(BinInst *mybin, G4_SrcRegRegion *srcRegion)
1112 {
1113 const char *swizzle = srcRegion->getSwizzle();
1114 if (swizzle[0] == 'r')
1115 SetSrc0RepCtrl(mybin, 0x1);
1116 else
1117 SetSrc0RepCtrl(mybin, 0x0);
1118 }
1119
EncodeSrc0Modifier(BinInst * mybin,G4_Operand * src0,G4_SrcRegRegion * srcRegion)1120 inline void EncodeSrc0Modifier(BinInst *mybin, G4_Operand *src0, G4_SrcRegRegion *srcRegion)
1121 {
1122 if (EncodingHelper::GetSrcRegFile(src0) != REG_FILE_M)
1123 {
1124 SetSrc0SrcMod(mybin, GetSrcMod(srcRegion));
1125 }
1126 };
1127
1128 static const uint32_t EXEC_CHANNELS[6] =
1129 {
1130 WIDTH_1,
1131 WIDTH_2,
1132 WIDTH_4,
1133 WIDTH_8,
1134 WIDTH_8,
1135 WIDTH_16
1136 };
1137
EncodeSrc0Width(G4_INST * inst,BinInst * mybin,const RegionDesc * rd,G4_Operand * src0)1138 inline bool EncodeSrc0Width(
1139 G4_INST *inst, BinInst *mybin, const RegionDesc *rd, G4_Operand *src0)
1140 {
1141 bool WidthValid = false;
1142 if (inst->isAligned16Inst()) return false;
1143
1144 if (rd)
1145 {
1146 if (rd->width != UNDEFINED_SHORT)
1147 {
1148 WidthValid = true;
1149 }
1150 switch (rd->width)
1151 {
1152 case 1: SetSrc0Width(mybin, WIDTH_1); break;
1153 case 2: SetSrc0Width(mybin, WIDTH_2); break;
1154 case 4: SetSrc0Width(mybin, WIDTH_4); break;
1155 case 8: SetSrc0Width(mybin, WIDTH_8); break;
1156 case 16: SetSrc0Width(mybin, WIDTH_16); break;
1157 case UNDEFINED_SHORT: break;
1158 default: MUST_BE_TRUE(false, "wrong width for src0!"); break;
1159 }
1160
1161 }
1162
1163 // apply default width
1164 if (!WidthValid)
1165 {
1166 if (EncodingHelper::isSrcSubRegNumValid(src0))
1167 {
1168 SetSrc0Width(mybin, WIDTH_1);
1169 }
1170 else
1171 {
1172 uint32_t execSize = GetEncodeExecSize(inst);
1173 MUST_BE_TRUE(execSize <= (uint32_t)ES_32_CHANNELS,
1174 "BinaryEncoding: Invalid exeuction channels");
1175 SetSrc0Width(mybin, EXEC_CHANNELS[execSize]);
1176 }
1177 }
1178
1179 return WidthValid;
1180 }
1181
1182 static const unsigned HORIZONTAL_STRIDE[6] =
1183 {
1184 (unsigned)HORZ_STRIDE_0,
1185 (unsigned)HORZ_STRIDE_1,
1186 (unsigned)HORZ_STRIDE_1,
1187 (unsigned)HORZ_STRIDE_1,
1188 (unsigned)HORZ_STRIDE_1,
1189 (unsigned)HORZ_STRIDE_1,
1190 };
1191
EncodeSrc0HorzStride(G4_INST * inst,BinInst * mybin,const RegionDesc * rd,G4_Operand * src0)1192 inline bool EncodeSrc0HorzStride(
1193 G4_INST *inst, BinInst *mybin, const RegionDesc *rd, G4_Operand *src0)
1194 {
1195 // For Align16 instruction (SIMD4), treat <HorzStride> as <VertStride>
1196 // For Align16 source operand disable HorzStride
1197 bool HorzStrideValid = false; // undef
1198 if (inst->isAligned16Inst()) return false;
1199
1200 if (rd) {
1201 if (rd->horzStride != UNDEFINED_SHORT)
1202 {
1203 HorzStrideValid = true;
1204 }
1205 switch (rd->horzStride)
1206 {
1207 case 0: SetSrc0HorzStride(mybin, HORZ_STRIDE_0); break;
1208 case 1: SetSrc0HorzStride(mybin, HORZ_STRIDE_1); break;
1209 case 2: SetSrc0HorzStride(mybin, HORZ_STRIDE_2); break;
1210 case 4: SetSrc0HorzStride(mybin, HORZ_STRIDE_4); break;
1211 case UNDEFINED_SHORT: break;
1212 default: MUST_BE_TRUE(false, "wrong horizontal stride for src0!"); break;
1213 }
1214 }
1215 // apply default horizontal stride
1216 if (!HorzStrideValid)
1217 {
1218 if (EncodingHelper::isSrcSubRegNumValid(src0))
1219 SetSrc0HorzStride(mybin, HORZ_STRIDE_0);
1220 else
1221 {
1222 uint32_t execSize = GetEncodeExecSize(inst);
1223 if (execSize <= (uint32_t)ES_32_CHANNELS)
1224 SetSrc0HorzStride(mybin, HORIZONTAL_STRIDE[execSize]);
1225 }
1226 } // end of valid horz stride
1227 return HorzStrideValid;
1228 }
1229
1230 static const unsigned VERTICAL_STRIDE[6] =
1231 {
1232 (unsigned)VERT_STRIDE_0,
1233 (unsigned)VERT_STRIDE_2,
1234 (unsigned)VERT_STRIDE_4,
1235 (unsigned)VERT_STRIDE_8,
1236 (unsigned)VERT_STRIDE_8,
1237 (unsigned)VERT_STRIDE_16
1238 };
1239
EncodeSrc0VertStride(G4_INST * inst,BinInst * mybin,const RegionDesc * rd,G4_Operand * src0,bool WidthValid,bool HorzStrideValid)1240 inline void EncodeSrc0VertStride(
1241 G4_INST *inst,
1242 BinInst *mybin,
1243 const RegionDesc *rd,
1244 G4_Operand *src0,
1245 bool WidthValid,
1246 bool HorzStrideValid)
1247 {
1248 bool VertStrideValid = false; // undef
1249 unsigned short VertStrideValue = UNDEFINED_SHORT, HorzStrideValue = 0;
1250
1251 if (rd)
1252 {
1253 VertStrideValue = rd->vertStride;
1254 HorzStrideValue = rd->horzStride;
1255 if (VertStrideValue != UNDEFINED_SHORT)
1256 {
1257 VertStrideValid = true;
1258 }
1259 switch (VertStrideValue)
1260 {
1261 case 0: SetSrc0VertStride(mybin, VERT_STRIDE_0); break;
1262 case 1: SetSrc0VertStride(mybin, VERT_STRIDE_1); break;
1263 case 2: SetSrc0VertStride(mybin, VERT_STRIDE_2); break;
1264 case 4: SetSrc0VertStride(mybin, VERT_STRIDE_4); break;
1265 case 8: SetSrc0VertStride(mybin, VERT_STRIDE_8); break;
1266 case 16: SetSrc0VertStride(mybin, VERT_STRIDE_16); break;
1267 case 32: SetSrc0VertStride(mybin, VERT_STRIDE_32); break;
1268 case UNDEFINED_SHORT: break;
1269 default: MUST_BE_TRUE(false, "wrong vertical stride for src0!"); break;
1270 }
1271 }
1272
1273 //apply default vertical stride below
1274 if (!WidthValid &&
1275 !HorzStrideValid &&
1276 !VertStrideValid &&
1277 src0)
1278 {
1279 VertStrideValid = true;
1280 if (EncodingHelper::isSrcSubRegNumValid(src0))
1281 {
1282 SetSrc0VertStride(mybin, VERT_STRIDE_0);
1283 }
1284 else
1285 {
1286 if (inst->isAligned1Inst())
1287 {
1288 uint32_t value = GetEncodeExecSize(inst);
1289 MUST_BE_TRUE(value <= (uint32_t)ES_32_CHANNELS,
1290 "BinaryEncoding: Invalid execution size");
1291 SetSrc0VertStride(mybin, VERTICAL_STRIDE[value]);
1292 }
1293 else
1294 {
1295 SetSrc0VertStride(mybin, VERT_STRIDE_4);
1296 }
1297 }
1298 }
1299
1300 if (VertStrideValid) { }
1301 else if (inst->isAligned16Inst())
1302 {
1303 if (HorzStrideValid && HorzStrideValue == 0)
1304 {
1305 SetSrc0HorzStride(mybin, HORZ_STRIDE_1);
1306 SetSrc0VertStride(mybin, VERT_STRIDE_0);
1307 }
1308 else if (HorzStrideValid && HorzStrideValue == 4)
1309 {
1310 SetSrc0HorzStride(mybin, HORZ_STRIDE_1);
1311 SetSrc0VertStride(mybin, VERT_STRIDE_4);
1312 }
1313 }
1314 else if (src0 != NULL && EncodingHelper::GetSrcAddrMode(src0) == ADDR_MODE_INDIR) { //indirect
1315 SetSrc0VertStride(mybin, VERT_STRIDE_ONE_DIMEN);
1316 }
1317
1318 }
1319
EncodeSrc0ArchRegNum(G4_INST * inst,BinInst * mybin,G4_SrcRegRegion * src0)1320 inline void EncodeSrc0ArchRegNum(G4_INST* inst, BinInst *mybin, G4_SrcRegRegion *src0)
1321 {
1322 unsigned short RegNumValue = 0, RegSubNumValue = 0;
1323 bool valid, subValid;
1324 uint32_t regOffset;
1325
1326 if (EncodingHelper::GetSrcRegFile(src0)==REG_FILE_A &&
1327 EncodingHelper::GetSrcAddrMode(src0)==ADDR_MODE_IMMED)
1328 {
1329 if (EncodingHelper::GetSrcArchRegType(src0) != ARCH_REG_FILE_NULL)
1330 {
1331 RegNumValue = src0->ExRegNum(valid);
1332 RegSubNumValue = src0->ExSubRegNum(subValid);
1333
1334 SetSrc0ArchRegNum(mybin, RegNumValue);
1335
1336 unsigned short ElementSizeValue = EncodingHelper::GetElementSizeValue(src0);
1337 regOffset = RegSubNumValue * ElementSizeValue;
1338 if (inst->isAligned1Inst()) {
1339 SetSrc0ArchSubRegNumByte(mybin, regOffset);
1340 } else {
1341 SetSrc0ArchSubRegNumOWord(mybin, regOffset/BYTES_PER_OWORD);
1342 }
1343 }
1344 }
1345
1346 }
1347
1348
EncodeSrc0RegNum(G4_INST * inst,BinInst * mybin,G4_Operand * src0)1349 inline void BinaryEncoding::EncodeSrc0RegNum(G4_INST* inst, BinInst *mybin, G4_Operand *src0)
1350 {
1351 if (EncodingHelper::GetSrcRegFile(src0) != REG_FILE_A &&
1352 EncodingHelper::GetSrcAddrMode(src0) == ADDR_MODE_IMMED)
1353 {
1354 bool repControl = EncodingHelper::GetRepControl(src0);
1355 uint32_t byteAddress = src0->getLinearizedStart();
1356 MUST_BE_TRUE(byteAddress < kernel.getNumRegTotal() * numEltPerGRF<Type_UB>(), "src0 exceeds total GRF number");
1357
1358 if (mybin->GetIs3Src())
1359 {
1360 // encode dwords
1361 mybin->SetBits(bits3SrcSrc0RegDWord_H, bits3SrcSrc0RegDWord_L, byteAddress >> 2);
1362 // encode word (for word type)
1363 mybin->SetBits(bits3SrcSrc0SubRegNumW_H, bits3SrcSrc0SubRegNumW_L, (byteAddress >> 1) & 0x1);
1364
1365 }
1366 else if (inst->isAligned1Inst() || repControl)
1367 {
1368 SetSrc0RegNumByte(mybin, byteAddress);
1369 }
1370 else
1371 {
1372 SetSrc0RegNumOWord(mybin, byteAddress/BYTES_PER_OWORD);
1373 }
1374 }
1375 }
1376
EncodeSrc0IndirectRegNum(G4_INST * inst,BinInst * mybin,G4_SrcRegRegion * src0)1377 inline void EncodeSrc0IndirectRegNum(G4_INST* inst, BinInst *mybin, G4_SrcRegRegion *src0)
1378 {
1379 bool subValid;
1380 unsigned short IndAddrRegSubNumValue = 0;
1381 short IndAddrImmedValue = 0;
1382
1383 if (EncodingHelper::GetSrcAddrMode(src0) == ADDR_MODE_INDIR)
1384 {
1385 if (!(EncodingHelper::GetSrcRegFile(src0)==REG_FILE_A &&
1386 EncodingHelper::GetSrcArchRegType(src0)==ARCH_REG_FILE_NULL))
1387 {
1388 IndAddrRegSubNumValue = src0->ExIndSubRegNum(subValid);
1389 IndAddrImmedValue = src0->ExIndImmVal();
1390
1391 SetSrc0IdxRegNum(mybin, IndAddrRegSubNumValue);
1392 /* Set the indirect address immediate value. */
1393 if (inst->isAligned1Inst())
1394 {
1395 SetSrc0IdxImmByte(mybin, IndAddrImmedValue);
1396 } else {
1397 SetSrc0IdxImmOWord(mybin, IndAddrImmedValue / BYTES_PER_OWORD);
1398 }
1399 }
1400 }
1401 }
1402
Set3SrcSrcType(BinInst * mybin,G4_INST * inst)1403 inline void Set3SrcSrcType(BinInst *mybin, G4_INST *inst)
1404 {
1405 if (inst->getSrc(0) == NULL) return;
1406 G4_Type type = inst->getSrc(0)->getType();
1407 ThreeSrcType sType = THREE_SRC_TYPE_F;
1408 switch (type)
1409 {
1410 case Type_F:
1411 sType = THREE_SRC_TYPE_F;
1412 break;
1413 case Type_D:
1414 sType = THREE_SRC_TYPE_D;
1415 break;
1416 case Type_UD:
1417 sType = THREE_SRC_TYPE_UD;
1418 break;
1419 case Type_DF:
1420 sType = THREE_SRC_TYPE_DF;
1421 break;
1422 case Type_HF:
1423 sType = THREE_SRC_TYPE_HF;
1424 break;
1425 default:
1426 break;
1427 }
1428 mybin->SetBits(bits3SrcSrcType[0], bits3SrcSrcType[1], (uint32_t)sType);
1429 if (inst->getPlatform() >= GENX_CHV)
1430 {
1431 if (inst->getSrc(1)->getType() == Type_HF)
1432 {
1433 mybin->SetBits(bits3SrcSrc1Type, bits3SrcSrc1Type, 1);
1434 }
1435 if (inst->getSrc(2)->getType() == Type_HF)
1436 {
1437 mybin->SetBits(bits3SrcSrc2Type, bits3SrcSrc2Type, 1);
1438 }
1439 }
1440 }
1441
Set3SrcDstType(BinInst * mybin,G4_Type type)1442 inline void Set3SrcDstType(BinInst *mybin, G4_Type type)
1443 {
1444 ThreeSrcType dType = THREE_SRC_TYPE_F;
1445 switch (type)
1446 {
1447 case Type_F:
1448 dType = THREE_SRC_TYPE_F;
1449 break;
1450 case Type_D:
1451 dType = THREE_SRC_TYPE_D;
1452 break;
1453 case Type_UD:
1454 dType = THREE_SRC_TYPE_UD;
1455 break;
1456 case Type_DF:
1457 dType = THREE_SRC_TYPE_DF;
1458 break;
1459 case Type_HF:
1460 dType = THREE_SRC_TYPE_HF;
1461 break;
1462 default:
1463 break;
1464 }
1465 mybin->SetBits(bits3SrcDstType[0], bits3SrcDstType[1], (uint32_t)dType);
1466 }
1467
EncodeOperandDst(G4_INST * inst)1468 BinaryEncoding::Status BinaryEncoding::EncodeOperandDst(G4_INST* inst)
1469 {
1470 Status myStatus = SUCCESS;
1471 BinInst *mybin = inst->getBinInst();
1472 G4_DstRegRegion *dst = inst->getDst();
1473
1474 if (inst->isSplitSend())
1475 {
1476 return EncodeSplitSendDst(inst);
1477 }
1478
1479 if (mybin->GetIs3Src())
1480 {
1481 MUST_BE_TRUE(EncodingHelper::GetDstRegFile(dst) == REG_FILE_R, "Dst for 3src instruction must be GRF");
1482 Set3SrcDstType(mybin, dst->getType());
1483 Set3SrcSrcType(mybin, inst);
1484 }
1485
1486 if (inst->opcode() == G4_wait) return SUCCESS;
1487 if (inst->opcode() == G4_jmpi)
1488 {
1489 SetDstRegFile(mybin, REG_FILE_A);
1490 SetDstArchRegFile(mybin, ARCH_REG_FILE_IP);
1491 //SetDstRegNumByte(mybin, 0);
1492 SetDstArchSubRegNumByte(mybin, 0);
1493 SetDstAddrMode(mybin, ADDR_MODE_IMMED);
1494 SetDstType(mybin, DST_TYPE_UD);
1495 SetDstHorzStride(mybin, 1);
1496
1497 if (inst->getSrc(0))
1498 {
1499 SetSrc0RegFile(mybin, REG_FILE_A);
1500 SetSrc0ArchRegFile(mybin, ARCH_REG_FILE_IP);
1501 SetSrc0Type(mybin, DST_TYPE_UD);
1502 SetSrc0AddrMode(mybin, ADDR_MODE_IMMED);
1503 //SetSrc0RegNumByte(mybin, 0);
1504 SetSrc0ArchSubRegNumByte(mybin, 0);
1505 if (!(inst->getSrc(0)->isLabel()))
1506 {
1507 SetSrc0Width(mybin, WIDTH_1);
1508 SetDstHorzStride(mybin, 1);
1509 }
1510 else
1511 {
1512 SetSrc0Width(mybin, WIDTH_1);
1513 SetSrc0VertStride(mybin, VERT_STRIDE_0);
1514 SetSrc0HorzStride(mybin, HORZ_STRIDE_0);
1515 SetSrc0SrcMod(mybin, SRC_MOD_NONE);
1516 }
1517 }
1518 }
1519
1520 if (dst == NULL)
1521 {
1522 SetDstHorzStride(mybin, HORZ_STRIDE_1);
1523 return FAILURE;
1524 }
1525
1526 SetOperandDstType(mybin, dst);
1527 EncodeDstRegFile(mybin, dst);
1528 EncodeDstAddrMode(mybin, dst);
1529 // Note: dst doesn't have the vertical stride and width
1530 EncodeDstHorzStride(inst, mybin, dst);
1531 EncodeDstChanEn(inst, mybin, dst);
1532 EncodeDstRegNum(inst, mybin, dst);
1533 EncodeDstIndirectRegNum(inst, mybin, dst);
1534 EncodeDstArchRegNum(inst, mybin, dst);
1535 return myStatus;
1536 }
1537
1538
EncodeOperandSrc0(G4_INST * inst)1539 inline BinaryEncoding::Status BinaryEncoding::EncodeOperandSrc0(G4_INST* inst)
1540 {
1541 Status myStatus = SUCCESS;
1542 if (inst->isLabel() ||
1543 inst->isCall())
1544 return myStatus;
1545
1546 if (inst->isSplitSend())
1547 {
1548 return EncodeSplitSendSrc0(inst);
1549 }
1550
1551 BinInst *mybin = inst->getBinInst();
1552 G4_Operand *src0 = inst->getSrc(0);
1553
1554 if (src0 == NULL ||src0->isLabel()) return FAILURE;
1555 if (inst->opcode() == G4_jmpi && src0->isSrcRegRegion())
1556 {
1557 // will treat this src0 as src1 in EncodeOperandSrc1
1558 return SUCCESS;
1559 }
1560
1561 EncodeSrc0Type(inst, mybin, src0);
1562 EncodeSrc0RegFile(mybin, src0);
1563 if (src0->isImm())
1564 {
1565 if (inst->opcode() != G4_mov && src0->getTypeSize() == 8)
1566 {
1567 MUST_BE_TRUE(false, "only Mov is allowed for 64bit immediate");
1568 }
1569 EncodeSrcImmData(mybin, src0);
1570 }
1571 else
1572 {
1573 G4_SrcRegRegion* src0Region = src0->asSrcRegRegion();
1574 EncodeSrc0AddrMode(mybin, src0);
1575 EncodeSrc0ChanSelect(inst, mybin, src0, src0Region);
1576 EncodeSrc0RepCtrl(mybin, src0Region);
1577 EncodeSrc0Modifier(mybin, src0, src0Region);
1578
1579 const RegionDesc *rd = src0Region->getRegion();
1580 bool WidthValid = EncodeSrc0Width(inst, mybin, rd, src0);
1581 bool HorzStrideValid = EncodeSrc0HorzStride(inst, mybin, rd, src0);
1582 EncodeSrc0VertStride(inst, mybin, rd, src0, WidthValid, HorzStrideValid);
1583
1584 EncodeSrc0ArchRegNum(inst, mybin, src0Region);
1585 EncodeSrc0RegNum(inst, mybin, src0);
1586 EncodeSrc0IndirectRegNum(inst, mybin, src0Region);
1587 }
1588 return myStatus;
1589 }
1590
1591 ///////////////////////////////////////////////////////////////////////////////
1592 // Src1
1593 ///////////////////////////////////////////////////////////////////////////////
1594
SetSrc1RegFile(BinInst * mybin,uint32_t value)1595 inline void SetSrc1RegFile(BinInst *mybin, uint32_t value)
1596 {
1597 if (mybin->GetIs3Src())
1598 return;
1599 else
1600 mybin->SetBits(bitsSrcRegFile[2],bitsSrcRegFile[3],value);
1601 }
1602
SetSrc1Type(BinInst * mybin,uint32_t value)1603 inline void SetSrc1Type(BinInst *mybin, uint32_t value)
1604 {
1605 if (mybin->GetIs3Src())
1606 // handled by Set3SrcSrcType
1607 return;
1608 else
1609 mybin->SetBits(bitsSrcType[2],bitsSrcType[3],value);
1610 }
1611
SetSrc1AddrMode(BinInst * mybin,uint32_t value)1612 inline void SetSrc1AddrMode(BinInst *mybin, uint32_t value)
1613 {
1614 if (mybin->GetIs3Src())
1615 return;
1616 else
1617 mybin->SetBits(bitsSrcAddrMode_2,bitsSrcAddrMode_3,value);
1618 }
SetSrc1SrcMod(BinInst * mybin,uint32_t value)1619 inline void SetSrc1SrcMod(BinInst *mybin, uint32_t value)
1620 {
1621 if (mybin->GetIs3Src())
1622 mybin->SetBits(bits3SrcSrcMod[2],
1623 bits3SrcSrcMod[3],value);
1624 else
1625 mybin->SetBits(bitsSrcSrcMod_2,
1626 bitsSrcSrcMod_3,value);
1627 }
1628
SetSrc1RepCtrl(BinInst * mybin,uint32_t value)1629 inline void SetSrc1RepCtrl(BinInst *mybin, uint32_t value)
1630 {
1631 if (mybin->GetIs3Src())
1632 mybin->SetBits(bits3SrcRepCtrl_2, bits3SrcRepCtrl_3, value);
1633 else
1634 return;
1635 }
1636
SetSrc1Swizzle(BinInst * mybin,uint32_t value)1637 inline void SetSrc1Swizzle(BinInst *mybin, uint32_t value)
1638 {
1639 if (mybin->GetIs3Src())
1640 mybin->SetBits(bits3SrcSwizzle_2, bits3SrcSwizzle_3, value);
1641 else
1642 return;
1643 }
1644
SetSrc1RegNumOWord(BinInst * mybin,uint32_t value)1645 inline void SetSrc1RegNumOWord(BinInst *mybin, uint32_t value)
1646 {
1647 if (mybin->GetIs3Src())
1648 mybin->SetBits(bits3SrcSrcRegNumOWord_2,
1649 bits3SrcSrcRegNumOWord_3, value);
1650 else
1651 mybin->SetBits(bitsSrcRegNumOWord_2,
1652 bitsSrcRegNumOWord_3, value);
1653 }
1654
SetSrc1RegNumByte(BinInst * mybin,uint32_t value)1655 inline void SetSrc1RegNumByte(BinInst *mybin, uint32_t value)
1656 {
1657 mybin->SetBits(bitsSrcRegNumByte_2,bitsSrcRegNumByte_3,value);
1658 }
1659
SetSrc1ChanSel_0(BinInst * mybin,uint32_t value)1660 inline void SetSrc1ChanSel_0(BinInst *mybin, uint32_t value)
1661 {
1662 if (mybin->GetIs3Src())
1663 mybin->SetBits(bits3SrcChanSel_0_2, bits3SrcChanSel_0_3, value);
1664 else
1665 mybin->SetBits(bitsSrcChanSel_0_2,bitsSrcChanSel_0_3,value);
1666 }
1667
SetSrc1ChanSel_1(BinInst * mybin,uint32_t value)1668 void SetSrc1ChanSel_1(BinInst *mybin, uint32_t value)
1669 {
1670 if (mybin->GetIs3Src())
1671 mybin->SetBits(bits3SrcChanSel_1_2, bits3SrcChanSel_1_3, value);
1672 else
1673 mybin->SetBits(bitsSrcChanSel_1_2,bitsSrcChanSel_1_3,value);
1674 }
1675
SetSrc1ChanSel_2(BinInst * mybin,uint32_t value)1676 inline void SetSrc1ChanSel_2(BinInst *mybin, uint32_t value)
1677 {
1678 if (mybin->GetIs3Src())
1679 mybin->SetBits(bits3SrcChanSel_2_2, bits3SrcChanSel_2_3, value);
1680 else
1681 mybin->SetBits(bitsSrcChanSel_2_2,bitsSrcChanSel_2_3,value);
1682 }
1683
SetSrc1ChanSel_3(BinInst * mybin,uint32_t value)1684 inline void SetSrc1ChanSel_3(BinInst *mybin, uint32_t value)
1685 {
1686 if (mybin->GetIs3Src())
1687 mybin->SetBits(bits3SrcChanSel_3_2, bits3SrcChanSel_3_3, value);
1688 else
1689 mybin->SetBits(bitsSrcChanSel_3_2,bitsSrcChanSel_3_3,value);
1690 }
1691
SetSrc1VertStride(BinInst * mybin,uint32_t value)1692 inline void SetSrc1VertStride(BinInst *mybin, uint32_t value)
1693 {
1694 if (mybin->GetIs3Src())
1695 return;
1696 else
1697 mybin->SetBits(bitsSrcVertStride_2,bitsSrcVertStride_3,value);
1698 }
1699
SetSrc1Width(BinInst * mybin,uint32_t value)1700 inline void SetSrc1Width(BinInst *mybin, uint32_t value)
1701 {
1702 if (mybin->GetIs3Src())
1703 return;
1704 else
1705 mybin->SetBits(bitsSrcWidth_2,bitsSrcWidth_3,value);
1706 }
1707
SetSrc1HorzStride(BinInst * mybin,uint32_t value)1708 inline void SetSrc1HorzStride(BinInst *mybin, uint32_t value)
1709 {
1710 if (mybin->GetIs3Src())
1711 return;
1712 else
1713 mybin->SetBits(bitsSrcHorzStride_2,bitsSrcHorzStride_3,value);
1714 }
1715
1716 /**
1717 * Below three functions set src1's indirect register number
1718 */
SetSrc1IdxRegNum(BinInst * mybin,uint32_t value)1719 inline void SetSrc1IdxRegNum(BinInst *mybin, uint32_t value)
1720 {
1721 if (mybin->GetIs3Src())
1722 return;
1723 else
1724 mybin->SetBits(bitsSrcIdxRegNum[2],bitsSrcIdxRegNum[3],value);
1725 }
1726
SetSrc1IdxImmOWord(BinInst * mybin,uint32_t value)1727 inline void SetSrc1IdxImmOWord(BinInst *mybin, uint32_t value)
1728 {
1729 if (mybin->GetIs3Src())
1730 return;
1731 mybin->SetBits(bitsSrcIdxImmOWord[2], bitsSrcIdxImmOWord[3], value);
1732 mybin->SetBits(bitsSrcIdxImmMSB[2], bitsSrcIdxImmMSB[3], (value >> 5));
1733 }
1734
SetSrc1IdxImmByte(BinInst * mybin,uint32_t value)1735 inline void SetSrc1IdxImmByte(BinInst *mybin, uint32_t value)
1736 {
1737 if (mybin->GetIs3Src())
1738 return;
1739 mybin->SetBits(bitsSrcIdxImmByte[2], bitsSrcIdxImmByte[3], value);
1740 mybin->SetBits(bitsSrcIdxImmMSB[2], bitsSrcIdxImmMSB[3], (value >> 9));
1741 }
1742
SetSrc1ArchRegFile(BinInst * mybin,uint32_t value)1743 inline void SetSrc1ArchRegFile(BinInst *mybin, uint32_t value)
1744 {
1745 if (mybin->GetIs3Src())
1746 return;
1747 else
1748 mybin->SetBits(bitsSrcArchRegFile_2,bitsSrcArchRegFile_3,value);
1749 }
1750
SetSrc1ArchRegNum(BinInst * mybin,uint32_t value)1751 inline void SetSrc1ArchRegNum(BinInst *mybin, uint32_t value)
1752 {
1753 if (mybin->GetIs3Src())
1754 return;
1755 else
1756 mybin->SetBits(bitsSrcArchRegNum_2,bitsSrcArchRegNum_3,value);
1757 }
1758
SetSrc1ArchSubRegNumOWord(BinInst * mybin,uint32_t value)1759 inline void SetSrc1ArchSubRegNumOWord(BinInst *mybin, uint32_t value)
1760 {
1761 if (mybin->GetIs3Src())
1762 return;
1763 else
1764 mybin->SetBits(bitsSrcArchSubRegNumOWord_2,bitsSrcArchSubRegNumOWord_3,value);
1765 }
1766
SetSrc1ArchSubRegNumWord(BinInst * mybin,uint32_t value)1767 inline void SetSrc1ArchSubRegNumWord(BinInst *mybin, uint32_t value)
1768 {
1769 if (mybin->GetIs3Src())
1770 return;
1771 else
1772 mybin->SetBits(bitsSrcArchSubRegNumWord_2,bitsSrcArchSubRegNumWord_3,value);
1773 }
1774
SetSrc1ArchSubRegNumByte(BinInst * mybin,uint32_t value)1775 inline void SetSrc1ArchSubRegNumByte(BinInst *mybin, uint32_t value)
1776 {
1777 if (mybin->GetIs3Src())
1778 return;
1779 else
1780 mybin->SetBits(bitsSrcArchSubRegNumByte_2,bitsSrcArchSubRegNumByte_3,value);
1781 }
1782
EncodeSrc1RegFile(BinInst * mybin,G4_Operand * src1)1783 inline void EncodeSrc1RegFile(BinInst *mybin, G4_Operand *src1)
1784 {
1785 RegFile regFile = EncodingHelper::GetSrcRegFile(src1);
1786 SetSrc1RegFile(mybin, regFile);
1787 if (regFile == REG_FILE_A)
1788 {
1789 SetSrc1ArchRegFile(mybin, EncodingHelper::GetSrcArchRegType(src1));
1790 }
1791 }
1792
EncodeSrc1Type(BinInst * mybin,G4_Operand * src1)1793 inline void EncodeSrc1Type(BinInst *mybin, G4_Operand *src1)
1794 {
1795 if (src1->isImm())
1796 {
1797 SetSrc1Type(mybin, GetOperandSrcImmType(src1));
1798 } else {
1799 SetSrc1Type(mybin, GetOperandSrcType(src1));
1800 }
1801 }
1802
EncodeSrc1AddrMode(BinInst * mybin,G4_Operand * src1)1803 inline void EncodeSrc1AddrMode(BinInst *mybin, G4_Operand *src1)
1804 {
1805 SetSrc1AddrMode(mybin, EncodingHelper::GetSrcAddrMode(src1));
1806 }
1807
EncodeSrc1ChanSelect(G4_INST * inst,BinInst * mybin,G4_SrcRegRegion * srcRegion)1808 inline void EncodeSrc1ChanSelect(G4_INST *inst, BinInst *mybin, G4_SrcRegRegion *srcRegion)
1809 {
1810 // encode acc2~acc9 if it is valid
1811 if (srcRegion->isAccRegValid())
1812 {
1813 if (inst->opcode() == G4_madm ||
1814 (inst->isMath() && inst->asMathInst()->getMathCtrl() == MATH_INVM) ||
1815 (inst->isMath() && inst->asMathInst()->getMathCtrl() == MATH_RSQRTM))
1816 {
1817 uint32_t value = srcRegion->getAccRegSel();
1818 SetSrc1ChanSel_0(mybin, value & 0x3);
1819 SetSrc1ChanSel_1(mybin, value >> 2 & 0x3);
1820 SetSrc1ChanSel_2(mybin, 0);
1821 SetSrc1ChanSel_3(mybin, 0);
1822 return;
1823 }
1824 ASSERT_USER(false, "acc2~acc7 were set on wrong instruction");
1825 }
1826
1827 const char *swizzle = srcRegion->getSwizzle();
1828 if (swizzle[0] != '\0' && swizzle[0] != 'r') {
1829 ChanSel ch0 = EncodingHelper::GetSrcChannelSelectValue(srcRegion, 0);
1830 ChanSel ch1 = EncodingHelper::GetSrcChannelSelectValue(srcRegion, 1);
1831 ChanSel ch2 = EncodingHelper::GetSrcChannelSelectValue(srcRegion, 2);
1832 ChanSel ch3 = EncodingHelper::GetSrcChannelSelectValue(srcRegion, 3);
1833 if (ch0 != CHAN_SEL_UNDEF)
1834 SetSrc1ChanSel_0(mybin, ch0);
1835 if (ch1 != CHAN_SEL_UNDEF)
1836 SetSrc1ChanSel_1(mybin, ch1);
1837 if (ch2 != CHAN_SEL_UNDEF)
1838 SetSrc1ChanSel_2(mybin, ch2);
1839 if (ch3 != CHAN_SEL_UNDEF)
1840 SetSrc1ChanSel_3(mybin, ch3);
1841 }
1842
1843 if (swizzle[0] == '\0')
1844 {
1845 if (inst->isAligned16Inst())
1846 {
1847 SetSrc1ChanSel_0(mybin, CHAN_SEL_X);
1848 SetSrc1ChanSel_1(mybin, CHAN_SEL_Y);
1849 SetSrc1ChanSel_2(mybin, CHAN_SEL_Z);
1850 SetSrc1ChanSel_3(mybin, CHAN_SEL_W);
1851 }
1852 }
1853 else if (inst->getNumSrc() == 3 && !inst->isSend())
1854 {
1855 if (swizzle[0] == 'r')
1856 {
1857 if (inst->isAligned16Inst())
1858 {
1859 SetSrc1ChanSel_0(mybin, CHAN_SEL_X);
1860 SetSrc1ChanSel_1(mybin, CHAN_SEL_Y);
1861 SetSrc1ChanSel_2(mybin, CHAN_SEL_Z);
1862 SetSrc1ChanSel_3(mybin, CHAN_SEL_W);
1863 }
1864 }
1865 }
1866 }
1867
EncodeSrc1RepCtrl(BinInst * mybin,G4_SrcRegRegion * srcRegion)1868 inline void EncodeSrc1RepCtrl(BinInst *mybin, G4_SrcRegRegion *srcRegion)
1869 {
1870 const char *swizzle = srcRegion->getSwizzle();
1871 if (swizzle[0] == 'r')
1872 SetSrc1RepCtrl(mybin, 0x1);
1873 else
1874 SetSrc1RepCtrl(mybin, 0x0);
1875 }
1876
EncodeSrc1Modifier(BinInst * mybin,G4_SrcRegRegion * srcRegion)1877 inline void EncodeSrc1Modifier(BinInst *mybin, G4_SrcRegRegion *srcRegion)
1878 {
1879 SetSrc1SrcMod(mybin, GetSrcMod(srcRegion));
1880 }
1881
EncodeSrc1Width(G4_INST * inst,BinInst * mybin,const RegionDesc * rd,G4_Operand * src1)1882 inline bool EncodeSrc1Width(
1883 G4_INST *inst, BinInst *mybin, const RegionDesc *rd, G4_Operand *src1)
1884 {
1885 bool WidthValid = false;
1886 if (inst->isAligned16Inst()) return false;
1887
1888 if (rd)
1889 {
1890 if (rd->width != UNDEFINED_SHORT)
1891 {
1892 WidthValid = true;
1893 }
1894 switch (rd->width)
1895 {
1896 case 1: SetSrc1Width(mybin, WIDTH_1); break;
1897 case 2: SetSrc1Width(mybin, WIDTH_2); break;
1898 case 4: SetSrc1Width(mybin, WIDTH_4); break;
1899 case 8: SetSrc1Width(mybin, WIDTH_8); break;
1900 case 16: SetSrc1Width(mybin, WIDTH_16); break;
1901 case UNDEFINED_SHORT:break;
1902 default: MUST_BE_TRUE(false, "wrong width for src1!"); break;
1903 }
1904 }
1905
1906 // apply default width
1907 if (!WidthValid)
1908 {
1909 if (EncodingHelper::isSrcSubRegNumValid(src1))
1910 {
1911 SetSrc1Width(mybin, WIDTH_1);
1912 }
1913 else
1914 {
1915 uint32_t width = GetEncodeExecSize(inst);
1916 if (width <= (uint32_t)ES_32_CHANNELS)
1917 {
1918 SetSrc1Width(mybin, EXEC_CHANNELS[width]);
1919 }
1920 }
1921 }
1922
1923 return WidthValid;
1924 }
1925
EncodeSrc1HorzStride(G4_INST * inst,BinInst * mybin,const RegionDesc * rd,G4_Operand * src1)1926 inline bool EncodeSrc1HorzStride(
1927 G4_INST *inst, BinInst *mybin, const RegionDesc *rd, G4_Operand *src1)
1928 {
1929 // For Align16 instruction (SIMD4), treat <HorzStride> as <VertStride>
1930 // For Align16 source operand disable HorzStride
1931 bool HorzStrideValid = false;
1932 if (inst->isAligned16Inst()) return false;
1933
1934 if (rd)
1935 {
1936 if (rd->horzStride != UNDEFINED_SHORT)
1937 {
1938 HorzStrideValid = true;
1939 }
1940 switch (rd->horzStride)
1941 {
1942 case 0: SetSrc1HorzStride(mybin, HORZ_STRIDE_0); break;
1943 case 1: SetSrc1HorzStride(mybin, HORZ_STRIDE_1); break;
1944 case 2: SetSrc1HorzStride(mybin, HORZ_STRIDE_2); break;
1945 case 4: SetSrc1HorzStride(mybin, HORZ_STRIDE_4); break;
1946 case UNDEFINED_SHORT: break;
1947 default: MUST_BE_TRUE(false, "wrong horizontal stride for src1!"); break;
1948 }
1949
1950 }
1951 // apply default horizontal stride
1952 if (!HorzStrideValid)
1953 {
1954 if (EncodingHelper::isSrcSubRegNumValid(src1))
1955 SetSrc1HorzStride(mybin, HORZ_STRIDE_0);
1956 else
1957 {
1958 uint32_t exeSize = GetEncodeExecSize(inst);
1959 MUST_BE_TRUE(exeSize <= (uint32_t)ES_32_CHANNELS,
1960 "Binary Encoding: Invalid execution size");
1961 {
1962 SetSrc1HorzStride(mybin, HORIZONTAL_STRIDE[exeSize]);
1963 }
1964 }
1965 }
1966
1967 return HorzStrideValid;
1968 }
1969
EncodeSrc1VertStride(G4_INST * inst,BinInst * mybin,const RegionDesc * rd,G4_Operand * src1,bool WidthValid,bool HorzStrideValid)1970 inline void EncodeSrc1VertStride(G4_INST *inst,
1971 BinInst *mybin,
1972 const RegionDesc *rd,
1973 G4_Operand *src1,
1974 bool WidthValid,
1975 bool HorzStrideValid)
1976 {
1977 bool VertStrideValid = false;
1978 unsigned short VertStrideValue= UNDEFINED_SHORT;
1979 unsigned short HorzStrideValue= UNDEFINED_SHORT;
1980
1981 if (rd) {
1982 VertStrideValue = rd->vertStride;
1983 HorzStrideValue = rd->horzStride;
1984 if (VertStrideValue != UNDEFINED_SHORT)
1985 {
1986 VertStrideValid = true;
1987 }
1988 switch (VertStrideValue)
1989 {
1990 case 0: SetSrc1VertStride(mybin, VERT_STRIDE_0); break;
1991 case 1: SetSrc1VertStride(mybin, VERT_STRIDE_1); break;
1992 case 2: SetSrc1VertStride(mybin, VERT_STRIDE_2); break;
1993 case 4: SetSrc1VertStride(mybin, VERT_STRIDE_4); break;
1994 case 8: SetSrc1VertStride(mybin, VERT_STRIDE_8); break;
1995 case 16: SetSrc1VertStride(mybin, VERT_STRIDE_16); break;
1996 case 32: SetSrc1VertStride(mybin, VERT_STRIDE_32); break;
1997 case UNDEFINED_SHORT: break;
1998 default: MUST_BE_TRUE(false, "wrong verical stride for src1!"); break;
1999 }
2000
2001 }
2002
2003 //apply default vertical stride below
2004 if (!WidthValid &&
2005 !HorzStrideValid &&
2006 !VertStrideValid &&
2007 src1)
2008 {
2009 VertStrideValid = true;
2010 if (EncodingHelper::isSrcSubRegNumValid(src1))
2011 {
2012 SetSrc1VertStride(mybin, VERT_STRIDE_0);
2013 }
2014 else
2015 {
2016 if (inst->isAligned1Inst())
2017 {
2018 uint32_t execSize = GetEncodeExecSize(inst);
2019 MUST_BE_TRUE(execSize <= (uint32_t)ES_32_CHANNELS,
2020 "BinaryEncoding: Invalid execution size");
2021 SetSrc1VertStride(mybin, VERTICAL_STRIDE[execSize]);
2022 }
2023 else
2024 {
2025 SetSrc1VertStride(mybin, VERT_STRIDE_4);
2026 }
2027 } // fi
2028 } // fi
2029
2030 if (VertStrideValid) {}
2031 else if (inst->isAligned16Inst())
2032 {
2033 if (HorzStrideValid == 1 &&
2034 HorzStrideValue == 4)
2035 {
2036 SetSrc1HorzStride(mybin, HORZ_STRIDE_1);
2037 SetSrc1VertStride(mybin, VERT_STRIDE_4);
2038 }
2039 }
2040 else if (src1 != NULL && EncodingHelper::GetSrcAddrMode(src1) == ADDR_MODE_INDIR)
2041 { //indirect
2042 SetSrc1VertStride(mybin, VERT_STRIDE_ONE_DIMEN);
2043 }
2044 }
2045
EncodeSrc1RegNum(G4_INST * inst,BinInst * mybin,G4_Operand * src1)2046 inline void BinaryEncoding::EncodeSrc1RegNum(G4_INST *inst, BinInst *mybin, G4_Operand *src1)
2047 {
2048 if (EncodingHelper::GetSrcRegFile(src1) != REG_FILE_A &&
2049 EncodingHelper::GetSrcAddrMode(src1)==ADDR_MODE_IMMED)
2050 {
2051 bool repControl = EncodingHelper::GetRepControl(src1);
2052 uint32_t byteAddress = src1->getLinearizedStart();
2053 MUST_BE_TRUE(byteAddress < kernel.getNumRegTotal() * numEltPerGRF<Type_UB>(), "src1 exceeds total GRF number");
2054
2055 if (mybin->GetIs3Src())
2056 {
2057 // src1 subregnum crosses dword boundary, which SetBits can't handle, so we have to break it into two (sigh)
2058 mybin->SetBits(bits3SrcSrc1RegDWord1_H, bits3SrcSrc1RegDWord1_L, byteAddress >> 4);
2059 mybin->SetBits(bits3SrcSrc1RegDWord2_H, bits3SrcSrc1RegDWord2_L, (byteAddress >> 2) & 0x3);
2060 mybin->SetBits(bits3SrcSrc1SubRegNumW_H, bits3SrcSrc1SubRegNumW_L, (byteAddress >> 1) & 0x1);
2061 }
2062 else if (inst->isAligned1Inst() || repControl)
2063 {
2064 SetSrc1RegNumByte(mybin, byteAddress);
2065 }
2066 else
2067 {
2068 SetSrc1RegNumOWord(mybin, byteAddress/BYTES_PER_OWORD);
2069 }
2070 }
2071 }
2072
EncodeSrc1ArchRegNum(G4_INST * inst,BinInst * mybin,G4_SrcRegRegion * src1)2073 inline void EncodeSrc1ArchRegNum(G4_INST *inst, BinInst *mybin, G4_SrcRegRegion *src1)
2074 {
2075 unsigned short RegNumValue = 0, RegSubNumValue = 0;
2076 bool valid, subValid;
2077 uint32_t regOffset;
2078
2079 if (EncodingHelper::GetSrcRegFile(src1)==REG_FILE_A &&
2080 EncodingHelper::GetSrcAddrMode(src1) == ADDR_MODE_IMMED)
2081 {
2082 if (EncodingHelper::GetSrcArchRegType(src1) != ARCH_REG_FILE_NULL)
2083 {
2084 RegNumValue = src1->ExRegNum(valid);
2085 RegSubNumValue = src1->ExSubRegNum(subValid);
2086
2087 SetSrc1ArchRegNum(mybin, RegNumValue);
2088
2089 unsigned short ElementSizeValue = EncodingHelper::GetElementSizeValue(src1);
2090 regOffset = RegSubNumValue * ElementSizeValue;
2091 if (inst->isAligned1Inst())
2092 {
2093 SetSrc1ArchSubRegNumByte(mybin, regOffset);
2094 } else {
2095 SetSrc1ArchSubRegNumOWord(mybin, regOffset/BYTES_PER_OWORD);
2096 }
2097 }
2098 }
2099 }
2100
EncodeSrc1IndirectRegNum(G4_INST * inst,BinInst * mybin,G4_SrcRegRegion * src1)2101 inline void EncodeSrc1IndirectRegNum(G4_INST* inst, BinInst *mybin, G4_SrcRegRegion *src1)
2102 {
2103 bool subValid;
2104 unsigned short IndAddrRegSubNumValue = 0;
2105 short IndAddrImmedValue = 0;
2106
2107 if (EncodingHelper::GetSrcAddrMode(src1)==ADDR_MODE_INDIR)
2108 {
2109 if (! (EncodingHelper::GetSrcRegFile(src1)==REG_FILE_A &&
2110 EncodingHelper::GetSrcArchRegType(src1)==ARCH_REG_FILE_NULL))
2111 {
2112 IndAddrRegSubNumValue = src1->ExIndSubRegNum(subValid);
2113 IndAddrImmedValue = src1->ExIndImmVal();
2114
2115 SetSrc1IdxRegNum(mybin, IndAddrRegSubNumValue);
2116 /* Set the indirect address immediate value. */
2117 if (inst->isAligned1Inst()) {
2118 SetSrc1IdxImmByte(mybin, IndAddrImmedValue);
2119 } else {
2120 SetSrc1IdxImmOWord(mybin, IndAddrImmedValue / BYTES_PER_OWORD);
2121 }
2122 }
2123 }
2124 }
2125
EncodeSplitSendDst(G4_INST * inst)2126 BinaryEncoding::Status BinaryEncoding::EncodeSplitSendDst(G4_INST* inst)
2127 {
2128 BinInst *mybin = inst->getBinInst();
2129 if (inst->getDst() == NULL)
2130 {
2131 return FAILURE;
2132 }
2133 G4_DstRegRegion* dst = inst->getDst();
2134
2135 EncodeDstRegFile(mybin, dst);
2136 SetOperandDstType(mybin, dst);
2137 if (EncodingHelper::GetDstAddrMode(dst)==ADDR_MODE_INDIR)
2138 {
2139 bool subValid;
2140 uint16_t IndAddrRegSubNumValue = dst->ExIndSubRegNum(subValid);
2141 int16_t IndAddrImmedValue = dst->ExIndImmVal();
2142
2143 mybin->SetBits(bitsSendsDstAddrMode_0, bitsSendsDstAddrMode_1, ADDR_MODE_INDIR);
2144 mybin->SetBits(bitsSendsDstAddrSubRegNum_0, bitsSendsDstAddrSubRegNum_1, IndAddrRegSubNumValue);
2145 mybin->SetBits(bitsSendsDstAddrImm8_4_0, bitsSendsDstAddrImm8_4_1, (IndAddrImmedValue >> 4) & 0x1F);
2146 mybin->SetBits(bitsSendsDstAddrImmSign_0, bitsSendsDstAddrImmSign_1, (IndAddrImmedValue >> 9) & 0x1);
2147 }
2148 else
2149 {
2150 mybin->SetBits(bitsSendsDstAddrMode_0, bitsSendsDstAddrMode_1, ADDR_MODE_IMMED);
2151 if (EncodingHelper::GetDstRegFile(dst) == REG_FILE_A)
2152 {
2153 // must be NULL, do nothing
2154 }
2155 else
2156 {
2157 // must be GRF
2158 uint32_t byteAddress = dst->getLinearizedStart();
2159 MUST_BE_TRUE(byteAddress % 16 == 0, "dst for sends/sendsc must be oword-aligned");
2160 mybin->SetBits(bitsSendsDstRegNum_0, bitsSendsDstRegNum_1, byteAddress >> 5);
2161 mybin->SetBits(bitsSendsDstSubRegNum_0, bitsSendsDstSubRegNum_1, (byteAddress >> 4) & 0x1);
2162 }
2163 }
2164
2165 return SUCCESS;
2166 }
2167
2168 // src2 is the message descriptor (either a0.0 or imm)
EncodeSplitSendSrc2(G4_INST * inst)2169 BinaryEncoding::Status BinaryEncoding::EncodeSplitSendSrc2(G4_INST* inst)
2170 {
2171 BinInst *mybin = inst->getBinInst();
2172 if (inst->getSrc(2) == NULL)
2173 {
2174 return FAILURE;
2175 }
2176 G4_Operand* src2 = inst->getSrc(2);
2177
2178 if (src2->isImm())
2179 {
2180 mybin->SetBits(bitsSendsSelReg32Desc_0, bitsSendsSelReg32Desc_0, 0);
2181 mybin->SetBits(bitsSrcImm32_2,bitsSrcImm32_3, (uint32_t) src2->asImm()->getInt());
2182 }
2183 else if (src2->isSrcRegRegion() && src2->asSrcRegRegion()->isA0())
2184 {
2185 mybin->SetBits(bitsSendsSelReg32Desc_0, bitsSendsSelReg32Desc_0, 1);
2186 }
2187
2188 return SUCCESS;
2189 }
2190
EncodeSplitSendSrc1(G4_INST * inst)2191 BinaryEncoding::Status BinaryEncoding::EncodeSplitSendSrc1(G4_INST* inst)
2192 {
2193 BinInst *mybin = inst->getBinInst();
2194 if (inst->getSrc(1) == NULL || !inst->getSrc(1)->isSrcRegRegion())
2195 {
2196 return FAILURE;
2197 }
2198 G4_SrcRegRegion* src1 = inst->getSrc(1)->asSrcRegRegion();
2199
2200 if (src1->isNullReg())
2201 {
2202 mybin->SetBits(bitsSendsSrc1RegFile_0, bitsSendsSrc1RegFile_1, REG_FILE_A);
2203 }
2204 else
2205 {
2206 mybin->SetBits(bitsSendsSrc1RegFile_0, bitsSendsSrc1RegFile_1, REG_FILE_R);
2207 if (EncodingHelper::GetSrcAddrMode(src1) == ADDR_MODE_INDIR)
2208 {
2209 bool subValid;
2210 uint16_t IndAddrRegSubNumValue = src1->ExIndSubRegNum(subValid);
2211 int16_t IndAddrImmedValue = src1->ExIndImmVal();
2212
2213 mybin->SetBits(bitsSendsSrc1AddrMode_0, bitsSendsSrc1AddrMode_1, ADDR_MODE_INDIR);
2214 mybin->SetBits(bitsSendsSrc1AddrSubRegNum_0, bitsSendsSrc1AddrSubRegNum_1, IndAddrRegSubNumValue);
2215 mybin->SetBits(bitsSendsSrc1AddrImm8_4_0, bitsSendsSrc1AddrImm8_4_1, (IndAddrImmedValue >> 4) & 0x1F);
2216 mybin->SetBits(bitsSendsSrc1AddrImmSign_0, bitsSendsSrc1AddrImmSign_1, (IndAddrImmedValue >> 9) & 0x1);
2217 }
2218 else
2219 {
2220 uint32_t byteAddress = src1->getLinearizedStart();
2221 MUST_BE_TRUE(byteAddress % 32 == 0, "src1 for sends/sendsc must be GRF-aligned");
2222 mybin->SetBits(bitsSendsSrc1RegNum_0, bitsSendsSrc1RegNum_1, byteAddress >> 5);
2223 }
2224 }
2225
2226 return SUCCESS;
2227 }
2228
EncodeSplitSendSrc0(G4_INST * inst)2229 BinaryEncoding::Status BinaryEncoding::EncodeSplitSendSrc0(G4_INST* inst)
2230 {
2231 BinInst *mybin = inst->getBinInst();
2232 if (inst->getSrc(0) == NULL || !inst->getSrc(0)->isSrcRegRegion())
2233 {
2234 return FAILURE;
2235 }
2236 G4_SrcRegRegion* src0 = inst->getSrc(0)->asSrcRegRegion();
2237
2238 if (EncodingHelper::GetSrcAddrMode(src0)==ADDR_MODE_INDIR)
2239 {
2240 bool subValid;
2241 uint16_t IndAddrRegSubNumValue = src0->ExIndSubRegNum(subValid);
2242 int16_t IndAddrImmedValue = src0->ExIndImmVal();
2243
2244 mybin->SetBits(bitsSendsSrc0AddrMode_0, bitsSendsSrc0AddrMode_1, ADDR_MODE_INDIR);
2245 mybin->SetBits(bitsSendsSrc0AddrSubRegNum_0, bitsSendsSrc0AddrSubRegNum_1, IndAddrRegSubNumValue);
2246 mybin->SetBits(bitsSendsSrc0AddrImm8_4_0, bitsSendsSrc0AddrImm8_4_1, (IndAddrImmedValue >> 4) & 0x1F);
2247 mybin->SetBits(bitsSendsSrc0AddrImmSign_0, bitsSendsSrc0AddrImmSign_1, (IndAddrImmedValue >> 9) & 0x1);
2248 }
2249 else
2250 {
2251 mybin->SetBits(bitsSendsSrc0AddrMode_0, bitsSendsSrc0AddrMode_1, ADDR_MODE_IMMED);
2252 uint32_t byteAddress = src0->getLinearizedStart();
2253 MUST_BE_TRUE(byteAddress % 32 == 0, "src1 for sends/sendsc must be GRF-aligned");
2254 mybin->SetBits(bitsSendsSrc0RegNum_0, bitsSendsSrc0RegNum_1, byteAddress >> 5);
2255 }
2256
2257 return SUCCESS;
2258 }
2259
2260 // Gen encodes target for call as src1, though internally we store it in src0
EncodeIndirectCallTarget(G4_INST * inst)2261 BinaryEncoding::Status BinaryEncoding::EncodeIndirectCallTarget(G4_INST* inst)
2262 {
2263 BinInst *mybin = inst->getBinInst();
2264 G4_Operand* funcAddr = inst->getSrc(0);
2265 EncodeSrc1RegFile(mybin, funcAddr);
2266 EncodeSrc1Type(mybin, funcAddr);
2267 if (funcAddr->isImm())
2268 {
2269 EncodeSrcImmData(mybin, funcAddr);
2270 }
2271 else
2272 {
2273 G4_SrcRegRegion *srcRegion = funcAddr->asSrcRegRegion();
2274 EncodeSrc1RegNum(inst, mybin, srcRegion);
2275 EncodeSrc1ArchRegNum(inst, mybin, srcRegion);
2276 EncodeSrc1IndirectRegNum(inst, mybin, srcRegion);
2277 EncodeSrc1AddrMode(mybin, srcRegion);
2278 EncodeSrc1RepCtrl(mybin, srcRegion);
2279 EncodeSrc1Modifier(mybin, srcRegion);
2280 EncodeSrc1ChanSelect(inst, mybin, srcRegion);
2281 const RegionDesc *rd = srcRegion->getRegion();
2282 bool WidthValid = EncodeSrc1Width(inst, mybin, rd, srcRegion);
2283 bool HorzStrideValid = EncodeSrc1HorzStride(inst, mybin, rd, srcRegion);
2284 EncodeSrc1VertStride(inst, mybin, rd, srcRegion, WidthValid, HorzStrideValid);
2285 }
2286
2287 return SUCCESS;
2288 }
2289
2290
EncodeOperandSrc1(G4_INST * inst)2291 BinaryEncoding::Status BinaryEncoding::EncodeOperandSrc1(G4_INST* inst)
2292 {
2293 BinInst *mybin = inst->getBinInst();
2294 G4_Operand *src1 = NULL;
2295
2296 if (inst->isSplitSend())
2297 {
2298 return EncodeSplitSendSrc1(inst);
2299 }
2300
2301 G4_Operand *src0 = inst->getSrc(0);
2302 bool isSrc0Region = false;
2303 if (src0)
2304 isSrc0Region = src0->isSrcRegRegion();
2305
2306 if (inst->opcode() == G4_jmpi &&
2307 isSrc0Region)
2308 {
2309 src1 = src0;
2310 }
2311 else
2312 {
2313 src1 = inst->getSrc(1);
2314 }
2315
2316 if (inst->isLabel()) {
2317 if (isSrc0Region)
2318 {
2319 //Gen4_IR has src1 operand on src0's place
2320 src1 = src0;
2321 }
2322 else
2323 return SUCCESS;
2324 }
2325
2326 if (src1==NULL ||src1->isLabel()) return FAILURE;
2327
2328 EncodeSrc1RegFile(mybin, src1);
2329 EncodeSrc1Type(mybin, src1);
2330 if (src1->isImm())
2331 {
2332 MUST_BE_TRUE(src1->getTypeSize() != 8, "64-bit immediate must be src0");
2333 EncodeSrcImmData(mybin, src1);
2334 }
2335 else
2336 {
2337 G4_SrcRegRegion *srcRegion = src1->asSrcRegRegion();
2338 EncodeSrc1RegNum(inst, mybin, src1);
2339 EncodeSrc1ArchRegNum(inst, mybin, srcRegion);
2340 EncodeSrc1IndirectRegNum(inst, mybin, srcRegion);
2341 EncodeSrc1AddrMode(mybin, src1);
2342 EncodeSrc1RepCtrl(mybin, srcRegion);
2343 EncodeSrc1Modifier(mybin, srcRegion);
2344 EncodeSrc1ChanSelect(inst, mybin, srcRegion);
2345 const RegionDesc *rd = srcRegion->getRegion();
2346 bool WidthValid = EncodeSrc1Width(inst, mybin, rd, src1);
2347 bool HorzStrideValid = EncodeSrc1HorzStride(inst, mybin, rd, src1);
2348 EncodeSrc1VertStride(inst, mybin, rd, src1, WidthValid, HorzStrideValid);
2349 }
2350
2351 return SUCCESS;
2352 }
2353
2354 ///////////////////////////////////////////////////////////////////////////////
2355 // Src2
2356 ///////////////////////////////////////////////////////////////////////////////
2357
SetSrc2SrcMod(BinInst * mybin,uint32_t value)2358 inline void SetSrc2SrcMod(BinInst *mybin, uint32_t value)
2359 {
2360 if (mybin->GetIs3Src())
2361 mybin->SetBits(bits3SrcSrcMod[4], bits3SrcSrcMod[5], value);
2362 else
2363 return;
2364 }
2365
SetSrc2RepCtrl(BinInst * mybin,uint32_t value)2366 inline void SetSrc2RepCtrl(BinInst *mybin, uint32_t value)
2367 {
2368 if (mybin->GetIs3Src())
2369 mybin->SetBits(bits3SrcRepCtrl_4, bits3SrcRepCtrl_5, value);
2370 else
2371 return;
2372
2373 }
2374
SetSrc2Swizzle(BinInst * mybin,uint32_t value)2375 inline void SetSrc2Swizzle(BinInst *mybin, uint32_t value)
2376 {
2377 if (mybin->GetIs3Src())
2378 mybin->SetBits(bits3SrcSwizzle_4, bits3SrcSwizzle_5, value);
2379 else
2380 return;
2381 }
2382
SetSrc2ChanSel_0(BinInst * mybin,uint32_t value)2383 inline void SetSrc2ChanSel_0(BinInst *mybin, uint32_t value)
2384 {
2385 if (mybin->GetIs3Src())
2386 mybin->SetBits(bits3SrcChanSel_0_4, bits3SrcChanSel_0_5, value);
2387 else
2388 return;
2389 }
2390
SetSrc2ChanSel_1(BinInst * mybin,uint32_t value)2391 inline void SetSrc2ChanSel_1(BinInst *mybin, uint32_t value)
2392 {
2393 if (mybin->GetIs3Src())
2394 mybin->SetBits(bits3SrcChanSel_1_4, bits3SrcChanSel_1_5, value);
2395 else
2396 return;
2397 }
2398
SetSrc2ChanSel_2(BinInst * mybin,uint32_t value)2399 inline void SetSrc2ChanSel_2(BinInst *mybin, uint32_t value)
2400 {
2401 if (mybin->GetIs3Src())
2402 mybin->SetBits(bits3SrcChanSel_2_4, bits3SrcChanSel_2_5, value);
2403 else
2404 return;
2405 }
2406
SetSrc2ChanSel_3(BinInst * mybin,uint32_t value)2407 inline void SetSrc2ChanSel_3(BinInst *mybin, uint32_t value)
2408 {
2409 if (mybin->GetIs3Src())
2410 mybin->SetBits(bits3SrcChanSel_3_4, bits3SrcChanSel_3_5, value);
2411 else
2412 return;
2413 }
2414
SetSrc2RegNumHWord(BinInst * mybin,uint32_t value)2415 inline void SetSrc2RegNumHWord(BinInst *mybin, uint32_t value)
2416 {
2417 if (mybin->GetIs3Src())
2418 mybin->SetBits(bits3SrcSrcRegNumHWord_4, bits3SrcSrcRegNumHWord_5, value);
2419 else
2420 return;
2421 }
2422
SetSrc2RegNumOWord(BinInst * mybin,uint32_t value)2423 inline void SetSrc2RegNumOWord(BinInst *mybin, uint32_t value)
2424 {
2425 if (mybin->GetIs3Src())
2426 mybin->SetBits(bits3SrcSrcRegNumOWord_4, bits3SrcSrcRegNumOWord_5, value);
2427 else
2428 return;
2429 }
2430
SetSrc2RegNumDWord(BinInst * mybin,uint32_t value)2431 inline void SetSrc2RegNumDWord(BinInst *mybin, uint32_t value)
2432 {
2433 if (mybin->GetIs3Src())
2434 mybin->SetBits(bits3SrcSrcRegNumDWord_4, bits3SrcSrcRegNumDWord_5, value);
2435 else
2436 return;
2437 }
2438
EncodeSrc2ChanSelect(G4_INST * inst,BinInst * mybin,G4_SrcRegRegion * srcRegion,G4_Operand * src2)2439 inline void EncodeSrc2ChanSelect(G4_INST *inst,
2440 BinInst *mybin,
2441 G4_SrcRegRegion *srcRegion,
2442 G4_Operand *src2)
2443 {
2444 if (src2->isAccRegValid())
2445 {
2446 if (inst->opcode() == G4_madm)
2447 {
2448 uint32_t value = src2->getAccRegSel();
2449 SetSrc2ChanSel_0(mybin, value & 0x3);
2450 SetSrc2ChanSel_1(mybin, value >> 2 & 0x3);
2451 SetSrc2ChanSel_2(mybin, 0);
2452 SetSrc2ChanSel_3(mybin, 0);
2453 return;
2454 }
2455 ASSERT_USER(false, "acc2~acc7 were set on wrong instruction");
2456 }
2457
2458 const char *swizzle = srcRegion->getSwizzle();
2459 {
2460 if (swizzle[0] != '\0' && swizzle[0] != 'r')
2461 {
2462 ChanSel ch0 = EncodingHelper::GetSrcChannelSelectValue(srcRegion, 0);
2463 ChanSel ch1 = EncodingHelper::GetSrcChannelSelectValue(srcRegion, 1);
2464 ChanSel ch2 = EncodingHelper::GetSrcChannelSelectValue(srcRegion, 2);
2465 ChanSel ch3 = EncodingHelper::GetSrcChannelSelectValue(srcRegion, 3);
2466 if (ch0 != CHAN_SEL_UNDEF)
2467 SetSrc2ChanSel_0(mybin, ch0);
2468 if (ch1 != CHAN_SEL_UNDEF)
2469 SetSrc2ChanSel_1(mybin, ch1);
2470 if (ch2 != CHAN_SEL_UNDEF)
2471 SetSrc2ChanSel_2(mybin, ch2);
2472 if (ch3 != CHAN_SEL_UNDEF)
2473 SetSrc2ChanSel_3(mybin, ch3);
2474 }
2475 }
2476
2477 //Following ISAASM example which encodes it to xyzw and is able to compact as a result.
2478 if (swizzle[0] == '\0' || swizzle[0] == 'r')
2479 {
2480 if (inst->isAligned16Inst())
2481 {
2482 SetSrc2ChanSel_0(mybin, CHAN_SEL_X);
2483 SetSrc2ChanSel_1(mybin, CHAN_SEL_Y);
2484 SetSrc2ChanSel_2(mybin, CHAN_SEL_Z);
2485 SetSrc2ChanSel_3(mybin, CHAN_SEL_W);
2486 }
2487 }
2488 }
2489
EncodeSrc2RepCtrl(BinInst * mybin,G4_SrcRegRegion * srcRegion)2490 inline void EncodeSrc2RepCtrl(BinInst *mybin, G4_SrcRegRegion *srcRegion)
2491 {
2492 const char *swizzle = srcRegion->getSwizzle();
2493 if (swizzle[0] == 'r')
2494 SetSrc2RepCtrl(mybin, 0x1);
2495 else
2496 SetSrc2RepCtrl(mybin, 0x0);
2497 }
2498
EncodeSrc2Modifier(BinInst * mybin,G4_SrcRegRegion * srcRegion,G4_Operand * src2)2499 inline void EncodeSrc2Modifier(BinInst *mybin, G4_SrcRegRegion *srcRegion, G4_Operand *src2)
2500 {
2501 if (EncodingHelper::GetSrcRegFile(src2) != REG_FILE_M)
2502 {
2503 SetSrc2SrcMod(mybin, GetSrcMod(srcRegion));
2504 }
2505 }
2506
EncodeSrc2RegNum(G4_INST * inst,BinInst * mybin,G4_Operand * src2)2507 inline void BinaryEncoding::EncodeSrc2RegNum(G4_INST* inst, BinInst *mybin, G4_Operand *src2)
2508 {
2509 if (EncodingHelper::GetSrcRegFile(src2) != REG_FILE_A &&
2510 EncodingHelper::GetSrcAddrMode(src2) == ADDR_MODE_IMMED)
2511 {
2512 uint32_t byteAddress = src2->getLinearizedStart();
2513 MUST_BE_TRUE(byteAddress < kernel.getNumRegTotal() * numEltPerGRF<Type_UB>(), "src2 exceeds total GRF number");
2514
2515 // encode dwords
2516 mybin->SetBits(bits3SrcSrc2RegDWord_H, bits3SrcSrc2RegDWord_L, byteAddress >> 2);
2517 // encode word (for word type)
2518 mybin->SetBits(bits3SrcSrc2SubRegNumW_H, bits3SrcSrc2SubRegNumW_L, (byteAddress >> 1) & 0x1);
2519 }
2520 }
2521
EncodeOperandSrc2(G4_INST * inst)2522 inline BinaryEncoding::Status BinaryEncoding::EncodeOperandSrc2(G4_INST* inst)
2523 {
2524 BinInst *mybin = inst->getBinInst();
2525 G4_Operand *src2 = inst->getSrc(2);
2526
2527 if (src2==NULL || src2->isLabel())
2528 {
2529 return SUCCESS;
2530 }
2531
2532 if (inst->isSplitSend())
2533 {
2534 return EncodeSplitSendSrc2(inst);
2535 }
2536
2537 if (!src2->isImm())
2538 {
2539 G4_SrcRegRegion *srcRegion = src2->asSrcRegRegion();
2540 EncodeSrc2ChanSelect(inst, mybin, srcRegion, src2);
2541 EncodeSrc2RepCtrl(mybin, srcRegion);
2542 EncodeSrc2Modifier(mybin, srcRegion, src2);
2543 EncodeSrc2RegNum(inst, mybin, src2);
2544 }
2545
2546 return SUCCESS;
2547 }
2548
SetExtMsgDescr(G4_INST * inst,BinInst * mybin,uint32_t value)2549 void SetExtMsgDescr(G4_INST *inst, BinInst *mybin, uint32_t value)
2550 {
2551
2552 EncExtMsgDescriptor emd;
2553 emd.ulData = value;
2554
2555
2556 if (inst->isSplitSend())
2557 {
2558 G4_Operand *src3 = inst->getSrc(3);
2559 // additional extended msg desc to be encoded
2560 if (src3 && src3->isSrcRegRegion() && src3->asSrcRegRegion()->isA0())
2561 {
2562 mybin->SetBits(bitsSendsSelReg32ExDesc_0, bitsSendsSelReg32ExDesc_1, 1);
2563 mybin->SetBits(bitsSendsExDescRegNum_0, bitsSendsExDescRegNum_1,
2564 src3->asSrcRegRegion()->getBase()->asRegVar()->getPhyRegOff());
2565 return;
2566 }
2567 }
2568
2569 // immediate extended message descriptor
2570 mybin->SetBits(bitsSharedFunctionID_0, bitsSharedFunctionID_1, emd.ExtMsgDescriptor.TargetUnitId);
2571 mybin->SetBits(bitsEndOfThread_0, bitsEndOfThread_1, emd.ExtMsgDescriptor.EndOfThread);
2572 mybin->SetBits(bitsExDescCPSLOD_0, bitsExDescCPSLOD_1, emd.ExtMsgDescriptor.CPSLODCompensation);
2573
2574
2575 if (inst->isSplitSend())
2576 {
2577 mybin->SetBits(bitsExMsgLength_0, bitsExMsgLength_1, emd.ExtMsgDescriptor.ExtMessageLength);
2578 mybin->SetBits(bitsSendsExDescFuncCtrl_0, bitsSendsExDescFuncCtrl_1, emd.ExtMsgDescriptor.ExtFunctionControl);
2579 }
2580 else if (inst->getPlatform() >= GENX_SKL)
2581 {
2582 // needs to encode extended message desc function control as well for SKL+
2583 uint32_t val = emd.ExtMsgDescriptor.ExtFunctionControl & 0xF;
2584 mybin->SetBits(bitsSendExDesc19, bitsSendExDesc16, val);
2585 val = (emd.ExtMsgDescriptor.ExtFunctionControl >> 4) & 0xF;
2586 mybin->SetBits(bitsSendExDesc23, bitsSendExDesc20, val);
2587 val = (emd.ExtMsgDescriptor.ExtFunctionControl >> 8) & 0xF;
2588 mybin->SetBits(bitsSendExDesc27, bitsSendExDesc24, val);
2589 val = (emd.ExtMsgDescriptor.ExtFunctionControl >> 12) & 0xF;
2590 mybin->SetBits(bitsSendExDesc31, bitsSendExDesc28, val);
2591 }
2592 }
2593
2594 inline
EncodeExtMsgDescr(G4_INST * inst)2595 BinaryEncoding::Status BinaryEncoding::EncodeExtMsgDescr(G4_INST* inst)
2596 {
2597 BinInst *mybin = inst->getBinInst();
2598 MUST_BE_TRUE(inst->getMsgDescRaw(), "expected raw descriptor");
2599 uint32_t msgDesc = inst->getMsgDescRaw()->getExtendedDesc();
2600 SetExtMsgDescr(inst, mybin, msgDesc);
2601 return SUCCESS;
2602 }
2603
EncodeOperands(G4_INST * inst)2604 BinaryEncoding::Status BinaryEncoding::EncodeOperands(G4_INST* inst)
2605 {
2606 Status myStatus = SUCCESS;
2607
2608 //Don't need to encode src1 if math only has one src.
2609 int i = ((inst->isMath() && inst->asMathInst()->isOneSrcMath())?1:inst->getNumSrc());
2610 switch (i)
2611 {
2612 case 4: // split send's ext msg descriptor encoding is skipped here
2613 case 3:
2614 EncodeOperandSrc2(inst);
2615 case 2:
2616 EncodeOperandSrc1(inst);
2617 case 1:
2618 EncodeOperandSrc0(inst);
2619 default:
2620 break;
2621 }
2622
2623 if (inst->opcode() == G4_jmpi &&
2624 inst->getSrc(0) &&
2625 inst->getSrc(0)->isSrcRegRegion())
2626 {
2627 EncodeOperandSrc1(inst);
2628 }
2629
2630 if (inst->isSend())
2631 EncodeExtMsgDescr(inst); // all the ext msg descriptor is handled here
2632
2633 return myStatus;
2634 }
2635
insertWaitDst(G4_INST * inst)2636 void BinaryEncoding::insertWaitDst(G4_INST *inst)
2637 {
2638 BinInst *mybin = inst->getBinInst();
2639 if (inst->opcode()==G4_wait)
2640 { // The wait instruction needs src0 inserted as dst operand
2641 G4_Operand *src0 = inst->getSrc(0);
2642
2643 RegFile regFile = EncodingHelper::GetSrcRegFile(src0);
2644 SetDstRegFile(mybin, regFile);
2645 if (regFile == REG_FILE_A)
2646 SetDstArchRegFile(mybin, EncodingHelper::GetSrcArchRegType(src0));
2647
2648 SetDstHorzStride(mybin, HORZ_STRIDE_1);
2649 SetDstAddrMode(mybin, EncodingHelper::GetSrcAddrMode(src0));
2650
2651 // set dst's RegNum and RegSubNum according to its src0's.
2652 if (EncodingHelper::GetSrcRegFile(src0)!=REG_FILE_A &&
2653 EncodingHelper::GetSrcAddrMode(src0) == ADDR_MODE_IMMED)
2654 {
2655 bool repControl = EncodingHelper::GetRepControl(src0);
2656 uint32_t byteAddress = src0->getLinearizedStart();
2657
2658 if (inst->isAligned1Inst() || repControl)
2659 {
2660 SetDstRegNumByte(mybin, byteAddress);
2661 } else {
2662 SetDstRegNumOWord(mybin, byteAddress/BYTES_PER_OWORD);
2663 }
2664 }
2665 }
2666 }
2667
SetCompactCtrl(BinInst * mybin,uint32_t value)2668 void BinaryEncoding::SetCompactCtrl (BinInst *mybin, uint32_t value)
2669 {
2670 mybin->SetBits(bitsCompactCtrl_0, bitsCompactCtrl_1, value);
2671 }
2672
GetCompactCtrl(BinInst * mybin)2673 uint32_t BinaryEncoding::GetCompactCtrl(BinInst *mybin)
2674 {
2675 return mybin->GetBits(bitsCompactCtrl_0, bitsCompactCtrl_1);
2676 }
2677
GetComprCtrl(BinInst * mybin)2678 inline uint32_t GetComprCtrl(BinInst *mybin)
2679 {
2680 return mybin->GetBits(bitsComprCtrl_0, bitsComprCtrl_1);
2681 }
2682
isIndirectJmp(G4_INST * inst)2683 bool isIndirectJmp(G4_INST *inst)
2684 {
2685 return (inst &&
2686 inst->opcode() == G4_jmpi &&
2687 inst->getSrc(0)->isSrcRegRegion() &&
2688 ((G4_SrcRegRegion *)(inst->getSrc(0)))->getBase()->isRegVar());
2689 }
2690
isIndirectJmpTarget(G4_INST * inst)2691 bool isIndirectJmpTarget(G4_INST *inst)
2692 {
2693 return (inst &&
2694 inst->opcode() == G4_jmpi &&
2695 inst->getSrc(0)->isLabel());
2696 }
2697
DoAllEncoding(G4_INST * inst)2698 BinaryEncoding::Status BinaryEncoding::DoAllEncoding(G4_INST* inst)
2699 {
2700 Status myStatus = SUCCESS;
2701 bool isFCCall = false, isFCRet = false;
2702
2703 if (inst->opcode() == G4_label) return myStatus;
2704
2705 if (inst->opcode() == G4_illegal)
2706 return FAILURE;
2707
2708 EncodingHelper::mark3Src(inst);
2709
2710 insertWaitDst(inst);
2711
2712 if (inst->opcode() == G4_pseudo_fc_call)
2713 {
2714 inst->asCFInst()->pseudoCallToCall();
2715 isFCCall = true;
2716 }
2717
2718 if (inst->opcode() == G4_pseudo_fc_ret)
2719 {
2720 inst->asCFInst()->pseudoRetToRet();
2721 isFCRet = true;
2722 }
2723
2724 EncodeOpCode(inst);
2725
2726 if (inst->opcode() == G4_nop)
2727 {
2728 return myStatus;
2729 }
2730
2731 EncodeExecSize(inst);
2732 EncodeFlagReg(inst);
2733 EncodeFlagRegPredicate(inst);
2734 EncodeCondModifier(inst);
2735 EncodeInstModifier(inst);
2736 EncodeInstOptionsString(inst);
2737
2738 if (inst->isSend())
2739 {
2740 EncodeSendMsgDesc29_30(inst);
2741 }
2742
2743 if (inst->opcode() == G4_math)
2744 {
2745 EncodeMathControl(inst);
2746 }
2747
2748 if (isFCCall == true) {
2749 BinInst *mybin = inst->getBinInst();
2750 SetSrc1RegFile(mybin, REG_FILE_I);
2751 SetSrc1Type(mybin, SRC_IMM_TYPE_D);
2752 inst->setOpcode(G4_pseudo_fc_call);
2753 }
2754
2755 if (isFCRet == true) {
2756 inst->setOpcode(G4_pseudo_fc_ret);
2757 }
2758
2759 return myStatus;
2760 }
2761
2762 //inline void dumpOptReport(int totalInst,
2763 // int numCompactedInst,
2764 // int numCompacted3SrcInst,
2765 // G4_Kernel& kernel)
2766 //{
2767 // if (kernel.getOption(vISA_OptReport))
2768 // {
2769 // std::ofstream optReport;
2770 // getOptReportStream(optReport, kernel.fg.builder->getOptions());
2771 // optReport << " === Binary Compaction ===" <<endl;
2772 // optReport<< fixed << endl;
2773 // optReport<< kernel.getName() <<": "
2774 // << numCompactedInst <<" out of " <<totalInst <<" instructions are compacted."<<endl;
2775 // if (numCompacted3SrcInst>0)
2776 // {
2777 // optReport<< kernel.getName() <<": "
2778 // << numCompacted3SrcInst <<" instructions of 3 src (mad/pln) are compacted."<<endl;
2779 // }
2780 // optReport<< setprecision(0)
2781 // << (float)(numCompactedInst*100)/(float)(totalInst)
2782 // << "% instructions of this kernel are compacted."
2783 // <<endl;
2784 // optReport<<endl;
2785 // closeOptReportStream(optReport);
2786 // }
2787 //}
2788
ProduceBinaryInstructions()2789 inline BinaryEncoding::Status BinaryEncoding::ProduceBinaryInstructions()
2790 {
2791 Status myStatus = FAILURE;
2792 BB_LIST_ITER ib, bend(kernel.fg.end());
2793
2794 int globalInstNum = 0;
2795 int globalHalfInstNum = 0;
2796 int numCompactedInst = 0;
2797 int numCompacted3SrcInst = 0;
2798 //define offsetVector to record forward jumps/calls
2799 std::vector<ForwardJmpOffset> offsetVector;
2800
2801 if (doCompaction())
2802 {
2803 for (uint8_t i=0; i<(int)COMPACT_TABLE_SIZE; i++)
2804 {
2805 BDWCompactControlTable.AddIndex(IVBCompactControlTable[i], i);
2806 BDWCompactSourceTable.AddIndex(IVBCompactSourceTable[i], i);
2807 BDWCompactSubRegTable.AddIndex(IVBCompactSubRegTable[i], i);
2808 BDWCompactSubRegTable.AddIndex1(IVBCompactSubRegTable[i] & 0x1F, i);
2809 BDWCompactSubRegTable.AddIndex2(IVBCompactSubRegTable[i] & 0x3FF, i);
2810 BDWCompactDataTypeTableStr.AddIndex(BDWCompactDataTypeTable[i], i);
2811 }
2812 }
2813
2814 /**
2815 * Traverse the flow graph basic block
2816 */
2817 for (ib = kernel.fg.begin(); ib != bend; ++ib)
2818 {
2819 G4_BB *bb = *ib;
2820 int localInstNum = 0;
2821 int localHalfInstNum = 0;
2822
2823 /**
2824 * Traverse the instruction lists
2825 */
2826 INST_LIST_ITER ii, iend(bb->end());
2827 //indirectJump = false;
2828 for (ii = bb->begin(); ii != iend; ++ii)
2829 {
2830 /* do detailed encoding here */
2831 G4_INST *inst = *ii;
2832
2833 if (inst->opcode() == G4_label)
2834 {
2835 inst->setBinInst(NULL);
2836 }
2837 else
2838 {
2839 BinInst *bin = new (mem) BinInst();
2840 inst->setBinInst(bin);
2841
2842 myStatus = DoAllEncoding(inst);
2843
2844
2845 if (inst->opcode() == G4_nop)
2846 {
2847 binInstList.push_back(inst->getBinInst());
2848 BuildLabelMap(inst, localHalfInstNum, localInstNum,
2849 globalHalfInstNum, globalInstNum);
2850 continue;
2851 }
2852
2853
2854 EncodeOperandDst(inst);
2855
2856 if (!EncodingHelper::hasLabelString(inst))
2857 {
2858 EncodeOperands(inst);
2859 }
2860
2861 if (inst->opcode() == G4_pseudo_fc_call ||
2862 inst->opcode() == G4_pseudo_fc_ret)
2863 {
2864 inst->getBinInst()->SetDontCompactFlag(true);
2865 }
2866
2867 if (doCompaction())
2868 {
2869 // do not compact the instruction that mark as NoCompact
2870 inst->getBinInst()->SetMustCompactFlag(false);
2871 inst->getBinInst()->SetDontCompactFlag(inst->isNoCompactedInst());
2872
2873 /**
2874 * handling switch/case for gen6: jump table should not be compacted
2875 */
2876 bool compacted = false;
2877 {
2878 TIME_SCOPE(ENCODE_COMPACTION);
2879 compacted = compactOneInstruction(inst);
2880 }
2881 if (compacted)
2882 {
2883 if (kernel.getOption(vISA_OptReport))
2884 {
2885 numCompactedInst++;
2886 if (inst->getBinInst()->GetIs3Src())
2887 numCompacted3SrcInst++;
2888 }
2889 inst->setCompacted();
2890 }
2891 }
2892 binInstList.push_back(inst->getBinInst());
2893
2894 if (inst->opcode() >= G4_jmpi && inst->opcode() <= G4_join)
2895 {
2896 if (!EncodeConditionalBranches(inst, globalHalfInstNum))
2897 {
2898 offsetVector.push_back(ForwardJmpOffset(inst, globalHalfInstNum));
2899 }
2900 }
2901 } // else if
2902
2903 BuildLabelMap(inst, localHalfInstNum, localInstNum,
2904 globalHalfInstNum, globalInstNum);
2905
2906 } // for inst
2907 } // for bb
2908 kernel.setAsmCount(globalInstNum);
2909 SetInstCounts((uint32_t)globalHalfInstNum);
2910
2911 EncodingHelper::dumpOptReport(globalInstNum, numCompactedInst, numCompacted3SrcInst, kernel);
2912 for (auto x = offsetVector.begin(), vEnd = offsetVector.end(); x != vEnd; x++)
2913 {
2914 // calculate offsets again since labels for forward jumps/calls
2915 // are available now
2916 if (!EncodeConditionalBranches(x->inst, x->offset))
2917 {
2918 MUST_BE_TRUE(false, "invalid label!");
2919 }
2920 }
2921
2922 return myStatus;
2923 }
2924
DoAll()2925 void BinaryEncoding::DoAll()
2926 {
2927 InitPlatform(getGenxPlatform());
2928 FixInst();
2929 ProduceBinaryInstructions();
2930 }
2931
SetBranchJIP(BinInst * mybin,uint32_t JIP)2932 inline void SetBranchJIP(BinInst *mybin, uint32_t JIP)
2933 {
2934 if (mybin->GetIs3Src())
2935 return;
2936 else
2937 {
2938 mybin->SetBits(bitsJIP[0], bitsJIP[1], JIP);
2939 }
2940 }
2941
2942
SetBranchJIPUIP(BinInst * mybin,uint32_t JIP,uint32_t UIP)2943 inline void SetBranchJIPUIP(BinInst *mybin, uint32_t JIP, uint32_t UIP)
2944 {
2945 if (mybin->GetIs3Src())
2946 return;
2947 else
2948 {
2949 mybin->SetBits(bitsJIP[0], bitsJIP[1], JIP);
2950 mybin->SetBits(bitsUIP[0], bitsUIP[1], UIP);
2951 }
2952 }
2953
SetBranchOffsets(G4_INST * inst,uint32_t JIP,uint32_t UIP)2954 void BinaryEncoding::SetBranchOffsets(G4_INST* inst,
2955 uint32_t JIP,
2956 uint32_t UIP)
2957 {
2958 BinInst *mybin = inst->getBinInst();
2959 G4_opcode opc = inst->opcode();
2960
2961 {
2962 //JIP and UIP are at src1
2963 //No need to set type and srcReg for src1
2964 //Not needed for instructions with JIP only
2965 //and over written by UIP
2966
2967 if (opc == G4_if ||
2968 opc == G4_break ||
2969 opc == G4_cont ||
2970 opc == G4_halt ||
2971 opc == G4_goto ||
2972 opc == G4_else)
2973 {
2974 SetSrc0RegFile(mybin, REG_FILE_I);
2975 SetSrc0Type(mybin, SRC_IMM_TYPE_D);
2976 SetBranchJIPUIP(mybin, JIP, UIP);
2977 }
2978 else
2979 {
2980 //JIP is at location src1 and must be of type D (signed dword integer).
2981 if ((opc == G4_while ||
2982 opc == G4_endif ||
2983 opc == G4_join))
2984 {
2985 SetSrc1RegFile(mybin, REG_FILE_I);
2986 SetSrc1Type(mybin, SRC_IMM_TYPE_D);
2987 }
2988 SetBranchJIP(mybin, JIP);
2989 }
2990 }
2991 }
2992
isValidIPOffset(int32_t ipOffset)2993 inline bool isValidIPOffset(int32_t ipOffset)
2994 {
2995 return true;
2996 }
2997
SetCmpSrc1Imm32(BinInst * mybin,uint32_t immediateData,G4_Operand * src)2998 void BinaryEncoding::SetCmpSrc1Imm32(BinInst *mybin, uint32_t immediateData, G4_Operand* src)
2999 {
3000 if (GetCompactCtrl(mybin))
3001 {
3002 SetCmpSrc1RegNum(mybin, immediateData & 0xff); // 63:56
3003 SetCmpSrc1Index(mybin, (immediateData >> 8)& 0x1f);
3004 }
3005 else
3006 {
3007 SetSrc1Imm32(mybin, immediateData, src);
3008 }
3009 }
3010
3011 /* EncodeConditionalBranches() returns true for backward jmp/call/jip/uip,
3012 * returns false for forward jmp/call/jip/uip.
3013 */
EncodeConditionalBranches(G4_INST * inst,uint32_t insOffset)3014 bool BinaryEncoding::EncodeConditionalBranches(G4_INST *inst,
3015 uint32_t insOffset)
3016 {
3017 std::string jipLabel;
3018 std::string uipLabel;
3019 int32_t jipOffset = 0;
3020 int32_t uipOffset = 0;
3021 G4_opcode op = inst->opcode();
3022
3023 // while and case only have JIP for all platforms
3024 // break, cont and halt have both JIP and UIP for all platforms
3025 if (op == G4_if ||
3026 op == G4_while ||
3027 op == G4_else ||
3028 op == G4_break ||
3029 op == G4_cont ||
3030 op == G4_halt ||
3031 op == G4_goto ||
3032 op == G4_endif ||
3033 op == G4_join)
3034 {
3035 G4_Label* jip = inst->asCFInst()->getJip();
3036 if (jip)
3037 {
3038 int32_t info = GetLabelInfo(jip);
3039 if (info == -1)
3040 {
3041 return false;
3042 }
3043 jipOffset = info - insOffset;
3044 if (!isValidIPOffset(jipOffset))
3045 {
3046 MUST_BE_TRUE(false, "invalid IP offset");
3047 }
3048 // BDW+: in unit of bytes
3049 jipOffset *= (int32_t)JUMP_INST_COUNT_SIZE;
3050 }
3051 //Setting RegFile and Type in case JIP is 0.
3052 else if (op == G4_while ||
3053 op == G4_endif ||
3054 op == G4_join)
3055 {
3056 BinInst * mybin = inst->getBinInst();
3057 SetSrc1RegFile(mybin, REG_FILE_I);
3058 SetSrc1Type(mybin, SRC_IMM_TYPE_D);
3059 }
3060 }
3061
3062 // halt has both JIP and UIP on all platforms
3063 // else has JIP for all platforms; else has UIP for BDW only
3064 if (op == G4_break ||
3065 op == G4_cont ||
3066 op == G4_halt ||
3067 op == G4_if ||
3068 op == G4_else ||
3069 op == G4_goto)
3070 {
3071 G4_Label* uip = inst->asCFInst()->getUip();
3072 if (uip)
3073 {
3074 int32_t info = GetLabelInfo(uip);
3075 if (info == -1)
3076 {
3077 return false;
3078 }
3079 uipOffset = info - insOffset;
3080 if (!isValidIPOffset(uipOffset))
3081 {
3082 MUST_BE_TRUE(false, "invalid IP offset");
3083 }
3084 uipOffset *= (uint32_t)JUMP_INST_COUNT_SIZE;
3085 }
3086 }
3087
3088 if (op == G4_endif && jipOffset == 0)
3089 {
3090 jipOffset = INST_SIZE; // Next instruction ...
3091 }
3092
3093 if (jipOffset != 0 || uipOffset != 0)
3094 {
3095 SetBranchOffsets(inst, jipOffset, uipOffset);
3096 }
3097
3098 if (op == G4_jmpi &&
3099 inst->getSrc(0) &&
3100 inst->getSrc(0)->isLabel())
3101 {
3102 // find the label's IP count
3103 G4_Label *opnd = inst->getSrc(0)->asLabel();
3104 BinInst * mybin = inst->getBinInst();
3105 // Calculate the address offset
3106 // Label has the same IP count as the following instruction,
3107 // "break 1" is to the fall through instruction
3108 int32_t info = GetLabelInfo(opnd);
3109 if (info == -1)
3110 {
3111 return false;
3112 }
3113 int32_t jmpOffset = info - insOffset;
3114 if (GetCompactCtrl(mybin))
3115 jmpOffset -= 1;
3116 else
3117 jmpOffset -= 2;
3118
3119 jmpOffset *= (int32_t)JUMP_INST_COUNT_SIZE;
3120
3121 if (!isValidIPOffset(jmpOffset))
3122 {
3123 // generate
3124 // add (1) ip ip jmpOffset+16
3125 // to work around the 16-bit jump offset limit
3126 // jmpOffset is incremented by 1 since jmpi implicitly performs it
3127 // (e.g., jmpi 0 jumps to the next instruction)
3128 // everything else about the instruction should stay the same
3129 // (dst and src0 are both ip for example)
3130 SetOpCode(mybin, G4_add);
3131 jmpOffset += 16;
3132 }
3133
3134 if (GetCompactCtrl(mybin))
3135 {
3136 SetCmpSrc1RegNum(mybin, jmpOffset & 0xff); // 63:56
3137 SetCmpSrc1Index(mybin, (jmpOffset >> 8)& 0x1f);
3138 }
3139 else
3140 {
3141 SetSrc1RegFile(mybin, REG_FILE_I);
3142 SetSrc1Type(mybin, SRC_IMM_TYPE_D);
3143 SetSrc1Imm32(mybin, (uint32_t)jmpOffset, opnd);
3144 }
3145 }
3146
3147 if (op == G4_call && inst->getSrc(0))
3148 {
3149
3150 if (inst->getSrc(0)->isLabel())
3151 {
3152 G4_Label *opnd = inst->getSrc(0)->asLabel();
3153 int32_t info = GetLabelInfo(opnd);
3154 if (info == -1)
3155 {
3156 return false;
3157 }
3158 int32_t jmpOffset = info - insOffset;
3159 if (!isValidIPOffset(jmpOffset))
3160 {
3161 MUST_BE_TRUE(false, "invalid IP offset for call");
3162 }
3163
3164 jmpOffset *= (int32_t)JUMP_INST_COUNT_SIZE;
3165
3166 BinInst *mybin = inst->getBinInst();
3167
3168 SetSrc0VertStride(mybin, 2);
3169 SetSrc0Width(mybin, 2);
3170 SetSrc0HorzStride(mybin, 1);
3171
3172
3173 SetSrc1RegFile(mybin, REG_FILE_I);
3174 SetSrc1Type(mybin, SRC_IMM_TYPE_D);
3175
3176 SetCmpSrc1Imm32(mybin, jmpOffset, opnd);
3177 }
3178 else
3179 {
3180 // indirect call
3181 BinInst *mybin = inst->getBinInst();
3182
3183 SetSrc0VertStride(mybin, 2);
3184 SetSrc0Width(mybin, 2);
3185 SetSrc0HorzStride(mybin, 1);
3186 EncodeIndirectCallTarget(inst);
3187 }
3188 }
3189 return true;
3190 }
3191