xref: /llvm-project/llvm/utils/TableGen/DecoderEmitter.cpp (revision 4e8c9d28132039a98feb97cec2759cddeb37d934)
1df3765bfSSheng //===---------------- DecoderEmitter.cpp - Decoder Generator --------------===//
2df3765bfSSheng //
3df3765bfSSheng // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4df3765bfSSheng // See https://llvm.org/LICENSE.txt for license information.
5df3765bfSSheng // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6df3765bfSSheng //
7df3765bfSSheng //===----------------------------------------------------------------------===//
8df3765bfSSheng //
9df3765bfSSheng // It contains the tablegen backend that emits the decoder functions for
10df3765bfSSheng // targets with fixed/variable length instruction set.
11df3765bfSSheng //
12df3765bfSSheng //===----------------------------------------------------------------------===//
13df3765bfSSheng 
14fa3d789dSPierre van Houtryve #include "Common/CodeGenHwModes.h"
15fa3d789dSPierre van Houtryve #include "Common/CodeGenInstruction.h"
16fa3d789dSPierre van Houtryve #include "Common/CodeGenTarget.h"
17fa3d789dSPierre van Houtryve #include "Common/InfoByHwMode.h"
18fa3d789dSPierre van Houtryve #include "Common/VarLenCodeEmitterGen.h"
19f35064dbSNAKAMURA Takumi #include "TableGenBackends.h"
20df3765bfSSheng #include "llvm/ADT/APInt.h"
21df3765bfSSheng #include "llvm/ADT/ArrayRef.h"
22df3765bfSSheng #include "llvm/ADT/CachedHashString.h"
23df3765bfSSheng #include "llvm/ADT/STLExtras.h"
24df3765bfSSheng #include "llvm/ADT/SetVector.h"
25f75c6ed9SJason Eckhardt #include "llvm/ADT/SmallBitVector.h"
26df3765bfSSheng #include "llvm/ADT/SmallString.h"
27df3765bfSSheng #include "llvm/ADT/Statistic.h"
28df3765bfSSheng #include "llvm/ADT/StringExtras.h"
29df3765bfSSheng #include "llvm/ADT/StringRef.h"
30c644488aSSheng #include "llvm/MC/MCDecoderOps.h"
31df3765bfSSheng #include "llvm/Support/Casting.h"
3205af9c83SJason Eckhardt #include "llvm/Support/CommandLine.h"
33df3765bfSSheng #include "llvm/Support/Debug.h"
34df3765bfSSheng #include "llvm/Support/ErrorHandling.h"
35df3765bfSSheng #include "llvm/Support/FormattedStream.h"
36df3765bfSSheng #include "llvm/Support/LEB128.h"
37df3765bfSSheng #include "llvm/Support/raw_ostream.h"
38df3765bfSSheng #include "llvm/TableGen/Error.h"
39df3765bfSSheng #include "llvm/TableGen/Record.h"
40df3765bfSSheng #include <algorithm>
41df3765bfSSheng #include <cassert>
42df3765bfSSheng #include <cstddef>
43df3765bfSSheng #include <cstdint>
44df3765bfSSheng #include <map>
45df3765bfSSheng #include <memory>
46df3765bfSSheng #include <set>
47df3765bfSSheng #include <string>
48df3765bfSSheng #include <utility>
49df3765bfSSheng #include <vector>
50df3765bfSSheng 
51df3765bfSSheng using namespace llvm;
52df3765bfSSheng 
53df3765bfSSheng #define DEBUG_TYPE "decoder-emitter"
54df3765bfSSheng 
5505af9c83SJason Eckhardt extern cl::OptionCategory DisassemblerEmitterCat;
5605af9c83SJason Eckhardt 
57da1d3d8fSsuperZWT123 enum SuppressLevel {
58da1d3d8fSsuperZWT123   SUPPRESSION_DISABLE,
59da1d3d8fSsuperZWT123   SUPPRESSION_LEVEL1,
60da1d3d8fSsuperZWT123   SUPPRESSION_LEVEL2
61da1d3d8fSsuperZWT123 };
62da1d3d8fSsuperZWT123 
63da1d3d8fSsuperZWT123 cl::opt<SuppressLevel> DecoderEmitterSuppressDuplicates(
6405af9c83SJason Eckhardt     "suppress-per-hwmode-duplicates",
6505af9c83SJason Eckhardt     cl::desc("Suppress duplication of instrs into per-HwMode decoder tables"),
66da1d3d8fSsuperZWT123     cl::values(
67da1d3d8fSsuperZWT123         clEnumValN(
68da1d3d8fSsuperZWT123             SUPPRESSION_DISABLE, "O0",
69da1d3d8fSsuperZWT123             "Do not prevent DecoderTable duplications caused by HwModes"),
70da1d3d8fSsuperZWT123         clEnumValN(
71da1d3d8fSsuperZWT123             SUPPRESSION_LEVEL1, "O1",
72da1d3d8fSsuperZWT123             "Remove duplicate DecoderTable entries generated due to HwModes"),
73da1d3d8fSsuperZWT123         clEnumValN(
74da1d3d8fSsuperZWT123             SUPPRESSION_LEVEL2, "O2",
75da1d3d8fSsuperZWT123             "Extract HwModes-specific instructions into new DecoderTables, "
76da1d3d8fSsuperZWT123             "significantly reducing Table Duplications")),
77da1d3d8fSsuperZWT123     cl::init(SUPPRESSION_DISABLE), cl::cat(DisassemblerEmitterCat));
7805af9c83SJason Eckhardt 
79df3765bfSSheng namespace {
80df3765bfSSheng 
81df3765bfSSheng STATISTIC(NumEncodings, "Number of encodings considered");
82b9079baaSPierre van Houtryve STATISTIC(NumEncodingsLackingDisasm,
83b9079baaSPierre van Houtryve           "Number of encodings without disassembler info");
84df3765bfSSheng STATISTIC(NumInstructions, "Number of instructions considered");
85df3765bfSSheng STATISTIC(NumEncodingsSupported, "Number of encodings supported");
86df3765bfSSheng STATISTIC(NumEncodingsOmitted, "Number of encodings omitted");
87df3765bfSSheng 
88df3765bfSSheng struct EncodingField {
89df3765bfSSheng   unsigned Base, Width, Offset;
90df3765bfSSheng   EncodingField(unsigned B, unsigned W, unsigned O)
91df3765bfSSheng       : Base(B), Width(W), Offset(O) {}
92df3765bfSSheng };
93df3765bfSSheng 
94df3765bfSSheng struct OperandInfo {
95df3765bfSSheng   std::vector<EncodingField> Fields;
96df3765bfSSheng   std::string Decoder;
97df3765bfSSheng   bool HasCompleteDecoder;
98df3765bfSSheng   uint64_t InitValue;
99df3765bfSSheng 
100df3765bfSSheng   OperandInfo(std::string D, bool HCD)
101df3765bfSSheng       : Decoder(std::move(D)), HasCompleteDecoder(HCD), InitValue(0) {}
102df3765bfSSheng 
103df3765bfSSheng   void addField(unsigned Base, unsigned Width, unsigned Offset) {
104df3765bfSSheng     Fields.push_back(EncodingField(Base, Width, Offset));
105df3765bfSSheng   }
106df3765bfSSheng 
107df3765bfSSheng   unsigned numFields() const { return Fields.size(); }
108df3765bfSSheng 
109df3765bfSSheng   typedef std::vector<EncodingField>::const_iterator const_iterator;
110df3765bfSSheng 
111df3765bfSSheng   const_iterator begin() const { return Fields.begin(); }
112df3765bfSSheng   const_iterator end() const { return Fields.end(); }
113df3765bfSSheng };
114df3765bfSSheng 
115df3765bfSSheng typedef std::vector<uint8_t> DecoderTable;
116df3765bfSSheng typedef uint32_t DecoderFixup;
117df3765bfSSheng typedef std::vector<DecoderFixup> FixupList;
118df3765bfSSheng typedef std::vector<FixupList> FixupScopeList;
119df3765bfSSheng typedef SmallSetVector<CachedHashString, 16> PredicateSet;
120df3765bfSSheng typedef SmallSetVector<CachedHashString, 16> DecoderSet;
121df3765bfSSheng struct DecoderTableInfo {
122df3765bfSSheng   DecoderTable Table;
123df3765bfSSheng   FixupScopeList FixupStack;
124df3765bfSSheng   PredicateSet Predicates;
125df3765bfSSheng   DecoderSet Decoders;
126df3765bfSSheng };
127df3765bfSSheng 
128df3765bfSSheng struct EncodingAndInst {
129df3765bfSSheng   const Record *EncodingDef;
130df3765bfSSheng   const CodeGenInstruction *Inst;
131df3765bfSSheng   StringRef HwModeName;
132df3765bfSSheng 
133df3765bfSSheng   EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst,
134df3765bfSSheng                   StringRef HwModeName = "")
135df3765bfSSheng       : EncodingDef(EncodingDef), Inst(Inst), HwModeName(HwModeName) {}
136df3765bfSSheng };
137df3765bfSSheng 
138df3765bfSSheng struct EncodingIDAndOpcode {
139df3765bfSSheng   unsigned EncodingID;
140df3765bfSSheng   unsigned Opcode;
141df3765bfSSheng 
142df3765bfSSheng   EncodingIDAndOpcode() : EncodingID(0), Opcode(0) {}
143df3765bfSSheng   EncodingIDAndOpcode(unsigned EncodingID, unsigned Opcode)
144df3765bfSSheng       : EncodingID(EncodingID), Opcode(Opcode) {}
145df3765bfSSheng };
146df3765bfSSheng 
1472ed0aacfSJason Eckhardt using EncodingIDsVec = std::vector<EncodingIDAndOpcode>;
148da1d3d8fSsuperZWT123 using NamespacesHwModesMap = std::map<std::string, std::set<StringRef>>;
1492ed0aacfSJason Eckhardt 
150df3765bfSSheng raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {
151df3765bfSSheng   if (Value.EncodingDef != Value.Inst->TheDef)
152df3765bfSSheng     OS << Value.EncodingDef->getName() << ":";
153df3765bfSSheng   OS << Value.Inst->TheDef->getName();
154df3765bfSSheng   return OS;
155df3765bfSSheng }
156df3765bfSSheng 
157df3765bfSSheng class DecoderEmitter {
1582bb3621fSRahul Joshi   const RecordKeeper &RK;
159df3765bfSSheng   std::vector<EncodingAndInst> NumberedEncodings;
160df3765bfSSheng 
161df3765bfSSheng public:
162b594b930SRahul Joshi   DecoderEmitter(const RecordKeeper &R, StringRef PredicateNamespace)
1632bb3621fSRahul Joshi       : RK(R), Target(R), PredicateNamespace(PredicateNamespace) {}
164df3765bfSSheng 
165df3765bfSSheng   // Emit the decoder state machine table.
166708567abSRahul Joshi   void emitTable(formatted_raw_ostream &OS, DecoderTable &Table, indent Indent,
167708567abSRahul Joshi                  unsigned BitWidth, StringRef Namespace,
1682ed0aacfSJason Eckhardt                  const EncodingIDsVec &EncodingIDs) const;
169df3765bfSSheng   void emitInstrLenTable(formatted_raw_ostream &OS,
170df3765bfSSheng                          std::vector<unsigned> &InstrLen) const;
171df3765bfSSheng   void emitPredicateFunction(formatted_raw_ostream &OS,
172708567abSRahul Joshi                              PredicateSet &Predicates, indent Indent) const;
173b9079baaSPierre van Houtryve   void emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
174708567abSRahul Joshi                            indent Indent) const;
175df3765bfSSheng 
176df3765bfSSheng   // run - Output the code emitter
177df3765bfSSheng   void run(raw_ostream &o);
178df3765bfSSheng 
179df3765bfSSheng private:
180df3765bfSSheng   CodeGenTarget Target;
181df3765bfSSheng 
182df3765bfSSheng public:
183b594b930SRahul Joshi   StringRef PredicateNamespace;
184df3765bfSSheng };
185df3765bfSSheng 
186df3765bfSSheng } // end anonymous namespace
187df3765bfSSheng 
188df3765bfSSheng // The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system
189df3765bfSSheng // for a bit value.
190df3765bfSSheng //
191df3765bfSSheng // BIT_UNFILTERED is used as the init value for a filter position.  It is used
192df3765bfSSheng // only for filter processings.
193df3765bfSSheng typedef enum {
194df3765bfSSheng   BIT_TRUE,      // '1'
195df3765bfSSheng   BIT_FALSE,     // '0'
196df3765bfSSheng   BIT_UNSET,     // '?'
197df3765bfSSheng   BIT_UNFILTERED // unfiltered
198df3765bfSSheng } bit_value_t;
199df3765bfSSheng 
200df3765bfSSheng static bool ValueSet(bit_value_t V) {
201df3765bfSSheng   return (V == BIT_TRUE || V == BIT_FALSE);
202df3765bfSSheng }
203df3765bfSSheng 
204b9079baaSPierre van Houtryve static bool ValueNotSet(bit_value_t V) { return (V == BIT_UNSET); }
205df3765bfSSheng 
206df3765bfSSheng static int Value(bit_value_t V) {
207df3765bfSSheng   return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1);
208df3765bfSSheng }
209df3765bfSSheng 
210df3765bfSSheng static bit_value_t bitFromBits(const BitsInit &bits, unsigned index) {
21162e2c7fbSRahul Joshi   if (const BitInit *bit = dyn_cast<BitInit>(bits.getBit(index)))
212df3765bfSSheng     return bit->getValue() ? BIT_TRUE : BIT_FALSE;
213df3765bfSSheng 
214df3765bfSSheng   // The bit is uninitialized.
215df3765bfSSheng   return BIT_UNSET;
216df3765bfSSheng }
217df3765bfSSheng 
218df3765bfSSheng // Prints the bit value for each position.
2193e24dd42SRahul Joshi static void dumpBits(raw_ostream &OS, const BitsInit &bits) {
220df3765bfSSheng   for (unsigned index = bits.getNumBits(); index > 0; --index) {
221df3765bfSSheng     switch (bitFromBits(bits, index - 1)) {
222df3765bfSSheng     case BIT_TRUE:
2233e24dd42SRahul Joshi       OS << "1";
224df3765bfSSheng       break;
225df3765bfSSheng     case BIT_FALSE:
2263e24dd42SRahul Joshi       OS << "0";
227df3765bfSSheng       break;
228df3765bfSSheng     case BIT_UNSET:
2293e24dd42SRahul Joshi       OS << "_";
230df3765bfSSheng       break;
231df3765bfSSheng     default:
232df3765bfSSheng       llvm_unreachable("unexpected return value from bitFromBits");
233df3765bfSSheng     }
234df3765bfSSheng   }
235df3765bfSSheng }
236df3765bfSSheng 
23762e2c7fbSRahul Joshi static const BitsInit &getBitsField(const Record &def, StringRef str) {
238df3765bfSSheng   const RecordVal *RV = def.getValue(str);
23962e2c7fbSRahul Joshi   if (const BitsInit *Bits = dyn_cast<BitsInit>(RV->getValue()))
240df3765bfSSheng     return *Bits;
241df3765bfSSheng 
242df3765bfSSheng   // variable length instruction
243df3765bfSSheng   VarLenInst VLI = VarLenInst(cast<DagInit>(RV->getValue()), RV);
24462e2c7fbSRahul Joshi   SmallVector<const Init *, 16> Bits;
245df3765bfSSheng 
246e9492ccaSJason Eckhardt   for (const auto &SI : VLI) {
247df3765bfSSheng     if (const BitsInit *BI = dyn_cast<BitsInit>(SI.Value)) {
248df3765bfSSheng       for (unsigned Idx = 0U; Idx < BI->getNumBits(); ++Idx) {
249df3765bfSSheng         Bits.push_back(BI->getBit(Idx));
250df3765bfSSheng       }
251df3765bfSSheng     } else if (const BitInit *BI = dyn_cast<BitInit>(SI.Value)) {
252df3765bfSSheng       Bits.push_back(const_cast<BitInit *>(BI));
253df3765bfSSheng     } else {
254df3765bfSSheng       for (unsigned Idx = 0U; Idx < SI.BitWidth; ++Idx)
2552ac3cd20SRiver Riddle         Bits.push_back(UnsetInit::get(def.getRecords()));
256df3765bfSSheng     }
257df3765bfSSheng   }
258df3765bfSSheng 
2592ac3cd20SRiver Riddle   return *BitsInit::get(def.getRecords(), Bits);
260df3765bfSSheng }
261df3765bfSSheng 
262df3765bfSSheng // Representation of the instruction to work on.
263df3765bfSSheng typedef std::vector<bit_value_t> insn_t;
264df3765bfSSheng 
265df3765bfSSheng namespace {
266df3765bfSSheng 
267df3765bfSSheng static const uint64_t NO_FIXED_SEGMENTS_SENTINEL = -1ULL;
268df3765bfSSheng 
269df3765bfSSheng class FilterChooser;
270df3765bfSSheng 
271df3765bfSSheng /// Filter - Filter works with FilterChooser to produce the decoding tree for
272df3765bfSSheng /// the ISA.
273df3765bfSSheng ///
274df3765bfSSheng /// It is useful to think of a Filter as governing the switch stmts of the
275df3765bfSSheng /// decoding tree in a certain level.  Each case stmt delegates to an inferior
276df3765bfSSheng /// FilterChooser to decide what further decoding logic to employ, or in another
277df3765bfSSheng /// words, what other remaining bits to look at.  The FilterChooser eventually
278df3765bfSSheng /// chooses a best Filter to do its job.
279df3765bfSSheng ///
280df3765bfSSheng /// This recursive scheme ends when the number of Opcodes assigned to the
281df3765bfSSheng /// FilterChooser becomes 1 or if there is a conflict.  A conflict happens when
282df3765bfSSheng /// the Filter/FilterChooser combo does not know how to distinguish among the
283df3765bfSSheng /// Opcodes assigned.
284df3765bfSSheng ///
285df3765bfSSheng /// An example of a conflict is
286df3765bfSSheng ///
287df3765bfSSheng /// Conflict:
288df3765bfSSheng ///                     111101000.00........00010000....
289df3765bfSSheng ///                     111101000.00........0001........
290df3765bfSSheng ///                     1111010...00........0001........
291df3765bfSSheng ///                     1111010...00....................
292df3765bfSSheng ///                     1111010.........................
293df3765bfSSheng ///                     1111............................
294df3765bfSSheng ///                     ................................
295df3765bfSSheng ///     VST4q8a         111101000_00________00010000____
296df3765bfSSheng ///     VST4q8b         111101000_00________00010000____
297df3765bfSSheng ///
298df3765bfSSheng /// The Debug output shows the path that the decoding tree follows to reach the
299df3765bfSSheng /// the conclusion that there is a conflict.  VST4q8a is a vst4 to double-spaced
300df3765bfSSheng /// even registers, while VST4q8b is a vst4 to double-spaced odd registers.
301df3765bfSSheng ///
302df3765bfSSheng /// The encoding info in the .td files does not specify this meta information,
303df3765bfSSheng /// which could have been used by the decoder to resolve the conflict.  The
304df3765bfSSheng /// decoder could try to decode the even/odd register numbering and assign to
305df3765bfSSheng /// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a"
306df3765bfSSheng /// version and return the Opcode since the two have the same Asm format string.
307df3765bfSSheng class Filter {
308df3765bfSSheng protected:
309b9079baaSPierre van Houtryve   const FilterChooser
310b9079baaSPierre van Houtryve       *Owner;        // points to the FilterChooser who owns this filter
311df3765bfSSheng   unsigned StartBit; // the starting bit position
312df3765bfSSheng   unsigned NumBits;  // number of bits to filter
313df3765bfSSheng   bool Mixed;        // a mixed region contains both set and unset bits
314df3765bfSSheng 
315df3765bfSSheng   // Map of well-known segment value to the set of uid's with that value.
316b9079baaSPierre van Houtryve   std::map<uint64_t, std::vector<EncodingIDAndOpcode>> FilteredInstructions;
317df3765bfSSheng 
318df3765bfSSheng   // Set of uid's with non-constant segment values.
319df3765bfSSheng   std::vector<EncodingIDAndOpcode> VariableInstructions;
320df3765bfSSheng 
321df3765bfSSheng   // Map of well-known segment value to its delegate.
322df3765bfSSheng   std::map<uint64_t, std::unique_ptr<const FilterChooser>> FilterChooserMap;
323df3765bfSSheng 
324df3765bfSSheng   // Number of instructions which fall under FilteredInstructions category.
325df3765bfSSheng   unsigned NumFiltered;
326df3765bfSSheng 
327df3765bfSSheng   // Keeps track of the last opcode in the filtered bucket.
328df3765bfSSheng   EncodingIDAndOpcode LastOpcFiltered;
329df3765bfSSheng 
330df3765bfSSheng public:
331df3765bfSSheng   Filter(Filter &&f);
332df3765bfSSheng   Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed);
333df3765bfSSheng 
334df3765bfSSheng   ~Filter() = default;
335df3765bfSSheng 
336df3765bfSSheng   unsigned getNumFiltered() const { return NumFiltered; }
337df3765bfSSheng 
338df3765bfSSheng   EncodingIDAndOpcode getSingletonOpc() const {
339df3765bfSSheng     assert(NumFiltered == 1);
340df3765bfSSheng     return LastOpcFiltered;
341df3765bfSSheng   }
342df3765bfSSheng 
343df3765bfSSheng   // Return the filter chooser for the group of instructions without constant
344df3765bfSSheng   // segment values.
345df3765bfSSheng   const FilterChooser &getVariableFC() const {
346df3765bfSSheng     assert(NumFiltered == 1);
347df3765bfSSheng     assert(FilterChooserMap.size() == 1);
348df3765bfSSheng     return *(FilterChooserMap.find(NO_FIXED_SEGMENTS_SENTINEL)->second);
349df3765bfSSheng   }
350df3765bfSSheng 
351df3765bfSSheng   // Divides the decoding task into sub tasks and delegates them to the
352df3765bfSSheng   // inferior FilterChooser's.
353df3765bfSSheng   //
354df3765bfSSheng   // A special case arises when there's only one entry in the filtered
355df3765bfSSheng   // instructions.  In order to unambiguously decode the singleton, we need to
356df3765bfSSheng   // match the remaining undecoded encoding bits against the singleton.
357df3765bfSSheng   void recurse();
358df3765bfSSheng 
359df3765bfSSheng   // Emit table entries to decode instructions given a segment or segments of
360df3765bfSSheng   // bits.
361df3765bfSSheng   void emitTableEntry(DecoderTableInfo &TableInfo) const;
362df3765bfSSheng 
363df3765bfSSheng   // Returns the number of fanout produced by the filter.  More fanout implies
364df3765bfSSheng   // the filter distinguishes more categories of instructions.
365df3765bfSSheng   unsigned usefulness() const;
366df3765bfSSheng }; // end class Filter
367df3765bfSSheng 
368df3765bfSSheng } // end anonymous namespace
369df3765bfSSheng 
370df3765bfSSheng // These are states of our finite state machines used in FilterChooser's
371df3765bfSSheng // filterProcessor() which produces the filter candidates to use.
372df3765bfSSheng typedef enum {
373df3765bfSSheng   ATTR_NONE,
374df3765bfSSheng   ATTR_FILTERED,
375df3765bfSSheng   ATTR_ALL_SET,
376df3765bfSSheng   ATTR_ALL_UNSET,
377df3765bfSSheng   ATTR_MIXED
378df3765bfSSheng } bitAttr_t;
379df3765bfSSheng 
380df3765bfSSheng /// FilterChooser - FilterChooser chooses the best filter among a set of Filters
381df3765bfSSheng /// in order to perform the decoding of instructions at the current level.
382df3765bfSSheng ///
383df3765bfSSheng /// Decoding proceeds from the top down.  Based on the well-known encoding bits
384df3765bfSSheng /// of instructions available, FilterChooser builds up the possible Filters that
385df3765bfSSheng /// can further the task of decoding by distinguishing among the remaining
386df3765bfSSheng /// candidate instructions.
387df3765bfSSheng ///
388df3765bfSSheng /// Once a filter has been chosen, it is called upon to divide the decoding task
389df3765bfSSheng /// into sub-tasks and delegates them to its inferior FilterChoosers for further
390df3765bfSSheng /// processings.
391df3765bfSSheng ///
392df3765bfSSheng /// It is useful to think of a Filter as governing the switch stmts of the
393df3765bfSSheng /// decoding tree.  And each case is delegated to an inferior FilterChooser to
394df3765bfSSheng /// decide what further remaining bits to look at.
395df3765bfSSheng namespace {
396df3765bfSSheng 
397df3765bfSSheng class FilterChooser {
398df3765bfSSheng protected:
399df3765bfSSheng   friend class Filter;
400df3765bfSSheng 
401df3765bfSSheng   // Vector of codegen instructions to choose our filter.
402df3765bfSSheng   ArrayRef<EncodingAndInst> AllInstructions;
403df3765bfSSheng 
404df3765bfSSheng   // Vector of uid's for this filter chooser to work on.
405df3765bfSSheng   // The first member of the pair is the opcode id being decoded, the second is
406df3765bfSSheng   // the opcode id that should be emitted.
407df3765bfSSheng   const std::vector<EncodingIDAndOpcode> &Opcodes;
408df3765bfSSheng 
409df3765bfSSheng   // Lookup table for the operand decoding of instructions.
410df3765bfSSheng   const std::map<unsigned, std::vector<OperandInfo>> &Operands;
411df3765bfSSheng 
412df3765bfSSheng   // Vector of candidate filters.
413df3765bfSSheng   std::vector<Filter> Filters;
414df3765bfSSheng 
415df3765bfSSheng   // Array of bit values passed down from our parent.
416df3765bfSSheng   // Set to all BIT_UNFILTERED's for Parent == NULL.
417df3765bfSSheng   std::vector<bit_value_t> FilterBitValues;
418df3765bfSSheng 
419df3765bfSSheng   // Links to the FilterChooser above us in the decoding tree.
420df3765bfSSheng   const FilterChooser *Parent;
421df3765bfSSheng 
422df3765bfSSheng   // Index of the best filter from Filters.
423df3765bfSSheng   int BestIndex;
424df3765bfSSheng 
425df3765bfSSheng   // Width of instructions
426df3765bfSSheng   unsigned BitWidth;
427df3765bfSSheng 
428df3765bfSSheng   // Parent emitter
429df3765bfSSheng   const DecoderEmitter *Emitter;
430df3765bfSSheng 
431df3765bfSSheng public:
432df3765bfSSheng   FilterChooser(ArrayRef<EncodingAndInst> Insts,
433df3765bfSSheng                 const std::vector<EncodingIDAndOpcode> &IDs,
434df3765bfSSheng                 const std::map<unsigned, std::vector<OperandInfo>> &Ops,
435df3765bfSSheng                 unsigned BW, const DecoderEmitter *E)
436df3765bfSSheng       : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
437df3765bfSSheng         FilterBitValues(BW, BIT_UNFILTERED), Parent(nullptr), BestIndex(-1),
438df3765bfSSheng         BitWidth(BW), Emitter(E) {
439df3765bfSSheng     doFilter();
440df3765bfSSheng   }
441df3765bfSSheng 
442df3765bfSSheng   FilterChooser(ArrayRef<EncodingAndInst> Insts,
443df3765bfSSheng                 const std::vector<EncodingIDAndOpcode> &IDs,
444df3765bfSSheng                 const std::map<unsigned, std::vector<OperandInfo>> &Ops,
445df3765bfSSheng                 const std::vector<bit_value_t> &ParentFilterBitValues,
446df3765bfSSheng                 const FilterChooser &parent)
447df3765bfSSheng       : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
448df3765bfSSheng         FilterBitValues(ParentFilterBitValues), Parent(&parent), BestIndex(-1),
449df3765bfSSheng         BitWidth(parent.BitWidth), Emitter(parent.Emitter) {
450df3765bfSSheng     doFilter();
451df3765bfSSheng   }
452df3765bfSSheng 
453df3765bfSSheng   FilterChooser(const FilterChooser &) = delete;
454df3765bfSSheng   void operator=(const FilterChooser &) = delete;
455df3765bfSSheng 
456df3765bfSSheng   unsigned getBitWidth() const { return BitWidth; }
457df3765bfSSheng 
458df3765bfSSheng protected:
459df3765bfSSheng   // Populates the insn given the uid.
460df3765bfSSheng   void insnWithID(insn_t &Insn, unsigned Opcode) const {
461e9492ccaSJason Eckhardt     const Record *EncodingDef = AllInstructions[Opcode].EncodingDef;
46262e2c7fbSRahul Joshi     const BitsInit &Bits = getBitsField(*EncodingDef, "Inst");
463e9492ccaSJason Eckhardt     Insn.resize(std::max(BitWidth, Bits.getNumBits()), BIT_UNSET);
464df3765bfSSheng     // We may have a SoftFail bitmask, which specifies a mask where an encoding
465df3765bfSSheng     // may differ from the value in "Inst" and yet still be valid, but the
466df3765bfSSheng     // disassembler should return SoftFail instead of Success.
467df3765bfSSheng     //
468df3765bfSSheng     // This is used for marking UNPREDICTABLE instructions in the ARM world.
469e9492ccaSJason Eckhardt     const RecordVal *RV = EncodingDef->getValue("SoftFail");
470df3765bfSSheng     const BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
471df3765bfSSheng     for (unsigned i = 0; i < Bits.getNumBits(); ++i) {
472df3765bfSSheng       if (SFBits && bitFromBits(*SFBits, i) == BIT_TRUE)
473df3765bfSSheng         Insn[i] = BIT_UNSET;
474df3765bfSSheng       else
475df3765bfSSheng         Insn[i] = bitFromBits(Bits, i);
476df3765bfSSheng     }
477df3765bfSSheng   }
478df3765bfSSheng 
479df3765bfSSheng   // Emit the name of the encoding/instruction pair.
480df3765bfSSheng   void emitNameWithID(raw_ostream &OS, unsigned Opcode) const {
481df3765bfSSheng     const Record *EncodingDef = AllInstructions[Opcode].EncodingDef;
482df3765bfSSheng     const Record *InstDef = AllInstructions[Opcode].Inst->TheDef;
483df3765bfSSheng     if (EncodingDef != InstDef)
484df3765bfSSheng       OS << EncodingDef->getName() << ":";
485df3765bfSSheng     OS << InstDef->getName();
486df3765bfSSheng   }
487df3765bfSSheng 
488df3765bfSSheng   // Populates the field of the insn given the start position and the number of
489df3765bfSSheng   // consecutive bits to scan for.
490df3765bfSSheng   //
491e9492ccaSJason Eckhardt   // Returns a pair of values (indicator, field), where the indicator is false
492e9492ccaSJason Eckhardt   // if there exists any uninitialized bit value in the range and true if all
493e9492ccaSJason Eckhardt   // bits are well-known. The second value is the potentially populated field.
494e9492ccaSJason Eckhardt   std::pair<bool, uint64_t> fieldFromInsn(const insn_t &Insn, unsigned StartBit,
495df3765bfSSheng                                           unsigned NumBits) const;
496df3765bfSSheng 
497df3765bfSSheng   /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
498df3765bfSSheng   /// filter array as a series of chars.
4993e24dd42SRahul Joshi   void dumpFilterArray(raw_ostream &OS,
500df3765bfSSheng                        const std::vector<bit_value_t> &filter) const;
501df3765bfSSheng 
502df3765bfSSheng   /// dumpStack - dumpStack traverses the filter chooser chain and calls
503df3765bfSSheng   /// dumpFilterArray on each filter chooser up to the top level one.
5043e24dd42SRahul Joshi   void dumpStack(raw_ostream &OS, const char *prefix) const;
505df3765bfSSheng 
506df3765bfSSheng   Filter &bestFilter() {
507df3765bfSSheng     assert(BestIndex != -1 && "BestIndex not set");
508df3765bfSSheng     return Filters[BestIndex];
509df3765bfSSheng   }
510df3765bfSSheng 
511df3765bfSSheng   bool PositionFiltered(unsigned i) const {
512df3765bfSSheng     return ValueSet(FilterBitValues[i]);
513df3765bfSSheng   }
514df3765bfSSheng 
515df3765bfSSheng   // Calculates the island(s) needed to decode the instruction.
516df3765bfSSheng   // This returns a lit of undecoded bits of an instructions, for example,
517df3765bfSSheng   // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
518df3765bfSSheng   // decoded bits in order to verify that the instruction matches the Opcode.
519df3765bfSSheng   unsigned getIslands(std::vector<unsigned> &StartBits,
520df3765bfSSheng                       std::vector<unsigned> &EndBits,
521df3765bfSSheng                       std::vector<uint64_t> &FieldVals,
522df3765bfSSheng                       const insn_t &Insn) const;
523df3765bfSSheng 
524df3765bfSSheng   // Emits code to check the Predicates member of an instruction are true.
525df3765bfSSheng   // Returns true if predicate matches were emitted, false otherwise.
5263e24dd42SRahul Joshi   bool emitPredicateMatch(raw_ostream &OS, unsigned Opc) const;
52745f3a5aaSFangrui Song   bool emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
52845f3a5aaSFangrui Song                              raw_ostream &OS) const;
529df3765bfSSheng 
530df3765bfSSheng   bool doesOpcodeNeedPredicate(unsigned Opc) const;
531df3765bfSSheng   unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const;
532b9079baaSPierre van Houtryve   void emitPredicateTableEntry(DecoderTableInfo &TableInfo, unsigned Opc) const;
533df3765bfSSheng 
534b9079baaSPierre van Houtryve   void emitSoftFailTableEntry(DecoderTableInfo &TableInfo, unsigned Opc) const;
535df3765bfSSheng 
536df3765bfSSheng   // Emits table entries to decode the singleton.
537df3765bfSSheng   void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
538df3765bfSSheng                                EncodingIDAndOpcode Opc) const;
539df3765bfSSheng 
540df3765bfSSheng   // Emits code to decode the singleton, and then to decode the rest.
541df3765bfSSheng   void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
542df3765bfSSheng                                const Filter &Best) const;
543df3765bfSSheng 
544708567abSRahul Joshi   void emitBinaryParser(raw_ostream &OS, indent Indent,
545df3765bfSSheng                         const OperandInfo &OpInfo,
546df3765bfSSheng                         bool &OpHasCompleteDecoder) const;
547df3765bfSSheng 
548708567abSRahul Joshi   void emitDecoder(raw_ostream &OS, indent Indent, unsigned Opc,
549df3765bfSSheng                    bool &HasCompleteDecoder) const;
550df3765bfSSheng   unsigned getDecoderIndex(DecoderSet &Decoders, unsigned Opc,
551df3765bfSSheng                            bool &HasCompleteDecoder) const;
552df3765bfSSheng 
553df3765bfSSheng   // Assign a single filter and run with it.
554df3765bfSSheng   void runSingleFilter(unsigned startBit, unsigned numBit, bool mixed);
555df3765bfSSheng 
556df3765bfSSheng   // reportRegion is a helper function for filterProcessor to mark a region as
557df3765bfSSheng   // eligible for use as a filter region.
558df3765bfSSheng   void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex,
559df3765bfSSheng                     bool AllowMixed);
560df3765bfSSheng 
561df3765bfSSheng   // FilterProcessor scans the well-known encoding bits of the instructions and
562df3765bfSSheng   // builds up a list of candidate filters.  It chooses the best filter and
563df3765bfSSheng   // recursively descends down the decoding tree.
564df3765bfSSheng   bool filterProcessor(bool AllowMixed, bool Greedy = true);
565df3765bfSSheng 
566df3765bfSSheng   // Decides on the best configuration of filter(s) to use in order to decode
567df3765bfSSheng   // the instructions.  A conflict of instructions may occur, in which case we
568df3765bfSSheng   // dump the conflict set to the standard error.
569df3765bfSSheng   void doFilter();
570df3765bfSSheng 
571df3765bfSSheng public:
572df3765bfSSheng   // emitTableEntries - Emit state machine entries to decode our share of
573df3765bfSSheng   // instructions.
574df3765bfSSheng   void emitTableEntries(DecoderTableInfo &TableInfo) const;
575df3765bfSSheng };
576df3765bfSSheng 
577df3765bfSSheng } // end anonymous namespace
578df3765bfSSheng 
579df3765bfSSheng ///////////////////////////
580df3765bfSSheng //                       //
581df3765bfSSheng // Filter Implementation //
582df3765bfSSheng //                       //
583df3765bfSSheng ///////////////////////////
584df3765bfSSheng 
585df3765bfSSheng Filter::Filter(Filter &&f)
586df3765bfSSheng     : Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed),
587df3765bfSSheng       FilteredInstructions(std::move(f.FilteredInstructions)),
588df3765bfSSheng       VariableInstructions(std::move(f.VariableInstructions)),
589b9079baaSPierre van Houtryve       FilterChooserMap(std::move(f.FilterChooserMap)),
590b9079baaSPierre van Houtryve       NumFiltered(f.NumFiltered), LastOpcFiltered(f.LastOpcFiltered) {}
591df3765bfSSheng 
592df3765bfSSheng Filter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits,
593df3765bfSSheng                bool mixed)
594df3765bfSSheng     : Owner(&owner), StartBit(startBit), NumBits(numBits), Mixed(mixed) {
595df3765bfSSheng   assert(StartBit + NumBits - 1 < Owner->BitWidth);
596df3765bfSSheng 
597df3765bfSSheng   NumFiltered = 0;
598df3765bfSSheng   LastOpcFiltered = {0, 0};
599df3765bfSSheng 
600e9492ccaSJason Eckhardt   for (const auto &OpcPair : Owner->Opcodes) {
601df3765bfSSheng     insn_t Insn;
602df3765bfSSheng 
603df3765bfSSheng     // Populates the insn given the uid.
604e9492ccaSJason Eckhardt     Owner->insnWithID(Insn, OpcPair.EncodingID);
605df3765bfSSheng 
606df3765bfSSheng     // Scans the segment for possibly well-specified encoding bits.
607e9492ccaSJason Eckhardt     auto [Ok, Field] = Owner->fieldFromInsn(Insn, StartBit, NumBits);
608df3765bfSSheng 
609e9492ccaSJason Eckhardt     if (Ok) {
610df3765bfSSheng       // The encoding bits are well-known.  Lets add the uid of the
611df3765bfSSheng       // instruction into the bucket keyed off the constant field value.
612e9492ccaSJason Eckhardt       LastOpcFiltered = OpcPair;
613df3765bfSSheng       FilteredInstructions[Field].push_back(LastOpcFiltered);
614df3765bfSSheng       ++NumFiltered;
615df3765bfSSheng     } else {
616df3765bfSSheng       // Some of the encoding bit(s) are unspecified.  This contributes to
617df3765bfSSheng       // one additional member of "Variable" instructions.
618e9492ccaSJason Eckhardt       VariableInstructions.push_back(OpcPair);
619df3765bfSSheng     }
620df3765bfSSheng   }
621df3765bfSSheng 
622b9079baaSPierre van Houtryve   assert((FilteredInstructions.size() + VariableInstructions.size() > 0) &&
623b9079baaSPierre van Houtryve          "Filter returns no instruction categories");
624df3765bfSSheng }
625df3765bfSSheng 
626df3765bfSSheng // Divides the decoding task into sub tasks and delegates them to the
627df3765bfSSheng // inferior FilterChooser's.
628df3765bfSSheng //
629df3765bfSSheng // A special case arises when there's only one entry in the filtered
630df3765bfSSheng // instructions.  In order to unambiguously decode the singleton, we need to
631df3765bfSSheng // match the remaining undecoded encoding bits against the singleton.
632df3765bfSSheng void Filter::recurse() {
633df3765bfSSheng   // Starts by inheriting our parent filter chooser's filter bit values.
634df3765bfSSheng   std::vector<bit_value_t> BitValueArray(Owner->FilterBitValues);
635df3765bfSSheng 
636df3765bfSSheng   if (!VariableInstructions.empty()) {
637df3765bfSSheng     // Conservatively marks each segment position as BIT_UNSET.
638df3765bfSSheng     for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex)
639df3765bfSSheng       BitValueArray[StartBit + bitIndex] = BIT_UNSET;
640df3765bfSSheng 
641df3765bfSSheng     // Delegates to an inferior filter chooser for further processing on this
642df3765bfSSheng     // group of instructions whose segment values are variable.
643*4e8c9d28SJay Foad     FilterChooserMap.try_emplace(
644b9079baaSPierre van Houtryve         NO_FIXED_SEGMENTS_SENTINEL,
645df3765bfSSheng         std::make_unique<FilterChooser>(Owner->AllInstructions,
646b9079baaSPierre van Houtryve                                         VariableInstructions, Owner->Operands,
647*4e8c9d28SJay Foad                                         BitValueArray, *Owner));
648df3765bfSSheng   }
649df3765bfSSheng 
650df3765bfSSheng   // No need to recurse for a singleton filtered instruction.
651df3765bfSSheng   // See also Filter::emit*().
652df3765bfSSheng   if (getNumFiltered() == 1) {
653df3765bfSSheng     assert(FilterChooserMap.size() == 1);
654df3765bfSSheng     return;
655df3765bfSSheng   }
656df3765bfSSheng 
657df3765bfSSheng   // Otherwise, create sub choosers.
658df3765bfSSheng   for (const auto &Inst : FilteredInstructions) {
659df3765bfSSheng 
660df3765bfSSheng     // Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
661df3765bfSSheng     for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) {
662df3765bfSSheng       if (Inst.first & (1ULL << bitIndex))
663df3765bfSSheng         BitValueArray[StartBit + bitIndex] = BIT_TRUE;
664df3765bfSSheng       else
665df3765bfSSheng         BitValueArray[StartBit + bitIndex] = BIT_FALSE;
666df3765bfSSheng     }
667df3765bfSSheng 
668df3765bfSSheng     // Delegates to an inferior filter chooser for further processing on this
669df3765bfSSheng     // category of instructions.
670*4e8c9d28SJay Foad     FilterChooserMap.try_emplace(Inst.first,
671*4e8c9d28SJay Foad                                  std::make_unique<FilterChooser>(
672f723260aSJay Foad                                      Owner->AllInstructions, Inst.second,
673*4e8c9d28SJay Foad                                      Owner->Operands, BitValueArray, *Owner));
674df3765bfSSheng   }
675df3765bfSSheng }
676df3765bfSSheng 
677df3765bfSSheng static void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups,
678df3765bfSSheng                                uint32_t DestIdx) {
679df3765bfSSheng   // Any NumToSkip fixups in the current scope can resolve to the
680df3765bfSSheng   // current location.
681b9079baaSPierre van Houtryve   for (FixupList::const_reverse_iterator I = Fixups.rbegin(), E = Fixups.rend();
682df3765bfSSheng        I != E; ++I) {
683df3765bfSSheng     // Calculate the distance from the byte following the fixup entry byte
684df3765bfSSheng     // to the destination. The Target is calculated from after the 16-bit
685df3765bfSSheng     // NumToSkip entry itself, so subtract two  from the displacement here
686df3765bfSSheng     // to account for that.
687df3765bfSSheng     uint32_t FixupIdx = *I;
688df3765bfSSheng     uint32_t Delta = DestIdx - FixupIdx - 3;
689df3765bfSSheng     // Our NumToSkip entries are 24-bits. Make sure our table isn't too
690df3765bfSSheng     // big.
691df3765bfSSheng     assert(Delta < (1u << 24));
692df3765bfSSheng     Table[FixupIdx] = (uint8_t)Delta;
693df3765bfSSheng     Table[FixupIdx + 1] = (uint8_t)(Delta >> 8);
694df3765bfSSheng     Table[FixupIdx + 2] = (uint8_t)(Delta >> 16);
695df3765bfSSheng   }
696df3765bfSSheng }
697df3765bfSSheng 
698df3765bfSSheng // Emit table entries to decode instructions given a segment or segments
699df3765bfSSheng // of bits.
700df3765bfSSheng void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
701d93f850cSJason Eckhardt   assert((NumBits < (1u << 8)) && "NumBits overflowed uint8 table entry!");
702df3765bfSSheng   TableInfo.Table.push_back(MCD::OPC_ExtractField);
703d93f850cSJason Eckhardt 
704d93f850cSJason Eckhardt   SmallString<16> SBytes;
705d93f850cSJason Eckhardt   raw_svector_ostream S(SBytes);
706d93f850cSJason Eckhardt   encodeULEB128(StartBit, S);
707d93f850cSJason Eckhardt   TableInfo.Table.insert(TableInfo.Table.end(), SBytes.begin(), SBytes.end());
708df3765bfSSheng   TableInfo.Table.push_back(NumBits);
709df3765bfSSheng 
710df3765bfSSheng   // A new filter entry begins a new scope for fixup resolution.
711df3765bfSSheng   TableInfo.FixupStack.emplace_back();
712df3765bfSSheng 
713df3765bfSSheng   DecoderTable &Table = TableInfo.Table;
714df3765bfSSheng 
715df3765bfSSheng   size_t PrevFilter = 0;
716df3765bfSSheng   bool HasFallthrough = false;
717e9492ccaSJason Eckhardt   for (const auto &Filter : FilterChooserMap) {
718df3765bfSSheng     // Field value -1 implies a non-empty set of variable instructions.
719df3765bfSSheng     // See also recurse().
720df3765bfSSheng     if (Filter.first == NO_FIXED_SEGMENTS_SENTINEL) {
721df3765bfSSheng       HasFallthrough = true;
722df3765bfSSheng 
723df3765bfSSheng       // Each scope should always have at least one filter value to check
724df3765bfSSheng       // for.
725df3765bfSSheng       assert(PrevFilter != 0 && "empty filter set!");
726df3765bfSSheng       FixupList &CurScope = TableInfo.FixupStack.back();
727df3765bfSSheng       // Resolve any NumToSkip fixups in the current scope.
728df3765bfSSheng       resolveTableFixups(Table, CurScope, Table.size());
729df3765bfSSheng       CurScope.clear();
730df3765bfSSheng       PrevFilter = 0; // Don't re-process the filter's fallthrough.
731df3765bfSSheng     } else {
732df3765bfSSheng       Table.push_back(MCD::OPC_FilterValue);
733df3765bfSSheng       // Encode and emit the value to filter against.
734df3765bfSSheng       uint8_t Buffer[16];
735df3765bfSSheng       unsigned Len = encodeULEB128(Filter.first, Buffer);
736df3765bfSSheng       Table.insert(Table.end(), Buffer, Buffer + Len);
737df3765bfSSheng       // Reserve space for the NumToSkip entry. We'll backpatch the value
738df3765bfSSheng       // later.
739df3765bfSSheng       PrevFilter = Table.size();
740df3765bfSSheng       Table.push_back(0);
741df3765bfSSheng       Table.push_back(0);
742df3765bfSSheng       Table.push_back(0);
743df3765bfSSheng     }
744df3765bfSSheng 
745df3765bfSSheng     // We arrive at a category of instructions with the same segment value.
746df3765bfSSheng     // Now delegate to the sub filter chooser for further decodings.
747df3765bfSSheng     // The case may fallthrough, which happens if the remaining well-known
748df3765bfSSheng     // encoding bits do not match exactly.
749df3765bfSSheng     Filter.second->emitTableEntries(TableInfo);
750df3765bfSSheng 
751df3765bfSSheng     // Now that we've emitted the body of the handler, update the NumToSkip
752df3765bfSSheng     // of the filter itself to be able to skip forward when false. Subtract
753df3765bfSSheng     // two as to account for the width of the NumToSkip field itself.
754df3765bfSSheng     if (PrevFilter) {
755df3765bfSSheng       uint32_t NumToSkip = Table.size() - PrevFilter - 3;
756b9079baaSPierre van Houtryve       assert(NumToSkip < (1u << 24) &&
757b9079baaSPierre van Houtryve              "disassembler decoding table too large!");
758df3765bfSSheng       Table[PrevFilter] = (uint8_t)NumToSkip;
759df3765bfSSheng       Table[PrevFilter + 1] = (uint8_t)(NumToSkip >> 8);
760df3765bfSSheng       Table[PrevFilter + 2] = (uint8_t)(NumToSkip >> 16);
761df3765bfSSheng     }
762df3765bfSSheng   }
763df3765bfSSheng 
764df3765bfSSheng   // Any remaining unresolved fixups bubble up to the parent fixup scope.
765df3765bfSSheng   assert(TableInfo.FixupStack.size() > 1 && "fixup stack underflow!");
766df3765bfSSheng   FixupScopeList::iterator Source = TableInfo.FixupStack.end() - 1;
767df3765bfSSheng   FixupScopeList::iterator Dest = Source - 1;
768df3765bfSSheng   llvm::append_range(*Dest, *Source);
769df3765bfSSheng   TableInfo.FixupStack.pop_back();
770df3765bfSSheng 
771df3765bfSSheng   // If there is no fallthrough, then the final filter should get fixed
772df3765bfSSheng   // up according to the enclosing scope rather than the current position.
773df3765bfSSheng   if (!HasFallthrough)
774df3765bfSSheng     TableInfo.FixupStack.back().push_back(PrevFilter);
775df3765bfSSheng }
776df3765bfSSheng 
777df3765bfSSheng // Returns the number of fanout produced by the filter.  More fanout implies
778df3765bfSSheng // the filter distinguishes more categories of instructions.
779df3765bfSSheng unsigned Filter::usefulness() const {
780df3765bfSSheng   if (!VariableInstructions.empty())
781df3765bfSSheng     return FilteredInstructions.size();
782df3765bfSSheng   else
783df3765bfSSheng     return FilteredInstructions.size() + 1;
784df3765bfSSheng }
785df3765bfSSheng 
786df3765bfSSheng //////////////////////////////////
787df3765bfSSheng //                              //
788df3765bfSSheng // Filterchooser Implementation //
789df3765bfSSheng //                              //
790df3765bfSSheng //////////////////////////////////
791df3765bfSSheng 
792df3765bfSSheng // Emit the decoder state machine table.
793df3765bfSSheng void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
794708567abSRahul Joshi                                indent Indent, unsigned BitWidth,
7952ed0aacfSJason Eckhardt                                StringRef Namespace,
7962ed0aacfSJason Eckhardt                                const EncodingIDsVec &EncodingIDs) const {
7972ed0aacfSJason Eckhardt   // We'll need to be able to map from a decoded opcode into the corresponding
7982ed0aacfSJason Eckhardt   // EncodingID for this specific combination of BitWidth and Namespace. This
7992ed0aacfSJason Eckhardt   // is used below to index into NumberedEncodings.
8002ed0aacfSJason Eckhardt   DenseMap<unsigned, unsigned> OpcodeToEncodingID;
8012ed0aacfSJason Eckhardt   OpcodeToEncodingID.reserve(EncodingIDs.size());
802e9492ccaSJason Eckhardt   for (const auto &EI : EncodingIDs)
8032ed0aacfSJason Eckhardt     OpcodeToEncodingID[EI.Opcode] = EI.EncodingID;
8042ed0aacfSJason Eckhardt 
805708567abSRahul Joshi   OS << Indent << "static const uint8_t DecoderTable" << Namespace << BitWidth
806708567abSRahul Joshi      << "[] = {\n";
807df3765bfSSheng 
8083e24dd42SRahul Joshi   Indent += 2;
809df3765bfSSheng 
8101442b0e6SJason Eckhardt   // Emit ULEB128 encoded value to OS, returning the number of bytes emitted.
8111442b0e6SJason Eckhardt   auto emitULEB128 = [](DecoderTable::const_iterator I,
8121442b0e6SJason Eckhardt                         formatted_raw_ostream &OS) {
8131442b0e6SJason Eckhardt     unsigned Len = 0;
8141442b0e6SJason Eckhardt     while (*I >= 128) {
8151442b0e6SJason Eckhardt       OS << (unsigned)*I++ << ", ";
8161442b0e6SJason Eckhardt       Len++;
8171442b0e6SJason Eckhardt     }
8181442b0e6SJason Eckhardt     OS << (unsigned)*I++ << ", ";
8191442b0e6SJason Eckhardt     return Len + 1;
8201442b0e6SJason Eckhardt   };
8211442b0e6SJason Eckhardt 
8221442b0e6SJason Eckhardt   // Emit 24-bit numtoskip value to OS, returning the NumToSkip value.
8231442b0e6SJason Eckhardt   auto emitNumToSkip = [](DecoderTable::const_iterator I,
8241442b0e6SJason Eckhardt                           formatted_raw_ostream &OS) {
8251442b0e6SJason Eckhardt     uint8_t Byte = *I++;
8261442b0e6SJason Eckhardt     uint32_t NumToSkip = Byte;
8271442b0e6SJason Eckhardt     OS << (unsigned)Byte << ", ";
8281442b0e6SJason Eckhardt     Byte = *I++;
8291442b0e6SJason Eckhardt     OS << (unsigned)Byte << ", ";
8301442b0e6SJason Eckhardt     NumToSkip |= Byte << 8;
8311442b0e6SJason Eckhardt     Byte = *I++;
8321442b0e6SJason Eckhardt     OS << utostr(Byte) << ", ";
8331442b0e6SJason Eckhardt     NumToSkip |= Byte << 16;
8341442b0e6SJason Eckhardt     return NumToSkip;
8351442b0e6SJason Eckhardt   };
8361442b0e6SJason Eckhardt 
837df3765bfSSheng   // FIXME: We may be able to use the NumToSkip values to recover
838df3765bfSSheng   // appropriate indentation levels.
839df3765bfSSheng   DecoderTable::const_iterator I = Table.begin();
840df3765bfSSheng   DecoderTable::const_iterator E = Table.end();
841df3765bfSSheng   while (I != E) {
842df3765bfSSheng     assert(I < E && "incomplete decode table entry!");
843df3765bfSSheng 
844df3765bfSSheng     uint64_t Pos = I - Table.begin();
845df3765bfSSheng     OS << "/* " << Pos << " */";
846df3765bfSSheng     OS.PadToColumn(12);
847df3765bfSSheng 
848df3765bfSSheng     switch (*I) {
849df3765bfSSheng     default:
850df3765bfSSheng       PrintFatalError("invalid decode table opcode");
851df3765bfSSheng     case MCD::OPC_ExtractField: {
852df3765bfSSheng       ++I;
853708567abSRahul Joshi       OS << Indent << "MCD::OPC_ExtractField, ";
854d93f850cSJason Eckhardt 
855d93f850cSJason Eckhardt       // ULEB128 encoded start value.
8561442b0e6SJason Eckhardt       const char *ErrMsg = nullptr;
8571442b0e6SJason Eckhardt       unsigned Start = decodeULEB128(Table.data() + Pos + 1, nullptr,
8581442b0e6SJason Eckhardt                                      Table.data() + Table.size(), &ErrMsg);
8591442b0e6SJason Eckhardt       assert(ErrMsg == nullptr && "ULEB128 value too large!");
8601442b0e6SJason Eckhardt       I += emitULEB128(I, OS);
861d93f850cSJason Eckhardt 
862df3765bfSSheng       unsigned Len = *I++;
863d93f850cSJason Eckhardt       OS << Len << ",  // Inst{";
864df3765bfSSheng       if (Len > 1)
865df3765bfSSheng         OS << (Start + Len - 1) << "-";
866df3765bfSSheng       OS << Start << "} ...\n";
867df3765bfSSheng       break;
868df3765bfSSheng     }
869df3765bfSSheng     case MCD::OPC_FilterValue: {
870df3765bfSSheng       ++I;
871708567abSRahul Joshi       OS << Indent << "MCD::OPC_FilterValue, ";
872df3765bfSSheng       // The filter value is ULEB128 encoded.
8731442b0e6SJason Eckhardt       I += emitULEB128(I, OS);
874df3765bfSSheng 
875df3765bfSSheng       // 24-bit numtoskip value.
8761442b0e6SJason Eckhardt       uint32_t NumToSkip = emitNumToSkip(I, OS);
8771442b0e6SJason Eckhardt       I += 3;
878df3765bfSSheng       OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
879df3765bfSSheng       break;
880df3765bfSSheng     }
881df3765bfSSheng     case MCD::OPC_CheckField: {
882df3765bfSSheng       ++I;
883708567abSRahul Joshi       OS << Indent << "MCD::OPC_CheckField, ";
884d93f850cSJason Eckhardt       // ULEB128 encoded start value.
8851442b0e6SJason Eckhardt       I += emitULEB128(I, OS);
886d93f850cSJason Eckhardt       // 8-bit length.
887df3765bfSSheng       unsigned Len = *I++;
888d93f850cSJason Eckhardt       OS << Len << ", ";
889df3765bfSSheng       // ULEB128 encoded field value.
8901442b0e6SJason Eckhardt       I += emitULEB128(I, OS);
8911442b0e6SJason Eckhardt 
892df3765bfSSheng       // 24-bit numtoskip value.
8931442b0e6SJason Eckhardt       uint32_t NumToSkip = emitNumToSkip(I, OS);
8941442b0e6SJason Eckhardt       I += 3;
895df3765bfSSheng       OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
896df3765bfSSheng       break;
897df3765bfSSheng     }
898df3765bfSSheng     case MCD::OPC_CheckPredicate: {
899df3765bfSSheng       ++I;
900708567abSRahul Joshi       OS << Indent << "MCD::OPC_CheckPredicate, ";
9011442b0e6SJason Eckhardt       I += emitULEB128(I, OS);
902df3765bfSSheng 
903df3765bfSSheng       // 24-bit numtoskip value.
9041442b0e6SJason Eckhardt       uint32_t NumToSkip = emitNumToSkip(I, OS);
9051442b0e6SJason Eckhardt       I += 3;
906df3765bfSSheng       OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
907df3765bfSSheng       break;
908df3765bfSSheng     }
909df3765bfSSheng     case MCD::OPC_Decode:
910df3765bfSSheng     case MCD::OPC_TryDecode: {
911df3765bfSSheng       bool IsTry = *I == MCD::OPC_TryDecode;
912df3765bfSSheng       ++I;
913df3765bfSSheng       // Decode the Opcode value.
9141442b0e6SJason Eckhardt       const char *ErrMsg = nullptr;
9151442b0e6SJason Eckhardt       unsigned Opc = decodeULEB128(Table.data() + Pos + 1, nullptr,
9161442b0e6SJason Eckhardt                                    Table.data() + Table.size(), &ErrMsg);
9171442b0e6SJason Eckhardt       assert(ErrMsg == nullptr && "ULEB128 value too large!");
9181442b0e6SJason Eckhardt 
919708567abSRahul Joshi       OS << Indent << "MCD::OPC_" << (IsTry ? "Try" : "") << "Decode, ";
9201442b0e6SJason Eckhardt       I += emitULEB128(I, OS);
921df3765bfSSheng 
922df3765bfSSheng       // Decoder index.
9231442b0e6SJason Eckhardt       I += emitULEB128(I, OS);
924df3765bfSSheng 
9252ed0aacfSJason Eckhardt       auto EncI = OpcodeToEncodingID.find(Opc);
9262ed0aacfSJason Eckhardt       assert(EncI != OpcodeToEncodingID.end() && "no encoding entry");
9272ed0aacfSJason Eckhardt       auto EncodingID = EncI->second;
9282ed0aacfSJason Eckhardt 
929df3765bfSSheng       if (!IsTry) {
9302ed0aacfSJason Eckhardt         OS << "// Opcode: " << NumberedEncodings[EncodingID] << "\n";
931df3765bfSSheng         break;
932df3765bfSSheng       }
933df3765bfSSheng 
934df3765bfSSheng       // Fallthrough for OPC_TryDecode.
935df3765bfSSheng 
936df3765bfSSheng       // 24-bit numtoskip value.
9371442b0e6SJason Eckhardt       uint32_t NumToSkip = emitNumToSkip(I, OS);
9381442b0e6SJason Eckhardt       I += 3;
939df3765bfSSheng 
9402ed0aacfSJason Eckhardt       OS << "// Opcode: " << NumberedEncodings[EncodingID]
941df3765bfSSheng          << ", skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
942df3765bfSSheng       break;
943df3765bfSSheng     }
944df3765bfSSheng     case MCD::OPC_SoftFail: {
945df3765bfSSheng       ++I;
946708567abSRahul Joshi       OS << Indent << "MCD::OPC_SoftFail";
947df3765bfSSheng       // Positive mask
948df3765bfSSheng       uint64_t Value = 0;
949df3765bfSSheng       unsigned Shift = 0;
950df3765bfSSheng       do {
951df3765bfSSheng         OS << ", " << (unsigned)*I;
952390f2870Smahesh-attarde         Value += ((uint64_t)(*I & 0x7f)) << Shift;
953df3765bfSSheng         Shift += 7;
954df3765bfSSheng       } while (*I++ >= 128);
955df3765bfSSheng       if (Value > 127) {
956df3765bfSSheng         OS << " /* 0x";
957df3765bfSSheng         OS.write_hex(Value);
958df3765bfSSheng         OS << " */";
959df3765bfSSheng       }
960df3765bfSSheng       // Negative mask
961df3765bfSSheng       Value = 0;
962df3765bfSSheng       Shift = 0;
963df3765bfSSheng       do {
964df3765bfSSheng         OS << ", " << (unsigned)*I;
965390f2870Smahesh-attarde         Value += ((uint64_t)(*I & 0x7f)) << Shift;
966df3765bfSSheng         Shift += 7;
967df3765bfSSheng       } while (*I++ >= 128);
968df3765bfSSheng       if (Value > 127) {
969df3765bfSSheng         OS << " /* 0x";
970df3765bfSSheng         OS.write_hex(Value);
971df3765bfSSheng         OS << " */";
972df3765bfSSheng       }
973df3765bfSSheng       OS << ",\n";
974df3765bfSSheng       break;
975df3765bfSSheng     }
976df3765bfSSheng     case MCD::OPC_Fail: {
977df3765bfSSheng       ++I;
978708567abSRahul Joshi       OS << Indent << "MCD::OPC_Fail,\n";
979df3765bfSSheng       break;
980df3765bfSSheng     }
981df3765bfSSheng     }
982df3765bfSSheng   }
983708567abSRahul Joshi   OS << Indent << "0\n";
984df3765bfSSheng 
9853e24dd42SRahul Joshi   Indent -= 2;
986df3765bfSSheng 
987708567abSRahul Joshi   OS << Indent << "};\n\n";
988df3765bfSSheng }
989df3765bfSSheng 
990df3765bfSSheng void DecoderEmitter::emitInstrLenTable(formatted_raw_ostream &OS,
991df3765bfSSheng                                        std::vector<unsigned> &InstrLen) const {
992df3765bfSSheng   OS << "static const uint8_t InstrLenTable[] = {\n";
993df3765bfSSheng   for (unsigned &Len : InstrLen) {
994df3765bfSSheng     OS << Len << ",\n";
995df3765bfSSheng   }
996df3765bfSSheng   OS << "};\n\n";
997df3765bfSSheng }
998df3765bfSSheng 
999df3765bfSSheng void DecoderEmitter::emitPredicateFunction(formatted_raw_ostream &OS,
1000df3765bfSSheng                                            PredicateSet &Predicates,
1001708567abSRahul Joshi                                            indent Indent) const {
1002df3765bfSSheng   // The predicate function is just a big switch statement based on the
1003df3765bfSSheng   // input predicate index.
1004708567abSRahul Joshi   OS << Indent << "static bool checkDecoderPredicate(unsigned Idx, "
1005df3765bfSSheng      << "const FeatureBitset &Bits) {\n";
10063e24dd42SRahul Joshi   Indent += 2;
1007df3765bfSSheng   if (!Predicates.empty()) {
1008708567abSRahul Joshi     OS << Indent << "switch (Idx) {\n";
1009708567abSRahul Joshi     OS << Indent << "default: llvm_unreachable(\"Invalid index!\");\n";
1010df3765bfSSheng     unsigned Index = 0;
1011df3765bfSSheng     for (const auto &Predicate : Predicates) {
1012708567abSRahul Joshi       OS << Indent << "case " << Index++ << ":\n";
1013708567abSRahul Joshi       OS << Indent + 2 << "return (" << Predicate << ");\n";
1014df3765bfSSheng     }
1015708567abSRahul Joshi     OS << Indent << "}\n";
1016df3765bfSSheng   } else {
1017df3765bfSSheng     // No case statement to emit
1018708567abSRahul Joshi     OS << Indent << "llvm_unreachable(\"Invalid index!\");\n";
1019df3765bfSSheng   }
10203e24dd42SRahul Joshi   Indent -= 2;
1021708567abSRahul Joshi   OS << Indent << "}\n\n";
1022df3765bfSSheng }
1023df3765bfSSheng 
1024df3765bfSSheng void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
1025df3765bfSSheng                                          DecoderSet &Decoders,
1026708567abSRahul Joshi                                          indent Indent) const {
1027df3765bfSSheng   // The decoder function is just a big switch statement based on the
1028df3765bfSSheng   // input decoder index.
1029708567abSRahul Joshi   OS << Indent << "template <typename InsnType>\n";
1030708567abSRahul Joshi   OS << Indent << "static DecodeStatus decodeToMCInst(DecodeStatus S,"
1031df3765bfSSheng      << " unsigned Idx, InsnType insn, MCInst &MI,\n";
1032708567abSRahul Joshi   OS << Indent << "                                   uint64_t "
1033df3765bfSSheng      << "Address, const MCDisassembler *Decoder, bool &DecodeComplete) {\n";
10343e24dd42SRahul Joshi   Indent += 2;
1035708567abSRahul Joshi   OS << Indent << "DecodeComplete = true;\n";
1036df3765bfSSheng   // TODO: When InsnType is large, using uint64_t limits all fields to 64 bits
1037df3765bfSSheng   // It would be better for emitBinaryParser to use a 64-bit tmp whenever
1038df3765bfSSheng   // possible but fall back to an InsnType-sized tmp for truly large fields.
1039708567abSRahul Joshi   OS << Indent
1040708567abSRahul Joshi      << "using TmpType = "
1041df3765bfSSheng         "std::conditional_t<std::is_integral<InsnType>::"
1042df3765bfSSheng         "value, InsnType, uint64_t>;\n";
1043708567abSRahul Joshi   OS << Indent << "TmpType tmp;\n";
1044708567abSRahul Joshi   OS << Indent << "switch (Idx) {\n";
1045708567abSRahul Joshi   OS << Indent << "default: llvm_unreachable(\"Invalid index!\");\n";
1046df3765bfSSheng   unsigned Index = 0;
1047df3765bfSSheng   for (const auto &Decoder : Decoders) {
1048708567abSRahul Joshi     OS << Indent << "case " << Index++ << ":\n";
1049df3765bfSSheng     OS << Decoder;
1050708567abSRahul Joshi     OS << Indent + 2 << "return S;\n";
1051df3765bfSSheng   }
1052708567abSRahul Joshi   OS << Indent << "}\n";
10533e24dd42SRahul Joshi   Indent -= 2;
1054708567abSRahul Joshi   OS << Indent << "}\n";
1055df3765bfSSheng }
1056df3765bfSSheng 
1057df3765bfSSheng // Populates the field of the insn given the start position and the number of
1058df3765bfSSheng // consecutive bits to scan for.
1059df3765bfSSheng //
1060e9492ccaSJason Eckhardt // Returns a pair of values (indicator, field), where the indicator is false
1061e9492ccaSJason Eckhardt // if there exists any uninitialized bit value in the range and true if all
1062e9492ccaSJason Eckhardt // bits are well-known. The second value is the potentially populated field.
1063e9492ccaSJason Eckhardt std::pair<bool, uint64_t> FilterChooser::fieldFromInsn(const insn_t &Insn,
1064e9492ccaSJason Eckhardt                                                        unsigned StartBit,
1065e9492ccaSJason Eckhardt                                                        unsigned NumBits) const {
1066e9492ccaSJason Eckhardt   uint64_t Field = 0;
1067df3765bfSSheng 
1068df3765bfSSheng   for (unsigned i = 0; i < NumBits; ++i) {
1069df3765bfSSheng     if (Insn[StartBit + i] == BIT_UNSET)
1070e9492ccaSJason Eckhardt       return {false, Field};
1071df3765bfSSheng 
1072df3765bfSSheng     if (Insn[StartBit + i] == BIT_TRUE)
1073df3765bfSSheng       Field = Field | (1ULL << i);
1074df3765bfSSheng   }
1075df3765bfSSheng 
1076e9492ccaSJason Eckhardt   return {true, Field};
1077df3765bfSSheng }
1078df3765bfSSheng 
1079df3765bfSSheng /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
1080df3765bfSSheng /// filter array as a series of chars.
1081b9079baaSPierre van Houtryve void FilterChooser::dumpFilterArray(
10823e24dd42SRahul Joshi     raw_ostream &OS, const std::vector<bit_value_t> &filter) const {
1083df3765bfSSheng   for (unsigned bitIndex = BitWidth; bitIndex > 0; bitIndex--) {
1084df3765bfSSheng     switch (filter[bitIndex - 1]) {
1085df3765bfSSheng     case BIT_UNFILTERED:
10863e24dd42SRahul Joshi       OS << ".";
1087df3765bfSSheng       break;
1088df3765bfSSheng     case BIT_UNSET:
10893e24dd42SRahul Joshi       OS << "_";
1090df3765bfSSheng       break;
1091df3765bfSSheng     case BIT_TRUE:
10923e24dd42SRahul Joshi       OS << "1";
1093df3765bfSSheng       break;
1094df3765bfSSheng     case BIT_FALSE:
10953e24dd42SRahul Joshi       OS << "0";
1096df3765bfSSheng       break;
1097df3765bfSSheng     }
1098df3765bfSSheng   }
1099df3765bfSSheng }
1100df3765bfSSheng 
1101df3765bfSSheng /// dumpStack - dumpStack traverses the filter chooser chain and calls
1102df3765bfSSheng /// dumpFilterArray on each filter chooser up to the top level one.
11033e24dd42SRahul Joshi void FilterChooser::dumpStack(raw_ostream &OS, const char *prefix) const {
1104df3765bfSSheng   const FilterChooser *current = this;
1105df3765bfSSheng 
1106df3765bfSSheng   while (current) {
11073e24dd42SRahul Joshi     OS << prefix;
11083e24dd42SRahul Joshi     dumpFilterArray(OS, current->FilterBitValues);
11093e24dd42SRahul Joshi     OS << '\n';
1110df3765bfSSheng     current = current->Parent;
1111df3765bfSSheng   }
1112df3765bfSSheng }
1113df3765bfSSheng 
1114df3765bfSSheng // Calculates the island(s) needed to decode the instruction.
1115df3765bfSSheng // This returns a list of undecoded bits of an instructions, for example,
1116df3765bfSSheng // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
1117df3765bfSSheng // decoded bits in order to verify that the instruction matches the Opcode.
1118df3765bfSSheng unsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits,
1119df3765bfSSheng                                    std::vector<unsigned> &EndBits,
1120df3765bfSSheng                                    std::vector<uint64_t> &FieldVals,
1121df3765bfSSheng                                    const insn_t &Insn) const {
1122df3765bfSSheng   unsigned Num, BitNo;
1123df3765bfSSheng   Num = BitNo = 0;
1124df3765bfSSheng 
1125df3765bfSSheng   uint64_t FieldVal = 0;
1126df3765bfSSheng 
1127df3765bfSSheng   // 0: Init
1128df3765bfSSheng   // 1: Water (the bit value does not affect decoding)
1129df3765bfSSheng   // 2: Island (well-known bit value needed for decoding)
1130df3765bfSSheng   int State = 0;
1131df3765bfSSheng 
1132df3765bfSSheng   for (unsigned i = 0; i < BitWidth; ++i) {
1133df3765bfSSheng     int64_t Val = Value(Insn[i]);
1134df3765bfSSheng     bool Filtered = PositionFiltered(i);
1135df3765bfSSheng     switch (State) {
1136b9079baaSPierre van Houtryve     default:
1137b9079baaSPierre van Houtryve       llvm_unreachable("Unreachable code!");
1138df3765bfSSheng     case 0:
1139df3765bfSSheng     case 1:
1140df3765bfSSheng       if (Filtered || Val == -1)
1141df3765bfSSheng         State = 1; // Still in Water
1142df3765bfSSheng       else {
1143df3765bfSSheng         State = 2; // Into the Island
1144df3765bfSSheng         BitNo = 0;
1145df3765bfSSheng         StartBits.push_back(i);
1146df3765bfSSheng         FieldVal = Val;
1147df3765bfSSheng       }
1148df3765bfSSheng       break;
1149df3765bfSSheng     case 2:
1150df3765bfSSheng       if (Filtered || Val == -1) {
1151df3765bfSSheng         State = 1; // Into the Water
1152df3765bfSSheng         EndBits.push_back(i - 1);
1153df3765bfSSheng         FieldVals.push_back(FieldVal);
1154df3765bfSSheng         ++Num;
1155df3765bfSSheng       } else {
1156df3765bfSSheng         State = 2; // Still in Island
1157df3765bfSSheng         ++BitNo;
1158df3765bfSSheng         FieldVal = FieldVal | Val << BitNo;
1159df3765bfSSheng       }
1160df3765bfSSheng       break;
1161df3765bfSSheng     }
1162df3765bfSSheng   }
1163df3765bfSSheng   // If we are still in Island after the loop, do some housekeeping.
1164df3765bfSSheng   if (State == 2) {
1165df3765bfSSheng     EndBits.push_back(BitWidth - 1);
1166df3765bfSSheng     FieldVals.push_back(FieldVal);
1167df3765bfSSheng     ++Num;
1168df3765bfSSheng   }
1169df3765bfSSheng 
1170df3765bfSSheng   assert(StartBits.size() == Num && EndBits.size() == Num &&
1171df3765bfSSheng          FieldVals.size() == Num);
1172df3765bfSSheng   return Num;
1173df3765bfSSheng }
1174df3765bfSSheng 
1175708567abSRahul Joshi void FilterChooser::emitBinaryParser(raw_ostream &OS, indent Indent,
1176df3765bfSSheng                                      const OperandInfo &OpInfo,
1177df3765bfSSheng                                      bool &OpHasCompleteDecoder) const {
1178df3765bfSSheng   const std::string &Decoder = OpInfo.Decoder;
1179df3765bfSSheng 
1180df3765bfSSheng   bool UseInsertBits = OpInfo.numFields() != 1 || OpInfo.InitValue != 0;
1181df3765bfSSheng 
1182df3765bfSSheng   if (UseInsertBits) {
1183708567abSRahul Joshi     OS << Indent << "tmp = 0x";
11843e24dd42SRahul Joshi     OS.write_hex(OpInfo.InitValue);
11853e24dd42SRahul Joshi     OS << ";\n";
1186df3765bfSSheng   }
1187df3765bfSSheng 
1188df3765bfSSheng   for (const EncodingField &EF : OpInfo) {
1189708567abSRahul Joshi     OS << Indent;
1190df3765bfSSheng     if (UseInsertBits)
11913e24dd42SRahul Joshi       OS << "insertBits(tmp, ";
1192df3765bfSSheng     else
11933e24dd42SRahul Joshi       OS << "tmp = ";
11943e24dd42SRahul Joshi     OS << "fieldFromInstruction(insn, " << EF.Base << ", " << EF.Width << ')';
1195df3765bfSSheng     if (UseInsertBits)
11963e24dd42SRahul Joshi       OS << ", " << EF.Offset << ", " << EF.Width << ')';
1197df3765bfSSheng     else if (EF.Offset != 0)
11983e24dd42SRahul Joshi       OS << " << " << EF.Offset;
11993e24dd42SRahul Joshi     OS << ";\n";
1200df3765bfSSheng   }
1201df3765bfSSheng 
1202df3765bfSSheng   if (Decoder != "") {
1203df3765bfSSheng     OpHasCompleteDecoder = OpInfo.HasCompleteDecoder;
1204708567abSRahul Joshi     OS << Indent << "if (!Check(S, " << Decoder
12059a26f893SJames Y Knight        << "(MI, tmp, Address, Decoder))) { "
1206708567abSRahul Joshi        << (OpHasCompleteDecoder ? "" : "DecodeComplete = false; ")
1207df3765bfSSheng        << "return MCDisassembler::Fail; }\n";
1208df3765bfSSheng   } else {
1209df3765bfSSheng     OpHasCompleteDecoder = true;
1210708567abSRahul Joshi     OS << Indent << "MI.addOperand(MCOperand::createImm(tmp));\n";
1211df3765bfSSheng   }
1212df3765bfSSheng }
1213df3765bfSSheng 
1214708567abSRahul Joshi void FilterChooser::emitDecoder(raw_ostream &OS, indent Indent, unsigned Opc,
12153e24dd42SRahul Joshi                                 bool &HasCompleteDecoder) const {
1216df3765bfSSheng   HasCompleteDecoder = true;
1217df3765bfSSheng 
1218df3765bfSSheng   for (const auto &Op : Operands.find(Opc)->second) {
1219df3765bfSSheng     // If a custom instruction decoder was specified, use that.
1220df3765bfSSheng     if (Op.numFields() == 0 && !Op.Decoder.empty()) {
1221df3765bfSSheng       HasCompleteDecoder = Op.HasCompleteDecoder;
1222708567abSRahul Joshi       OS << Indent << "if (!Check(S, " << Op.Decoder
12239a26f893SJames Y Knight          << "(MI, insn, Address, Decoder))) { "
1224708567abSRahul Joshi          << (HasCompleteDecoder ? "" : "DecodeComplete = false; ")
1225df3765bfSSheng          << "return MCDisassembler::Fail; }\n";
1226df3765bfSSheng       break;
1227df3765bfSSheng     }
1228df3765bfSSheng 
1229df3765bfSSheng     bool OpHasCompleteDecoder;
12303e24dd42SRahul Joshi     emitBinaryParser(OS, Indent, Op, OpHasCompleteDecoder);
1231df3765bfSSheng     if (!OpHasCompleteDecoder)
1232df3765bfSSheng       HasCompleteDecoder = false;
1233df3765bfSSheng   }
1234df3765bfSSheng }
1235df3765bfSSheng 
1236b9079baaSPierre van Houtryve unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders, unsigned Opc,
1237df3765bfSSheng                                         bool &HasCompleteDecoder) const {
1238df3765bfSSheng   // Build up the predicate string.
1239df3765bfSSheng   SmallString<256> Decoder;
1240df3765bfSSheng   // FIXME: emitDecoder() function can take a buffer directly rather than
1241df3765bfSSheng   // a stream.
1242df3765bfSSheng   raw_svector_ostream S(Decoder);
1243708567abSRahul Joshi   emitDecoder(S, indent(4), Opc, HasCompleteDecoder);
1244df3765bfSSheng 
1245df3765bfSSheng   // Using the full decoder string as the key value here is a bit
1246df3765bfSSheng   // heavyweight, but is effective. If the string comparisons become a
1247df3765bfSSheng   // performance concern, we can implement a mangling of the predicate
1248df3765bfSSheng   // data easily enough with a map back to the actual string. That's
1249df3765bfSSheng   // overkill for now, though.
1250df3765bfSSheng 
1251df3765bfSSheng   // Make sure the predicate is in the table.
1252df3765bfSSheng   Decoders.insert(CachedHashString(Decoder));
1253df3765bfSSheng   // Now figure out the index for when we write out the table.
1254df3765bfSSheng   DecoderSet::const_iterator P = find(Decoders, Decoder.str());
1255df3765bfSSheng   return (unsigned)(P - Decoders.begin());
1256df3765bfSSheng }
1257df3765bfSSheng 
125845f3a5aaSFangrui Song // If ParenIfBinOp is true, print a surrounding () if Val uses && or ||.
125945f3a5aaSFangrui Song bool FilterChooser::emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
126045f3a5aaSFangrui Song                                           raw_ostream &OS) const {
1261e9492ccaSJason Eckhardt   if (const auto *D = dyn_cast<DefInit>(&Val)) {
126245f3a5aaSFangrui Song     if (!D->getDef()->isSubClassOf("SubtargetFeature"))
126345f3a5aaSFangrui Song       return true;
126445f3a5aaSFangrui Song     OS << "Bits[" << Emitter->PredicateNamespace << "::" << D->getAsString()
126545f3a5aaSFangrui Song        << "]";
126645f3a5aaSFangrui Song     return false;
126745f3a5aaSFangrui Song   }
1268e9492ccaSJason Eckhardt   if (const auto *D = dyn_cast<DagInit>(&Val)) {
126945f3a5aaSFangrui Song     std::string Op = D->getOperator()->getAsString();
127045f3a5aaSFangrui Song     if (Op == "not" && D->getNumArgs() == 1) {
127145f3a5aaSFangrui Song       OS << '!';
127245f3a5aaSFangrui Song       return emitPredicateMatchAux(*D->getArg(0), true, OS);
127345f3a5aaSFangrui Song     }
127445f3a5aaSFangrui Song     if ((Op == "any_of" || Op == "all_of") && D->getNumArgs() > 0) {
127545f3a5aaSFangrui Song       bool Paren = D->getNumArgs() > 1 && std::exchange(ParenIfBinOp, true);
127645f3a5aaSFangrui Song       if (Paren)
127745f3a5aaSFangrui Song         OS << '(';
127845f3a5aaSFangrui Song       ListSeparator LS(Op == "any_of" ? " || " : " && ");
127945f3a5aaSFangrui Song       for (auto *Arg : D->getArgs()) {
128045f3a5aaSFangrui Song         OS << LS;
128145f3a5aaSFangrui Song         if (emitPredicateMatchAux(*Arg, ParenIfBinOp, OS))
128245f3a5aaSFangrui Song           return true;
128345f3a5aaSFangrui Song       }
128445f3a5aaSFangrui Song       if (Paren)
128545f3a5aaSFangrui Song         OS << ')';
128645f3a5aaSFangrui Song       return false;
128745f3a5aaSFangrui Song     }
128845f3a5aaSFangrui Song   }
128945f3a5aaSFangrui Song   return true;
129045f3a5aaSFangrui Song }
129145f3a5aaSFangrui Song 
12923e24dd42SRahul Joshi bool FilterChooser::emitPredicateMatch(raw_ostream &OS, unsigned Opc) const {
129362e2c7fbSRahul Joshi   const ListInit *Predicates =
1294df3765bfSSheng       AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
1295df3765bfSSheng   bool IsFirstEmission = true;
1296df3765bfSSheng   for (unsigned i = 0; i < Predicates->size(); ++i) {
12972bb3621fSRahul Joshi     const Record *Pred = Predicates->getElementAsRecord(i);
1298df3765bfSSheng     if (!Pred->getValue("AssemblerMatcherPredicate"))
1299df3765bfSSheng       continue;
1300df3765bfSSheng 
1301df3765bfSSheng     if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
1302df3765bfSSheng       continue;
1303df3765bfSSheng 
1304df3765bfSSheng     if (!IsFirstEmission)
13053e24dd42SRahul Joshi       OS << " && ";
130645f3a5aaSFangrui Song     if (emitPredicateMatchAux(*Pred->getValueAsDag("AssemblerCondDag"),
13073e24dd42SRahul Joshi                               Predicates->size() > 1, OS))
1308df3765bfSSheng       PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
1309df3765bfSSheng     IsFirstEmission = false;
1310df3765bfSSheng   }
1311df3765bfSSheng   return !Predicates->empty();
1312df3765bfSSheng }
1313df3765bfSSheng 
1314df3765bfSSheng bool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const {
13152bb3621fSRahul Joshi   const ListInit *Predicates =
1316df3765bfSSheng       AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
1317df3765bfSSheng   for (unsigned i = 0; i < Predicates->size(); ++i) {
13182bb3621fSRahul Joshi     const Record *Pred = Predicates->getElementAsRecord(i);
1319df3765bfSSheng     if (!Pred->getValue("AssemblerMatcherPredicate"))
1320df3765bfSSheng       continue;
1321df3765bfSSheng 
1322df3765bfSSheng     if (isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
1323df3765bfSSheng       return true;
1324df3765bfSSheng   }
1325df3765bfSSheng   return false;
1326df3765bfSSheng }
1327df3765bfSSheng 
1328df3765bfSSheng unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo,
1329df3765bfSSheng                                           StringRef Predicate) const {
1330df3765bfSSheng   // Using the full predicate string as the key value here is a bit
1331df3765bfSSheng   // heavyweight, but is effective. If the string comparisons become a
1332df3765bfSSheng   // performance concern, we can implement a mangling of the predicate
1333df3765bfSSheng   // data easily enough with a map back to the actual string. That's
1334df3765bfSSheng   // overkill for now, though.
1335df3765bfSSheng 
1336df3765bfSSheng   // Make sure the predicate is in the table.
1337df3765bfSSheng   TableInfo.Predicates.insert(CachedHashString(Predicate));
1338df3765bfSSheng   // Now figure out the index for when we write out the table.
1339df3765bfSSheng   PredicateSet::const_iterator P = find(TableInfo.Predicates, Predicate);
1340df3765bfSSheng   return (unsigned)(P - TableInfo.Predicates.begin());
1341df3765bfSSheng }
1342df3765bfSSheng 
1343df3765bfSSheng void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo,
1344df3765bfSSheng                                             unsigned Opc) const {
1345df3765bfSSheng   if (!doesOpcodeNeedPredicate(Opc))
1346df3765bfSSheng     return;
1347df3765bfSSheng 
1348df3765bfSSheng   // Build up the predicate string.
1349df3765bfSSheng   SmallString<256> Predicate;
1350df3765bfSSheng   // FIXME: emitPredicateMatch() functions can take a buffer directly rather
1351df3765bfSSheng   // than a stream.
1352df3765bfSSheng   raw_svector_ostream PS(Predicate);
13533e24dd42SRahul Joshi   emitPredicateMatch(PS, Opc);
1354df3765bfSSheng 
1355df3765bfSSheng   // Figure out the index into the predicate table for the predicate just
1356df3765bfSSheng   // computed.
1357df3765bfSSheng   unsigned PIdx = getPredicateIndex(TableInfo, PS.str());
1358df3765bfSSheng   SmallString<16> PBytes;
1359df3765bfSSheng   raw_svector_ostream S(PBytes);
1360df3765bfSSheng   encodeULEB128(PIdx, S);
1361df3765bfSSheng 
1362df3765bfSSheng   TableInfo.Table.push_back(MCD::OPC_CheckPredicate);
1363e9492ccaSJason Eckhardt   // Predicate index.
1364e9492ccaSJason Eckhardt   for (const auto PB : PBytes)
1365e9492ccaSJason Eckhardt     TableInfo.Table.push_back(PB);
1366df3765bfSSheng   // Push location for NumToSkip backpatching.
1367df3765bfSSheng   TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
1368df3765bfSSheng   TableInfo.Table.push_back(0);
1369df3765bfSSheng   TableInfo.Table.push_back(0);
1370df3765bfSSheng   TableInfo.Table.push_back(0);
1371df3765bfSSheng }
1372df3765bfSSheng 
1373df3765bfSSheng void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
1374df3765bfSSheng                                            unsigned Opc) const {
1375e9492ccaSJason Eckhardt   const Record *EncodingDef = AllInstructions[Opc].EncodingDef;
1376e9492ccaSJason Eckhardt   const RecordVal *RV = EncodingDef->getValue("SoftFail");
137762e2c7fbSRahul Joshi   const BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
1378df3765bfSSheng 
1379b9079baaSPierre van Houtryve   if (!SFBits)
1380b9079baaSPierre van Houtryve     return;
138162e2c7fbSRahul Joshi   const BitsInit *InstBits = EncodingDef->getValueAsBitsInit("Inst");
1382df3765bfSSheng 
1383df3765bfSSheng   APInt PositiveMask(BitWidth, 0ULL);
1384df3765bfSSheng   APInt NegativeMask(BitWidth, 0ULL);
1385df3765bfSSheng   for (unsigned i = 0; i < BitWidth; ++i) {
1386df3765bfSSheng     bit_value_t B = bitFromBits(*SFBits, i);
1387df3765bfSSheng     bit_value_t IB = bitFromBits(*InstBits, i);
1388df3765bfSSheng 
1389b9079baaSPierre van Houtryve     if (B != BIT_TRUE)
1390b9079baaSPierre van Houtryve       continue;
1391df3765bfSSheng 
1392df3765bfSSheng     switch (IB) {
1393df3765bfSSheng     case BIT_FALSE:
1394df3765bfSSheng       // The bit is meant to be false, so emit a check to see if it is true.
1395df3765bfSSheng       PositiveMask.setBit(i);
1396df3765bfSSheng       break;
1397df3765bfSSheng     case BIT_TRUE:
1398df3765bfSSheng       // The bit is meant to be true, so emit a check to see if it is false.
1399df3765bfSSheng       NegativeMask.setBit(i);
1400df3765bfSSheng       break;
1401df3765bfSSheng     default:
1402df3765bfSSheng       // The bit is not set; this must be an error!
1403df3765bfSSheng       errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in "
1404df3765bfSSheng              << AllInstructions[Opc] << " is set but Inst{" << i
1405df3765bfSSheng              << "} is unset!\n"
1406df3765bfSSheng              << "  - You can only mark a bit as SoftFail if it is fully defined"
1407df3765bfSSheng              << " (1/0 - not '?') in Inst\n";
1408df3765bfSSheng       return;
1409df3765bfSSheng     }
1410df3765bfSSheng   }
1411df3765bfSSheng 
1412df3765bfSSheng   bool NeedPositiveMask = PositiveMask.getBoolValue();
1413df3765bfSSheng   bool NeedNegativeMask = NegativeMask.getBoolValue();
1414df3765bfSSheng 
1415df3765bfSSheng   if (!NeedPositiveMask && !NeedNegativeMask)
1416df3765bfSSheng     return;
1417df3765bfSSheng 
1418df3765bfSSheng   TableInfo.Table.push_back(MCD::OPC_SoftFail);
1419df3765bfSSheng 
1420df3765bfSSheng   SmallString<16> MaskBytes;
1421df3765bfSSheng   raw_svector_ostream S(MaskBytes);
1422df3765bfSSheng   if (NeedPositiveMask) {
1423df3765bfSSheng     encodeULEB128(PositiveMask.getZExtValue(), S);
1424df3765bfSSheng     for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i)
1425df3765bfSSheng       TableInfo.Table.push_back(MaskBytes[i]);
1426df3765bfSSheng   } else
1427df3765bfSSheng     TableInfo.Table.push_back(0);
1428df3765bfSSheng   if (NeedNegativeMask) {
1429df3765bfSSheng     MaskBytes.clear();
1430df3765bfSSheng     encodeULEB128(NegativeMask.getZExtValue(), S);
1431df3765bfSSheng     for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i)
1432df3765bfSSheng       TableInfo.Table.push_back(MaskBytes[i]);
1433df3765bfSSheng   } else
1434df3765bfSSheng     TableInfo.Table.push_back(0);
1435df3765bfSSheng }
1436df3765bfSSheng 
1437df3765bfSSheng // Emits table entries to decode the singleton.
1438df3765bfSSheng void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1439df3765bfSSheng                                             EncodingIDAndOpcode Opc) const {
1440df3765bfSSheng   std::vector<unsigned> StartBits;
1441df3765bfSSheng   std::vector<unsigned> EndBits;
1442df3765bfSSheng   std::vector<uint64_t> FieldVals;
1443df3765bfSSheng   insn_t Insn;
1444df3765bfSSheng   insnWithID(Insn, Opc.EncodingID);
1445df3765bfSSheng 
1446df3765bfSSheng   // Look for islands of undecoded bits of the singleton.
1447df3765bfSSheng   getIslands(StartBits, EndBits, FieldVals, Insn);
1448df3765bfSSheng 
1449df3765bfSSheng   unsigned Size = StartBits.size();
1450df3765bfSSheng 
1451df3765bfSSheng   // Emit the predicate table entry if one is needed.
1452df3765bfSSheng   emitPredicateTableEntry(TableInfo, Opc.EncodingID);
1453df3765bfSSheng 
1454df3765bfSSheng   // Check any additional encoding fields needed.
1455df3765bfSSheng   for (unsigned I = Size; I != 0; --I) {
1456df3765bfSSheng     unsigned NumBits = EndBits[I - 1] - StartBits[I - 1] + 1;
1457d93f850cSJason Eckhardt     assert((NumBits < (1u << 8)) && "NumBits overflowed uint8 table entry!");
1458df3765bfSSheng     TableInfo.Table.push_back(MCD::OPC_CheckField);
1459d93f850cSJason Eckhardt     uint8_t Buffer[16], *P;
1460d93f850cSJason Eckhardt     encodeULEB128(StartBits[I - 1], Buffer);
1461d93f850cSJason Eckhardt     for (P = Buffer; *P >= 128; ++P)
1462d93f850cSJason Eckhardt       TableInfo.Table.push_back(*P);
1463d93f850cSJason Eckhardt     TableInfo.Table.push_back(*P);
1464df3765bfSSheng     TableInfo.Table.push_back(NumBits);
1465df3765bfSSheng     encodeULEB128(FieldVals[I - 1], Buffer);
1466d93f850cSJason Eckhardt     for (P = Buffer; *P >= 128; ++P)
1467d93f850cSJason Eckhardt       TableInfo.Table.push_back(*P);
1468d93f850cSJason Eckhardt     TableInfo.Table.push_back(*P);
1469df3765bfSSheng     // Push location for NumToSkip backpatching.
1470df3765bfSSheng     TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
1471df3765bfSSheng     // The fixup is always 24-bits, so go ahead and allocate the space
1472df3765bfSSheng     // in the table so all our relative position calculations work OK even
1473df3765bfSSheng     // before we fully resolve the real value here.
1474df3765bfSSheng     TableInfo.Table.push_back(0);
1475df3765bfSSheng     TableInfo.Table.push_back(0);
1476df3765bfSSheng     TableInfo.Table.push_back(0);
1477df3765bfSSheng   }
1478df3765bfSSheng 
1479df3765bfSSheng   // Check for soft failure of the match.
1480df3765bfSSheng   emitSoftFailTableEntry(TableInfo, Opc.EncodingID);
1481df3765bfSSheng 
1482df3765bfSSheng   bool HasCompleteDecoder;
1483df3765bfSSheng   unsigned DIdx =
1484df3765bfSSheng       getDecoderIndex(TableInfo.Decoders, Opc.EncodingID, HasCompleteDecoder);
1485df3765bfSSheng 
1486df3765bfSSheng   // Produce OPC_Decode or OPC_TryDecode opcode based on the information
1487df3765bfSSheng   // whether the instruction decoder is complete or not. If it is complete
1488df3765bfSSheng   // then it handles all possible values of remaining variable/unfiltered bits
1489df3765bfSSheng   // and for any value can determine if the bitpattern is a valid instruction
1490df3765bfSSheng   // or not. This means OPC_Decode will be the final step in the decoding
1491df3765bfSSheng   // process. If it is not complete, then the Fail return code from the
1492df3765bfSSheng   // decoder method indicates that additional processing should be done to see
1493df3765bfSSheng   // if there is any other instruction that also matches the bitpattern and
1494df3765bfSSheng   // can decode it.
1495b9079baaSPierre van Houtryve   TableInfo.Table.push_back(HasCompleteDecoder ? MCD::OPC_Decode
1496b9079baaSPierre van Houtryve                                                : MCD::OPC_TryDecode);
1497df3765bfSSheng   NumEncodingsSupported++;
1498df3765bfSSheng   uint8_t Buffer[16], *p;
1499df3765bfSSheng   encodeULEB128(Opc.Opcode, Buffer);
1500df3765bfSSheng   for (p = Buffer; *p >= 128; ++p)
1501df3765bfSSheng     TableInfo.Table.push_back(*p);
1502df3765bfSSheng   TableInfo.Table.push_back(*p);
1503df3765bfSSheng 
1504df3765bfSSheng   SmallString<16> Bytes;
1505df3765bfSSheng   raw_svector_ostream S(Bytes);
1506df3765bfSSheng   encodeULEB128(DIdx, S);
1507df3765bfSSheng 
1508e9492ccaSJason Eckhardt   // Decoder index.
1509e9492ccaSJason Eckhardt   for (const auto B : Bytes)
1510e9492ccaSJason Eckhardt     TableInfo.Table.push_back(B);
1511df3765bfSSheng 
1512df3765bfSSheng   if (!HasCompleteDecoder) {
1513df3765bfSSheng     // Push location for NumToSkip backpatching.
1514df3765bfSSheng     TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
1515df3765bfSSheng     // Allocate the space for the fixup.
1516df3765bfSSheng     TableInfo.Table.push_back(0);
1517df3765bfSSheng     TableInfo.Table.push_back(0);
1518df3765bfSSheng     TableInfo.Table.push_back(0);
1519df3765bfSSheng   }
1520df3765bfSSheng }
1521df3765bfSSheng 
1522df3765bfSSheng // Emits table entries to decode the singleton, and then to decode the rest.
1523df3765bfSSheng void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1524df3765bfSSheng                                             const Filter &Best) const {
1525df3765bfSSheng   EncodingIDAndOpcode Opc = Best.getSingletonOpc();
1526df3765bfSSheng 
1527df3765bfSSheng   // complex singletons need predicate checks from the first singleton
1528df3765bfSSheng   // to refer forward to the variable filterchooser that follows.
1529df3765bfSSheng   TableInfo.FixupStack.emplace_back();
1530df3765bfSSheng 
1531df3765bfSSheng   emitSingletonTableEntry(TableInfo, Opc);
1532df3765bfSSheng 
1533df3765bfSSheng   resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
1534df3765bfSSheng                      TableInfo.Table.size());
1535df3765bfSSheng   TableInfo.FixupStack.pop_back();
1536df3765bfSSheng 
1537df3765bfSSheng   Best.getVariableFC().emitTableEntries(TableInfo);
1538df3765bfSSheng }
1539df3765bfSSheng 
1540df3765bfSSheng // Assign a single filter and run with it.  Top level API client can initialize
1541df3765bfSSheng // with a single filter to start the filtering process.
1542df3765bfSSheng void FilterChooser::runSingleFilter(unsigned startBit, unsigned numBit,
1543df3765bfSSheng                                     bool mixed) {
1544df3765bfSSheng   Filters.clear();
1545df3765bfSSheng   Filters.emplace_back(*this, startBit, numBit, true);
1546df3765bfSSheng   BestIndex = 0; // Sole Filter instance to choose from.
1547df3765bfSSheng   bestFilter().recurse();
1548df3765bfSSheng }
1549df3765bfSSheng 
1550df3765bfSSheng // reportRegion is a helper function for filterProcessor to mark a region as
1551df3765bfSSheng // eligible for use as a filter region.
1552df3765bfSSheng void FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit,
1553df3765bfSSheng                                  unsigned BitIndex, bool AllowMixed) {
1554df3765bfSSheng   if (RA == ATTR_MIXED && AllowMixed)
1555df3765bfSSheng     Filters.emplace_back(*this, StartBit, BitIndex - StartBit, true);
1556df3765bfSSheng   else if (RA == ATTR_ALL_SET && !AllowMixed)
1557df3765bfSSheng     Filters.emplace_back(*this, StartBit, BitIndex - StartBit, false);
1558df3765bfSSheng }
1559df3765bfSSheng 
1560df3765bfSSheng // FilterProcessor scans the well-known encoding bits of the instructions and
1561df3765bfSSheng // builds up a list of candidate filters.  It chooses the best filter and
1562df3765bfSSheng // recursively descends down the decoding tree.
1563df3765bfSSheng bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
1564df3765bfSSheng   Filters.clear();
1565df3765bfSSheng   BestIndex = -1;
1566df3765bfSSheng   unsigned numInstructions = Opcodes.size();
1567df3765bfSSheng 
1568df3765bfSSheng   assert(numInstructions && "Filter created with no instructions");
1569df3765bfSSheng 
1570df3765bfSSheng   // No further filtering is necessary.
1571df3765bfSSheng   if (numInstructions == 1)
1572df3765bfSSheng     return true;
1573df3765bfSSheng 
1574df3765bfSSheng   // Heuristics.  See also doFilter()'s "Heuristics" comment when num of
1575df3765bfSSheng   // instructions is 3.
1576df3765bfSSheng   if (AllowMixed && !Greedy) {
1577df3765bfSSheng     assert(numInstructions == 3);
1578df3765bfSSheng 
1579e9492ccaSJason Eckhardt     for (const auto &Opcode : Opcodes) {
1580df3765bfSSheng       std::vector<unsigned> StartBits;
1581df3765bfSSheng       std::vector<unsigned> EndBits;
1582df3765bfSSheng       std::vector<uint64_t> FieldVals;
1583df3765bfSSheng       insn_t Insn;
1584df3765bfSSheng 
1585df3765bfSSheng       insnWithID(Insn, Opcode.EncodingID);
1586df3765bfSSheng 
1587df3765bfSSheng       // Look for islands of undecoded bits of any instruction.
1588df3765bfSSheng       if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) {
1589df3765bfSSheng         // Found an instruction with island(s).  Now just assign a filter.
1590df3765bfSSheng         runSingleFilter(StartBits[0], EndBits[0] - StartBits[0] + 1, true);
1591df3765bfSSheng         return true;
1592df3765bfSSheng       }
1593df3765bfSSheng     }
1594df3765bfSSheng   }
1595df3765bfSSheng 
1596df3765bfSSheng   unsigned BitIndex;
1597df3765bfSSheng 
1598df3765bfSSheng   // We maintain BIT_WIDTH copies of the bitAttrs automaton.
1599df3765bfSSheng   // The automaton consumes the corresponding bit from each
1600df3765bfSSheng   // instruction.
1601df3765bfSSheng   //
1602df3765bfSSheng   //   Input symbols: 0, 1, and _ (unset).
1603df3765bfSSheng   //   States:        NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED.
1604df3765bfSSheng   //   Initial state: NONE.
1605df3765bfSSheng   //
1606df3765bfSSheng   // (NONE) ------- [01] -> (ALL_SET)
1607df3765bfSSheng   // (NONE) ------- _ ----> (ALL_UNSET)
1608df3765bfSSheng   // (ALL_SET) ---- [01] -> (ALL_SET)
1609df3765bfSSheng   // (ALL_SET) ---- _ ----> (MIXED)
1610df3765bfSSheng   // (ALL_UNSET) -- [01] -> (MIXED)
1611df3765bfSSheng   // (ALL_UNSET) -- _ ----> (ALL_UNSET)
1612df3765bfSSheng   // (MIXED) ------ . ----> (MIXED)
1613df3765bfSSheng   // (FILTERED)---- . ----> (FILTERED)
1614df3765bfSSheng 
1615df3765bfSSheng   std::vector<bitAttr_t> bitAttrs;
1616df3765bfSSheng 
1617df3765bfSSheng   // FILTERED bit positions provide no entropy and are not worthy of pursuing.
1618df3765bfSSheng   // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position.
1619df3765bfSSheng   for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex)
1620df3765bfSSheng     if (FilterBitValues[BitIndex] == BIT_TRUE ||
1621df3765bfSSheng         FilterBitValues[BitIndex] == BIT_FALSE)
1622df3765bfSSheng       bitAttrs.push_back(ATTR_FILTERED);
1623df3765bfSSheng     else
1624df3765bfSSheng       bitAttrs.push_back(ATTR_NONE);
1625df3765bfSSheng 
1626e9492ccaSJason Eckhardt   for (const auto &OpcPair : Opcodes) {
1627df3765bfSSheng     insn_t insn;
1628df3765bfSSheng 
1629e9492ccaSJason Eckhardt     insnWithID(insn, OpcPair.EncodingID);
1630df3765bfSSheng 
1631df3765bfSSheng     for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
1632df3765bfSSheng       switch (bitAttrs[BitIndex]) {
1633df3765bfSSheng       case ATTR_NONE:
1634df3765bfSSheng         if (insn[BitIndex] == BIT_UNSET)
1635df3765bfSSheng           bitAttrs[BitIndex] = ATTR_ALL_UNSET;
1636df3765bfSSheng         else
1637df3765bfSSheng           bitAttrs[BitIndex] = ATTR_ALL_SET;
1638df3765bfSSheng         break;
1639df3765bfSSheng       case ATTR_ALL_SET:
1640df3765bfSSheng         if (insn[BitIndex] == BIT_UNSET)
1641df3765bfSSheng           bitAttrs[BitIndex] = ATTR_MIXED;
1642df3765bfSSheng         break;
1643df3765bfSSheng       case ATTR_ALL_UNSET:
1644df3765bfSSheng         if (insn[BitIndex] != BIT_UNSET)
1645df3765bfSSheng           bitAttrs[BitIndex] = ATTR_MIXED;
1646df3765bfSSheng         break;
1647df3765bfSSheng       case ATTR_MIXED:
1648df3765bfSSheng       case ATTR_FILTERED:
1649df3765bfSSheng         break;
1650df3765bfSSheng       }
1651df3765bfSSheng     }
1652df3765bfSSheng   }
1653df3765bfSSheng 
1654df3765bfSSheng   // The regionAttr automaton consumes the bitAttrs automatons' state,
1655df3765bfSSheng   // lowest-to-highest.
1656df3765bfSSheng   //
1657df3765bfSSheng   //   Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed)
1658df3765bfSSheng   //   States:        NONE, ALL_SET, MIXED
1659df3765bfSSheng   //   Initial state: NONE
1660df3765bfSSheng   //
1661df3765bfSSheng   // (NONE) ----- F --> (NONE)
1662df3765bfSSheng   // (NONE) ----- S --> (ALL_SET)     ; and set region start
1663df3765bfSSheng   // (NONE) ----- U --> (NONE)
1664df3765bfSSheng   // (NONE) ----- M --> (MIXED)       ; and set region start
1665df3765bfSSheng   // (ALL_SET) -- F --> (NONE)        ; and report an ALL_SET region
1666df3765bfSSheng   // (ALL_SET) -- S --> (ALL_SET)
1667df3765bfSSheng   // (ALL_SET) -- U --> (NONE)        ; and report an ALL_SET region
1668df3765bfSSheng   // (ALL_SET) -- M --> (MIXED)       ; and report an ALL_SET region
1669df3765bfSSheng   // (MIXED) ---- F --> (NONE)        ; and report a MIXED region
1670df3765bfSSheng   // (MIXED) ---- S --> (ALL_SET)     ; and report a MIXED region
1671df3765bfSSheng   // (MIXED) ---- U --> (NONE)        ; and report a MIXED region
1672df3765bfSSheng   // (MIXED) ---- M --> (MIXED)
1673df3765bfSSheng 
1674df3765bfSSheng   bitAttr_t RA = ATTR_NONE;
1675df3765bfSSheng   unsigned StartBit = 0;
1676df3765bfSSheng 
1677df3765bfSSheng   for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
1678df3765bfSSheng     bitAttr_t bitAttr = bitAttrs[BitIndex];
1679df3765bfSSheng 
1680df3765bfSSheng     assert(bitAttr != ATTR_NONE && "Bit without attributes");
1681df3765bfSSheng 
1682df3765bfSSheng     switch (RA) {
1683df3765bfSSheng     case ATTR_NONE:
1684df3765bfSSheng       switch (bitAttr) {
1685df3765bfSSheng       case ATTR_FILTERED:
1686df3765bfSSheng         break;
1687df3765bfSSheng       case ATTR_ALL_SET:
1688df3765bfSSheng         StartBit = BitIndex;
1689df3765bfSSheng         RA = ATTR_ALL_SET;
1690df3765bfSSheng         break;
1691df3765bfSSheng       case ATTR_ALL_UNSET:
1692df3765bfSSheng         break;
1693df3765bfSSheng       case ATTR_MIXED:
1694df3765bfSSheng         StartBit = BitIndex;
1695df3765bfSSheng         RA = ATTR_MIXED;
1696df3765bfSSheng         break;
1697df3765bfSSheng       default:
1698df3765bfSSheng         llvm_unreachable("Unexpected bitAttr!");
1699df3765bfSSheng       }
1700df3765bfSSheng       break;
1701df3765bfSSheng     case ATTR_ALL_SET:
1702df3765bfSSheng       switch (bitAttr) {
1703df3765bfSSheng       case ATTR_FILTERED:
1704df3765bfSSheng         reportRegion(RA, StartBit, BitIndex, AllowMixed);
1705df3765bfSSheng         RA = ATTR_NONE;
1706df3765bfSSheng         break;
1707df3765bfSSheng       case ATTR_ALL_SET:
1708df3765bfSSheng         break;
1709df3765bfSSheng       case ATTR_ALL_UNSET:
1710df3765bfSSheng         reportRegion(RA, StartBit, BitIndex, AllowMixed);
1711df3765bfSSheng         RA = ATTR_NONE;
1712df3765bfSSheng         break;
1713df3765bfSSheng       case ATTR_MIXED:
1714df3765bfSSheng         reportRegion(RA, StartBit, BitIndex, AllowMixed);
1715df3765bfSSheng         StartBit = BitIndex;
1716df3765bfSSheng         RA = ATTR_MIXED;
1717df3765bfSSheng         break;
1718df3765bfSSheng       default:
1719df3765bfSSheng         llvm_unreachable("Unexpected bitAttr!");
1720df3765bfSSheng       }
1721df3765bfSSheng       break;
1722df3765bfSSheng     case ATTR_MIXED:
1723df3765bfSSheng       switch (bitAttr) {
1724df3765bfSSheng       case ATTR_FILTERED:
1725df3765bfSSheng         reportRegion(RA, StartBit, BitIndex, AllowMixed);
1726df3765bfSSheng         StartBit = BitIndex;
1727df3765bfSSheng         RA = ATTR_NONE;
1728df3765bfSSheng         break;
1729df3765bfSSheng       case ATTR_ALL_SET:
1730df3765bfSSheng         reportRegion(RA, StartBit, BitIndex, AllowMixed);
1731df3765bfSSheng         StartBit = BitIndex;
1732df3765bfSSheng         RA = ATTR_ALL_SET;
1733df3765bfSSheng         break;
1734df3765bfSSheng       case ATTR_ALL_UNSET:
1735df3765bfSSheng         reportRegion(RA, StartBit, BitIndex, AllowMixed);
1736df3765bfSSheng         RA = ATTR_NONE;
1737df3765bfSSheng         break;
1738df3765bfSSheng       case ATTR_MIXED:
1739df3765bfSSheng         break;
1740df3765bfSSheng       default:
1741df3765bfSSheng         llvm_unreachable("Unexpected bitAttr!");
1742df3765bfSSheng       }
1743df3765bfSSheng       break;
1744df3765bfSSheng     case ATTR_ALL_UNSET:
1745df3765bfSSheng       llvm_unreachable("regionAttr state machine has no ATTR_UNSET state");
1746df3765bfSSheng     case ATTR_FILTERED:
1747df3765bfSSheng       llvm_unreachable("regionAttr state machine has no ATTR_FILTERED state");
1748df3765bfSSheng     }
1749df3765bfSSheng   }
1750df3765bfSSheng 
1751df3765bfSSheng   // At the end, if we're still in ALL_SET or MIXED states, report a region
1752df3765bfSSheng   switch (RA) {
1753df3765bfSSheng   case ATTR_NONE:
1754df3765bfSSheng     break;
1755df3765bfSSheng   case ATTR_FILTERED:
1756df3765bfSSheng     break;
1757df3765bfSSheng   case ATTR_ALL_SET:
1758df3765bfSSheng     reportRegion(RA, StartBit, BitIndex, AllowMixed);
1759df3765bfSSheng     break;
1760df3765bfSSheng   case ATTR_ALL_UNSET:
1761df3765bfSSheng     break;
1762df3765bfSSheng   case ATTR_MIXED:
1763df3765bfSSheng     reportRegion(RA, StartBit, BitIndex, AllowMixed);
1764df3765bfSSheng     break;
1765df3765bfSSheng   }
1766df3765bfSSheng 
1767df3765bfSSheng   // We have finished with the filter processings.  Now it's time to choose
1768df3765bfSSheng   // the best performing filter.
1769df3765bfSSheng   BestIndex = 0;
1770df3765bfSSheng   bool AllUseless = true;
1771df3765bfSSheng   unsigned BestScore = 0;
1772df3765bfSSheng 
1773e9492ccaSJason Eckhardt   for (const auto &[Idx, Filter] : enumerate(Filters)) {
1774e9492ccaSJason Eckhardt     unsigned Usefulness = Filter.usefulness();
1775df3765bfSSheng 
1776df3765bfSSheng     if (Usefulness)
1777df3765bfSSheng       AllUseless = false;
1778df3765bfSSheng 
1779df3765bfSSheng     if (Usefulness > BestScore) {
1780e9492ccaSJason Eckhardt       BestIndex = Idx;
1781df3765bfSSheng       BestScore = Usefulness;
1782df3765bfSSheng     }
1783df3765bfSSheng   }
1784df3765bfSSheng 
1785df3765bfSSheng   if (!AllUseless)
1786df3765bfSSheng     bestFilter().recurse();
1787df3765bfSSheng 
1788df3765bfSSheng   return !AllUseless;
1789df3765bfSSheng } // end of FilterChooser::filterProcessor(bool)
1790df3765bfSSheng 
1791df3765bfSSheng // Decides on the best configuration of filter(s) to use in order to decode
1792df3765bfSSheng // the instructions.  A conflict of instructions may occur, in which case we
1793df3765bfSSheng // dump the conflict set to the standard error.
1794df3765bfSSheng void FilterChooser::doFilter() {
1795df3765bfSSheng   unsigned Num = Opcodes.size();
1796df3765bfSSheng   assert(Num && "FilterChooser created with no instructions");
1797df3765bfSSheng 
1798df3765bfSSheng   // Try regions of consecutive known bit values first.
1799df3765bfSSheng   if (filterProcessor(false))
1800df3765bfSSheng     return;
1801df3765bfSSheng 
1802df3765bfSSheng   // Then regions of mixed bits (both known and unitialized bit values allowed).
1803df3765bfSSheng   if (filterProcessor(true))
1804df3765bfSSheng     return;
1805df3765bfSSheng 
1806df3765bfSSheng   // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where
1807df3765bfSSheng   // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a
1808df3765bfSSheng   // well-known encoding pattern.  In such case, we backtrack and scan for the
1809df3765bfSSheng   // the very first consecutive ATTR_ALL_SET region and assign a filter to it.
1810df3765bfSSheng   if (Num == 3 && filterProcessor(true, false))
1811df3765bfSSheng     return;
1812df3765bfSSheng 
1813df3765bfSSheng   // If we come to here, the instruction decoding has failed.
1814df3765bfSSheng   // Set the BestIndex to -1 to indicate so.
1815df3765bfSSheng   BestIndex = -1;
1816df3765bfSSheng }
1817df3765bfSSheng 
1818df3765bfSSheng // emitTableEntries - Emit state machine entries to decode our share of
1819df3765bfSSheng // instructions.
1820df3765bfSSheng void FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const {
1821df3765bfSSheng   if (Opcodes.size() == 1) {
1822df3765bfSSheng     // There is only one instruction in the set, which is great!
1823df3765bfSSheng     // Call emitSingletonDecoder() to see whether there are any remaining
1824df3765bfSSheng     // encodings bits.
1825df3765bfSSheng     emitSingletonTableEntry(TableInfo, Opcodes[0]);
1826df3765bfSSheng     return;
1827df3765bfSSheng   }
1828df3765bfSSheng 
1829df3765bfSSheng   // Choose the best filter to do the decodings!
1830df3765bfSSheng   if (BestIndex != -1) {
1831df3765bfSSheng     const Filter &Best = Filters[BestIndex];
1832df3765bfSSheng     if (Best.getNumFiltered() == 1)
1833df3765bfSSheng       emitSingletonTableEntry(TableInfo, Best);
1834df3765bfSSheng     else
1835df3765bfSSheng       Best.emitTableEntry(TableInfo);
1836df3765bfSSheng     return;
1837df3765bfSSheng   }
1838df3765bfSSheng 
1839df3765bfSSheng   // We don't know how to decode these instructions!  Dump the
1840df3765bfSSheng   // conflict set and bail.
1841df3765bfSSheng 
1842df3765bfSSheng   // Print out useful conflict information for postmortem analysis.
1843df3765bfSSheng   errs() << "Decoding Conflict:\n";
1844df3765bfSSheng 
1845df3765bfSSheng   dumpStack(errs(), "\t\t");
1846df3765bfSSheng 
1847df3765bfSSheng   for (auto Opcode : Opcodes) {
1848df3765bfSSheng     errs() << '\t';
1849df3765bfSSheng     emitNameWithID(errs(), Opcode.EncodingID);
1850df3765bfSSheng     errs() << " ";
1851df3765bfSSheng     dumpBits(
1852df3765bfSSheng         errs(),
1853df3765bfSSheng         getBitsField(*AllInstructions[Opcode.EncodingID].EncodingDef, "Inst"));
1854df3765bfSSheng     errs() << '\n';
1855df3765bfSSheng   }
1856df3765bfSSheng }
1857df3765bfSSheng 
1858bdf02249SRahul Joshi static std::string findOperandDecoderMethod(const Record *Record) {
1859df3765bfSSheng   std::string Decoder;
1860df3765bfSSheng 
1861bdf02249SRahul Joshi   const RecordVal *DecoderString = Record->getValue("DecoderMethod");
18622bb3621fSRahul Joshi   const StringInit *String =
1863b9079baaSPierre van Houtryve       DecoderString ? dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
1864df3765bfSSheng   if (String) {
1865df3765bfSSheng     Decoder = std::string(String->getValue());
1866df3765bfSSheng     if (!Decoder.empty())
1867df3765bfSSheng       return Decoder;
1868df3765bfSSheng   }
1869df3765bfSSheng 
1870df3765bfSSheng   if (Record->isSubClassOf("RegisterOperand"))
1871a46d60adSMax Beck-Jones     // Allows use of a DecoderMethod in referenced RegisterClass if set.
1872a46d60adSMax Beck-Jones     return findOperandDecoderMethod(Record->getValueAsDef("RegClass"));
1873df3765bfSSheng 
1874df3765bfSSheng   if (Record->isSubClassOf("RegisterClass")) {
1875df3765bfSSheng     Decoder = "Decode" + Record->getName().str() + "RegisterClass";
1876df3765bfSSheng   } else if (Record->isSubClassOf("PointerLikeRegClass")) {
1877df3765bfSSheng     Decoder = "DecodePointerLikeRegClass" +
1878df3765bfSSheng               utostr(Record->getValueAsInt("RegClassKind"));
1879df3765bfSSheng   }
1880df3765bfSSheng 
1881df3765bfSSheng   return Decoder;
1882df3765bfSSheng }
1883df3765bfSSheng 
1884bdf02249SRahul Joshi OperandInfo getOpInfo(const Record *TypeRecord) {
1885df3765bfSSheng   std::string Decoder = findOperandDecoderMethod(TypeRecord);
1886df3765bfSSheng 
1887bdf02249SRahul Joshi   const RecordVal *HasCompleteDecoderVal =
1888bdf02249SRahul Joshi       TypeRecord->getValue("hasCompleteDecoder");
188962e2c7fbSRahul Joshi   const BitInit *HasCompleteDecoderBit =
1890df3765bfSSheng       HasCompleteDecoderVal
1891df3765bfSSheng           ? dyn_cast<BitInit>(HasCompleteDecoderVal->getValue())
1892df3765bfSSheng           : nullptr;
1893df3765bfSSheng   bool HasCompleteDecoder =
1894df3765bfSSheng       HasCompleteDecoderBit ? HasCompleteDecoderBit->getValue() : true;
1895df3765bfSSheng 
189631ce47b5Sabhishek-kaushik22   return OperandInfo(std::move(Decoder), HasCompleteDecoder);
1897df3765bfSSheng }
1898df3765bfSSheng 
1899bdf02249SRahul Joshi static void parseVarLenInstOperand(const Record &Def,
1900df3765bfSSheng                                    std::vector<OperandInfo> &Operands,
1901df3765bfSSheng                                    const CodeGenInstruction &CGI) {
1902df3765bfSSheng 
1903df3765bfSSheng   const RecordVal *RV = Def.getValue("Inst");
1904df3765bfSSheng   VarLenInst VLI(cast<DagInit>(RV->getValue()), RV);
1905df3765bfSSheng   SmallVector<int> TiedTo;
1906df3765bfSSheng 
1907e9492ccaSJason Eckhardt   for (const auto &[Idx, Op] : enumerate(CGI.Operands)) {
1908df3765bfSSheng     if (Op.MIOperandInfo && Op.MIOperandInfo->getNumArgs() > 0)
1909df3765bfSSheng       for (auto *Arg : Op.MIOperandInfo->getArgs())
1910df3765bfSSheng         Operands.push_back(getOpInfo(cast<DefInit>(Arg)->getDef()));
1911df3765bfSSheng     else
1912df3765bfSSheng       Operands.push_back(getOpInfo(Op.Rec));
1913df3765bfSSheng 
1914df3765bfSSheng     int TiedReg = Op.getTiedRegister();
1915df3765bfSSheng     TiedTo.push_back(-1);
1916df3765bfSSheng     if (TiedReg != -1) {
1917df3765bfSSheng       TiedTo[Idx] = TiedReg;
1918df3765bfSSheng       TiedTo[TiedReg] = Idx;
1919df3765bfSSheng     }
1920df3765bfSSheng   }
1921df3765bfSSheng 
1922df3765bfSSheng   unsigned CurrBitPos = 0;
1923e9492ccaSJason Eckhardt   for (const auto &EncodingSegment : VLI) {
1924df3765bfSSheng     unsigned Offset = 0;
1925df3765bfSSheng     StringRef OpName;
1926df3765bfSSheng 
1927df3765bfSSheng     if (const StringInit *SI = dyn_cast<StringInit>(EncodingSegment.Value)) {
1928df3765bfSSheng       OpName = SI->getValue();
1929df3765bfSSheng     } else if (const DagInit *DI = dyn_cast<DagInit>(EncodingSegment.Value)) {
1930df3765bfSSheng       OpName = cast<StringInit>(DI->getArg(0))->getValue();
1931df3765bfSSheng       Offset = cast<IntInit>(DI->getArg(2))->getValue();
1932df3765bfSSheng     }
1933df3765bfSSheng 
1934df3765bfSSheng     if (!OpName.empty()) {
1935df3765bfSSheng       auto OpSubOpPair =
1936df3765bfSSheng           const_cast<CodeGenInstruction &>(CGI).Operands.ParseOperandName(
1937df3765bfSSheng               OpName);
1938df3765bfSSheng       unsigned OpIdx = CGI.Operands.getFlattenedOperandNumber(OpSubOpPair);
1939df3765bfSSheng       Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset);
194036c19eaeSMin-Yih Hsu       if (!EncodingSegment.CustomDecoder.empty())
194136c19eaeSMin-Yih Hsu         Operands[OpIdx].Decoder = EncodingSegment.CustomDecoder.str();
1942df3765bfSSheng 
1943df3765bfSSheng       int TiedReg = TiedTo[OpSubOpPair.first];
1944df3765bfSSheng       if (TiedReg != -1) {
1945df3765bfSSheng         unsigned OpIdx = CGI.Operands.getFlattenedOperandNumber(
1946*4e8c9d28SJay Foad             {TiedReg, OpSubOpPair.second});
1947df3765bfSSheng         Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset);
1948df3765bfSSheng       }
1949df3765bfSSheng     }
1950df3765bfSSheng 
1951df3765bfSSheng     CurrBitPos += EncodingSegment.BitWidth;
1952df3765bfSSheng   }
1953df3765bfSSheng }
1954df3765bfSSheng 
1955372240dfSJames Y Knight static void debugDumpRecord(const Record &Rec) {
19560ceffd36SRahul Joshi   // Dump the record, so we can see what's going on.
19570ceffd36SRahul Joshi   PrintNote([&Rec](raw_ostream &OS) {
19580ceffd36SRahul Joshi     OS << "Dumping record for previous error:\n";
19590ceffd36SRahul Joshi     OS << Rec;
19600ceffd36SRahul Joshi   });
1961372240dfSJames Y Knight }
1962372240dfSJames Y Knight 
1963372240dfSJames Y Knight /// For an operand field named OpName: populate OpInfo.InitValue with the
1964372240dfSJames Y Knight /// constant-valued bit values, and OpInfo.Fields with the ranges of bits to
1965372240dfSJames Y Knight /// insert from the decoded instruction.
1966d1fbdf5bSJames Y Knight static void addOneOperandFields(const Record &EncodingDef, const BitsInit &Bits,
1967d1fbdf5bSJames Y Knight                                 std::map<std::string, std::string> &TiedNames,
1968d1fbdf5bSJames Y Knight                                 StringRef OpName, OperandInfo &OpInfo) {
1969d1fbdf5bSJames Y Knight   // Some bits of the operand may be required to be 1 depending on the
1970d1fbdf5bSJames Y Knight   // instruction's encoding. Collect those bits.
1971d1fbdf5bSJames Y Knight   if (const RecordVal *EncodedValue = EncodingDef.getValue(OpName))
1972d1fbdf5bSJames Y Knight     if (const BitsInit *OpBits = dyn_cast<BitsInit>(EncodedValue->getValue()))
1973d1fbdf5bSJames Y Knight       for (unsigned I = 0; I < OpBits->getNumBits(); ++I)
1974d1fbdf5bSJames Y Knight         if (const BitInit *OpBit = dyn_cast<BitInit>(OpBits->getBit(I)))
1975d1fbdf5bSJames Y Knight           if (OpBit->getValue())
1976d1fbdf5bSJames Y Knight             OpInfo.InitValue |= 1ULL << I;
1977d1fbdf5bSJames Y Knight 
1978ff1ebcc5SFangrui Song   for (unsigned I = 0, J = 0; I != Bits.getNumBits(); I = J) {
197962e2c7fbSRahul Joshi     const VarInit *Var;
1980d1fbdf5bSJames Y Knight     unsigned Offset = 0;
1981ff1ebcc5SFangrui Song     for (; J != Bits.getNumBits(); ++J) {
198262e2c7fbSRahul Joshi       const VarBitInit *BJ = dyn_cast<VarBitInit>(Bits.getBit(J));
1983ff1ebcc5SFangrui Song       if (BJ) {
1984ff1ebcc5SFangrui Song         Var = dyn_cast<VarInit>(BJ->getBitVar());
1985ff1ebcc5SFangrui Song         if (I == J)
1986ff1ebcc5SFangrui Song           Offset = BJ->getBitNum();
1987ff1ebcc5SFangrui Song         else if (BJ->getBitNum() != Offset + J - I)
1988ff1ebcc5SFangrui Song           break;
1989d1fbdf5bSJames Y Knight       } else {
1990ff1ebcc5SFangrui Song         Var = dyn_cast<VarInit>(Bits.getBit(J));
1991d1fbdf5bSJames Y Knight       }
1992ff1ebcc5SFangrui Song       if (!Var || (Var->getName() != OpName &&
1993ff1ebcc5SFangrui Song                    Var->getName() != TiedNames[std::string(OpName)]))
1994ff1ebcc5SFangrui Song         break;
1995d1fbdf5bSJames Y Knight     }
1996ff1ebcc5SFangrui Song     if (I == J)
1997ff1ebcc5SFangrui Song       ++J;
1998ff1ebcc5SFangrui Song     else
1999ff1ebcc5SFangrui Song       OpInfo.addField(I, J - I, Offset);
2000ff1ebcc5SFangrui Song   }
2001d1fbdf5bSJames Y Knight }
2002d1fbdf5bSJames Y Knight 
2003df3765bfSSheng static unsigned
20042bb3621fSRahul Joshi populateInstruction(const CodeGenTarget &Target, const Record &EncodingDef,
2005df3765bfSSheng                     const CodeGenInstruction &CGI, unsigned Opc,
2006df3765bfSSheng                     std::map<unsigned, std::vector<OperandInfo>> &Operands,
2007df3765bfSSheng                     bool IsVarLenInst) {
2008df3765bfSSheng   const Record &Def = *CGI.TheDef;
2009df3765bfSSheng   // If all the bit positions are not specified; do not decode this instruction.
2010df3765bfSSheng   // We are bound to fail!  For proper disassembly, the well-known encoding bits
2011df3765bfSSheng   // of the instruction must be fully specified.
2012df3765bfSSheng 
201362e2c7fbSRahul Joshi   const BitsInit &Bits = getBitsField(EncodingDef, "Inst");
2014df3765bfSSheng   if (Bits.allInComplete())
2015df3765bfSSheng     return 0;
2016df3765bfSSheng 
2017df3765bfSSheng   std::vector<OperandInfo> InsnOperands;
2018df3765bfSSheng 
2019df3765bfSSheng   // If the instruction has specified a custom decoding hook, use that instead
2020df3765bfSSheng   // of trying to auto-generate the decoder.
2021df3765bfSSheng   StringRef InstDecoder = EncodingDef.getValueAsString("DecoderMethod");
2022df3765bfSSheng   if (InstDecoder != "") {
2023b9079baaSPierre van Houtryve     bool HasCompleteInstDecoder =
2024b9079baaSPierre van Houtryve         EncodingDef.getValueAsBit("hasCompleteDecoder");
2025df3765bfSSheng     InsnOperands.push_back(
2026df3765bfSSheng         OperandInfo(std::string(InstDecoder), HasCompleteInstDecoder));
202731ce47b5Sabhishek-kaushik22     Operands[Opc] = std::move(InsnOperands);
2028df3765bfSSheng     return Bits.getNumBits();
2029df3765bfSSheng   }
2030df3765bfSSheng 
2031df3765bfSSheng   // Generate a description of the operand of the instruction that we know
2032df3765bfSSheng   // how to decode automatically.
2033df3765bfSSheng   // FIXME: We'll need to have a way to manually override this as needed.
2034df3765bfSSheng 
2035df3765bfSSheng   // Gather the outputs/inputs of the instruction, so we can find their
2036df3765bfSSheng   // positions in the encoding.  This assumes for now that they appear in the
2037df3765bfSSheng   // MCInst in the order that they're listed.
203862e2c7fbSRahul Joshi   std::vector<std::pair<const Init *, StringRef>> InOutOperands;
203962e2c7fbSRahul Joshi   const DagInit *Out = Def.getValueAsDag("OutOperandList");
204062e2c7fbSRahul Joshi   const DagInit *In = Def.getValueAsDag("InOperandList");
2041e9492ccaSJason Eckhardt   for (const auto &[Idx, Arg] : enumerate(Out->getArgs()))
2042*4e8c9d28SJay Foad     InOutOperands.emplace_back(Arg, Out->getArgNameStr(Idx));
2043e9492ccaSJason Eckhardt   for (const auto &[Idx, Arg] : enumerate(In->getArgs()))
2044*4e8c9d28SJay Foad     InOutOperands.emplace_back(Arg, In->getArgNameStr(Idx));
2045df3765bfSSheng 
2046df3765bfSSheng   // Search for tied operands, so that we can correctly instantiate
2047df3765bfSSheng   // operands that are not explicitly represented in the encoding.
2048df3765bfSSheng   std::map<std::string, std::string> TiedNames;
2049e9492ccaSJason Eckhardt   for (const auto &[I, Op] : enumerate(CGI.Operands)) {
2050e9492ccaSJason Eckhardt     for (const auto &[J, CI] : enumerate(Op.Constraints)) {
2051372240dfSJames Y Knight       if (CI.isTied()) {
2052df3765bfSSheng         std::pair<unsigned, unsigned> SO =
2053e9492ccaSJason Eckhardt             CGI.Operands.getSubOperandNumber(CI.getTiedOperand());
2054372240dfSJames Y Knight         std::string TiedName = CGI.Operands[SO.first].SubOpNames[SO.second];
2055372240dfSJames Y Knight         if (TiedName.empty())
2056372240dfSJames Y Knight           TiedName = CGI.Operands[SO.first].Name;
2057e9492ccaSJason Eckhardt         std::string MyName = Op.SubOpNames[J];
2058372240dfSJames Y Knight         if (MyName.empty())
2059372240dfSJames Y Knight           MyName = Op.Name;
2060372240dfSJames Y Knight 
2061372240dfSJames Y Knight         TiedNames[MyName] = TiedName;
206231ce47b5Sabhishek-kaushik22         TiedNames[TiedName] = std::move(MyName);
2063372240dfSJames Y Knight       }
2064df3765bfSSheng     }
2065df3765bfSSheng   }
2066df3765bfSSheng 
2067df3765bfSSheng   if (IsVarLenInst) {
2068df3765bfSSheng     parseVarLenInstOperand(EncodingDef, InsnOperands, CGI);
2069df3765bfSSheng   } else {
2070df3765bfSSheng     // For each operand, see if we can figure out where it is encoded.
2071df3765bfSSheng     for (const auto &Op : InOutOperands) {
207262e2c7fbSRahul Joshi       const Init *OpInit = Op.first;
2073d1fbdf5bSJames Y Knight       StringRef OpName = Op.second;
2074d1fbdf5bSJames Y Knight 
2075b9079baaSPierre van Houtryve       // We're ready to find the instruction encoding locations for this
2076b9079baaSPierre van Houtryve       // operand.
2077df3765bfSSheng 
2078372240dfSJames Y Knight       // First, find the operand type ("OpInit"), and sub-op names
2079372240dfSJames Y Knight       // ("SubArgDag") if present.
208062e2c7fbSRahul Joshi       const DagInit *SubArgDag = dyn_cast<DagInit>(OpInit);
2081372240dfSJames Y Knight       if (SubArgDag)
2082372240dfSJames Y Knight         OpInit = SubArgDag->getOperator();
20832bb3621fSRahul Joshi       const Record *OpTypeRec = cast<DefInit>(OpInit)->getDef();
2084372240dfSJames Y Knight       // Lookup the sub-operands from the operand type record (note that only
2085372240dfSJames Y Knight       // Operand subclasses have MIOperandInfo, see CodeGenInstruction.cpp).
20862bb3621fSRahul Joshi       const DagInit *SubOps = OpTypeRec->isSubClassOf("Operand")
2087372240dfSJames Y Knight                                   ? OpTypeRec->getValueAsDag("MIOperandInfo")
2088372240dfSJames Y Knight                                   : nullptr;
2089372240dfSJames Y Knight 
2090b9079baaSPierre van Houtryve       // Lookup the decoder method and construct a new OperandInfo to hold our
2091b9079baaSPierre van Houtryve       // result.
2092372240dfSJames Y Knight       OperandInfo OpInfo = getOpInfo(OpTypeRec);
2093372240dfSJames Y Knight 
2094372240dfSJames Y Knight       // If we have named sub-operands...
2095372240dfSJames Y Knight       if (SubArgDag) {
2096372240dfSJames Y Knight         // Then there should not be a custom decoder specified on the top-level
2097372240dfSJames Y Knight         // type.
2098372240dfSJames Y Knight         if (!OpInfo.Decoder.empty()) {
2099372240dfSJames Y Knight           PrintError(EncodingDef.getLoc(),
2100372240dfSJames Y Knight                      "DecoderEmitter: operand \"" + OpName + "\" has type \"" +
2101372240dfSJames Y Knight                          OpInit->getAsString() +
2102372240dfSJames Y Knight                          "\" with a custom DecoderMethod, but also named "
2103372240dfSJames Y Knight                          "sub-operands.");
2104372240dfSJames Y Knight           continue;
2105372240dfSJames Y Knight         }
2106372240dfSJames Y Knight 
2107372240dfSJames Y Knight         // Decode each of the sub-ops separately.
2108372240dfSJames Y Knight         assert(SubOps && SubArgDag->getNumArgs() == SubOps->getNumArgs());
2109e9492ccaSJason Eckhardt         for (const auto &[I, Arg] : enumerate(SubOps->getArgs())) {
2110e9492ccaSJason Eckhardt           StringRef SubOpName = SubArgDag->getArgNameStr(I);
2111e9492ccaSJason Eckhardt           OperandInfo SubOpInfo = getOpInfo(cast<DefInit>(Arg)->getDef());
2112372240dfSJames Y Knight 
2113372240dfSJames Y Knight           addOneOperandFields(EncodingDef, Bits, TiedNames, SubOpName,
2114372240dfSJames Y Knight                               SubOpInfo);
211531ce47b5Sabhishek-kaushik22           InsnOperands.push_back(std::move(SubOpInfo));
2116372240dfSJames Y Knight         }
2117372240dfSJames Y Knight         continue;
2118372240dfSJames Y Knight       }
2119372240dfSJames Y Knight 
2120372240dfSJames Y Knight       // Otherwise, if we have an operand with sub-operands, but they aren't
2121372240dfSJames Y Knight       // named...
2122372240dfSJames Y Knight       if (SubOps && OpInfo.Decoder.empty()) {
2123372240dfSJames Y Knight         // If it's a single sub-operand, and no custom decoder, use the decoder
2124372240dfSJames Y Knight         // from the one sub-operand.
2125372240dfSJames Y Knight         if (SubOps->getNumArgs() == 1)
2126372240dfSJames Y Knight           OpInfo = getOpInfo(cast<DefInit>(SubOps->getArg(0))->getDef());
2127372240dfSJames Y Knight 
2128372240dfSJames Y Knight         // If we have multiple sub-ops, there'd better have a custom
2129372240dfSJames Y Knight         // decoder. (Otherwise we don't know how to populate them properly...)
2130372240dfSJames Y Knight         if (SubOps->getNumArgs() > 1) {
2131372240dfSJames Y Knight           PrintError(EncodingDef.getLoc(),
2132372240dfSJames Y Knight                      "DecoderEmitter: operand \"" + OpName +
2133372240dfSJames Y Knight                          "\" uses MIOperandInfo with multiple ops, but doesn't "
2134372240dfSJames Y Knight                          "have a custom decoder!");
2135372240dfSJames Y Knight           debugDumpRecord(EncodingDef);
2136372240dfSJames Y Knight           continue;
2137372240dfSJames Y Knight         }
2138372240dfSJames Y Knight       }
2139df3765bfSSheng 
2140d1fbdf5bSJames Y Knight       addOneOperandFields(EncodingDef, Bits, TiedNames, OpName, OpInfo);
2141372240dfSJames Y Knight       // FIXME: it should be an error not to find a definition for a given
2142372240dfSJames Y Knight       // operand, rather than just failing to add it to the resulting
2143372240dfSJames Y Knight       // instruction! (This is a longstanding bug, which will be addressed in an
2144372240dfSJames Y Knight       // upcoming change.)
2145df3765bfSSheng       if (OpInfo.numFields() > 0)
214631ce47b5Sabhishek-kaushik22         InsnOperands.push_back(std::move(OpInfo));
2147df3765bfSSheng     }
2148df3765bfSSheng   }
2149943b212dSabhishek-kaushik22   Operands[Opc] = std::move(InsnOperands);
2150df3765bfSSheng 
2151df3765bfSSheng #if 0
2152df3765bfSSheng   LLVM_DEBUG({
2153df3765bfSSheng       // Dumps the instruction encoding bits.
2154df3765bfSSheng       dumpBits(errs(), Bits);
2155df3765bfSSheng 
2156df3765bfSSheng       errs() << '\n';
2157df3765bfSSheng 
2158df3765bfSSheng       // Dumps the list of operand info.
2159df3765bfSSheng       for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) {
2160df3765bfSSheng         const CGIOperandList::OperandInfo &Info = CGI.Operands[i];
2161df3765bfSSheng         const std::string &OperandName = Info.Name;
2162df3765bfSSheng         const Record &OperandDef = *Info.Rec;
2163df3765bfSSheng 
2164df3765bfSSheng         errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n";
2165df3765bfSSheng       }
2166df3765bfSSheng     });
2167df3765bfSSheng #endif
2168df3765bfSSheng 
2169df3765bfSSheng   return Bits.getNumBits();
2170df3765bfSSheng }
2171df3765bfSSheng 
2172df3765bfSSheng // emitFieldFromInstruction - Emit the templated helper function
2173df3765bfSSheng // fieldFromInstruction().
2174df3765bfSSheng // On Windows we make sure that this function is not inlined when
2175df3765bfSSheng // using the VS compiler. It has a bug which causes the function
2176a2d45017SKazu Hirata // to be optimized out in some circumstances. See llvm.org/pr38292
2177df3765bfSSheng static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
2178e9492ccaSJason Eckhardt   OS << R"(
2179e9492ccaSJason Eckhardt // Helper functions for extracting fields from encoded instructions.
2180e9492ccaSJason Eckhardt // InsnType must either be integral or an APInt-like object that must:
2181e9492ccaSJason Eckhardt // * be default-constructible and copy-constructible
2182e9492ccaSJason Eckhardt // * be constructible from an APInt (this can be private)
2183e9492ccaSJason Eckhardt // * Support insertBits(bits, startBit, numBits)
2184e9492ccaSJason Eckhardt // * Support extractBitsAsZExtValue(numBits, startBit)
2185e9492ccaSJason Eckhardt // * Support the ~, &, ==, and != operators with other objects of the same type
2186e9492ccaSJason Eckhardt // * Support the != and bitwise & with uint64_t
2187e9492ccaSJason Eckhardt // * Support put (<<) to raw_ostream&
2188e9492ccaSJason Eckhardt template <typename InsnType>
2189e9492ccaSJason Eckhardt #if defined(_MSC_VER) && !defined(__clang__)
2190e9492ccaSJason Eckhardt __declspec(noinline)
2191e9492ccaSJason Eckhardt #endif
2192e9492ccaSJason Eckhardt static std::enable_if_t<std::is_integral<InsnType>::value, InsnType>
2193e9492ccaSJason Eckhardt fieldFromInstruction(const InsnType &insn, unsigned startBit,
2194e9492ccaSJason Eckhardt                      unsigned numBits) {
2195e9492ccaSJason Eckhardt   assert(startBit + numBits <= 64 && "Cannot support >64-bit extractions!");
2196e9492ccaSJason Eckhardt   assert(startBit + numBits <= (sizeof(InsnType) * 8) &&
2197e9492ccaSJason Eckhardt          "Instruction field out of bounds!");
2198e9492ccaSJason Eckhardt   InsnType fieldMask;
2199e9492ccaSJason Eckhardt   if (numBits == sizeof(InsnType) * 8)
2200e9492ccaSJason Eckhardt     fieldMask = (InsnType)(-1LL);
2201e9492ccaSJason Eckhardt   else
2202e9492ccaSJason Eckhardt     fieldMask = (((InsnType)1 << numBits) - 1) << startBit;
2203e9492ccaSJason Eckhardt   return (insn & fieldMask) >> startBit;
2204e9492ccaSJason Eckhardt }
2205e9492ccaSJason Eckhardt 
2206e9492ccaSJason Eckhardt template <typename InsnType>
2207e9492ccaSJason Eckhardt static std::enable_if_t<!std::is_integral<InsnType>::value, uint64_t>
2208e9492ccaSJason Eckhardt fieldFromInstruction(const InsnType &insn, unsigned startBit,
2209e9492ccaSJason Eckhardt                      unsigned numBits) {
2210e9492ccaSJason Eckhardt   return insn.extractBitsAsZExtValue(numBits, startBit);
2211e9492ccaSJason Eckhardt }
2212e9492ccaSJason Eckhardt )";
2213df3765bfSSheng }
2214df3765bfSSheng 
2215df3765bfSSheng // emitInsertBits - Emit the templated helper function insertBits().
2216df3765bfSSheng static void emitInsertBits(formatted_raw_ostream &OS) {
2217e9492ccaSJason Eckhardt   OS << R"(
2218e9492ccaSJason Eckhardt // Helper function for inserting bits extracted from an encoded instruction into
2219e9492ccaSJason Eckhardt // a field.
2220e9492ccaSJason Eckhardt template <typename InsnType>
2221e9492ccaSJason Eckhardt static std::enable_if_t<std::is_integral<InsnType>::value>
2222e9492ccaSJason Eckhardt insertBits(InsnType &field, InsnType bits, unsigned startBit, unsigned numBits) {
2223e9492ccaSJason Eckhardt   assert(startBit + numBits <= sizeof field * 8);
2224e9492ccaSJason Eckhardt   field |= (InsnType)bits << startBit;
2225e9492ccaSJason Eckhardt }
2226e9492ccaSJason Eckhardt 
2227e9492ccaSJason Eckhardt template <typename InsnType>
2228e9492ccaSJason Eckhardt static std::enable_if_t<!std::is_integral<InsnType>::value>
2229e9492ccaSJason Eckhardt insertBits(InsnType &field, uint64_t bits, unsigned startBit, unsigned numBits) {
2230e9492ccaSJason Eckhardt   field.insertBits(bits, startBit, numBits);
2231e9492ccaSJason Eckhardt }
2232e9492ccaSJason Eckhardt )";
2233df3765bfSSheng }
2234df3765bfSSheng 
2235df3765bfSSheng // emitDecodeInstruction - Emit the templated helper function
2236df3765bfSSheng // decodeInstruction().
2237df3765bfSSheng static void emitDecodeInstruction(formatted_raw_ostream &OS,
2238df3765bfSSheng                                   bool IsVarLenInst) {
2239e9492ccaSJason Eckhardt   OS << R"(
2240e9492ccaSJason Eckhardt template <typename InsnType>
2241e9492ccaSJason Eckhardt static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2242e9492ccaSJason Eckhardt                                       InsnType insn, uint64_t Address,
2243e9492ccaSJason Eckhardt                                       const MCDisassembler *DisAsm,
2244e9492ccaSJason Eckhardt                                       const MCSubtargetInfo &STI)";
2245df3765bfSSheng   if (IsVarLenInst) {
2246df3765bfSSheng     OS << ",\n                                      "
2247e9492ccaSJason Eckhardt           "llvm::function_ref<void(APInt &, uint64_t)> makeUp";
2248df3765bfSSheng   }
2249e9492ccaSJason Eckhardt   OS << R"() {
2250e9492ccaSJason Eckhardt   const FeatureBitset &Bits = STI.getFeatureBits();
2251e9492ccaSJason Eckhardt 
2252e9492ccaSJason Eckhardt   const uint8_t *Ptr = DecodeTable;
2253e9492ccaSJason Eckhardt   uint64_t CurFieldValue = 0;
2254e9492ccaSJason Eckhardt   DecodeStatus S = MCDisassembler::Success;
2255e9492ccaSJason Eckhardt   while (true) {
2256e9492ccaSJason Eckhardt     ptrdiff_t Loc = Ptr - DecodeTable;
2257e9492ccaSJason Eckhardt     switch (*Ptr) {
2258e9492ccaSJason Eckhardt     default:
2259e9492ccaSJason Eckhardt       errs() << Loc << ": Unexpected decode table opcode!\n";
2260e9492ccaSJason Eckhardt       return MCDisassembler::Fail;
2261e9492ccaSJason Eckhardt     case MCD::OPC_ExtractField: {
2262e9492ccaSJason Eckhardt       // Decode the start value.
226335bb9f15SPiotr Fusik       unsigned Start = decodeULEB128AndIncUnsafe(++Ptr);
2264e9492ccaSJason Eckhardt       unsigned Len = *Ptr++;)";
2265df3765bfSSheng   if (IsVarLenInst)
2266e9492ccaSJason Eckhardt     OS << "\n      makeUp(insn, Start + Len);";
2267e9492ccaSJason Eckhardt   OS << R"(
2268e9492ccaSJason Eckhardt       CurFieldValue = fieldFromInstruction(insn, Start, Len);
2269e9492ccaSJason Eckhardt       LLVM_DEBUG(dbgs() << Loc << ": OPC_ExtractField(" << Start << ", "
2270e9492ccaSJason Eckhardt                    << Len << "): " << CurFieldValue << "\n");
2271e9492ccaSJason Eckhardt       break;
2272e9492ccaSJason Eckhardt     }
2273e9492ccaSJason Eckhardt     case MCD::OPC_FilterValue: {
2274e9492ccaSJason Eckhardt       // Decode the field value.
227535bb9f15SPiotr Fusik       uint64_t Val = decodeULEB128AndIncUnsafe(++Ptr);
2276e9492ccaSJason Eckhardt       // NumToSkip is a plain 24-bit integer.
2277e9492ccaSJason Eckhardt       unsigned NumToSkip = *Ptr++;
2278e9492ccaSJason Eckhardt       NumToSkip |= (*Ptr++) << 8;
2279e9492ccaSJason Eckhardt       NumToSkip |= (*Ptr++) << 16;
2280e9492ccaSJason Eckhardt 
2281e9492ccaSJason Eckhardt       // Perform the filter operation.
2282e9492ccaSJason Eckhardt       if (Val != CurFieldValue)
2283e9492ccaSJason Eckhardt         Ptr += NumToSkip;
2284e9492ccaSJason Eckhardt       LLVM_DEBUG(dbgs() << Loc << ": OPC_FilterValue(" << Val << ", " << NumToSkip
2285e9492ccaSJason Eckhardt                    << "): " << ((Val != CurFieldValue) ? "FAIL:" : "PASS:")
2286e9492ccaSJason Eckhardt                    << " continuing at " << (Ptr - DecodeTable) << "\n");
2287e9492ccaSJason Eckhardt 
2288e9492ccaSJason Eckhardt       break;
2289e9492ccaSJason Eckhardt     }
2290e9492ccaSJason Eckhardt     case MCD::OPC_CheckField: {
2291e9492ccaSJason Eckhardt       // Decode the start value.
2292efad1495SFangrui Song       unsigned Start = decodeULEB128AndIncUnsafe(++Ptr);
229335bf8e79SFangrui Song       unsigned Len = *Ptr;)";
2294df3765bfSSheng   if (IsVarLenInst)
2295e9492ccaSJason Eckhardt     OS << "\n      makeUp(insn, Start + Len);";
2296e9492ccaSJason Eckhardt   OS << R"(
2297e9492ccaSJason Eckhardt       uint64_t FieldValue = fieldFromInstruction(insn, Start, Len);
2298e9492ccaSJason Eckhardt       // Decode the field value.
2299e9492ccaSJason Eckhardt       unsigned PtrLen = 0;
2300e9492ccaSJason Eckhardt       uint64_t ExpectedValue = decodeULEB128(++Ptr, &PtrLen);
2301e9492ccaSJason Eckhardt       Ptr += PtrLen;
2302e9492ccaSJason Eckhardt       // NumToSkip is a plain 24-bit integer.
2303e9492ccaSJason Eckhardt       unsigned NumToSkip = *Ptr++;
2304e9492ccaSJason Eckhardt       NumToSkip |= (*Ptr++) << 8;
2305e9492ccaSJason Eckhardt       NumToSkip |= (*Ptr++) << 16;
2306e9492ccaSJason Eckhardt 
2307e9492ccaSJason Eckhardt       // If the actual and expected values don't match, skip.
2308e9492ccaSJason Eckhardt       if (ExpectedValue != FieldValue)
2309e9492ccaSJason Eckhardt         Ptr += NumToSkip;
2310e9492ccaSJason Eckhardt       LLVM_DEBUG(dbgs() << Loc << ": OPC_CheckField(" << Start << ", "
2311e9492ccaSJason Eckhardt                    << Len << ", " << ExpectedValue << ", " << NumToSkip
2312e9492ccaSJason Eckhardt                    << "): FieldValue = " << FieldValue << ", ExpectedValue = "
2313e9492ccaSJason Eckhardt                    << ExpectedValue << ": "
2314e9492ccaSJason Eckhardt                    << ((ExpectedValue == FieldValue) ? "PASS\n" : "FAIL\n"));
2315e9492ccaSJason Eckhardt       break;
2316e9492ccaSJason Eckhardt     }
2317e9492ccaSJason Eckhardt     case MCD::OPC_CheckPredicate: {
2318e9492ccaSJason Eckhardt       // Decode the Predicate Index value.
2319efad1495SFangrui Song       unsigned PIdx = decodeULEB128AndIncUnsafe(++Ptr);
2320e9492ccaSJason Eckhardt       // NumToSkip is a plain 24-bit integer.
2321e9492ccaSJason Eckhardt       unsigned NumToSkip = *Ptr++;
2322e9492ccaSJason Eckhardt       NumToSkip |= (*Ptr++) << 8;
2323e9492ccaSJason Eckhardt       NumToSkip |= (*Ptr++) << 16;
2324e9492ccaSJason Eckhardt       // Check the predicate.
2325e9492ccaSJason Eckhardt       bool Pred;
2326e9492ccaSJason Eckhardt       if (!(Pred = checkDecoderPredicate(PIdx, Bits)))
2327e9492ccaSJason Eckhardt         Ptr += NumToSkip;
2328e9492ccaSJason Eckhardt       (void)Pred;
2329e9492ccaSJason Eckhardt       LLVM_DEBUG(dbgs() << Loc << ": OPC_CheckPredicate(" << PIdx << "): "
2330e9492ccaSJason Eckhardt             << (Pred ? "PASS\n" : "FAIL\n"));
2331e9492ccaSJason Eckhardt 
2332e9492ccaSJason Eckhardt       break;
2333e9492ccaSJason Eckhardt     }
2334e9492ccaSJason Eckhardt     case MCD::OPC_Decode: {
2335e9492ccaSJason Eckhardt       // Decode the Opcode value.
2336efad1495SFangrui Song       unsigned Opc = decodeULEB128AndIncUnsafe(++Ptr);
2337efad1495SFangrui Song       unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
2338e9492ccaSJason Eckhardt 
2339e9492ccaSJason Eckhardt       MI.clear();
2340e9492ccaSJason Eckhardt       MI.setOpcode(Opc);
2341e9492ccaSJason Eckhardt       bool DecodeComplete;)";
2342df3765bfSSheng   if (IsVarLenInst) {
234335bf8e79SFangrui Song     OS << "\n      unsigned Len = InstrLenTable[Opc];\n"
2344e9492ccaSJason Eckhardt        << "      makeUp(insn, Len);";
2345df3765bfSSheng   }
2346e9492ccaSJason Eckhardt   OS << R"(
2347e9492ccaSJason Eckhardt       S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, DecodeComplete);
2348e9492ccaSJason Eckhardt       assert(DecodeComplete);
2349e9492ccaSJason Eckhardt 
2350e9492ccaSJason Eckhardt       LLVM_DEBUG(dbgs() << Loc << ": OPC_Decode: opcode " << Opc
2351e9492ccaSJason Eckhardt                    << ", using decoder " << DecodeIdx << ": "
2352e9492ccaSJason Eckhardt                    << (S != MCDisassembler::Fail ? "PASS" : "FAIL") << "\n");
2353e9492ccaSJason Eckhardt       return S;
2354e9492ccaSJason Eckhardt     }
2355e9492ccaSJason Eckhardt     case MCD::OPC_TryDecode: {
2356e9492ccaSJason Eckhardt       // Decode the Opcode value.
2357efad1495SFangrui Song       unsigned Opc = decodeULEB128AndIncUnsafe(++Ptr);
2358efad1495SFangrui Song       unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
2359e9492ccaSJason Eckhardt       // NumToSkip is a plain 24-bit integer.
2360e9492ccaSJason Eckhardt       unsigned NumToSkip = *Ptr++;
2361e9492ccaSJason Eckhardt       NumToSkip |= (*Ptr++) << 8;
2362e9492ccaSJason Eckhardt       NumToSkip |= (*Ptr++) << 16;
2363e9492ccaSJason Eckhardt 
2364e9492ccaSJason Eckhardt       // Perform the decode operation.
2365e9492ccaSJason Eckhardt       MCInst TmpMI;
2366e9492ccaSJason Eckhardt       TmpMI.setOpcode(Opc);
2367e9492ccaSJason Eckhardt       bool DecodeComplete;
2368e9492ccaSJason Eckhardt       S = decodeToMCInst(S, DecodeIdx, insn, TmpMI, Address, DisAsm, DecodeComplete);
2369e9492ccaSJason Eckhardt       LLVM_DEBUG(dbgs() << Loc << ": OPC_TryDecode: opcode " << Opc
2370e9492ccaSJason Eckhardt                    << ", using decoder " << DecodeIdx << ": ");
2371e9492ccaSJason Eckhardt 
2372e9492ccaSJason Eckhardt       if (DecodeComplete) {
2373e9492ccaSJason Eckhardt         // Decoding complete.
2374e9492ccaSJason Eckhardt         LLVM_DEBUG(dbgs() << (S != MCDisassembler::Fail ? "PASS" : "FAIL") << "\n");
2375e9492ccaSJason Eckhardt         MI = TmpMI;
2376e9492ccaSJason Eckhardt         return S;
2377e9492ccaSJason Eckhardt       } else {
2378e9492ccaSJason Eckhardt         assert(S == MCDisassembler::Fail);
2379e9492ccaSJason Eckhardt         // If the decoding was incomplete, skip.
2380e9492ccaSJason Eckhardt         Ptr += NumToSkip;
2381e9492ccaSJason Eckhardt         LLVM_DEBUG(dbgs() << "FAIL: continuing at " << (Ptr - DecodeTable) << "\n");
2382e9492ccaSJason Eckhardt         // Reset decode status. This also drops a SoftFail status that could be
2383e9492ccaSJason Eckhardt         // set before the decode attempt.
2384e9492ccaSJason Eckhardt         S = MCDisassembler::Success;
2385e9492ccaSJason Eckhardt       }
2386e9492ccaSJason Eckhardt       break;
2387e9492ccaSJason Eckhardt     }
2388e9492ccaSJason Eckhardt     case MCD::OPC_SoftFail: {
2389e9492ccaSJason Eckhardt       // Decode the mask values.
2390efad1495SFangrui Song       uint64_t PositiveMask = decodeULEB128AndIncUnsafe(++Ptr);
2391efad1495SFangrui Song       uint64_t NegativeMask = decodeULEB128AndIncUnsafe(Ptr);
2392e9492ccaSJason Eckhardt       bool Fail = (insn & PositiveMask) != 0 || (~insn & NegativeMask) != 0;
2393e9492ccaSJason Eckhardt       if (Fail)
2394e9492ccaSJason Eckhardt         S = MCDisassembler::SoftFail;
2395e9492ccaSJason Eckhardt       LLVM_DEBUG(dbgs() << Loc << ": OPC_SoftFail: " << (Fail ? "FAIL\n" : "PASS\n"));
2396e9492ccaSJason Eckhardt       break;
2397e9492ccaSJason Eckhardt     }
2398e9492ccaSJason Eckhardt     case MCD::OPC_Fail: {
2399e9492ccaSJason Eckhardt       LLVM_DEBUG(dbgs() << Loc << ": OPC_Fail\n");
2400e9492ccaSJason Eckhardt       return MCDisassembler::Fail;
2401e9492ccaSJason Eckhardt     }
2402e9492ccaSJason Eckhardt     }
2403e9492ccaSJason Eckhardt   }
2404e9492ccaSJason Eckhardt   llvm_unreachable("bogosity detected in disassembler state machine!");
2405e9492ccaSJason Eckhardt }
2406e9492ccaSJason Eckhardt 
2407e9492ccaSJason Eckhardt )";
2408df3765bfSSheng }
2409df3765bfSSheng 
24109a26f893SJames Y Knight // Helper to propagate SoftFail status. Returns false if the status is Fail;
24119a26f893SJames Y Knight // callers are expected to early-exit in that condition. (Note, the '&' operator
24129a26f893SJames Y Knight // is correct to propagate the values of this enum; see comment on 'enum
24139a26f893SJames Y Knight // DecodeStatus'.)
24149a26f893SJames Y Knight static void emitCheck(formatted_raw_ostream &OS) {
2415e9492ccaSJason Eckhardt   OS << R"(
2416e9492ccaSJason Eckhardt static bool Check(DecodeStatus &Out, DecodeStatus In) {
2417e9492ccaSJason Eckhardt   Out = static_cast<DecodeStatus>(Out & In);
2418e9492ccaSJason Eckhardt   return Out != MCDisassembler::Fail;
2419e9492ccaSJason Eckhardt }
2420e9492ccaSJason Eckhardt 
2421e9492ccaSJason Eckhardt )";
24229a26f893SJames Y Knight }
24239a26f893SJames Y Knight 
2424f75c6ed9SJason Eckhardt // Collect all HwModes referenced by the target for encoding purposes,
2425f75c6ed9SJason Eckhardt // returning a vector of corresponding names.
2426da1d3d8fSsuperZWT123 static void collectHwModesReferencedForEncodings(
2427da1d3d8fSsuperZWT123     const CodeGenHwModes &HWM, std::vector<StringRef> &Names,
2428da1d3d8fSsuperZWT123     NamespacesHwModesMap &NamespacesWithHwModes) {
2429f75c6ed9SJason Eckhardt   SmallBitVector BV(HWM.getNumModeIds());
2430f75c6ed9SJason Eckhardt   for (const auto &MS : HWM.getHwModeSelects()) {
2431f75c6ed9SJason Eckhardt     for (const HwModeSelect::PairType &P : MS.second.Items) {
2432da1d3d8fSsuperZWT123       if (P.second->isSubClassOf("InstructionEncoding")) {
2433da1d3d8fSsuperZWT123         std::string DecoderNamespace =
2434da1d3d8fSsuperZWT123             std::string(P.second->getValueAsString("DecoderNamespace"));
2435da1d3d8fSsuperZWT123         if (P.first == DefaultMode) {
2436da1d3d8fSsuperZWT123           NamespacesWithHwModes[DecoderNamespace].insert("");
2437da1d3d8fSsuperZWT123         } else {
2438da1d3d8fSsuperZWT123           NamespacesWithHwModes[DecoderNamespace].insert(
2439da1d3d8fSsuperZWT123               HWM.getMode(P.first).Name);
2440da1d3d8fSsuperZWT123         }
2441f75c6ed9SJason Eckhardt         BV.set(P.first);
2442f75c6ed9SJason Eckhardt       }
2443f75c6ed9SJason Eckhardt     }
2444da1d3d8fSsuperZWT123   }
2445ad43ea33SJason Eckhardt   transform(BV.set_bits(), std::back_inserter(Names), [&HWM](const int &M) {
2446da1d3d8fSsuperZWT123     if (M == DefaultMode)
2447da1d3d8fSsuperZWT123       return StringRef("");
2448ad43ea33SJason Eckhardt     return HWM.getModeName(M, /*IncludeDefault=*/true);
2449ad43ea33SJason Eckhardt   });
2450f75c6ed9SJason Eckhardt }
2451f75c6ed9SJason Eckhardt 
2452da1d3d8fSsuperZWT123 static void
2453da1d3d8fSsuperZWT123 handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
2454da1d3d8fSsuperZWT123                                 const std::vector<StringRef> &HwModeNames,
2455da1d3d8fSsuperZWT123                                 NamespacesHwModesMap &NamespacesWithHwModes,
2456da1d3d8fSsuperZWT123                                 std::vector<EncodingAndInst> &GlobalEncodings) {
2457da1d3d8fSsuperZWT123   const Record *InstDef = Instr->TheDef;
2458da1d3d8fSsuperZWT123 
2459da1d3d8fSsuperZWT123   switch (DecoderEmitterSuppressDuplicates) {
2460da1d3d8fSsuperZWT123   case SUPPRESSION_DISABLE: {
2461da1d3d8fSsuperZWT123     for (StringRef HwModeName : HwModeNames)
2462da1d3d8fSsuperZWT123       GlobalEncodings.emplace_back(InstDef, Instr, HwModeName);
2463da1d3d8fSsuperZWT123     break;
2464da1d3d8fSsuperZWT123   }
2465da1d3d8fSsuperZWT123   case SUPPRESSION_LEVEL1: {
2466da1d3d8fSsuperZWT123     std::string DecoderNamespace =
2467da1d3d8fSsuperZWT123         std::string(InstDef->getValueAsString("DecoderNamespace"));
2468da1d3d8fSsuperZWT123     auto It = NamespacesWithHwModes.find(DecoderNamespace);
2469da1d3d8fSsuperZWT123     if (It != NamespacesWithHwModes.end()) {
2470da1d3d8fSsuperZWT123       for (StringRef HwModeName : It->second)
2471da1d3d8fSsuperZWT123         GlobalEncodings.emplace_back(InstDef, Instr, HwModeName);
2472da1d3d8fSsuperZWT123     } else {
2473da1d3d8fSsuperZWT123       // Only emit the encoding once, as it's DecoderNamespace doesn't
2474da1d3d8fSsuperZWT123       // contain any HwModes.
2475da1d3d8fSsuperZWT123       GlobalEncodings.emplace_back(InstDef, Instr, "");
2476da1d3d8fSsuperZWT123     }
2477da1d3d8fSsuperZWT123     break;
2478da1d3d8fSsuperZWT123   }
2479da1d3d8fSsuperZWT123   case SUPPRESSION_LEVEL2:
2480da1d3d8fSsuperZWT123     GlobalEncodings.emplace_back(InstDef, Instr, "");
2481da1d3d8fSsuperZWT123     break;
2482da1d3d8fSsuperZWT123   }
2483da1d3d8fSsuperZWT123 }
2484da1d3d8fSsuperZWT123 
2485df3765bfSSheng // Emits disassembler code for instruction decoding.
2486df3765bfSSheng void DecoderEmitter::run(raw_ostream &o) {
2487df3765bfSSheng   formatted_raw_ostream OS(o);
2488e9492ccaSJason Eckhardt   OS << R"(
2489e9492ccaSJason Eckhardt #include "llvm/MC/MCInst.h"
2490e9492ccaSJason Eckhardt #include "llvm/MC/MCSubtargetInfo.h"
2491e9492ccaSJason Eckhardt #include "llvm/Support/DataTypes.h"
2492e9492ccaSJason Eckhardt #include "llvm/Support/Debug.h"
2493e9492ccaSJason Eckhardt #include "llvm/Support/LEB128.h"
2494e9492ccaSJason Eckhardt #include "llvm/Support/raw_ostream.h"
2495e9492ccaSJason Eckhardt #include "llvm/TargetParser/SubtargetFeature.h"
2496e9492ccaSJason Eckhardt #include <assert.h>
2497e9492ccaSJason Eckhardt 
2498e9492ccaSJason Eckhardt namespace llvm {
2499e9492ccaSJason Eckhardt )";
2500df3765bfSSheng 
2501df3765bfSSheng   emitFieldFromInstruction(OS);
2502df3765bfSSheng   emitInsertBits(OS);
25039a26f893SJames Y Knight   emitCheck(OS);
2504df3765bfSSheng 
2505df3765bfSSheng   Target.reverseBitsForLittleEndianEncoding();
2506df3765bfSSheng 
2507df3765bfSSheng   // Parameterize the decoders based on namespace and instruction width.
2508f75c6ed9SJason Eckhardt 
2509f75c6ed9SJason Eckhardt   // First, collect all encoding-related HwModes referenced by the target.
2510da1d3d8fSsuperZWT123   // And establish a mapping table between DecoderNamespace and HwMode.
2511f75c6ed9SJason Eckhardt   // If HwModeNames is empty, add the empty string so we always have one HwMode.
2512f75c6ed9SJason Eckhardt   const CodeGenHwModes &HWM = Target.getHwModes();
2513f75c6ed9SJason Eckhardt   std::vector<StringRef> HwModeNames;
2514da1d3d8fSsuperZWT123   NamespacesHwModesMap NamespacesWithHwModes;
2515da1d3d8fSsuperZWT123   collectHwModesReferencedForEncodings(HWM, HwModeNames, NamespacesWithHwModes);
2516f75c6ed9SJason Eckhardt   if (HwModeNames.empty())
2517f75c6ed9SJason Eckhardt     HwModeNames.push_back("");
2518f75c6ed9SJason Eckhardt 
2519df3765bfSSheng   const auto &NumberedInstructions = Target.getInstructionsByEnumValue();
2520df3765bfSSheng   NumberedEncodings.reserve(NumberedInstructions.size());
2521df3765bfSSheng   for (const auto &NumberedInstruction : NumberedInstructions) {
25226f7e940cSJason Eckhardt     const Record *InstDef = NumberedInstruction->TheDef;
25236f7e940cSJason Eckhardt     if (const RecordVal *RV = InstDef->getValue("EncodingInfos")) {
252462e2c7fbSRahul Joshi       if (const DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
2525df3765bfSSheng         EncodingInfoByHwMode EBM(DI->getDef(), HWM);
2526da1d3d8fSsuperZWT123         for (auto &[ModeId, Encoding] : EBM) {
2527da1d3d8fSsuperZWT123           // DecoderTables with DefaultMode should not have any suffix.
2528da1d3d8fSsuperZWT123           if (ModeId == DefaultMode) {
2529da1d3d8fSsuperZWT123             NumberedEncodings.emplace_back(Encoding, NumberedInstruction, "");
2530da1d3d8fSsuperZWT123           } else {
2531da1d3d8fSsuperZWT123             NumberedEncodings.emplace_back(Encoding, NumberedInstruction,
2532da1d3d8fSsuperZWT123                                            HWM.getMode(ModeId).Name);
2533da1d3d8fSsuperZWT123           }
2534da1d3d8fSsuperZWT123         }
2535df3765bfSSheng         continue;
2536df3765bfSSheng       }
2537df3765bfSSheng     }
2538da1d3d8fSsuperZWT123     // This instruction is encoded the same on all HwModes.
2539da1d3d8fSsuperZWT123     // According to user needs, provide varying degrees of suppression.
2540da1d3d8fSsuperZWT123     handleHwModesUnrelatedEncodings(NumberedInstruction, HwModeNames,
2541da1d3d8fSsuperZWT123                                     NamespacesWithHwModes, NumberedEncodings);
254205af9c83SJason Eckhardt   }
25432bb3621fSRahul Joshi   for (const Record *NumberedAlias :
2544b9079baaSPierre van Houtryve        RK.getAllDerivedDefinitions("AdditionalEncoding"))
2545df3765bfSSheng     NumberedEncodings.emplace_back(
2546df3765bfSSheng         NumberedAlias,
2547df3765bfSSheng         &Target.getInstruction(NumberedAlias->getValueAsDef("AliasOf")));
2548df3765bfSSheng 
2549df3765bfSSheng   std::map<std::pair<std::string, unsigned>, std::vector<EncodingIDAndOpcode>>
2550df3765bfSSheng       OpcMap;
2551df3765bfSSheng   std::map<unsigned, std::vector<OperandInfo>> Operands;
2552df3765bfSSheng   std::vector<unsigned> InstrLen;
25536f7e940cSJason Eckhardt   bool IsVarLenInst = Target.hasVariableLengthEncodings();
2554df3765bfSSheng   unsigned MaxInstLen = 0;
2555df3765bfSSheng 
2556e9492ccaSJason Eckhardt   for (const auto &[NEI, NumberedEncoding] : enumerate(NumberedEncodings)) {
2557e9492ccaSJason Eckhardt     const Record *EncodingDef = NumberedEncoding.EncodingDef;
2558e9492ccaSJason Eckhardt     const CodeGenInstruction *Inst = NumberedEncoding.Inst;
2559df3765bfSSheng     const Record *Def = Inst->TheDef;
2560df3765bfSSheng     unsigned Size = EncodingDef->getValueAsInt("Size");
2561df3765bfSSheng     if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
2562df3765bfSSheng         Def->getValueAsBit("isPseudo") ||
2563df3765bfSSheng         Def->getValueAsBit("isAsmParserOnly") ||
2564df3765bfSSheng         Def->getValueAsBit("isCodeGenOnly")) {
2565df3765bfSSheng       NumEncodingsLackingDisasm++;
2566df3765bfSSheng       continue;
2567df3765bfSSheng     }
2568df3765bfSSheng 
2569e9492ccaSJason Eckhardt     if (NEI < NumberedInstructions.size())
2570df3765bfSSheng       NumInstructions++;
2571df3765bfSSheng     NumEncodings++;
2572df3765bfSSheng 
2573df3765bfSSheng     if (!Size && !IsVarLenInst)
2574df3765bfSSheng       continue;
2575df3765bfSSheng 
2576df3765bfSSheng     if (IsVarLenInst)
2577df3765bfSSheng       InstrLen.resize(NumberedInstructions.size(), 0);
2578df3765bfSSheng 
2579e9492ccaSJason Eckhardt     if (unsigned Len = populateInstruction(Target, *EncodingDef, *Inst, NEI,
2580df3765bfSSheng                                            Operands, IsVarLenInst)) {
2581df3765bfSSheng       if (IsVarLenInst) {
2582df3765bfSSheng         MaxInstLen = std::max(MaxInstLen, Len);
2583e9492ccaSJason Eckhardt         InstrLen[NEI] = Len;
2584df3765bfSSheng       }
2585df3765bfSSheng       std::string DecoderNamespace =
2586df3765bfSSheng           std::string(EncodingDef->getValueAsString("DecoderNamespace"));
2587e9492ccaSJason Eckhardt       if (!NumberedEncoding.HwModeName.empty())
2588df3765bfSSheng         DecoderNamespace +=
2589e9492ccaSJason Eckhardt             std::string("_") + NumberedEncoding.HwModeName.str();
2590*4e8c9d28SJay Foad       OpcMap[{DecoderNamespace, Size}].emplace_back(
2591e9492ccaSJason Eckhardt           NEI, Target.getInstrIntValue(Def));
2592df3765bfSSheng     } else {
2593df3765bfSSheng       NumEncodingsOmitted++;
2594df3765bfSSheng     }
2595df3765bfSSheng   }
2596df3765bfSSheng 
2597df3765bfSSheng   DecoderTableInfo TableInfo;
2598df3765bfSSheng   for (const auto &Opc : OpcMap) {
2599df3765bfSSheng     // Emit the decoder for this namespace+width combination.
2600b9079baaSPierre van Houtryve     ArrayRef<EncodingAndInst> NumberedEncodingsRef(NumberedEncodings.data(),
2601b9079baaSPierre van Houtryve                                                    NumberedEncodings.size());
2602df3765bfSSheng     FilterChooser FC(NumberedEncodingsRef, Opc.second, Operands,
2603df3765bfSSheng                      IsVarLenInst ? MaxInstLen : 8 * Opc.first.second, this);
2604df3765bfSSheng 
2605df3765bfSSheng     // The decode table is cleared for each top level decoder function. The
2606df3765bfSSheng     // predicates and decoders themselves, however, are shared across all
2607df3765bfSSheng     // decoders to give more opportunities for uniqueing.
2608df3765bfSSheng     TableInfo.Table.clear();
2609df3765bfSSheng     TableInfo.FixupStack.clear();
2610df3765bfSSheng     TableInfo.Table.reserve(16384);
2611df3765bfSSheng     TableInfo.FixupStack.emplace_back();
2612df3765bfSSheng     FC.emitTableEntries(TableInfo);
2613df3765bfSSheng     // Any NumToSkip fixups in the top level scope can resolve to the
2614df3765bfSSheng     // OPC_Fail at the end of the table.
2615df3765bfSSheng     assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!");
2616df3765bfSSheng     // Resolve any NumToSkip fixups in the current scope.
2617df3765bfSSheng     resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
2618df3765bfSSheng                        TableInfo.Table.size());
2619df3765bfSSheng     TableInfo.FixupStack.clear();
2620df3765bfSSheng 
2621df3765bfSSheng     TableInfo.Table.push_back(MCD::OPC_Fail);
2622df3765bfSSheng 
2623df3765bfSSheng     // Print the table to the output stream.
2624708567abSRahul Joshi     emitTable(OS, TableInfo.Table, indent(0), FC.getBitWidth(), Opc.first.first,
26252ed0aacfSJason Eckhardt               Opc.second);
2626df3765bfSSheng   }
2627df3765bfSSheng 
2628df3765bfSSheng   // For variable instruction, we emit a instruction length table
2629df3765bfSSheng   // to let the decoder know how long the instructions are.
2630df3765bfSSheng   // You can see example usage in M68k's disassembler.
2631df3765bfSSheng   if (IsVarLenInst)
2632df3765bfSSheng     emitInstrLenTable(OS, InstrLen);
2633df3765bfSSheng   // Emit the predicate function.
2634708567abSRahul Joshi   emitPredicateFunction(OS, TableInfo.Predicates, indent(0));
2635df3765bfSSheng 
2636df3765bfSSheng   // Emit the decoder function.
2637708567abSRahul Joshi   emitDecoderFunction(OS, TableInfo.Decoders, indent(0));
2638df3765bfSSheng 
2639df3765bfSSheng   // Emit the main entry point for the decoder, decodeInstruction().
2640df3765bfSSheng   emitDecodeInstruction(OS, IsVarLenInst);
2641df3765bfSSheng 
2642df3765bfSSheng   OS << "\n} // end namespace llvm\n";
2643df3765bfSSheng }
2644df3765bfSSheng 
2645b594b930SRahul Joshi void llvm::EmitDecoder(const RecordKeeper &RK, raw_ostream &OS,
2646b594b930SRahul Joshi                        StringRef PredicateNamespace) {
26479a26f893SJames Y Knight   DecoderEmitter(RK, PredicateNamespace).run(OS);
2648df3765bfSSheng }
2649