@@ -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
12541269bool 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