@@ -147,9 +147,10 @@ class InstructionEncoding {
147147 // / meaning the decoder is generated.
148148 StringRef DecoderMethod;
149149
150- // / Whether the custom decoding function always succeeds. Should not be used
151- // / if the decoder is generated.
152- bool HasCompleteDecoder = true ;
150+ // / Whether the custom decoding function always succeeds. If a custom decoder
151+ // / function is specified, the value is taken from the target description,
152+ // / otherwise it is inferred.
153+ bool HasCompleteDecoder;
153154
154155 // / Information about the operands' contribution to this encoding.
155156 SmallVector<OperandInfo, 16 > Operands;
@@ -174,11 +175,9 @@ class InstructionEncoding {
174175 // / if the decoder is generated.
175176 StringRef getDecoderMethod () const { return DecoderMethod; }
176177
177- // / Returns whether the custom decoding function always succeeds.
178- bool hasCompleteDecoder () const {
179- assert (!DecoderMethod.empty ());
180- return HasCompleteDecoder;
181- }
178+ // / Returns whether the decoder (either generated or specified by the user)
179+ // / always succeeds.
180+ bool hasCompleteDecoder () const { return HasCompleteDecoder; }
182181
183182 // / Returns information about the operands' contribution to this encoding.
184183 ArrayRef<OperandInfo> getOperands () const { return Operands; }
@@ -658,12 +657,11 @@ class FilterChooser {
658657 void emitSingletonTableEntry (DecoderTableInfo &TableInfo,
659658 const Filter &Best) const ;
660659
661- bool emitBinaryParser (raw_ostream &OS, indent Indent,
660+ void emitBinaryParser (raw_ostream &OS, indent Indent,
662661 const OperandInfo &OpInfo) const ;
663662
664- bool emitDecoder (raw_ostream &OS, indent Indent, unsigned EncodingID) const ;
665- std::pair<unsigned , bool > getDecoderIndex (DecoderSet &Decoders,
666- unsigned EncodingID) const ;
663+ void emitDecoder (raw_ostream &OS, indent Indent, unsigned EncodingID) const ;
664+ unsigned getDecoderIndex (DecoderSet &Decoders, unsigned EncodingID) const ;
667665
668666 // Assign a single filter and run with it.
669667 void runSingleFilter (unsigned startBit, unsigned numBit);
@@ -1212,7 +1210,7 @@ FilterChooser::getIslands(const insn_t &Insn) const {
12121210 return Islands;
12131211}
12141212
1215- bool FilterChooser::emitBinaryParser (raw_ostream &OS, indent Indent,
1213+ void FilterChooser::emitBinaryParser (raw_ostream &OS, indent Indent,
12161214 const OperandInfo &OpInfo) const {
12171215 const std::string &Decoder = OpInfo.Decoder ;
12181216
@@ -1238,65 +1236,56 @@ bool FilterChooser::emitBinaryParser(raw_ostream &OS, indent Indent,
12381236 OS << " ;\n " ;
12391237 }
12401238
1241- bool OpHasCompleteDecoder;
12421239 if (!Decoder.empty ()) {
1243- OpHasCompleteDecoder = OpInfo.HasCompleteDecoder ;
12441240 OS << Indent << " if (!Check(S, " << Decoder
12451241 << " (MI, tmp, Address, Decoder))) { "
1246- << (OpHasCompleteDecoder ? " " : " DecodeComplete = false; " )
1242+ << (OpInfo. HasCompleteDecoder ? " " : " DecodeComplete = false; " )
12471243 << " return MCDisassembler::Fail; }\n " ;
12481244 } else {
1249- OpHasCompleteDecoder = true ;
12501245 OS << Indent << " MI.addOperand(MCOperand::createImm(tmp));\n " ;
12511246 }
1252- return OpHasCompleteDecoder;
12531247}
12541248
1255- bool FilterChooser::emitDecoder (raw_ostream &OS, indent Indent,
1249+ void FilterChooser::emitDecoder (raw_ostream &OS, indent Indent,
12561250 unsigned EncodingID) const {
12571251 const InstructionEncoding &Encoding = Encodings[EncodingID];
12581252
12591253 // If a custom instruction decoder was specified, use that.
12601254 StringRef DecoderMethod = Encoding.getDecoderMethod ();
12611255 if (!DecoderMethod.empty ()) {
1262- bool HasCompleteDecoder = Encoding.hasCompleteDecoder ();
12631256 OS << Indent << " if (!Check(S, " << DecoderMethod
12641257 << " (MI, insn, Address, Decoder))) { "
1265- << (HasCompleteDecoder ? " " : " DecodeComplete = false; " )
1258+ << (Encoding. hasCompleteDecoder () ? " " : " DecodeComplete = false; " )
12661259 << " return MCDisassembler::Fail; }\n " ;
1267- return HasCompleteDecoder ;
1260+ return ;
12681261 }
12691262
1270- bool HasCompleteDecoder = true ;
12711263 for (const OperandInfo &Op : Encoding.getOperands ()) {
12721264 // FIXME: This is broken. If there is an operand that doesn't contribute
12731265 // to the encoding, we generate the same code as if the decoder method
12741266 // was specified on the encoding. And then we stop, ignoring the rest
12751267 // of the operands. M68k disassembler experiences this.
12761268 if (Op.numFields () == 0 && !Op.Decoder .empty ()) {
1277- HasCompleteDecoder = Op.HasCompleteDecoder ;
12781269 OS << Indent << " if (!Check(S, " << Op.Decoder
12791270 << " (MI, insn, Address, Decoder))) { "
1280- << (HasCompleteDecoder ? " " : " DecodeComplete = false; " )
1271+ << (Op. HasCompleteDecoder ? " " : " DecodeComplete = false; " )
12811272 << " return MCDisassembler::Fail; }\n " ;
12821273 break ;
12831274 }
12841275
1285- HasCompleteDecoder &= emitBinaryParser (OS, Indent, Op);
1276+ emitBinaryParser (OS, Indent, Op);
12861277 }
1287- return HasCompleteDecoder;
12881278}
12891279
1290- std::pair<unsigned , bool >
1291- FilterChooser::getDecoderIndex (DecoderSet &Decoders,
1292- unsigned EncodingID) const {
1280+ unsigned FilterChooser::getDecoderIndex (DecoderSet &Decoders,
1281+ unsigned EncodingID) const {
12931282 // Build up the predicate string.
12941283 SmallString<256 > Decoder;
12951284 // FIXME: emitDecoder() function can take a buffer directly rather than
12961285 // a stream.
12971286 raw_svector_ostream S (Decoder);
12981287 indent Indent (UseFnTableInDecodeToMCInst ? 2 : 4 );
1299- bool HasCompleteDecoder = emitDecoder (S, Indent, EncodingID);
1288+ emitDecoder (S, Indent, EncodingID);
13001289
13011290 // Using the full decoder string as the key value here is a bit
13021291 // heavyweight, but is effective. If the string comparisons become a
@@ -1308,7 +1297,7 @@ FilterChooser::getDecoderIndex(DecoderSet &Decoders,
13081297 Decoders.insert (CachedHashString (Decoder));
13091298 // Now figure out the index for when we write out the table.
13101299 DecoderSet::const_iterator P = find (Decoders, Decoder.str ());
1311- return {( unsigned )(P - Decoders.begin ()), HasCompleteDecoder} ;
1300+ return std::distance ( Decoders.begin (), P) ;
13121301}
13131302
13141303// If ParenIfBinOp is true, print a surrounding () if Val uses && or ||.
@@ -1508,8 +1497,7 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
15081497 // Check for soft failure of the match.
15091498 emitSoftFailTableEntry (TableInfo, EncodingID);
15101499
1511- auto [DIdx, HasCompleteDecoder] =
1512- getDecoderIndex (TableInfo.Decoders , EncodingID);
1500+ unsigned DIdx = getDecoderIndex (TableInfo.Decoders , EncodingID);
15131501
15141502 // Produce OPC_Decode or OPC_TryDecode opcode based on the information
15151503 // whether the instruction decoder is complete or not. If it is complete
@@ -1520,10 +1508,12 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
15201508 // decoder method indicates that additional processing should be done to see
15211509 // if there is any other instruction that also matches the bitpattern and
15221510 // can decode it.
1523- const uint8_t DecoderOp = HasCompleteDecoder ? MCD::OPC_Decode
1524- : (TableInfo.isOutermostScope ()
1525- ? MCD::OPC_TryDecodeOrFail
1526- : MCD::OPC_TryDecode);
1511+ const InstructionEncoding &Encoding = Encodings[EncodingID];
1512+ const uint8_t DecoderOp =
1513+ Encoding.hasCompleteDecoder ()
1514+ ? MCD::OPC_Decode
1515+ : (TableInfo.isOutermostScope () ? MCD::OPC_TryDecodeOrFail
1516+ : MCD::OPC_TryDecode);
15271517 TableInfo.Table .push_back (DecoderOp);
15281518 const Record *InstDef = Encodings[EncodingID].getInstruction ()->TheDef ;
15291519 TableInfo.Table .insertULEB128 (Emitter->getTarget ().getInstrIntValue (InstDef));
@@ -2124,6 +2114,16 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef,
21242114 if (DecoderMethod.empty ())
21252115 parseFixedLenOperands (*BI);
21262116 }
2117+
2118+ if (DecoderMethod.empty ()) {
2119+ // A generated decoder is always successful if none of the operand
2120+ // decoders can fail (all are always successful).
2121+ HasCompleteDecoder = all_of (Operands, [](const OperandInfo &Op) {
2122+ // By default, a generated operand decoder is assumed to always succeed.
2123+ // This can be overridden by the user.
2124+ return Op.Decoder .empty () || Op.HasCompleteDecoder ;
2125+ });
2126+ }
21272127}
21282128
21292129// emitFieldFromInstruction - Emit the templated helper function
0 commit comments