1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2017-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #ifndef _COMMON_BINARYENCODING_H_
10 #define _COMMON_BINARYENCODING_H_
11 
12 #include "FlowGraph.h"
13 #include "Timer.h"
14 
15 extern "C" void* allocCodeBlock(size_t sz);
16 
17 
18 ///////////////////////////////////////////////////////////////////////////////
19 // Constants
20 ///////////////////////////////////////////////////////////////////////////////
21 const uint32_t INST_SIZE       = 16; // bytes
22 const uint32_t JUMP_INST_COUNT_SIZE = INST_SIZE / 2;
23 
24 #define BYTES_PER_INST 16
25 #define BYTES_PER_OWORD 16
26 #define DWORDS_PER_INST 4
27 #define BITS_PER_DWORD 32
28 
29 const uint32_t NUM_REGISTER_BYTES     = 1 << 5;
30 
31 const uint32_t SCRATCH_BINDING_TABLE_INDEX = 255;
32 
33 #define ES_1_CHANNEL 0
34 #define ES_2_CHANNELS 1
35 #define ES_4_CHANNELS 2
36 #define ES_8_CHANNELS 3
37 #define ES_16_CHANNELS 4
38 #define ES_32_CHANNELS 5
39 
40 
41 typedef enum _RegFile_
42 {
43     REG_FILE_A,
44     REG_FILE_R,
45     REG_FILE_M,
46     REG_FILE_I
47 } RegFile;
48 
49 typedef enum _ArchRegFile_
50 {                                          // (ARF Registers -- Overview):
51     ARCH_REG_FILE_NULL        = 0x00,  // 0000 null    Null register
52     ARCH_REG_FILE_A           = 0x01,  // 0001 a0.#    Address register
53     ARCH_REG_FILE_ACC         = 0x02,  // 0010 acc#    Accumulator register
54     ARCH_REG_FILE_F           = 0x03,  // 0011 f#.#    Flag register
55     ARCH_REG_FILE_CE_REG      = 0x04,  // 0100 ce#     Channel Enable register
56     ARCH_REG_FILE_MSG_REG     = 0x05,  // 0101 msg+    Message Control Register
57     ARCH_REG_FILE_SP_REG      = 0x06,  // 0110 sp      Stack Pointer Register
58     ARCH_REG_FILE_STATE_REG   = 0x07,  // 0111 sr0.#   State register
59     ARCH_REG_FILE_CNTL_REG    = 0x08,  // 1000 cr0.#   Control register
60     ARCH_REG_FILE_NCNT_REG    = 0x09,  // 1001 n#      Notification count register
61     ARCH_REG_FILE_IP          = 0x0A,  // 1010 ip      Instruction pointer register
62     ARCH_REG_FILE_TDR_REG     = 0x0B,  // 1011 tdr     Thread dependency register
63     ARCH_REG_FILE_TM_REG      = 0x0C,  // 1100 tm0     TimeStamp register
64     ARCH_REG_FILE_FC_REG      = 0x0D,  // 1101 fc#.#   Flow Control register
65     ARCH_REG_FILE_DBG_REG     = 0x0F   // 1111 dbg0    Debug only
66 } ArchRegFile;
67 
68 enum class Align1PredCtrl
69 {
70     NONE,
71     SEQUENTIAL,
72     ANYV,
73     ALLV,
74     ANY2H,
75     ALL2H,
76     ANY4H,
77     ALL4H,
78     ANY8H,
79     ALL8H,
80     ANY16H,
81     ALL16H,
82     ANY32H,
83     ALL32H
84 };
85 
86 typedef enum _AddrMode_
87 {
88     ADDR_MODE_IMMED,
89     ADDR_MODE_INDIR
90 } AddrMode;
91 
92 typedef enum _ChanSel_
93 {
94     CHAN_SEL_X      ,
95     CHAN_SEL_Y      ,
96     CHAN_SEL_Z      ,
97     CHAN_SEL_W      ,
98     CHAN_SEL_UNDEF
99 } ChanSel;
100 
101 
102 #define NUM_REGISTER_CHANNELS 4
103 
104 namespace vISA
105 {
106     class ForwardJmpOffset
107     {
108     public:
109         G4_INST *inst;
110         int32_t offset;
ForwardJmpOffset(G4_INST * _inst,int32_t _offset)111         ForwardJmpOffset(G4_INST *_inst, int32_t _offset) :
112             inst(_inst), offset(_offset) {};
113     };
114 
115     class EncodingHelper
116     {
117     public:
118         static inline RegFile GetDstRegFile(G4_DstRegRegion *dst);
119         static inline RegFile GetSrcRegFile(G4_Operand *src);
120         static inline uint32_t GetArchRegType(G4_VarBase *opnd);
121         static inline uint32_t GetDstArchRegType(G4_DstRegRegion *opnd);
122         static inline unsigned short GetElementSizeValue(G4_Operand *opnd);
123         static inline AddrMode GetDstAddrMode(G4_DstRegRegion *dst);
124         static inline AddrMode GetSrcAddrMode(G4_Operand *src);
125         static inline void mark3Src(G4_INST* inst);
126         static void dumpOptReport(int totalInst,
127             int numCompactedInst,
128             int numCompacted3SrcInst,
129             G4_Kernel& kernel);
130         static inline bool hasLabelString(G4_INST *inst);
131 
132 
isSrcSubRegNumValid(G4_Operand * src)133         static inline bool isSrcSubRegNumValid(G4_Operand *src)
134         {
135             bool valid = false;
136             if (EncodingHelper::GetSrcRegFile(src) != REG_FILE_A ||
137                 EncodingHelper::GetSrcArchRegType(src) != ARCH_REG_FILE_NULL)
138             {
139                 if (EncodingHelper::GetSrcAddrMode(src) == ADDR_MODE_IMMED)
140                 {
141                     if (!src->isSrcRegRegion() ||
142                         src->asSrcRegRegion()->getSubRegOff() != (short)UNDEFINED_SHORT)
143                     {
144                         valid = true;
145                     }
146                 }
147             }
148 
149             return valid;
150         }
151 
GetSrcArchRegType(G4_Operand * opnd)152         static inline uint32_t GetSrcArchRegType(G4_Operand *opnd)
153         {
154             if (opnd->isSrcRegRegion())
155             {
156                 G4_VarBase *base = opnd->asSrcRegRegion()->getBase();
157 
158                 if (base->isRegVar())
159                 {
160                     G4_VarBase *preg = base->asRegVar()->getPhyReg();
161                     return EncodingHelper::GetArchRegType(preg);
162                 }
163                 else
164                 {
165                     return EncodingHelper::GetArchRegType(base);
166                 }
167             }
168 
169             return ARCH_REG_FILE_NULL;
170         }
171 
GetSrcChannelSelectValue(G4_SrcRegRegion * srcRegion,int i)172         static inline ChanSel GetSrcChannelSelectValue(G4_SrcRegRegion *srcRegion, int i)
173         {
174             ChanSel ChanSelectValue = CHAN_SEL_UNDEF;
175 
176             const char *swizzle = srcRegion->getSwizzle();
177 
178             if (i < NUM_REGISTER_CHANNELS) {
179                 switch (swizzle[i])        {
180                 case 'x':
181                     ChanSelectValue = CHAN_SEL_X;
182                     break;
183                 case 'y':
184                     ChanSelectValue = CHAN_SEL_Y;
185                     break;
186                 case 'z':
187                     ChanSelectValue = CHAN_SEL_Z;
188                     break;
189                 case 'w':
190                     ChanSelectValue = CHAN_SEL_W;
191                     break;
192                 }
193             }
194             return ChanSelectValue;
195         }
196 
GetRepControl(G4_Operand * src)197         static inline bool GetRepControl(G4_Operand *src)
198         {
199             if (src->isSrcRegRegion())
200             {
201                 const char *swizzle = src->asSrcRegRegion()->getSwizzle();
202                 if (swizzle[0] != '\0')
203                 {
204                     if (swizzle[0] == 'r')
205                     {
206                         return true;
207                     }
208                 }
209             }
210             return false;
211         }
212 
213     };
214 
215     //===----------------------------------------------------------------------===//
216     /// \brief Binary instruction wrapper
217     ///
218     class BinInst
219     {
220     private:
221         bool is3Src;
222     public:
223         // constructor: initializing to be 0
224         union {
225             uint32_t DWords[DWORDS_PER_INST];
226             char     Bytes[BYTES_PER_INST];
227         };
228         uint32_t localInstNumber; // Instruction's position within the BB
229         uint32_t instNumber;      // Global instruction number
230         bool compacted = false;
231 
232         uint64_t genOffset;
233 
BinInst()234         BinInst()
235         {
236             DWords[0] = 0;
237             DWords[1] = 0;
238             DWords[2] = 0;
239             DWords[3] = 0;
240             is3Src = false;
241             localInstNumber = 0;
242             instNumber = 0;
243         }
244 
new(size_t sz,Mem_Manager & m)245     void *operator new(size_t sz, Mem_Manager& m) {return m.alloc(sz);}
246 
GetBits(const int HighBit,const int LowBit)247     inline uint32_t GetBits(const int HighBit, const int LowBit)
248     {
249         MUST_BE_TRUE(HighBit >= LowBit, "high bit must be >= low bit");
250 
251         int retValue;
252         int HighDword = HighBit / BITS_PER_DWORD;
253         int LowDword = LowBit / BITS_PER_DWORD;
254         if (HighDword == LowDword)
255         {
256             uint32_t Dword = HighDword;
257             int mask = (int)(0xffffffff >> (32 - (HighBit - LowBit + 1)));
258             uint32_t shift = LowBit - (Dword * BITS_PER_DWORD);
259 
260             retValue = DWords[Dword] >> shift;
261             retValue &= mask;
262         }
263         else
264         {
265             // only allow reading from at most 2 dwords
266             MUST_BE_TRUE(HighDword == LowDword + 1, "can't return > 32 bits");
267             uint32_t shift = LowBit - (LowDword * BITS_PER_DWORD);
268             retValue = DWords[LowDword] >> shift;
269             retValue |= GetBits(HighBit, (LowDword + 1) * BITS_PER_DWORD) << (32 - shift);
270         }
271 
272         return retValue;
273     }
274 
SetBits(const uint32_t HighBit,const uint32_t LowBit,const uint32_t value)275     inline void SetBits(const uint32_t HighBit, const uint32_t LowBit, const uint32_t value)
276     {
277         MUST_BE_TRUE(HighBit >= LowBit, "high bit must be >= low bit");
278         MUST_BE_TRUE(HighBit / BITS_PER_DWORD == LowBit / BITS_PER_DWORD, "function doesn't handle bits crossing dword");
279 
280         uint32_t maxvalue = ((1 << (HighBit - LowBit)) - 1) | (1 << (HighBit - LowBit));
281         uint32_t newvalue = value;
282         newvalue &= maxvalue;
283         uint32_t Dword = HighBit / BITS_PER_DWORD;
284 
285         int mask = (int)(0xffffffff >> (32 - (HighBit - LowBit + 1)));
286         uint32_t shift = LowBit - (Dword * BITS_PER_DWORD);
287         mask <<= shift;
288         DWords[Dword] &= ~mask;
289         DWords[Dword] |= (newvalue << shift);
290     }
291 
SetIs3Src(bool _is3src)292     void SetIs3Src(bool _is3src) { is3Src = _is3src; };
GetIs3Src()293     bool GetIs3Src() { return is3Src; };
294 
295     private:
296         bool dontCompact = false;
297         bool mustCompact = false;
298 
299     public:
SetDontCompactFlag(bool _d)300         void SetDontCompactFlag(bool _d) { dontCompact = _d; };
GetDontCompactFlag()301         bool GetDontCompactFlag() { return dontCompact; };
302 
SetMustCompactFlag(bool _m)303         void SetMustCompactFlag(bool _m) { mustCompact = _m; };
GetMustCompactFlag()304         bool GetMustCompactFlag() { return mustCompact; };
305 
SetInstNumber(uint32_t _n)306         void SetInstNumber(uint32_t _n) { instNumber = _n; };
GetInstNumber()307         uint32_t GetInstNumber() { return instNumber; };
308 
SetGenOffset(uint64_t o)309         void SetGenOffset(uint64_t o) { genOffset = o; }
GetGenOffset()310         uint64_t GetGenOffset() const { return genOffset; }
311 
isInitialized()312         bool isInitialized()
313         {   // not all 0s
314             return (!(DWords[0] == 0 &&
315                 DWords[1] == 0 &&
316                 DWords[2] == 0 &&
317                 DWords[3] == 0));
318         }
319     };
320 }
321 
322 struct DebugFormatHeader
323 {
324     uint32_t  magic;
325     uint16_t stringCount;
326     std::vector<std::string> strings;
327     uint16_t offset;
328 };
329 
330 namespace vISA
331 {
332     class DebugInfoFormat
333     {
334     private:
335         std::string   m_kernelName;
336         mutable int m_kernelNameIntern;
337         int      m_cisaOffset;
338         uint64_t m_genOffset;
339 
340     public:
DebugInfoFormat(std::string kernelName,int cisaOffset,uint64_t genOffset)341         DebugInfoFormat(std::string kernelName, int cisaOffset, uint64_t genOffset) :
342             m_kernelName(kernelName),
343             m_kernelNameIntern(-1),
344             m_cisaOffset(cisaOffset),
345             m_genOffset(genOffset)
346         {
347 
348         }
349 
~DebugInfoFormat()350         virtual ~DebugInfoFormat()
351         {
352         }
353 
DebugInfoFormat(DebugInfoFormat const & d)354         DebugInfoFormat(DebugInfoFormat const & d)
355         {
356             m_kernelName = d.getKernelName();
357             m_kernelNameIntern = d.getKernelNameIntern();
358             m_cisaOffset = d.getCisaOffset();
359             m_genOffset = d.getGenOffset();
360         }
361 
362         DebugInfoFormat& operator= (const DebugInfoFormat& rhs)
363         {
364             m_kernelName = rhs.getKernelName();
365             m_kernelNameIntern = rhs.getKernelNameIntern();
366             m_cisaOffset = rhs.getCisaOffset();
367             m_genOffset = rhs.getGenOffset();
368 
369             return *this;
370         }
371 
getKernelName()372         std::string   getKernelName() const { return m_kernelName; }
getKernelNameIntern()373         int      getKernelNameIntern() const { return m_kernelNameIntern; }
getCisaOffset()374         int      getCisaOffset() const { return m_cisaOffset; }
getGenOffset()375         uint64_t getGenOffset() const { return m_genOffset; }
376 
setKernelNameIntern(int intern)377         void setKernelNameIntern(int intern) const { m_kernelNameIntern = intern; };
378     };
379 }
380 
381 
382 /* A list of binary instructions */
383 /* FIX ME: delete each binary instruction inside BinInstList at the end*/
384 namespace vISA
385 {
386 class BinInstList : public std::vector<BinInst *> {};
387 }
388 
389 //===----------------------------------------------------------------------===//
390 /// \brief Common base class for binary encoders
391 ///
392 
393 //===----------------------------------------------------------------------===//
394 /// \brief common IVB compaction source table
395 ///
396 
397 const uint32_t COMPACT_TABLE_SIZE = 32;
398 const uint32_t COMPACT_TABLE_SIZE_3SRC = 4;
399 
400 static uint32_t IVBCompactControlTable[COMPACT_TABLE_SIZE]=
401 {
402     0x00000002, //000,0000,0000,0000,0010
403     0x00004000, //000,0100,0000,0000,0000
404     0x00004001, //000,0100,0000,0000,0001
405     0x00004002, //000,0100,0000,0000,0010
406     0x00004003, //000,0100,0000,0000,0011
407     0x00004004, //000,0100,0000,0000,0100
408     0x00004005, //000,0100,0000,0000,0101
409     0x00004007, //000,0100,0000,0000,0111
410     0x00004008, //000,0100,0000,0000,1000
411     0x00004009, //000,0100,0000,0000,1001
412     0x0000400D, //000,0100,0000,0000,1101
413     0x00006000, //000,0110,0000,0000,0000
414     0x00006001, //000,0110,0000,0000,0001
415     0x00006002, //000,0110,0000,0000,0010
416     0x00006003, //000,0110,0000,0000,0011
417     0x00006004, //000,0110,0000,0000,0100
418     0x00006005, //000,0110,0000,0000,0101
419     0x00006007, //000,0110,0000,0000,0111
420     0x00006009, //000,0110,0000,0000,1001
421     0x0000600D, //000,0110,0000,0000,1101
422     0x00006010, //000,0110,0000,0001,0000
423     0x00006100, //000,0110,0001,0000,0000
424     0x00008000, //000,1000,0000,0000,0000
425     0x00008002, //000,1000,0000,0000,0010
426     0x00008004, //000,1000,0000,0000,0100
427     0x00008100, //000,1000,0001,0000,0000
428     0x00016000, //001,0110,0000,0000,0000
429     0x00016010, //001,0110,0000,0001,0000
430     0x00018000, //001,1000,0000,0000,0000
431     0x00018100, //001,1000,0001,0000,0000
432     0x00028000, //010,1000,0000,0000,0000
433     0x00028100  //010,1000,0001,0000,0000
434 };
435 
436 static uint32_t IVBCompactSourceTable[COMPACT_TABLE_SIZE]=
437 {
438     0x00000000, //000000000000
439     0x00000002, //000000000010
440     0x00000010, //000000010000
441     0x00000012, //000000010010
442     0x00000018, //000000011000
443     0x00000020, //000000100000
444     0x00000028, //000000101000
445     0x00000048, //000001001000
446     0x00000050, //000001010000
447     0x00000070, //000001110000
448     0x00000078, //000001111000
449     0x00000300, //001100000000
450     0x00000302, //001100000010
451     0x00000308, //001100001000
452     0x00000310, //001100010000
453     0x00000312, //001100010010
454     0x00000320, //001100100000
455     0x00000328, //001100101000
456     0x00000338, //001100111000
457     0x00000340, //001101000000
458     0x00000342, //001101000010
459     0x00000348, //001101001000
460     0x00000350, //001101010000
461     0x00000360, //001101100000
462     0x00000368, //001101101000
463     0x00000370, //001101110000
464     0x00000371, //001101110001
465     0x00000378, //001101111000
466     0x00000468, //010001101000
467     0x00000469, //010001101001
468     0x0000046A, //010001101010
469     0x00000588  //010110001000
470 };
471 
472 static uint32_t IVBCompactSubRegTable[COMPACT_TABLE_SIZE]=
473 {
474     0x00000000, //000,0000,0000,0000
475     0x00000001, //000,0000,0000,0001
476     0x00000008, //000,0000,0000,1000
477     0x0000000F, //000,0000,0000,1111
478     0x00000010, //000,0000,0001,0000
479     0x00000080, //000,0000,1000,0000
480     0x00000100, //000,0001,0000,0000
481     0x00000180, //000,0001,1000,0000
482     0x00000200, //000,0010,0000,0000
483     0x00000210, //000,0010,0001,0000
484     0x00000280, //000,0010,1000,0000
485     0x00001000, //001,0000,0000,0000
486     0x00001001, //001,0000,0000,0001
487     0x00001081, //001,0000,1000,0001
488     0x00001082, //001,0000,1000,0010
489     0x00001083, //001,0000,1000,0011
490     0x00001084, //001,0000,1000,0100
491     0x00001087, //001,0000,1000,0111
492     0x00001088, //001,0000,1000,1000
493     0x0000108E, //001,0000,1000,1110
494     0x0000108F, //001,0000,1000,1111
495     0x00001180, //001,0001,1000,0000
496     0x000011E8, //001,0001,1110,1000
497     0x00002000, //010,0000,0000,0000
498     0x00002180, //010,0001,1000,0000
499     0x00003000, //011,0000,0000,0000
500     0x00003C87, //011,1100,1000,0111
501     0x00004000, //100,0000,0000,0000
502     0x00005000, //101,0000,0000,0000
503     0x00006000, //110,0000,0000,0000
504     0x00007000, //111,0000,0000,0000
505     0x0000701C  //111,0000,0001,1100
506 };
507 static uint32_t IVBCompactDataTypeTable[COMPACT_TABLE_SIZE]=
508 {
509     0x00008001, //00,1000,0000,0000,0001
510     0x00008020, //00,1000,0000,0010,0000
511     0x00008021, //00,1000,0000,0010,0001
512     0x00008061, //00,1000,0000,0110,0001
513     0x000080BD, //00,1000,0000,1011,1101
514     0x000082FD, //00,1000,0010,1111,1101
515     0x000083A1, //00,1000,0011,1010,0001
516     0x000083A5, //00,1000,0011,1010,0101
517     0x000083BD, //00,1000,0011,1011,1101
518     0x00008421, //00,1000,0100,0010,0001
519     0x00008C20, //00,1000,1100,0010,0000
520     0x00008C21, //00,1000,1100,0010,0001
521     0x000094A5, //00,1001,0100,1010,0101
522     0x00009CA4, //00,1001,1100,1010,0100
523     0x00009CA5, //00,1001,1100,1010,0101
524     0x0000F3BD, //00,1111,0011,1011,1101
525     0x0000F79D, //00,1111,0111,1001,1101
526     0x0000F7BC, //00,1111,0111,1011,1100
527     0x0000F7BD, //00,1111,0111,1011,1101
528     0x0000FFBC, //00,1111,1111,1011,1100
529     0x0000020C, //00,0000,0010,0000,1100
530     0x0000803D, //00,1000,0000,0011,1101
531     0x000080A5, //00,1000,0000,1010,0101
532     0x00008420, //00,1000,0100,0010,0000
533     0x000094A4, //00,1001,0100,1010,0100
534     0x00009C84, //00,1001,1100,1000,0100
535     0x0000A509, //00,1010,0101,0000,1001
536     0x0000DFBD, //00,1101,1111,1011,1101
537     0x0000FFBD, //00,1111,1111,1011,1101
538     0x0000BDAC, //00,1011,1101,1010,1100
539     0x0000A528, //00,1010,0101,0010,1000
540     0x0000AD28  //00,1010,1101,0010,100
541 };
542 
543 // DataTypeIndex Compact Instruction Field Mappings 1/2 Source Operands DevBDW
544 // DataTypeIndex 21-Bit Mapping Mapped Meaning
545 
546 static uint32_t BDWCompactDataTypeTable[COMPACT_TABLE_SIZE]=
547 {
548     0x00040001, //001000000000000000001
549     0x00040040, //001000000000001000000
550     0x00040041, //001000000000001000001
551     0x000400C1, //001000000000011000001
552     0x0004015D, //001000000000101011101
553     0x000405DD, //001000000010111011101
554     0x00040741, //001000000011101000001
555     0x00040745, //001000000011101000101
556     0x0004075D, //001000000011101011101
557     0x00041041, //001000001000001000001
558     0x00043040, //001000011000001000000
559     0x00043041, //001000011000001000001
560     0x00045145, //001000101000101000101
561     0x00047144, //001000111000101000100
562     0x00047145, //001000111000101000101
563     0x0005C75D, //001011100011101011101
564     0x0005D71D, //001011101011100011101
565     0x0005D75C, //001011101011101011100
566     0x0005D75D, //001011101011101011101
567     0x0005F75C, //001011111011101011100
568     0x0000040C, //000000000010000001100
569     0x0004005D, //001000000000001011101
570     0x00040145, //001000000000101000101
571     0x00041040, //001000001000001000000
572     0x00045144, //001000101000101000100
573     0x00047104, //001000111000100000100
574     0x00049209, //001001001001000001001
575     0x0005775D, //001010111011101011101
576     0x0005F75D, //001011111011101011101
577     0x0004F34C, //001001111001101001100
578     0x00049248, //001001001001001001000
579     0x0004B248, //001001011001001001000
580 };
581 
582 static uint32_t ICLCompactDataTypeTable[COMPACT_TABLE_SIZE] =
583 {
584     0x40001, // 001000000000000000001
585     0x40040, // 001000000000001000000
586     0x40041, // 001000000000001000001
587     0x400C1, // 001000000000011000001
588     0x40165, // 001000000000101100101
589     0x40BE5, // 001000000101111100101
590     0x40941, // 001000000100101000001
591     0x40945, // 001000000100101000101
592     0x40965, // 001000000100101100101
593     0x41041, // 001000001000001000001
594     0x43040, // 001000011000001000000
595     0x43041, // 001000011000001000001
596     0x45145, // 001000101000101000101
597     0x47144, // 001000111000101000100
598     0x47145, // 001000111000101000101
599     0x64965, // 001100100100101100101
600     0x65925, // 001100101100100100101
601     0x65964, // 001100101100101100100
602     0x65965, // 001100101100101100101
603     0x67964, // 001100111100101100100
604     0x0040C, // 000000000010000001100
605     0x40065, // 001000000000001100101
606     0x40145, // 001000000000101000101
607     0x41040, // 001000001000001000000
608     0x45144, // 001000101000101000100
609     0x47104, // 001000111000100000100
610     0x49209, // 001001001001000001001
611     0x6F965, // 001101111100101100101
612     0x67965, // 001100111100101100101
613     0x4F34C, // 001001111001101001100
614     0x49248, // 001001001001001001000
615     0x4B248, // 001001011001001001000
616 };
617 
618 // ControlIndex Compact Instruction Field Mappings 3 Source Operands BDW/CHV
619 static uint32_t BDWCompactControlTable3Src[COMPACT_TABLE_SIZE_3SRC]=
620 {
621     0x00806001, //100000000110000000000001
622     0x00006001, //000000000110000000000001
623     0x00008001, //000000001000000000000001
624     0x00008021, //000000001000000000100001
625 };
626 
627 // SourceIndex Compact Instruction Field Mappings 3 Source Operands BDW/CHV
628 static uint64_t BDWCompactSourceTable3Src[COMPACT_TABLE_SIZE_3SRC]=
629 {
630     0x07272720F000, //0001110010011100100111001000001111000000000000
631     0x07272720F002, //0001110010011100100111001000001111000000000010
632     0x07272720F008, //0001110010011100100111001000001111000000001000
633     0x07272720F020, //0001110010011100100111001000001111000000100000
634 };
635 
636 static struct _CompactDataTypeTable_
637 {
638     union Data
639     {
640         struct
641         {
642             uint32_t Bits_046_032 : 15;
643             uint32_t Bits_063_061 :  3;
644             uint32_t Reserved     : 14;
645         } sData;
646         uint32_t ulData;
647     };
648 
GetBits_063_061_CompactDataTypeTable_649     uint32_t GetBits_063_061(uint32_t index)
650     {
651         MUST_BE_TRUE(index < COMPACT_TABLE_SIZE, "Out of Control Bit Datatype Table range.");
652         Data data;
653         data.ulData = Values[index];
654         return data.sData.Bits_063_061;
655     }
656 
GetBits_046_032_CompactDataTypeTable_657     uint32_t GetBits_046_032(uint32_t index)
658     {
659         MUST_BE_TRUE(index < COMPACT_TABLE_SIZE, "Out of Control Bit Datatype Table range.");
660         Data data;
661         data.ulData = Values[index];
662         return data.sData.Bits_046_032;
663     }
664 
FindIndex_CompactDataTypeTable_665     bool FindIndex(uint32_t &index,
666         uint32_t bits_063_061,
667         uint32_t bits_046_032)
668     {
669         for (index = 0; index < COMPACT_TABLE_SIZE; ++index)
670         {
671             Data data;
672             data.ulData = Values[index];
673             if (data.sData.Bits_063_061 == bits_063_061 &&
674                 data.sData.Bits_046_032 == bits_046_032)
675             {
676                 return true;
677             }
678         }
679         return false;
680     }
681 
682     uint32_t Values[COMPACT_TABLE_SIZE];
683 } CompactDataTypeTable;
684 
685 static struct _CompactSubRegTable_
686 {
687     union Data
688     {
689         struct
690         {
691             uint32_t Bits_052_048 :  5;
692             uint32_t Bits_068_064 :  5;
693             uint32_t Bits_100_096 :  5;
694             uint32_t Reserved     : 17;
695         } sData;
696         uint32_t ulData;
697     };
698 
GetBits_100_096_CompactSubRegTable_699     uint32_t GetBits_100_096(uint32_t index)
700     {
701         MUST_BE_TRUE(index < COMPACT_TABLE_SIZE, "Out of Control Bit Subreg Table range.");
702         Data data;
703         data.ulData = Values[index];
704         return data.sData.Bits_100_096;
705     }
706 
GetBits_068_064_CompactSubRegTable_707     uint32_t GetBits_068_064(uint32_t index)
708     {
709         MUST_BE_TRUE(index < COMPACT_TABLE_SIZE, "Out of Control Bit Subreg Table range.");
710         Data data;
711         data.ulData = Values[index];
712         return data.sData.Bits_068_064;
713     }
714 
GetBits_052_048_CompactSubRegTable_715     uint32_t GetBits_052_048(uint32_t index)
716     {
717         MUST_BE_TRUE(index < COMPACT_TABLE_SIZE, "Out of Control Bit Subreg Table range.");
718         Data data;
719         data.ulData = Values[index];
720         return data.sData.Bits_052_048;
721     }
722 
FindIndex_CompactSubRegTable_723     bool FindIndex(uint32_t &index,
724         uint32_t bits_100_096,
725         uint32_t bits_068_064,
726         uint32_t bits_052_048)
727     {
728         for (index = 0; index < COMPACT_TABLE_SIZE; ++index)
729         {
730             Data data;
731             data.ulData = Values[index];
732             if (data.sData.Bits_100_096 == bits_100_096 &&
733                 data.sData.Bits_068_064 == bits_068_064 &&
734                 data.sData.Bits_052_048 == bits_052_048)
735             {
736                 return true;
737             }
738         }
739         return false;
740     }
741 
HasMatch_CompactSubRegTable_742     bool HasMatch(uint32_t &index, uint32_t bits_100_096, uint32_t bits_068_064, uint32_t bits_052_048, unsigned int match_mask)
743     {
744         bool match[3];
745         match[0] = (match_mask & 0x1) == 0x1;
746         match[1] = (match_mask & 0x2) == 0x2;
747         match[2] = (match_mask & 0x4) == 0x4;
748 
749         for (index = 0; index < COMPACT_TABLE_SIZE; ++index)
750         {
751             Data data;
752             data.ulData = Values[index];
753             bool found[3] = {false, false, false};
754 
755             for (int i =0;i<3;i++)
756             {
757                 if (!match[i])
758                     found[i] = true;
759             }
760 
761             if (match[0] && (data.sData.Bits_052_048 == bits_052_048))
762             {
763                 found[0] = true;
764             }
765 
766             if (match[1] && (data.sData.Bits_068_064 == bits_068_064))
767             {
768                 found[1] = true;
769             }
770 
771             if (match[2] && (data.sData.Bits_100_096 == bits_100_096))
772             {
773                 found[2] = true;
774             }
775 
776             if (found[0] && found[1] && found[2])
777                 return true;
778         }
779 
780         return false;
781     }
782 
783     uint32_t Values[COMPACT_TABLE_SIZE];
784 } CompactSubRegTable;
785 
786 static struct _CompactSourceTable_
787 {
GetBits_120_109_CompactSourceTable_788     uint32_t GetBits_120_109(uint32_t index)
789     {
790         MUST_BE_TRUE(index < COMPACT_TABLE_SIZE, "Out of Control Bit Source Table range.");
791         return Values[index];
792     }
793 
GetBits_088_077_CompactSourceTable_794     uint32_t GetBits_088_077(uint32_t index)
795     {
796         MUST_BE_TRUE(index < COMPACT_TABLE_SIZE, "Out of Control Bit Source Table range.");
797         return Values[index];
798     }
799 
FindIndex_CompactSourceTable_800     bool FindIndex(uint32_t &index, uint32_t bits)
801     {
802         for (index = 0; index < COMPACT_TABLE_SIZE; ++index)
803         {
804             if (Values[index] == bits)
805             {
806                 return true;
807             }
808         }
809         return false;
810     }
811 
812     uint32_t Values[COMPACT_TABLE_SIZE];
813 } CompactSourceTable;
814 
815 namespace vISA
816 {
817     class _BDWCompactControlTable_
818     {
819         const static unsigned maxEntry = 111;
820     Mem_Manager& mem;
821 
822         struct HashNode
823         {
824             uint32_t key;
825             uint8_t  idx;
826             HashNode* next;
827 
HashNodeHashNode828             HashNode(uint32_t k, uint8_t i, HashNode *nxt) : key(k), idx(i), next(nxt) {}
newHashNode829         void *operator new(size_t sz, Mem_Manager& m) {return m.alloc(sz);}
830         };
831 
832         HashNode* table[maxEntry];
833 
FindEntry(uint32_t key)834         unsigned FindEntry(uint32_t key)
835         {
836             return key % maxEntry;
837             // return (key & 0xF) | (key >> 9);
838         }
839 
840     public:
841 
_BDWCompactControlTable_(Mem_Manager & m)842     _BDWCompactControlTable_ (Mem_Manager& m) : mem(m)
843         {
844             for (unsigned i = 0; i < maxEntry; i++)
845                 table[i] = NULL;
846         }
847 
FindIndex(uint32_t & index,uint32_t bits_033_032,uint32_t bits_031_031,uint32_t bits_023_012,uint32_t bits_010_009,uint32_t bits_034_034,uint32_t bits_008_008)848         bool FindIndex(uint32_t &index,
849             uint32_t bits_033_032,
850             uint32_t bits_031_031,
851             uint32_t bits_023_012,
852             uint32_t bits_010_009,
853             uint32_t bits_034_034,
854             uint32_t bits_008_008)
855         {
856             uint32_t i = bits_008_008 |
857                 (bits_034_034 << 1) |
858                 (bits_010_009 << 2) |
859                 (bits_023_012 << 4) |
860                 (bits_031_031 << 16) |
861                 (bits_033_032 << 17);
862             for (HashNode* n = table[FindEntry(i)]; n != NULL; n = n->next)
863             {
864                 if (n->key == i)
865                 {
866                     index = n->idx;
867                     return true;
868                 }
869             }
870             return false;
871         }
872 
AddIndex(uint32_t key,uint8_t idx)873         void AddIndex(uint32_t key, uint8_t idx)
874         {
875             int entry = FindEntry(key);
876             table[entry] = new (mem)HashNode(key, idx, table[entry]);
877         }
878     };
879 
880     class _BDWCompactSourceTable_
881     {
882         const static unsigned maxEntry = 61;
883     Mem_Manager& mem;
884 
885         struct HashNode
886         {
887             uint32_t key;
888             uint8_t  idx;
889             HashNode* next;
890 
HashNodeHashNode891             HashNode(uint32_t k, uint8_t i, HashNode *nxt) : key(k), idx(i), next(nxt) {}
newHashNode892         void *operator new(size_t sz, Mem_Manager& m) {return m.alloc(sz);}
893         };
894 
895         HashNode* table[maxEntry];
896 
FindEntry(uint32_t key)897         unsigned FindEntry(uint32_t key)
898         {
899             return key % maxEntry;
900             //return (key & 0x3) | ((key & 0x3f8) >> 1);
901         }
902 
903     public:
904 
_BDWCompactSourceTable_(Mem_Manager & m)905         _BDWCompactSourceTable_(Mem_Manager& m) : mem(m)
906         {
907             for (unsigned i = 0; i < maxEntry; i++)
908                 table[i] = NULL;
909         }
910 
FindIndex(uint32_t & index,uint32_t bits)911         bool FindIndex(uint32_t& index, uint32_t bits)
912         {
913             for (HashNode* n = table[FindEntry(bits)]; n != NULL; n = n->next)
914             {
915                 if (n->key == bits)
916                 {
917                     index = n->idx;
918                     return true;
919                 }
920             }
921             return false;
922         }
923 
AddIndex(uint32_t key,uint8_t idx)924         void AddIndex(uint32_t key, uint8_t idx)
925         {
926             int entry = FindEntry(key);
927             table[entry] = new (mem)HashNode(key, idx, table[entry]);
928         }
929 
GetBits_120_109(uint32_t index)930         uint32_t GetBits_120_109(uint32_t index)
931         {
932             return IVBCompactSourceTable[index];
933         }
934 
GetBits_088_077(uint32_t index)935         uint32_t GetBits_088_077(uint32_t index)
936         {
937             return IVBCompactSourceTable[index];
938         }
939     };
940 
941     class _BDWCompactSubRegTable_
942     {
943         const static unsigned maxEntry = 37;
944         const static unsigned maxEntry1 = 37;
945         const static unsigned maxEntry2 = 37;
946 
947     Mem_Manager& mem;
948 
949         struct HashNode
950         {
951             uint32_t key;
952             uint8_t  idx;
953             HashNode* next;
954 
HashNodeHashNode955             HashNode(uint32_t k, uint8_t i, HashNode *nxt) : key(k), idx(i), next(nxt) {}
newHashNode956         void *operator new(size_t sz, Mem_Manager& m) {return m.alloc(sz);}
957         };
958 
959         HashNode* table[maxEntry];
960         HashNode* table1[maxEntry1];
961         HashNode* table2[maxEntry2];
962 
FindEntry(uint32_t key)963         unsigned FindEntry(uint32_t key)
964         {
965             return key % maxEntry;
966             //return (key >> 12) | ((key & 0xF) << 3) | (key & 0x380) ;
967         }
968 
FindEntry1(uint32_t key)969         unsigned FindEntry1(uint32_t key)
970         {
971             return key % maxEntry1;
972         }
973 
FindEntry2(uint32_t key)974         unsigned FindEntry2(uint32_t key)
975         {
976             return key % maxEntry2;
977         }
978 
979     public:
980 
_BDWCompactSubRegTable_(Mem_Manager & m)981     _BDWCompactSubRegTable_ (Mem_Manager& m) : mem(m)
982         {
983             for (unsigned i = 0; i < maxEntry; i++)
984             {
985                 table[i] = table1[i] = table2[i] = NULL;
986             }
987         }
988 
FindIndex(uint32_t & index,uint32_t bits_100_096,uint32_t bits_068_064,uint32_t bits_052_048)989         bool FindIndex(uint32_t &index,
990             uint32_t bits_100_096,
991             uint32_t bits_068_064,
992             uint32_t bits_052_048)
993         {
994             uint32_t i = bits_052_048 |
995                 (bits_068_064 << 5) |
996                 (bits_100_096 << 10);
997             for (HashNode* n = table[FindEntry(i)]; n != NULL; n = n->next)
998             {
999                 if (n->key == i)
1000                 {
1001                     index = n->idx;
1002                     return true;
1003                 }
1004             }
1005             return false;
1006         }
1007 
FindIndex1(uint32_t & index,uint32_t bits_052_048)1008         bool FindIndex1(uint32_t &index,
1009             uint32_t bits_052_048)
1010         {
1011             for (HashNode* n = table1[FindEntry1(bits_052_048)]; n != NULL; n = n->next)
1012             {
1013                 if (n->key == bits_052_048)
1014                 {
1015                     index = n->idx;
1016                     return true;
1017                 }
1018             }
1019             return false;
1020         }
1021 
FindIndex2(uint32_t & index,uint32_t bits_068_064,uint32_t bits_052_048)1022         bool FindIndex2(uint32_t &index,
1023             uint32_t bits_068_064,
1024             uint32_t bits_052_048)
1025         {
1026             uint32_t i = bits_052_048 |
1027                 (bits_068_064 << 5);
1028             for (HashNode* n = table2[FindEntry2(i)]; n != NULL; n = n->next)
1029             {
1030                 if (n->key == i)
1031                 {
1032                     index = n->idx;
1033                     return true;
1034                 }
1035             }
1036             return false;
1037         }
1038 
AddIndex(uint32_t key,uint8_t idx)1039         void AddIndex(uint32_t key, uint8_t idx)
1040         {
1041             int entry = FindEntry(key);
1042             table[entry] = new (mem)HashNode(key, idx, table[entry]);
1043         }
1044 
AddIndex1(uint32_t key,uint8_t idx)1045         void AddIndex1(uint32_t key, uint8_t idx)
1046         {
1047             int entry = FindEntry1(key);
1048             HashNode* n = table1[entry];
1049             for (; n != NULL; n = n->next)
1050             {
1051                 if (n->key == key)
1052                 {
1053                     break;
1054                 }
1055             }
1056             if (n == NULL)
1057             {
1058                 table1[entry] = new (mem)HashNode(key, idx, table1[entry]);
1059             }
1060         }
1061 
AddIndex2(uint32_t key,uint8_t idx)1062         void AddIndex2(uint32_t key, uint8_t idx)
1063         {
1064             int entry = FindEntry2(key);
1065             HashNode* n = table2[entry];
1066             for (; n != NULL; n = n->next)
1067             {
1068                 if (n->key == key)
1069                 {
1070                     break;
1071                 }
1072             }
1073             if (n == NULL)
1074             {
1075                 table2[entry] = new (mem)HashNode(key, idx, table2[entry]);
1076             }
1077         }
1078 
GetBits_100_096(uint32_t index)1079         uint32_t GetBits_100_096(uint32_t index)
1080         {
1081             return IVBCompactSubRegTable[index] >> 10;
1082         }
1083 
GetBits_068_064(uint32_t index)1084         uint32_t GetBits_068_064(uint32_t index)
1085         {
1086             return (IVBCompactSubRegTable[index] & 0x000003E0) >> 5;
1087         }
1088 
GetBits_052_048(uint32_t index)1089         uint32_t GetBits_052_048(uint32_t index)
1090         {
1091             return IVBCompactSubRegTable[index] & 0x0000001F;
1092         }
1093 
1094     };
1095 
1096     // add Str in below struct to differentiate its loop up table
1097     class _BDWCompactDataTypeTableStr_
1098     {
1099         const static unsigned maxEntry = 111;
1100     Mem_Manager& mem;
1101 
1102         struct HashNode
1103         {
1104             uint32_t key;
1105             uint8_t  idx;
1106             HashNode* next;
1107 
HashNodeHashNode1108             HashNode(uint32_t k, uint8_t i, HashNode *nxt) : key(k), idx(i), next(nxt) {}
newHashNode1109         void *operator new(size_t sz, Mem_Manager& m) {return m.alloc(sz);}
1110         };
1111 
1112         HashNode* table[maxEntry];
1113 
FindEntry(uint32_t key)1114         unsigned FindEntry(uint32_t key)
1115         {
1116             return key % maxEntry;
1117             //return ((key & 0x3FC) >> 2) | ((key & 0x3000) >> 4);
1118         }
1119 
1120     public:
1121 
_BDWCompactDataTypeTableStr_(Mem_Manager & m)1122     _BDWCompactDataTypeTableStr_ (Mem_Manager& m) : mem(m)
1123         {
1124             for (unsigned i = 0; i < maxEntry; i++)
1125                 table[i] = NULL;
1126         }
1127 
FindIndex(uint32_t & index,uint32_t bits_063_061,uint32_t bits_094_089,uint32_t bits_046_035)1128         bool FindIndex(uint32_t &index,
1129             uint32_t bits_063_061,
1130             uint32_t bits_094_089,
1131             uint32_t bits_046_035)
1132         {
1133             uint32_t i = 0;
1134             i = bits_046_035 |
1135                 (bits_094_089 << 12) |
1136                 (bits_063_061 << 18);
1137             for (HashNode* n = table[FindEntry(i)]; n != NULL; n = n->next)
1138             {
1139                 if (n->key == i)
1140                 {
1141                     index = n->idx;
1142                     return true;
1143                 }
1144             }
1145             return false;
1146         }
1147 
AddIndex(uint32_t key,uint8_t idx)1148         void AddIndex(uint32_t key, uint8_t idx)
1149         {
1150             int entry = FindEntry(key);
1151             table[entry] = new (mem)HashNode(key, idx, table[entry]);
1152         }
1153 
1154     };
1155 }
1156 extern unsigned long bitsSrcRegFile[4];// = {128, 128, 128, 128};
1157 extern unsigned long bits3SrcFlagRegNum[2];// = {128, 128};
1158 extern unsigned long bitsFlagRegNum[2];// = {128, 128};
1159 
1160 #define SET_BIT_RANGE(field, high, low) \
1161     (field)[0] = high;  \
1162     (field)[1] = low;
1163 
1164 #define SET_BIT_RANGES(field, high1, low1, high2, low2) \
1165     (field)[0] = high1;  \
1166     (field)[1] = low1;   \
1167     (field)[2] = high2;  \
1168     (field)[3] = low2;
1169 
1170 // below are extended for BDW/CHV compaction
1171 namespace vISA
1172 {
1173     class _CompactControl3Src_
1174     {
1175         uint32_t Values[COMPACT_TABLE_SIZE_3SRC];
1176         union Data
1177         {
1178             struct
1179             {
1180                 uint32_t Bits_028_008 : 21;
1181                 uint32_t Bits_034_032 : 3;
1182                 // bits 36-35 are only for CHV, reserved for BDW
1183                 uint32_t Bits_036_035 : 2;
1184                 uint32_t Reserved : 6;
1185             } sData;
1186             uint32_t ulData;
1187         };
1188 
GetBit_028_008(uint32_t index)1189         uint32_t GetBit_028_008(uint32_t index)
1190         {
1191             MUST_BE_TRUE(index < COMPACT_TABLE_SIZE_3SRC, "Out of Control Bit Compact Table range.");
1192             Data data;
1193             data.ulData = Values[index];
1194             return data.sData.Bits_028_008;
1195         }
1196 
GetBits_034_032(uint32_t index)1197         uint32_t GetBits_034_032(uint32_t index)
1198         {
1199             MUST_BE_TRUE(index < COMPACT_TABLE_SIZE_3SRC, "Out of Control Bit Compact Table range.");
1200             Data data;
1201             data.ulData = Values[index];
1202             return data.sData.Bits_034_032;
1203         }
1204 
GetBits_036_035(uint32_t index)1205         uint32_t GetBits_036_035(uint32_t index)
1206         {
1207             MUST_BE_TRUE(index < COMPACT_TABLE_SIZE_3SRC, "Out of Control Bit Compact Table range.");
1208             Data data;
1209             data.ulData = Values[index];
1210             return data.sData.Bits_036_035;
1211         }
1212 
1213     public:
FindBDWIndex(uint32_t & index,uint32_t bits_034_032,uint32_t bits_028_008)1214         bool FindBDWIndex(uint32_t &index,
1215             uint32_t bits_034_032,
1216             uint32_t bits_028_008)
1217         {
1218             for (index = 0; index < COMPACT_TABLE_SIZE_3SRC; ++index)
1219             {
1220                 Data data;
1221                 data.ulData = Values[index];
1222                 if (data.sData.Bits_034_032 == bits_034_032 &&
1223                     data.sData.Bits_028_008 == bits_028_008)
1224                 {
1225                     return true;
1226                 }
1227             }
1228             return false;
1229         }
1230 
FindCHVIndex(uint32_t & index,uint32_t bits_036_035,uint32_t bits_034_032,uint32_t bits_028_008)1231         bool FindCHVIndex(uint32_t &index,
1232             uint32_t bits_036_035,
1233             uint32_t bits_034_032,
1234             uint32_t bits_028_008)
1235         {
1236             for (index = 0; index < COMPACT_TABLE_SIZE_3SRC; ++index)
1237             {
1238                 Data data;
1239                 data.ulData = Values[index];
1240                 if (data.sData.Bits_036_035 == bits_036_035 &&
1241                     data.sData.Bits_034_032 == bits_034_032 &&
1242                     data.sData.Bits_028_008 == bits_028_008)
1243                 {
1244                     return true;
1245                 }
1246             }
1247             return false;
1248         }
1249 
_CompactControl3Src_()1250         _CompactControl3Src_()
1251         {
1252             TARGET_PLATFORM platform = getGenxPlatform();
1253             if (platform == GENX_BDW)
1254             {
1255                 for (int i = 0; i < (int)COMPACT_TABLE_SIZE_3SRC; i++)
1256                 {
1257                     Values[i] = BDWCompactControlTable3Src[i];
1258                 }
1259             }
1260             else if (platform >= GENX_CHV)
1261             {
1262                 // CHV is the same as BDW, except for:
1263                 // -- 2 extra leading bits (00) for the control table (26 v. 24 bits)
1264                 // -- 3 extra leading bits (000) for the source table (49 v. 46 bits)
1265                 // as such, we use the same tables from BDW
1266                 // initialization of 3src compaction table for both CHV and SKL
1267                 for (int i = 0; i < (int)COMPACT_TABLE_SIZE_3SRC; i++)
1268                 {
1269                     Values[i] = BDWCompactControlTable3Src[i];
1270                 }
1271             }
1272         }
1273 
1274     };
1275 
1276     class _CompactSourceTable3Src_
1277     {
1278         uint64_t Values[COMPACT_TABLE_SIZE_3SRC];
1279         union Data
1280         {
1281             struct
1282             {
1283                 // we have to use uint64_t since Bits_093_086 straddles dword
1284                 uint64_t Bits_055_037 : 19;
1285                 uint64_t Bits_072_065 : 8;
1286                 uint64_t Bits_093_086 : 8;
1287                 uint64_t Bits_114_107 : 8;
1288                 uint64_t Bits_083_083 : 1;
1289                 uint64_t Bits_104_104 : 1;
1290                 uint64_t Bits_125_125 : 1;
1291                 uint64_t Reserved : 18;
1292             } sData;
1293             uint64_t ulData;
1294         };
1295     public:
FindIndex(uint32_t & index,uint32_t bits_125_125,uint32_t bits_104_104,uint32_t bits_083_083,uint32_t bits_114_107,uint32_t bits_093_086,uint32_t bits_072_065,uint32_t bits_055_037)1296         bool FindIndex(uint32_t &index,
1297             uint32_t bits_125_125,
1298             uint32_t bits_104_104,
1299             uint32_t bits_083_083,
1300             uint32_t bits_114_107,
1301             uint32_t bits_093_086,
1302             uint32_t bits_072_065,
1303             uint32_t bits_055_037)
1304         {
1305 
1306             for (index = 0; index < COMPACT_TABLE_SIZE_3SRC; ++index)
1307             {
1308                 Data data;
1309                 data.ulData = Values[index];
1310                 if (data.sData.Bits_125_125 == bits_125_125  &&
1311                     data.sData.Bits_104_104 == bits_104_104  &&
1312                     data.sData.Bits_083_083 == bits_083_083  &&
1313                     data.sData.Bits_114_107 == bits_114_107  &&
1314                     data.sData.Bits_093_086 == bits_093_086  &&
1315                     data.sData.Bits_072_065 == bits_072_065  &&
1316                     data.sData.Bits_055_037 == bits_055_037)
1317                 {
1318                     return true;
1319                 }
1320             }
1321             return false;
1322         }
1323 
1324 
_CompactSourceTable3Src_()1325         _CompactSourceTable3Src_()
1326         {
1327             TARGET_PLATFORM platform = getGenxPlatform();
1328             if (platform == GENX_BDW)
1329             {
1330                 for (int i = 0; i < (int)COMPACT_TABLE_SIZE_3SRC; i++)
1331                 {
1332                     Values[i] = BDWCompactSourceTable3Src[i];
1333                 }
1334             }
1335         }
1336     };
1337 
1338     class _CompactSourceTable3SrcCHV_
1339     {
1340     public:
1341         union Data
1342         {
1343             struct
1344             {
1345                 uint64_t Bits_055_037 : 19;
1346                 uint64_t Bits_072_065 : 8;
1347                 uint64_t Bits_093_086 : 8;
1348                 uint64_t Bits_114_107 : 8;
1349                 uint64_t Bits_084_083 : 2;
1350                 uint64_t Bits_105_104 : 2;
1351                 uint64_t Bits_126_125 : 2;
1352                 uint64_t Reserved : 17;
1353             } sData;
1354             uint64_t ulData;
1355         };
1356 
FindIndex(uint32_t & index,uint32_t bits_126_125,uint32_t bits_105_104,uint32_t bits_084_083,uint32_t bits_114_107,uint32_t bits_093_086,uint32_t bits_072_065,uint32_t bits_055_037)1357         bool FindIndex(uint32_t &index,
1358             uint32_t bits_126_125,
1359             uint32_t bits_105_104,
1360             uint32_t bits_084_083,
1361             uint32_t bits_114_107,
1362             uint32_t bits_093_086,
1363             uint32_t bits_072_065,
1364             uint32_t bits_055_037)
1365         {
1366 
1367             for (index = 0; index < COMPACT_TABLE_SIZE_3SRC; ++index)
1368             {
1369                 Data data;
1370                 data.ulData = Values[index];
1371                 if (data.sData.Bits_126_125 == bits_126_125  &&
1372                     data.sData.Bits_105_104 == bits_105_104  &&
1373                     data.sData.Bits_084_083 == bits_084_083  &&
1374                     data.sData.Bits_114_107 == bits_114_107  &&
1375                     data.sData.Bits_093_086 == bits_093_086  &&
1376                     data.sData.Bits_072_065 == bits_072_065  &&
1377                     data.sData.Bits_055_037 == bits_055_037)
1378                 {
1379                     return true;
1380                 }
1381             }
1382             return false;
1383         }
1384 
_CompactSourceTable3SrcCHV_()1385         _CompactSourceTable3SrcCHV_()
1386         {
1387             TARGET_PLATFORM platform = getGenxPlatform();
1388             if (platform >= GENX_CHV)
1389             {
1390                 // CHV is the same as BDW, except for:
1391                 // -- 2 extra leading bits (00) for the control table (26 v. 24 bits)
1392                 // -- 3 extra leading bits (000) for the source table (49 v. 46 bits)
1393                 // as such, we use the same tables from BDW
1394                 // initialization of 3src compaction table for both CHV and SKL
1395                 for (int i = 0; i < (int)COMPACT_TABLE_SIZE_3SRC; i++)
1396                 {
1397                     Values[i] = BDWCompactSourceTable3Src[i];
1398                 }
1399             }
1400         }
1401         uint64_t Values[COMPACT_TABLE_SIZE_3SRC];
1402     };
1403 }
1404 
1405 namespace vISA
1406 {
1407     class BinaryEncodingBase
1408     {
1409     public:
1410         _BDWCompactControlTable_ BDWCompactControlTable;
1411         _BDWCompactSourceTable_ BDWCompactSourceTable;
1412         _BDWCompactSubRegTable_ BDWCompactSubRegTable;
1413         _BDWCompactDataTypeTableStr_ BDWCompactDataTypeTableStr;
1414         _CompactControl3Src_ CompactControlTable3Src;
1415         _CompactSourceTable3Src_ CompactSourceTable3Src;
1416         _CompactSourceTable3SrcCHV_ CompactSourceTable3SrcCHV;
1417 
BinaryEncodingBase(Mem_Manager & m,G4_Kernel & k,std::string fname)1418         BinaryEncodingBase(Mem_Manager &m, G4_Kernel& k, std::string fname)
1419             : BDWCompactControlTable(m),
1420             BDWCompactSourceTable(m),
1421             BDWCompactSubRegTable(m),
1422             BDWCompactDataTypeTableStr(m),
1423             mem(m),
1424             fileName(fname),
1425             kernel(k),
1426             instCounts(0)
1427         {
1428         }
1429 
1430         typedef enum { SUCCESS, FAILURE } Status;
1431 
getBinInstList()1432         BinInstList& getBinInstList() { return binInstList; }
1433 
~BinaryEncodingBase()1434         virtual ~BinaryEncodingBase()
1435         {
1436         }
1437 
1438         bool isBBBinInstEmpty(G4_BB *bb);
1439         G4_INST *getFirstNonLabelInst(G4_BB *bb);
1440 
1441         void BuildLabelMap(G4_INST *, int&, int&, int&, int&);
1442         virtual void SetCompactCtrl(BinInst *mybin, uint32_t value) = 0;
1443         virtual uint32_t GetCompactCtrl(BinInst *mybin) = 0;
1444 
1445         void FixInst();
1446         void FixAlign16Inst(G4_INST* inst);
1447         void FixMathInst(G4_INST* inst);
1448 
1449         void ProduceBinaryBuf(void* &);
1450         void *EmitBinary(uint32_t&);
1451         virtual Status WriteToDatFile();
1452 
1453         virtual void DoAll() = 0;
1454 
1455 
GetInstCounts()1456         uint32_t GetInstCounts() { return instCounts; };
SetInstCounts(uint32_t _i)1457         void SetInstCounts(uint32_t _i) { instCounts = _i; };
1458 
1459         void computeBinaryOffsets();
1460 
1461         bool compactOneInstruction(G4_INST *);
1462         bool BDWcompactOneInstruction(G4_INST *);
1463         bool BDWcompactOneInstruction3Src(G4_INST *);
1464         bool CHVcompactOneInstruction3Src(G4_INST *);
1465         bool uncompactOneInstruction(G4_INST *);
1466 
1467         bool doCompaction() const;
1468 
1469     protected:
1470 
1471         // returns the offset for label in # of half instructions (kernel entry is 0), or -1 if the label is not present
GetLabelInfo(G4_Label * label)1472         uint32_t GetLabelInfo(G4_Label* label)
1473         {
1474             auto iter = LabelMap.find(label);
1475             if (iter == LabelMap.end())
1476             {
1477                 return -1;
1478             }
1479             return iter->second;
1480         }
1481 
1482         Mem_Manager     &mem;     ///< Reference to the memory manager
1483         std::string          fileName; ///< Name of the binary file
1484         G4_Kernel&      kernel;
1485         BinInstList     binInstList; ///< Reference to the binary instructions
1486         std::map<G4_Label*, uint32_t> LabelMap;
1487 
1488         uint32_t        instCounts;
1489 
1490     public:
1491         // all platform specific bit locations are initialized here
InitPlatform()1492         static void InitPlatform()
1493         {
1494             // BDW+ encoding
1495             SET_BIT_RANGE(bitsFlagRegNum, 33, 33);
1496             SET_BIT_RANGE(bits3SrcFlagRegNum, 33, 33);
1497             SET_BIT_RANGES(bitsSrcRegFile, 42, 41, 90, 89);
1498         }
1499 
GetSrc0RegFile(BinInst * mybin)1500         inline uint32_t GetSrc0RegFile(BinInst *mybin)
1501         {
1502             if (mybin->GetIs3Src())
1503                 return REG_FILE_R;
1504             else
1505                 return mybin->GetBits(bitsSrcRegFile[0], bitsSrcRegFile[1]);
1506         }
1507 
GetSrc1RegFile(BinInst * mybin)1508         inline uint32_t GetSrc1RegFile(BinInst *mybin)
1509         {
1510             if (mybin->GetIs3Src())
1511                 return REG_FILE_R;
1512             else
1513                 return mybin->GetBits(bitsSrcRegFile[2], bitsSrcRegFile[3]);
1514         }
GetFlagRegNum(BinInst * mybin)1515         inline uint32_t GetFlagRegNum(BinInst *mybin)
1516         {
1517             if (mybin->GetIs3Src())
1518                 return mybin->GetBits(bits3SrcFlagRegNum[0], bits3SrcFlagRegNum[1]);
1519             else
1520                 return mybin->GetBits(bitsFlagRegNum[0], bitsFlagRegNum[1]);
1521         }
SetFlagRegNum(BinInst * mybin,uint32_t value)1522         inline void SetFlagRegNum(BinInst *mybin, uint32_t value)
1523         {
1524             if (mybin->GetIs3Src())
1525                 mybin->SetBits(bits3SrcFlagRegNum[0], bits3SrcFlagRegNum[1], value);
1526             else
1527                 mybin->SetBits(bitsFlagRegNum[0], bitsFlagRegNum[1], value);
1528         }
1529 
1530         // Should use G9HDL::EU_OPCODE as return type. But Forward declaration of enum
1531         // fails for linux, so use uint32_t as WA for now.
1532         uint32_t getEUOpcode(G4_opcode g4opc);  // defined in BinaryEncodingCNL.cpp
1533     }; // BinaryEncodingBase
1534 }
1535 
1536 namespace vISA
1537 {
BuildLabelMap(G4_INST * inst,int & localHalfInstNum,int & localInstNum,int & globalHalfInstNum,int & globalInstNum)1538     inline void BinaryEncodingBase::BuildLabelMap(G4_INST *inst,
1539         int& localHalfInstNum,
1540         int& localInstNum,
1541         int& globalHalfInstNum,
1542         int& globalInstNum)
1543     {
1544         if (inst->isLabel())
1545         {
1546             this->LabelMap[inst->getLabel()] = globalHalfInstNum;
1547         }
1548         else
1549         {
1550             BinInst *bin = inst->getBinInst();
1551 
1552             localInstNum++;
1553             globalInstNum++;
1554             if (GetCompactCtrl(bin))
1555             {
1556                 localHalfInstNum += 1;
1557                 globalHalfInstNum += 1;
1558             }
1559             else
1560             {
1561                 localHalfInstNum += 2;
1562                 globalHalfInstNum += 2;
1563             }
1564         }
1565     }
1566 
1567     /**
1568      * labels will be skipped in encoding stage and calculated in computeOffset()
1569      */
hasLabelString(G4_INST * inst)1570     inline bool EncodingHelper::hasLabelString(G4_INST *inst)
1571     {
1572         G4_opcode op = inst->opcode();
1573         if (op == G4_label ||
1574             op == G4_break ||
1575             op == G4_cont ||
1576             op == G4_halt ||
1577             op == G4_endif)
1578             return true;
1579         else if (op == G4_call             &&
1580             inst->getSrc(0) &&
1581             inst->getSrc(0)->isLabel())
1582         {
1583             return true;
1584         }
1585         else if (op == G4_jmpi             &&
1586             inst->getSrc(0) &&
1587             inst->getSrc(0)->isLabel())
1588         {
1589             return true;
1590         }
1591 
1592         return false;
1593     }
1594 
1595     //////////////////////////////////////////////////////////////////////////
mark3Src(G4_INST * inst)1596     inline void EncodingHelper::mark3Src(G4_INST* inst)
1597     {
1598         BinInst *mybin = inst->getBinInst();
1599 
1600         if (inst->getNumSrc() == 3 && !inst->isSend())
1601         {
1602             mybin->SetIs3Src(true);
1603         }
1604         else
1605         {
1606             mybin->SetIs3Src(false);
1607         }
1608     }
1609 
1610     /// Returns the register file of source operands.
GetSrcRegFile(G4_Operand * src)1611     inline RegFile EncodingHelper::GetSrcRegFile(G4_Operand *src) {
1612         if (src->isImm())
1613             return REG_FILE_I;
1614 
1615         G4_SrcRegRegion* srcRegRegion = src->asSrcRegRegion();
1616 
1617         if (srcRegRegion->isIndirect())
1618         {
1619             return REG_FILE_R;
1620         }
1621 
1622         G4_VarBase* base = srcRegRegion->getBase();
1623 
1624         if (base->isRegVar())
1625         {
1626             G4_VarBase *opnd = base->asRegVar()->getPhyReg();
1627             if (opnd->isAreg())
1628                 return REG_FILE_A;
1629             else if (opnd->isGreg())
1630                 return REG_FILE_R;
1631         }
1632         else {
1633             if (base->isAreg())
1634                 return REG_FILE_A;
1635             else if (base->isGreg())
1636                 return REG_FILE_R;
1637         }
1638 
1639         MUST_BE_TRUE(false, "invalid src regfile");
1640         return REG_FILE_R;
1641     }
1642 
1643     //////////////////////////////////////////////////////////////////////////
GetDstAddrMode(G4_DstRegRegion * dst)1644     inline AddrMode EncodingHelper::GetDstAddrMode(G4_DstRegRegion *dst)
1645     {
1646         if (dst->getRegAccess() == Direct)
1647             return ADDR_MODE_IMMED;
1648         else
1649             return ADDR_MODE_INDIR;
1650     }
1651 
1652     //////////////////////////////////////////////////////////////////////////
GetSrcAddrMode(G4_Operand * src)1653     inline AddrMode EncodingHelper::GetSrcAddrMode(G4_Operand *src)
1654     {
1655         if (src->isSrcRegRegion())
1656         {
1657             if (src->asSrcRegRegion()->getRegAccess() == Direct)
1658                 return ADDR_MODE_IMMED;
1659             else
1660                 return ADDR_MODE_INDIR;
1661         }
1662 
1663         return ADDR_MODE_IMMED;
1664     }
1665 
1666     //////////////////////////////////////////////////////////////////////////
GetElementSizeValue(G4_Operand * opnd)1667     inline unsigned short EncodingHelper::GetElementSizeValue(G4_Operand *opnd)
1668     {
1669         unsigned short ElementSizeValue = 0;
1670         switch (opnd->getType())
1671         {
1672         case Type_B:
1673         case Type_UB:
1674             ElementSizeValue = 1;
1675             break;
1676         case Type_UW:
1677         case Type_W:
1678         case Type_HF:
1679             ElementSizeValue = 2;
1680             break;
1681         case Type_UD:
1682         case Type_D:
1683         case Type_F:
1684             ElementSizeValue = 4;
1685             break;
1686         case Type_DF:
1687             ElementSizeValue = 8;
1688             break;
1689         case Type_Q:
1690         case Type_UQ:
1691             ElementSizeValue = 8;
1692             break;
1693         default: // error here
1694             break;
1695         }
1696         return ElementSizeValue;
1697     }
1698 
1699     //////////////////////////////////////////////////////////////////////////
GetDstArchRegType(G4_DstRegRegion * opnd)1700     inline uint32_t EncodingHelper::GetDstArchRegType(G4_DstRegRegion *opnd)
1701     {
1702         G4_VarBase *base = opnd->getBase();
1703 
1704         if (base->isRegVar())
1705         {
1706             G4_VarBase *preg = base->asRegVar()->getPhyReg();
1707             return GetArchRegType(preg);
1708         }
1709         else
1710         {
1711             return GetArchRegType(base);
1712         }
1713     }
1714 
1715     //////////////////////////////////////////////////////////////////////////
GetArchRegType(G4_VarBase * opnd)1716     inline uint32_t EncodingHelper::GetArchRegType(G4_VarBase *opnd)
1717     {
1718         uint32_t kind = ARCH_REG_FILE_DBG_REG;
1719         if (opnd->isAreg()) {
1720             switch (((G4_Areg *)opnd)->getArchRegType()) {
1721             case AREG_NULL:
1722                 kind = ARCH_REG_FILE_NULL;
1723                 break;
1724             case AREG_A0:
1725                 kind = ARCH_REG_FILE_A;
1726                 break;
1727             case AREG_ACC0:
1728             case AREG_ACC1:
1729                 kind = ARCH_REG_FILE_ACC;
1730                 break;
1731             case AREG_MASK0:
1732                 kind = ARCH_REG_FILE_CE_REG;
1733                 break;
1734             case AREG_MS0:
1735                 kind = ARCH_REG_FILE_MSG_REG;
1736                 break;
1737             case AREG_DBG:
1738                 kind = ARCH_REG_FILE_DBG_REG;
1739                 break;
1740             case AREG_SR0:
1741                 kind = ARCH_REG_FILE_STATE_REG;
1742                 break;
1743             case AREG_CR0:
1744                 kind = ARCH_REG_FILE_CNTL_REG;
1745                 break;
1746             case AREG_TM0:
1747                 kind = ARCH_REG_FILE_TM_REG;
1748                 break;
1749             case AREG_N0:
1750             case AREG_N1:
1751                 kind = ARCH_REG_FILE_NCNT_REG;
1752                 break;
1753             case AREG_IP:
1754                 kind = ARCH_REG_FILE_IP;
1755                 break;
1756             case AREG_F0:
1757             case AREG_F1:
1758                 kind = ARCH_REG_FILE_F;
1759                 break;
1760             case AREG_TDR0:
1761                 kind = ARCH_REG_FILE_TDR_REG;
1762                 break;
1763             case AREG_SP:
1764                 kind = ARCH_REG_FILE_SP_REG;
1765                 break;
1766             default:
1767                 kind = ARCH_REG_FILE_DBG_REG;
1768                 //TODO: err message here except from send dst
1769             }
1770         }
1771         return kind;
1772     }
1773 
1774     //////////////////////////////////////////////////////////////////////////
GetDstRegFile(G4_DstRegRegion * dst)1775     inline RegFile EncodingHelper::GetDstRegFile(G4_DstRegRegion *dst) {
1776 
1777         if (dst->isIndirect()) {
1778             return REG_FILE_R;
1779         }
1780 
1781         G4_VarBase *base = dst->getBase();
1782 
1783         if (base->isRegVar())
1784         {
1785             G4_VarBase *opnd = base->asRegVar()->getPhyReg();
1786             if (opnd->isAreg())
1787                 return REG_FILE_A;
1788             else if (opnd->isGreg())
1789                 return REG_FILE_R;
1790         }
1791         else {
1792             if (base->isAreg())
1793                 return REG_FILE_A;
1794             else if (base->isGreg())
1795                 return REG_FILE_R;
1796         }
1797         MUST_BE_TRUE(false, "invalid dst regfile");
1798         return REG_FILE_R;
1799     }
1800 
1801     //////////////////////////////////////////////////////////////////////////
GetEncodeExecSize(G4_INST * inst)1802     inline uint32_t GetEncodeExecSize(G4_INST* inst)
1803     {
1804         unsigned char execSize;
1805         G4_opcode op = inst->opcode();
1806 
1807         if (op == G4_nop || op == G4_wait || op == G4_jmpi)
1808         {
1809             return ES_1_CHANNEL;
1810         }
1811 
1812         execSize = inst->getExecSize();
1813         uint32_t exSz;
1814         switch (execSize)
1815         {
1816         case 1:
1817             exSz = ES_1_CHANNEL;
1818             break;
1819         case 2:
1820             exSz = ES_2_CHANNELS;
1821             break;
1822         case 4:
1823             exSz = ES_4_CHANNELS;
1824             break;
1825         case 8:
1826             exSz = ES_8_CHANNELS;
1827             break;
1828         case 16:
1829             exSz = ES_16_CHANNELS;
1830             break;
1831         case 32:
1832             exSz = ES_32_CHANNELS;
1833             break;
1834         default:
1835             MUST_BE_TRUE(0, "[Verifying]:[ERR]: Invalid execution size (" << (short)execSize << "):\t");
1836         }
1837         return exSz;
1838     }
1839 }
1840 #define bitsSrcImm32_0 127
1841 #define bitsSrcImm32_1 96
1842 #define bitsSrcImm32_2 127
1843 #define bitsSrcImm32_3 96
1844 #define bitsDebugCtrl_0 30
1845 #define bitsDebugCtrl_1 30
1846 #define bitsAccWrCtrl_0 28
1847 #define bitsAccWrCtrl_1 28
1848 #define bitsCondModifier_0 27
1849 #define bitsCondModifier_1 24
1850 #define bits3SrcDstRegNumHWord_0 63
1851 #define bits3SrcDstRegNumHWord_1 56
1852 #define bitsDstRegNumHWord_0 60
1853 #define bitsDstRegNumHWord_1 53
1854 #define bits64DebugCtrl_0 7
1855 #define bits64DebugCtrl_1 7
1856 #define bits64ControlIndex_0 12
1857 #define bits64ControlIndex_1 8
1858 #define bits64DataTypeIndex_0 17
1859 #define bits64DataTypeIndex_1 13
1860 #define bits64SubRegIndex_0 22
1861 #define bits64SubRegIndex_1 18
1862 
1863 // CondModifier [27:24] same as 128 bit
1864 #define bits64FlagSubRegNum_0 28
1865 #define bits64FlagSubRegNum_1 28
1866 
1867 //change from reserve to AccWrCtrl
1868 #define bits64AccWrCtrl_0 23
1869 #define bits64AccWrCtrl_1 23
1870 
1871 // CompactCtrl [29:29] same as 128 bit
1872 #define bits64Src0Index_0 34
1873 #define bits64Src0Index_1 32
1874 #define bits64Src0Index_2 31
1875 #define bits64Src0Index_3 30
1876 #define bits64Src1Index_0 39
1877 #define bits64Src1Index_1 35
1878 #define bits64DstRegNum_0 47
1879 #define bits64DstRegNum_1 40
1880 #define bits64Src0RegNum_0 55
1881 #define bits64Src0RegNum_1 48
1882 #define bits64Src1RegNum_0 63
1883 #define bits64Src1RegNum_1 56
1884 #define bits3SrcSrcRegNumHWord_0 83
1885 #define bits3SrcSrcRegNumHWord_1 76
1886 #define bits3SrcSrcRegNumHWord_2 104
1887 #define bits3SrcSrcRegNumHWord_3 97
1888 #define bitsSrcRegNumHWord_0 76
1889 #define bitsSrcRegNumHWord_1 69
1890 #define bitsSrcRegNumHWord_2 108
1891 #define bitsSrcRegNumHWord_3 101
1892 
1893 static const uint32_t UNDEFINED_VALUE = 0x00000000;
1894 
1895 namespace vISA
1896 {
GetSrc0Imm32(BinInst * mybin)1897     inline uint32_t GetSrc0Imm32(BinInst *mybin)
1898     {
1899         if (mybin->GetIs3Src())
1900             return UNDEFINED_VALUE;
1901         else
1902             return mybin->GetBits(bitsSrcImm32_0, bitsSrcImm32_1);
1903     }
1904 
GetSrc1Imm32(BinInst * mybin)1905     inline uint32_t GetSrc1Imm32(BinInst *mybin)
1906     {
1907         if (mybin->GetIs3Src())
1908             return UNDEFINED_VALUE;
1909         else
1910             return mybin->GetBits(bitsSrcImm32_2, bitsSrcImm32_3);
1911     }
1912 
CompactableImmediate(uint32_t Immediate)1913     inline bool CompactableImmediate(uint32_t Immediate)
1914     {
1915         // Each word needs to be of the format:
1916         // Old rule, not valid 000 0xxxx yyyyyyyy or 111 1xxxx yyyyyyyy
1917 
1918         //new rule, the 32 bit has to be
1919         //zzzzzzzz zzzzzzzz zzz zxxxx yyyyyyyy; z could be either 0 or 1
1920 
1921         // Separate immediate into 2 words
1922         uint32_t Words[2];
1923         Words[0] = Immediate & 0xffff;
1924         Words[1] = (Immediate >> 16) & 0xffff;
1925 
1926         // Words must be identical
1927         // if (Words[0] != Words[1])
1928         //     return false;
1929 
1930         // Make sure upper 4 bits for word 0 and all bit for word 1 are identical
1931         //for (int word = 0; word < WORDS_PER_DWORD; word++)
1932         {
1933             int UpperFour = (Words[0] >> 12) & 0xf;
1934             if (!(((UpperFour == 0x0) && (Words[1] == 0x0)) ||
1935                 ((UpperFour == 0xf) && (Words[1] == 0xffff))))
1936                 return false;
1937         }
1938 
1939         // If it passes, compact able
1940         return true;
1941     }
1942 
GetDebugCtrl(BinInst * mybin)1943     inline uint32_t GetDebugCtrl(BinInst *mybin)
1944     {
1945         return mybin->GetBits(bitsDebugCtrl_0, bitsDebugCtrl_1);
1946     }
1947 
GetAccWrCtrl(BinInst * mybin)1948     inline uint32_t GetAccWrCtrl(BinInst *mybin)
1949     {
1950         return mybin->GetBits(bitsAccWrCtrl_0, bitsAccWrCtrl_1);
1951     } // GT
1952 
GetCondModifier(BinInst * mybin)1953     inline uint32_t GetCondModifier(BinInst *mybin)
1954     {
1955         return mybin->GetBits(bitsCondModifier_0, bitsCondModifier_1);
1956     }
1957 
GetDstRegNumHWord(BinInst * mybin)1958     inline uint32_t GetDstRegNumHWord(BinInst *mybin)
1959     {
1960         if (mybin->GetIs3Src())
1961             return mybin->GetBits(bits3SrcDstRegNumHWord_0,
1962             bits3SrcDstRegNumHWord_1);
1963         else
1964             return mybin->GetBits(bitsDstRegNumHWord_0, bitsDstRegNumHWord_1);
1965     }
1966 
GetCmpDebugCtrl(BinInst * mybin)1967     inline uint32_t GetCmpDebugCtrl(BinInst *mybin)
1968     {
1969         return mybin->GetBits(bits64DebugCtrl_0, bits64DebugCtrl_1);
1970     }
1971 
1972 
SetCmpDebugCtrl(BinInst * mybin,uint32_t value)1973     inline void SetCmpDebugCtrl(BinInst *mybin, uint32_t value)
1974     {
1975         mybin->SetBits(bits64DebugCtrl_0, bits64DebugCtrl_1, value);
1976     }
1977 
SetAccWrCtrl(BinInst * mybin,uint32_t value)1978     inline void SetAccWrCtrl(BinInst *mybin, uint32_t value)
1979     {
1980         mybin->SetBits(bitsAccWrCtrl_0, bitsAccWrCtrl_1, value);
1981     }
1982 
SetDebugCtrl(BinInst * mybin,uint32_t value)1983     inline void SetDebugCtrl(BinInst *mybin, uint32_t value)
1984     {
1985         mybin->SetBits(bitsDebugCtrl_0, bitsDebugCtrl_1, value);
1986     }
1987 
1988 
GetCmpControlIndex(BinInst * mybin)1989     inline uint32_t GetCmpControlIndex(BinInst *mybin)
1990     {
1991         return mybin->GetBits(bits64ControlIndex_0, bits64ControlIndex_1);
1992     }
1993 
SetCmpControlIndex(BinInst * mybin,uint32_t value)1994     inline void SetCmpControlIndex(BinInst *mybin, uint32_t value)
1995     {
1996         mybin->SetBits(bits64ControlIndex_0, bits64ControlIndex_1, value);
1997     }
1998 
GetCmpDataTypeIndex(BinInst * mybin)1999     inline uint32_t GetCmpDataTypeIndex(BinInst *mybin)
2000     {
2001         return mybin->GetBits(bits64DataTypeIndex_0, bits64DataTypeIndex_1);
2002     }
2003 
SetCmpDataTypeIndex(BinInst * mybin,uint32_t value)2004     inline void SetCmpDataTypeIndex(BinInst *mybin, uint32_t value)
2005     {
2006         mybin->SetBits(bits64DataTypeIndex_0, bits64DataTypeIndex_1, value);
2007     }
2008 
GetCmpSubRegIndex(BinInst * mybin)2009     inline uint32_t GetCmpSubRegIndex(BinInst *mybin)
2010     {
2011         return mybin->GetBits(bits64SubRegIndex_0, bits64SubRegIndex_1);
2012     }
2013 
SetCmpSubRegIndex(BinInst * mybin,uint32_t value)2014     inline void SetCmpSubRegIndex(BinInst *mybin, uint32_t value)
2015     {
2016         mybin->SetBits(bits64SubRegIndex_0, bits64SubRegIndex_1, value);
2017     }
2018 
GetCmpFlagSubRegNum(BinInst * mybin)2019     inline uint32_t GetCmpFlagSubRegNum(BinInst *mybin)
2020     {
2021         return mybin->GetBits(bits64FlagSubRegNum_0, bits64FlagSubRegNum_1);
2022     }
2023 
SetCmpFlagSubRegNum(BinInst * mybin,uint32_t value)2024     inline void SetCmpFlagSubRegNum(BinInst *mybin, uint32_t value)
2025     {
2026         mybin->SetBits(bits64FlagSubRegNum_0, bits64FlagSubRegNum_1, value);
2027     }
2028 
GetCmpAccWrCtrl(BinInst * mybin)2029     inline uint32_t GetCmpAccWrCtrl(BinInst *mybin)
2030     {
2031         return mybin->GetBits(bits64AccWrCtrl_0, bits64AccWrCtrl_1);
2032     }
2033 
SetCmpAccWrCtrl(BinInst * mybin,uint32_t value)2034     inline void SetCmpAccWrCtrl(BinInst *mybin, uint32_t value)
2035     {
2036         mybin->SetBits(bits64AccWrCtrl_0, bits64AccWrCtrl_1, value);
2037     }
2038 
SetCondModifier(BinInst * mybin,uint32_t value)2039     inline void SetCondModifier(BinInst *mybin, uint32_t value)
2040     {
2041         mybin->SetBits(bitsCondModifier_0, bitsCondModifier_1, value);
2042     }
2043 
GetCmpSrc0Index(BinInst * mybin)2044     inline uint32_t GetCmpSrc0Index(BinInst *mybin)
2045     {
2046         // This one is ugly.  GetBits can't cross 32 bit boundary.
2047 
2048         // Get upper 3 bits...
2049         uint32_t upper3 = mybin->GetBits(bits64Src0Index_0, bits64Src0Index_1);
2050         // Lower 2 bits...
2051         uint32_t lower2 = mybin->GetBits(bits64Src0Index_2, bits64Src0Index_3);
2052 
2053         return (upper3 << 2) | lower2;
2054     }
2055 
SetCmpSrc0Index(BinInst * mybin,uint32_t value)2056     inline void SetCmpSrc0Index(BinInst *mybin, uint32_t value)
2057     {
2058         // This one is ugly.  SetBits can't cross 32 bit boundary.
2059 
2060         // Upper 3 bits...
2061         mybin->SetBits(bits64Src0Index_0, bits64Src0Index_1, value >> 2);
2062         // Lower 2 bits...
2063         mybin->SetBits(bits64Src0Index_2, bits64Src0Index_3, value);
2064     }
2065 
GetCmpSrc1Index(BinInst * mybin)2066     inline uint32_t GetCmpSrc1Index(BinInst *mybin)
2067     {
2068         return mybin->GetBits(bits64Src1Index_0, bits64Src1Index_1);
2069     }
2070 
SetCmpSrc1Index(BinInst * mybin,uint32_t value)2071     inline void SetCmpSrc1Index(BinInst *mybin, uint32_t value)
2072     {
2073         mybin->SetBits(bits64Src1Index_0, bits64Src1Index_1, value);
2074     }
2075 
GetCmpDstRegNum(BinInst * mybin)2076     inline uint32_t GetCmpDstRegNum(BinInst *mybin)
2077     {
2078         return  mybin->GetBits(bits64DstRegNum_0, bits64DstRegNum_1);
2079     }
2080 
SetCmpDstRegNum(BinInst * mybin,uint32_t value)2081     inline void SetCmpDstRegNum(BinInst *mybin, uint32_t value)
2082     {
2083         mybin->SetBits(bits64DstRegNum_0, bits64DstRegNum_1, value);
2084     }
2085 
GetCmpSrc1RegNum(BinInst * mybin)2086     inline uint32_t GetCmpSrc1RegNum(BinInst *mybin)
2087     {
2088         return mybin->GetBits(bits64Src1RegNum_0, bits64Src1RegNum_1);
2089     }
2090 
SetCmpSrc1RegNum(BinInst * mybin,uint32_t value)2091     inline void SetCmpSrc1RegNum(BinInst *mybin, uint32_t value)
2092     {
2093         mybin->SetBits(bits64Src1RegNum_0, bits64Src1RegNum_1, value);
2094     }
2095 
GetCmpSrc0RegNum(BinInst * mybin)2096     inline uint32_t GetCmpSrc0RegNum(BinInst *mybin)
2097     {
2098         return mybin->GetBits(bits64Src0RegNum_0, bits64Src0RegNum_1);
2099     }
2100 
SetCmpSrc0RegNum(BinInst * mybin,uint32_t value)2101     inline void SetCmpSrc0RegNum(BinInst *mybin, uint32_t value)
2102     {
2103         mybin->SetBits(bits64Src0RegNum_0, bits64Src0RegNum_1, value);
2104     }
2105 
GetSrc0RegNumHWord(BinInst * mybin)2106     inline uint32_t GetSrc0RegNumHWord(BinInst *mybin)
2107     {
2108         if (mybin->GetIs3Src())
2109             return mybin->GetBits(bits3SrcSrcRegNumHWord_0,
2110             bits3SrcSrcRegNumHWord_1);
2111         else
2112             return mybin->GetBits(bitsSrcRegNumHWord_0, bitsSrcRegNumHWord_1);
2113     }
2114 
GetSrc1RegNumHWord(BinInst * mybin)2115     inline uint32_t GetSrc1RegNumHWord(BinInst *mybin)
2116     {
2117         if (mybin->GetIs3Src())
2118             return mybin->GetBits(bits3SrcSrcRegNumHWord_2,
2119             bits3SrcSrcRegNumHWord_3);
2120         else
2121             return mybin->GetBits(bitsSrcRegNumHWord_2, bitsSrcRegNumHWord_3);
2122     }
2123 
SetDstRegNumHWord(BinInst * mybin,uint32_t value)2124     inline void SetDstRegNumHWord(BinInst *mybin, uint32_t value)
2125     {
2126         if (mybin->GetIs3Src())
2127             mybin->SetBits(bits3SrcDstRegNumHWord_0,
2128             bits3SrcDstRegNumHWord_1, value);
2129         else
2130             mybin->SetBits(bitsDstRegNumHWord_0,
2131             bitsDstRegNumHWord_1, value);
2132     }
2133 
SetSrc0RegNumHWord(BinInst * mybin,uint32_t value)2134     inline void SetSrc0RegNumHWord(BinInst *mybin, uint32_t value)
2135     {
2136         if (mybin->GetIs3Src())
2137             mybin->SetBits(bits3SrcSrcRegNumHWord_0,
2138             bits3SrcSrcRegNumHWord_1, value);
2139         else
2140             mybin->SetBits(bitsSrcRegNumHWord_0,
2141             bitsSrcRegNumHWord_1, value);
2142     }
2143 
SetSrc1RegNumHWord(BinInst * mybin,uint32_t value)2144     inline void SetSrc1RegNumHWord(BinInst *mybin, uint32_t value)
2145     {
2146         if (mybin->GetIs3Src())
2147             mybin->SetBits(bits3SrcSrcRegNumHWord_2,
2148             bits3SrcSrcRegNumHWord_3, value);
2149         else
2150             mybin->SetBits(bitsSrcRegNumHWord_2,
2151             bitsSrcRegNumHWord_3, value);
2152     }
2153 
GetAlign1PredCtrl(G4_Predicate_Control ctrl)2154     inline Align1PredCtrl GetAlign1PredCtrl(G4_Predicate_Control ctrl)
2155     {
2156         Align1PredCtrl pCntrl = Align1PredCtrl::NONE;
2157 
2158         switch (ctrl)
2159         {
2160         case PRED_DEFAULT:
2161             pCntrl = Align1PredCtrl::SEQUENTIAL;
2162             break;
2163         case PRED_ANY2H:
2164             pCntrl = Align1PredCtrl::ANY2H;
2165             break;
2166         case PRED_ANY4H:
2167             pCntrl = Align1PredCtrl::ANY4H;
2168             break;
2169         case PRED_ANY8H:
2170             pCntrl = Align1PredCtrl::ANY8H;
2171             break;
2172         case PRED_ANY16H:
2173             pCntrl = Align1PredCtrl::ANY16H;
2174             break;
2175         case PRED_ANY32H:
2176             pCntrl = Align1PredCtrl::ANY32H;
2177             break;
2178         case PRED_ALL2H:
2179             pCntrl = Align1PredCtrl::ALL2H;
2180             break;
2181         case PRED_ALL4H:
2182             pCntrl = Align1PredCtrl::ALL4H;
2183             break;
2184         case PRED_ALL8H:
2185             pCntrl = Align1PredCtrl::ALL8H;
2186             break;
2187         case PRED_ALL16H:
2188             pCntrl = Align1PredCtrl::ALL16H;
2189             break;
2190         case PRED_ALL32H:
2191             pCntrl = Align1PredCtrl::ALL32H;
2192             break;
2193         case PRED_ANYV:
2194             pCntrl = Align1PredCtrl::ANYV;
2195             break;
2196         case PRED_ALLV:
2197             pCntrl = Align1PredCtrl::ALLV;
2198             break;
2199         default:
2200             break;
2201         }
2202         return pCntrl;
2203     }
2204 
2205 
2206 }
2207 static struct _CompactControlTable_
2208 {
2209     union Data
2210     {
2211         struct
2212         {
2213             uint32_t Bits_023_008 : 16;
2214             uint32_t Bits_031_031 :  1;
2215             uint32_t Bits_090_089 :  2;
2216             uint32_t Reserved     : 13;
2217         } sData;
2218         uint32_t ulData;
2219     };
2220 
GetBit_031_CompactControlTable_2221     uint32_t GetBit_031(uint32_t index)
2222     {
2223         MUST_BE_TRUE(index < COMPACT_TABLE_SIZE, "Out of Control Bit Compact Table range.");
2224         Data data;
2225         data.ulData = Values[index];
2226         return data.sData.Bits_031_031;
2227     }
2228 
GetBits_023_008_CompactControlTable_2229     uint32_t GetBits_023_008(uint32_t index)
2230     {
2231         MUST_BE_TRUE(index < COMPACT_TABLE_SIZE, "Out of Control Bit Compact Table range.");
2232         Data data;
2233         data.ulData = Values[index];
2234         return data.sData.Bits_023_008;
2235     }
2236 
GetBits_090_089_CompactControlTable_2237     uint32_t GetBits_090_089(uint32_t index)
2238     {
2239         MUST_BE_TRUE(index < COMPACT_TABLE_SIZE, "Out of Control Bit Compact Table range.");
2240         Data data;
2241         data.ulData = Values[index];
2242         return data.sData.Bits_090_089;
2243     }
2244 
2245     uint32_t Values[COMPACT_TABLE_SIZE];
2246 } CompactControlTable;
2247 
2248 namespace vISA
2249 {
compactOneInstruction(G4_INST * inst)2250     inline bool BinaryEncodingBase::compactOneInstruction(G4_INST *inst)
2251     {
2252         G4_opcode op = inst->opcode();
2253         BinInst *mybin = inst->getBinInst();
2254         if (op == G4_if || op == G4_else || op == G4_endif ||
2255             op == G4_while || op == G4_halt ||
2256             op == G4_break || op == G4_cont ||
2257             /* GetComprCtrl(mybin) == COMPR_CTRL_COMPRESSED  || */
2258             mybin->GetDontCompactFlag())
2259         {
2260             // do not compact conditional branches
2261             return false;
2262         }
2263 
2264         if (op == G4_nop)
2265         {
2266             return false;
2267         }
2268 
2269         // temporary WA, to be removed later
2270         // we disable compacting nop/return
2271         // until it is clear that we can compact them
2272         if (op == G4_call || op == G4_return)
2273         {
2274             return false;
2275         }
2276 
2277         bool result = BDWcompactOneInstruction(inst);
2278 
2279         return result;
2280     }
2281 
BDWcompactOneInstruction3Src(G4_INST * inst)2282     inline bool BinaryEncodingBase::BDWcompactOneInstruction3Src(G4_INST *inst)
2283     {
2284         BinInst *mybin = inst->getBinInst();
2285 
2286         // Check control table...
2287         uint32_t controlIndex;
2288         uint32_t bits_034_032 = mybin->GetBits(34, 32);
2289         uint32_t bits_028_008 = mybin->GetBits(28, 8);
2290         bool mustCompact = !(mybin->GetMustCompactFlag());
2291         if (!CompactControlTable3Src.FindBDWIndex(controlIndex,
2292             bits_034_032,
2293             bits_028_008))
2294         {
2295             MUST_BE_TRUE(mustCompact, "Compaction failure for control table");
2296             // Can't compact...
2297             return false;
2298         }
2299 
2300         // Check source index table...
2301         uint32_t srcIndex;
2302         uint32_t bits_125_125 = mybin->GetBits(125, 125);
2303         uint32_t bits_104_104 = mybin->GetBits(104, 104);
2304         uint32_t bits_083_083 = mybin->GetBits(83, 83);
2305         uint32_t bits_114_107 = mybin->GetBits(114, 107);
2306         uint32_t bits_093_086 = mybin->GetBits(93, 86);
2307         uint32_t bits_072_065 = mybin->GetBits(72, 65);
2308         uint32_t bits_055_037 = mybin->GetBits(55, 37);
2309 
2310         if (!CompactSourceTable3Src.FindIndex(srcIndex,
2311             bits_125_125,
2312             bits_104_104,
2313             bits_083_083,
2314             bits_114_107,
2315             bits_093_086,
2316             bits_072_065,
2317             bits_055_037))
2318         {
2319             MUST_BE_TRUE(mustCompact, "Compaction failure for source table");
2320             // Can't compact...
2321             return false;
2322         }
2323 
2324         // We have valid indices at this point.  Make a compacted instruction...
2325         // The field of opcode 6:0 and reserved 7 remain the same
2326 
2327         mybin->SetBits(9, 8, controlIndex);
2328         mybin->SetBits(11, 10, srcIndex);
2329         mybin->SetBits(18, 12, mybin->GetBits(63, 56));
2330         mybin->SetBits(27, 19, 0); // 27 to 19: reverved
2331         mybin->SetBits(28, 28, mybin->GetBits(64, 64));
2332         SetCompactCtrl(mybin, 1); // 29
2333         // 30, 31: the same
2334         mybin->SetBits(32, 32, mybin->GetBits(85, 85));
2335         mybin->SetBits(33, 33, mybin->GetBits(106, 106));
2336         mybin->SetBits(36, 34, mybin->GetBits(75, 73));
2337         mybin->SetBits(39, 37, mybin->GetBits(96, 94));
2338         mybin->SetBits(42, 40, mybin->GetBits(117, 115));
2339         mybin->SetBits(49, 43, mybin->GetBits(82, 76));
2340         mybin->SetBits(56, 50, mybin->GetBits(103, 97));
2341         mybin->SetBits(63, 57, mybin->GetBits(124, 118));
2342 
2343         //SetMustCompact(true);
2344 
2345         // Copy on top of ourselves...
2346         return true;
2347     }
2348 
CHVcompactOneInstruction3Src(G4_INST * inst)2349     inline bool BinaryEncodingBase::CHVcompactOneInstruction3Src(G4_INST *inst)
2350     {
2351         BinInst *mybin = inst->getBinInst();
2352 
2353         // Check control table...
2354         uint32_t controlIndex;
2355         uint32_t bits_036_035 = mybin->GetBits(36, 35);
2356         uint32_t bits_034_032 = mybin->GetBits(34, 32);
2357         uint32_t bits_028_008 = mybin->GetBits(28, 8);
2358         bool mustCompact = !(mybin->GetMustCompactFlag());
2359         if (!CompactControlTable3Src.FindCHVIndex(controlIndex,
2360             bits_036_035,
2361             bits_034_032,
2362             bits_028_008))
2363         {
2364             MUST_BE_TRUE(mustCompact, "Compaction failure for control table");
2365             // Can't compact...
2366             return false;
2367         }
2368 
2369         // Check source index table...
2370         uint32_t srcIndex;
2371         uint32_t bits_126_125 = mybin->GetBits(126, 125);
2372         uint32_t bits_105_104 = mybin->GetBits(105, 104);
2373         uint32_t bits_084_083 = mybin->GetBits(84, 83);
2374         uint32_t bits_114_107 = mybin->GetBits(114, 107);
2375         uint32_t bits_093_086 = mybin->GetBits(93, 86);
2376         uint32_t bits_072_065 = mybin->GetBits(72, 65);
2377         uint32_t bits_055_037 = mybin->GetBits(55, 37);
2378 
2379         if (!CompactSourceTable3SrcCHV.FindIndex(srcIndex,
2380             bits_126_125,
2381             bits_105_104,
2382             bits_084_083,
2383             bits_114_107,
2384             bits_093_086,
2385             bits_072_065,
2386             bits_055_037))
2387         {
2388             MUST_BE_TRUE(mustCompact, "Compaction failure for source table");
2389             // Can't compact...
2390             return false;
2391         }
2392 
2393         // We have valid indices at this point.  Make a compacted instruction...
2394         // The field of opcode 6:0 and reserved 7 remain the same
2395 
2396         mybin->SetBits(9, 8, controlIndex);
2397         mybin->SetBits(11, 10, srcIndex);
2398         mybin->SetBits(18, 12, mybin->GetBits(63, 56));
2399         mybin->SetBits(27, 19, 0); // 27 to 19: reverved
2400         mybin->SetBits(28, 28, mybin->GetBits(64, 64));
2401         SetCompactCtrl(mybin, 1); // 29
2402         // 30, 31: the same
2403         mybin->SetBits(32, 32, mybin->GetBits(85, 85));
2404         mybin->SetBits(33, 33, mybin->GetBits(106, 106));
2405         mybin->SetBits(36, 34, mybin->GetBits(75, 73));
2406         mybin->SetBits(39, 37, mybin->GetBits(96, 94));
2407         mybin->SetBits(42, 40, mybin->GetBits(117, 115));
2408         mybin->SetBits(49, 43, mybin->GetBits(82, 76));
2409         mybin->SetBits(56, 50, mybin->GetBits(103, 97));
2410         mybin->SetBits(63, 57, mybin->GetBits(124, 118));
2411 
2412         return true;
2413     }
2414 
BDWcompactOneInstruction(G4_INST * inst)2415     inline bool BinaryEncodingBase::BDWcompactOneInstruction(G4_INST *inst)
2416     {
2417         BinInst *mybin = inst->getBinInst();
2418 
2419         if (mybin->GetIs3Src())
2420         {
2421             if (inst->getPlatform() == GENX_BDW)
2422             {
2423                 return BDWcompactOneInstruction3Src(inst);
2424             }
2425             else if (inst->getPlatform() >= GENX_CHV)
2426             {
2427                 // CHV and SKL are using the same compaction table for 3src
2428                 return CHVcompactOneInstruction3Src(inst);
2429             }
2430             else
2431             {
2432                 // other platforms not handled yet
2433                 return false;
2434             }
2435         }
2436 
2437         if (inst->getPlatform() >= GENX_CHV && inst->isSend())
2438         {
2439             return false;
2440         }
2441 
2442         bool source_immediate[2];
2443         source_immediate[0] = (RegFile(GetSrc0RegFile(mybin)) == REG_FILE_I);
2444         source_immediate[1] = (RegFile(GetSrc1RegFile(mybin)) == REG_FILE_I);
2445 
2446         // Check control table...
2447         uint32_t controlIndex;
2448         uint32_t bits_033_032 = mybin->GetBits(33, 32);
2449         uint32_t bits_031_031 = mybin->GetBits(31, 31);
2450         uint32_t bits_023_012 = mybin->GetBits(23, 12);
2451         uint32_t bits_010_009 = mybin->GetBits(10, 9);
2452         uint32_t bits_034_034 = mybin->GetBits(34, 34);
2453         uint32_t bits_008_008 = mybin->GetBits(8, 8);
2454         bool mustCompact = !(mybin->GetMustCompactFlag());
2455         if (!BDWCompactControlTable.FindIndex(controlIndex,
2456             bits_033_032,
2457             bits_031_031,
2458             bits_023_012,
2459             bits_010_009,
2460             bits_034_034,
2461             bits_008_008))
2462         {
2463             MUST_BE_TRUE(mustCompact, "Compaction failure for control table");
2464             // Can't compact...
2465             return false;
2466         }
2467 
2468 
2469         // Check data type table
2470         uint32_t dataTypeIndex;
2471         uint32_t bits_063_061 = mybin->GetBits(63, 61);
2472         uint32_t bits_094_089 = mybin->GetBits(94, 89);
2473         uint32_t bits_046_035 = mybin->GetBits(46, 35);
2474         if (!BDWCompactDataTypeTableStr.FindIndex(dataTypeIndex,
2475             bits_063_061,
2476             bits_094_089,
2477             bits_046_035))
2478         {
2479             MUST_BE_TRUE(mustCompact, "Compaction failure for data type table");
2480             // Can't compact...
2481             return false;
2482         }
2483 
2484         // Check sub-register table...
2485         uint32_t subRegIndex;
2486         uint32_t bits_100_096 = mybin->GetBits(100, 96);
2487         uint32_t bits_068_064 = mybin->GetBits(68, 64);
2488         uint32_t bits_052_048 = mybin->GetBits(52, 48);
2489 
2490         // If source 0 is an immediate, we only check destination
2491         // sub-register info for compaction restrictions.
2492         if (source_immediate[0])
2493         {
2494             if (!BDWCompactSubRegTable.FindIndex1(subRegIndex, bits_052_048))
2495             {
2496                 MUST_BE_TRUE(mustCompact, "Compaction failure for sub reg table");
2497                 // Can't compact...
2498                 return false;
2499             }
2500         }
2501         // If source 1 is an immediate, we need to check sub-register info
2502         // for source 0 in addition to sub-register info for destination
2503         else if (source_immediate[1])
2504         {
2505             if (!BDWCompactSubRegTable.FindIndex2(subRegIndex, bits_068_064, bits_052_048))
2506             {
2507                 MUST_BE_TRUE(mustCompact, "Compaction failure for sub reg table");
2508                 // Can't compact...
2509                 return false;
2510             }
2511         }
2512         // Otherwise we check everything
2513         else if (!BDWCompactSubRegTable.FindIndex(subRegIndex,
2514             bits_100_096, bits_068_064, bits_052_048))
2515         {
2516             MUST_BE_TRUE(mustCompact, "Compaction failure for sub reg table");
2517             // Can't compact...
2518             return false;
2519         }
2520 
2521         // Check source 0 table...
2522         uint32_t src0Index;
2523         uint32_t bits_088_077 = mybin->GetBits(88, 77);
2524 
2525         // If source 0 is not immediate data, we need to check source 0 info
2526         if (!source_immediate[0])
2527         {
2528             if (!BDWCompactSourceTable.FindIndex(src0Index, bits_088_077))
2529             {
2530                 MUST_BE_TRUE(mustCompact, "Compaction failure for source table");
2531                 // Can't compact...
2532                 return false;
2533             }
2534         }
2535         else
2536         {
2537             // Default to index0 of tables
2538             src0Index = 0;
2539         }
2540 
2541         // Check source 1 table...
2542         uint32_t src1Index;
2543         uint32_t bits_120_109 = mybin->GetBits(120, 109);
2544 
2545         // If both source 0 and source 1 are not immediate data,
2546         // we need to cehck source 1 information
2547         if (!source_immediate[0] && !source_immediate[1])
2548         {
2549             if (!BDWCompactSourceTable.FindIndex(src1Index, bits_120_109))
2550             {
2551                 MUST_BE_TRUE(mustCompact, "Compact should be set to false");
2552                 // Can't compact...
2553                 return false;
2554             }
2555         }
2556         else
2557         {
2558             src1Index = mybin->GetBits(127, 104);
2559         }
2560 
2561         uint32_t immediateData = 0;
2562         // If we have an immediate, overwrite bits [39:35] [63:56] with immediate
2563         if (source_immediate[0] || source_immediate[1])
2564         {
2565             if (source_immediate[0])
2566             {
2567                 immediateData = GetSrc0Imm32(mybin);
2568             }
2569             else
2570             {
2571                 immediateData = GetSrc1Imm32(mybin);
2572             }
2573 
2574             if (!CompactableImmediate(immediateData))
2575             {
2576                 MUST_BE_TRUE(mustCompact, "Compact should be set to false");
2577                 // Can't compact...
2578                 return false;
2579             }
2580         }
2581 
2582         // We have valid indices at this point.  Make a compacted instruction...
2583         // The field of opcode/debugCtrl, Bits 6:0 and 7 remain the same
2584 
2585         uint32_t accWrCtrl = GetAccWrCtrl(mybin);
2586         uint32_t dstRegNum = GetDstRegNumHWord(mybin);
2587         uint32_t src0RegNum = GetSrc0RegNumHWord(mybin);
2588         uint32_t src1RegNum = GetSrc1RegNumHWord(mybin);
2589         uint32_t debugCtrl = GetDebugCtrl(mybin);
2590 
2591         SetCmpDebugCtrl(mybin, debugCtrl);
2592         SetCmpControlIndex(mybin, controlIndex); // 12:8
2593         SetCmpDataTypeIndex(mybin, dataTypeIndex); //17:13
2594         SetCmpSubRegIndex(mybin, subRegIndex); // 22:18
2595         SetCmpAccWrCtrl(mybin, accWrCtrl);// 23
2596         // 27:24 cond modifier remain the same;
2597         mybin->SetBits(28, 28, 0);//28 reserved
2598         SetCompactCtrl(mybin, 1); // 29
2599         SetCmpSrc0Index(mybin, src0Index); //34:30
2600         SetCmpSrc1Index(mybin, src1Index); // 39:35
2601         SetCmpDstRegNum(mybin, dstRegNum); // 47:40
2602         if (source_immediate[0])
2603             SetCmpSrc0RegNum(mybin, 0);
2604         else
2605             SetCmpSrc0RegNum(mybin, src0RegNum); // 55:48
2606         if (source_immediate[1])
2607             SetCmpSrc1RegNum(mybin, 0);
2608         else
2609             SetCmpSrc1RegNum(mybin, src1RegNum); //63:56
2610 
2611         // If we have an immediate, overwrite bits [39:35] [63:56] with immediate
2612         if (source_immediate[0] || source_immediate[1])
2613         {
2614             SetCmpSrc1RegNum(mybin, immediateData & 0xff);          // 63:56
2615             // 39:35 change from (immediateData & 0x1f)>>8
2616             // to (immediateData >> 8)& 0x1f)
2617             SetCmpSrc1Index(mybin, (immediateData >> 8) & 0x1f);
2618         }
2619 
2620         //SetMustCompact(true);
2621 
2622         // Copy on top of ourselves...
2623         return true;
2624 
2625     }
2626 
uncompactOneInstruction(G4_INST * inst)2627     inline bool BinaryEncodingBase::uncompactOneInstruction(G4_INST *inst)
2628     {
2629         BinInst *mybin = inst->getBinInst();
2630         // Validate control index...
2631         unsigned long controlIndex = GetCmpControlIndex(mybin);
2632         if (COMPACT_TABLE_SIZE <= controlIndex)
2633         {
2634             return false;
2635         }
2636 
2637         // Validate data type index...
2638         uint32_t dataTypeIndex = GetCmpDataTypeIndex(mybin);
2639         if (COMPACT_TABLE_SIZE <= dataTypeIndex)
2640         {
2641             return false;
2642         }
2643 
2644         // Validate sub-register index...
2645         uint32_t subRegIndex = GetCmpSubRegIndex(mybin);
2646         if (COMPACT_TABLE_SIZE <= subRegIndex)
2647         {
2648             return false;
2649         }
2650 
2651         // Validate source 0 index...
2652         uint32_t src0Index = GetCmpSrc0Index(mybin);
2653         if (COMPACT_TABLE_SIZE <= src0Index)
2654         {
2655             return false;
2656         }
2657 
2658         // Validate source 1 index...
2659         uint32_t src1Index = GetCmpSrc1Index(mybin);
2660         if (COMPACT_TABLE_SIZE <= src1Index)
2661         {
2662             return false;
2663         }
2664 
2665         // Pull out compatced immediate source
2666         // Get bits [39] [39] [39] [39:35]
2667         uint32_t src1IndexSignExtend = GetCmpSrc1Index(mybin);
2668         if ((src1IndexSignExtend & 0x10) != 0)
2669         {
2670             src1IndexSignExtend |= 0xe0;
2671         }
2672         // Get bits [63:56]
2673         uint32_t src1RegNum = GetCmpSrc1RegNum(mybin);
2674         // Put together [39] [39] [39] [39:35] [63:56] [39] [39] [39] [39:35] [63:56]
2675         uint32_t immediateSource = 0;
2676         immediateSource = (src1RegNum | (src1IndexSignExtend << 8));// | (src1RegNum << 16) | (src1IndexSignExtend << 24));
2677         //do the sign extension upto 32 bit
2678         if ((immediateSource & 0x8000) == 0x8000) //if the sign is 1
2679             immediateSource = immediateSource | 0xffff0000;
2680 
2681         // Start clear...
2682         // Uncompact...
2683         //ins.SetOpCode(GetOpCode());
2684 
2685         uint32_t comDebugCtrl = GetCmpDebugCtrl(mybin);
2686         uint32_t controlIndex31 = CompactControlTable.GetBit_031(controlIndex);
2687         uint32_t controlIndex23 = CompactControlTable.GetBits_023_008(controlIndex);
2688         uint32_t dataTypeIndex63 = CompactDataTypeTable.GetBits_063_061(dataTypeIndex);
2689         uint32_t dataTypeIndex46 = CompactDataTypeTable.GetBits_046_032(dataTypeIndex);
2690         uint32_t subRegIndex100 = CompactSubRegTable.GetBits_100_096(subRegIndex);
2691         uint32_t subRegIndex68 = CompactSubRegTable.GetBits_068_064(subRegIndex);
2692         uint32_t subRegIndex52 = CompactSubRegTable.GetBits_052_048(subRegIndex);
2693         uint32_t condModifer = GetCondModifier(mybin);
2694         uint32_t accWrCtrl = GetCmpAccWrCtrl(mybin);
2695         uint32_t flagSubRegNum = GetCmpFlagSubRegNum(mybin);
2696         uint32_t bits88 = CompactSourceTable.GetBits_088_077(src0Index);
2697         uint32_t bits120 = CompactSourceTable.GetBits_120_109(src1Index);
2698         uint32_t dstRegNum = GetCmpDstRegNum(mybin);
2699         uint32_t src0RegNum = GetCmpSrc0RegNum(mybin);
2700         uint32_t src0RegFile = GetSrc0RegFile(mybin);
2701         uint32_t src1RegFile = GetSrc1RegFile(mybin);
2702 
2703         SetDebugCtrl(mybin, comDebugCtrl);
2704         mybin->SetBits(31, 31, controlIndex31);
2705         mybin->SetBits(23, 8, controlIndex23);
2706         mybin->SetBits(63, 61, dataTypeIndex63);
2707         mybin->SetBits(46, 32, dataTypeIndex46);
2708         mybin->SetBits(100, 96, subRegIndex100);
2709         mybin->SetBits(68, 64, subRegIndex68);
2710         mybin->SetBits(52, 48, subRegIndex52);
2711         SetCondModifier(mybin, condModifer);
2712         SetAccWrCtrl(mybin, accWrCtrl);
2713         SetFlagRegNum(mybin, flagSubRegNum);
2714         SetCompactCtrl(mybin, 0);  // uncompaction
2715         mybin->SetBits(88, 77, bits88);
2716         //  mybin->SetBits(100, 96, CompactSubRegTable.GetBits_100_096(subRegIndex));
2717         mybin->SetBits(120, 109, bits120);
2718         SetDstRegNumHWord(mybin, dstRegNum);
2719         SetSrc0RegNumHWord(mybin, src0RegNum);
2720         SetSrc1RegNumHWord(mybin, src1RegNum);
2721 
2722         //set all MBZ bits in DW0 & DW1 to 0
2723         mybin->SetBits(7, 7, 0);
2724 
2725         // If either source is immediate, fill in w/ Source Immediate above
2726         if ((RegFile(src0RegFile) == REG_FILE_I) ||
2727             (RegFile(src1RegFile) == REG_FILE_I))
2728         {
2729             mybin->SetBits(127, 96, immediateSource);
2730         }
2731 
2732         return true;
2733 
2734     }
2735 }
2736 #endif
2737