Skip to content

Commit 46343ca

Browse files
authored
[TableGen][DecoderEmitter] Add DecoderMethod to InstructionEncoding (NFC) (#154477)
We used to abuse Operands list to store instruction encoding's DecoderMethod there. Let's store it in the InstructionEncoding class instead, where it belongs.
1 parent dbbd3f0 commit 46343ca

File tree

1 file changed

+41
-11
lines changed

1 file changed

+41
-11
lines changed

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ class InstructionEncoding {
143143
/// The size of this encoding, in bits.
144144
unsigned BitWidth;
145145

146+
/// The name of the function to use for decoding. May be an empty string,
147+
/// meaning the decoder is generated.
148+
StringRef DecoderMethod;
149+
150+
/// Whether the custom decoding function always succeeds. Should not be used
151+
/// if the decoder is generated.
152+
bool HasCompleteDecoder = true;
153+
146154
/// Information about the operands' contribution to this encoding.
147155
SmallVector<OperandInfo, 16> Operands;
148156

@@ -156,12 +164,9 @@ class InstructionEncoding {
156164
Name = (EncodingDef->getName() + Twine(':')).str();
157165
Name.append(InstDef->getName());
158166

159-
StringRef DecoderMethod = EncodingDef->getValueAsString("DecoderMethod");
160-
if (!DecoderMethod.empty()) {
161-
bool HasCompleteDecoder =
162-
EncodingDef->getValueAsBit("hasCompleteDecoder");
163-
Operands.push_back(OperandInfo(DecoderMethod.str(), HasCompleteDecoder));
164-
}
167+
DecoderMethod = EncodingDef->getValueAsString("DecoderMethod");
168+
if (!DecoderMethod.empty())
169+
HasCompleteDecoder = EncodingDef->getValueAsBit("hasCompleteDecoder");
165170

166171
populateEncoding();
167172
}
@@ -178,6 +183,16 @@ class InstructionEncoding {
178183
/// Returns the size of this encoding, in bits.
179184
unsigned getBitWidth() const { return BitWidth; }
180185

186+
/// Returns the name of the function to use for decoding, or an empty string
187+
/// if the decoder is generated.
188+
StringRef getDecoderMethod() const { return DecoderMethod; }
189+
190+
/// Returns whether the custom decoding function always succeeds.
191+
bool hasCompleteDecoder() const {
192+
assert(!DecoderMethod.empty());
193+
return HasCompleteDecoder;
194+
}
195+
181196
/// Returns information about the operands' contribution to this encoding.
182197
ArrayRef<OperandInfo> getOperands() const { return Operands; }
183198

@@ -1253,10 +1268,25 @@ bool FilterChooser::emitBinaryParser(raw_ostream &OS, indent Indent,
12531268

12541269
bool FilterChooser::emitDecoder(raw_ostream &OS, indent Indent,
12551270
unsigned EncodingID) const {
1256-
bool HasCompleteDecoder = true;
1271+
const InstructionEncoding &Encoding = Encodings[EncodingID];
1272+
1273+
// If a custom instruction decoder was specified, use that.
1274+
StringRef DecoderMethod = Encoding.getDecoderMethod();
1275+
if (!DecoderMethod.empty()) {
1276+
bool HasCompleteDecoder = Encoding.hasCompleteDecoder();
1277+
OS << Indent << "if (!Check(S, " << DecoderMethod
1278+
<< "(MI, insn, Address, Decoder))) { "
1279+
<< (HasCompleteDecoder ? "" : "DecodeComplete = false; ")
1280+
<< "return MCDisassembler::Fail; }\n";
1281+
return HasCompleteDecoder;
1282+
}
12571283

1258-
for (const OperandInfo &Op : Encodings[EncodingID].getOperands()) {
1259-
// If a custom instruction decoder was specified, use that.
1284+
bool HasCompleteDecoder = true;
1285+
for (const OperandInfo &Op : Encoding.getOperands()) {
1286+
// FIXME: This is broken. If there is an operand that doesn't contribute
1287+
// to the encoding, we generate the same code as if the decoder method
1288+
// was specified on the encoding. And then we stop, ignoring the rest
1289+
// of the operands. M68k disassembler experiences this.
12601290
if (Op.numFields() == 0 && !Op.Decoder.empty()) {
12611291
HasCompleteDecoder = Op.HasCompleteDecoder;
12621292
OS << Indent << "if (!Check(S, " << Op.Decoder
@@ -2086,13 +2116,13 @@ void InstructionEncoding::populateEncoding() {
20862116
VarLenInst VLI(DI, InstField);
20872117
BitWidth = VLI.size();
20882118
// If the encoding has a custom decoder, don't bother parsing the operands.
2089-
if (Operands.empty())
2119+
if (DecoderMethod.empty())
20902120
populateVarLenEncoding(VLI);
20912121
} else {
20922122
const auto *BI = cast<BitsInit>(InstField->getValue());
20932123
BitWidth = BI->getNumBits();
20942124
// If the encoding has a custom decoder, don't bother parsing the operands.
2095-
if (Operands.empty())
2125+
if (DecoderMethod.empty())
20962126
populateFixedLenEncoding(*BI);
20972127
}
20982128
}

0 commit comments

Comments
 (0)