@@ -143,6 +143,14 @@ class InstructionEncoding {
143
143
// / The size of this encoding, in bits.
144
144
unsigned BitWidth;
145
145
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
+
146
154
// / Information about the operands' contribution to this encoding.
147
155
SmallVector<OperandInfo, 16 > Operands;
148
156
@@ -156,12 +164,9 @@ class InstructionEncoding {
156
164
Name = (EncodingDef->getName () + Twine (' :' )).str ();
157
165
Name.append (InstDef->getName ());
158
166
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" );
165
170
166
171
populateEncoding ();
167
172
}
@@ -178,6 +183,16 @@ class InstructionEncoding {
178
183
// / Returns the size of this encoding, in bits.
179
184
unsigned getBitWidth () const { return BitWidth; }
180
185
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
+
181
196
// / Returns information about the operands' contribution to this encoding.
182
197
ArrayRef<OperandInfo> getOperands () const { return Operands; }
183
198
@@ -1253,10 +1268,25 @@ bool FilterChooser::emitBinaryParser(raw_ostream &OS, indent Indent,
1253
1268
1254
1269
bool FilterChooser::emitDecoder (raw_ostream &OS, indent Indent,
1255
1270
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
+ }
1257
1283
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.
1260
1290
if (Op.numFields () == 0 && !Op.Decoder .empty ()) {
1261
1291
HasCompleteDecoder = Op.HasCompleteDecoder ;
1262
1292
OS << Indent << " if (!Check(S, " << Op.Decoder
@@ -2086,13 +2116,13 @@ void InstructionEncoding::populateEncoding() {
2086
2116
VarLenInst VLI (DI, InstField);
2087
2117
BitWidth = VLI.size ();
2088
2118
// If the encoding has a custom decoder, don't bother parsing the operands.
2089
- if (Operands .empty ())
2119
+ if (DecoderMethod .empty ())
2090
2120
populateVarLenEncoding (VLI);
2091
2121
} else {
2092
2122
const auto *BI = cast<BitsInit>(InstField->getValue ());
2093
2123
BitWidth = BI->getNumBits ();
2094
2124
// If the encoding has a custom decoder, don't bother parsing the operands.
2095
- if (Operands .empty ())
2125
+ if (DecoderMethod .empty ())
2096
2126
populateFixedLenEncoding (*BI);
2097
2127
}
2098
2128
}
0 commit comments