Skip to content

Commit ad43ea3

Browse files
authored
[TableGen] Add support for DefaultMode in per-HwMode encode/decode. (#83029)
Currently the decoder and encoder emitters will crash if DefaultMode is used within an EncodingByHwMode. As can be done today for RegInfoByHwMode and ValueTypeByHwMode, this patch adds support for this usage in EncodingByHwMode: let EncodingInfos = EncodingByHwMode<[ModeA, DefaultMode], [EncA, EncDefault]>;
1 parent 46bd65a commit ad43ea3

File tree

4 files changed

+183
-8
lines changed

4 files changed

+183
-8
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
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 -I \
6+
// RUN: %p/../../include %s | FileCheck %s --check-prefix=DECODER-SUPPRESS
7+
8+
include "llvm/Target/Target.td"
9+
10+
def archInstrInfo : InstrInfo { }
11+
12+
def arch : Target {
13+
let InstructionSet = archInstrInfo;
14+
}
15+
16+
def Myi32 : Operand<i32> {
17+
let DecoderMethod = "DecodeMyi32";
18+
}
19+
20+
def HasA : Predicate<"Subtarget->hasA()">;
21+
def HasB : Predicate<"Subtarget->hasB()">;
22+
23+
def ModeA : HwMode<"+a", [HasA]>;
24+
def ModeB : HwMode<"+b", [HasB]>;
25+
26+
27+
def fooTypeEncDefault : InstructionEncoding {
28+
let Size = 8;
29+
field bits<64> SoftFail = 0;
30+
bits<64> Inst;
31+
bits<8> factor;
32+
let Inst{7...0} = factor;
33+
let Inst{3...2} = 0b10;
34+
let Inst{1...0} = 0b00;
35+
}
36+
37+
def fooTypeEncA : InstructionEncoding {
38+
let Size = 4;
39+
field bits<32> SoftFail = 0;
40+
bits<32> Inst;
41+
bits<8> factor;
42+
let Inst{7...0} = factor;
43+
let Inst{3...2} = 0b11;
44+
let Inst{1...0} = 0b00;
45+
}
46+
47+
def fooTypeEncB : InstructionEncoding {
48+
let Size = 4;
49+
field bits<32> SoftFail = 0;
50+
bits<32> Inst;
51+
bits<8> factor;
52+
let Inst{15...8} = factor;
53+
let Inst{1...0} = 0b11;
54+
}
55+
56+
// Test for DefaultMode as a selector.
57+
def foo : Instruction {
58+
let OutOperandList = (outs);
59+
let InOperandList = (ins i32imm:$factor);
60+
let EncodingInfos = EncodingByHwMode<
61+
[ModeA, ModeB, DefaultMode], [fooTypeEncA, fooTypeEncB, fooTypeEncDefault]
62+
>;
63+
let AsmString = "foo $factor";
64+
}
65+
66+
def bar: Instruction {
67+
let OutOperandList = (outs);
68+
let InOperandList = (ins i32imm:$factor);
69+
let Size = 4;
70+
bits<32> Inst;
71+
bits<32> SoftFail;
72+
bits<8> factor;
73+
let Inst{31...24} = factor;
74+
let Inst{1...0} = 0b10;
75+
let AsmString = "bar $factor";
76+
}
77+
78+
def baz : Instruction {
79+
let OutOperandList = (outs);
80+
let InOperandList = (ins i32imm:$factor);
81+
bits<32> Inst;
82+
let EncodingInfos = EncodingByHwMode<
83+
[ModeB], [fooTypeEncA]
84+
>;
85+
let AsmString = "foo $factor";
86+
}
87+
88+
def unrelated: Instruction {
89+
let OutOperandList = (outs);
90+
let DecoderNamespace = "Alt";
91+
let InOperandList = (ins i32imm:$factor);
92+
let Size = 4;
93+
bits<32> Inst;
94+
bits<32> SoftFail;
95+
bits<8> factor;
96+
let Inst{31...24} = factor;
97+
let Inst{1...0} = 0b10;
98+
let AsmString = "unrelated $factor";
99+
}
100+
101+
102+
// DECODER-LABEL: DecoderTableAlt_DefaultMode32[] =
103+
// DECODER-DAG: Opcode: unrelated
104+
// DECODER-LABEL: DecoderTableAlt_ModeA32[] =
105+
// DECODER-DAG: Opcode: unrelated
106+
// DECODER-LABEL: DecoderTableAlt_ModeB32[] =
107+
// DECODER-DAG: Opcode: unrelated
108+
// DECODER-LABEL: DecoderTable_DefaultMode32[] =
109+
// DECODER-DAG: Opcode: bar
110+
// DECODER-LABEL: DecoderTable_DefaultMode64[] =
111+
// DECODER-DAG: Opcode: fooTypeEncDefault:foo
112+
// DECODER-LABEL: DecoderTable_ModeA32[] =
113+
// DECODER-DAG: Opcode: fooTypeEncA:foo
114+
// DECODER-DAG: Opcode: bar
115+
// DECODER-LABEL: DecoderTable_ModeB32[] =
116+
// DECODER-DAG: Opcode: fooTypeEncB:foo
117+
// DECODER-DAG: Opcode: fooTypeEncA:baz
118+
// DECODER-DAG: Opcode: bar
119+
120+
121+
// DECODER-SUPPRESS-LABEL: DecoderTableAlt_AllModes32[] =
122+
// DECODER-SUPPRESS-DAG: Opcode: unrelated
123+
// DECODER-SUPPRESS-LABEL: DecoderTable_AllModes32[] =
124+
// DECODER-SUPPRESS-DAG: Opcode: bar
125+
// DECODER-SUPPRESS-LABEL: DecoderTable_DefaultMode64[] =
126+
// DECODER-SUPPRESS-NOT: Opcode: bar
127+
// DECODER-SUPPRESS-DAG: Opcode: fooTypeEncDefault:foo
128+
// DECODER-SUPPRESS-LABEL: DecoderTable_ModeA32[] =
129+
// DECODER-SUPPRESS-DAG: Opcode: fooTypeEncA:foo
130+
// DECODER-SUPPRESS-NOT: Opcode: bar
131+
// DECODER-SUPPRESS-LABEL: DecoderTable_ModeB32[] =
132+
// DECODER-SUPPRESS-DAG: Opcode: fooTypeEncB:foo
133+
// DECODER-SUPPRESS-DAG: Opcode: fooTypeEncA:baz
134+
// DECODER-SUPPRESS-NOT: Opcode: bar
135+
136+
// ENCODER-LABEL: static const uint64_t InstBits_DefaultMode[] = {
137+
// ENCODER: UINT64_C(2), // bar
138+
// ENCODER: UINT64_C(0), // baz
139+
// ENCODER: UINT64_C(8), // foo
140+
// ENCODER: UINT64_C(2), // unrelated
141+
142+
// ENCODER-LABEL: static const uint64_t InstBits_ModeA[] = {
143+
// ENCODER: UINT64_C(2), // bar
144+
// ENCODER: UINT64_C(0), // baz
145+
// ENCODER: UINT64_C(12), // foo
146+
// ENCODER: UINT64_C(2), // unrelated
147+
148+
// ENCODER-LABEL: static const uint64_t InstBits_ModeB[] = {
149+
// ENCODER: UINT64_C(2), // bar
150+
// ENCODER: UINT64_C(12), // baz
151+
// ENCODER: UINT64_C(3), // foo
152+
// ENCODER: UINT64_C(2), // unrelated
153+
154+
// ENCODER: unsigned HwMode = STI.getHwMode();
155+
// ENCODER: switch (HwMode) {
156+
// ENCODER: default: llvm_unreachable("Unknown hardware mode!"); break;
157+
// ENCODER: case 0: InstBits = InstBits_DefaultMode; break;
158+
// ENCODER: case 1: InstBits = InstBits_ModeA; break;
159+
// ENCODER: case 2: InstBits = InstBits_ModeB; break;
160+
// ENCODER: };
161+
162+
// ENCODER: case ::foo: {
163+
// ENCODER: switch (HwMode) {
164+
// ENCODER: default: llvm_unreachable("Unhandled HwMode");
165+
// ENCODER: case 0: {
166+
// ENCODER: case 1: {
167+
// ENCODER: case 2: {
168+

llvm/utils/TableGen/CodeEmitterGen.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,8 @@ void CodeEmitterGen::emitInstructionBaseValues(
365365
if (HwMode == -1)
366366
o << " static const uint64_t InstBits[] = {\n";
367367
else
368-
o << " static const uint64_t InstBits_" << HWM.getMode(HwMode).Name
369-
<< "[] = {\n";
368+
o << " static const uint64_t InstBits_"
369+
<< HWM.getModeName(HwMode, /*IncludeDefault=*/true) << "[] = {\n";
370370

371371
for (const CodeGenInstruction *CGI : NumberedInstructions) {
372372
Record *R = CGI->TheDef;
@@ -495,8 +495,8 @@ void CodeEmitterGen::run(raw_ostream &o) {
495495
o << " switch (HwMode) {\n";
496496
o << " default: llvm_unreachable(\"Unknown hardware mode!\"); break;\n";
497497
for (unsigned I : HwModes) {
498-
o << " case " << I << ": InstBits = InstBits_" << HWM.getMode(I).Name
499-
<< "; break;\n";
498+
o << " case " << I << ": InstBits = InstBits_"
499+
<< HWM.getModeName(I, /*IncludeDefault=*/true) << "; break;\n";
500500
}
501501
o << " };\n";
502502
}

llvm/utils/TableGen/CodeGenHwModes.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ struct CodeGenHwModes {
5252
assert(Id != 0 && "Mode id of 0 is reserved for the default mode");
5353
return Modes[Id - 1];
5454
}
55+
StringRef getModeName(unsigned Id, bool IncludeDefault = false) const {
56+
if (IncludeDefault && Id == CodeGenHwModes::DefaultMode)
57+
return DefaultModeName;
58+
return getMode(Id).Name;
59+
}
5560
const HwModeSelect &getHwModeSelect(Record *R) const;
5661
const std::map<Record *, HwModeSelect> &getHwModeSelects() const {
5762
return ModeSelects;

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2461,8 +2461,9 @@ collectHwModesReferencedForEncodings(const CodeGenHwModes &HWM,
24612461
BV.set(P.first);
24622462
}
24632463
}
2464-
transform(BV.set_bits(), std::back_inserter(Names),
2465-
[&HWM](const int &M) { return HWM.getMode(M).Name; });
2464+
transform(BV.set_bits(), std::back_inserter(Names), [&HWM](const int &M) {
2465+
return HWM.getModeName(M, /*IncludeDefault=*/true);
2466+
});
24662467
}
24672468

24682469
// Emits disassembler code for instruction decoding.
@@ -2503,8 +2504,9 @@ void DecoderEmitter::run(raw_ostream &o) {
25032504
if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
25042505
EncodingInfoByHwMode EBM(DI->getDef(), HWM);
25052506
for (auto &KV : EBM)
2506-
NumberedEncodings.emplace_back(KV.second, NumberedInstruction,
2507-
HWM.getMode(KV.first).Name);
2507+
NumberedEncodings.emplace_back(
2508+
KV.second, NumberedInstruction,
2509+
HWM.getModeName(KV.first, /*IncludeDefault=*/true));
25082510
continue;
25092511
}
25102512
}

0 commit comments

Comments
 (0)