xref: /src/contrib/llvm-project/llvm/utils/TableGen/DecoderEmitter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1145449b1SDimitry Andric //===---------------- DecoderEmitter.cpp - Decoder Generator --------------===//
2cf099d11SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cf099d11SDimitry Andric //
7cf099d11SDimitry Andric //===----------------------------------------------------------------------===//
8cf099d11SDimitry Andric //
9cf099d11SDimitry Andric // It contains the tablegen backend that emits the decoder functions for
10145449b1SDimitry Andric // targets with fixed/variable length instruction set.
11cf099d11SDimitry Andric //
12cf099d11SDimitry Andric //===----------------------------------------------------------------------===//
13cf099d11SDimitry Andric 
14ac9a064cSDimitry Andric #include "Common/CodeGenHwModes.h"
15ac9a064cSDimitry Andric #include "Common/CodeGenInstruction.h"
16ac9a064cSDimitry Andric #include "Common/CodeGenTarget.h"
17ac9a064cSDimitry Andric #include "Common/InfoByHwMode.h"
18ac9a064cSDimitry Andric #include "Common/VarLenCodeEmitterGen.h"
197fa27ce4SDimitry Andric #include "TableGenBackends.h"
2063faed5bSDimitry Andric #include "llvm/ADT/APInt.h"
21b915e9e0SDimitry Andric #include "llvm/ADT/ArrayRef.h"
22b915e9e0SDimitry Andric #include "llvm/ADT/CachedHashString.h"
23b915e9e0SDimitry Andric #include "llvm/ADT/STLExtras.h"
24e6d15924SDimitry Andric #include "llvm/ADT/SetVector.h"
25ac9a064cSDimitry Andric #include "llvm/ADT/SmallBitVector.h"
26e6d15924SDimitry Andric #include "llvm/ADT/SmallString.h"
27e6d15924SDimitry Andric #include "llvm/ADT/Statistic.h"
28cf099d11SDimitry Andric #include "llvm/ADT/StringExtras.h"
29902a7b52SDimitry Andric #include "llvm/ADT/StringRef.h"
30145449b1SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
31b915e9e0SDimitry Andric #include "llvm/Support/Casting.h"
32ac9a064cSDimitry Andric #include "llvm/Support/CommandLine.h"
33cf099d11SDimitry Andric #include "llvm/Support/Debug.h"
34b915e9e0SDimitry Andric #include "llvm/Support/ErrorHandling.h"
35902a7b52SDimitry Andric #include "llvm/Support/FormattedStream.h"
36902a7b52SDimitry Andric #include "llvm/Support/LEB128.h"
37cf099d11SDimitry Andric #include "llvm/Support/raw_ostream.h"
384a16efa3SDimitry Andric #include "llvm/TableGen/Error.h"
394a16efa3SDimitry Andric #include "llvm/TableGen/Record.h"
40b915e9e0SDimitry Andric #include <algorithm>
41b915e9e0SDimitry Andric #include <cassert>
42b915e9e0SDimitry Andric #include <cstddef>
43b915e9e0SDimitry Andric #include <cstdint>
44cf099d11SDimitry Andric #include <map>
45b915e9e0SDimitry Andric #include <memory>
46b915e9e0SDimitry Andric #include <set>
47cf099d11SDimitry Andric #include <string>
4801095a5dSDimitry Andric #include <utility>
494a16efa3SDimitry Andric #include <vector>
50cf099d11SDimitry Andric 
51cf099d11SDimitry Andric using namespace llvm;
52cf099d11SDimitry Andric 
535ca98fd9SDimitry Andric #define DEBUG_TYPE "decoder-emitter"
545ca98fd9SDimitry Andric 
55ac9a064cSDimitry Andric extern cl::OptionCategory DisassemblerEmitterCat;
56ac9a064cSDimitry Andric 
57ac9a064cSDimitry Andric enum SuppressLevel {
58ac9a064cSDimitry Andric   SUPPRESSION_DISABLE,
59ac9a064cSDimitry Andric   SUPPRESSION_LEVEL1,
60ac9a064cSDimitry Andric   SUPPRESSION_LEVEL2
61ac9a064cSDimitry Andric };
62ac9a064cSDimitry Andric 
63ac9a064cSDimitry Andric cl::opt<SuppressLevel> DecoderEmitterSuppressDuplicates(
64ac9a064cSDimitry Andric     "suppress-per-hwmode-duplicates",
65ac9a064cSDimitry Andric     cl::desc("Suppress duplication of instrs into per-HwMode decoder tables"),
66ac9a064cSDimitry Andric     cl::values(
67ac9a064cSDimitry Andric         clEnumValN(
68ac9a064cSDimitry Andric             SUPPRESSION_DISABLE, "O0",
69ac9a064cSDimitry Andric             "Do not prevent DecoderTable duplications caused by HwModes"),
70ac9a064cSDimitry Andric         clEnumValN(
71ac9a064cSDimitry Andric             SUPPRESSION_LEVEL1, "O1",
72ac9a064cSDimitry Andric             "Remove duplicate DecoderTable entries generated due to HwModes"),
73ac9a064cSDimitry Andric         clEnumValN(
74ac9a064cSDimitry Andric             SUPPRESSION_LEVEL2, "O2",
75ac9a064cSDimitry Andric             "Extract HwModes-specific instructions into new DecoderTables, "
76ac9a064cSDimitry Andric             "significantly reducing Table Duplications")),
77ac9a064cSDimitry Andric     cl::init(SUPPRESSION_DISABLE), cl::cat(DisassemblerEmitterCat));
78ac9a064cSDimitry Andric 
7958b69754SDimitry Andric namespace {
80b915e9e0SDimitry Andric 
81e6d15924SDimitry Andric STATISTIC(NumEncodings, "Number of encodings considered");
82ac9a064cSDimitry Andric STATISTIC(NumEncodingsLackingDisasm,
83ac9a064cSDimitry Andric           "Number of encodings without disassembler info");
84e6d15924SDimitry Andric STATISTIC(NumInstructions, "Number of instructions considered");
85e6d15924SDimitry Andric STATISTIC(NumEncodingsSupported, "Number of encodings supported");
86e6d15924SDimitry Andric STATISTIC(NumEncodingsOmitted, "Number of encodings omitted");
87e6d15924SDimitry Andric 
8858b69754SDimitry Andric struct EncodingField {
8958b69754SDimitry Andric   unsigned Base, Width, Offset;
EncodingField__anon260f03c00111::EncodingField9058b69754SDimitry Andric   EncodingField(unsigned B, unsigned W, unsigned O)
9158b69754SDimitry Andric       : Base(B), Width(W), Offset(O) {}
9258b69754SDimitry Andric };
9358b69754SDimitry Andric 
9458b69754SDimitry Andric struct OperandInfo {
9558b69754SDimitry Andric   std::vector<EncodingField> Fields;
9658b69754SDimitry Andric   std::string Decoder;
97dd58ef01SDimitry Andric   bool HasCompleteDecoder;
981d5ae102SDimitry Andric   uint64_t InitValue;
9958b69754SDimitry Andric 
OperandInfo__anon260f03c00111::OperandInfo100dd58ef01SDimitry Andric   OperandInfo(std::string D, bool HCD)
1011d5ae102SDimitry Andric       : Decoder(std::move(D)), HasCompleteDecoder(HCD), InitValue(0) {}
10258b69754SDimitry Andric 
addField__anon260f03c00111::OperandInfo10358b69754SDimitry Andric   void addField(unsigned Base, unsigned Width, unsigned Offset) {
10458b69754SDimitry Andric     Fields.push_back(EncodingField(Base, Width, Offset));
10558b69754SDimitry Andric   }
10658b69754SDimitry Andric 
numFields__anon260f03c00111::OperandInfo10758b69754SDimitry Andric   unsigned numFields() const { return Fields.size(); }
10858b69754SDimitry Andric 
10958b69754SDimitry Andric   typedef std::vector<EncodingField>::const_iterator const_iterator;
11058b69754SDimitry Andric 
begin__anon260f03c00111::OperandInfo11158b69754SDimitry Andric   const_iterator begin() const { return Fields.begin(); }
end__anon260f03c00111::OperandInfo11258b69754SDimitry Andric   const_iterator end() const { return Fields.end(); }
11358b69754SDimitry Andric };
114902a7b52SDimitry Andric 
115902a7b52SDimitry Andric typedef std::vector<uint8_t> DecoderTable;
116902a7b52SDimitry Andric typedef uint32_t DecoderFixup;
117902a7b52SDimitry Andric typedef std::vector<DecoderFixup> FixupList;
118902a7b52SDimitry Andric typedef std::vector<FixupList> FixupScopeList;
119b915e9e0SDimitry Andric typedef SmallSetVector<CachedHashString, 16> PredicateSet;
120b915e9e0SDimitry Andric typedef SmallSetVector<CachedHashString, 16> DecoderSet;
121902a7b52SDimitry Andric struct DecoderTableInfo {
122902a7b52SDimitry Andric   DecoderTable Table;
123902a7b52SDimitry Andric   FixupScopeList FixupStack;
124902a7b52SDimitry Andric   PredicateSet Predicates;
125902a7b52SDimitry Andric   DecoderSet Decoders;
126902a7b52SDimitry Andric };
127902a7b52SDimitry Andric 
128d8e91e46SDimitry Andric struct EncodingAndInst {
129d8e91e46SDimitry Andric   const Record *EncodingDef;
130d8e91e46SDimitry Andric   const CodeGenInstruction *Inst;
1311d5ae102SDimitry Andric   StringRef HwModeName;
132d8e91e46SDimitry Andric 
EncodingAndInst__anon260f03c00111::EncodingAndInst1331d5ae102SDimitry Andric   EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst,
1341d5ae102SDimitry Andric                   StringRef HwModeName = "")
1351d5ae102SDimitry Andric       : EncodingDef(EncodingDef), Inst(Inst), HwModeName(HwModeName) {}
136d8e91e46SDimitry Andric };
137d8e91e46SDimitry Andric 
138e6d15924SDimitry Andric struct EncodingIDAndOpcode {
139e6d15924SDimitry Andric   unsigned EncodingID;
140e6d15924SDimitry Andric   unsigned Opcode;
141e6d15924SDimitry Andric 
EncodingIDAndOpcode__anon260f03c00111::EncodingIDAndOpcode142e6d15924SDimitry Andric   EncodingIDAndOpcode() : EncodingID(0), Opcode(0) {}
EncodingIDAndOpcode__anon260f03c00111::EncodingIDAndOpcode143e6d15924SDimitry Andric   EncodingIDAndOpcode(unsigned EncodingID, unsigned Opcode)
144e6d15924SDimitry Andric       : EncodingID(EncodingID), Opcode(Opcode) {}
145e6d15924SDimitry Andric };
146e6d15924SDimitry Andric 
147ac9a064cSDimitry Andric using EncodingIDsVec = std::vector<EncodingIDAndOpcode>;
148ac9a064cSDimitry Andric using NamespacesHwModesMap = std::map<std::string, std::set<StringRef>>;
149ac9a064cSDimitry Andric 
operator <<(raw_ostream & OS,const EncodingAndInst & Value)150d8e91e46SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {
151d8e91e46SDimitry Andric   if (Value.EncodingDef != Value.Inst->TheDef)
152d8e91e46SDimitry Andric     OS << Value.EncodingDef->getName() << ":";
153d8e91e46SDimitry Andric   OS << Value.Inst->TheDef->getName();
154d8e91e46SDimitry Andric   return OS;
155d8e91e46SDimitry Andric }
156d8e91e46SDimitry Andric 
157145449b1SDimitry Andric class DecoderEmitter {
158e6d15924SDimitry Andric   RecordKeeper &RK;
159d8e91e46SDimitry Andric   std::vector<EncodingAndInst> NumberedEncodings;
16058b69754SDimitry Andric 
161b915e9e0SDimitry Andric public:
DecoderEmitter(RecordKeeper & R,std::string PredicateNamespace)162e3b55780SDimitry Andric   DecoderEmitter(RecordKeeper &R, std::string PredicateNamespace)
163e3b55780SDimitry Andric       : RK(R), Target(R), PredicateNamespace(std::move(PredicateNamespace)) {}
16458b69754SDimitry Andric 
165902a7b52SDimitry Andric   // Emit the decoder state machine table.
166902a7b52SDimitry Andric   void emitTable(formatted_raw_ostream &o, DecoderTable &Table,
167ac9a064cSDimitry Andric                  unsigned Indentation, unsigned BitWidth, StringRef Namespace,
168ac9a064cSDimitry Andric                  const EncodingIDsVec &EncodingIDs) const;
169145449b1SDimitry Andric   void emitInstrLenTable(formatted_raw_ostream &OS,
170145449b1SDimitry Andric                          std::vector<unsigned> &InstrLen) const;
171902a7b52SDimitry Andric   void emitPredicateFunction(formatted_raw_ostream &OS,
172902a7b52SDimitry Andric                              PredicateSet &Predicates,
173902a7b52SDimitry Andric                              unsigned Indentation) const;
174ac9a064cSDimitry Andric   void emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
175902a7b52SDimitry Andric                            unsigned Indentation) const;
176902a7b52SDimitry Andric 
17758b69754SDimitry Andric   // run - Output the code emitter
17858b69754SDimitry Andric   void run(raw_ostream &o);
17958b69754SDimitry Andric 
18058b69754SDimitry Andric private:
18158b69754SDimitry Andric   CodeGenTarget Target;
182b915e9e0SDimitry Andric 
18358b69754SDimitry Andric public:
18458b69754SDimitry Andric   std::string PredicateNamespace;
18558b69754SDimitry Andric };
186b915e9e0SDimitry Andric 
187b915e9e0SDimitry Andric } // end anonymous namespace
18858b69754SDimitry Andric 
189cf099d11SDimitry Andric // The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system
190cf099d11SDimitry Andric // for a bit value.
191cf099d11SDimitry Andric //
192cf099d11SDimitry Andric // BIT_UNFILTERED is used as the init value for a filter position.  It is used
193cf099d11SDimitry Andric // only for filter processings.
194cf099d11SDimitry Andric typedef enum {
195cf099d11SDimitry Andric   BIT_TRUE,      // '1'
196cf099d11SDimitry Andric   BIT_FALSE,     // '0'
197cf099d11SDimitry Andric   BIT_UNSET,     // '?'
198cf099d11SDimitry Andric   BIT_UNFILTERED // unfiltered
199cf099d11SDimitry Andric } bit_value_t;
200cf099d11SDimitry Andric 
ValueSet(bit_value_t V)201cf099d11SDimitry Andric static bool ValueSet(bit_value_t V) {
202cf099d11SDimitry Andric   return (V == BIT_TRUE || V == BIT_FALSE);
203cf099d11SDimitry Andric }
204b915e9e0SDimitry Andric 
ValueNotSet(bit_value_t V)205ac9a064cSDimitry Andric static bool ValueNotSet(bit_value_t V) { return (V == BIT_UNSET); }
206b915e9e0SDimitry Andric 
Value(bit_value_t V)207cf099d11SDimitry Andric static int Value(bit_value_t V) {
208cf099d11SDimitry Andric   return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1);
209cf099d11SDimitry Andric }
210b915e9e0SDimitry Andric 
bitFromBits(const BitsInit & bits,unsigned index)21163faed5bSDimitry Andric static bit_value_t bitFromBits(const BitsInit &bits, unsigned index) {
212522600a2SDimitry Andric   if (BitInit *bit = dyn_cast<BitInit>(bits.getBit(index)))
213cf099d11SDimitry Andric     return bit->getValue() ? BIT_TRUE : BIT_FALSE;
214cf099d11SDimitry Andric 
215cf099d11SDimitry Andric   // The bit is uninitialized.
216cf099d11SDimitry Andric   return BIT_UNSET;
217cf099d11SDimitry Andric }
218b915e9e0SDimitry Andric 
219cf099d11SDimitry Andric // Prints the bit value for each position.
dumpBits(raw_ostream & o,const BitsInit & bits)22063faed5bSDimitry Andric static void dumpBits(raw_ostream &o, const BitsInit &bits) {
221902a7b52SDimitry Andric   for (unsigned index = bits.getNumBits(); index > 0; --index) {
222cf099d11SDimitry Andric     switch (bitFromBits(bits, index - 1)) {
223cf099d11SDimitry Andric     case BIT_TRUE:
224cf099d11SDimitry Andric       o << "1";
225cf099d11SDimitry Andric       break;
226cf099d11SDimitry Andric     case BIT_FALSE:
227cf099d11SDimitry Andric       o << "0";
228cf099d11SDimitry Andric       break;
229cf099d11SDimitry Andric     case BIT_UNSET:
230cf099d11SDimitry Andric       o << "_";
231cf099d11SDimitry Andric       break;
232cf099d11SDimitry Andric     default:
23363faed5bSDimitry Andric       llvm_unreachable("unexpected return value from bitFromBits");
234cf099d11SDimitry Andric     }
235cf099d11SDimitry Andric   }
236cf099d11SDimitry Andric }
237cf099d11SDimitry Andric 
getBitsField(const Record & def,StringRef str)238b915e9e0SDimitry Andric static BitsInit &getBitsField(const Record &def, StringRef str) {
239145449b1SDimitry Andric   const RecordVal *RV = def.getValue(str);
240145449b1SDimitry Andric   if (BitsInit *Bits = dyn_cast<BitsInit>(RV->getValue()))
241145449b1SDimitry Andric     return *Bits;
242145449b1SDimitry Andric 
243145449b1SDimitry Andric   // variable length instruction
244145449b1SDimitry Andric   VarLenInst VLI = VarLenInst(cast<DagInit>(RV->getValue()), RV);
245145449b1SDimitry Andric   SmallVector<Init *, 16> Bits;
246145449b1SDimitry Andric 
247ac9a064cSDimitry Andric   for (const auto &SI : VLI) {
248145449b1SDimitry Andric     if (const BitsInit *BI = dyn_cast<BitsInit>(SI.Value)) {
249145449b1SDimitry Andric       for (unsigned Idx = 0U; Idx < BI->getNumBits(); ++Idx) {
250145449b1SDimitry Andric         Bits.push_back(BI->getBit(Idx));
251145449b1SDimitry Andric       }
252145449b1SDimitry Andric     } else if (const BitInit *BI = dyn_cast<BitInit>(SI.Value)) {
253145449b1SDimitry Andric       Bits.push_back(const_cast<BitInit *>(BI));
254145449b1SDimitry Andric     } else {
255145449b1SDimitry Andric       for (unsigned Idx = 0U; Idx < SI.BitWidth; ++Idx)
256145449b1SDimitry Andric         Bits.push_back(UnsetInit::get(def.getRecords()));
257145449b1SDimitry Andric     }
258145449b1SDimitry Andric   }
259145449b1SDimitry Andric 
260145449b1SDimitry Andric   return *BitsInit::get(def.getRecords(), Bits);
261cf099d11SDimitry Andric }
262cf099d11SDimitry Andric 
263cf099d11SDimitry Andric // Representation of the instruction to work on.
26430815c53SDimitry Andric typedef std::vector<bit_value_t> insn_t;
265cf099d11SDimitry Andric 
266b915e9e0SDimitry Andric namespace {
267b915e9e0SDimitry Andric 
268b60736ecSDimitry Andric static const uint64_t NO_FIXED_SEGMENTS_SENTINEL = -1ULL;
269b60736ecSDimitry Andric 
270b915e9e0SDimitry Andric class FilterChooser;
271b915e9e0SDimitry Andric 
272cf099d11SDimitry Andric /// Filter - Filter works with FilterChooser to produce the decoding tree for
273cf099d11SDimitry Andric /// the ISA.
274cf099d11SDimitry Andric ///
275cf099d11SDimitry Andric /// It is useful to think of a Filter as governing the switch stmts of the
276cf099d11SDimitry Andric /// decoding tree in a certain level.  Each case stmt delegates to an inferior
277cf099d11SDimitry Andric /// FilterChooser to decide what further decoding logic to employ, or in another
278cf099d11SDimitry Andric /// words, what other remaining bits to look at.  The FilterChooser eventually
279cf099d11SDimitry Andric /// chooses a best Filter to do its job.
280cf099d11SDimitry Andric ///
281cf099d11SDimitry Andric /// This recursive scheme ends when the number of Opcodes assigned to the
282cf099d11SDimitry Andric /// FilterChooser becomes 1 or if there is a conflict.  A conflict happens when
283cf099d11SDimitry Andric /// the Filter/FilterChooser combo does not know how to distinguish among the
284cf099d11SDimitry Andric /// Opcodes assigned.
285cf099d11SDimitry Andric ///
286cf099d11SDimitry Andric /// An example of a conflict is
287cf099d11SDimitry Andric ///
288cf099d11SDimitry Andric /// Conflict:
289cf099d11SDimitry Andric ///                     111101000.00........00010000....
290cf099d11SDimitry Andric ///                     111101000.00........0001........
291cf099d11SDimitry Andric ///                     1111010...00........0001........
292cf099d11SDimitry Andric ///                     1111010...00....................
293cf099d11SDimitry Andric ///                     1111010.........................
294cf099d11SDimitry Andric ///                     1111............................
295cf099d11SDimitry Andric ///                     ................................
296cf099d11SDimitry Andric ///     VST4q8a         111101000_00________00010000____
297cf099d11SDimitry Andric ///     VST4q8b         111101000_00________00010000____
298cf099d11SDimitry Andric ///
299cf099d11SDimitry Andric /// The Debug output shows the path that the decoding tree follows to reach the
300cf099d11SDimitry Andric /// the conclusion that there is a conflict.  VST4q8a is a vst4 to double-spaced
301ee8648bdSDimitry Andric /// even registers, while VST4q8b is a vst4 to double-spaced odd registers.
302cf099d11SDimitry Andric ///
303cf099d11SDimitry Andric /// The encoding info in the .td files does not specify this meta information,
304cf099d11SDimitry Andric /// which could have been used by the decoder to resolve the conflict.  The
305cf099d11SDimitry Andric /// decoder could try to decode the even/odd register numbering and assign to
306cf099d11SDimitry Andric /// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a"
307cf099d11SDimitry Andric /// version and return the Opcode since the two have the same Asm format string.
308cf099d11SDimitry Andric class Filter {
309cf099d11SDimitry Andric protected:
310ac9a064cSDimitry Andric   const FilterChooser
311ac9a064cSDimitry Andric       *Owner;        // points to the FilterChooser who owns this filter
312cf099d11SDimitry Andric   unsigned StartBit; // the starting bit position
313cf099d11SDimitry Andric   unsigned NumBits;  // number of bits to filter
314cf099d11SDimitry Andric   bool Mixed;        // a mixed region contains both set and unset bits
315cf099d11SDimitry Andric 
316cf099d11SDimitry Andric   // Map of well-known segment value to the set of uid's with that value.
317ac9a064cSDimitry Andric   std::map<uint64_t, std::vector<EncodingIDAndOpcode>> FilteredInstructions;
318cf099d11SDimitry Andric 
319cf099d11SDimitry Andric   // Set of uid's with non-constant segment values.
320e6d15924SDimitry Andric   std::vector<EncodingIDAndOpcode> VariableInstructions;
321cf099d11SDimitry Andric 
322cf099d11SDimitry Andric   // Map of well-known segment value to its delegate.
323b60736ecSDimitry Andric   std::map<uint64_t, std::unique_ptr<const FilterChooser>> FilterChooserMap;
324cf099d11SDimitry Andric 
325cf099d11SDimitry Andric   // Number of instructions which fall under FilteredInstructions category.
326cf099d11SDimitry Andric   unsigned NumFiltered;
327cf099d11SDimitry Andric 
328cf099d11SDimitry Andric   // Keeps track of the last opcode in the filtered bucket.
329e6d15924SDimitry Andric   EncodingIDAndOpcode LastOpcFiltered;
330cf099d11SDimitry Andric 
331cf099d11SDimitry Andric public:
332b915e9e0SDimitry Andric   Filter(Filter &&f);
333b915e9e0SDimitry Andric   Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed);
334b915e9e0SDimitry Andric 
335b915e9e0SDimitry Andric   ~Filter() = default;
336b915e9e0SDimitry Andric 
getNumFiltered() const33763faed5bSDimitry Andric   unsigned getNumFiltered() const { return NumFiltered; }
338b915e9e0SDimitry Andric 
getSingletonOpc() const339e6d15924SDimitry Andric   EncodingIDAndOpcode getSingletonOpc() const {
340cf099d11SDimitry Andric     assert(NumFiltered == 1);
341cf099d11SDimitry Andric     return LastOpcFiltered;
342cf099d11SDimitry Andric   }
343b915e9e0SDimitry Andric 
344cf099d11SDimitry Andric   // Return the filter chooser for the group of instructions without constant
345cf099d11SDimitry Andric   // segment values.
getVariableFC() const34663faed5bSDimitry Andric   const FilterChooser &getVariableFC() const {
347cf099d11SDimitry Andric     assert(NumFiltered == 1);
348cf099d11SDimitry Andric     assert(FilterChooserMap.size() == 1);
349b60736ecSDimitry Andric     return *(FilterChooserMap.find(NO_FIXED_SEGMENTS_SENTINEL)->second);
350cf099d11SDimitry Andric   }
351cf099d11SDimitry Andric 
352cf099d11SDimitry Andric   // Divides the decoding task into sub tasks and delegates them to the
353cf099d11SDimitry Andric   // inferior FilterChooser's.
354cf099d11SDimitry Andric   //
355cf099d11SDimitry Andric   // A special case arises when there's only one entry in the filtered
356cf099d11SDimitry Andric   // instructions.  In order to unambiguously decode the singleton, we need to
357cf099d11SDimitry Andric   // match the remaining undecoded encoding bits against the singleton.
358cf099d11SDimitry Andric   void recurse();
359cf099d11SDimitry Andric 
360902a7b52SDimitry Andric   // Emit table entries to decode instructions given a segment or segments of
361902a7b52SDimitry Andric   // bits.
362902a7b52SDimitry Andric   void emitTableEntry(DecoderTableInfo &TableInfo) const;
363cf099d11SDimitry Andric 
364cf099d11SDimitry Andric   // Returns the number of fanout produced by the filter.  More fanout implies
365cf099d11SDimitry Andric   // the filter distinguishes more categories of instructions.
366cf099d11SDimitry Andric   unsigned usefulness() const;
367b915e9e0SDimitry Andric }; // end class Filter
368b915e9e0SDimitry Andric 
369b915e9e0SDimitry Andric } // end anonymous namespace
370cf099d11SDimitry Andric 
371cf099d11SDimitry Andric // These are states of our finite state machines used in FilterChooser's
372cf099d11SDimitry Andric // filterProcessor() which produces the filter candidates to use.
373cf099d11SDimitry Andric typedef enum {
374cf099d11SDimitry Andric   ATTR_NONE,
375cf099d11SDimitry Andric   ATTR_FILTERED,
376cf099d11SDimitry Andric   ATTR_ALL_SET,
377cf099d11SDimitry Andric   ATTR_ALL_UNSET,
378cf099d11SDimitry Andric   ATTR_MIXED
379cf099d11SDimitry Andric } bitAttr_t;
380cf099d11SDimitry Andric 
381cf099d11SDimitry Andric /// FilterChooser - FilterChooser chooses the best filter among a set of Filters
382cf099d11SDimitry Andric /// in order to perform the decoding of instructions at the current level.
383cf099d11SDimitry Andric ///
384cf099d11SDimitry Andric /// Decoding proceeds from the top down.  Based on the well-known encoding bits
385cf099d11SDimitry Andric /// of instructions available, FilterChooser builds up the possible Filters that
386cf099d11SDimitry Andric /// can further the task of decoding by distinguishing among the remaining
387cf099d11SDimitry Andric /// candidate instructions.
388cf099d11SDimitry Andric ///
389cf099d11SDimitry Andric /// Once a filter has been chosen, it is called upon to divide the decoding task
390cf099d11SDimitry Andric /// into sub-tasks and delegates them to its inferior FilterChoosers for further
391cf099d11SDimitry Andric /// processings.
392cf099d11SDimitry Andric ///
393cf099d11SDimitry Andric /// It is useful to think of a Filter as governing the switch stmts of the
394cf099d11SDimitry Andric /// decoding tree.  And each case is delegated to an inferior FilterChooser to
395cf099d11SDimitry Andric /// decide what further remaining bits to look at.
39658b69754SDimitry Andric namespace {
397b915e9e0SDimitry Andric 
398cf099d11SDimitry Andric class FilterChooser {
399cf099d11SDimitry Andric protected:
400cf099d11SDimitry Andric   friend class Filter;
401cf099d11SDimitry Andric 
402cf099d11SDimitry Andric   // Vector of codegen instructions to choose our filter.
403d8e91e46SDimitry Andric   ArrayRef<EncodingAndInst> AllInstructions;
404cf099d11SDimitry Andric 
405cf099d11SDimitry Andric   // Vector of uid's for this filter chooser to work on.
406e6d15924SDimitry Andric   // The first member of the pair is the opcode id being decoded, the second is
407e6d15924SDimitry Andric   // the opcode id that should be emitted.
408e6d15924SDimitry Andric   const std::vector<EncodingIDAndOpcode> &Opcodes;
409cf099d11SDimitry Andric 
410cf099d11SDimitry Andric   // Lookup table for the operand decoding of instructions.
41163faed5bSDimitry Andric   const std::map<unsigned, std::vector<OperandInfo>> &Operands;
412cf099d11SDimitry Andric 
413cf099d11SDimitry Andric   // Vector of candidate filters.
414cf099d11SDimitry Andric   std::vector<Filter> Filters;
415cf099d11SDimitry Andric 
416cf099d11SDimitry Andric   // Array of bit values passed down from our parent.
417cf099d11SDimitry Andric   // Set to all BIT_UNFILTERED's for Parent == NULL.
41830815c53SDimitry Andric   std::vector<bit_value_t> FilterBitValues;
419cf099d11SDimitry Andric 
420cf099d11SDimitry Andric   // Links to the FilterChooser above us in the decoding tree.
42163faed5bSDimitry Andric   const FilterChooser *Parent;
422cf099d11SDimitry Andric 
423cf099d11SDimitry Andric   // Index of the best filter from Filters.
424cf099d11SDimitry Andric   int BestIndex;
425cf099d11SDimitry Andric 
42630815c53SDimitry Andric   // Width of instructions
42730815c53SDimitry Andric   unsigned BitWidth;
42830815c53SDimitry Andric 
42930815c53SDimitry Andric   // Parent emitter
430145449b1SDimitry Andric   const DecoderEmitter *Emitter;
43130815c53SDimitry Andric 
432cf099d11SDimitry Andric public:
FilterChooser(ArrayRef<EncodingAndInst> Insts,const std::vector<EncodingIDAndOpcode> & IDs,const std::map<unsigned,std::vector<OperandInfo>> & Ops,unsigned BW,const DecoderEmitter * E)433d8e91e46SDimitry Andric   FilterChooser(ArrayRef<EncodingAndInst> Insts,
434e6d15924SDimitry Andric                 const std::vector<EncodingIDAndOpcode> &IDs,
43563faed5bSDimitry Andric                 const std::map<unsigned, std::vector<OperandInfo>> &Ops,
436145449b1SDimitry Andric                 unsigned BW, const DecoderEmitter *E)
437b915e9e0SDimitry Andric       : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
43867c32a98SDimitry Andric         FilterBitValues(BW, BIT_UNFILTERED), Parent(nullptr), BestIndex(-1),
43967c32a98SDimitry Andric         BitWidth(BW), Emitter(E) {
440cf099d11SDimitry Andric     doFilter();
441cf099d11SDimitry Andric   }
442cf099d11SDimitry Andric 
FilterChooser(ArrayRef<EncodingAndInst> Insts,const std::vector<EncodingIDAndOpcode> & IDs,const std::map<unsigned,std::vector<OperandInfo>> & Ops,const std::vector<bit_value_t> & ParentFilterBitValues,const FilterChooser & parent)443d8e91e46SDimitry Andric   FilterChooser(ArrayRef<EncodingAndInst> Insts,
444e6d15924SDimitry Andric                 const std::vector<EncodingIDAndOpcode> &IDs,
44563faed5bSDimitry Andric                 const std::map<unsigned, std::vector<OperandInfo>> &Ops,
44663faed5bSDimitry Andric                 const std::vector<bit_value_t> &ParentFilterBitValues,
44763faed5bSDimitry Andric                 const FilterChooser &parent)
44863faed5bSDimitry Andric       : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
449b915e9e0SDimitry Andric         FilterBitValues(ParentFilterBitValues), Parent(&parent), BestIndex(-1),
450b915e9e0SDimitry Andric         BitWidth(parent.BitWidth), Emitter(parent.Emitter) {
451cf099d11SDimitry Andric     doFilter();
452cf099d11SDimitry Andric   }
453cf099d11SDimitry Andric 
454b915e9e0SDimitry Andric   FilterChooser(const FilterChooser &) = delete;
455b915e9e0SDimitry Andric   void operator=(const FilterChooser &) = delete;
456b915e9e0SDimitry Andric 
getBitWidth() const457902a7b52SDimitry Andric   unsigned getBitWidth() const { return BitWidth; }
458cf099d11SDimitry Andric 
459cf099d11SDimitry Andric protected:
460cf099d11SDimitry Andric   // Populates the insn given the uid.
insnWithID(insn_t & Insn,unsigned Opcode) const461cf099d11SDimitry Andric   void insnWithID(insn_t &Insn, unsigned Opcode) const {
462ac9a064cSDimitry Andric     const Record *EncodingDef = AllInstructions[Opcode].EncodingDef;
463ac9a064cSDimitry Andric     BitsInit &Bits = getBitsField(*EncodingDef, "Inst");
464ac9a064cSDimitry Andric     Insn.resize(std::max(BitWidth, Bits.getNumBits()), BIT_UNSET);
46563faed5bSDimitry Andric     // We may have a SoftFail bitmask, which specifies a mask where an encoding
46663faed5bSDimitry Andric     // may differ from the value in "Inst" and yet still be valid, but the
46763faed5bSDimitry Andric     // disassembler should return SoftFail instead of Success.
46863faed5bSDimitry Andric     //
46963faed5bSDimitry Andric     // This is used for marking UNPREDICTABLE instructions in the ARM world.
470ac9a064cSDimitry Andric     const RecordVal *RV = EncodingDef->getValue("SoftFail");
471145449b1SDimitry Andric     const BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
472145449b1SDimitry Andric     for (unsigned i = 0; i < Bits.getNumBits(); ++i) {
47363faed5bSDimitry Andric       if (SFBits && bitFromBits(*SFBits, i) == BIT_TRUE)
474145449b1SDimitry Andric         Insn[i] = BIT_UNSET;
47563faed5bSDimitry Andric       else
476145449b1SDimitry Andric         Insn[i] = bitFromBits(Bits, i);
477cf099d11SDimitry Andric     }
47863faed5bSDimitry Andric   }
479cf099d11SDimitry Andric 
480e6d15924SDimitry Andric   // Emit the name of the encoding/instruction pair.
emitNameWithID(raw_ostream & OS,unsigned Opcode) const481e6d15924SDimitry Andric   void emitNameWithID(raw_ostream &OS, unsigned Opcode) const {
482e6d15924SDimitry Andric     const Record *EncodingDef = AllInstructions[Opcode].EncodingDef;
483e6d15924SDimitry Andric     const Record *InstDef = AllInstructions[Opcode].Inst->TheDef;
484e6d15924SDimitry Andric     if (EncodingDef != InstDef)
485e6d15924SDimitry Andric       OS << EncodingDef->getName() << ":";
486e6d15924SDimitry Andric     OS << InstDef->getName();
487e6d15924SDimitry Andric   }
488e6d15924SDimitry Andric 
489cf099d11SDimitry Andric   // Populates the field of the insn given the start position and the number of
490cf099d11SDimitry Andric   // consecutive bits to scan for.
491cf099d11SDimitry Andric   //
492ac9a064cSDimitry Andric   // Returns a pair of values (indicator, field), where the indicator is false
493ac9a064cSDimitry Andric   // if there exists any uninitialized bit value in the range and true if all
494ac9a064cSDimitry Andric   // bits are well-known. The second value is the potentially populated field.
495ac9a064cSDimitry Andric   std::pair<bool, uint64_t> fieldFromInsn(const insn_t &Insn, unsigned StartBit,
496cf099d11SDimitry Andric                                           unsigned NumBits) const;
497cf099d11SDimitry Andric 
498cf099d11SDimitry Andric   /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
499cf099d11SDimitry Andric   /// filter array as a series of chars.
50063faed5bSDimitry Andric   void dumpFilterArray(raw_ostream &o,
50163faed5bSDimitry Andric                        const std::vector<bit_value_t> &filter) const;
502cf099d11SDimitry Andric 
503cf099d11SDimitry Andric   /// dumpStack - dumpStack traverses the filter chooser chain and calls
504cf099d11SDimitry Andric   /// dumpFilterArray on each filter chooser up to the top level one.
50563faed5bSDimitry Andric   void dumpStack(raw_ostream &o, const char *prefix) const;
506cf099d11SDimitry Andric 
bestFilter()507cf099d11SDimitry Andric   Filter &bestFilter() {
508cf099d11SDimitry Andric     assert(BestIndex != -1 && "BestIndex not set");
509cf099d11SDimitry Andric     return Filters[BestIndex];
510cf099d11SDimitry Andric   }
511cf099d11SDimitry Andric 
PositionFiltered(unsigned i) const51263faed5bSDimitry Andric   bool PositionFiltered(unsigned i) const {
513cf099d11SDimitry Andric     return ValueSet(FilterBitValues[i]);
514cf099d11SDimitry Andric   }
515cf099d11SDimitry Andric 
516cf099d11SDimitry Andric   // Calculates the island(s) needed to decode the instruction.
517cf099d11SDimitry Andric   // This returns a lit of undecoded bits of an instructions, for example,
518cf099d11SDimitry Andric   // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
519cf099d11SDimitry Andric   // decoded bits in order to verify that the instruction matches the Opcode.
520cf099d11SDimitry Andric   unsigned getIslands(std::vector<unsigned> &StartBits,
52163faed5bSDimitry Andric                       std::vector<unsigned> &EndBits,
52263faed5bSDimitry Andric                       std::vector<uint64_t> &FieldVals,
52363faed5bSDimitry Andric                       const insn_t &Insn) const;
524cf099d11SDimitry Andric 
52530815c53SDimitry Andric   // Emits code to check the Predicates member of an instruction are true.
52630815c53SDimitry Andric   // Returns true if predicate matches were emitted, false otherwise.
52763faed5bSDimitry Andric   bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
52863faed5bSDimitry Andric                           unsigned Opc) const;
529145449b1SDimitry Andric   bool emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
530145449b1SDimitry Andric                              raw_ostream &OS) const;
53163faed5bSDimitry Andric 
532902a7b52SDimitry Andric   bool doesOpcodeNeedPredicate(unsigned Opc) const;
533902a7b52SDimitry Andric   unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const;
534ac9a064cSDimitry Andric   void emitPredicateTableEntry(DecoderTableInfo &TableInfo, unsigned Opc) const;
53530815c53SDimitry Andric 
536ac9a064cSDimitry Andric   void emitSoftFailTableEntry(DecoderTableInfo &TableInfo, unsigned Opc) const;
537902a7b52SDimitry Andric 
538902a7b52SDimitry Andric   // Emits table entries to decode the singleton.
539902a7b52SDimitry Andric   void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
540e6d15924SDimitry Andric                                EncodingIDAndOpcode Opc) const;
541cf099d11SDimitry Andric 
542cf099d11SDimitry Andric   // Emits code to decode the singleton, and then to decode the rest.
543902a7b52SDimitry Andric   void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
54463faed5bSDimitry Andric                                const Filter &Best) const;
545cf099d11SDimitry Andric 
54630815c53SDimitry Andric   void emitBinaryParser(raw_ostream &o, unsigned &Indentation,
547dd58ef01SDimitry Andric                         const OperandInfo &OpInfo,
548dd58ef01SDimitry Andric                         bool &OpHasCompleteDecoder) const;
54930815c53SDimitry Andric 
550dd58ef01SDimitry Andric   void emitDecoder(raw_ostream &OS, unsigned Indentation, unsigned Opc,
551dd58ef01SDimitry Andric                    bool &HasCompleteDecoder) const;
552dd58ef01SDimitry Andric   unsigned getDecoderIndex(DecoderSet &Decoders, unsigned Opc,
553dd58ef01SDimitry Andric                            bool &HasCompleteDecoder) const;
554902a7b52SDimitry Andric 
555cf099d11SDimitry Andric   // Assign a single filter and run with it.
55663faed5bSDimitry Andric   void runSingleFilter(unsigned startBit, unsigned numBit, bool mixed);
557cf099d11SDimitry Andric 
558cf099d11SDimitry Andric   // reportRegion is a helper function for filterProcessor to mark a region as
559cf099d11SDimitry Andric   // eligible for use as a filter region.
560cf099d11SDimitry Andric   void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex,
561cf099d11SDimitry Andric                     bool AllowMixed);
562cf099d11SDimitry Andric 
563cf099d11SDimitry Andric   // FilterProcessor scans the well-known encoding bits of the instructions and
564cf099d11SDimitry Andric   // builds up a list of candidate filters.  It chooses the best filter and
565cf099d11SDimitry Andric   // recursively descends down the decoding tree.
566cf099d11SDimitry Andric   bool filterProcessor(bool AllowMixed, bool Greedy = true);
567cf099d11SDimitry Andric 
568cf099d11SDimitry Andric   // Decides on the best configuration of filter(s) to use in order to decode
569cf099d11SDimitry Andric   // the instructions.  A conflict of instructions may occur, in which case we
570cf099d11SDimitry Andric   // dump the conflict set to the standard error.
571cf099d11SDimitry Andric   void doFilter();
572cf099d11SDimitry Andric 
573902a7b52SDimitry Andric public:
574902a7b52SDimitry Andric   // emitTableEntries - Emit state machine entries to decode our share of
575902a7b52SDimitry Andric   // instructions.
576902a7b52SDimitry Andric   void emitTableEntries(DecoderTableInfo &TableInfo) const;
577cf099d11SDimitry Andric };
578b915e9e0SDimitry Andric 
579b915e9e0SDimitry Andric } // end anonymous namespace
580cf099d11SDimitry Andric 
581cf099d11SDimitry Andric ///////////////////////////
582cf099d11SDimitry Andric //                       //
58363faed5bSDimitry Andric // Filter Implementation //
584cf099d11SDimitry Andric //                       //
585cf099d11SDimitry Andric ///////////////////////////
586cf099d11SDimitry Andric 
Filter(Filter && f)58767c32a98SDimitry Andric Filter::Filter(Filter &&f)
58863faed5bSDimitry Andric     : Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed),
58967c32a98SDimitry Andric       FilteredInstructions(std::move(f.FilteredInstructions)),
59067c32a98SDimitry Andric       VariableInstructions(std::move(f.VariableInstructions)),
591ac9a064cSDimitry Andric       FilterChooserMap(std::move(f.FilterChooserMap)),
592ac9a064cSDimitry Andric       NumFiltered(f.NumFiltered), LastOpcFiltered(f.LastOpcFiltered) {}
593cf099d11SDimitry Andric 
Filter(FilterChooser & owner,unsigned startBit,unsigned numBits,bool mixed)594cf099d11SDimitry Andric Filter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits,
59563faed5bSDimitry Andric                bool mixed)
59663faed5bSDimitry Andric     : Owner(&owner), StartBit(startBit), NumBits(numBits), Mixed(mixed) {
59730815c53SDimitry Andric   assert(StartBit + NumBits - 1 < Owner->BitWidth);
598cf099d11SDimitry Andric 
599cf099d11SDimitry Andric   NumFiltered = 0;
600e6d15924SDimitry Andric   LastOpcFiltered = {0, 0};
601cf099d11SDimitry Andric 
602ac9a064cSDimitry Andric   for (const auto &OpcPair : Owner->Opcodes) {
603cf099d11SDimitry Andric     insn_t Insn;
604cf099d11SDimitry Andric 
605cf099d11SDimitry Andric     // Populates the insn given the uid.
606ac9a064cSDimitry Andric     Owner->insnWithID(Insn, OpcPair.EncodingID);
607cf099d11SDimitry Andric 
608cf099d11SDimitry Andric     // Scans the segment for possibly well-specified encoding bits.
609ac9a064cSDimitry Andric     auto [Ok, Field] = Owner->fieldFromInsn(Insn, StartBit, NumBits);
610cf099d11SDimitry Andric 
611ac9a064cSDimitry Andric     if (Ok) {
612cf099d11SDimitry Andric       // The encoding bits are well-known.  Lets add the uid of the
613cf099d11SDimitry Andric       // instruction into the bucket keyed off the constant field value.
614ac9a064cSDimitry Andric       LastOpcFiltered = OpcPair;
615cf099d11SDimitry Andric       FilteredInstructions[Field].push_back(LastOpcFiltered);
616cf099d11SDimitry Andric       ++NumFiltered;
617cf099d11SDimitry Andric     } else {
61863faed5bSDimitry Andric       // Some of the encoding bit(s) are unspecified.  This contributes to
619cf099d11SDimitry Andric       // one additional member of "Variable" instructions.
620ac9a064cSDimitry Andric       VariableInstructions.push_back(OpcPair);
621cf099d11SDimitry Andric     }
622cf099d11SDimitry Andric   }
623cf099d11SDimitry Andric 
624ac9a064cSDimitry Andric   assert((FilteredInstructions.size() + VariableInstructions.size() > 0) &&
625ac9a064cSDimitry Andric          "Filter returns no instruction categories");
626cf099d11SDimitry Andric }
627cf099d11SDimitry Andric 
628cf099d11SDimitry Andric // Divides the decoding task into sub tasks and delegates them to the
629cf099d11SDimitry Andric // inferior FilterChooser's.
630cf099d11SDimitry Andric //
631cf099d11SDimitry Andric // A special case arises when there's only one entry in the filtered
632cf099d11SDimitry Andric // instructions.  In order to unambiguously decode the singleton, we need to
633cf099d11SDimitry Andric // match the remaining undecoded encoding bits against the singleton.
recurse()634cf099d11SDimitry Andric void Filter::recurse() {
635cf099d11SDimitry Andric   // Starts by inheriting our parent filter chooser's filter bit values.
63630815c53SDimitry Andric   std::vector<bit_value_t> BitValueArray(Owner->FilterBitValues);
637cf099d11SDimitry Andric 
6385a5ac124SDimitry Andric   if (!VariableInstructions.empty()) {
639cf099d11SDimitry Andric     // Conservatively marks each segment position as BIT_UNSET.
640902a7b52SDimitry Andric     for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex)
641cf099d11SDimitry Andric       BitValueArray[StartBit + bitIndex] = BIT_UNSET;
642cf099d11SDimitry Andric 
6436b943ff3SDimitry Andric     // Delegates to an inferior filter chooser for further processing on this
644cf099d11SDimitry Andric     // group of instructions whose segment values are variable.
645ac9a064cSDimitry Andric     FilterChooserMap.insert(std::pair(
646ac9a064cSDimitry Andric         NO_FIXED_SEGMENTS_SENTINEL,
647b60736ecSDimitry Andric         std::make_unique<FilterChooser>(Owner->AllInstructions,
648ac9a064cSDimitry Andric                                         VariableInstructions, Owner->Operands,
649ac9a064cSDimitry Andric                                         BitValueArray, *Owner)));
650cf099d11SDimitry Andric   }
651cf099d11SDimitry Andric 
652cf099d11SDimitry Andric   // No need to recurse for a singleton filtered instruction.
653902a7b52SDimitry Andric   // See also Filter::emit*().
654cf099d11SDimitry Andric   if (getNumFiltered() == 1) {
655cf099d11SDimitry Andric     assert(FilterChooserMap.size() == 1);
656cf099d11SDimitry Andric     return;
657cf099d11SDimitry Andric   }
658cf099d11SDimitry Andric 
659cf099d11SDimitry Andric   // Otherwise, create sub choosers.
66067c32a98SDimitry Andric   for (const auto &Inst : FilteredInstructions) {
661cf099d11SDimitry Andric 
662cf099d11SDimitry Andric     // Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
663902a7b52SDimitry Andric     for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) {
66467c32a98SDimitry Andric       if (Inst.first & (1ULL << bitIndex))
665cf099d11SDimitry Andric         BitValueArray[StartBit + bitIndex] = BIT_TRUE;
666cf099d11SDimitry Andric       else
667cf099d11SDimitry Andric         BitValueArray[StartBit + bitIndex] = BIT_FALSE;
668cf099d11SDimitry Andric     }
669cf099d11SDimitry Andric 
6706b943ff3SDimitry Andric     // Delegates to an inferior filter chooser for further processing on this
671cf099d11SDimitry Andric     // category of instructions.
672ac9a064cSDimitry Andric     FilterChooserMap.insert(
673ac9a064cSDimitry Andric         std::pair(Inst.first, std::make_unique<FilterChooser>(
67467c32a98SDimitry Andric                                   Owner->AllInstructions, Inst.second,
67567c32a98SDimitry Andric                                   Owner->Operands, BitValueArray, *Owner)));
676cf099d11SDimitry Andric   }
677cf099d11SDimitry Andric }
678cf099d11SDimitry Andric 
resolveTableFixups(DecoderTable & Table,const FixupList & Fixups,uint32_t DestIdx)679902a7b52SDimitry Andric static void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups,
680902a7b52SDimitry Andric                                uint32_t DestIdx) {
681902a7b52SDimitry Andric   // Any NumToSkip fixups in the current scope can resolve to the
682902a7b52SDimitry Andric   // current location.
683ac9a064cSDimitry Andric   for (FixupList::const_reverse_iterator I = Fixups.rbegin(), E = Fixups.rend();
684902a7b52SDimitry Andric        I != E; ++I) {
685902a7b52SDimitry Andric     // Calculate the distance from the byte following the fixup entry byte
686902a7b52SDimitry Andric     // to the destination. The Target is calculated from after the 16-bit
687902a7b52SDimitry Andric     // NumToSkip entry itself, so subtract two  from the displacement here
688902a7b52SDimitry Andric     // to account for that.
689902a7b52SDimitry Andric     uint32_t FixupIdx = *I;
690eb11fae6SDimitry Andric     uint32_t Delta = DestIdx - FixupIdx - 3;
691eb11fae6SDimitry Andric     // Our NumToSkip entries are 24-bits. Make sure our table isn't too
692902a7b52SDimitry Andric     // big.
693eb11fae6SDimitry Andric     assert(Delta < (1u << 24));
694902a7b52SDimitry Andric     Table[FixupIdx] = (uint8_t)Delta;
695902a7b52SDimitry Andric     Table[FixupIdx + 1] = (uint8_t)(Delta >> 8);
696eb11fae6SDimitry Andric     Table[FixupIdx + 2] = (uint8_t)(Delta >> 16);
697902a7b52SDimitry Andric   }
698902a7b52SDimitry Andric }
699cf099d11SDimitry Andric 
700902a7b52SDimitry Andric // Emit table entries to decode instructions given a segment or segments
701902a7b52SDimitry Andric // of bits.
emitTableEntry(DecoderTableInfo & TableInfo) const702902a7b52SDimitry Andric void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
703ac9a064cSDimitry Andric   assert((NumBits < (1u << 8)) && "NumBits overflowed uint8 table entry!");
704902a7b52SDimitry Andric   TableInfo.Table.push_back(MCD::OPC_ExtractField);
705ac9a064cSDimitry Andric 
706ac9a064cSDimitry Andric   SmallString<16> SBytes;
707ac9a064cSDimitry Andric   raw_svector_ostream S(SBytes);
708ac9a064cSDimitry Andric   encodeULEB128(StartBit, S);
709ac9a064cSDimitry Andric   TableInfo.Table.insert(TableInfo.Table.end(), SBytes.begin(), SBytes.end());
710902a7b52SDimitry Andric   TableInfo.Table.push_back(NumBits);
711cf099d11SDimitry Andric 
712902a7b52SDimitry Andric   // A new filter entry begins a new scope for fixup resolution.
71385d8b2bbSDimitry Andric   TableInfo.FixupStack.emplace_back();
714cf099d11SDimitry Andric 
715902a7b52SDimitry Andric   DecoderTable &Table = TableInfo.Table;
716902a7b52SDimitry Andric 
717902a7b52SDimitry Andric   size_t PrevFilter = 0;
718902a7b52SDimitry Andric   bool HasFallthrough = false;
719ac9a064cSDimitry Andric   for (const auto &Filter : FilterChooserMap) {
720cf099d11SDimitry Andric     // Field value -1 implies a non-empty set of variable instructions.
721cf099d11SDimitry Andric     // See also recurse().
722b60736ecSDimitry Andric     if (Filter.first == NO_FIXED_SEGMENTS_SENTINEL) {
723902a7b52SDimitry Andric       HasFallthrough = true;
724cf099d11SDimitry Andric 
725902a7b52SDimitry Andric       // Each scope should always have at least one filter value to check
726902a7b52SDimitry Andric       // for.
727902a7b52SDimitry Andric       assert(PrevFilter != 0 && "empty filter set!");
728902a7b52SDimitry Andric       FixupList &CurScope = TableInfo.FixupStack.back();
729902a7b52SDimitry Andric       // Resolve any NumToSkip fixups in the current scope.
730902a7b52SDimitry Andric       resolveTableFixups(Table, CurScope, Table.size());
731902a7b52SDimitry Andric       CurScope.clear();
732902a7b52SDimitry Andric       PrevFilter = 0; // Don't re-process the filter's fallthrough.
733902a7b52SDimitry Andric     } else {
734902a7b52SDimitry Andric       Table.push_back(MCD::OPC_FilterValue);
735902a7b52SDimitry Andric       // Encode and emit the value to filter against.
736eb11fae6SDimitry Andric       uint8_t Buffer[16];
73767c32a98SDimitry Andric       unsigned Len = encodeULEB128(Filter.first, Buffer);
738902a7b52SDimitry Andric       Table.insert(Table.end(), Buffer, Buffer + Len);
739902a7b52SDimitry Andric       // Reserve space for the NumToSkip entry. We'll backpatch the value
740902a7b52SDimitry Andric       // later.
741902a7b52SDimitry Andric       PrevFilter = Table.size();
742902a7b52SDimitry Andric       Table.push_back(0);
743902a7b52SDimitry Andric       Table.push_back(0);
744eb11fae6SDimitry Andric       Table.push_back(0);
745902a7b52SDimitry Andric     }
746cf099d11SDimitry Andric 
747cf099d11SDimitry Andric     // We arrive at a category of instructions with the same segment value.
748cf099d11SDimitry Andric     // Now delegate to the sub filter chooser for further decodings.
749cf099d11SDimitry Andric     // The case may fallthrough, which happens if the remaining well-known
750cf099d11SDimitry Andric     // encoding bits do not match exactly.
75167c32a98SDimitry Andric     Filter.second->emitTableEntries(TableInfo);
752cf099d11SDimitry Andric 
753902a7b52SDimitry Andric     // Now that we've emitted the body of the handler, update the NumToSkip
754902a7b52SDimitry Andric     // of the filter itself to be able to skip forward when false. Subtract
755902a7b52SDimitry Andric     // two as to account for the width of the NumToSkip field itself.
756902a7b52SDimitry Andric     if (PrevFilter) {
757eb11fae6SDimitry Andric       uint32_t NumToSkip = Table.size() - PrevFilter - 3;
758ac9a064cSDimitry Andric       assert(NumToSkip < (1u << 24) &&
759ac9a064cSDimitry Andric              "disassembler decoding table too large!");
760902a7b52SDimitry Andric       Table[PrevFilter] = (uint8_t)NumToSkip;
761902a7b52SDimitry Andric       Table[PrevFilter + 1] = (uint8_t)(NumToSkip >> 8);
762eb11fae6SDimitry Andric       Table[PrevFilter + 2] = (uint8_t)(NumToSkip >> 16);
763902a7b52SDimitry Andric     }
764cf099d11SDimitry Andric   }
765cf099d11SDimitry Andric 
766902a7b52SDimitry Andric   // Any remaining unresolved fixups bubble up to the parent fixup scope.
767902a7b52SDimitry Andric   assert(TableInfo.FixupStack.size() > 1 && "fixup stack underflow!");
768902a7b52SDimitry Andric   FixupScopeList::iterator Source = TableInfo.FixupStack.end() - 1;
769902a7b52SDimitry Andric   FixupScopeList::iterator Dest = Source - 1;
770b60736ecSDimitry Andric   llvm::append_range(*Dest, *Source);
771902a7b52SDimitry Andric   TableInfo.FixupStack.pop_back();
772902a7b52SDimitry Andric 
773902a7b52SDimitry Andric   // If there is no fallthrough, then the final filter should get fixed
774902a7b52SDimitry Andric   // up according to the enclosing scope rather than the current position.
775902a7b52SDimitry Andric   if (!HasFallthrough)
776902a7b52SDimitry Andric     TableInfo.FixupStack.back().push_back(PrevFilter);
777cf099d11SDimitry Andric }
778cf099d11SDimitry Andric 
779cf099d11SDimitry Andric // Returns the number of fanout produced by the filter.  More fanout implies
780cf099d11SDimitry Andric // the filter distinguishes more categories of instructions.
usefulness() const781cf099d11SDimitry Andric unsigned Filter::usefulness() const {
7825a5ac124SDimitry Andric   if (!VariableInstructions.empty())
783cf099d11SDimitry Andric     return FilteredInstructions.size();
784cf099d11SDimitry Andric   else
785cf099d11SDimitry Andric     return FilteredInstructions.size() + 1;
786cf099d11SDimitry Andric }
787cf099d11SDimitry Andric 
788cf099d11SDimitry Andric //////////////////////////////////
789cf099d11SDimitry Andric //                              //
790cf099d11SDimitry Andric // Filterchooser Implementation //
791cf099d11SDimitry Andric //                              //
792cf099d11SDimitry Andric //////////////////////////////////
793cf099d11SDimitry Andric 
794902a7b52SDimitry Andric // Emit the decoder state machine table.
emitTable(formatted_raw_ostream & OS,DecoderTable & Table,unsigned Indentation,unsigned BitWidth,StringRef Namespace,const EncodingIDsVec & EncodingIDs) const795145449b1SDimitry Andric void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
796145449b1SDimitry Andric                                unsigned Indentation, unsigned BitWidth,
797ac9a064cSDimitry Andric                                StringRef Namespace,
798ac9a064cSDimitry Andric                                const EncodingIDsVec &EncodingIDs) const {
799ac9a064cSDimitry Andric   // We'll need to be able to map from a decoded opcode into the corresponding
800ac9a064cSDimitry Andric   // EncodingID for this specific combination of BitWidth and Namespace. This
801ac9a064cSDimitry Andric   // is used below to index into NumberedEncodings.
802ac9a064cSDimitry Andric   DenseMap<unsigned, unsigned> OpcodeToEncodingID;
803ac9a064cSDimitry Andric   OpcodeToEncodingID.reserve(EncodingIDs.size());
804ac9a064cSDimitry Andric   for (const auto &EI : EncodingIDs)
805ac9a064cSDimitry Andric     OpcodeToEncodingID[EI.Opcode] = EI.EncodingID;
806ac9a064cSDimitry Andric 
807902a7b52SDimitry Andric   OS.indent(Indentation) << "static const uint8_t DecoderTable" << Namespace
808902a7b52SDimitry Andric                          << BitWidth << "[] = {\n";
809cf099d11SDimitry Andric 
810902a7b52SDimitry Andric   Indentation += 2;
811cf099d11SDimitry Andric 
812ac9a064cSDimitry Andric   // Emit ULEB128 encoded value to OS, returning the number of bytes emitted.
813ac9a064cSDimitry Andric   auto emitULEB128 = [](DecoderTable::const_iterator I,
814ac9a064cSDimitry Andric                         formatted_raw_ostream &OS) {
815ac9a064cSDimitry Andric     unsigned Len = 0;
816ac9a064cSDimitry Andric     while (*I >= 128) {
817ac9a064cSDimitry Andric       OS << (unsigned)*I++ << ", ";
818ac9a064cSDimitry Andric       Len++;
819ac9a064cSDimitry Andric     }
820ac9a064cSDimitry Andric     OS << (unsigned)*I++ << ", ";
821ac9a064cSDimitry Andric     return Len + 1;
822ac9a064cSDimitry Andric   };
823ac9a064cSDimitry Andric 
824ac9a064cSDimitry Andric   // Emit 24-bit numtoskip value to OS, returning the NumToSkip value.
825ac9a064cSDimitry Andric   auto emitNumToSkip = [](DecoderTable::const_iterator I,
826ac9a064cSDimitry Andric                           formatted_raw_ostream &OS) {
827ac9a064cSDimitry Andric     uint8_t Byte = *I++;
828ac9a064cSDimitry Andric     uint32_t NumToSkip = Byte;
829ac9a064cSDimitry Andric     OS << (unsigned)Byte << ", ";
830ac9a064cSDimitry Andric     Byte = *I++;
831ac9a064cSDimitry Andric     OS << (unsigned)Byte << ", ";
832ac9a064cSDimitry Andric     NumToSkip |= Byte << 8;
833ac9a064cSDimitry Andric     Byte = *I++;
834ac9a064cSDimitry Andric     OS << utostr(Byte) << ", ";
835ac9a064cSDimitry Andric     NumToSkip |= Byte << 16;
836ac9a064cSDimitry Andric     return NumToSkip;
837ac9a064cSDimitry Andric   };
838ac9a064cSDimitry Andric 
839902a7b52SDimitry Andric   // FIXME: We may be able to use the NumToSkip values to recover
840902a7b52SDimitry Andric   // appropriate indentation levels.
841902a7b52SDimitry Andric   DecoderTable::const_iterator I = Table.begin();
842902a7b52SDimitry Andric   DecoderTable::const_iterator E = Table.end();
843902a7b52SDimitry Andric   while (I != E) {
844902a7b52SDimitry Andric     assert(I < E && "incomplete decode table entry!");
845cf099d11SDimitry Andric 
846902a7b52SDimitry Andric     uint64_t Pos = I - Table.begin();
847902a7b52SDimitry Andric     OS << "/* " << Pos << " */";
848902a7b52SDimitry Andric     OS.PadToColumn(12);
849cf099d11SDimitry Andric 
850902a7b52SDimitry Andric     switch (*I) {
851902a7b52SDimitry Andric     default:
852522600a2SDimitry Andric       PrintFatalError("invalid decode table opcode");
853902a7b52SDimitry Andric     case MCD::OPC_ExtractField: {
854902a7b52SDimitry Andric       ++I;
855ac9a064cSDimitry Andric       OS.indent(Indentation) << "MCD::OPC_ExtractField, ";
856ac9a064cSDimitry Andric 
857ac9a064cSDimitry Andric       // ULEB128 encoded start value.
858ac9a064cSDimitry Andric       const char *ErrMsg = nullptr;
859ac9a064cSDimitry Andric       unsigned Start = decodeULEB128(Table.data() + Pos + 1, nullptr,
860ac9a064cSDimitry Andric                                      Table.data() + Table.size(), &ErrMsg);
861ac9a064cSDimitry Andric       assert(ErrMsg == nullptr && "ULEB128 value too large!");
862ac9a064cSDimitry Andric       I += emitULEB128(I, OS);
863ac9a064cSDimitry Andric 
864902a7b52SDimitry Andric       unsigned Len = *I++;
865ac9a064cSDimitry Andric       OS << Len << ",  // Inst{";
866902a7b52SDimitry Andric       if (Len > 1)
867902a7b52SDimitry Andric         OS << (Start + Len - 1) << "-";
868902a7b52SDimitry Andric       OS << Start << "} ...\n";
869902a7b52SDimitry Andric       break;
870902a7b52SDimitry Andric     }
871902a7b52SDimitry Andric     case MCD::OPC_FilterValue: {
872902a7b52SDimitry Andric       ++I;
873902a7b52SDimitry Andric       OS.indent(Indentation) << "MCD::OPC_FilterValue, ";
874902a7b52SDimitry Andric       // The filter value is ULEB128 encoded.
875ac9a064cSDimitry Andric       I += emitULEB128(I, OS);
876902a7b52SDimitry Andric 
877eb11fae6SDimitry Andric       // 24-bit numtoskip value.
878ac9a064cSDimitry Andric       uint32_t NumToSkip = emitNumToSkip(I, OS);
879ac9a064cSDimitry Andric       I += 3;
880902a7b52SDimitry Andric       OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
881902a7b52SDimitry Andric       break;
882902a7b52SDimitry Andric     }
883902a7b52SDimitry Andric     case MCD::OPC_CheckField: {
884902a7b52SDimitry Andric       ++I;
885ac9a064cSDimitry Andric       OS.indent(Indentation) << "MCD::OPC_CheckField, ";
886ac9a064cSDimitry Andric       // ULEB128 encoded start value.
887ac9a064cSDimitry Andric       I += emitULEB128(I, OS);
888ac9a064cSDimitry Andric       // 8-bit length.
889902a7b52SDimitry Andric       unsigned Len = *I++;
890ac9a064cSDimitry Andric       OS << Len << ", ";
891902a7b52SDimitry Andric       // ULEB128 encoded field value.
892ac9a064cSDimitry Andric       I += emitULEB128(I, OS);
893ac9a064cSDimitry Andric 
894eb11fae6SDimitry Andric       // 24-bit numtoskip value.
895ac9a064cSDimitry Andric       uint32_t NumToSkip = emitNumToSkip(I, OS);
896ac9a064cSDimitry Andric       I += 3;
897902a7b52SDimitry Andric       OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
898902a7b52SDimitry Andric       break;
899902a7b52SDimitry Andric     }
900902a7b52SDimitry Andric     case MCD::OPC_CheckPredicate: {
901902a7b52SDimitry Andric       ++I;
902902a7b52SDimitry Andric       OS.indent(Indentation) << "MCD::OPC_CheckPredicate, ";
903ac9a064cSDimitry Andric       I += emitULEB128(I, OS);
904902a7b52SDimitry Andric 
905eb11fae6SDimitry Andric       // 24-bit numtoskip value.
906ac9a064cSDimitry Andric       uint32_t NumToSkip = emitNumToSkip(I, OS);
907ac9a064cSDimitry Andric       I += 3;
908902a7b52SDimitry Andric       OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
909902a7b52SDimitry Andric       break;
910902a7b52SDimitry Andric     }
911dd58ef01SDimitry Andric     case MCD::OPC_Decode:
912dd58ef01SDimitry Andric     case MCD::OPC_TryDecode: {
913dd58ef01SDimitry Andric       bool IsTry = *I == MCD::OPC_TryDecode;
914902a7b52SDimitry Andric       ++I;
915902a7b52SDimitry Andric       // Decode the Opcode value.
916ac9a064cSDimitry Andric       const char *ErrMsg = nullptr;
917ac9a064cSDimitry Andric       unsigned Opc = decodeULEB128(Table.data() + Pos + 1, nullptr,
918ac9a064cSDimitry Andric                                    Table.data() + Table.size(), &ErrMsg);
919ac9a064cSDimitry Andric       assert(ErrMsg == nullptr && "ULEB128 value too large!");
920ac9a064cSDimitry Andric 
921ac9a064cSDimitry Andric       OS.indent(Indentation)
922ac9a064cSDimitry Andric           << "MCD::OPC_" << (IsTry ? "Try" : "") << "Decode, ";
923ac9a064cSDimitry Andric       I += emitULEB128(I, OS);
924902a7b52SDimitry Andric 
925902a7b52SDimitry Andric       // Decoder index.
926ac9a064cSDimitry Andric       I += emitULEB128(I, OS);
927ac9a064cSDimitry Andric 
928ac9a064cSDimitry Andric       auto EncI = OpcodeToEncodingID.find(Opc);
929ac9a064cSDimitry Andric       assert(EncI != OpcodeToEncodingID.end() && "no encoding entry");
930ac9a064cSDimitry Andric       auto EncodingID = EncI->second;
931902a7b52SDimitry Andric 
932dd58ef01SDimitry Andric       if (!IsTry) {
933ac9a064cSDimitry Andric         OS << "// Opcode: " << NumberedEncodings[EncodingID] << "\n";
934902a7b52SDimitry Andric         break;
935902a7b52SDimitry Andric       }
936dd58ef01SDimitry Andric 
937dd58ef01SDimitry Andric       // Fallthrough for OPC_TryDecode.
938dd58ef01SDimitry Andric 
939eb11fae6SDimitry Andric       // 24-bit numtoskip value.
940ac9a064cSDimitry Andric       uint32_t NumToSkip = emitNumToSkip(I, OS);
941ac9a064cSDimitry Andric       I += 3;
942dd58ef01SDimitry Andric 
943ac9a064cSDimitry Andric       OS << "// Opcode: " << NumberedEncodings[EncodingID]
944dd58ef01SDimitry Andric          << ", skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
945dd58ef01SDimitry Andric       break;
946dd58ef01SDimitry Andric     }
947902a7b52SDimitry Andric     case MCD::OPC_SoftFail: {
948902a7b52SDimitry Andric       ++I;
949902a7b52SDimitry Andric       OS.indent(Indentation) << "MCD::OPC_SoftFail";
950902a7b52SDimitry Andric       // Positive mask
951902a7b52SDimitry Andric       uint64_t Value = 0;
952902a7b52SDimitry Andric       unsigned Shift = 0;
953902a7b52SDimitry Andric       do {
95401095a5dSDimitry Andric         OS << ", " << (unsigned)*I;
955ac9a064cSDimitry Andric         Value += ((uint64_t)(*I & 0x7f)) << Shift;
956902a7b52SDimitry Andric         Shift += 7;
957902a7b52SDimitry Andric       } while (*I++ >= 128);
95801095a5dSDimitry Andric       if (Value > 127) {
95901095a5dSDimitry Andric         OS << " /* 0x";
96001095a5dSDimitry Andric         OS.write_hex(Value);
96101095a5dSDimitry Andric         OS << " */";
96201095a5dSDimitry Andric       }
963902a7b52SDimitry Andric       // Negative mask
964902a7b52SDimitry Andric       Value = 0;
965902a7b52SDimitry Andric       Shift = 0;
966902a7b52SDimitry Andric       do {
96701095a5dSDimitry Andric         OS << ", " << (unsigned)*I;
968ac9a064cSDimitry Andric         Value += ((uint64_t)(*I & 0x7f)) << Shift;
969902a7b52SDimitry Andric         Shift += 7;
970902a7b52SDimitry Andric       } while (*I++ >= 128);
97101095a5dSDimitry Andric       if (Value > 127) {
97201095a5dSDimitry Andric         OS << " /* 0x";
97301095a5dSDimitry Andric         OS.write_hex(Value);
97401095a5dSDimitry Andric         OS << " */";
97501095a5dSDimitry Andric       }
976902a7b52SDimitry Andric       OS << ",\n";
977902a7b52SDimitry Andric       break;
978902a7b52SDimitry Andric     }
979902a7b52SDimitry Andric     case MCD::OPC_Fail: {
980902a7b52SDimitry Andric       ++I;
981902a7b52SDimitry Andric       OS.indent(Indentation) << "MCD::OPC_Fail,\n";
982902a7b52SDimitry Andric       break;
983902a7b52SDimitry Andric     }
984902a7b52SDimitry Andric     }
985902a7b52SDimitry Andric   }
986902a7b52SDimitry Andric   OS.indent(Indentation) << "0\n";
987902a7b52SDimitry Andric 
988902a7b52SDimitry Andric   Indentation -= 2;
989902a7b52SDimitry Andric 
990902a7b52SDimitry Andric   OS.indent(Indentation) << "};\n\n";
991902a7b52SDimitry Andric }
992902a7b52SDimitry Andric 
emitInstrLenTable(formatted_raw_ostream & OS,std::vector<unsigned> & InstrLen) const993145449b1SDimitry Andric void DecoderEmitter::emitInstrLenTable(formatted_raw_ostream &OS,
994145449b1SDimitry Andric                                        std::vector<unsigned> &InstrLen) const {
995145449b1SDimitry Andric   OS << "static const uint8_t InstrLenTable[] = {\n";
996145449b1SDimitry Andric   for (unsigned &Len : InstrLen) {
997145449b1SDimitry Andric     OS << Len << ",\n";
998145449b1SDimitry Andric   }
999145449b1SDimitry Andric   OS << "};\n\n";
1000145449b1SDimitry Andric }
1001145449b1SDimitry Andric 
emitPredicateFunction(formatted_raw_ostream & OS,PredicateSet & Predicates,unsigned Indentation) const1002145449b1SDimitry Andric void DecoderEmitter::emitPredicateFunction(formatted_raw_ostream &OS,
1003145449b1SDimitry Andric                                            PredicateSet &Predicates,
1004902a7b52SDimitry Andric                                            unsigned Indentation) const {
1005902a7b52SDimitry Andric   // The predicate function is just a big switch statement based on the
1006902a7b52SDimitry Andric   // input predicate index.
1007902a7b52SDimitry Andric   OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
10085a5ac124SDimitry Andric                          << "const FeatureBitset &Bits) {\n";
1009902a7b52SDimitry Andric   Indentation += 2;
1010f8af5cf6SDimitry Andric   if (!Predicates.empty()) {
1011902a7b52SDimitry Andric     OS.indent(Indentation) << "switch (Idx) {\n";
1012ac9a064cSDimitry Andric     OS.indent(Indentation)
1013ac9a064cSDimitry Andric         << "default: llvm_unreachable(\"Invalid index!\");\n";
1014902a7b52SDimitry Andric     unsigned Index = 0;
101567c32a98SDimitry Andric     for (const auto &Predicate : Predicates) {
101667c32a98SDimitry Andric       OS.indent(Indentation) << "case " << Index++ << ":\n";
101767c32a98SDimitry Andric       OS.indent(Indentation + 2) << "return (" << Predicate << ");\n";
1018902a7b52SDimitry Andric     }
1019902a7b52SDimitry Andric     OS.indent(Indentation) << "}\n";
1020f8af5cf6SDimitry Andric   } else {
1021f8af5cf6SDimitry Andric     // No case statement to emit
1022f8af5cf6SDimitry Andric     OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n";
1023f8af5cf6SDimitry Andric   }
1024902a7b52SDimitry Andric   Indentation -= 2;
1025902a7b52SDimitry Andric   OS.indent(Indentation) << "}\n\n";
1026902a7b52SDimitry Andric }
1027902a7b52SDimitry Andric 
emitDecoderFunction(formatted_raw_ostream & OS,DecoderSet & Decoders,unsigned Indentation) const1028145449b1SDimitry Andric void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
1029145449b1SDimitry Andric                                          DecoderSet &Decoders,
1030902a7b52SDimitry Andric                                          unsigned Indentation) const {
1031902a7b52SDimitry Andric   // The decoder function is just a big switch statement based on the
1032902a7b52SDimitry Andric   // input decoder index.
1033902a7b52SDimitry Andric   OS.indent(Indentation) << "template <typename InsnType>\n";
1034902a7b52SDimitry Andric   OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S,"
1035902a7b52SDimitry Andric                          << " unsigned Idx, InsnType insn, MCInst &MI,\n";
1036145449b1SDimitry Andric   OS.indent(Indentation)
1037145449b1SDimitry Andric       << "                                   uint64_t "
1038145449b1SDimitry Andric       << "Address, const MCDisassembler *Decoder, bool &DecodeComplete) {\n";
1039902a7b52SDimitry Andric   Indentation += 2;
1040dd58ef01SDimitry Andric   OS.indent(Indentation) << "DecodeComplete = true;\n";
1041344a3780SDimitry Andric   // TODO: When InsnType is large, using uint64_t limits all fields to 64 bits
1042344a3780SDimitry Andric   // It would be better for emitBinaryParser to use a 64-bit tmp whenever
1043344a3780SDimitry Andric   // possible but fall back to an InsnType-sized tmp for truly large fields.
1044344a3780SDimitry Andric   OS.indent(Indentation) << "using TmpType = "
1045344a3780SDimitry Andric                             "std::conditional_t<std::is_integral<InsnType>::"
1046344a3780SDimitry Andric                             "value, InsnType, uint64_t>;\n";
1047344a3780SDimitry Andric   OS.indent(Indentation) << "TmpType tmp;\n";
1048902a7b52SDimitry Andric   OS.indent(Indentation) << "switch (Idx) {\n";
1049902a7b52SDimitry Andric   OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
1050902a7b52SDimitry Andric   unsigned Index = 0;
105167c32a98SDimitry Andric   for (const auto &Decoder : Decoders) {
105267c32a98SDimitry Andric     OS.indent(Indentation) << "case " << Index++ << ":\n";
105367c32a98SDimitry Andric     OS << Decoder;
1054902a7b52SDimitry Andric     OS.indent(Indentation + 2) << "return S;\n";
1055902a7b52SDimitry Andric   }
1056902a7b52SDimitry Andric   OS.indent(Indentation) << "}\n";
1057902a7b52SDimitry Andric   Indentation -= 2;
1058ac9a064cSDimitry Andric   OS.indent(Indentation) << "}\n";
1059cf099d11SDimitry Andric }
1060cf099d11SDimitry Andric 
1061cf099d11SDimitry Andric // Populates the field of the insn given the start position and the number of
1062cf099d11SDimitry Andric // consecutive bits to scan for.
1063cf099d11SDimitry Andric //
1064ac9a064cSDimitry Andric // Returns a pair of values (indicator, field), where the indicator is false
1065ac9a064cSDimitry Andric // if there exists any uninitialized bit value in the range and true if all
1066ac9a064cSDimitry Andric // bits are well-known. The second value is the potentially populated field.
fieldFromInsn(const insn_t & Insn,unsigned StartBit,unsigned NumBits) const1067ac9a064cSDimitry Andric std::pair<bool, uint64_t> FilterChooser::fieldFromInsn(const insn_t &Insn,
1068ac9a064cSDimitry Andric                                                        unsigned StartBit,
1069ac9a064cSDimitry Andric                                                        unsigned NumBits) const {
1070ac9a064cSDimitry Andric   uint64_t Field = 0;
1071cf099d11SDimitry Andric 
1072cf099d11SDimitry Andric   for (unsigned i = 0; i < NumBits; ++i) {
1073cf099d11SDimitry Andric     if (Insn[StartBit + i] == BIT_UNSET)
1074ac9a064cSDimitry Andric       return {false, Field};
1075cf099d11SDimitry Andric 
1076cf099d11SDimitry Andric     if (Insn[StartBit + i] == BIT_TRUE)
1077cf099d11SDimitry Andric       Field = Field | (1ULL << i);
1078cf099d11SDimitry Andric   }
1079cf099d11SDimitry Andric 
1080ac9a064cSDimitry Andric   return {true, Field};
1081cf099d11SDimitry Andric }
1082cf099d11SDimitry Andric 
1083cf099d11SDimitry Andric /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
1084cf099d11SDimitry Andric /// filter array as a series of chars.
dumpFilterArray(raw_ostream & o,const std::vector<bit_value_t> & filter) const1085ac9a064cSDimitry Andric void FilterChooser::dumpFilterArray(
1086ac9a064cSDimitry Andric     raw_ostream &o, const std::vector<bit_value_t> &filter) const {
1087902a7b52SDimitry Andric   for (unsigned bitIndex = BitWidth; bitIndex > 0; bitIndex--) {
1088cf099d11SDimitry Andric     switch (filter[bitIndex - 1]) {
1089cf099d11SDimitry Andric     case BIT_UNFILTERED:
1090cf099d11SDimitry Andric       o << ".";
1091cf099d11SDimitry Andric       break;
1092cf099d11SDimitry Andric     case BIT_UNSET:
1093cf099d11SDimitry Andric       o << "_";
1094cf099d11SDimitry Andric       break;
1095cf099d11SDimitry Andric     case BIT_TRUE:
1096cf099d11SDimitry Andric       o << "1";
1097cf099d11SDimitry Andric       break;
1098cf099d11SDimitry Andric     case BIT_FALSE:
1099cf099d11SDimitry Andric       o << "0";
1100cf099d11SDimitry Andric       break;
1101cf099d11SDimitry Andric     }
1102cf099d11SDimitry Andric   }
1103cf099d11SDimitry Andric }
1104cf099d11SDimitry Andric 
1105cf099d11SDimitry Andric /// dumpStack - dumpStack traverses the filter chooser chain and calls
1106cf099d11SDimitry Andric /// dumpFilterArray on each filter chooser up to the top level one.
dumpStack(raw_ostream & o,const char * prefix) const110763faed5bSDimitry Andric void FilterChooser::dumpStack(raw_ostream &o, const char *prefix) const {
110863faed5bSDimitry Andric   const FilterChooser *current = this;
1109cf099d11SDimitry Andric 
1110cf099d11SDimitry Andric   while (current) {
1111cf099d11SDimitry Andric     o << prefix;
1112cf099d11SDimitry Andric     dumpFilterArray(o, current->FilterBitValues);
1113cf099d11SDimitry Andric     o << '\n';
1114cf099d11SDimitry Andric     current = current->Parent;
1115cf099d11SDimitry Andric   }
1116cf099d11SDimitry Andric }
1117cf099d11SDimitry Andric 
1118cf099d11SDimitry Andric // Calculates the island(s) needed to decode the instruction.
1119cf099d11SDimitry Andric // This returns a list of undecoded bits of an instructions, for example,
1120cf099d11SDimitry Andric // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
1121cf099d11SDimitry Andric // decoded bits in order to verify that the instruction matches the Opcode.
getIslands(std::vector<unsigned> & StartBits,std::vector<unsigned> & EndBits,std::vector<uint64_t> & FieldVals,const insn_t & Insn) const1122cf099d11SDimitry Andric unsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits,
112363faed5bSDimitry Andric                                    std::vector<unsigned> &EndBits,
112463faed5bSDimitry Andric                                    std::vector<uint64_t> &FieldVals,
112563faed5bSDimitry Andric                                    const insn_t &Insn) const {
1126cf099d11SDimitry Andric   unsigned Num, BitNo;
1127cf099d11SDimitry Andric   Num = BitNo = 0;
1128cf099d11SDimitry Andric 
1129cf099d11SDimitry Andric   uint64_t FieldVal = 0;
1130cf099d11SDimitry Andric 
1131cf099d11SDimitry Andric   // 0: Init
1132cf099d11SDimitry Andric   // 1: Water (the bit value does not affect decoding)
1133cf099d11SDimitry Andric   // 2: Island (well-known bit value needed for decoding)
1134cf099d11SDimitry Andric   int State = 0;
1135cf099d11SDimitry Andric 
113630815c53SDimitry Andric   for (unsigned i = 0; i < BitWidth; ++i) {
1137706b4fc4SDimitry Andric     int64_t Val = Value(Insn[i]);
1138cf099d11SDimitry Andric     bool Filtered = PositionFiltered(i);
1139cf099d11SDimitry Andric     switch (State) {
1140ac9a064cSDimitry Andric     default:
1141ac9a064cSDimitry Andric       llvm_unreachable("Unreachable code!");
1142cf099d11SDimitry Andric     case 0:
1143cf099d11SDimitry Andric     case 1:
1144cf099d11SDimitry Andric       if (Filtered || Val == -1)
1145cf099d11SDimitry Andric         State = 1; // Still in Water
1146cf099d11SDimitry Andric       else {
1147cf099d11SDimitry Andric         State = 2; // Into the Island
1148cf099d11SDimitry Andric         BitNo = 0;
1149cf099d11SDimitry Andric         StartBits.push_back(i);
1150cf099d11SDimitry Andric         FieldVal = Val;
1151cf099d11SDimitry Andric       }
1152cf099d11SDimitry Andric       break;
1153cf099d11SDimitry Andric     case 2:
1154cf099d11SDimitry Andric       if (Filtered || Val == -1) {
1155cf099d11SDimitry Andric         State = 1; // Into the Water
1156cf099d11SDimitry Andric         EndBits.push_back(i - 1);
1157cf099d11SDimitry Andric         FieldVals.push_back(FieldVal);
1158cf099d11SDimitry Andric         ++Num;
1159cf099d11SDimitry Andric       } else {
1160cf099d11SDimitry Andric         State = 2; // Still in Island
1161cf099d11SDimitry Andric         ++BitNo;
1162cf099d11SDimitry Andric         FieldVal = FieldVal | Val << BitNo;
1163cf099d11SDimitry Andric       }
1164cf099d11SDimitry Andric       break;
1165cf099d11SDimitry Andric     }
1166cf099d11SDimitry Andric   }
1167cf099d11SDimitry Andric   // If we are still in Island after the loop, do some housekeeping.
1168cf099d11SDimitry Andric   if (State == 2) {
116930815c53SDimitry Andric     EndBits.push_back(BitWidth - 1);
1170cf099d11SDimitry Andric     FieldVals.push_back(FieldVal);
1171cf099d11SDimitry Andric     ++Num;
1172cf099d11SDimitry Andric   }
1173cf099d11SDimitry Andric 
1174cf099d11SDimitry Andric   assert(StartBits.size() == Num && EndBits.size() == Num &&
1175cf099d11SDimitry Andric          FieldVals.size() == Num);
1176cf099d11SDimitry Andric   return Num;
1177cf099d11SDimitry Andric }
1178cf099d11SDimitry Andric 
emitBinaryParser(raw_ostream & o,unsigned & Indentation,const OperandInfo & OpInfo,bool & OpHasCompleteDecoder) const117930815c53SDimitry Andric void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
1180dd58ef01SDimitry Andric                                      const OperandInfo &OpInfo,
1181dd58ef01SDimitry Andric                                      bool &OpHasCompleteDecoder) const {
118263faed5bSDimitry Andric   const std::string &Decoder = OpInfo.Decoder;
118330815c53SDimitry Andric 
1184344a3780SDimitry Andric   bool UseInsertBits = OpInfo.numFields() != 1 || OpInfo.InitValue != 0;
1185344a3780SDimitry Andric 
1186344a3780SDimitry Andric   if (UseInsertBits) {
11871d5ae102SDimitry Andric     o.indent(Indentation) << "tmp = 0x";
11881d5ae102SDimitry Andric     o.write_hex(OpInfo.InitValue);
11891d5ae102SDimitry Andric     o << ";\n";
11901d5ae102SDimitry Andric   }
119167c32a98SDimitry Andric 
119267c32a98SDimitry Andric   for (const EncodingField &EF : OpInfo) {
1193344a3780SDimitry Andric     o.indent(Indentation);
1194344a3780SDimitry Andric     if (UseInsertBits)
1195344a3780SDimitry Andric       o << "insertBits(tmp, ";
1196344a3780SDimitry Andric     else
1197344a3780SDimitry Andric       o << "tmp = ";
1198344a3780SDimitry Andric     o << "fieldFromInstruction(insn, " << EF.Base << ", " << EF.Width << ')';
1199344a3780SDimitry Andric     if (UseInsertBits)
1200344a3780SDimitry Andric       o << ", " << EF.Offset << ", " << EF.Width << ')';
1201344a3780SDimitry Andric     else if (EF.Offset != 0)
120267c32a98SDimitry Andric       o << " << " << EF.Offset;
120367c32a98SDimitry Andric     o << ";\n";
120430815c53SDimitry Andric   }
120530815c53SDimitry Andric 
1206dd58ef01SDimitry Andric   if (Decoder != "") {
1207dd58ef01SDimitry Andric     OpHasCompleteDecoder = OpInfo.HasCompleteDecoder;
1208e3b55780SDimitry Andric     o.indent(Indentation) << "if (!Check(S, " << Decoder
1209e3b55780SDimitry Andric                           << "(MI, tmp, Address, Decoder))) { "
1210e3b55780SDimitry Andric                           << (OpHasCompleteDecoder ? ""
1211e3b55780SDimitry Andric                                                    : "DecodeComplete = false; ")
1212dd58ef01SDimitry Andric                           << "return MCDisassembler::Fail; }\n";
1213dd58ef01SDimitry Andric   } else {
1214dd58ef01SDimitry Andric     OpHasCompleteDecoder = true;
12155a5ac124SDimitry Andric     o.indent(Indentation) << "MI.addOperand(MCOperand::createImm(tmp));\n";
1216dd58ef01SDimitry Andric   }
121730815c53SDimitry Andric }
121830815c53SDimitry Andric 
emitDecoder(raw_ostream & OS,unsigned Indentation,unsigned Opc,bool & HasCompleteDecoder) const1219902a7b52SDimitry Andric void FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation,
1220dd58ef01SDimitry Andric                                 unsigned Opc, bool &HasCompleteDecoder) const {
1221dd58ef01SDimitry Andric   HasCompleteDecoder = true;
1222dd58ef01SDimitry Andric 
122367c32a98SDimitry Andric   for (const auto &Op : Operands.find(Opc)->second) {
1224902a7b52SDimitry Andric     // If a custom instruction decoder was specified, use that.
1225b915e9e0SDimitry Andric     if (Op.numFields() == 0 && !Op.Decoder.empty()) {
1226dd58ef01SDimitry Andric       HasCompleteDecoder = Op.HasCompleteDecoder;
1227e3b55780SDimitry Andric       OS.indent(Indentation)
1228e3b55780SDimitry Andric           << "if (!Check(S, " << Op.Decoder
1229e3b55780SDimitry Andric           << "(MI, insn, Address, Decoder))) { "
1230e3b55780SDimitry Andric           << (HasCompleteDecoder ? "" : "DecodeComplete = false; ")
1231dd58ef01SDimitry Andric           << "return MCDisassembler::Fail; }\n";
1232902a7b52SDimitry Andric       break;
1233902a7b52SDimitry Andric     }
1234902a7b52SDimitry Andric 
1235dd58ef01SDimitry Andric     bool OpHasCompleteDecoder;
1236dd58ef01SDimitry Andric     emitBinaryParser(OS, Indentation, Op, OpHasCompleteDecoder);
1237dd58ef01SDimitry Andric     if (!OpHasCompleteDecoder)
1238dd58ef01SDimitry Andric       HasCompleteDecoder = false;
1239902a7b52SDimitry Andric   }
1240902a7b52SDimitry Andric }
1241902a7b52SDimitry Andric 
getDecoderIndex(DecoderSet & Decoders,unsigned Opc,bool & HasCompleteDecoder) const1242ac9a064cSDimitry Andric unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders, unsigned Opc,
1243dd58ef01SDimitry Andric                                         bool &HasCompleteDecoder) const {
1244902a7b52SDimitry Andric   // Build up the predicate string.
1245902a7b52SDimitry Andric   SmallString<256> Decoder;
1246902a7b52SDimitry Andric   // FIXME: emitDecoder() function can take a buffer directly rather than
1247902a7b52SDimitry Andric   // a stream.
1248902a7b52SDimitry Andric   raw_svector_ostream S(Decoder);
1249902a7b52SDimitry Andric   unsigned I = 4;
1250dd58ef01SDimitry Andric   emitDecoder(S, I, Opc, HasCompleteDecoder);
1251902a7b52SDimitry Andric 
1252902a7b52SDimitry Andric   // Using the full decoder string as the key value here is a bit
1253902a7b52SDimitry Andric   // heavyweight, but is effective. If the string comparisons become a
1254902a7b52SDimitry Andric   // performance concern, we can implement a mangling of the predicate
1255dd58ef01SDimitry Andric   // data easily enough with a map back to the actual string. That's
1256902a7b52SDimitry Andric   // overkill for now, though.
1257902a7b52SDimitry Andric 
1258902a7b52SDimitry Andric   // Make sure the predicate is in the table.
1259b915e9e0SDimitry Andric   Decoders.insert(CachedHashString(Decoder));
1260902a7b52SDimitry Andric   // Now figure out the index for when we write out the table.
1261b915e9e0SDimitry Andric   DecoderSet::const_iterator P = find(Decoders, Decoder.str());
1262902a7b52SDimitry Andric   return (unsigned)(P - Decoders.begin());
1263902a7b52SDimitry Andric }
1264902a7b52SDimitry Andric 
1265145449b1SDimitry Andric // If ParenIfBinOp is true, print a surrounding () if Val uses && or ||.
emitPredicateMatchAux(const Init & Val,bool ParenIfBinOp,raw_ostream & OS) const1266145449b1SDimitry Andric bool FilterChooser::emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
1267145449b1SDimitry Andric                                           raw_ostream &OS) const {
1268ac9a064cSDimitry Andric   if (const auto *D = dyn_cast<DefInit>(&Val)) {
1269145449b1SDimitry Andric     if (!D->getDef()->isSubClassOf("SubtargetFeature"))
1270145449b1SDimitry Andric       return true;
1271145449b1SDimitry Andric     OS << "Bits[" << Emitter->PredicateNamespace << "::" << D->getAsString()
1272145449b1SDimitry Andric        << "]";
1273145449b1SDimitry Andric     return false;
1274145449b1SDimitry Andric   }
1275ac9a064cSDimitry Andric   if (const auto *D = dyn_cast<DagInit>(&Val)) {
1276145449b1SDimitry Andric     std::string Op = D->getOperator()->getAsString();
1277145449b1SDimitry Andric     if (Op == "not" && D->getNumArgs() == 1) {
1278145449b1SDimitry Andric       OS << '!';
1279145449b1SDimitry Andric       return emitPredicateMatchAux(*D->getArg(0), true, OS);
1280145449b1SDimitry Andric     }
1281145449b1SDimitry Andric     if ((Op == "any_of" || Op == "all_of") && D->getNumArgs() > 0) {
1282145449b1SDimitry Andric       bool Paren = D->getNumArgs() > 1 && std::exchange(ParenIfBinOp, true);
1283145449b1SDimitry Andric       if (Paren)
1284145449b1SDimitry Andric         OS << '(';
1285145449b1SDimitry Andric       ListSeparator LS(Op == "any_of" ? " || " : " && ");
1286145449b1SDimitry Andric       for (auto *Arg : D->getArgs()) {
1287145449b1SDimitry Andric         OS << LS;
1288145449b1SDimitry Andric         if (emitPredicateMatchAux(*Arg, ParenIfBinOp, OS))
1289145449b1SDimitry Andric           return true;
1290145449b1SDimitry Andric       }
1291145449b1SDimitry Andric       if (Paren)
1292145449b1SDimitry Andric         OS << ')';
1293145449b1SDimitry Andric       return false;
1294145449b1SDimitry Andric     }
1295145449b1SDimitry Andric   }
1296145449b1SDimitry Andric   return true;
1297145449b1SDimitry Andric }
1298145449b1SDimitry Andric 
emitPredicateMatch(raw_ostream & o,unsigned & Indentation,unsigned Opc) const129930815c53SDimitry Andric bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
130063faed5bSDimitry Andric                                        unsigned Opc) const {
130163faed5bSDimitry Andric   ListInit *Predicates =
1302d8e91e46SDimitry Andric       AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
13035a5ac124SDimitry Andric   bool IsFirstEmission = true;
130485d8b2bbSDimitry Andric   for (unsigned i = 0; i < Predicates->size(); ++i) {
130530815c53SDimitry Andric     Record *Pred = Predicates->getElementAsRecord(i);
130630815c53SDimitry Andric     if (!Pred->getValue("AssemblerMatcherPredicate"))
130730815c53SDimitry Andric       continue;
130830815c53SDimitry Andric 
1309b60736ecSDimitry Andric     if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
131030815c53SDimitry Andric       continue;
131130815c53SDimitry Andric 
13125a5ac124SDimitry Andric     if (!IsFirstEmission)
131330815c53SDimitry Andric       o << " && ";
1314145449b1SDimitry Andric     if (emitPredicateMatchAux(*Pred->getValueAsDag("AssemblerCondDag"),
1315145449b1SDimitry Andric                               Predicates->size() > 1, o))
1316cfca06d7SDimitry Andric       PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
13175a5ac124SDimitry Andric     IsFirstEmission = false;
131830815c53SDimitry Andric   }
131985d8b2bbSDimitry Andric   return !Predicates->empty();
132030815c53SDimitry Andric }
132130815c53SDimitry Andric 
doesOpcodeNeedPredicate(unsigned Opc) const1322902a7b52SDimitry Andric bool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const {
1323902a7b52SDimitry Andric   ListInit *Predicates =
1324d8e91e46SDimitry Andric       AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
132585d8b2bbSDimitry Andric   for (unsigned i = 0; i < Predicates->size(); ++i) {
1326902a7b52SDimitry Andric     Record *Pred = Predicates->getElementAsRecord(i);
1327902a7b52SDimitry Andric     if (!Pred->getValue("AssemblerMatcherPredicate"))
1328902a7b52SDimitry Andric       continue;
1329902a7b52SDimitry Andric 
1330344a3780SDimitry Andric     if (isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
1331902a7b52SDimitry Andric       return true;
1332902a7b52SDimitry Andric   }
1333902a7b52SDimitry Andric   return false;
1334902a7b52SDimitry Andric }
1335902a7b52SDimitry Andric 
getPredicateIndex(DecoderTableInfo & TableInfo,StringRef Predicate) const1336902a7b52SDimitry Andric unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo,
1337902a7b52SDimitry Andric                                           StringRef Predicate) const {
1338902a7b52SDimitry Andric   // Using the full predicate string as the key value here is a bit
1339902a7b52SDimitry Andric   // heavyweight, but is effective. If the string comparisons become a
1340902a7b52SDimitry Andric   // performance concern, we can implement a mangling of the predicate
1341dd58ef01SDimitry Andric   // data easily enough with a map back to the actual string. That's
1342902a7b52SDimitry Andric   // overkill for now, though.
1343902a7b52SDimitry Andric 
1344902a7b52SDimitry Andric   // Make sure the predicate is in the table.
1345b915e9e0SDimitry Andric   TableInfo.Predicates.insert(CachedHashString(Predicate));
1346902a7b52SDimitry Andric   // Now figure out the index for when we write out the table.
1347b915e9e0SDimitry Andric   PredicateSet::const_iterator P = find(TableInfo.Predicates, Predicate);
1348902a7b52SDimitry Andric   return (unsigned)(P - TableInfo.Predicates.begin());
1349902a7b52SDimitry Andric }
1350902a7b52SDimitry Andric 
emitPredicateTableEntry(DecoderTableInfo & TableInfo,unsigned Opc) const1351902a7b52SDimitry Andric void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo,
1352902a7b52SDimitry Andric                                             unsigned Opc) const {
1353902a7b52SDimitry Andric   if (!doesOpcodeNeedPredicate(Opc))
1354902a7b52SDimitry Andric     return;
1355902a7b52SDimitry Andric 
1356902a7b52SDimitry Andric   // Build up the predicate string.
1357902a7b52SDimitry Andric   SmallString<256> Predicate;
1358902a7b52SDimitry Andric   // FIXME: emitPredicateMatch() functions can take a buffer directly rather
1359902a7b52SDimitry Andric   // than a stream.
1360902a7b52SDimitry Andric   raw_svector_ostream PS(Predicate);
1361902a7b52SDimitry Andric   unsigned I = 0;
1362902a7b52SDimitry Andric   emitPredicateMatch(PS, I, Opc);
1363902a7b52SDimitry Andric 
1364902a7b52SDimitry Andric   // Figure out the index into the predicate table for the predicate just
1365902a7b52SDimitry Andric   // computed.
1366902a7b52SDimitry Andric   unsigned PIdx = getPredicateIndex(TableInfo, PS.str());
1367902a7b52SDimitry Andric   SmallString<16> PBytes;
1368902a7b52SDimitry Andric   raw_svector_ostream S(PBytes);
1369902a7b52SDimitry Andric   encodeULEB128(PIdx, S);
1370902a7b52SDimitry Andric 
1371902a7b52SDimitry Andric   TableInfo.Table.push_back(MCD::OPC_CheckPredicate);
1372ac9a064cSDimitry Andric   // Predicate index.
1373ac9a064cSDimitry Andric   for (const auto PB : PBytes)
1374ac9a064cSDimitry Andric     TableInfo.Table.push_back(PB);
1375902a7b52SDimitry Andric   // Push location for NumToSkip backpatching.
1376902a7b52SDimitry Andric   TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
1377902a7b52SDimitry Andric   TableInfo.Table.push_back(0);
1378902a7b52SDimitry Andric   TableInfo.Table.push_back(0);
1379eb11fae6SDimitry Andric   TableInfo.Table.push_back(0);
1380902a7b52SDimitry Andric }
1381902a7b52SDimitry Andric 
emitSoftFailTableEntry(DecoderTableInfo & TableInfo,unsigned Opc) const1382902a7b52SDimitry Andric void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
138363faed5bSDimitry Andric                                            unsigned Opc) const {
1384ac9a064cSDimitry Andric   const Record *EncodingDef = AllInstructions[Opc].EncodingDef;
1385ac9a064cSDimitry Andric   const RecordVal *RV = EncodingDef->getValue("SoftFail");
1386145449b1SDimitry Andric   BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
1387145449b1SDimitry Andric 
1388ac9a064cSDimitry Andric   if (!SFBits)
1389ac9a064cSDimitry Andric     return;
1390ac9a064cSDimitry Andric   BitsInit *InstBits = EncodingDef->getValueAsBitsInit("Inst");
139163faed5bSDimitry Andric 
139263faed5bSDimitry Andric   APInt PositiveMask(BitWidth, 0ULL);
139363faed5bSDimitry Andric   APInt NegativeMask(BitWidth, 0ULL);
139463faed5bSDimitry Andric   for (unsigned i = 0; i < BitWidth; ++i) {
139563faed5bSDimitry Andric     bit_value_t B = bitFromBits(*SFBits, i);
139663faed5bSDimitry Andric     bit_value_t IB = bitFromBits(*InstBits, i);
139763faed5bSDimitry Andric 
1398ac9a064cSDimitry Andric     if (B != BIT_TRUE)
1399ac9a064cSDimitry Andric       continue;
140063faed5bSDimitry Andric 
140163faed5bSDimitry Andric     switch (IB) {
140263faed5bSDimitry Andric     case BIT_FALSE:
140363faed5bSDimitry Andric       // The bit is meant to be false, so emit a check to see if it is true.
140463faed5bSDimitry Andric       PositiveMask.setBit(i);
140563faed5bSDimitry Andric       break;
140663faed5bSDimitry Andric     case BIT_TRUE:
140763faed5bSDimitry Andric       // The bit is meant to be true, so emit a check to see if it is false.
140863faed5bSDimitry Andric       NegativeMask.setBit(i);
140963faed5bSDimitry Andric       break;
141063faed5bSDimitry Andric     default:
141163faed5bSDimitry Andric       // The bit is not set; this must be an error!
1412d8e91e46SDimitry Andric       errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in "
1413d8e91e46SDimitry Andric              << AllInstructions[Opc] << " is set but Inst{" << i
1414d8e91e46SDimitry Andric              << "} is unset!\n"
141563faed5bSDimitry Andric              << "  - You can only mark a bit as SoftFail if it is fully defined"
141663faed5bSDimitry Andric              << " (1/0 - not '?') in Inst\n";
1417902a7b52SDimitry Andric       return;
141863faed5bSDimitry Andric     }
141963faed5bSDimitry Andric   }
142063faed5bSDimitry Andric 
142163faed5bSDimitry Andric   bool NeedPositiveMask = PositiveMask.getBoolValue();
142263faed5bSDimitry Andric   bool NeedNegativeMask = NegativeMask.getBoolValue();
142363faed5bSDimitry Andric 
142463faed5bSDimitry Andric   if (!NeedPositiveMask && !NeedNegativeMask)
142563faed5bSDimitry Andric     return;
142663faed5bSDimitry Andric 
1427902a7b52SDimitry Andric   TableInfo.Table.push_back(MCD::OPC_SoftFail);
142863faed5bSDimitry Andric 
1429902a7b52SDimitry Andric   SmallString<16> MaskBytes;
1430902a7b52SDimitry Andric   raw_svector_ostream S(MaskBytes);
1431902a7b52SDimitry Andric   if (NeedPositiveMask) {
1432902a7b52SDimitry Andric     encodeULEB128(PositiveMask.getZExtValue(), S);
1433902a7b52SDimitry Andric     for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i)
1434902a7b52SDimitry Andric       TableInfo.Table.push_back(MaskBytes[i]);
1435902a7b52SDimitry Andric   } else
1436902a7b52SDimitry Andric     TableInfo.Table.push_back(0);
1437902a7b52SDimitry Andric   if (NeedNegativeMask) {
1438902a7b52SDimitry Andric     MaskBytes.clear();
1439902a7b52SDimitry Andric     encodeULEB128(NegativeMask.getZExtValue(), S);
1440902a7b52SDimitry Andric     for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i)
1441902a7b52SDimitry Andric       TableInfo.Table.push_back(MaskBytes[i]);
1442902a7b52SDimitry Andric   } else
1443902a7b52SDimitry Andric     TableInfo.Table.push_back(0);
144463faed5bSDimitry Andric }
144563faed5bSDimitry Andric 
1446902a7b52SDimitry Andric // Emits table entries to decode the singleton.
emitSingletonTableEntry(DecoderTableInfo & TableInfo,EncodingIDAndOpcode Opc) const1447902a7b52SDimitry Andric void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1448e6d15924SDimitry Andric                                             EncodingIDAndOpcode Opc) const {
1449cf099d11SDimitry Andric   std::vector<unsigned> StartBits;
1450cf099d11SDimitry Andric   std::vector<unsigned> EndBits;
1451cf099d11SDimitry Andric   std::vector<uint64_t> FieldVals;
1452cf099d11SDimitry Andric   insn_t Insn;
1453e6d15924SDimitry Andric   insnWithID(Insn, Opc.EncodingID);
1454cf099d11SDimitry Andric 
1455cf099d11SDimitry Andric   // Look for islands of undecoded bits of the singleton.
1456cf099d11SDimitry Andric   getIslands(StartBits, EndBits, FieldVals, Insn);
1457cf099d11SDimitry Andric 
1458cf099d11SDimitry Andric   unsigned Size = StartBits.size();
1459cf099d11SDimitry Andric 
1460902a7b52SDimitry Andric   // Emit the predicate table entry if one is needed.
1461e6d15924SDimitry Andric   emitPredicateTableEntry(TableInfo, Opc.EncodingID);
1462902a7b52SDimitry Andric 
1463902a7b52SDimitry Andric   // Check any additional encoding fields needed.
1464902a7b52SDimitry Andric   for (unsigned I = Size; I != 0; --I) {
1465902a7b52SDimitry Andric     unsigned NumBits = EndBits[I - 1] - StartBits[I - 1] + 1;
1466ac9a064cSDimitry Andric     assert((NumBits < (1u << 8)) && "NumBits overflowed uint8 table entry!");
1467902a7b52SDimitry Andric     TableInfo.Table.push_back(MCD::OPC_CheckField);
1468ac9a064cSDimitry Andric     uint8_t Buffer[16], *P;
1469ac9a064cSDimitry Andric     encodeULEB128(StartBits[I - 1], Buffer);
1470ac9a064cSDimitry Andric     for (P = Buffer; *P >= 128; ++P)
1471ac9a064cSDimitry Andric       TableInfo.Table.push_back(*P);
1472ac9a064cSDimitry Andric     TableInfo.Table.push_back(*P);
1473902a7b52SDimitry Andric     TableInfo.Table.push_back(NumBits);
1474902a7b52SDimitry Andric     encodeULEB128(FieldVals[I - 1], Buffer);
1475ac9a064cSDimitry Andric     for (P = Buffer; *P >= 128; ++P)
1476ac9a064cSDimitry Andric       TableInfo.Table.push_back(*P);
1477ac9a064cSDimitry Andric     TableInfo.Table.push_back(*P);
1478902a7b52SDimitry Andric     // Push location for NumToSkip backpatching.
1479902a7b52SDimitry Andric     TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
1480eb11fae6SDimitry Andric     // The fixup is always 24-bits, so go ahead and allocate the space
1481902a7b52SDimitry Andric     // in the table so all our relative position calculations work OK even
1482902a7b52SDimitry Andric     // before we fully resolve the real value here.
1483902a7b52SDimitry Andric     TableInfo.Table.push_back(0);
1484902a7b52SDimitry Andric     TableInfo.Table.push_back(0);
1485eb11fae6SDimitry Andric     TableInfo.Table.push_back(0);
1486cf099d11SDimitry Andric   }
1487cf099d11SDimitry Andric 
1488902a7b52SDimitry Andric   // Check for soft failure of the match.
1489e6d15924SDimitry Andric   emitSoftFailTableEntry(TableInfo, Opc.EncodingID);
1490902a7b52SDimitry Andric 
1491dd58ef01SDimitry Andric   bool HasCompleteDecoder;
1492e6d15924SDimitry Andric   unsigned DIdx =
1493e6d15924SDimitry Andric       getDecoderIndex(TableInfo.Decoders, Opc.EncodingID, HasCompleteDecoder);
1494dd58ef01SDimitry Andric 
1495dd58ef01SDimitry Andric   // Produce OPC_Decode or OPC_TryDecode opcode based on the information
1496dd58ef01SDimitry Andric   // whether the instruction decoder is complete or not. If it is complete
1497dd58ef01SDimitry Andric   // then it handles all possible values of remaining variable/unfiltered bits
1498dd58ef01SDimitry Andric   // and for any value can determine if the bitpattern is a valid instruction
1499dd58ef01SDimitry Andric   // or not. This means OPC_Decode will be the final step in the decoding
1500dd58ef01SDimitry Andric   // process. If it is not complete, then the Fail return code from the
1501dd58ef01SDimitry Andric   // decoder method indicates that additional processing should be done to see
1502dd58ef01SDimitry Andric   // if there is any other instruction that also matches the bitpattern and
1503dd58ef01SDimitry Andric   // can decode it.
1504ac9a064cSDimitry Andric   TableInfo.Table.push_back(HasCompleteDecoder ? MCD::OPC_Decode
1505ac9a064cSDimitry Andric                                                : MCD::OPC_TryDecode);
1506e6d15924SDimitry Andric   NumEncodingsSupported++;
1507eb11fae6SDimitry Andric   uint8_t Buffer[16], *p;
1508e6d15924SDimitry Andric   encodeULEB128(Opc.Opcode, Buffer);
1509902a7b52SDimitry Andric   for (p = Buffer; *p >= 128; ++p)
1510902a7b52SDimitry Andric     TableInfo.Table.push_back(*p);
1511902a7b52SDimitry Andric   TableInfo.Table.push_back(*p);
1512902a7b52SDimitry Andric 
1513902a7b52SDimitry Andric   SmallString<16> Bytes;
1514902a7b52SDimitry Andric   raw_svector_ostream S(Bytes);
1515902a7b52SDimitry Andric   encodeULEB128(DIdx, S);
1516902a7b52SDimitry Andric 
1517ac9a064cSDimitry Andric   // Decoder index.
1518ac9a064cSDimitry Andric   for (const auto B : Bytes)
1519ac9a064cSDimitry Andric     TableInfo.Table.push_back(B);
1520dd58ef01SDimitry Andric 
1521dd58ef01SDimitry Andric   if (!HasCompleteDecoder) {
1522dd58ef01SDimitry Andric     // Push location for NumToSkip backpatching.
1523dd58ef01SDimitry Andric     TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
1524dd58ef01SDimitry Andric     // Allocate the space for the fixup.
1525dd58ef01SDimitry Andric     TableInfo.Table.push_back(0);
1526dd58ef01SDimitry Andric     TableInfo.Table.push_back(0);
1527eb11fae6SDimitry Andric     TableInfo.Table.push_back(0);
1528dd58ef01SDimitry Andric   }
1529cf099d11SDimitry Andric }
1530cf099d11SDimitry Andric 
1531902a7b52SDimitry Andric // Emits table entries to decode the singleton, and then to decode the rest.
emitSingletonTableEntry(DecoderTableInfo & TableInfo,const Filter & Best) const1532902a7b52SDimitry Andric void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
153363faed5bSDimitry Andric                                             const Filter &Best) const {
1534e6d15924SDimitry Andric   EncodingIDAndOpcode Opc = Best.getSingletonOpc();
1535cf099d11SDimitry Andric 
1536902a7b52SDimitry Andric   // complex singletons need predicate checks from the first singleton
1537902a7b52SDimitry Andric   // to refer forward to the variable filterchooser that follows.
153885d8b2bbSDimitry Andric   TableInfo.FixupStack.emplace_back();
1539cf099d11SDimitry Andric 
1540902a7b52SDimitry Andric   emitSingletonTableEntry(TableInfo, Opc);
1541cf099d11SDimitry Andric 
1542902a7b52SDimitry Andric   resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
1543902a7b52SDimitry Andric                      TableInfo.Table.size());
1544902a7b52SDimitry Andric   TableInfo.FixupStack.pop_back();
1545902a7b52SDimitry Andric 
1546902a7b52SDimitry Andric   Best.getVariableFC().emitTableEntries(TableInfo);
1547cf099d11SDimitry Andric }
1548cf099d11SDimitry Andric 
1549cf099d11SDimitry Andric // Assign a single filter and run with it.  Top level API client can initialize
1550cf099d11SDimitry Andric // with a single filter to start the filtering process.
runSingleFilter(unsigned startBit,unsigned numBit,bool mixed)155163faed5bSDimitry Andric void FilterChooser::runSingleFilter(unsigned startBit, unsigned numBit,
155263faed5bSDimitry Andric                                     bool mixed) {
1553cf099d11SDimitry Andric   Filters.clear();
155485d8b2bbSDimitry Andric   Filters.emplace_back(*this, startBit, numBit, true);
1555cf099d11SDimitry Andric   BestIndex = 0; // Sole Filter instance to choose from.
1556cf099d11SDimitry Andric   bestFilter().recurse();
1557cf099d11SDimitry Andric }
1558cf099d11SDimitry Andric 
1559cf099d11SDimitry Andric // reportRegion is a helper function for filterProcessor to mark a region as
1560cf099d11SDimitry Andric // eligible for use as a filter region.
reportRegion(bitAttr_t RA,unsigned StartBit,unsigned BitIndex,bool AllowMixed)1561cf099d11SDimitry Andric void FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit,
1562cf099d11SDimitry Andric                                  unsigned BitIndex, bool AllowMixed) {
1563cf099d11SDimitry Andric   if (RA == ATTR_MIXED && AllowMixed)
156485d8b2bbSDimitry Andric     Filters.emplace_back(*this, StartBit, BitIndex - StartBit, true);
1565cf099d11SDimitry Andric   else if (RA == ATTR_ALL_SET && !AllowMixed)
156685d8b2bbSDimitry Andric     Filters.emplace_back(*this, StartBit, BitIndex - StartBit, false);
1567cf099d11SDimitry Andric }
1568cf099d11SDimitry Andric 
1569cf099d11SDimitry Andric // FilterProcessor scans the well-known encoding bits of the instructions and
1570cf099d11SDimitry Andric // builds up a list of candidate filters.  It chooses the best filter and
1571cf099d11SDimitry Andric // recursively descends down the decoding tree.
filterProcessor(bool AllowMixed,bool Greedy)1572cf099d11SDimitry Andric bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
1573cf099d11SDimitry Andric   Filters.clear();
1574cf099d11SDimitry Andric   BestIndex = -1;
1575cf099d11SDimitry Andric   unsigned numInstructions = Opcodes.size();
1576cf099d11SDimitry Andric 
1577cf099d11SDimitry Andric   assert(numInstructions && "Filter created with no instructions");
1578cf099d11SDimitry Andric 
1579cf099d11SDimitry Andric   // No further filtering is necessary.
1580cf099d11SDimitry Andric   if (numInstructions == 1)
1581cf099d11SDimitry Andric     return true;
1582cf099d11SDimitry Andric 
1583cf099d11SDimitry Andric   // Heuristics.  See also doFilter()'s "Heuristics" comment when num of
1584cf099d11SDimitry Andric   // instructions is 3.
1585cf099d11SDimitry Andric   if (AllowMixed && !Greedy) {
1586cf099d11SDimitry Andric     assert(numInstructions == 3);
1587cf099d11SDimitry Andric 
1588ac9a064cSDimitry Andric     for (const auto &Opcode : Opcodes) {
1589cf099d11SDimitry Andric       std::vector<unsigned> StartBits;
1590cf099d11SDimitry Andric       std::vector<unsigned> EndBits;
1591cf099d11SDimitry Andric       std::vector<uint64_t> FieldVals;
1592cf099d11SDimitry Andric       insn_t Insn;
1593cf099d11SDimitry Andric 
1594344a3780SDimitry Andric       insnWithID(Insn, Opcode.EncodingID);
1595cf099d11SDimitry Andric 
1596cf099d11SDimitry Andric       // Look for islands of undecoded bits of any instruction.
1597cf099d11SDimitry Andric       if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) {
1598cf099d11SDimitry Andric         // Found an instruction with island(s).  Now just assign a filter.
159963faed5bSDimitry Andric         runSingleFilter(StartBits[0], EndBits[0] - StartBits[0] + 1, true);
1600cf099d11SDimitry Andric         return true;
1601cf099d11SDimitry Andric       }
1602cf099d11SDimitry Andric     }
1603cf099d11SDimitry Andric   }
1604cf099d11SDimitry Andric 
1605902a7b52SDimitry Andric   unsigned BitIndex;
1606cf099d11SDimitry Andric 
1607cf099d11SDimitry Andric   // We maintain BIT_WIDTH copies of the bitAttrs automaton.
1608cf099d11SDimitry Andric   // The automaton consumes the corresponding bit from each
1609cf099d11SDimitry Andric   // instruction.
1610cf099d11SDimitry Andric   //
1611cf099d11SDimitry Andric   //   Input symbols: 0, 1, and _ (unset).
1612cf099d11SDimitry Andric   //   States:        NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED.
1613cf099d11SDimitry Andric   //   Initial state: NONE.
1614cf099d11SDimitry Andric   //
1615cf099d11SDimitry Andric   // (NONE) ------- [01] -> (ALL_SET)
1616cf099d11SDimitry Andric   // (NONE) ------- _ ----> (ALL_UNSET)
1617cf099d11SDimitry Andric   // (ALL_SET) ---- [01] -> (ALL_SET)
1618cf099d11SDimitry Andric   // (ALL_SET) ---- _ ----> (MIXED)
1619cf099d11SDimitry Andric   // (ALL_UNSET) -- [01] -> (MIXED)
1620cf099d11SDimitry Andric   // (ALL_UNSET) -- _ ----> (ALL_UNSET)
1621cf099d11SDimitry Andric   // (MIXED) ------ . ----> (MIXED)
1622cf099d11SDimitry Andric   // (FILTERED)---- . ----> (FILTERED)
1623cf099d11SDimitry Andric 
162430815c53SDimitry Andric   std::vector<bitAttr_t> bitAttrs;
1625cf099d11SDimitry Andric 
1626cf099d11SDimitry Andric   // FILTERED bit positions provide no entropy and are not worthy of pursuing.
1627cf099d11SDimitry Andric   // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position.
162830815c53SDimitry Andric   for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex)
1629cf099d11SDimitry Andric     if (FilterBitValues[BitIndex] == BIT_TRUE ||
1630cf099d11SDimitry Andric         FilterBitValues[BitIndex] == BIT_FALSE)
163130815c53SDimitry Andric       bitAttrs.push_back(ATTR_FILTERED);
1632cf099d11SDimitry Andric     else
163330815c53SDimitry Andric       bitAttrs.push_back(ATTR_NONE);
1634cf099d11SDimitry Andric 
1635ac9a064cSDimitry Andric   for (const auto &OpcPair : Opcodes) {
1636cf099d11SDimitry Andric     insn_t insn;
1637cf099d11SDimitry Andric 
1638ac9a064cSDimitry Andric     insnWithID(insn, OpcPair.EncodingID);
1639cf099d11SDimitry Andric 
164030815c53SDimitry Andric     for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
1641cf099d11SDimitry Andric       switch (bitAttrs[BitIndex]) {
1642cf099d11SDimitry Andric       case ATTR_NONE:
1643cf099d11SDimitry Andric         if (insn[BitIndex] == BIT_UNSET)
1644cf099d11SDimitry Andric           bitAttrs[BitIndex] = ATTR_ALL_UNSET;
1645cf099d11SDimitry Andric         else
1646cf099d11SDimitry Andric           bitAttrs[BitIndex] = ATTR_ALL_SET;
1647cf099d11SDimitry Andric         break;
1648cf099d11SDimitry Andric       case ATTR_ALL_SET:
1649cf099d11SDimitry Andric         if (insn[BitIndex] == BIT_UNSET)
1650cf099d11SDimitry Andric           bitAttrs[BitIndex] = ATTR_MIXED;
1651cf099d11SDimitry Andric         break;
1652cf099d11SDimitry Andric       case ATTR_ALL_UNSET:
1653cf099d11SDimitry Andric         if (insn[BitIndex] != BIT_UNSET)
1654cf099d11SDimitry Andric           bitAttrs[BitIndex] = ATTR_MIXED;
1655cf099d11SDimitry Andric         break;
1656cf099d11SDimitry Andric       case ATTR_MIXED:
1657cf099d11SDimitry Andric       case ATTR_FILTERED:
1658cf099d11SDimitry Andric         break;
1659cf099d11SDimitry Andric       }
1660cf099d11SDimitry Andric     }
1661cf099d11SDimitry Andric   }
1662cf099d11SDimitry Andric 
1663cf099d11SDimitry Andric   // The regionAttr automaton consumes the bitAttrs automatons' state,
1664cf099d11SDimitry Andric   // lowest-to-highest.
1665cf099d11SDimitry Andric   //
1666cf099d11SDimitry Andric   //   Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed)
1667cf099d11SDimitry Andric   //   States:        NONE, ALL_SET, MIXED
1668cf099d11SDimitry Andric   //   Initial state: NONE
1669cf099d11SDimitry Andric   //
1670cf099d11SDimitry Andric   // (NONE) ----- F --> (NONE)
1671cf099d11SDimitry Andric   // (NONE) ----- S --> (ALL_SET)     ; and set region start
1672cf099d11SDimitry Andric   // (NONE) ----- U --> (NONE)
1673cf099d11SDimitry Andric   // (NONE) ----- M --> (MIXED)       ; and set region start
1674cf099d11SDimitry Andric   // (ALL_SET) -- F --> (NONE)        ; and report an ALL_SET region
1675cf099d11SDimitry Andric   // (ALL_SET) -- S --> (ALL_SET)
1676cf099d11SDimitry Andric   // (ALL_SET) -- U --> (NONE)        ; and report an ALL_SET region
1677cf099d11SDimitry Andric   // (ALL_SET) -- M --> (MIXED)       ; and report an ALL_SET region
1678cf099d11SDimitry Andric   // (MIXED) ---- F --> (NONE)        ; and report a MIXED region
1679cf099d11SDimitry Andric   // (MIXED) ---- S --> (ALL_SET)     ; and report a MIXED region
1680cf099d11SDimitry Andric   // (MIXED) ---- U --> (NONE)        ; and report a MIXED region
1681cf099d11SDimitry Andric   // (MIXED) ---- M --> (MIXED)
1682cf099d11SDimitry Andric 
1683cf099d11SDimitry Andric   bitAttr_t RA = ATTR_NONE;
1684cf099d11SDimitry Andric   unsigned StartBit = 0;
1685cf099d11SDimitry Andric 
1686902a7b52SDimitry Andric   for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
1687cf099d11SDimitry Andric     bitAttr_t bitAttr = bitAttrs[BitIndex];
1688cf099d11SDimitry Andric 
1689cf099d11SDimitry Andric     assert(bitAttr != ATTR_NONE && "Bit without attributes");
1690cf099d11SDimitry Andric 
1691cf099d11SDimitry Andric     switch (RA) {
1692cf099d11SDimitry Andric     case ATTR_NONE:
1693cf099d11SDimitry Andric       switch (bitAttr) {
1694cf099d11SDimitry Andric       case ATTR_FILTERED:
1695cf099d11SDimitry Andric         break;
1696cf099d11SDimitry Andric       case ATTR_ALL_SET:
1697cf099d11SDimitry Andric         StartBit = BitIndex;
1698cf099d11SDimitry Andric         RA = ATTR_ALL_SET;
1699cf099d11SDimitry Andric         break;
1700cf099d11SDimitry Andric       case ATTR_ALL_UNSET:
1701cf099d11SDimitry Andric         break;
1702cf099d11SDimitry Andric       case ATTR_MIXED:
1703cf099d11SDimitry Andric         StartBit = BitIndex;
1704cf099d11SDimitry Andric         RA = ATTR_MIXED;
1705cf099d11SDimitry Andric         break;
1706cf099d11SDimitry Andric       default:
170763faed5bSDimitry Andric         llvm_unreachable("Unexpected bitAttr!");
1708cf099d11SDimitry Andric       }
1709cf099d11SDimitry Andric       break;
1710cf099d11SDimitry Andric     case ATTR_ALL_SET:
1711cf099d11SDimitry Andric       switch (bitAttr) {
1712cf099d11SDimitry Andric       case ATTR_FILTERED:
1713cf099d11SDimitry Andric         reportRegion(RA, StartBit, BitIndex, AllowMixed);
1714cf099d11SDimitry Andric         RA = ATTR_NONE;
1715cf099d11SDimitry Andric         break;
1716cf099d11SDimitry Andric       case ATTR_ALL_SET:
1717cf099d11SDimitry Andric         break;
1718cf099d11SDimitry Andric       case ATTR_ALL_UNSET:
1719cf099d11SDimitry Andric         reportRegion(RA, StartBit, BitIndex, AllowMixed);
1720cf099d11SDimitry Andric         RA = ATTR_NONE;
1721cf099d11SDimitry Andric         break;
1722cf099d11SDimitry Andric       case ATTR_MIXED:
1723cf099d11SDimitry Andric         reportRegion(RA, StartBit, BitIndex, AllowMixed);
1724cf099d11SDimitry Andric         StartBit = BitIndex;
1725cf099d11SDimitry Andric         RA = ATTR_MIXED;
1726cf099d11SDimitry Andric         break;
1727cf099d11SDimitry Andric       default:
172863faed5bSDimitry Andric         llvm_unreachable("Unexpected bitAttr!");
1729cf099d11SDimitry Andric       }
1730cf099d11SDimitry Andric       break;
1731cf099d11SDimitry Andric     case ATTR_MIXED:
1732cf099d11SDimitry Andric       switch (bitAttr) {
1733cf099d11SDimitry Andric       case ATTR_FILTERED:
1734cf099d11SDimitry Andric         reportRegion(RA, StartBit, BitIndex, AllowMixed);
1735cf099d11SDimitry Andric         StartBit = BitIndex;
1736cf099d11SDimitry Andric         RA = ATTR_NONE;
1737cf099d11SDimitry Andric         break;
1738cf099d11SDimitry Andric       case ATTR_ALL_SET:
1739cf099d11SDimitry Andric         reportRegion(RA, StartBit, BitIndex, AllowMixed);
1740cf099d11SDimitry Andric         StartBit = BitIndex;
1741cf099d11SDimitry Andric         RA = ATTR_ALL_SET;
1742cf099d11SDimitry Andric         break;
1743cf099d11SDimitry Andric       case ATTR_ALL_UNSET:
1744cf099d11SDimitry Andric         reportRegion(RA, StartBit, BitIndex, AllowMixed);
1745cf099d11SDimitry Andric         RA = ATTR_NONE;
1746cf099d11SDimitry Andric         break;
1747cf099d11SDimitry Andric       case ATTR_MIXED:
1748cf099d11SDimitry Andric         break;
1749cf099d11SDimitry Andric       default:
175063faed5bSDimitry Andric         llvm_unreachable("Unexpected bitAttr!");
1751cf099d11SDimitry Andric       }
1752cf099d11SDimitry Andric       break;
1753cf099d11SDimitry Andric     case ATTR_ALL_UNSET:
175463faed5bSDimitry Andric       llvm_unreachable("regionAttr state machine has no ATTR_UNSET state");
1755cf099d11SDimitry Andric     case ATTR_FILTERED:
175663faed5bSDimitry Andric       llvm_unreachable("regionAttr state machine has no ATTR_FILTERED state");
1757cf099d11SDimitry Andric     }
1758cf099d11SDimitry Andric   }
1759cf099d11SDimitry Andric 
1760cf099d11SDimitry Andric   // At the end, if we're still in ALL_SET or MIXED states, report a region
1761cf099d11SDimitry Andric   switch (RA) {
1762cf099d11SDimitry Andric   case ATTR_NONE:
1763cf099d11SDimitry Andric     break;
1764cf099d11SDimitry Andric   case ATTR_FILTERED:
1765cf099d11SDimitry Andric     break;
1766cf099d11SDimitry Andric   case ATTR_ALL_SET:
1767cf099d11SDimitry Andric     reportRegion(RA, StartBit, BitIndex, AllowMixed);
1768cf099d11SDimitry Andric     break;
1769cf099d11SDimitry Andric   case ATTR_ALL_UNSET:
1770cf099d11SDimitry Andric     break;
1771cf099d11SDimitry Andric   case ATTR_MIXED:
1772cf099d11SDimitry Andric     reportRegion(RA, StartBit, BitIndex, AllowMixed);
1773cf099d11SDimitry Andric     break;
1774cf099d11SDimitry Andric   }
1775cf099d11SDimitry Andric 
1776cf099d11SDimitry Andric   // We have finished with the filter processings.  Now it's time to choose
1777cf099d11SDimitry Andric   // the best performing filter.
1778cf099d11SDimitry Andric   BestIndex = 0;
1779cf099d11SDimitry Andric   bool AllUseless = true;
1780cf099d11SDimitry Andric   unsigned BestScore = 0;
1781cf099d11SDimitry Andric 
1782ac9a064cSDimitry Andric   for (const auto &[Idx, Filter] : enumerate(Filters)) {
1783ac9a064cSDimitry Andric     unsigned Usefulness = Filter.usefulness();
1784cf099d11SDimitry Andric 
1785cf099d11SDimitry Andric     if (Usefulness)
1786cf099d11SDimitry Andric       AllUseless = false;
1787cf099d11SDimitry Andric 
1788cf099d11SDimitry Andric     if (Usefulness > BestScore) {
1789ac9a064cSDimitry Andric       BestIndex = Idx;
1790cf099d11SDimitry Andric       BestScore = Usefulness;
1791cf099d11SDimitry Andric     }
1792cf099d11SDimitry Andric   }
1793cf099d11SDimitry Andric 
1794cf099d11SDimitry Andric   if (!AllUseless)
1795cf099d11SDimitry Andric     bestFilter().recurse();
1796cf099d11SDimitry Andric 
1797cf099d11SDimitry Andric   return !AllUseless;
1798cf099d11SDimitry Andric } // end of FilterChooser::filterProcessor(bool)
1799cf099d11SDimitry Andric 
1800cf099d11SDimitry Andric // Decides on the best configuration of filter(s) to use in order to decode
1801cf099d11SDimitry Andric // the instructions.  A conflict of instructions may occur, in which case we
1802cf099d11SDimitry Andric // dump the conflict set to the standard error.
doFilter()1803cf099d11SDimitry Andric void FilterChooser::doFilter() {
1804cf099d11SDimitry Andric   unsigned Num = Opcodes.size();
1805cf099d11SDimitry Andric   assert(Num && "FilterChooser created with no instructions");
1806cf099d11SDimitry Andric 
1807cf099d11SDimitry Andric   // Try regions of consecutive known bit values first.
1808cf099d11SDimitry Andric   if (filterProcessor(false))
1809cf099d11SDimitry Andric     return;
1810cf099d11SDimitry Andric 
1811cf099d11SDimitry Andric   // Then regions of mixed bits (both known and unitialized bit values allowed).
1812cf099d11SDimitry Andric   if (filterProcessor(true))
1813cf099d11SDimitry Andric     return;
1814cf099d11SDimitry Andric 
1815cf099d11SDimitry Andric   // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where
1816cf099d11SDimitry Andric   // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a
1817cf099d11SDimitry Andric   // well-known encoding pattern.  In such case, we backtrack and scan for the
1818cf099d11SDimitry Andric   // the very first consecutive ATTR_ALL_SET region and assign a filter to it.
1819cf099d11SDimitry Andric   if (Num == 3 && filterProcessor(true, false))
1820cf099d11SDimitry Andric     return;
1821cf099d11SDimitry Andric 
1822cf099d11SDimitry Andric   // If we come to here, the instruction decoding has failed.
1823cf099d11SDimitry Andric   // Set the BestIndex to -1 to indicate so.
1824cf099d11SDimitry Andric   BestIndex = -1;
1825cf099d11SDimitry Andric }
1826cf099d11SDimitry Andric 
1827902a7b52SDimitry Andric // emitTableEntries - Emit state machine entries to decode our share of
1828902a7b52SDimitry Andric // instructions.
emitTableEntries(DecoderTableInfo & TableInfo) const1829902a7b52SDimitry Andric void FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const {
1830902a7b52SDimitry Andric   if (Opcodes.size() == 1) {
1831cf099d11SDimitry Andric     // There is only one instruction in the set, which is great!
1832cf099d11SDimitry Andric     // Call emitSingletonDecoder() to see whether there are any remaining
1833cf099d11SDimitry Andric     // encodings bits.
1834902a7b52SDimitry Andric     emitSingletonTableEntry(TableInfo, Opcodes[0]);
1835902a7b52SDimitry Andric     return;
1836902a7b52SDimitry Andric   }
1837cf099d11SDimitry Andric 
1838cf099d11SDimitry Andric   // Choose the best filter to do the decodings!
1839cf099d11SDimitry Andric   if (BestIndex != -1) {
184063faed5bSDimitry Andric     const Filter &Best = Filters[BestIndex];
1841cf099d11SDimitry Andric     if (Best.getNumFiltered() == 1)
1842902a7b52SDimitry Andric       emitSingletonTableEntry(TableInfo, Best);
1843cf099d11SDimitry Andric     else
1844902a7b52SDimitry Andric       Best.emitTableEntry(TableInfo);
1845902a7b52SDimitry Andric     return;
1846cf099d11SDimitry Andric   }
1847cf099d11SDimitry Andric 
1848902a7b52SDimitry Andric   // We don't know how to decode these instructions!  Dump the
1849902a7b52SDimitry Andric   // conflict set and bail.
1850cf099d11SDimitry Andric 
1851cf099d11SDimitry Andric   // Print out useful conflict information for postmortem analysis.
1852cf099d11SDimitry Andric   errs() << "Decoding Conflict:\n";
1853cf099d11SDimitry Andric 
1854cf099d11SDimitry Andric   dumpStack(errs(), "\t\t");
1855cf099d11SDimitry Andric 
1856344a3780SDimitry Andric   for (auto Opcode : Opcodes) {
1857e6d15924SDimitry Andric     errs() << '\t';
1858344a3780SDimitry Andric     emitNameWithID(errs(), Opcode.EncodingID);
1859e6d15924SDimitry Andric     errs() << " ";
1860e6d15924SDimitry Andric     dumpBits(
1861e6d15924SDimitry Andric         errs(),
1862344a3780SDimitry Andric         getBitsField(*AllInstructions[Opcode.EncodingID].EncodingDef, "Inst"));
1863cf099d11SDimitry Andric     errs() << '\n';
1864cf099d11SDimitry Andric   }
1865cf099d11SDimitry Andric }
1866cf099d11SDimitry Andric 
findOperandDecoderMethod(Record * Record)1867145449b1SDimitry Andric static std::string findOperandDecoderMethod(Record *Record) {
1868b915e9e0SDimitry Andric   std::string Decoder;
1869b915e9e0SDimitry Andric 
1870eb11fae6SDimitry Andric   RecordVal *DecoderString = Record->getValue("DecoderMethod");
1871ac9a064cSDimitry Andric   StringInit *String =
1872ac9a064cSDimitry Andric       DecoderString ? dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
1873b915e9e0SDimitry Andric   if (String) {
1874cfca06d7SDimitry Andric     Decoder = std::string(String->getValue());
1875b915e9e0SDimitry Andric     if (!Decoder.empty())
1876b915e9e0SDimitry Andric       return Decoder;
1877b915e9e0SDimitry Andric   }
1878b915e9e0SDimitry Andric 
1879eb11fae6SDimitry Andric   if (Record->isSubClassOf("RegisterOperand"))
1880ac9a064cSDimitry Andric     // Allows use of a DecoderMethod in referenced RegisterClass if set.
1881ac9a064cSDimitry Andric     return findOperandDecoderMethod(Record->getValueAsDef("RegClass"));
1882b915e9e0SDimitry Andric 
1883eb11fae6SDimitry Andric   if (Record->isSubClassOf("RegisterClass")) {
1884eb11fae6SDimitry Andric     Decoder = "Decode" + Record->getName().str() + "RegisterClass";
1885eb11fae6SDimitry Andric   } else if (Record->isSubClassOf("PointerLikeRegClass")) {
1886b915e9e0SDimitry Andric     Decoder = "DecodePointerLikeRegClass" +
1887eb11fae6SDimitry Andric               utostr(Record->getValueAsInt("RegClassKind"));
1888b915e9e0SDimitry Andric   }
1889b915e9e0SDimitry Andric 
1890b915e9e0SDimitry Andric   return Decoder;
1891b915e9e0SDimitry Andric }
1892b915e9e0SDimitry Andric 
getOpInfo(Record * TypeRecord)1893145449b1SDimitry Andric OperandInfo getOpInfo(Record *TypeRecord) {
1894145449b1SDimitry Andric   std::string Decoder = findOperandDecoderMethod(TypeRecord);
1895145449b1SDimitry Andric 
1896145449b1SDimitry Andric   RecordVal *HasCompleteDecoderVal = TypeRecord->getValue("hasCompleteDecoder");
1897145449b1SDimitry Andric   BitInit *HasCompleteDecoderBit =
1898145449b1SDimitry Andric       HasCompleteDecoderVal
1899145449b1SDimitry Andric           ? dyn_cast<BitInit>(HasCompleteDecoderVal->getValue())
1900145449b1SDimitry Andric           : nullptr;
1901145449b1SDimitry Andric   bool HasCompleteDecoder =
1902145449b1SDimitry Andric       HasCompleteDecoderBit ? HasCompleteDecoderBit->getValue() : true;
1903145449b1SDimitry Andric 
1904145449b1SDimitry Andric   return OperandInfo(Decoder, HasCompleteDecoder);
1905145449b1SDimitry Andric }
1906145449b1SDimitry Andric 
parseVarLenInstOperand(const Record & Def,std::vector<OperandInfo> & Operands,const CodeGenInstruction & CGI)1907145449b1SDimitry Andric void parseVarLenInstOperand(const Record &Def,
1908145449b1SDimitry Andric                             std::vector<OperandInfo> &Operands,
1909145449b1SDimitry Andric                             const CodeGenInstruction &CGI) {
1910145449b1SDimitry Andric 
1911145449b1SDimitry Andric   const RecordVal *RV = Def.getValue("Inst");
1912145449b1SDimitry Andric   VarLenInst VLI(cast<DagInit>(RV->getValue()), RV);
1913145449b1SDimitry Andric   SmallVector<int> TiedTo;
1914145449b1SDimitry Andric 
1915ac9a064cSDimitry Andric   for (const auto &[Idx, Op] : enumerate(CGI.Operands)) {
1916145449b1SDimitry Andric     if (Op.MIOperandInfo && Op.MIOperandInfo->getNumArgs() > 0)
1917145449b1SDimitry Andric       for (auto *Arg : Op.MIOperandInfo->getArgs())
1918145449b1SDimitry Andric         Operands.push_back(getOpInfo(cast<DefInit>(Arg)->getDef()));
1919145449b1SDimitry Andric     else
1920145449b1SDimitry Andric       Operands.push_back(getOpInfo(Op.Rec));
1921145449b1SDimitry Andric 
1922145449b1SDimitry Andric     int TiedReg = Op.getTiedRegister();
1923145449b1SDimitry Andric     TiedTo.push_back(-1);
1924145449b1SDimitry Andric     if (TiedReg != -1) {
1925145449b1SDimitry Andric       TiedTo[Idx] = TiedReg;
1926145449b1SDimitry Andric       TiedTo[TiedReg] = Idx;
1927145449b1SDimitry Andric     }
1928145449b1SDimitry Andric   }
1929145449b1SDimitry Andric 
1930145449b1SDimitry Andric   unsigned CurrBitPos = 0;
1931ac9a064cSDimitry Andric   for (const auto &EncodingSegment : VLI) {
1932145449b1SDimitry Andric     unsigned Offset = 0;
1933145449b1SDimitry Andric     StringRef OpName;
1934145449b1SDimitry Andric 
1935145449b1SDimitry Andric     if (const StringInit *SI = dyn_cast<StringInit>(EncodingSegment.Value)) {
1936145449b1SDimitry Andric       OpName = SI->getValue();
1937145449b1SDimitry Andric     } else if (const DagInit *DI = dyn_cast<DagInit>(EncodingSegment.Value)) {
1938145449b1SDimitry Andric       OpName = cast<StringInit>(DI->getArg(0))->getValue();
1939145449b1SDimitry Andric       Offset = cast<IntInit>(DI->getArg(2))->getValue();
1940145449b1SDimitry Andric     }
1941145449b1SDimitry Andric 
1942145449b1SDimitry Andric     if (!OpName.empty()) {
1943145449b1SDimitry Andric       auto OpSubOpPair =
1944145449b1SDimitry Andric           const_cast<CodeGenInstruction &>(CGI).Operands.ParseOperandName(
1945145449b1SDimitry Andric               OpName);
1946145449b1SDimitry Andric       unsigned OpIdx = CGI.Operands.getFlattenedOperandNumber(OpSubOpPair);
1947145449b1SDimitry Andric       Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset);
1948e3b55780SDimitry Andric       if (!EncodingSegment.CustomDecoder.empty())
1949e3b55780SDimitry Andric         Operands[OpIdx].Decoder = EncodingSegment.CustomDecoder.str();
1950145449b1SDimitry Andric 
1951145449b1SDimitry Andric       int TiedReg = TiedTo[OpSubOpPair.first];
1952145449b1SDimitry Andric       if (TiedReg != -1) {
1953145449b1SDimitry Andric         unsigned OpIdx = CGI.Operands.getFlattenedOperandNumber(
1954ac9a064cSDimitry Andric             std::pair(TiedReg, OpSubOpPair.second));
1955145449b1SDimitry Andric         Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset);
1956145449b1SDimitry Andric       }
1957145449b1SDimitry Andric     }
1958145449b1SDimitry Andric 
1959145449b1SDimitry Andric     CurrBitPos += EncodingSegment.BitWidth;
1960145449b1SDimitry Andric   }
1961145449b1SDimitry Andric }
1962145449b1SDimitry Andric 
debugDumpRecord(const Record & Rec)1963e3b55780SDimitry Andric static void debugDumpRecord(const Record &Rec) {
1964e3b55780SDimitry Andric   // Dump the record, so we can see what's going on...
1965e3b55780SDimitry Andric   std::string E;
1966e3b55780SDimitry Andric   raw_string_ostream S(E);
1967e3b55780SDimitry Andric   S << "Dumping record for previous error:\n";
1968e3b55780SDimitry Andric   S << Rec;
1969e3b55780SDimitry Andric   PrintNote(E);
1970e3b55780SDimitry Andric }
1971e3b55780SDimitry Andric 
1972e3b55780SDimitry Andric /// For an operand field named OpName: populate OpInfo.InitValue with the
1973e3b55780SDimitry Andric /// constant-valued bit values, and OpInfo.Fields with the ranges of bits to
1974e3b55780SDimitry Andric /// insert from the decoded instruction.
addOneOperandFields(const Record & EncodingDef,const BitsInit & Bits,std::map<std::string,std::string> & TiedNames,StringRef OpName,OperandInfo & OpInfo)1975e3b55780SDimitry Andric static void addOneOperandFields(const Record &EncodingDef, const BitsInit &Bits,
1976e3b55780SDimitry Andric                                 std::map<std::string, std::string> &TiedNames,
1977e3b55780SDimitry Andric                                 StringRef OpName, OperandInfo &OpInfo) {
1978e3b55780SDimitry Andric   // Some bits of the operand may be required to be 1 depending on the
1979e3b55780SDimitry Andric   // instruction's encoding. Collect those bits.
1980e3b55780SDimitry Andric   if (const RecordVal *EncodedValue = EncodingDef.getValue(OpName))
1981e3b55780SDimitry Andric     if (const BitsInit *OpBits = dyn_cast<BitsInit>(EncodedValue->getValue()))
1982e3b55780SDimitry Andric       for (unsigned I = 0; I < OpBits->getNumBits(); ++I)
1983e3b55780SDimitry Andric         if (const BitInit *OpBit = dyn_cast<BitInit>(OpBits->getBit(I)))
1984e3b55780SDimitry Andric           if (OpBit->getValue())
1985e3b55780SDimitry Andric             OpInfo.InitValue |= 1ULL << I;
1986e3b55780SDimitry Andric 
1987e3b55780SDimitry Andric   for (unsigned I = 0, J = 0; I != Bits.getNumBits(); I = J) {
1988e3b55780SDimitry Andric     VarInit *Var;
1989e3b55780SDimitry Andric     unsigned Offset = 0;
1990e3b55780SDimitry Andric     for (; J != Bits.getNumBits(); ++J) {
1991e3b55780SDimitry Andric       VarBitInit *BJ = dyn_cast<VarBitInit>(Bits.getBit(J));
1992e3b55780SDimitry Andric       if (BJ) {
1993e3b55780SDimitry Andric         Var = dyn_cast<VarInit>(BJ->getBitVar());
1994e3b55780SDimitry Andric         if (I == J)
1995e3b55780SDimitry Andric           Offset = BJ->getBitNum();
1996e3b55780SDimitry Andric         else if (BJ->getBitNum() != Offset + J - I)
1997e3b55780SDimitry Andric           break;
1998e3b55780SDimitry Andric       } else {
1999e3b55780SDimitry Andric         Var = dyn_cast<VarInit>(Bits.getBit(J));
2000e3b55780SDimitry Andric       }
2001e3b55780SDimitry Andric       if (!Var || (Var->getName() != OpName &&
2002e3b55780SDimitry Andric                    Var->getName() != TiedNames[std::string(OpName)]))
2003e3b55780SDimitry Andric         break;
2004e3b55780SDimitry Andric     }
2005e3b55780SDimitry Andric     if (I == J)
2006e3b55780SDimitry Andric       ++J;
2007e3b55780SDimitry Andric     else
2008e3b55780SDimitry Andric       OpInfo.addField(I, J - I, Offset);
2009e3b55780SDimitry Andric   }
2010e3b55780SDimitry Andric }
2011e3b55780SDimitry Andric 
2012145449b1SDimitry Andric static unsigned
populateInstruction(CodeGenTarget & Target,const Record & EncodingDef,const CodeGenInstruction & CGI,unsigned Opc,std::map<unsigned,std::vector<OperandInfo>> & Operands,bool IsVarLenInst)2013e6d15924SDimitry Andric populateInstruction(CodeGenTarget &Target, const Record &EncodingDef,
20145ca98fd9SDimitry Andric                     const CodeGenInstruction &CGI, unsigned Opc,
2015145449b1SDimitry Andric                     std::map<unsigned, std::vector<OperandInfo>> &Operands,
2016145449b1SDimitry Andric                     bool IsVarLenInst) {
2017cf099d11SDimitry Andric   const Record &Def = *CGI.TheDef;
2018cf099d11SDimitry Andric   // If all the bit positions are not specified; do not decode this instruction.
2019cf099d11SDimitry Andric   // We are bound to fail!  For proper disassembly, the well-known encoding bits
2020cf099d11SDimitry Andric   // of the instruction must be fully specified.
2021cf099d11SDimitry Andric 
2022e6d15924SDimitry Andric   BitsInit &Bits = getBitsField(EncodingDef, "Inst");
2023145449b1SDimitry Andric   if (Bits.allInComplete())
2024145449b1SDimitry Andric     return 0;
2025411bd29eSDimitry Andric 
2026cf099d11SDimitry Andric   std::vector<OperandInfo> InsnOperands;
2027cf099d11SDimitry Andric 
2028cf099d11SDimitry Andric   // If the instruction has specified a custom decoding hook, use that instead
2029cf099d11SDimitry Andric   // of trying to auto-generate the decoder.
2030e6d15924SDimitry Andric   StringRef InstDecoder = EncodingDef.getValueAsString("DecoderMethod");
2031cf099d11SDimitry Andric   if (InstDecoder != "") {
2032ac9a064cSDimitry Andric     bool HasCompleteInstDecoder =
2033ac9a064cSDimitry Andric         EncodingDef.getValueAsBit("hasCompleteDecoder");
2034cfca06d7SDimitry Andric     InsnOperands.push_back(
2035cfca06d7SDimitry Andric         OperandInfo(std::string(InstDecoder), HasCompleteInstDecoder));
2036cf099d11SDimitry Andric     Operands[Opc] = InsnOperands;
2037145449b1SDimitry Andric     return Bits.getNumBits();
2038cf099d11SDimitry Andric   }
2039cf099d11SDimitry Andric 
2040cf099d11SDimitry Andric   // Generate a description of the operand of the instruction that we know
2041cf099d11SDimitry Andric   // how to decode automatically.
2042cf099d11SDimitry Andric   // FIXME: We'll need to have a way to manually override this as needed.
2043cf099d11SDimitry Andric 
2044cf099d11SDimitry Andric   // Gather the outputs/inputs of the instruction, so we can find their
2045cf099d11SDimitry Andric   // positions in the encoding.  This assumes for now that they appear in the
2046cf099d11SDimitry Andric   // MCInst in the order that they're listed.
2047b915e9e0SDimitry Andric   std::vector<std::pair<Init *, StringRef>> InOutOperands;
2048cf099d11SDimitry Andric   DagInit *Out = Def.getValueAsDag("OutOperandList");
2049cf099d11SDimitry Andric   DagInit *In = Def.getValueAsDag("InOperandList");
2050ac9a064cSDimitry Andric   for (const auto &[Idx, Arg] : enumerate(Out->getArgs()))
2051ac9a064cSDimitry Andric     InOutOperands.push_back(std::pair(Arg, Out->getArgNameStr(Idx)));
2052ac9a064cSDimitry Andric   for (const auto &[Idx, Arg] : enumerate(In->getArgs()))
2053ac9a064cSDimitry Andric     InOutOperands.push_back(std::pair(Arg, In->getArgNameStr(Idx)));
2054cf099d11SDimitry Andric 
205530815c53SDimitry Andric   // Search for tied operands, so that we can correctly instantiate
205630815c53SDimitry Andric   // operands that are not explicitly represented in the encoding.
205730815c53SDimitry Andric   std::map<std::string, std::string> TiedNames;
2058ac9a064cSDimitry Andric   for (const auto &[I, Op] : enumerate(CGI.Operands)) {
2059ac9a064cSDimitry Andric     for (const auto &[J, CI] : enumerate(Op.Constraints)) {
2060e3b55780SDimitry Andric       if (CI.isTied()) {
20615ca98fd9SDimitry Andric         std::pair<unsigned, unsigned> SO =
2062ac9a064cSDimitry Andric             CGI.Operands.getSubOperandNumber(CI.getTiedOperand());
2063e3b55780SDimitry Andric         std::string TiedName = CGI.Operands[SO.first].SubOpNames[SO.second];
2064e3b55780SDimitry Andric         if (TiedName.empty())
2065e3b55780SDimitry Andric           TiedName = CGI.Operands[SO.first].Name;
2066ac9a064cSDimitry Andric         std::string MyName = Op.SubOpNames[J];
2067e3b55780SDimitry Andric         if (MyName.empty())
2068e3b55780SDimitry Andric           MyName = Op.Name;
2069e3b55780SDimitry Andric 
2070e3b55780SDimitry Andric         TiedNames[MyName] = TiedName;
2071e3b55780SDimitry Andric         TiedNames[TiedName] = MyName;
2072e3b55780SDimitry Andric       }
20735ca98fd9SDimitry Andric     }
20745ca98fd9SDimitry Andric   }
20755ca98fd9SDimitry Andric 
2076145449b1SDimitry Andric   if (IsVarLenInst) {
2077145449b1SDimitry Andric     parseVarLenInstOperand(EncodingDef, InsnOperands, CGI);
2078145449b1SDimitry Andric   } else {
2079cf099d11SDimitry Andric     // For each operand, see if we can figure out where it is encoded.
208067c32a98SDimitry Andric     for (const auto &Op : InOutOperands) {
2081e3b55780SDimitry Andric       Init *OpInit = Op.first;
2082e3b55780SDimitry Andric       StringRef OpName = Op.second;
2083e3b55780SDimitry Andric 
2084ac9a064cSDimitry Andric       // We're ready to find the instruction encoding locations for this
2085ac9a064cSDimitry Andric       // operand.
208630815c53SDimitry Andric 
2087e3b55780SDimitry Andric       // First, find the operand type ("OpInit"), and sub-op names
2088e3b55780SDimitry Andric       // ("SubArgDag") if present.
2089e3b55780SDimitry Andric       DagInit *SubArgDag = dyn_cast<DagInit>(OpInit);
2090e3b55780SDimitry Andric       if (SubArgDag)
2091e3b55780SDimitry Andric         OpInit = SubArgDag->getOperator();
2092e3b55780SDimitry Andric       Record *OpTypeRec = cast<DefInit>(OpInit)->getDef();
2093e3b55780SDimitry Andric       // Lookup the sub-operands from the operand type record (note that only
2094e3b55780SDimitry Andric       // Operand subclasses have MIOperandInfo, see CodeGenInstruction.cpp).
2095e3b55780SDimitry Andric       DagInit *SubOps = OpTypeRec->isSubClassOf("Operand")
2096e3b55780SDimitry Andric                             ? OpTypeRec->getValueAsDag("MIOperandInfo")
2097e3b55780SDimitry Andric                             : nullptr;
20981d5ae102SDimitry Andric 
2099ac9a064cSDimitry Andric       // Lookup the decoder method and construct a new OperandInfo to hold our
2100ac9a064cSDimitry Andric       // result.
2101e3b55780SDimitry Andric       OperandInfo OpInfo = getOpInfo(OpTypeRec);
21021d5ae102SDimitry Andric 
2103e3b55780SDimitry Andric       // If we have named sub-operands...
2104e3b55780SDimitry Andric       if (SubArgDag) {
2105e3b55780SDimitry Andric         // Then there should not be a custom decoder specified on the top-level
2106e3b55780SDimitry Andric         // type.
2107e3b55780SDimitry Andric         if (!OpInfo.Decoder.empty()) {
2108e3b55780SDimitry Andric           PrintError(EncodingDef.getLoc(),
2109e3b55780SDimitry Andric                      "DecoderEmitter: operand \"" + OpName + "\" has type \"" +
2110e3b55780SDimitry Andric                          OpInit->getAsString() +
2111e3b55780SDimitry Andric                          "\" with a custom DecoderMethod, but also named "
2112e3b55780SDimitry Andric                          "sub-operands.");
2113e3b55780SDimitry Andric           continue;
2114e3b55780SDimitry Andric         }
211530815c53SDimitry Andric 
2116e3b55780SDimitry Andric         // Decode each of the sub-ops separately.
2117e3b55780SDimitry Andric         assert(SubOps && SubArgDag->getNumArgs() == SubOps->getNumArgs());
2118ac9a064cSDimitry Andric         for (const auto &[I, Arg] : enumerate(SubOps->getArgs())) {
2119ac9a064cSDimitry Andric           StringRef SubOpName = SubArgDag->getArgNameStr(I);
2120ac9a064cSDimitry Andric           OperandInfo SubOpInfo = getOpInfo(cast<DefInit>(Arg)->getDef());
212130815c53SDimitry Andric 
2122e3b55780SDimitry Andric           addOneOperandFields(EncodingDef, Bits, TiedNames, SubOpName,
2123e3b55780SDimitry Andric                               SubOpInfo);
2124e3b55780SDimitry Andric           InsnOperands.push_back(SubOpInfo);
212530815c53SDimitry Andric         }
212630815c53SDimitry Andric         continue;
2127cf099d11SDimitry Andric       }
2128cf099d11SDimitry Andric 
2129e3b55780SDimitry Andric       // Otherwise, if we have an operand with sub-operands, but they aren't
2130e3b55780SDimitry Andric       // named...
2131e3b55780SDimitry Andric       if (SubOps && OpInfo.Decoder.empty()) {
2132e3b55780SDimitry Andric         // If it's a single sub-operand, and no custom decoder, use the decoder
2133e3b55780SDimitry Andric         // from the one sub-operand.
2134e3b55780SDimitry Andric         if (SubOps->getNumArgs() == 1)
2135e3b55780SDimitry Andric           OpInfo = getOpInfo(cast<DefInit>(SubOps->getArg(0))->getDef());
2136e3b55780SDimitry Andric 
2137e3b55780SDimitry Andric         // If we have multiple sub-ops, there'd better have a custom
2138e3b55780SDimitry Andric         // decoder. (Otherwise we don't know how to populate them properly...)
2139e3b55780SDimitry Andric         if (SubOps->getNumArgs() > 1) {
2140e3b55780SDimitry Andric           PrintError(EncodingDef.getLoc(),
2141e3b55780SDimitry Andric                      "DecoderEmitter: operand \"" + OpName +
2142e3b55780SDimitry Andric                          "\" uses MIOperandInfo with multiple ops, but doesn't "
2143e3b55780SDimitry Andric                          "have a custom decoder!");
2144e3b55780SDimitry Andric           debugDumpRecord(EncodingDef);
214530815c53SDimitry Andric           continue;
214630815c53SDimitry Andric         }
214730815c53SDimitry Andric       }
214830815c53SDimitry Andric 
2149e3b55780SDimitry Andric       addOneOperandFields(EncodingDef, Bits, TiedNames, OpName, OpInfo);
2150e3b55780SDimitry Andric       // FIXME: it should be an error not to find a definition for a given
2151e3b55780SDimitry Andric       // operand, rather than just failing to add it to the resulting
2152e3b55780SDimitry Andric       // instruction! (This is a longstanding bug, which will be addressed in an
2153e3b55780SDimitry Andric       // upcoming change.)
215430815c53SDimitry Andric       if (OpInfo.numFields() > 0)
215530815c53SDimitry Andric         InsnOperands.push_back(OpInfo);
2156cf099d11SDimitry Andric     }
2157145449b1SDimitry Andric   }
2158cf099d11SDimitry Andric   Operands[Opc] = InsnOperands;
2159cf099d11SDimitry Andric 
2160cf099d11SDimitry Andric #if 0
2161eb11fae6SDimitry Andric   LLVM_DEBUG({
2162cf099d11SDimitry Andric       // Dumps the instruction encoding bits.
2163cf099d11SDimitry Andric       dumpBits(errs(), Bits);
2164cf099d11SDimitry Andric 
2165cf099d11SDimitry Andric       errs() << '\n';
2166cf099d11SDimitry Andric 
2167cf099d11SDimitry Andric       // Dumps the list of operand info.
2168cf099d11SDimitry Andric       for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) {
2169cf099d11SDimitry Andric         const CGIOperandList::OperandInfo &Info = CGI.Operands[i];
2170cf099d11SDimitry Andric         const std::string &OperandName = Info.Name;
2171cf099d11SDimitry Andric         const Record &OperandDef = *Info.Rec;
2172cf099d11SDimitry Andric 
2173cf099d11SDimitry Andric         errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n";
2174cf099d11SDimitry Andric       }
2175cf099d11SDimitry Andric     });
2176cf099d11SDimitry Andric #endif
2177cf099d11SDimitry Andric 
2178145449b1SDimitry Andric   return Bits.getNumBits();
2179cf099d11SDimitry Andric }
2180cf099d11SDimitry Andric 
2181902a7b52SDimitry Andric // emitFieldFromInstruction - Emit the templated helper function
2182902a7b52SDimitry Andric // fieldFromInstruction().
2183eb11fae6SDimitry Andric // On Windows we make sure that this function is not inlined when
2184eb11fae6SDimitry Andric // using the VS compiler. It has a bug which causes the function
2185e3b55780SDimitry Andric // to be optimized out in some circumstances. See llvm.org/pr38292
emitFieldFromInstruction(formatted_raw_ostream & OS)2186902a7b52SDimitry Andric static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
2187ac9a064cSDimitry Andric   OS << R"(
2188ac9a064cSDimitry Andric // Helper functions for extracting fields from encoded instructions.
2189ac9a064cSDimitry Andric // InsnType must either be integral or an APInt-like object that must:
2190ac9a064cSDimitry Andric // * be default-constructible and copy-constructible
2191ac9a064cSDimitry Andric // * be constructible from an APInt (this can be private)
2192ac9a064cSDimitry Andric // * Support insertBits(bits, startBit, numBits)
2193ac9a064cSDimitry Andric // * Support extractBitsAsZExtValue(numBits, startBit)
2194ac9a064cSDimitry Andric // * Support the ~, &, ==, and != operators with other objects of the same type
2195ac9a064cSDimitry Andric // * Support the != and bitwise & with uint64_t
2196ac9a064cSDimitry Andric // * Support put (<<) to raw_ostream&
2197ac9a064cSDimitry Andric template <typename InsnType>
2198ac9a064cSDimitry Andric #if defined(_MSC_VER) && !defined(__clang__)
2199ac9a064cSDimitry Andric __declspec(noinline)
2200ac9a064cSDimitry Andric #endif
2201ac9a064cSDimitry Andric static std::enable_if_t<std::is_integral<InsnType>::value, InsnType>
2202ac9a064cSDimitry Andric fieldFromInstruction(const InsnType &insn, unsigned startBit,
2203ac9a064cSDimitry Andric                      unsigned numBits) {
2204ac9a064cSDimitry Andric   assert(startBit + numBits <= 64 && "Cannot support >64-bit extractions!");
2205ac9a064cSDimitry Andric   assert(startBit + numBits <= (sizeof(InsnType) * 8) &&
2206ac9a064cSDimitry Andric          "Instruction field out of bounds!");
2207ac9a064cSDimitry Andric   InsnType fieldMask;
2208ac9a064cSDimitry Andric   if (numBits == sizeof(InsnType) * 8)
2209ac9a064cSDimitry Andric     fieldMask = (InsnType)(-1LL);
2210ac9a064cSDimitry Andric   else
2211ac9a064cSDimitry Andric     fieldMask = (((InsnType)1 << numBits) - 1) << startBit;
2212ac9a064cSDimitry Andric   return (insn & fieldMask) >> startBit;
2213ac9a064cSDimitry Andric }
2214ac9a064cSDimitry Andric 
2215ac9a064cSDimitry Andric template <typename InsnType>
2216ac9a064cSDimitry Andric static std::enable_if_t<!std::is_integral<InsnType>::value, uint64_t>
2217ac9a064cSDimitry Andric fieldFromInstruction(const InsnType &insn, unsigned startBit,
2218ac9a064cSDimitry Andric                      unsigned numBits) {
2219ac9a064cSDimitry Andric   return insn.extractBitsAsZExtValue(numBits, startBit);
2220ac9a064cSDimitry Andric }
2221ac9a064cSDimitry Andric )";
2222344a3780SDimitry Andric }
2223344a3780SDimitry Andric 
2224344a3780SDimitry Andric // emitInsertBits - Emit the templated helper function insertBits().
emitInsertBits(formatted_raw_ostream & OS)2225344a3780SDimitry Andric static void emitInsertBits(formatted_raw_ostream &OS) {
2226ac9a064cSDimitry Andric   OS << R"(
2227ac9a064cSDimitry Andric // Helper function for inserting bits extracted from an encoded instruction into
2228ac9a064cSDimitry Andric // a field.
2229ac9a064cSDimitry Andric template <typename InsnType>
2230ac9a064cSDimitry Andric static std::enable_if_t<std::is_integral<InsnType>::value>
2231ac9a064cSDimitry Andric insertBits(InsnType &field, InsnType bits, unsigned startBit, unsigned numBits) {
2232ac9a064cSDimitry Andric   assert(startBit + numBits <= sizeof field * 8);
2233ac9a064cSDimitry Andric   field |= (InsnType)bits << startBit;
2234ac9a064cSDimitry Andric }
2235ac9a064cSDimitry Andric 
2236ac9a064cSDimitry Andric template <typename InsnType>
2237ac9a064cSDimitry Andric static std::enable_if_t<!std::is_integral<InsnType>::value>
2238ac9a064cSDimitry Andric insertBits(InsnType &field, uint64_t bits, unsigned startBit, unsigned numBits) {
2239ac9a064cSDimitry Andric   field.insertBits(bits, startBit, numBits);
2240ac9a064cSDimitry Andric }
2241ac9a064cSDimitry Andric )";
2242902a7b52SDimitry Andric }
2243cf099d11SDimitry Andric 
2244902a7b52SDimitry Andric // emitDecodeInstruction - Emit the templated helper function
2245902a7b52SDimitry Andric // decodeInstruction().
emitDecodeInstruction(formatted_raw_ostream & OS,bool IsVarLenInst)2246145449b1SDimitry Andric static void emitDecodeInstruction(formatted_raw_ostream &OS,
2247145449b1SDimitry Andric                                   bool IsVarLenInst) {
2248ac9a064cSDimitry Andric   OS << R"(
2249ac9a064cSDimitry Andric template <typename InsnType>
2250ac9a064cSDimitry Andric static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2251ac9a064cSDimitry Andric                                       InsnType insn, uint64_t Address,
2252ac9a064cSDimitry Andric                                       const MCDisassembler *DisAsm,
2253ac9a064cSDimitry Andric                                       const MCSubtargetInfo &STI)";
2254145449b1SDimitry Andric   if (IsVarLenInst) {
2255145449b1SDimitry Andric     OS << ",\n                                      "
2256ac9a064cSDimitry Andric           "llvm::function_ref<void(APInt &, uint64_t)> makeUp";
2257145449b1SDimitry Andric   }
2258ac9a064cSDimitry Andric   OS << R"() {
2259ac9a064cSDimitry Andric   const FeatureBitset &Bits = STI.getFeatureBits();
2260ac9a064cSDimitry Andric 
2261ac9a064cSDimitry Andric   const uint8_t *Ptr = DecodeTable;
2262ac9a064cSDimitry Andric   uint64_t CurFieldValue = 0;
2263ac9a064cSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
2264ac9a064cSDimitry Andric   while (true) {
2265ac9a064cSDimitry Andric     ptrdiff_t Loc = Ptr - DecodeTable;
2266ac9a064cSDimitry Andric     switch (*Ptr) {
2267ac9a064cSDimitry Andric     default:
2268ac9a064cSDimitry Andric       errs() << Loc << ": Unexpected decode table opcode!\n";
2269ac9a064cSDimitry Andric       return MCDisassembler::Fail;
2270ac9a064cSDimitry Andric     case MCD::OPC_ExtractField: {
2271ac9a064cSDimitry Andric       // Decode the start value.
2272ac9a064cSDimitry Andric       unsigned Start = decodeULEB128AndIncUnsafe(++Ptr);
2273ac9a064cSDimitry Andric       unsigned Len = *Ptr++;)";
2274145449b1SDimitry Andric   if (IsVarLenInst)
2275ac9a064cSDimitry Andric     OS << "\n      makeUp(insn, Start + Len);";
2276ac9a064cSDimitry Andric   OS << R"(
2277ac9a064cSDimitry Andric       CurFieldValue = fieldFromInstruction(insn, Start, Len);
2278ac9a064cSDimitry Andric       LLVM_DEBUG(dbgs() << Loc << ": OPC_ExtractField(" << Start << ", "
2279ac9a064cSDimitry Andric                    << Len << "): " << CurFieldValue << "\n");
2280ac9a064cSDimitry Andric       break;
2281ac9a064cSDimitry Andric     }
2282ac9a064cSDimitry Andric     case MCD::OPC_FilterValue: {
2283ac9a064cSDimitry Andric       // Decode the field value.
2284ac9a064cSDimitry Andric       uint64_t Val = decodeULEB128AndIncUnsafe(++Ptr);
2285ac9a064cSDimitry Andric       // NumToSkip is a plain 24-bit integer.
2286ac9a064cSDimitry Andric       unsigned NumToSkip = *Ptr++;
2287ac9a064cSDimitry Andric       NumToSkip |= (*Ptr++) << 8;
2288ac9a064cSDimitry Andric       NumToSkip |= (*Ptr++) << 16;
2289ac9a064cSDimitry Andric 
2290ac9a064cSDimitry Andric       // Perform the filter operation.
2291ac9a064cSDimitry Andric       if (Val != CurFieldValue)
2292ac9a064cSDimitry Andric         Ptr += NumToSkip;
2293ac9a064cSDimitry Andric       LLVM_DEBUG(dbgs() << Loc << ": OPC_FilterValue(" << Val << ", " << NumToSkip
2294ac9a064cSDimitry Andric                    << "): " << ((Val != CurFieldValue) ? "FAIL:" : "PASS:")
2295ac9a064cSDimitry Andric                    << " continuing at " << (Ptr - DecodeTable) << "\n");
2296ac9a064cSDimitry Andric 
2297ac9a064cSDimitry Andric       break;
2298ac9a064cSDimitry Andric     }
2299ac9a064cSDimitry Andric     case MCD::OPC_CheckField: {
2300ac9a064cSDimitry Andric       // Decode the start value.
2301ac9a064cSDimitry Andric       unsigned Start = decodeULEB128AndIncUnsafe(++Ptr);
2302ac9a064cSDimitry Andric       unsigned Len = *Ptr;)";
2303145449b1SDimitry Andric   if (IsVarLenInst)
2304ac9a064cSDimitry Andric     OS << "\n      makeUp(insn, Start + Len);";
2305ac9a064cSDimitry Andric   OS << R"(
2306ac9a064cSDimitry Andric       uint64_t FieldValue = fieldFromInstruction(insn, Start, Len);
2307ac9a064cSDimitry Andric       // Decode the field value.
2308ac9a064cSDimitry Andric       unsigned PtrLen = 0;
2309ac9a064cSDimitry Andric       uint64_t ExpectedValue = decodeULEB128(++Ptr, &PtrLen);
2310ac9a064cSDimitry Andric       Ptr += PtrLen;
2311ac9a064cSDimitry Andric       // NumToSkip is a plain 24-bit integer.
2312ac9a064cSDimitry Andric       unsigned NumToSkip = *Ptr++;
2313ac9a064cSDimitry Andric       NumToSkip |= (*Ptr++) << 8;
2314ac9a064cSDimitry Andric       NumToSkip |= (*Ptr++) << 16;
2315ac9a064cSDimitry Andric 
2316ac9a064cSDimitry Andric       // If the actual and expected values don't match, skip.
2317ac9a064cSDimitry Andric       if (ExpectedValue != FieldValue)
2318ac9a064cSDimitry Andric         Ptr += NumToSkip;
2319ac9a064cSDimitry Andric       LLVM_DEBUG(dbgs() << Loc << ": OPC_CheckField(" << Start << ", "
2320ac9a064cSDimitry Andric                    << Len << ", " << ExpectedValue << ", " << NumToSkip
2321ac9a064cSDimitry Andric                    << "): FieldValue = " << FieldValue << ", ExpectedValue = "
2322ac9a064cSDimitry Andric                    << ExpectedValue << ": "
2323ac9a064cSDimitry Andric                    << ((ExpectedValue == FieldValue) ? "PASS\n" : "FAIL\n"));
2324ac9a064cSDimitry Andric       break;
2325ac9a064cSDimitry Andric     }
2326ac9a064cSDimitry Andric     case MCD::OPC_CheckPredicate: {
2327ac9a064cSDimitry Andric       // Decode the Predicate Index value.
2328ac9a064cSDimitry Andric       unsigned PIdx = decodeULEB128AndIncUnsafe(++Ptr);
2329ac9a064cSDimitry Andric       // NumToSkip is a plain 24-bit integer.
2330ac9a064cSDimitry Andric       unsigned NumToSkip = *Ptr++;
2331ac9a064cSDimitry Andric       NumToSkip |= (*Ptr++) << 8;
2332ac9a064cSDimitry Andric       NumToSkip |= (*Ptr++) << 16;
2333ac9a064cSDimitry Andric       // Check the predicate.
2334ac9a064cSDimitry Andric       bool Pred;
2335ac9a064cSDimitry Andric       if (!(Pred = checkDecoderPredicate(PIdx, Bits)))
2336ac9a064cSDimitry Andric         Ptr += NumToSkip;
2337ac9a064cSDimitry Andric       (void)Pred;
2338ac9a064cSDimitry Andric       LLVM_DEBUG(dbgs() << Loc << ": OPC_CheckPredicate(" << PIdx << "): "
2339ac9a064cSDimitry Andric             << (Pred ? "PASS\n" : "FAIL\n"));
2340ac9a064cSDimitry Andric 
2341ac9a064cSDimitry Andric       break;
2342ac9a064cSDimitry Andric     }
2343ac9a064cSDimitry Andric     case MCD::OPC_Decode: {
2344ac9a064cSDimitry Andric       // Decode the Opcode value.
2345ac9a064cSDimitry Andric       unsigned Opc = decodeULEB128AndIncUnsafe(++Ptr);
2346ac9a064cSDimitry Andric       unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
2347ac9a064cSDimitry Andric 
2348ac9a064cSDimitry Andric       MI.clear();
2349ac9a064cSDimitry Andric       MI.setOpcode(Opc);
2350ac9a064cSDimitry Andric       bool DecodeComplete;)";
2351145449b1SDimitry Andric   if (IsVarLenInst) {
2352ac9a064cSDimitry Andric     OS << "\n      unsigned Len = InstrLenTable[Opc];\n"
2353ac9a064cSDimitry Andric        << "      makeUp(insn, Len);";
2354145449b1SDimitry Andric   }
2355ac9a064cSDimitry Andric   OS << R"(
2356ac9a064cSDimitry Andric       S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, DecodeComplete);
2357ac9a064cSDimitry Andric       assert(DecodeComplete);
2358ac9a064cSDimitry Andric 
2359ac9a064cSDimitry Andric       LLVM_DEBUG(dbgs() << Loc << ": OPC_Decode: opcode " << Opc
2360ac9a064cSDimitry Andric                    << ", using decoder " << DecodeIdx << ": "
2361ac9a064cSDimitry Andric                    << (S != MCDisassembler::Fail ? "PASS" : "FAIL") << "\n");
2362ac9a064cSDimitry Andric       return S;
2363ac9a064cSDimitry Andric     }
2364ac9a064cSDimitry Andric     case MCD::OPC_TryDecode: {
2365ac9a064cSDimitry Andric       // Decode the Opcode value.
2366ac9a064cSDimitry Andric       unsigned Opc = decodeULEB128AndIncUnsafe(++Ptr);
2367ac9a064cSDimitry Andric       unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
2368ac9a064cSDimitry Andric       // NumToSkip is a plain 24-bit integer.
2369ac9a064cSDimitry Andric       unsigned NumToSkip = *Ptr++;
2370ac9a064cSDimitry Andric       NumToSkip |= (*Ptr++) << 8;
2371ac9a064cSDimitry Andric       NumToSkip |= (*Ptr++) << 16;
2372ac9a064cSDimitry Andric 
2373ac9a064cSDimitry Andric       // Perform the decode operation.
2374ac9a064cSDimitry Andric       MCInst TmpMI;
2375ac9a064cSDimitry Andric       TmpMI.setOpcode(Opc);
2376ac9a064cSDimitry Andric       bool DecodeComplete;
2377ac9a064cSDimitry Andric       S = decodeToMCInst(S, DecodeIdx, insn, TmpMI, Address, DisAsm, DecodeComplete);
2378ac9a064cSDimitry Andric       LLVM_DEBUG(dbgs() << Loc << ": OPC_TryDecode: opcode " << Opc
2379ac9a064cSDimitry Andric                    << ", using decoder " << DecodeIdx << ": ");
2380ac9a064cSDimitry Andric 
2381ac9a064cSDimitry Andric       if (DecodeComplete) {
2382ac9a064cSDimitry Andric         // Decoding complete.
2383ac9a064cSDimitry Andric         LLVM_DEBUG(dbgs() << (S != MCDisassembler::Fail ? "PASS" : "FAIL") << "\n");
2384ac9a064cSDimitry Andric         MI = TmpMI;
2385ac9a064cSDimitry Andric         return S;
2386ac9a064cSDimitry Andric       } else {
2387ac9a064cSDimitry Andric         assert(S == MCDisassembler::Fail);
2388ac9a064cSDimitry Andric         // If the decoding was incomplete, skip.
2389ac9a064cSDimitry Andric         Ptr += NumToSkip;
2390ac9a064cSDimitry Andric         LLVM_DEBUG(dbgs() << "FAIL: continuing at " << (Ptr - DecodeTable) << "\n");
2391ac9a064cSDimitry Andric         // Reset decode status. This also drops a SoftFail status that could be
2392ac9a064cSDimitry Andric         // set before the decode attempt.
2393ac9a064cSDimitry Andric         S = MCDisassembler::Success;
2394ac9a064cSDimitry Andric       }
2395ac9a064cSDimitry Andric       break;
2396ac9a064cSDimitry Andric     }
2397ac9a064cSDimitry Andric     case MCD::OPC_SoftFail: {
2398ac9a064cSDimitry Andric       // Decode the mask values.
2399ac9a064cSDimitry Andric       uint64_t PositiveMask = decodeULEB128AndIncUnsafe(++Ptr);
2400ac9a064cSDimitry Andric       uint64_t NegativeMask = decodeULEB128AndIncUnsafe(Ptr);
2401ac9a064cSDimitry Andric       bool Fail = (insn & PositiveMask) != 0 || (~insn & NegativeMask) != 0;
2402ac9a064cSDimitry Andric       if (Fail)
2403ac9a064cSDimitry Andric         S = MCDisassembler::SoftFail;
2404ac9a064cSDimitry Andric       LLVM_DEBUG(dbgs() << Loc << ": OPC_SoftFail: " << (Fail ? "FAIL\n" : "PASS\n"));
2405ac9a064cSDimitry Andric       break;
2406ac9a064cSDimitry Andric     }
2407ac9a064cSDimitry Andric     case MCD::OPC_Fail: {
2408ac9a064cSDimitry Andric       LLVM_DEBUG(dbgs() << Loc << ": OPC_Fail\n");
2409ac9a064cSDimitry Andric       return MCDisassembler::Fail;
2410ac9a064cSDimitry Andric     }
2411ac9a064cSDimitry Andric     }
2412ac9a064cSDimitry Andric   }
2413ac9a064cSDimitry Andric   llvm_unreachable("bogosity detected in disassembler state machine!");
2414ac9a064cSDimitry Andric }
2415ac9a064cSDimitry Andric 
2416ac9a064cSDimitry Andric )";
2417cf099d11SDimitry Andric }
2418cf099d11SDimitry Andric 
2419e3b55780SDimitry Andric // Helper to propagate SoftFail status. Returns false if the status is Fail;
2420e3b55780SDimitry Andric // callers are expected to early-exit in that condition. (Note, the '&' operator
2421e3b55780SDimitry Andric // is correct to propagate the values of this enum; see comment on 'enum
2422e3b55780SDimitry Andric // DecodeStatus'.)
emitCheck(formatted_raw_ostream & OS)2423e3b55780SDimitry Andric static void emitCheck(formatted_raw_ostream &OS) {
2424ac9a064cSDimitry Andric   OS << R"(
2425ac9a064cSDimitry Andric static bool Check(DecodeStatus &Out, DecodeStatus In) {
2426ac9a064cSDimitry Andric   Out = static_cast<DecodeStatus>(Out & In);
2427ac9a064cSDimitry Andric   return Out != MCDisassembler::Fail;
2428ac9a064cSDimitry Andric }
2429ac9a064cSDimitry Andric 
2430ac9a064cSDimitry Andric )";
2431ac9a064cSDimitry Andric }
2432ac9a064cSDimitry Andric 
2433ac9a064cSDimitry Andric // Collect all HwModes referenced by the target for encoding purposes,
2434ac9a064cSDimitry Andric // returning a vector of corresponding names.
collectHwModesReferencedForEncodings(const CodeGenHwModes & HWM,std::vector<StringRef> & Names,NamespacesHwModesMap & NamespacesWithHwModes)2435ac9a064cSDimitry Andric static void collectHwModesReferencedForEncodings(
2436ac9a064cSDimitry Andric     const CodeGenHwModes &HWM, std::vector<StringRef> &Names,
2437ac9a064cSDimitry Andric     NamespacesHwModesMap &NamespacesWithHwModes) {
2438ac9a064cSDimitry Andric   SmallBitVector BV(HWM.getNumModeIds());
2439ac9a064cSDimitry Andric   for (const auto &MS : HWM.getHwModeSelects()) {
2440ac9a064cSDimitry Andric     for (const HwModeSelect::PairType &P : MS.second.Items) {
2441ac9a064cSDimitry Andric       if (P.second->isSubClassOf("InstructionEncoding")) {
2442ac9a064cSDimitry Andric         std::string DecoderNamespace =
2443ac9a064cSDimitry Andric             std::string(P.second->getValueAsString("DecoderNamespace"));
2444ac9a064cSDimitry Andric         if (P.first == DefaultMode) {
2445ac9a064cSDimitry Andric           NamespacesWithHwModes[DecoderNamespace].insert("");
2446ac9a064cSDimitry Andric         } else {
2447ac9a064cSDimitry Andric           NamespacesWithHwModes[DecoderNamespace].insert(
2448ac9a064cSDimitry Andric               HWM.getMode(P.first).Name);
2449ac9a064cSDimitry Andric         }
2450ac9a064cSDimitry Andric         BV.set(P.first);
2451ac9a064cSDimitry Andric       }
2452ac9a064cSDimitry Andric     }
2453ac9a064cSDimitry Andric   }
2454ac9a064cSDimitry Andric   transform(BV.set_bits(), std::back_inserter(Names), [&HWM](const int &M) {
2455ac9a064cSDimitry Andric     if (M == DefaultMode)
2456ac9a064cSDimitry Andric       return StringRef("");
2457ac9a064cSDimitry Andric     return HWM.getModeName(M, /*IncludeDefault=*/true);
2458ac9a064cSDimitry Andric   });
2459ac9a064cSDimitry Andric }
2460ac9a064cSDimitry Andric 
2461ac9a064cSDimitry Andric static void
handleHwModesUnrelatedEncodings(const CodeGenInstruction * Instr,const std::vector<StringRef> & HwModeNames,NamespacesHwModesMap & NamespacesWithHwModes,std::vector<EncodingAndInst> & GlobalEncodings)2462ac9a064cSDimitry Andric handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
2463ac9a064cSDimitry Andric                                 const std::vector<StringRef> &HwModeNames,
2464ac9a064cSDimitry Andric                                 NamespacesHwModesMap &NamespacesWithHwModes,
2465ac9a064cSDimitry Andric                                 std::vector<EncodingAndInst> &GlobalEncodings) {
2466ac9a064cSDimitry Andric   const Record *InstDef = Instr->TheDef;
2467ac9a064cSDimitry Andric 
2468ac9a064cSDimitry Andric   switch (DecoderEmitterSuppressDuplicates) {
2469ac9a064cSDimitry Andric   case SUPPRESSION_DISABLE: {
2470ac9a064cSDimitry Andric     for (StringRef HwModeName : HwModeNames)
2471ac9a064cSDimitry Andric       GlobalEncodings.emplace_back(InstDef, Instr, HwModeName);
2472ac9a064cSDimitry Andric     break;
2473ac9a064cSDimitry Andric   }
2474ac9a064cSDimitry Andric   case SUPPRESSION_LEVEL1: {
2475ac9a064cSDimitry Andric     std::string DecoderNamespace =
2476ac9a064cSDimitry Andric         std::string(InstDef->getValueAsString("DecoderNamespace"));
2477ac9a064cSDimitry Andric     auto It = NamespacesWithHwModes.find(DecoderNamespace);
2478ac9a064cSDimitry Andric     if (It != NamespacesWithHwModes.end()) {
2479ac9a064cSDimitry Andric       for (StringRef HwModeName : It->second)
2480ac9a064cSDimitry Andric         GlobalEncodings.emplace_back(InstDef, Instr, HwModeName);
2481ac9a064cSDimitry Andric     } else {
2482ac9a064cSDimitry Andric       // Only emit the encoding once, as it's DecoderNamespace doesn't
2483ac9a064cSDimitry Andric       // contain any HwModes.
2484ac9a064cSDimitry Andric       GlobalEncodings.emplace_back(InstDef, Instr, "");
2485ac9a064cSDimitry Andric     }
2486ac9a064cSDimitry Andric     break;
2487ac9a064cSDimitry Andric   }
2488ac9a064cSDimitry Andric   case SUPPRESSION_LEVEL2:
2489ac9a064cSDimitry Andric     GlobalEncodings.emplace_back(InstDef, Instr, "");
2490ac9a064cSDimitry Andric     break;
2491ac9a064cSDimitry Andric   }
2492e3b55780SDimitry Andric }
2493e3b55780SDimitry Andric 
2494cf099d11SDimitry Andric // Emits disassembler code for instruction decoding.
run(raw_ostream & o)2495145449b1SDimitry Andric void DecoderEmitter::run(raw_ostream &o) {
2496902a7b52SDimitry Andric   formatted_raw_ostream OS(o);
2497ac9a064cSDimitry Andric   OS << R"(
2498ac9a064cSDimitry Andric #include "llvm/MC/MCInst.h"
2499ac9a064cSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
2500ac9a064cSDimitry Andric #include "llvm/Support/DataTypes.h"
2501ac9a064cSDimitry Andric #include "llvm/Support/Debug.h"
2502ac9a064cSDimitry Andric #include "llvm/Support/LEB128.h"
2503ac9a064cSDimitry Andric #include "llvm/Support/raw_ostream.h"
2504ac9a064cSDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
2505ac9a064cSDimitry Andric #include <assert.h>
2506ac9a064cSDimitry Andric 
2507ac9a064cSDimitry Andric namespace llvm {
2508ac9a064cSDimitry Andric )";
2509902a7b52SDimitry Andric 
2510902a7b52SDimitry Andric   emitFieldFromInstruction(OS);
2511344a3780SDimitry Andric   emitInsertBits(OS);
2512e3b55780SDimitry Andric   emitCheck(OS);
2513cf099d11SDimitry Andric 
25145ca98fd9SDimitry Andric   Target.reverseBitsForLittleEndianEncoding();
25155ca98fd9SDimitry Andric 
251630815c53SDimitry Andric   // Parameterize the decoders based on namespace and instruction width.
2517ac9a064cSDimitry Andric 
2518ac9a064cSDimitry Andric   // First, collect all encoding-related HwModes referenced by the target.
2519ac9a064cSDimitry Andric   // And establish a mapping table between DecoderNamespace and HwMode.
2520ac9a064cSDimitry Andric   // If HwModeNames is empty, add the empty string so we always have one HwMode.
2521ac9a064cSDimitry Andric   const CodeGenHwModes &HWM = Target.getHwModes();
2522ac9a064cSDimitry Andric   std::vector<StringRef> HwModeNames;
2523ac9a064cSDimitry Andric   NamespacesHwModesMap NamespacesWithHwModes;
2524ac9a064cSDimitry Andric   collectHwModesReferencedForEncodings(HWM, HwModeNames, NamespacesWithHwModes);
2525ac9a064cSDimitry Andric   if (HwModeNames.empty())
2526ac9a064cSDimitry Andric     HwModeNames.push_back("");
2527ac9a064cSDimitry Andric 
2528d8e91e46SDimitry Andric   const auto &NumberedInstructions = Target.getInstructionsByEnumValue();
2529d8e91e46SDimitry Andric   NumberedEncodings.reserve(NumberedInstructions.size());
2530e6d15924SDimitry Andric   for (const auto &NumberedInstruction : NumberedInstructions) {
2531ac9a064cSDimitry Andric     const Record *InstDef = NumberedInstruction->TheDef;
2532ac9a064cSDimitry Andric     if (const RecordVal *RV = InstDef->getValue("EncodingInfos")) {
25331d5ae102SDimitry Andric       if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
25341d5ae102SDimitry Andric         EncodingInfoByHwMode EBM(DI->getDef(), HWM);
2535ac9a064cSDimitry Andric         for (auto &[ModeId, Encoding] : EBM) {
2536ac9a064cSDimitry Andric           // DecoderTables with DefaultMode should not have any suffix.
2537ac9a064cSDimitry Andric           if (ModeId == DefaultMode) {
2538ac9a064cSDimitry Andric             NumberedEncodings.emplace_back(Encoding, NumberedInstruction, "");
2539ac9a064cSDimitry Andric           } else {
2540ac9a064cSDimitry Andric             NumberedEncodings.emplace_back(Encoding, NumberedInstruction,
2541ac9a064cSDimitry Andric                                            HWM.getMode(ModeId).Name);
2542ac9a064cSDimitry Andric           }
25431d5ae102SDimitry Andric         }
25441d5ae102SDimitry Andric         continue;
25451d5ae102SDimitry Andric       }
25461d5ae102SDimitry Andric     }
2547ac9a064cSDimitry Andric     // This instruction is encoded the same on all HwModes.
2548ac9a064cSDimitry Andric     // According to user needs, provide varying degrees of suppression.
2549ac9a064cSDimitry Andric     handleHwModesUnrelatedEncodings(NumberedInstruction, HwModeNames,
2550ac9a064cSDimitry Andric                                     NamespacesWithHwModes, NumberedEncodings);
2551e6d15924SDimitry Andric   }
2552ac9a064cSDimitry Andric   for (const auto &NumberedAlias :
2553ac9a064cSDimitry Andric        RK.getAllDerivedDefinitions("AdditionalEncoding"))
2554e6d15924SDimitry Andric     NumberedEncodings.emplace_back(
2555e6d15924SDimitry Andric         NumberedAlias,
2556e6d15924SDimitry Andric         &Target.getInstruction(NumberedAlias->getValueAsDef("AliasOf")));
2557d8e91e46SDimitry Andric 
2558e6d15924SDimitry Andric   std::map<std::pair<std::string, unsigned>, std::vector<EncodingIDAndOpcode>>
2559e6d15924SDimitry Andric       OpcMap;
256030815c53SDimitry Andric   std::map<unsigned, std::vector<OperandInfo>> Operands;
2561145449b1SDimitry Andric   std::vector<unsigned> InstrLen;
2562ac9a064cSDimitry Andric   bool IsVarLenInst = Target.hasVariableLengthEncodings();
2563145449b1SDimitry Andric   unsigned MaxInstLen = 0;
256430815c53SDimitry Andric 
2565ac9a064cSDimitry Andric   for (const auto &[NEI, NumberedEncoding] : enumerate(NumberedEncodings)) {
2566ac9a064cSDimitry Andric     const Record *EncodingDef = NumberedEncoding.EncodingDef;
2567ac9a064cSDimitry Andric     const CodeGenInstruction *Inst = NumberedEncoding.Inst;
256863faed5bSDimitry Andric     const Record *Def = Inst->TheDef;
2569e6d15924SDimitry Andric     unsigned Size = EncodingDef->getValueAsInt("Size");
257030815c53SDimitry Andric     if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
257130815c53SDimitry Andric         Def->getValueAsBit("isPseudo") ||
257230815c53SDimitry Andric         Def->getValueAsBit("isAsmParserOnly") ||
2573e6d15924SDimitry Andric         Def->getValueAsBit("isCodeGenOnly")) {
2574e6d15924SDimitry Andric       NumEncodingsLackingDisasm++;
257530815c53SDimitry Andric       continue;
2576e6d15924SDimitry Andric     }
257730815c53SDimitry Andric 
2578ac9a064cSDimitry Andric     if (NEI < NumberedInstructions.size())
2579e6d15924SDimitry Andric       NumInstructions++;
2580e6d15924SDimitry Andric     NumEncodings++;
2581e6d15924SDimitry Andric 
2582145449b1SDimitry Andric     if (!Size && !IsVarLenInst)
25831d5ae102SDimitry Andric       continue;
258430815c53SDimitry Andric 
2585145449b1SDimitry Andric     if (IsVarLenInst)
2586145449b1SDimitry Andric       InstrLen.resize(NumberedInstructions.size(), 0);
2587145449b1SDimitry Andric 
2588ac9a064cSDimitry Andric     if (unsigned Len = populateInstruction(Target, *EncodingDef, *Inst, NEI,
2589145449b1SDimitry Andric                                            Operands, IsVarLenInst)) {
2590145449b1SDimitry Andric       if (IsVarLenInst) {
2591145449b1SDimitry Andric         MaxInstLen = std::max(MaxInstLen, Len);
2592ac9a064cSDimitry Andric         InstrLen[NEI] = Len;
2593145449b1SDimitry Andric       }
25941d5ae102SDimitry Andric       std::string DecoderNamespace =
2595cfca06d7SDimitry Andric           std::string(EncodingDef->getValueAsString("DecoderNamespace"));
2596ac9a064cSDimitry Andric       if (!NumberedEncoding.HwModeName.empty())
25971d5ae102SDimitry Andric         DecoderNamespace +=
2598ac9a064cSDimitry Andric             std::string("_") + NumberedEncoding.HwModeName.str();
2599ac9a064cSDimitry Andric       OpcMap[std::pair(DecoderNamespace, Size)].emplace_back(
2600ac9a064cSDimitry Andric           NEI, Target.getInstrIntValue(Def));
26011d5ae102SDimitry Andric     } else {
2602e6d15924SDimitry Andric       NumEncodingsOmitted++;
260330815c53SDimitry Andric     }
260430815c53SDimitry Andric   }
260530815c53SDimitry Andric 
2606902a7b52SDimitry Andric   DecoderTableInfo TableInfo;
260767c32a98SDimitry Andric   for (const auto &Opc : OpcMap) {
260830815c53SDimitry Andric     // Emit the decoder for this namespace+width combination.
2609ac9a064cSDimitry Andric     ArrayRef<EncodingAndInst> NumberedEncodingsRef(NumberedEncodings.data(),
2610ac9a064cSDimitry Andric                                                    NumberedEncodings.size());
2611d8e91e46SDimitry Andric     FilterChooser FC(NumberedEncodingsRef, Opc.second, Operands,
2612145449b1SDimitry Andric                      IsVarLenInst ? MaxInstLen : 8 * Opc.first.second, this);
2613902a7b52SDimitry Andric 
2614902a7b52SDimitry Andric     // The decode table is cleared for each top level decoder function. The
2615902a7b52SDimitry Andric     // predicates and decoders themselves, however, are shared across all
2616902a7b52SDimitry Andric     // decoders to give more opportunities for uniqueing.
2617902a7b52SDimitry Andric     TableInfo.Table.clear();
2618902a7b52SDimitry Andric     TableInfo.FixupStack.clear();
2619902a7b52SDimitry Andric     TableInfo.Table.reserve(16384);
262085d8b2bbSDimitry Andric     TableInfo.FixupStack.emplace_back();
2621902a7b52SDimitry Andric     FC.emitTableEntries(TableInfo);
2622902a7b52SDimitry Andric     // Any NumToSkip fixups in the top level scope can resolve to the
2623902a7b52SDimitry Andric     // OPC_Fail at the end of the table.
2624902a7b52SDimitry Andric     assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!");
2625902a7b52SDimitry Andric     // Resolve any NumToSkip fixups in the current scope.
2626902a7b52SDimitry Andric     resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
2627902a7b52SDimitry Andric                        TableInfo.Table.size());
2628902a7b52SDimitry Andric     TableInfo.FixupStack.clear();
2629902a7b52SDimitry Andric 
2630902a7b52SDimitry Andric     TableInfo.Table.push_back(MCD::OPC_Fail);
2631902a7b52SDimitry Andric 
2632902a7b52SDimitry Andric     // Print the table to the output stream.
2633ac9a064cSDimitry Andric     emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), Opc.first.first,
2634ac9a064cSDimitry Andric               Opc.second);
263530815c53SDimitry Andric   }
2636cf099d11SDimitry Andric 
2637145449b1SDimitry Andric   // For variable instruction, we emit a instruction length table
2638145449b1SDimitry Andric   // to let the decoder know how long the instructions are.
2639145449b1SDimitry Andric   // You can see example usage in M68k's disassembler.
2640145449b1SDimitry Andric   if (IsVarLenInst)
2641145449b1SDimitry Andric     emitInstrLenTable(OS, InstrLen);
2642902a7b52SDimitry Andric   // Emit the predicate function.
2643902a7b52SDimitry Andric   emitPredicateFunction(OS, TableInfo.Predicates, 0);
2644902a7b52SDimitry Andric 
2645902a7b52SDimitry Andric   // Emit the decoder function.
2646902a7b52SDimitry Andric   emitDecoderFunction(OS, TableInfo.Decoders, 0);
2647902a7b52SDimitry Andric 
2648902a7b52SDimitry Andric   // Emit the main entry point for the decoder, decodeInstruction().
2649145449b1SDimitry Andric   emitDecodeInstruction(OS, IsVarLenInst);
2650902a7b52SDimitry Andric 
26511d5ae102SDimitry Andric   OS << "\n} // end namespace llvm\n";
2652cf099d11SDimitry Andric }
265358b69754SDimitry Andric 
265458b69754SDimitry Andric namespace llvm {
265558b69754SDimitry Andric 
EmitDecoder(RecordKeeper & RK,raw_ostream & OS,const std::string & PredicateNamespace)2656145449b1SDimitry Andric void EmitDecoder(RecordKeeper &RK, raw_ostream &OS,
2657e3b55780SDimitry Andric                  const std::string &PredicateNamespace) {
2658e3b55780SDimitry Andric   DecoderEmitter(RK, PredicateNamespace).run(OS);
265958b69754SDimitry Andric }
266058b69754SDimitry Andric 
2661b915e9e0SDimitry Andric } // end namespace llvm
2662