xref: /llvm-project/llvm/test/TableGen/HwModeEncodeDecode3.td (revision ffc9a30938ae5c42c03f9c563db1465876b4def6)
1// RUN: llvm-tblgen -gen-emitter -I %p/../../include %s | \
2// RUN:     FileCheck %s --check-prefix=ENCODER
3// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | \
4// RUN:     FileCheck %s --check-prefix=DECODER
5// RUN: llvm-tblgen -gen-disassembler --suppress-per-hwmode-duplicates=O1 -I \
6// RUN:     %p/../../include %s | FileCheck %s --check-prefix=DECODER-SUPPRESS-O1
7// RUN: llvm-tblgen -gen-disassembler --suppress-per-hwmode-duplicates=O2 -I \
8// RUN:     %p/../../include %s | FileCheck %s --check-prefix=DECODER-SUPPRESS-O2
9
10include "llvm/Target/Target.td"
11
12def archInstrInfo : InstrInfo { }
13
14def arch : Target {
15  let InstructionSet = archInstrInfo;
16}
17
18def Myi32 : Operand<i32> {
19  let DecoderMethod = "DecodeMyi32";
20}
21
22def HasA : Predicate<"Subtarget->hasA()">;
23def HasB : Predicate<"Subtarget->hasB()">;
24
25def ModeA : HwMode<"+a", [HasA]>; // Mode 1
26def ModeB : HwMode<"+b", [HasB]>; // Mode 2
27def ModeC : HwMode<"+c", []>;     // Mode 3
28
29
30def fooTypeEncDefault : InstructionEncoding {
31  let Size = 8;
32  field bits<64> SoftFail = 0;
33  bits<64> Inst;
34  bits<8> factor;
35  let Inst{7...0} = factor;
36  let Inst{3...2} = 0b10;
37  let Inst{1...0} = 0b00;
38}
39
40def fooTypeEncA : InstructionEncoding {
41  let Size = 4;
42  field bits<32> SoftFail = 0;
43  bits<32> Inst;
44  bits<8> factor;
45  let Inst{7...0} = factor;
46  let Inst{3...2} = 0b11;
47  let Inst{1...0} = 0b00;
48}
49
50def fooTypeEncB : InstructionEncoding {
51  let Size = 4;
52  field bits<32> SoftFail = 0;
53  bits<32> Inst;
54  bits<8> factor;
55  let Inst{15...8} = factor;
56  let Inst{1...0} = 0b11;
57}
58
59def fooTypeEncC : InstructionEncoding {
60  let Size = 4;
61  field bits<32> SoftFail = 0;
62  bits<32> Inst;
63  bits<8> factor;
64  let Inst{31...24} = factor;
65  let Inst{23...21} = 0b110;
66  let Inst{1...0} = 0b11;
67}
68
69// Test for DefaultMode as a selector.
70def foo : Instruction {
71  let OutOperandList = (outs);
72  let InOperandList = (ins i32imm:$factor);
73  let EncodingInfos = EncodingByHwMode<
74  [ModeC, ModeA, ModeB, DefaultMode],
75  [fooTypeEncC, fooTypeEncA, fooTypeEncB, fooTypeEncDefault]>;
76  let AsmString = "foo  $factor";
77}
78
79def bar: Instruction {
80  let OutOperandList = (outs);
81  let InOperandList = (ins i32imm:$factor);
82  let Size = 4;
83  bits<32> Inst;
84  bits<32> SoftFail;
85  bits<8> factor;
86  let Inst{31...24} = factor;
87  let Inst{1...0} = 0b10;
88  let AsmString = "bar  $factor";
89}
90
91def baz : Instruction {
92  let OutOperandList = (outs);
93  let InOperandList = (ins i32imm:$factor);
94  bits<32> Inst;
95  let EncodingInfos = EncodingByHwMode<
96    [ModeB], [fooTypeEncA]
97  >;
98  let AsmString = "foo  $factor";
99}
100
101def unrelated: Instruction {
102  let OutOperandList = (outs);
103  let DecoderNamespace = "Alt";
104  let InOperandList = (ins i32imm:$factor);
105  let Size = 4;
106  bits<32> Inst;
107  bits<32> SoftFail;
108  bits<8> factor;
109  let Inst{31...24} = factor;
110  let Inst{1...0} = 0b10;
111  let AsmString = "unrelated  $factor";
112}
113
114
115// Under default settings, using 'HwMode' to dictate instruction encodings results in
116// significant duplication of DecoderTables. The four tables ‘DecoderTableAlt32’,
117// ‘DecoderTableAlt_ModeA32’, ‘DecoderTableAlt_ModeB32’ and 'DecoderTable_ModeC32' are
118// exact duplicates and could effectively be merged into one.
119// DECODER-LABEL: DecoderTable32[] =
120// DECODER-DAG: Opcode: bar
121// DECODER-LABEL: DecoderTable64[] =
122// DECODER-DAG: Opcode: fooTypeEncDefault:foo
123// DECODER-LABEL: DecoderTableAlt32[] =
124// DECODER-DAG: Opcode: unrelated
125// DECODER-LABEL: DecoderTableAlt_ModeA32[] =
126// DECODER-DAG: Opcode: unrelated
127// DECODER-LABEL: DecoderTableAlt_ModeB32[] =
128// DECODER-DAG: Opcode: unrelated
129// DECODER-LABEL: DecoderTableAlt_ModeC32[] =
130// DECODER-DAG: Opcode: unrelated
131// DECODER-LABEL: DecoderTable_ModeA32[] =
132// DECODER-DAG: Opcode: fooTypeEncA:foo
133// DECODER-DAG: Opcode: bar
134// DECODER-LABEL: DecoderTable_ModeB32[] =
135// DECODER-DAG: Opcode: fooTypeEncB:foo
136// DECODER-DAG: Opcode: fooTypeEncA:baz
137// DECODER-DAG: Opcode: bar
138// DECODER-LABEL: DecoderTable_ModeC32[] =
139// DECODER-DAG: Opcode: fooTypeEncC:foo
140// DECODER-DAG: Opcode: bar
141
142// Under the 'O1' optimization level, unnecessary duplicate tables will be eliminated,
143// reducing the four ‘Alt’ tables down to just one.
144// DECODER-SUPPRESS-O1-LABEL: DecoderTable32[] =
145// DECODER-SUPPRESS-O1-DAG: Opcode: bar
146// DECODER-SUPPRESS-O1-LABEL: DecoderTable64[] =
147// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncDefault:foo
148// DECODER-SUPPRESS-O1-LABEL: DecoderTableAlt32[] =
149// DECODER-SUPPRESS-O1-DAG: Opcode: unrelated
150// DECODER-SUPPRESS-O1-LABEL: DecoderTable_ModeA32[] =
151// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncA:foo
152// DECODER-SUPPRESS-O1-DAG: Opcode: bar
153// DECODER-SUPPRESS-O1-LABEL: DecoderTable_ModeB32[] =
154// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncB:foo
155// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncA:baz
156// DECODER-SUPPRESS-O1-DAG: Opcode: bar
157// DECODER-SUPPRESS-O1-LABEL: DecoderTable_ModeC32[] =
158// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncC:foo
159// DECODER-SUPPRESS-O1-DAG: Opcode: bar
160
161// Under the 'O2' optimization condition, instructions possessing the 'EncodingByHwMode'
162// attribute will be extracted from their original DecoderNamespace and placed into their
163// respective HwMode tables. Meanwhile, other instructions that do not have the 'EncodingByHwMode'
164// attribute but are within the same DecoderNamespace will be stored in the 'Default' table. This
165// approach will significantly reduce instruction redundancy, but it necessitates users to thoroughly
166// consider the interplay between HwMode and DecoderNamespace for their instructions.
167// DECODER-SUPPRESS-O2-LABEL: DecoderTable32[] =
168// DECODER-SUPPRESS-O2-DAG: Opcode: bar
169// DECODER-SUPPRESS-O2-LABEL: DecoderTable64[] =
170// DECODER-SUPPRESS-O2-NOT: Opcode: bar
171// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncDefault:foo
172// DECODER-SUPPRESS-O2-LABEL: DecoderTableAlt32[] =
173// DECODER-SUPPRESS-O2-DAG: Opcode: unrelated
174// DECODER-SUPPRESS-O2-LABEL: DecoderTable_ModeA32[] =
175// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncA:foo
176// DECODER-SUPPRESS-O2-NOT: Opcode: bar
177// DECODER-SUPPRESS-O2-LABEL: DecoderTable_ModeB32[] =
178// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncB:foo
179// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncA:baz
180// DECODER-SUPPRESS-O2-NOT: Opcode: bar
181// DECODER-SUPPRESS-O2-LABEL: DecoderTable_ModeC32[] =
182// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncC:foo
183// DECODER-SUPPRESS-O2-NOT: Opcode: bar
184
185// For 'bar' and 'unrelated', we didn't assign any HwModes for them,
186// they should keep the same in the following four tables.
187// For 'foo' we assigned four HwModes( includes 'DefaultMode' ),
188// it's encodings should be different in the following four tables.
189// For 'baz' we only assigned ModeB for it, so it will be presented
190// as '0' in the tables of ModeA, ModeC and Default Mode.
191// ENCODER-LABEL:   static const uint64_t InstBits[] = {
192// ENCODER:         UINT64_C(2),        // bar
193// ENCODER:         UINT64_C(0),        // baz
194// ENCODER:         UINT64_C(8),        // foo
195// ENCODER:         UINT64_C(2),        // unrelated
196// ENCODER-LABEL:   static const uint64_t InstBits_ModeA[] = {
197// ENCODER:         UINT64_C(2),        // bar
198// ENCODER:         UINT64_C(0),        // baz
199// ENCODER:         UINT64_C(12),       // foo
200// ENCODER:         UINT64_C(2),        // unrelated
201// ENCODER-LABEL:   static const uint64_t InstBits_ModeB[] = {
202// ENCODER:         UINT64_C(2),        // bar
203// ENCODER:         UINT64_C(12),       // baz
204// ENCODER:         UINT64_C(3),        // foo
205// ENCODER:         UINT64_C(2),        // unrelated
206// ENCODER-LABEL:   static const uint64_t InstBits_ModeC[] = {
207// ENCODER:         UINT64_C(2),        // bar
208// ENCODER:         UINT64_C(0),        // baz
209// ENCODER:         UINT64_C(12582915), // foo
210// ENCODER:         UINT64_C(2),        // unrelated
211
212// ENCODER-LABEL: case ::bar:
213// ENCODER-LABEL: case ::unrelated:
214// ENCODER-NOT: getHwMode
215// ENCODER-LABEL: case ::foo: {
216// ENCODER: unsigned HwMode = STI.getHwMode(MCSubtargetInfo::HwMode_EncodingInfo);
217// ENCODER: switch (HwMode) {
218// ENCODER: default: llvm_unreachable("Unknown hardware mode!"); break;
219// ENCODER: case 0: InstBitsByHw = InstBits; break;
220// ENCODER: case 1: InstBitsByHw = InstBits_ModeA; break;
221// ENCODER: case 2: InstBitsByHw = InstBits_ModeB; break;
222// ENCODER: case 3: InstBitsByHw = InstBits_ModeC; break;
223// ENCODER: };
224// ENCODER: Value = InstBitsByHw[opcode];
225// ENCODER: switch (HwMode) {
226// ENCODER: default: llvm_unreachable("Unhandled HwMode");
227// ENCODER: case 0: {
228// ENCODER: op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI);
229// ENCODER: op &= UINT64_C(240);
230// ENCODER: Value |= op;
231// ENCODER: break;
232// ENCODER: }
233// ENCODER: case 1: {
234// ENCODER: op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI);
235// ENCODER: op &= UINT64_C(240);
236// ENCODER: Value |= op;
237// ENCODER: break;
238// ENCODER: }
239// ENCODER: case 2: {
240// ENCODER: op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI);
241// ENCODER: op &= UINT64_C(255);
242// ENCODER: op <<= 8;
243// ENCODER: Value |= op;
244// ENCODER: break;
245// ENCODER: }
246// ENCODER: case 3: {
247// ENCODER: op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI);
248// ENCODER: op &= UINT64_C(255);
249// ENCODER: op <<= 24;
250// ENCODER: Value |= op;
251// ENCODER: break;
252// ENCODER: }
253// ENCODER-LABEL: case ::baz: {
254// ENCODER: unsigned HwMode = STI.getHwMode(MCSubtargetInfo::HwMode_EncodingInfo);
255// ENCODER: switch (HwMode) {
256// ENCODER: default: llvm_unreachable("Unknown hardware mode!"); break;
257// ENCODER: case 2: InstBitsByHw = InstBits_ModeB; break;
258// ENCODER: };
259// ENCODER: Value = InstBitsByHw[opcode];
260// ENCODER: switch (HwMode) {
261// ENCODER: default: llvm_unreachable("Unhandled HwMode");
262// ENCODER: case 2: {
263// ENCODER: op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI);
264// ENCODER: op &= UINT64_C(240);
265// ENCODER: Value |= op;
266// ENCODER: break;
267// ENCODER: }
268