xref: /freebsd-src/contrib/llvm-project/llvm/utils/TableGen/DecoderEmitter.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
181ad6265SDimitry Andric //===---------------- DecoderEmitter.cpp - Decoder Generator --------------===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric //
981ad6265SDimitry Andric // It contains the tablegen backend that emits the decoder functions for
1081ad6265SDimitry Andric // targets with fixed/variable length instruction set.
1181ad6265SDimitry Andric //
1281ad6265SDimitry Andric //===----------------------------------------------------------------------===//
1381ad6265SDimitry Andric 
14*06c3fb27SDimitry Andric #include "CodeGenHwModes.h"
1581ad6265SDimitry Andric #include "CodeGenInstruction.h"
1681ad6265SDimitry Andric #include "CodeGenTarget.h"
1781ad6265SDimitry Andric #include "InfoByHwMode.h"
18*06c3fb27SDimitry Andric #include "TableGenBackends.h"
1981ad6265SDimitry Andric #include "VarLenCodeEmitterGen.h"
2081ad6265SDimitry Andric #include "llvm/ADT/APInt.h"
2181ad6265SDimitry Andric #include "llvm/ADT/ArrayRef.h"
2281ad6265SDimitry Andric #include "llvm/ADT/CachedHashString.h"
2381ad6265SDimitry Andric #include "llvm/ADT/STLExtras.h"
2481ad6265SDimitry Andric #include "llvm/ADT/SetVector.h"
2581ad6265SDimitry Andric #include "llvm/ADT/SmallString.h"
2681ad6265SDimitry Andric #include "llvm/ADT/Statistic.h"
2781ad6265SDimitry Andric #include "llvm/ADT/StringExtras.h"
2881ad6265SDimitry Andric #include "llvm/ADT/StringRef.h"
2981ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
3081ad6265SDimitry Andric #include "llvm/Support/Casting.h"
3181ad6265SDimitry Andric #include "llvm/Support/Debug.h"
3281ad6265SDimitry Andric #include "llvm/Support/ErrorHandling.h"
3381ad6265SDimitry Andric #include "llvm/Support/FormattedStream.h"
3481ad6265SDimitry Andric #include "llvm/Support/LEB128.h"
3581ad6265SDimitry Andric #include "llvm/Support/raw_ostream.h"
3681ad6265SDimitry Andric #include "llvm/TableGen/Error.h"
3781ad6265SDimitry Andric #include "llvm/TableGen/Record.h"
3881ad6265SDimitry Andric #include <algorithm>
3981ad6265SDimitry Andric #include <cassert>
4081ad6265SDimitry Andric #include <cstddef>
4181ad6265SDimitry Andric #include <cstdint>
4281ad6265SDimitry Andric #include <map>
4381ad6265SDimitry Andric #include <memory>
4481ad6265SDimitry Andric #include <set>
4581ad6265SDimitry Andric #include <string>
4681ad6265SDimitry Andric #include <utility>
4781ad6265SDimitry Andric #include <vector>
4881ad6265SDimitry Andric 
4981ad6265SDimitry Andric using namespace llvm;
5081ad6265SDimitry Andric 
5181ad6265SDimitry Andric #define DEBUG_TYPE "decoder-emitter"
5281ad6265SDimitry Andric 
5381ad6265SDimitry Andric namespace {
5481ad6265SDimitry Andric 
5581ad6265SDimitry Andric STATISTIC(NumEncodings, "Number of encodings considered");
5681ad6265SDimitry Andric STATISTIC(NumEncodingsLackingDisasm, "Number of encodings without disassembler info");
5781ad6265SDimitry Andric STATISTIC(NumInstructions, "Number of instructions considered");
5881ad6265SDimitry Andric STATISTIC(NumEncodingsSupported, "Number of encodings supported");
5981ad6265SDimitry Andric STATISTIC(NumEncodingsOmitted, "Number of encodings omitted");
6081ad6265SDimitry Andric 
6181ad6265SDimitry Andric struct EncodingField {
6281ad6265SDimitry Andric   unsigned Base, Width, Offset;
6381ad6265SDimitry Andric   EncodingField(unsigned B, unsigned W, unsigned O)
6481ad6265SDimitry Andric     : Base(B), Width(W), Offset(O) { }
6581ad6265SDimitry Andric };
6681ad6265SDimitry Andric 
6781ad6265SDimitry Andric struct OperandInfo {
6881ad6265SDimitry Andric   std::vector<EncodingField> Fields;
6981ad6265SDimitry Andric   std::string Decoder;
7081ad6265SDimitry Andric   bool HasCompleteDecoder;
7181ad6265SDimitry Andric   uint64_t InitValue;
7281ad6265SDimitry Andric 
7381ad6265SDimitry Andric   OperandInfo(std::string D, bool HCD)
7481ad6265SDimitry Andric       : Decoder(std::move(D)), HasCompleteDecoder(HCD), InitValue(0) {}
7581ad6265SDimitry Andric 
7681ad6265SDimitry Andric   void addField(unsigned Base, unsigned Width, unsigned Offset) {
7781ad6265SDimitry Andric     Fields.push_back(EncodingField(Base, Width, Offset));
7881ad6265SDimitry Andric   }
7981ad6265SDimitry Andric 
8081ad6265SDimitry Andric   unsigned numFields() const { return Fields.size(); }
8181ad6265SDimitry Andric 
8281ad6265SDimitry Andric   typedef std::vector<EncodingField>::const_iterator const_iterator;
8381ad6265SDimitry Andric 
8481ad6265SDimitry Andric   const_iterator begin() const { return Fields.begin(); }
8581ad6265SDimitry Andric   const_iterator end() const   { return Fields.end();   }
8681ad6265SDimitry Andric };
8781ad6265SDimitry Andric 
8881ad6265SDimitry Andric typedef std::vector<uint8_t> DecoderTable;
8981ad6265SDimitry Andric typedef uint32_t DecoderFixup;
9081ad6265SDimitry Andric typedef std::vector<DecoderFixup> FixupList;
9181ad6265SDimitry Andric typedef std::vector<FixupList> FixupScopeList;
9281ad6265SDimitry Andric typedef SmallSetVector<CachedHashString, 16> PredicateSet;
9381ad6265SDimitry Andric typedef SmallSetVector<CachedHashString, 16> DecoderSet;
9481ad6265SDimitry Andric struct DecoderTableInfo {
9581ad6265SDimitry Andric   DecoderTable Table;
9681ad6265SDimitry Andric   FixupScopeList FixupStack;
9781ad6265SDimitry Andric   PredicateSet Predicates;
9881ad6265SDimitry Andric   DecoderSet Decoders;
9981ad6265SDimitry Andric };
10081ad6265SDimitry Andric 
10181ad6265SDimitry Andric struct EncodingAndInst {
10281ad6265SDimitry Andric   const Record *EncodingDef;
10381ad6265SDimitry Andric   const CodeGenInstruction *Inst;
10481ad6265SDimitry Andric   StringRef HwModeName;
10581ad6265SDimitry Andric 
10681ad6265SDimitry Andric   EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst,
10781ad6265SDimitry Andric                   StringRef HwModeName = "")
10881ad6265SDimitry Andric       : EncodingDef(EncodingDef), Inst(Inst), HwModeName(HwModeName) {}
10981ad6265SDimitry Andric };
11081ad6265SDimitry Andric 
11181ad6265SDimitry Andric struct EncodingIDAndOpcode {
11281ad6265SDimitry Andric   unsigned EncodingID;
11381ad6265SDimitry Andric   unsigned Opcode;
11481ad6265SDimitry Andric 
11581ad6265SDimitry Andric   EncodingIDAndOpcode() : EncodingID(0), Opcode(0) {}
11681ad6265SDimitry Andric   EncodingIDAndOpcode(unsigned EncodingID, unsigned Opcode)
11781ad6265SDimitry Andric       : EncodingID(EncodingID), Opcode(Opcode) {}
11881ad6265SDimitry Andric };
11981ad6265SDimitry Andric 
12081ad6265SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {
12181ad6265SDimitry Andric   if (Value.EncodingDef != Value.Inst->TheDef)
12281ad6265SDimitry Andric     OS << Value.EncodingDef->getName() << ":";
12381ad6265SDimitry Andric   OS << Value.Inst->TheDef->getName();
12481ad6265SDimitry Andric   return OS;
12581ad6265SDimitry Andric }
12681ad6265SDimitry Andric 
12781ad6265SDimitry Andric class DecoderEmitter {
12881ad6265SDimitry Andric   RecordKeeper &RK;
12981ad6265SDimitry Andric   std::vector<EncodingAndInst> NumberedEncodings;
13081ad6265SDimitry Andric 
13181ad6265SDimitry Andric public:
132bdd1243dSDimitry Andric   DecoderEmitter(RecordKeeper &R, std::string PredicateNamespace)
133bdd1243dSDimitry Andric       : RK(R), Target(R), PredicateNamespace(std::move(PredicateNamespace)) {}
13481ad6265SDimitry Andric 
13581ad6265SDimitry Andric   // Emit the decoder state machine table.
13681ad6265SDimitry Andric   void emitTable(formatted_raw_ostream &o, DecoderTable &Table,
13781ad6265SDimitry Andric                  unsigned Indentation, unsigned BitWidth,
13881ad6265SDimitry Andric                  StringRef Namespace) const;
13981ad6265SDimitry Andric   void emitInstrLenTable(formatted_raw_ostream &OS,
14081ad6265SDimitry Andric                          std::vector<unsigned> &InstrLen) const;
14181ad6265SDimitry Andric   void emitPredicateFunction(formatted_raw_ostream &OS,
14281ad6265SDimitry Andric                              PredicateSet &Predicates,
14381ad6265SDimitry Andric                              unsigned Indentation) const;
14481ad6265SDimitry Andric   void emitDecoderFunction(formatted_raw_ostream &OS,
14581ad6265SDimitry Andric                            DecoderSet &Decoders,
14681ad6265SDimitry Andric                            unsigned Indentation) const;
14781ad6265SDimitry Andric 
14881ad6265SDimitry Andric   // run - Output the code emitter
14981ad6265SDimitry Andric   void run(raw_ostream &o);
15081ad6265SDimitry Andric 
15181ad6265SDimitry Andric private:
15281ad6265SDimitry Andric   CodeGenTarget Target;
15381ad6265SDimitry Andric 
15481ad6265SDimitry Andric public:
15581ad6265SDimitry Andric   std::string PredicateNamespace;
15681ad6265SDimitry Andric };
15781ad6265SDimitry Andric 
15881ad6265SDimitry Andric } // end anonymous namespace
15981ad6265SDimitry Andric 
16081ad6265SDimitry Andric // The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system
16181ad6265SDimitry Andric // for a bit value.
16281ad6265SDimitry Andric //
16381ad6265SDimitry Andric // BIT_UNFILTERED is used as the init value for a filter position.  It is used
16481ad6265SDimitry Andric // only for filter processings.
16581ad6265SDimitry Andric typedef enum {
16681ad6265SDimitry Andric   BIT_TRUE,      // '1'
16781ad6265SDimitry Andric   BIT_FALSE,     // '0'
16881ad6265SDimitry Andric   BIT_UNSET,     // '?'
16981ad6265SDimitry Andric   BIT_UNFILTERED // unfiltered
17081ad6265SDimitry Andric } bit_value_t;
17181ad6265SDimitry Andric 
17281ad6265SDimitry Andric static bool ValueSet(bit_value_t V) {
17381ad6265SDimitry Andric   return (V == BIT_TRUE || V == BIT_FALSE);
17481ad6265SDimitry Andric }
17581ad6265SDimitry Andric 
17681ad6265SDimitry Andric static bool ValueNotSet(bit_value_t V) {
17781ad6265SDimitry Andric   return (V == BIT_UNSET);
17881ad6265SDimitry Andric }
17981ad6265SDimitry Andric 
18081ad6265SDimitry Andric static int Value(bit_value_t V) {
18181ad6265SDimitry Andric   return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1);
18281ad6265SDimitry Andric }
18381ad6265SDimitry Andric 
18481ad6265SDimitry Andric static bit_value_t bitFromBits(const BitsInit &bits, unsigned index) {
18581ad6265SDimitry Andric   if (BitInit *bit = dyn_cast<BitInit>(bits.getBit(index)))
18681ad6265SDimitry Andric     return bit->getValue() ? BIT_TRUE : BIT_FALSE;
18781ad6265SDimitry Andric 
18881ad6265SDimitry Andric   // The bit is uninitialized.
18981ad6265SDimitry Andric   return BIT_UNSET;
19081ad6265SDimitry Andric }
19181ad6265SDimitry Andric 
19281ad6265SDimitry Andric // Prints the bit value for each position.
19381ad6265SDimitry Andric static void dumpBits(raw_ostream &o, const BitsInit &bits) {
19481ad6265SDimitry Andric   for (unsigned index = bits.getNumBits(); index > 0; --index) {
19581ad6265SDimitry Andric     switch (bitFromBits(bits, index - 1)) {
19681ad6265SDimitry Andric     case BIT_TRUE:
19781ad6265SDimitry Andric       o << "1";
19881ad6265SDimitry Andric       break;
19981ad6265SDimitry Andric     case BIT_FALSE:
20081ad6265SDimitry Andric       o << "0";
20181ad6265SDimitry Andric       break;
20281ad6265SDimitry Andric     case BIT_UNSET:
20381ad6265SDimitry Andric       o << "_";
20481ad6265SDimitry Andric       break;
20581ad6265SDimitry Andric     default:
20681ad6265SDimitry Andric       llvm_unreachable("unexpected return value from bitFromBits");
20781ad6265SDimitry Andric     }
20881ad6265SDimitry Andric   }
20981ad6265SDimitry Andric }
21081ad6265SDimitry Andric 
21181ad6265SDimitry Andric static BitsInit &getBitsField(const Record &def, StringRef str) {
21281ad6265SDimitry Andric   const RecordVal *RV = def.getValue(str);
21381ad6265SDimitry Andric   if (BitsInit *Bits = dyn_cast<BitsInit>(RV->getValue()))
21481ad6265SDimitry Andric     return *Bits;
21581ad6265SDimitry Andric 
21681ad6265SDimitry Andric   // variable length instruction
21781ad6265SDimitry Andric   VarLenInst VLI = VarLenInst(cast<DagInit>(RV->getValue()), RV);
21881ad6265SDimitry Andric   SmallVector<Init *, 16> Bits;
21981ad6265SDimitry Andric 
22081ad6265SDimitry Andric   for (auto &SI : VLI) {
22181ad6265SDimitry Andric     if (const BitsInit *BI = dyn_cast<BitsInit>(SI.Value)) {
22281ad6265SDimitry Andric       for (unsigned Idx = 0U; Idx < BI->getNumBits(); ++Idx) {
22381ad6265SDimitry Andric         Bits.push_back(BI->getBit(Idx));
22481ad6265SDimitry Andric       }
22581ad6265SDimitry Andric     } else if (const BitInit *BI = dyn_cast<BitInit>(SI.Value)) {
22681ad6265SDimitry Andric       Bits.push_back(const_cast<BitInit *>(BI));
22781ad6265SDimitry Andric     } else {
22881ad6265SDimitry Andric       for (unsigned Idx = 0U; Idx < SI.BitWidth; ++Idx)
22981ad6265SDimitry Andric         Bits.push_back(UnsetInit::get(def.getRecords()));
23081ad6265SDimitry Andric     }
23181ad6265SDimitry Andric   }
23281ad6265SDimitry Andric 
23381ad6265SDimitry Andric   return *BitsInit::get(def.getRecords(), Bits);
23481ad6265SDimitry Andric }
23581ad6265SDimitry Andric 
23681ad6265SDimitry Andric // Representation of the instruction to work on.
23781ad6265SDimitry Andric typedef std::vector<bit_value_t> insn_t;
23881ad6265SDimitry Andric 
23981ad6265SDimitry Andric namespace {
24081ad6265SDimitry Andric 
24181ad6265SDimitry Andric static const uint64_t NO_FIXED_SEGMENTS_SENTINEL = -1ULL;
24281ad6265SDimitry Andric 
24381ad6265SDimitry Andric class FilterChooser;
24481ad6265SDimitry Andric 
24581ad6265SDimitry Andric /// Filter - Filter works with FilterChooser to produce the decoding tree for
24681ad6265SDimitry Andric /// the ISA.
24781ad6265SDimitry Andric ///
24881ad6265SDimitry Andric /// It is useful to think of a Filter as governing the switch stmts of the
24981ad6265SDimitry Andric /// decoding tree in a certain level.  Each case stmt delegates to an inferior
25081ad6265SDimitry Andric /// FilterChooser to decide what further decoding logic to employ, or in another
25181ad6265SDimitry Andric /// words, what other remaining bits to look at.  The FilterChooser eventually
25281ad6265SDimitry Andric /// chooses a best Filter to do its job.
25381ad6265SDimitry Andric ///
25481ad6265SDimitry Andric /// This recursive scheme ends when the number of Opcodes assigned to the
25581ad6265SDimitry Andric /// FilterChooser becomes 1 or if there is a conflict.  A conflict happens when
25681ad6265SDimitry Andric /// the Filter/FilterChooser combo does not know how to distinguish among the
25781ad6265SDimitry Andric /// Opcodes assigned.
25881ad6265SDimitry Andric ///
25981ad6265SDimitry Andric /// An example of a conflict is
26081ad6265SDimitry Andric ///
26181ad6265SDimitry Andric /// Conflict:
26281ad6265SDimitry Andric ///                     111101000.00........00010000....
26381ad6265SDimitry Andric ///                     111101000.00........0001........
26481ad6265SDimitry Andric ///                     1111010...00........0001........
26581ad6265SDimitry Andric ///                     1111010...00....................
26681ad6265SDimitry Andric ///                     1111010.........................
26781ad6265SDimitry Andric ///                     1111............................
26881ad6265SDimitry Andric ///                     ................................
26981ad6265SDimitry Andric ///     VST4q8a         111101000_00________00010000____
27081ad6265SDimitry Andric ///     VST4q8b         111101000_00________00010000____
27181ad6265SDimitry Andric ///
27281ad6265SDimitry Andric /// The Debug output shows the path that the decoding tree follows to reach the
27381ad6265SDimitry Andric /// the conclusion that there is a conflict.  VST4q8a is a vst4 to double-spaced
27481ad6265SDimitry Andric /// even registers, while VST4q8b is a vst4 to double-spaced odd registers.
27581ad6265SDimitry Andric ///
27681ad6265SDimitry Andric /// The encoding info in the .td files does not specify this meta information,
27781ad6265SDimitry Andric /// which could have been used by the decoder to resolve the conflict.  The
27881ad6265SDimitry Andric /// decoder could try to decode the even/odd register numbering and assign to
27981ad6265SDimitry Andric /// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a"
28081ad6265SDimitry Andric /// version and return the Opcode since the two have the same Asm format string.
28181ad6265SDimitry Andric class Filter {
28281ad6265SDimitry Andric protected:
28381ad6265SDimitry Andric   const FilterChooser *Owner;// points to the FilterChooser who owns this filter
28481ad6265SDimitry Andric   unsigned StartBit; // the starting bit position
28581ad6265SDimitry Andric   unsigned NumBits; // number of bits to filter
28681ad6265SDimitry Andric   bool Mixed; // a mixed region contains both set and unset bits
28781ad6265SDimitry Andric 
28881ad6265SDimitry Andric   // Map of well-known segment value to the set of uid's with that value.
28981ad6265SDimitry Andric   std::map<uint64_t, std::vector<EncodingIDAndOpcode>>
29081ad6265SDimitry Andric       FilteredInstructions;
29181ad6265SDimitry Andric 
29281ad6265SDimitry Andric   // Set of uid's with non-constant segment values.
29381ad6265SDimitry Andric   std::vector<EncodingIDAndOpcode> VariableInstructions;
29481ad6265SDimitry Andric 
29581ad6265SDimitry Andric   // Map of well-known segment value to its delegate.
29681ad6265SDimitry Andric   std::map<uint64_t, std::unique_ptr<const FilterChooser>> FilterChooserMap;
29781ad6265SDimitry Andric 
29881ad6265SDimitry Andric   // Number of instructions which fall under FilteredInstructions category.
29981ad6265SDimitry Andric   unsigned NumFiltered;
30081ad6265SDimitry Andric 
30181ad6265SDimitry Andric   // Keeps track of the last opcode in the filtered bucket.
30281ad6265SDimitry Andric   EncodingIDAndOpcode LastOpcFiltered;
30381ad6265SDimitry Andric 
30481ad6265SDimitry Andric public:
30581ad6265SDimitry Andric   Filter(Filter &&f);
30681ad6265SDimitry Andric   Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed);
30781ad6265SDimitry Andric 
30881ad6265SDimitry Andric   ~Filter() = default;
30981ad6265SDimitry Andric 
31081ad6265SDimitry Andric   unsigned getNumFiltered() const { return NumFiltered; }
31181ad6265SDimitry Andric 
31281ad6265SDimitry Andric   EncodingIDAndOpcode getSingletonOpc() const {
31381ad6265SDimitry Andric     assert(NumFiltered == 1);
31481ad6265SDimitry Andric     return LastOpcFiltered;
31581ad6265SDimitry Andric   }
31681ad6265SDimitry Andric 
31781ad6265SDimitry Andric   // Return the filter chooser for the group of instructions without constant
31881ad6265SDimitry Andric   // segment values.
31981ad6265SDimitry Andric   const FilterChooser &getVariableFC() const {
32081ad6265SDimitry Andric     assert(NumFiltered == 1);
32181ad6265SDimitry Andric     assert(FilterChooserMap.size() == 1);
32281ad6265SDimitry Andric     return *(FilterChooserMap.find(NO_FIXED_SEGMENTS_SENTINEL)->second);
32381ad6265SDimitry Andric   }
32481ad6265SDimitry Andric 
32581ad6265SDimitry Andric   // Divides the decoding task into sub tasks and delegates them to the
32681ad6265SDimitry Andric   // inferior FilterChooser's.
32781ad6265SDimitry Andric   //
32881ad6265SDimitry Andric   // A special case arises when there's only one entry in the filtered
32981ad6265SDimitry Andric   // instructions.  In order to unambiguously decode the singleton, we need to
33081ad6265SDimitry Andric   // match the remaining undecoded encoding bits against the singleton.
33181ad6265SDimitry Andric   void recurse();
33281ad6265SDimitry Andric 
33381ad6265SDimitry Andric   // Emit table entries to decode instructions given a segment or segments of
33481ad6265SDimitry Andric   // bits.
33581ad6265SDimitry Andric   void emitTableEntry(DecoderTableInfo &TableInfo) const;
33681ad6265SDimitry Andric 
33781ad6265SDimitry Andric   // Returns the number of fanout produced by the filter.  More fanout implies
33881ad6265SDimitry Andric   // the filter distinguishes more categories of instructions.
33981ad6265SDimitry Andric   unsigned usefulness() const;
34081ad6265SDimitry Andric }; // end class Filter
34181ad6265SDimitry Andric 
34281ad6265SDimitry Andric } // end anonymous namespace
34381ad6265SDimitry Andric 
34481ad6265SDimitry Andric // These are states of our finite state machines used in FilterChooser's
34581ad6265SDimitry Andric // filterProcessor() which produces the filter candidates to use.
34681ad6265SDimitry Andric typedef enum {
34781ad6265SDimitry Andric   ATTR_NONE,
34881ad6265SDimitry Andric   ATTR_FILTERED,
34981ad6265SDimitry Andric   ATTR_ALL_SET,
35081ad6265SDimitry Andric   ATTR_ALL_UNSET,
35181ad6265SDimitry Andric   ATTR_MIXED
35281ad6265SDimitry Andric } bitAttr_t;
35381ad6265SDimitry Andric 
35481ad6265SDimitry Andric /// FilterChooser - FilterChooser chooses the best filter among a set of Filters
35581ad6265SDimitry Andric /// in order to perform the decoding of instructions at the current level.
35681ad6265SDimitry Andric ///
35781ad6265SDimitry Andric /// Decoding proceeds from the top down.  Based on the well-known encoding bits
35881ad6265SDimitry Andric /// of instructions available, FilterChooser builds up the possible Filters that
35981ad6265SDimitry Andric /// can further the task of decoding by distinguishing among the remaining
36081ad6265SDimitry Andric /// candidate instructions.
36181ad6265SDimitry Andric ///
36281ad6265SDimitry Andric /// Once a filter has been chosen, it is called upon to divide the decoding task
36381ad6265SDimitry Andric /// into sub-tasks and delegates them to its inferior FilterChoosers for further
36481ad6265SDimitry Andric /// processings.
36581ad6265SDimitry Andric ///
36681ad6265SDimitry Andric /// It is useful to think of a Filter as governing the switch stmts of the
36781ad6265SDimitry Andric /// decoding tree.  And each case is delegated to an inferior FilterChooser to
36881ad6265SDimitry Andric /// decide what further remaining bits to look at.
36981ad6265SDimitry Andric namespace {
37081ad6265SDimitry Andric 
37181ad6265SDimitry Andric class FilterChooser {
37281ad6265SDimitry Andric protected:
37381ad6265SDimitry Andric   friend class Filter;
37481ad6265SDimitry Andric 
37581ad6265SDimitry Andric   // Vector of codegen instructions to choose our filter.
37681ad6265SDimitry Andric   ArrayRef<EncodingAndInst> AllInstructions;
37781ad6265SDimitry Andric 
37881ad6265SDimitry Andric   // Vector of uid's for this filter chooser to work on.
37981ad6265SDimitry Andric   // The first member of the pair is the opcode id being decoded, the second is
38081ad6265SDimitry Andric   // the opcode id that should be emitted.
38181ad6265SDimitry Andric   const std::vector<EncodingIDAndOpcode> &Opcodes;
38281ad6265SDimitry Andric 
38381ad6265SDimitry Andric   // Lookup table for the operand decoding of instructions.
38481ad6265SDimitry Andric   const std::map<unsigned, std::vector<OperandInfo>> &Operands;
38581ad6265SDimitry Andric 
38681ad6265SDimitry Andric   // Vector of candidate filters.
38781ad6265SDimitry Andric   std::vector<Filter> Filters;
38881ad6265SDimitry Andric 
38981ad6265SDimitry Andric   // Array of bit values passed down from our parent.
39081ad6265SDimitry Andric   // Set to all BIT_UNFILTERED's for Parent == NULL.
39181ad6265SDimitry Andric   std::vector<bit_value_t> FilterBitValues;
39281ad6265SDimitry Andric 
39381ad6265SDimitry Andric   // Links to the FilterChooser above us in the decoding tree.
39481ad6265SDimitry Andric   const FilterChooser *Parent;
39581ad6265SDimitry Andric 
39681ad6265SDimitry Andric   // Index of the best filter from Filters.
39781ad6265SDimitry Andric   int BestIndex;
39881ad6265SDimitry Andric 
39981ad6265SDimitry Andric   // Width of instructions
40081ad6265SDimitry Andric   unsigned BitWidth;
40181ad6265SDimitry Andric 
40281ad6265SDimitry Andric   // Parent emitter
40381ad6265SDimitry Andric   const DecoderEmitter *Emitter;
40481ad6265SDimitry Andric 
40581ad6265SDimitry Andric public:
40681ad6265SDimitry Andric   FilterChooser(ArrayRef<EncodingAndInst> Insts,
40781ad6265SDimitry Andric                 const std::vector<EncodingIDAndOpcode> &IDs,
40881ad6265SDimitry Andric                 const std::map<unsigned, std::vector<OperandInfo>> &Ops,
40981ad6265SDimitry Andric                 unsigned BW, const DecoderEmitter *E)
41081ad6265SDimitry Andric       : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
41181ad6265SDimitry Andric         FilterBitValues(BW, BIT_UNFILTERED), Parent(nullptr), BestIndex(-1),
41281ad6265SDimitry Andric         BitWidth(BW), Emitter(E) {
41381ad6265SDimitry Andric     doFilter();
41481ad6265SDimitry Andric   }
41581ad6265SDimitry Andric 
41681ad6265SDimitry Andric   FilterChooser(ArrayRef<EncodingAndInst> Insts,
41781ad6265SDimitry Andric                 const std::vector<EncodingIDAndOpcode> &IDs,
41881ad6265SDimitry Andric                 const std::map<unsigned, std::vector<OperandInfo>> &Ops,
41981ad6265SDimitry Andric                 const std::vector<bit_value_t> &ParentFilterBitValues,
42081ad6265SDimitry Andric                 const FilterChooser &parent)
42181ad6265SDimitry Andric       : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
42281ad6265SDimitry Andric         FilterBitValues(ParentFilterBitValues), Parent(&parent), BestIndex(-1),
42381ad6265SDimitry Andric         BitWidth(parent.BitWidth), Emitter(parent.Emitter) {
42481ad6265SDimitry Andric     doFilter();
42581ad6265SDimitry Andric   }
42681ad6265SDimitry Andric 
42781ad6265SDimitry Andric   FilterChooser(const FilterChooser &) = delete;
42881ad6265SDimitry Andric   void operator=(const FilterChooser &) = delete;
42981ad6265SDimitry Andric 
43081ad6265SDimitry Andric   unsigned getBitWidth() const { return BitWidth; }
43181ad6265SDimitry Andric 
43281ad6265SDimitry Andric protected:
43381ad6265SDimitry Andric   // Populates the insn given the uid.
43481ad6265SDimitry Andric   void insnWithID(insn_t &Insn, unsigned Opcode) const {
43581ad6265SDimitry Andric     BitsInit &Bits = getBitsField(*AllInstructions[Opcode].EncodingDef, "Inst");
43681ad6265SDimitry Andric     Insn.resize(BitWidth > Bits.getNumBits() ? BitWidth : Bits.getNumBits(),
43781ad6265SDimitry Andric                 BIT_UNSET);
43881ad6265SDimitry Andric     // We may have a SoftFail bitmask, which specifies a mask where an encoding
43981ad6265SDimitry Andric     // may differ from the value in "Inst" and yet still be valid, but the
44081ad6265SDimitry Andric     // disassembler should return SoftFail instead of Success.
44181ad6265SDimitry Andric     //
44281ad6265SDimitry Andric     // This is used for marking UNPREDICTABLE instructions in the ARM world.
44381ad6265SDimitry Andric     const RecordVal *RV =
44481ad6265SDimitry Andric         AllInstructions[Opcode].EncodingDef->getValue("SoftFail");
44581ad6265SDimitry Andric     const BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
44681ad6265SDimitry Andric     for (unsigned i = 0; i < Bits.getNumBits(); ++i) {
44781ad6265SDimitry Andric       if (SFBits && bitFromBits(*SFBits, i) == BIT_TRUE)
44881ad6265SDimitry Andric         Insn[i] = BIT_UNSET;
44981ad6265SDimitry Andric       else
45081ad6265SDimitry Andric         Insn[i] = bitFromBits(Bits, i);
45181ad6265SDimitry Andric     }
45281ad6265SDimitry Andric   }
45381ad6265SDimitry Andric 
45481ad6265SDimitry Andric   // Emit the name of the encoding/instruction pair.
45581ad6265SDimitry Andric   void emitNameWithID(raw_ostream &OS, unsigned Opcode) const {
45681ad6265SDimitry Andric     const Record *EncodingDef = AllInstructions[Opcode].EncodingDef;
45781ad6265SDimitry Andric     const Record *InstDef = AllInstructions[Opcode].Inst->TheDef;
45881ad6265SDimitry Andric     if (EncodingDef != InstDef)
45981ad6265SDimitry Andric       OS << EncodingDef->getName() << ":";
46081ad6265SDimitry Andric     OS << InstDef->getName();
46181ad6265SDimitry Andric   }
46281ad6265SDimitry Andric 
46381ad6265SDimitry Andric   // Populates the field of the insn given the start position and the number of
46481ad6265SDimitry Andric   // consecutive bits to scan for.
46581ad6265SDimitry Andric   //
46681ad6265SDimitry Andric   // Returns false if there exists any uninitialized bit value in the range.
46781ad6265SDimitry Andric   // Returns true, otherwise.
46881ad6265SDimitry Andric   bool fieldFromInsn(uint64_t &Field, insn_t &Insn, unsigned StartBit,
46981ad6265SDimitry Andric                      unsigned NumBits) const;
47081ad6265SDimitry Andric 
47181ad6265SDimitry Andric   /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
47281ad6265SDimitry Andric   /// filter array as a series of chars.
47381ad6265SDimitry Andric   void dumpFilterArray(raw_ostream &o,
47481ad6265SDimitry Andric                        const std::vector<bit_value_t> & filter) const;
47581ad6265SDimitry Andric 
47681ad6265SDimitry Andric   /// dumpStack - dumpStack traverses the filter chooser chain and calls
47781ad6265SDimitry Andric   /// dumpFilterArray on each filter chooser up to the top level one.
47881ad6265SDimitry Andric   void dumpStack(raw_ostream &o, const char *prefix) const;
47981ad6265SDimitry Andric 
48081ad6265SDimitry Andric   Filter &bestFilter() {
48181ad6265SDimitry Andric     assert(BestIndex != -1 && "BestIndex not set");
48281ad6265SDimitry Andric     return Filters[BestIndex];
48381ad6265SDimitry Andric   }
48481ad6265SDimitry Andric 
48581ad6265SDimitry Andric   bool PositionFiltered(unsigned i) const {
48681ad6265SDimitry Andric     return ValueSet(FilterBitValues[i]);
48781ad6265SDimitry Andric   }
48881ad6265SDimitry Andric 
48981ad6265SDimitry Andric   // Calculates the island(s) needed to decode the instruction.
49081ad6265SDimitry Andric   // This returns a lit of undecoded bits of an instructions, for example,
49181ad6265SDimitry Andric   // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
49281ad6265SDimitry Andric   // decoded bits in order to verify that the instruction matches the Opcode.
49381ad6265SDimitry Andric   unsigned getIslands(std::vector<unsigned> &StartBits,
49481ad6265SDimitry Andric                       std::vector<unsigned> &EndBits,
49581ad6265SDimitry Andric                       std::vector<uint64_t> &FieldVals,
49681ad6265SDimitry Andric                       const insn_t &Insn) const;
49781ad6265SDimitry Andric 
49881ad6265SDimitry Andric   // Emits code to check the Predicates member of an instruction are true.
49981ad6265SDimitry Andric   // Returns true if predicate matches were emitted, false otherwise.
50081ad6265SDimitry Andric   bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
50181ad6265SDimitry Andric                           unsigned Opc) const;
50281ad6265SDimitry Andric   bool emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
50381ad6265SDimitry Andric                              raw_ostream &OS) const;
50481ad6265SDimitry Andric 
50581ad6265SDimitry Andric   bool doesOpcodeNeedPredicate(unsigned Opc) const;
50681ad6265SDimitry Andric   unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const;
50781ad6265SDimitry Andric   void emitPredicateTableEntry(DecoderTableInfo &TableInfo,
50881ad6265SDimitry Andric                                unsigned Opc) const;
50981ad6265SDimitry Andric 
51081ad6265SDimitry Andric   void emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
51181ad6265SDimitry Andric                               unsigned Opc) const;
51281ad6265SDimitry Andric 
51381ad6265SDimitry Andric   // Emits table entries to decode the singleton.
51481ad6265SDimitry Andric   void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
51581ad6265SDimitry Andric                                EncodingIDAndOpcode Opc) const;
51681ad6265SDimitry Andric 
51781ad6265SDimitry Andric   // Emits code to decode the singleton, and then to decode the rest.
51881ad6265SDimitry Andric   void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
51981ad6265SDimitry Andric                                const Filter &Best) const;
52081ad6265SDimitry Andric 
52181ad6265SDimitry Andric   void emitBinaryParser(raw_ostream &o, unsigned &Indentation,
52281ad6265SDimitry Andric                         const OperandInfo &OpInfo,
52381ad6265SDimitry Andric                         bool &OpHasCompleteDecoder) const;
52481ad6265SDimitry Andric 
52581ad6265SDimitry Andric   void emitDecoder(raw_ostream &OS, unsigned Indentation, unsigned Opc,
52681ad6265SDimitry Andric                    bool &HasCompleteDecoder) const;
52781ad6265SDimitry Andric   unsigned getDecoderIndex(DecoderSet &Decoders, unsigned Opc,
52881ad6265SDimitry Andric                            bool &HasCompleteDecoder) const;
52981ad6265SDimitry Andric 
53081ad6265SDimitry Andric   // Assign a single filter and run with it.
53181ad6265SDimitry Andric   void runSingleFilter(unsigned startBit, unsigned numBit, bool mixed);
53281ad6265SDimitry Andric 
53381ad6265SDimitry Andric   // reportRegion is a helper function for filterProcessor to mark a region as
53481ad6265SDimitry Andric   // eligible for use as a filter region.
53581ad6265SDimitry Andric   void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex,
53681ad6265SDimitry Andric                     bool AllowMixed);
53781ad6265SDimitry Andric 
53881ad6265SDimitry Andric   // FilterProcessor scans the well-known encoding bits of the instructions and
53981ad6265SDimitry Andric   // builds up a list of candidate filters.  It chooses the best filter and
54081ad6265SDimitry Andric   // recursively descends down the decoding tree.
54181ad6265SDimitry Andric   bool filterProcessor(bool AllowMixed, bool Greedy = true);
54281ad6265SDimitry Andric 
54381ad6265SDimitry Andric   // Decides on the best configuration of filter(s) to use in order to decode
54481ad6265SDimitry Andric   // the instructions.  A conflict of instructions may occur, in which case we
54581ad6265SDimitry Andric   // dump the conflict set to the standard error.
54681ad6265SDimitry Andric   void doFilter();
54781ad6265SDimitry Andric 
54881ad6265SDimitry Andric public:
54981ad6265SDimitry Andric   // emitTableEntries - Emit state machine entries to decode our share of
55081ad6265SDimitry Andric   // instructions.
55181ad6265SDimitry Andric   void emitTableEntries(DecoderTableInfo &TableInfo) const;
55281ad6265SDimitry Andric };
55381ad6265SDimitry Andric 
55481ad6265SDimitry Andric } // end anonymous namespace
55581ad6265SDimitry Andric 
55681ad6265SDimitry Andric ///////////////////////////
55781ad6265SDimitry Andric //                       //
55881ad6265SDimitry Andric // Filter Implementation //
55981ad6265SDimitry Andric //                       //
56081ad6265SDimitry Andric ///////////////////////////
56181ad6265SDimitry Andric 
56281ad6265SDimitry Andric Filter::Filter(Filter &&f)
56381ad6265SDimitry Andric   : Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed),
56481ad6265SDimitry Andric     FilteredInstructions(std::move(f.FilteredInstructions)),
56581ad6265SDimitry Andric     VariableInstructions(std::move(f.VariableInstructions)),
56681ad6265SDimitry Andric     FilterChooserMap(std::move(f.FilterChooserMap)), NumFiltered(f.NumFiltered),
56781ad6265SDimitry Andric     LastOpcFiltered(f.LastOpcFiltered) {
56881ad6265SDimitry Andric }
56981ad6265SDimitry Andric 
57081ad6265SDimitry Andric Filter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits,
57181ad6265SDimitry Andric                bool mixed)
57281ad6265SDimitry Andric   : Owner(&owner), StartBit(startBit), NumBits(numBits), Mixed(mixed) {
57381ad6265SDimitry Andric   assert(StartBit + NumBits - 1 < Owner->BitWidth);
57481ad6265SDimitry Andric 
57581ad6265SDimitry Andric   NumFiltered = 0;
57681ad6265SDimitry Andric   LastOpcFiltered = {0, 0};
57781ad6265SDimitry Andric 
57881ad6265SDimitry Andric   for (unsigned i = 0, e = Owner->Opcodes.size(); i != e; ++i) {
57981ad6265SDimitry Andric     insn_t Insn;
58081ad6265SDimitry Andric 
58181ad6265SDimitry Andric     // Populates the insn given the uid.
58281ad6265SDimitry Andric     Owner->insnWithID(Insn, Owner->Opcodes[i].EncodingID);
58381ad6265SDimitry Andric 
58481ad6265SDimitry Andric     uint64_t Field;
58581ad6265SDimitry Andric     // Scans the segment for possibly well-specified encoding bits.
58681ad6265SDimitry Andric     bool ok = Owner->fieldFromInsn(Field, Insn, StartBit, NumBits);
58781ad6265SDimitry Andric 
58881ad6265SDimitry Andric     if (ok) {
58981ad6265SDimitry Andric       // The encoding bits are well-known.  Lets add the uid of the
59081ad6265SDimitry Andric       // instruction into the bucket keyed off the constant field value.
59181ad6265SDimitry Andric       LastOpcFiltered = Owner->Opcodes[i];
59281ad6265SDimitry Andric       FilteredInstructions[Field].push_back(LastOpcFiltered);
59381ad6265SDimitry Andric       ++NumFiltered;
59481ad6265SDimitry Andric     } else {
59581ad6265SDimitry Andric       // Some of the encoding bit(s) are unspecified.  This contributes to
59681ad6265SDimitry Andric       // one additional member of "Variable" instructions.
59781ad6265SDimitry Andric       VariableInstructions.push_back(Owner->Opcodes[i]);
59881ad6265SDimitry Andric     }
59981ad6265SDimitry Andric   }
60081ad6265SDimitry Andric 
60181ad6265SDimitry Andric   assert((FilteredInstructions.size() + VariableInstructions.size() > 0)
60281ad6265SDimitry Andric          && "Filter returns no instruction categories");
60381ad6265SDimitry Andric }
60481ad6265SDimitry Andric 
60581ad6265SDimitry Andric // Divides the decoding task into sub tasks and delegates them to the
60681ad6265SDimitry Andric // inferior FilterChooser's.
60781ad6265SDimitry Andric //
60881ad6265SDimitry Andric // A special case arises when there's only one entry in the filtered
60981ad6265SDimitry Andric // instructions.  In order to unambiguously decode the singleton, we need to
61081ad6265SDimitry Andric // match the remaining undecoded encoding bits against the singleton.
61181ad6265SDimitry Andric void Filter::recurse() {
61281ad6265SDimitry Andric   // Starts by inheriting our parent filter chooser's filter bit values.
61381ad6265SDimitry Andric   std::vector<bit_value_t> BitValueArray(Owner->FilterBitValues);
61481ad6265SDimitry Andric 
61581ad6265SDimitry Andric   if (!VariableInstructions.empty()) {
61681ad6265SDimitry Andric     // Conservatively marks each segment position as BIT_UNSET.
61781ad6265SDimitry Andric     for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex)
61881ad6265SDimitry Andric       BitValueArray[StartBit + bitIndex] = BIT_UNSET;
61981ad6265SDimitry Andric 
62081ad6265SDimitry Andric     // Delegates to an inferior filter chooser for further processing on this
62181ad6265SDimitry Andric     // group of instructions whose segment values are variable.
62281ad6265SDimitry Andric     FilterChooserMap.insert(std::make_pair(NO_FIXED_SEGMENTS_SENTINEL,
62381ad6265SDimitry Andric         std::make_unique<FilterChooser>(Owner->AllInstructions,
62481ad6265SDimitry Andric             VariableInstructions, Owner->Operands, BitValueArray, *Owner)));
62581ad6265SDimitry Andric   }
62681ad6265SDimitry Andric 
62781ad6265SDimitry Andric   // No need to recurse for a singleton filtered instruction.
62881ad6265SDimitry Andric   // See also Filter::emit*().
62981ad6265SDimitry Andric   if (getNumFiltered() == 1) {
63081ad6265SDimitry Andric     assert(FilterChooserMap.size() == 1);
63181ad6265SDimitry Andric     return;
63281ad6265SDimitry Andric   }
63381ad6265SDimitry Andric 
63481ad6265SDimitry Andric   // Otherwise, create sub choosers.
63581ad6265SDimitry Andric   for (const auto &Inst : FilteredInstructions) {
63681ad6265SDimitry Andric 
63781ad6265SDimitry Andric     // Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
63881ad6265SDimitry Andric     for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) {
63981ad6265SDimitry Andric       if (Inst.first & (1ULL << bitIndex))
64081ad6265SDimitry Andric         BitValueArray[StartBit + bitIndex] = BIT_TRUE;
64181ad6265SDimitry Andric       else
64281ad6265SDimitry Andric         BitValueArray[StartBit + bitIndex] = BIT_FALSE;
64381ad6265SDimitry Andric     }
64481ad6265SDimitry Andric 
64581ad6265SDimitry Andric     // Delegates to an inferior filter chooser for further processing on this
64681ad6265SDimitry Andric     // category of instructions.
64781ad6265SDimitry Andric     FilterChooserMap.insert(std::make_pair(
64881ad6265SDimitry Andric         Inst.first, std::make_unique<FilterChooser>(
64981ad6265SDimitry Andric                                 Owner->AllInstructions, Inst.second,
65081ad6265SDimitry Andric                                 Owner->Operands, BitValueArray, *Owner)));
65181ad6265SDimitry Andric   }
65281ad6265SDimitry Andric }
65381ad6265SDimitry Andric 
65481ad6265SDimitry Andric static void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups,
65581ad6265SDimitry Andric                                uint32_t DestIdx) {
65681ad6265SDimitry Andric   // Any NumToSkip fixups in the current scope can resolve to the
65781ad6265SDimitry Andric   // current location.
65881ad6265SDimitry Andric   for (FixupList::const_reverse_iterator I = Fixups.rbegin(),
65981ad6265SDimitry Andric                                          E = Fixups.rend();
66081ad6265SDimitry Andric        I != E; ++I) {
66181ad6265SDimitry Andric     // Calculate the distance from the byte following the fixup entry byte
66281ad6265SDimitry Andric     // to the destination. The Target is calculated from after the 16-bit
66381ad6265SDimitry Andric     // NumToSkip entry itself, so subtract two  from the displacement here
66481ad6265SDimitry Andric     // to account for that.
66581ad6265SDimitry Andric     uint32_t FixupIdx = *I;
66681ad6265SDimitry Andric     uint32_t Delta = DestIdx - FixupIdx - 3;
66781ad6265SDimitry Andric     // Our NumToSkip entries are 24-bits. Make sure our table isn't too
66881ad6265SDimitry Andric     // big.
66981ad6265SDimitry Andric     assert(Delta < (1u << 24));
67081ad6265SDimitry Andric     Table[FixupIdx] = (uint8_t)Delta;
67181ad6265SDimitry Andric     Table[FixupIdx + 1] = (uint8_t)(Delta >> 8);
67281ad6265SDimitry Andric     Table[FixupIdx + 2] = (uint8_t)(Delta >> 16);
67381ad6265SDimitry Andric   }
67481ad6265SDimitry Andric }
67581ad6265SDimitry Andric 
67681ad6265SDimitry Andric // Emit table entries to decode instructions given a segment or segments
67781ad6265SDimitry Andric // of bits.
67881ad6265SDimitry Andric void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
67981ad6265SDimitry Andric   TableInfo.Table.push_back(MCD::OPC_ExtractField);
68081ad6265SDimitry Andric   TableInfo.Table.push_back(StartBit);
68181ad6265SDimitry Andric   TableInfo.Table.push_back(NumBits);
68281ad6265SDimitry Andric 
68381ad6265SDimitry Andric   // A new filter entry begins a new scope for fixup resolution.
68481ad6265SDimitry Andric   TableInfo.FixupStack.emplace_back();
68581ad6265SDimitry Andric 
68681ad6265SDimitry Andric   DecoderTable &Table = TableInfo.Table;
68781ad6265SDimitry Andric 
68881ad6265SDimitry Andric   size_t PrevFilter = 0;
68981ad6265SDimitry Andric   bool HasFallthrough = false;
69081ad6265SDimitry Andric   for (auto &Filter : FilterChooserMap) {
69181ad6265SDimitry Andric     // Field value -1 implies a non-empty set of variable instructions.
69281ad6265SDimitry Andric     // See also recurse().
69381ad6265SDimitry Andric     if (Filter.first == NO_FIXED_SEGMENTS_SENTINEL) {
69481ad6265SDimitry Andric       HasFallthrough = true;
69581ad6265SDimitry Andric 
69681ad6265SDimitry Andric       // Each scope should always have at least one filter value to check
69781ad6265SDimitry Andric       // for.
69881ad6265SDimitry Andric       assert(PrevFilter != 0 && "empty filter set!");
69981ad6265SDimitry Andric       FixupList &CurScope = TableInfo.FixupStack.back();
70081ad6265SDimitry Andric       // Resolve any NumToSkip fixups in the current scope.
70181ad6265SDimitry Andric       resolveTableFixups(Table, CurScope, Table.size());
70281ad6265SDimitry Andric       CurScope.clear();
70381ad6265SDimitry Andric       PrevFilter = 0;  // Don't re-process the filter's fallthrough.
70481ad6265SDimitry Andric     } else {
70581ad6265SDimitry Andric       Table.push_back(MCD::OPC_FilterValue);
70681ad6265SDimitry Andric       // Encode and emit the value to filter against.
70781ad6265SDimitry Andric       uint8_t Buffer[16];
70881ad6265SDimitry Andric       unsigned Len = encodeULEB128(Filter.first, Buffer);
70981ad6265SDimitry Andric       Table.insert(Table.end(), Buffer, Buffer + Len);
71081ad6265SDimitry Andric       // Reserve space for the NumToSkip entry. We'll backpatch the value
71181ad6265SDimitry Andric       // later.
71281ad6265SDimitry Andric       PrevFilter = Table.size();
71381ad6265SDimitry Andric       Table.push_back(0);
71481ad6265SDimitry Andric       Table.push_back(0);
71581ad6265SDimitry Andric       Table.push_back(0);
71681ad6265SDimitry Andric     }
71781ad6265SDimitry Andric 
71881ad6265SDimitry Andric     // We arrive at a category of instructions with the same segment value.
71981ad6265SDimitry Andric     // Now delegate to the sub filter chooser for further decodings.
72081ad6265SDimitry Andric     // The case may fallthrough, which happens if the remaining well-known
72181ad6265SDimitry Andric     // encoding bits do not match exactly.
72281ad6265SDimitry Andric     Filter.second->emitTableEntries(TableInfo);
72381ad6265SDimitry Andric 
72481ad6265SDimitry Andric     // Now that we've emitted the body of the handler, update the NumToSkip
72581ad6265SDimitry Andric     // of the filter itself to be able to skip forward when false. Subtract
72681ad6265SDimitry Andric     // two as to account for the width of the NumToSkip field itself.
72781ad6265SDimitry Andric     if (PrevFilter) {
72881ad6265SDimitry Andric       uint32_t NumToSkip = Table.size() - PrevFilter - 3;
72981ad6265SDimitry Andric       assert(NumToSkip < (1u << 24) && "disassembler decoding table too large!");
73081ad6265SDimitry Andric       Table[PrevFilter] = (uint8_t)NumToSkip;
73181ad6265SDimitry Andric       Table[PrevFilter + 1] = (uint8_t)(NumToSkip >> 8);
73281ad6265SDimitry Andric       Table[PrevFilter + 2] = (uint8_t)(NumToSkip >> 16);
73381ad6265SDimitry Andric     }
73481ad6265SDimitry Andric   }
73581ad6265SDimitry Andric 
73681ad6265SDimitry Andric   // Any remaining unresolved fixups bubble up to the parent fixup scope.
73781ad6265SDimitry Andric   assert(TableInfo.FixupStack.size() > 1 && "fixup stack underflow!");
73881ad6265SDimitry Andric   FixupScopeList::iterator Source = TableInfo.FixupStack.end() - 1;
73981ad6265SDimitry Andric   FixupScopeList::iterator Dest = Source - 1;
74081ad6265SDimitry Andric   llvm::append_range(*Dest, *Source);
74181ad6265SDimitry Andric   TableInfo.FixupStack.pop_back();
74281ad6265SDimitry Andric 
74381ad6265SDimitry Andric   // If there is no fallthrough, then the final filter should get fixed
74481ad6265SDimitry Andric   // up according to the enclosing scope rather than the current position.
74581ad6265SDimitry Andric   if (!HasFallthrough)
74681ad6265SDimitry Andric     TableInfo.FixupStack.back().push_back(PrevFilter);
74781ad6265SDimitry Andric }
74881ad6265SDimitry Andric 
74981ad6265SDimitry Andric // Returns the number of fanout produced by the filter.  More fanout implies
75081ad6265SDimitry Andric // the filter distinguishes more categories of instructions.
75181ad6265SDimitry Andric unsigned Filter::usefulness() const {
75281ad6265SDimitry Andric   if (!VariableInstructions.empty())
75381ad6265SDimitry Andric     return FilteredInstructions.size();
75481ad6265SDimitry Andric   else
75581ad6265SDimitry Andric     return FilteredInstructions.size() + 1;
75681ad6265SDimitry Andric }
75781ad6265SDimitry Andric 
75881ad6265SDimitry Andric //////////////////////////////////
75981ad6265SDimitry Andric //                              //
76081ad6265SDimitry Andric // Filterchooser Implementation //
76181ad6265SDimitry Andric //                              //
76281ad6265SDimitry Andric //////////////////////////////////
76381ad6265SDimitry Andric 
76481ad6265SDimitry Andric // Emit the decoder state machine table.
76581ad6265SDimitry Andric void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
76681ad6265SDimitry Andric                                unsigned Indentation, unsigned BitWidth,
76781ad6265SDimitry Andric                                StringRef Namespace) const {
76881ad6265SDimitry Andric   OS.indent(Indentation) << "static const uint8_t DecoderTable" << Namespace
76981ad6265SDimitry Andric     << BitWidth << "[] = {\n";
77081ad6265SDimitry Andric 
77181ad6265SDimitry Andric   Indentation += 2;
77281ad6265SDimitry Andric 
77381ad6265SDimitry Andric   // FIXME: We may be able to use the NumToSkip values to recover
77481ad6265SDimitry Andric   // appropriate indentation levels.
77581ad6265SDimitry Andric   DecoderTable::const_iterator I = Table.begin();
77681ad6265SDimitry Andric   DecoderTable::const_iterator E = Table.end();
77781ad6265SDimitry Andric   while (I != E) {
77881ad6265SDimitry Andric     assert (I < E && "incomplete decode table entry!");
77981ad6265SDimitry Andric 
78081ad6265SDimitry Andric     uint64_t Pos = I - Table.begin();
78181ad6265SDimitry Andric     OS << "/* " << Pos << " */";
78281ad6265SDimitry Andric     OS.PadToColumn(12);
78381ad6265SDimitry Andric 
78481ad6265SDimitry Andric     switch (*I) {
78581ad6265SDimitry Andric     default:
78681ad6265SDimitry Andric       PrintFatalError("invalid decode table opcode");
78781ad6265SDimitry Andric     case MCD::OPC_ExtractField: {
78881ad6265SDimitry Andric       ++I;
78981ad6265SDimitry Andric       unsigned Start = *I++;
79081ad6265SDimitry Andric       unsigned Len = *I++;
79181ad6265SDimitry Andric       OS.indent(Indentation) << "MCD::OPC_ExtractField, " << Start << ", "
79281ad6265SDimitry Andric         << Len << ",  // Inst{";
79381ad6265SDimitry Andric       if (Len > 1)
79481ad6265SDimitry Andric         OS << (Start + Len - 1) << "-";
79581ad6265SDimitry Andric       OS << Start << "} ...\n";
79681ad6265SDimitry Andric       break;
79781ad6265SDimitry Andric     }
79881ad6265SDimitry Andric     case MCD::OPC_FilterValue: {
79981ad6265SDimitry Andric       ++I;
80081ad6265SDimitry Andric       OS.indent(Indentation) << "MCD::OPC_FilterValue, ";
80181ad6265SDimitry Andric       // The filter value is ULEB128 encoded.
80281ad6265SDimitry Andric       while (*I >= 128)
80381ad6265SDimitry Andric         OS << (unsigned)*I++ << ", ";
80481ad6265SDimitry Andric       OS << (unsigned)*I++ << ", ";
80581ad6265SDimitry Andric 
80681ad6265SDimitry Andric       // 24-bit numtoskip value.
80781ad6265SDimitry Andric       uint8_t Byte = *I++;
80881ad6265SDimitry Andric       uint32_t NumToSkip = Byte;
80981ad6265SDimitry Andric       OS << (unsigned)Byte << ", ";
81081ad6265SDimitry Andric       Byte = *I++;
81181ad6265SDimitry Andric       OS << (unsigned)Byte << ", ";
81281ad6265SDimitry Andric       NumToSkip |= Byte << 8;
81381ad6265SDimitry Andric       Byte = *I++;
81481ad6265SDimitry Andric       OS << utostr(Byte) << ", ";
81581ad6265SDimitry Andric       NumToSkip |= Byte << 16;
81681ad6265SDimitry Andric       OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
81781ad6265SDimitry Andric       break;
81881ad6265SDimitry Andric     }
81981ad6265SDimitry Andric     case MCD::OPC_CheckField: {
82081ad6265SDimitry Andric       ++I;
82181ad6265SDimitry Andric       unsigned Start = *I++;
82281ad6265SDimitry Andric       unsigned Len = *I++;
82381ad6265SDimitry Andric       OS.indent(Indentation) << "MCD::OPC_CheckField, " << Start << ", "
82481ad6265SDimitry Andric         << Len << ", ";// << Val << ", " << NumToSkip << ",\n";
82581ad6265SDimitry Andric       // ULEB128 encoded field value.
82681ad6265SDimitry Andric       for (; *I >= 128; ++I)
82781ad6265SDimitry Andric         OS << (unsigned)*I << ", ";
82881ad6265SDimitry Andric       OS << (unsigned)*I++ << ", ";
82981ad6265SDimitry Andric       // 24-bit numtoskip value.
83081ad6265SDimitry Andric       uint8_t Byte = *I++;
83181ad6265SDimitry Andric       uint32_t NumToSkip = Byte;
83281ad6265SDimitry Andric       OS << (unsigned)Byte << ", ";
83381ad6265SDimitry Andric       Byte = *I++;
83481ad6265SDimitry Andric       OS << (unsigned)Byte << ", ";
83581ad6265SDimitry Andric       NumToSkip |= Byte << 8;
83681ad6265SDimitry Andric       Byte = *I++;
83781ad6265SDimitry Andric       OS << utostr(Byte) << ", ";
83881ad6265SDimitry Andric       NumToSkip |= Byte << 16;
83981ad6265SDimitry Andric       OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
84081ad6265SDimitry Andric       break;
84181ad6265SDimitry Andric     }
84281ad6265SDimitry Andric     case MCD::OPC_CheckPredicate: {
84381ad6265SDimitry Andric       ++I;
84481ad6265SDimitry Andric       OS.indent(Indentation) << "MCD::OPC_CheckPredicate, ";
84581ad6265SDimitry Andric       for (; *I >= 128; ++I)
84681ad6265SDimitry Andric         OS << (unsigned)*I << ", ";
84781ad6265SDimitry Andric       OS << (unsigned)*I++ << ", ";
84881ad6265SDimitry Andric 
84981ad6265SDimitry Andric       // 24-bit numtoskip value.
85081ad6265SDimitry Andric       uint8_t Byte = *I++;
85181ad6265SDimitry Andric       uint32_t NumToSkip = Byte;
85281ad6265SDimitry Andric       OS << (unsigned)Byte << ", ";
85381ad6265SDimitry Andric       Byte = *I++;
85481ad6265SDimitry Andric       OS << (unsigned)Byte << ", ";
85581ad6265SDimitry Andric       NumToSkip |= Byte << 8;
85681ad6265SDimitry Andric       Byte = *I++;
85781ad6265SDimitry Andric       OS << utostr(Byte) << ", ";
85881ad6265SDimitry Andric       NumToSkip |= Byte << 16;
85981ad6265SDimitry Andric       OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
86081ad6265SDimitry Andric       break;
86181ad6265SDimitry Andric     }
86281ad6265SDimitry Andric     case MCD::OPC_Decode:
86381ad6265SDimitry Andric     case MCD::OPC_TryDecode: {
86481ad6265SDimitry Andric       bool IsTry = *I == MCD::OPC_TryDecode;
86581ad6265SDimitry Andric       ++I;
86681ad6265SDimitry Andric       // Extract the ULEB128 encoded Opcode to a buffer.
86781ad6265SDimitry Andric       uint8_t Buffer[16], *p = Buffer;
86881ad6265SDimitry Andric       while ((*p++ = *I++) >= 128)
86981ad6265SDimitry Andric         assert((p - Buffer) <= (ptrdiff_t)sizeof(Buffer)
87081ad6265SDimitry Andric                && "ULEB128 value too large!");
87181ad6265SDimitry Andric       // Decode the Opcode value.
87281ad6265SDimitry Andric       unsigned Opc = decodeULEB128(Buffer);
87381ad6265SDimitry Andric       OS.indent(Indentation) << "MCD::OPC_" << (IsTry ? "Try" : "")
87481ad6265SDimitry Andric         << "Decode, ";
87581ad6265SDimitry Andric       for (p = Buffer; *p >= 128; ++p)
87681ad6265SDimitry Andric         OS << (unsigned)*p << ", ";
87781ad6265SDimitry Andric       OS << (unsigned)*p << ", ";
87881ad6265SDimitry Andric 
87981ad6265SDimitry Andric       // Decoder index.
88081ad6265SDimitry Andric       for (; *I >= 128; ++I)
88181ad6265SDimitry Andric         OS << (unsigned)*I << ", ";
88281ad6265SDimitry Andric       OS << (unsigned)*I++ << ", ";
88381ad6265SDimitry Andric 
88481ad6265SDimitry Andric       if (!IsTry) {
88581ad6265SDimitry Andric         OS << "// Opcode: " << NumberedEncodings[Opc] << "\n";
88681ad6265SDimitry Andric         break;
88781ad6265SDimitry Andric       }
88881ad6265SDimitry Andric 
88981ad6265SDimitry Andric       // Fallthrough for OPC_TryDecode.
89081ad6265SDimitry Andric 
89181ad6265SDimitry Andric       // 24-bit numtoskip value.
89281ad6265SDimitry Andric       uint8_t Byte = *I++;
89381ad6265SDimitry Andric       uint32_t NumToSkip = Byte;
89481ad6265SDimitry Andric       OS << (unsigned)Byte << ", ";
89581ad6265SDimitry Andric       Byte = *I++;
89681ad6265SDimitry Andric       OS << (unsigned)Byte << ", ";
89781ad6265SDimitry Andric       NumToSkip |= Byte << 8;
89881ad6265SDimitry Andric       Byte = *I++;
89981ad6265SDimitry Andric       OS << utostr(Byte) << ", ";
90081ad6265SDimitry Andric       NumToSkip |= Byte << 16;
90181ad6265SDimitry Andric 
90281ad6265SDimitry Andric       OS << "// Opcode: " << NumberedEncodings[Opc]
90381ad6265SDimitry Andric          << ", skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
90481ad6265SDimitry Andric       break;
90581ad6265SDimitry Andric     }
90681ad6265SDimitry Andric     case MCD::OPC_SoftFail: {
90781ad6265SDimitry Andric       ++I;
90881ad6265SDimitry Andric       OS.indent(Indentation) << "MCD::OPC_SoftFail";
90981ad6265SDimitry Andric       // Positive mask
91081ad6265SDimitry Andric       uint64_t Value = 0;
91181ad6265SDimitry Andric       unsigned Shift = 0;
91281ad6265SDimitry Andric       do {
91381ad6265SDimitry Andric         OS << ", " << (unsigned)*I;
91481ad6265SDimitry Andric         Value += (*I & 0x7f) << Shift;
91581ad6265SDimitry Andric         Shift += 7;
91681ad6265SDimitry Andric       } while (*I++ >= 128);
91781ad6265SDimitry Andric       if (Value > 127) {
91881ad6265SDimitry Andric         OS << " /* 0x";
91981ad6265SDimitry Andric         OS.write_hex(Value);
92081ad6265SDimitry Andric         OS << " */";
92181ad6265SDimitry Andric       }
92281ad6265SDimitry Andric       // Negative mask
92381ad6265SDimitry Andric       Value = 0;
92481ad6265SDimitry Andric       Shift = 0;
92581ad6265SDimitry Andric       do {
92681ad6265SDimitry Andric         OS << ", " << (unsigned)*I;
92781ad6265SDimitry Andric         Value += (*I & 0x7f) << Shift;
92881ad6265SDimitry Andric         Shift += 7;
92981ad6265SDimitry Andric       } while (*I++ >= 128);
93081ad6265SDimitry Andric       if (Value > 127) {
93181ad6265SDimitry Andric         OS << " /* 0x";
93281ad6265SDimitry Andric         OS.write_hex(Value);
93381ad6265SDimitry Andric         OS << " */";
93481ad6265SDimitry Andric       }
93581ad6265SDimitry Andric       OS << ",\n";
93681ad6265SDimitry Andric       break;
93781ad6265SDimitry Andric     }
93881ad6265SDimitry Andric     case MCD::OPC_Fail: {
93981ad6265SDimitry Andric       ++I;
94081ad6265SDimitry Andric       OS.indent(Indentation) << "MCD::OPC_Fail,\n";
94181ad6265SDimitry Andric       break;
94281ad6265SDimitry Andric     }
94381ad6265SDimitry Andric     }
94481ad6265SDimitry Andric   }
94581ad6265SDimitry Andric   OS.indent(Indentation) << "0\n";
94681ad6265SDimitry Andric 
94781ad6265SDimitry Andric   Indentation -= 2;
94881ad6265SDimitry Andric 
94981ad6265SDimitry Andric   OS.indent(Indentation) << "};\n\n";
95081ad6265SDimitry Andric }
95181ad6265SDimitry Andric 
95281ad6265SDimitry Andric void DecoderEmitter::emitInstrLenTable(formatted_raw_ostream &OS,
95381ad6265SDimitry Andric                                        std::vector<unsigned> &InstrLen) const {
95481ad6265SDimitry Andric   OS << "static const uint8_t InstrLenTable[] = {\n";
95581ad6265SDimitry Andric   for (unsigned &Len : InstrLen) {
95681ad6265SDimitry Andric     OS << Len << ",\n";
95781ad6265SDimitry Andric   }
95881ad6265SDimitry Andric   OS << "};\n\n";
95981ad6265SDimitry Andric }
96081ad6265SDimitry Andric 
96181ad6265SDimitry Andric void DecoderEmitter::emitPredicateFunction(formatted_raw_ostream &OS,
96281ad6265SDimitry Andric                                            PredicateSet &Predicates,
96381ad6265SDimitry Andric                                            unsigned Indentation) const {
96481ad6265SDimitry Andric   // The predicate function is just a big switch statement based on the
96581ad6265SDimitry Andric   // input predicate index.
96681ad6265SDimitry Andric   OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
96781ad6265SDimitry Andric     << "const FeatureBitset &Bits) {\n";
96881ad6265SDimitry Andric   Indentation += 2;
96981ad6265SDimitry Andric   if (!Predicates.empty()) {
97081ad6265SDimitry Andric     OS.indent(Indentation) << "switch (Idx) {\n";
97181ad6265SDimitry Andric     OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
97281ad6265SDimitry Andric     unsigned Index = 0;
97381ad6265SDimitry Andric     for (const auto &Predicate : Predicates) {
97481ad6265SDimitry Andric       OS.indent(Indentation) << "case " << Index++ << ":\n";
97581ad6265SDimitry Andric       OS.indent(Indentation+2) << "return (" << Predicate << ");\n";
97681ad6265SDimitry Andric     }
97781ad6265SDimitry Andric     OS.indent(Indentation) << "}\n";
97881ad6265SDimitry Andric   } else {
97981ad6265SDimitry Andric     // No case statement to emit
98081ad6265SDimitry Andric     OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n";
98181ad6265SDimitry Andric   }
98281ad6265SDimitry Andric   Indentation -= 2;
98381ad6265SDimitry Andric   OS.indent(Indentation) << "}\n\n";
98481ad6265SDimitry Andric }
98581ad6265SDimitry Andric 
98681ad6265SDimitry Andric void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
98781ad6265SDimitry Andric                                          DecoderSet &Decoders,
98881ad6265SDimitry Andric                                          unsigned Indentation) const {
98981ad6265SDimitry Andric   // The decoder function is just a big switch statement based on the
99081ad6265SDimitry Andric   // input decoder index.
99181ad6265SDimitry Andric   OS.indent(Indentation) << "template <typename InsnType>\n";
99281ad6265SDimitry Andric   OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S,"
99381ad6265SDimitry Andric     << " unsigned Idx, InsnType insn, MCInst &MI,\n";
99481ad6265SDimitry Andric   OS.indent(Indentation)
99581ad6265SDimitry Andric       << "                                   uint64_t "
99681ad6265SDimitry Andric       << "Address, const MCDisassembler *Decoder, bool &DecodeComplete) {\n";
99781ad6265SDimitry Andric   Indentation += 2;
99881ad6265SDimitry Andric   OS.indent(Indentation) << "DecodeComplete = true;\n";
99981ad6265SDimitry Andric   // TODO: When InsnType is large, using uint64_t limits all fields to 64 bits
100081ad6265SDimitry Andric   // It would be better for emitBinaryParser to use a 64-bit tmp whenever
100181ad6265SDimitry Andric   // possible but fall back to an InsnType-sized tmp for truly large fields.
100281ad6265SDimitry Andric   OS.indent(Indentation) << "using TmpType = "
100381ad6265SDimitry Andric                             "std::conditional_t<std::is_integral<InsnType>::"
100481ad6265SDimitry Andric                             "value, InsnType, uint64_t>;\n";
100581ad6265SDimitry Andric   OS.indent(Indentation) << "TmpType tmp;\n";
100681ad6265SDimitry Andric   OS.indent(Indentation) << "switch (Idx) {\n";
100781ad6265SDimitry Andric   OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
100881ad6265SDimitry Andric   unsigned Index = 0;
100981ad6265SDimitry Andric   for (const auto &Decoder : Decoders) {
101081ad6265SDimitry Andric     OS.indent(Indentation) << "case " << Index++ << ":\n";
101181ad6265SDimitry Andric     OS << Decoder;
101281ad6265SDimitry Andric     OS.indent(Indentation+2) << "return S;\n";
101381ad6265SDimitry Andric   }
101481ad6265SDimitry Andric   OS.indent(Indentation) << "}\n";
101581ad6265SDimitry Andric   Indentation -= 2;
101681ad6265SDimitry Andric   OS.indent(Indentation) << "}\n\n";
101781ad6265SDimitry Andric }
101881ad6265SDimitry Andric 
101981ad6265SDimitry Andric // Populates the field of the insn given the start position and the number of
102081ad6265SDimitry Andric // consecutive bits to scan for.
102181ad6265SDimitry Andric //
102281ad6265SDimitry Andric // Returns false if and on the first uninitialized bit value encountered.
102381ad6265SDimitry Andric // Returns true, otherwise.
102481ad6265SDimitry Andric bool FilterChooser::fieldFromInsn(uint64_t &Field, insn_t &Insn,
102581ad6265SDimitry Andric                                   unsigned StartBit, unsigned NumBits) const {
102681ad6265SDimitry Andric   Field = 0;
102781ad6265SDimitry Andric 
102881ad6265SDimitry Andric   for (unsigned i = 0; i < NumBits; ++i) {
102981ad6265SDimitry Andric     if (Insn[StartBit + i] == BIT_UNSET)
103081ad6265SDimitry Andric       return false;
103181ad6265SDimitry Andric 
103281ad6265SDimitry Andric     if (Insn[StartBit + i] == BIT_TRUE)
103381ad6265SDimitry Andric       Field = Field | (1ULL << i);
103481ad6265SDimitry Andric   }
103581ad6265SDimitry Andric 
103681ad6265SDimitry Andric   return true;
103781ad6265SDimitry Andric }
103881ad6265SDimitry Andric 
103981ad6265SDimitry Andric /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
104081ad6265SDimitry Andric /// filter array as a series of chars.
104181ad6265SDimitry Andric void FilterChooser::dumpFilterArray(raw_ostream &o,
104281ad6265SDimitry Andric                                  const std::vector<bit_value_t> &filter) const {
104381ad6265SDimitry Andric   for (unsigned bitIndex = BitWidth; bitIndex > 0; bitIndex--) {
104481ad6265SDimitry Andric     switch (filter[bitIndex - 1]) {
104581ad6265SDimitry Andric     case BIT_UNFILTERED:
104681ad6265SDimitry Andric       o << ".";
104781ad6265SDimitry Andric       break;
104881ad6265SDimitry Andric     case BIT_UNSET:
104981ad6265SDimitry Andric       o << "_";
105081ad6265SDimitry Andric       break;
105181ad6265SDimitry Andric     case BIT_TRUE:
105281ad6265SDimitry Andric       o << "1";
105381ad6265SDimitry Andric       break;
105481ad6265SDimitry Andric     case BIT_FALSE:
105581ad6265SDimitry Andric       o << "0";
105681ad6265SDimitry Andric       break;
105781ad6265SDimitry Andric     }
105881ad6265SDimitry Andric   }
105981ad6265SDimitry Andric }
106081ad6265SDimitry Andric 
106181ad6265SDimitry Andric /// dumpStack - dumpStack traverses the filter chooser chain and calls
106281ad6265SDimitry Andric /// dumpFilterArray on each filter chooser up to the top level one.
106381ad6265SDimitry Andric void FilterChooser::dumpStack(raw_ostream &o, const char *prefix) const {
106481ad6265SDimitry Andric   const FilterChooser *current = this;
106581ad6265SDimitry Andric 
106681ad6265SDimitry Andric   while (current) {
106781ad6265SDimitry Andric     o << prefix;
106881ad6265SDimitry Andric     dumpFilterArray(o, current->FilterBitValues);
106981ad6265SDimitry Andric     o << '\n';
107081ad6265SDimitry Andric     current = current->Parent;
107181ad6265SDimitry Andric   }
107281ad6265SDimitry Andric }
107381ad6265SDimitry Andric 
107481ad6265SDimitry Andric // Calculates the island(s) needed to decode the instruction.
107581ad6265SDimitry Andric // This returns a list of undecoded bits of an instructions, for example,
107681ad6265SDimitry Andric // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
107781ad6265SDimitry Andric // decoded bits in order to verify that the instruction matches the Opcode.
107881ad6265SDimitry Andric unsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits,
107981ad6265SDimitry Andric                                    std::vector<unsigned> &EndBits,
108081ad6265SDimitry Andric                                    std::vector<uint64_t> &FieldVals,
108181ad6265SDimitry Andric                                    const insn_t &Insn) const {
108281ad6265SDimitry Andric   unsigned Num, BitNo;
108381ad6265SDimitry Andric   Num = BitNo = 0;
108481ad6265SDimitry Andric 
108581ad6265SDimitry Andric   uint64_t FieldVal = 0;
108681ad6265SDimitry Andric 
108781ad6265SDimitry Andric   // 0: Init
108881ad6265SDimitry Andric   // 1: Water (the bit value does not affect decoding)
108981ad6265SDimitry Andric   // 2: Island (well-known bit value needed for decoding)
109081ad6265SDimitry Andric   int State = 0;
109181ad6265SDimitry Andric 
109281ad6265SDimitry Andric   for (unsigned i = 0; i < BitWidth; ++i) {
109381ad6265SDimitry Andric     int64_t Val = Value(Insn[i]);
109481ad6265SDimitry Andric     bool Filtered = PositionFiltered(i);
109581ad6265SDimitry Andric     switch (State) {
109681ad6265SDimitry Andric     default: llvm_unreachable("Unreachable code!");
109781ad6265SDimitry Andric     case 0:
109881ad6265SDimitry Andric     case 1:
109981ad6265SDimitry Andric       if (Filtered || Val == -1)
110081ad6265SDimitry Andric         State = 1; // Still in Water
110181ad6265SDimitry Andric       else {
110281ad6265SDimitry Andric         State = 2; // Into the Island
110381ad6265SDimitry Andric         BitNo = 0;
110481ad6265SDimitry Andric         StartBits.push_back(i);
110581ad6265SDimitry Andric         FieldVal = Val;
110681ad6265SDimitry Andric       }
110781ad6265SDimitry Andric       break;
110881ad6265SDimitry Andric     case 2:
110981ad6265SDimitry Andric       if (Filtered || Val == -1) {
111081ad6265SDimitry Andric         State = 1; // Into the Water
111181ad6265SDimitry Andric         EndBits.push_back(i - 1);
111281ad6265SDimitry Andric         FieldVals.push_back(FieldVal);
111381ad6265SDimitry Andric         ++Num;
111481ad6265SDimitry Andric       } else {
111581ad6265SDimitry Andric         State = 2; // Still in Island
111681ad6265SDimitry Andric         ++BitNo;
111781ad6265SDimitry Andric         FieldVal = FieldVal | Val << BitNo;
111881ad6265SDimitry Andric       }
111981ad6265SDimitry Andric       break;
112081ad6265SDimitry Andric     }
112181ad6265SDimitry Andric   }
112281ad6265SDimitry Andric   // If we are still in Island after the loop, do some housekeeping.
112381ad6265SDimitry Andric   if (State == 2) {
112481ad6265SDimitry Andric     EndBits.push_back(BitWidth - 1);
112581ad6265SDimitry Andric     FieldVals.push_back(FieldVal);
112681ad6265SDimitry Andric     ++Num;
112781ad6265SDimitry Andric   }
112881ad6265SDimitry Andric 
112981ad6265SDimitry Andric   assert(StartBits.size() == Num && EndBits.size() == Num &&
113081ad6265SDimitry Andric          FieldVals.size() == Num);
113181ad6265SDimitry Andric   return Num;
113281ad6265SDimitry Andric }
113381ad6265SDimitry Andric 
113481ad6265SDimitry Andric void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
113581ad6265SDimitry Andric                                      const OperandInfo &OpInfo,
113681ad6265SDimitry Andric                                      bool &OpHasCompleteDecoder) const {
113781ad6265SDimitry Andric   const std::string &Decoder = OpInfo.Decoder;
113881ad6265SDimitry Andric 
113981ad6265SDimitry Andric   bool UseInsertBits = OpInfo.numFields() != 1 || OpInfo.InitValue != 0;
114081ad6265SDimitry Andric 
114181ad6265SDimitry Andric   if (UseInsertBits) {
114281ad6265SDimitry Andric     o.indent(Indentation) << "tmp = 0x";
114381ad6265SDimitry Andric     o.write_hex(OpInfo.InitValue);
114481ad6265SDimitry Andric     o << ";\n";
114581ad6265SDimitry Andric   }
114681ad6265SDimitry Andric 
114781ad6265SDimitry Andric   for (const EncodingField &EF : OpInfo) {
114881ad6265SDimitry Andric     o.indent(Indentation);
114981ad6265SDimitry Andric     if (UseInsertBits)
115081ad6265SDimitry Andric       o << "insertBits(tmp, ";
115181ad6265SDimitry Andric     else
115281ad6265SDimitry Andric       o << "tmp = ";
115381ad6265SDimitry Andric     o << "fieldFromInstruction(insn, " << EF.Base << ", " << EF.Width << ')';
115481ad6265SDimitry Andric     if (UseInsertBits)
115581ad6265SDimitry Andric       o << ", " << EF.Offset << ", " << EF.Width << ')';
115681ad6265SDimitry Andric     else if (EF.Offset != 0)
115781ad6265SDimitry Andric       o << " << " << EF.Offset;
115881ad6265SDimitry Andric     o << ";\n";
115981ad6265SDimitry Andric   }
116081ad6265SDimitry Andric 
116181ad6265SDimitry Andric   if (Decoder != "") {
116281ad6265SDimitry Andric     OpHasCompleteDecoder = OpInfo.HasCompleteDecoder;
1163bdd1243dSDimitry Andric     o.indent(Indentation) << "if (!Check(S, " << Decoder
1164bdd1243dSDimitry Andric                           << "(MI, tmp, Address, Decoder))) { "
1165bdd1243dSDimitry Andric                           << (OpHasCompleteDecoder ? ""
1166bdd1243dSDimitry Andric                                                    : "DecodeComplete = false; ")
116781ad6265SDimitry Andric                           << "return MCDisassembler::Fail; }\n";
116881ad6265SDimitry Andric   } else {
116981ad6265SDimitry Andric     OpHasCompleteDecoder = true;
117081ad6265SDimitry Andric     o.indent(Indentation) << "MI.addOperand(MCOperand::createImm(tmp));\n";
117181ad6265SDimitry Andric   }
117281ad6265SDimitry Andric }
117381ad6265SDimitry Andric 
117481ad6265SDimitry Andric void FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation,
117581ad6265SDimitry Andric                                 unsigned Opc, bool &HasCompleteDecoder) const {
117681ad6265SDimitry Andric   HasCompleteDecoder = true;
117781ad6265SDimitry Andric 
117881ad6265SDimitry Andric   for (const auto &Op : Operands.find(Opc)->second) {
117981ad6265SDimitry Andric     // If a custom instruction decoder was specified, use that.
118081ad6265SDimitry Andric     if (Op.numFields() == 0 && !Op.Decoder.empty()) {
118181ad6265SDimitry Andric       HasCompleteDecoder = Op.HasCompleteDecoder;
1182bdd1243dSDimitry Andric       OS.indent(Indentation)
1183bdd1243dSDimitry Andric           << "if (!Check(S, " << Op.Decoder
1184bdd1243dSDimitry Andric           << "(MI, insn, Address, Decoder))) { "
1185bdd1243dSDimitry Andric           << (HasCompleteDecoder ? "" : "DecodeComplete = false; ")
118681ad6265SDimitry Andric           << "return MCDisassembler::Fail; }\n";
118781ad6265SDimitry Andric       break;
118881ad6265SDimitry Andric     }
118981ad6265SDimitry Andric 
119081ad6265SDimitry Andric     bool OpHasCompleteDecoder;
119181ad6265SDimitry Andric     emitBinaryParser(OS, Indentation, Op, OpHasCompleteDecoder);
119281ad6265SDimitry Andric     if (!OpHasCompleteDecoder)
119381ad6265SDimitry Andric       HasCompleteDecoder = false;
119481ad6265SDimitry Andric   }
119581ad6265SDimitry Andric }
119681ad6265SDimitry Andric 
119781ad6265SDimitry Andric unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders,
119881ad6265SDimitry Andric                                         unsigned Opc,
119981ad6265SDimitry Andric                                         bool &HasCompleteDecoder) const {
120081ad6265SDimitry Andric   // Build up the predicate string.
120181ad6265SDimitry Andric   SmallString<256> Decoder;
120281ad6265SDimitry Andric   // FIXME: emitDecoder() function can take a buffer directly rather than
120381ad6265SDimitry Andric   // a stream.
120481ad6265SDimitry Andric   raw_svector_ostream S(Decoder);
120581ad6265SDimitry Andric   unsigned I = 4;
120681ad6265SDimitry Andric   emitDecoder(S, I, Opc, HasCompleteDecoder);
120781ad6265SDimitry Andric 
120881ad6265SDimitry Andric   // Using the full decoder string as the key value here is a bit
120981ad6265SDimitry Andric   // heavyweight, but is effective. If the string comparisons become a
121081ad6265SDimitry Andric   // performance concern, we can implement a mangling of the predicate
121181ad6265SDimitry Andric   // data easily enough with a map back to the actual string. That's
121281ad6265SDimitry Andric   // overkill for now, though.
121381ad6265SDimitry Andric 
121481ad6265SDimitry Andric   // Make sure the predicate is in the table.
121581ad6265SDimitry Andric   Decoders.insert(CachedHashString(Decoder));
121681ad6265SDimitry Andric   // Now figure out the index for when we write out the table.
121781ad6265SDimitry Andric   DecoderSet::const_iterator P = find(Decoders, Decoder.str());
121881ad6265SDimitry Andric   return (unsigned)(P - Decoders.begin());
121981ad6265SDimitry Andric }
122081ad6265SDimitry Andric 
122181ad6265SDimitry Andric // If ParenIfBinOp is true, print a surrounding () if Val uses && or ||.
122281ad6265SDimitry Andric bool FilterChooser::emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
122381ad6265SDimitry Andric                                           raw_ostream &OS) const {
122481ad6265SDimitry Andric   if (auto *D = dyn_cast<DefInit>(&Val)) {
122581ad6265SDimitry Andric     if (!D->getDef()->isSubClassOf("SubtargetFeature"))
122681ad6265SDimitry Andric       return true;
122781ad6265SDimitry Andric     OS << "Bits[" << Emitter->PredicateNamespace << "::" << D->getAsString()
122881ad6265SDimitry Andric        << "]";
122981ad6265SDimitry Andric     return false;
123081ad6265SDimitry Andric   }
123181ad6265SDimitry Andric   if (auto *D = dyn_cast<DagInit>(&Val)) {
123281ad6265SDimitry Andric     std::string Op = D->getOperator()->getAsString();
123381ad6265SDimitry Andric     if (Op == "not" && D->getNumArgs() == 1) {
123481ad6265SDimitry Andric       OS << '!';
123581ad6265SDimitry Andric       return emitPredicateMatchAux(*D->getArg(0), true, OS);
123681ad6265SDimitry Andric     }
123781ad6265SDimitry Andric     if ((Op == "any_of" || Op == "all_of") && D->getNumArgs() > 0) {
123881ad6265SDimitry Andric       bool Paren = D->getNumArgs() > 1 && std::exchange(ParenIfBinOp, true);
123981ad6265SDimitry Andric       if (Paren)
124081ad6265SDimitry Andric         OS << '(';
124181ad6265SDimitry Andric       ListSeparator LS(Op == "any_of" ? " || " : " && ");
124281ad6265SDimitry Andric       for (auto *Arg : D->getArgs()) {
124381ad6265SDimitry Andric         OS << LS;
124481ad6265SDimitry Andric         if (emitPredicateMatchAux(*Arg, ParenIfBinOp, OS))
124581ad6265SDimitry Andric           return true;
124681ad6265SDimitry Andric       }
124781ad6265SDimitry Andric       if (Paren)
124881ad6265SDimitry Andric         OS << ')';
124981ad6265SDimitry Andric       return false;
125081ad6265SDimitry Andric     }
125181ad6265SDimitry Andric   }
125281ad6265SDimitry Andric   return true;
125381ad6265SDimitry Andric }
125481ad6265SDimitry Andric 
125581ad6265SDimitry Andric bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
125681ad6265SDimitry Andric                                        unsigned Opc) const {
125781ad6265SDimitry Andric   ListInit *Predicates =
125881ad6265SDimitry Andric       AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
125981ad6265SDimitry Andric   bool IsFirstEmission = true;
126081ad6265SDimitry Andric   for (unsigned i = 0; i < Predicates->size(); ++i) {
126181ad6265SDimitry Andric     Record *Pred = Predicates->getElementAsRecord(i);
126281ad6265SDimitry Andric     if (!Pred->getValue("AssemblerMatcherPredicate"))
126381ad6265SDimitry Andric       continue;
126481ad6265SDimitry Andric 
126581ad6265SDimitry Andric     if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
126681ad6265SDimitry Andric       continue;
126781ad6265SDimitry Andric 
126881ad6265SDimitry Andric     if (!IsFirstEmission)
126981ad6265SDimitry Andric       o << " && ";
127081ad6265SDimitry Andric     if (emitPredicateMatchAux(*Pred->getValueAsDag("AssemblerCondDag"),
127181ad6265SDimitry Andric                               Predicates->size() > 1, o))
127281ad6265SDimitry Andric       PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
127381ad6265SDimitry Andric     IsFirstEmission = false;
127481ad6265SDimitry Andric   }
127581ad6265SDimitry Andric   return !Predicates->empty();
127681ad6265SDimitry Andric }
127781ad6265SDimitry Andric 
127881ad6265SDimitry Andric bool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const {
127981ad6265SDimitry Andric   ListInit *Predicates =
128081ad6265SDimitry Andric       AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
128181ad6265SDimitry Andric   for (unsigned i = 0; i < Predicates->size(); ++i) {
128281ad6265SDimitry Andric     Record *Pred = Predicates->getElementAsRecord(i);
128381ad6265SDimitry Andric     if (!Pred->getValue("AssemblerMatcherPredicate"))
128481ad6265SDimitry Andric       continue;
128581ad6265SDimitry Andric 
128681ad6265SDimitry Andric     if (isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
128781ad6265SDimitry Andric       return true;
128881ad6265SDimitry Andric   }
128981ad6265SDimitry Andric   return false;
129081ad6265SDimitry Andric }
129181ad6265SDimitry Andric 
129281ad6265SDimitry Andric unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo,
129381ad6265SDimitry Andric                                           StringRef Predicate) const {
129481ad6265SDimitry Andric   // Using the full predicate string as the key value here is a bit
129581ad6265SDimitry Andric   // heavyweight, but is effective. If the string comparisons become a
129681ad6265SDimitry Andric   // performance concern, we can implement a mangling of the predicate
129781ad6265SDimitry Andric   // data easily enough with a map back to the actual string. That's
129881ad6265SDimitry Andric   // overkill for now, though.
129981ad6265SDimitry Andric 
130081ad6265SDimitry Andric   // Make sure the predicate is in the table.
130181ad6265SDimitry Andric   TableInfo.Predicates.insert(CachedHashString(Predicate));
130281ad6265SDimitry Andric   // Now figure out the index for when we write out the table.
130381ad6265SDimitry Andric   PredicateSet::const_iterator P = find(TableInfo.Predicates, Predicate);
130481ad6265SDimitry Andric   return (unsigned)(P - TableInfo.Predicates.begin());
130581ad6265SDimitry Andric }
130681ad6265SDimitry Andric 
130781ad6265SDimitry Andric void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo,
130881ad6265SDimitry Andric                                             unsigned Opc) const {
130981ad6265SDimitry Andric   if (!doesOpcodeNeedPredicate(Opc))
131081ad6265SDimitry Andric     return;
131181ad6265SDimitry Andric 
131281ad6265SDimitry Andric   // Build up the predicate string.
131381ad6265SDimitry Andric   SmallString<256> Predicate;
131481ad6265SDimitry Andric   // FIXME: emitPredicateMatch() functions can take a buffer directly rather
131581ad6265SDimitry Andric   // than a stream.
131681ad6265SDimitry Andric   raw_svector_ostream PS(Predicate);
131781ad6265SDimitry Andric   unsigned I = 0;
131881ad6265SDimitry Andric   emitPredicateMatch(PS, I, Opc);
131981ad6265SDimitry Andric 
132081ad6265SDimitry Andric   // Figure out the index into the predicate table for the predicate just
132181ad6265SDimitry Andric   // computed.
132281ad6265SDimitry Andric   unsigned PIdx = getPredicateIndex(TableInfo, PS.str());
132381ad6265SDimitry Andric   SmallString<16> PBytes;
132481ad6265SDimitry Andric   raw_svector_ostream S(PBytes);
132581ad6265SDimitry Andric   encodeULEB128(PIdx, S);
132681ad6265SDimitry Andric 
132781ad6265SDimitry Andric   TableInfo.Table.push_back(MCD::OPC_CheckPredicate);
132881ad6265SDimitry Andric   // Predicate index
132981ad6265SDimitry Andric   for (unsigned i = 0, e = PBytes.size(); i != e; ++i)
133081ad6265SDimitry Andric     TableInfo.Table.push_back(PBytes[i]);
133181ad6265SDimitry Andric   // Push location for NumToSkip backpatching.
133281ad6265SDimitry Andric   TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
133381ad6265SDimitry Andric   TableInfo.Table.push_back(0);
133481ad6265SDimitry Andric   TableInfo.Table.push_back(0);
133581ad6265SDimitry Andric   TableInfo.Table.push_back(0);
133681ad6265SDimitry Andric }
133781ad6265SDimitry Andric 
133881ad6265SDimitry Andric void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
133981ad6265SDimitry Andric                                            unsigned Opc) const {
134081ad6265SDimitry Andric   const RecordVal *RV = AllInstructions[Opc].EncodingDef->getValue("SoftFail");
134181ad6265SDimitry Andric   BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
134281ad6265SDimitry Andric 
134381ad6265SDimitry Andric   if (!SFBits) return;
134481ad6265SDimitry Andric   BitsInit *InstBits =
134581ad6265SDimitry Andric       AllInstructions[Opc].EncodingDef->getValueAsBitsInit("Inst");
134681ad6265SDimitry Andric 
134781ad6265SDimitry Andric   APInt PositiveMask(BitWidth, 0ULL);
134881ad6265SDimitry Andric   APInt NegativeMask(BitWidth, 0ULL);
134981ad6265SDimitry Andric   for (unsigned i = 0; i < BitWidth; ++i) {
135081ad6265SDimitry Andric     bit_value_t B = bitFromBits(*SFBits, i);
135181ad6265SDimitry Andric     bit_value_t IB = bitFromBits(*InstBits, i);
135281ad6265SDimitry Andric 
135381ad6265SDimitry Andric     if (B != BIT_TRUE) continue;
135481ad6265SDimitry Andric 
135581ad6265SDimitry Andric     switch (IB) {
135681ad6265SDimitry Andric     case BIT_FALSE:
135781ad6265SDimitry Andric       // The bit is meant to be false, so emit a check to see if it is true.
135881ad6265SDimitry Andric       PositiveMask.setBit(i);
135981ad6265SDimitry Andric       break;
136081ad6265SDimitry Andric     case BIT_TRUE:
136181ad6265SDimitry Andric       // The bit is meant to be true, so emit a check to see if it is false.
136281ad6265SDimitry Andric       NegativeMask.setBit(i);
136381ad6265SDimitry Andric       break;
136481ad6265SDimitry Andric     default:
136581ad6265SDimitry Andric       // The bit is not set; this must be an error!
136681ad6265SDimitry Andric       errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in "
136781ad6265SDimitry Andric              << AllInstructions[Opc] << " is set but Inst{" << i
136881ad6265SDimitry Andric              << "} is unset!\n"
136981ad6265SDimitry Andric              << "  - You can only mark a bit as SoftFail if it is fully defined"
137081ad6265SDimitry Andric              << " (1/0 - not '?') in Inst\n";
137181ad6265SDimitry Andric       return;
137281ad6265SDimitry Andric     }
137381ad6265SDimitry Andric   }
137481ad6265SDimitry Andric 
137581ad6265SDimitry Andric   bool NeedPositiveMask = PositiveMask.getBoolValue();
137681ad6265SDimitry Andric   bool NeedNegativeMask = NegativeMask.getBoolValue();
137781ad6265SDimitry Andric 
137881ad6265SDimitry Andric   if (!NeedPositiveMask && !NeedNegativeMask)
137981ad6265SDimitry Andric     return;
138081ad6265SDimitry Andric 
138181ad6265SDimitry Andric   TableInfo.Table.push_back(MCD::OPC_SoftFail);
138281ad6265SDimitry Andric 
138381ad6265SDimitry Andric   SmallString<16> MaskBytes;
138481ad6265SDimitry Andric   raw_svector_ostream S(MaskBytes);
138581ad6265SDimitry Andric   if (NeedPositiveMask) {
138681ad6265SDimitry Andric     encodeULEB128(PositiveMask.getZExtValue(), S);
138781ad6265SDimitry Andric     for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i)
138881ad6265SDimitry Andric       TableInfo.Table.push_back(MaskBytes[i]);
138981ad6265SDimitry Andric   } else
139081ad6265SDimitry Andric     TableInfo.Table.push_back(0);
139181ad6265SDimitry Andric   if (NeedNegativeMask) {
139281ad6265SDimitry Andric     MaskBytes.clear();
139381ad6265SDimitry Andric     encodeULEB128(NegativeMask.getZExtValue(), S);
139481ad6265SDimitry Andric     for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i)
139581ad6265SDimitry Andric       TableInfo.Table.push_back(MaskBytes[i]);
139681ad6265SDimitry Andric   } else
139781ad6265SDimitry Andric     TableInfo.Table.push_back(0);
139881ad6265SDimitry Andric }
139981ad6265SDimitry Andric 
140081ad6265SDimitry Andric // Emits table entries to decode the singleton.
140181ad6265SDimitry Andric void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
140281ad6265SDimitry Andric                                             EncodingIDAndOpcode Opc) const {
140381ad6265SDimitry Andric   std::vector<unsigned> StartBits;
140481ad6265SDimitry Andric   std::vector<unsigned> EndBits;
140581ad6265SDimitry Andric   std::vector<uint64_t> FieldVals;
140681ad6265SDimitry Andric   insn_t Insn;
140781ad6265SDimitry Andric   insnWithID(Insn, Opc.EncodingID);
140881ad6265SDimitry Andric 
140981ad6265SDimitry Andric   // Look for islands of undecoded bits of the singleton.
141081ad6265SDimitry Andric   getIslands(StartBits, EndBits, FieldVals, Insn);
141181ad6265SDimitry Andric 
141281ad6265SDimitry Andric   unsigned Size = StartBits.size();
141381ad6265SDimitry Andric 
141481ad6265SDimitry Andric   // Emit the predicate table entry if one is needed.
141581ad6265SDimitry Andric   emitPredicateTableEntry(TableInfo, Opc.EncodingID);
141681ad6265SDimitry Andric 
141781ad6265SDimitry Andric   // Check any additional encoding fields needed.
141881ad6265SDimitry Andric   for (unsigned I = Size; I != 0; --I) {
141981ad6265SDimitry Andric     unsigned NumBits = EndBits[I-1] - StartBits[I-1] + 1;
142081ad6265SDimitry Andric     TableInfo.Table.push_back(MCD::OPC_CheckField);
142181ad6265SDimitry Andric     TableInfo.Table.push_back(StartBits[I-1]);
142281ad6265SDimitry Andric     TableInfo.Table.push_back(NumBits);
142381ad6265SDimitry Andric     uint8_t Buffer[16], *p;
142481ad6265SDimitry Andric     encodeULEB128(FieldVals[I-1], Buffer);
142581ad6265SDimitry Andric     for (p = Buffer; *p >= 128 ; ++p)
142681ad6265SDimitry Andric       TableInfo.Table.push_back(*p);
142781ad6265SDimitry Andric     TableInfo.Table.push_back(*p);
142881ad6265SDimitry Andric     // Push location for NumToSkip backpatching.
142981ad6265SDimitry Andric     TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
143081ad6265SDimitry Andric     // The fixup is always 24-bits, so go ahead and allocate the space
143181ad6265SDimitry Andric     // in the table so all our relative position calculations work OK even
143281ad6265SDimitry Andric     // before we fully resolve the real value here.
143381ad6265SDimitry Andric     TableInfo.Table.push_back(0);
143481ad6265SDimitry Andric     TableInfo.Table.push_back(0);
143581ad6265SDimitry Andric     TableInfo.Table.push_back(0);
143681ad6265SDimitry Andric   }
143781ad6265SDimitry Andric 
143881ad6265SDimitry Andric   // Check for soft failure of the match.
143981ad6265SDimitry Andric   emitSoftFailTableEntry(TableInfo, Opc.EncodingID);
144081ad6265SDimitry Andric 
144181ad6265SDimitry Andric   bool HasCompleteDecoder;
144281ad6265SDimitry Andric   unsigned DIdx =
144381ad6265SDimitry Andric       getDecoderIndex(TableInfo.Decoders, Opc.EncodingID, HasCompleteDecoder);
144481ad6265SDimitry Andric 
144581ad6265SDimitry Andric   // Produce OPC_Decode or OPC_TryDecode opcode based on the information
144681ad6265SDimitry Andric   // whether the instruction decoder is complete or not. If it is complete
144781ad6265SDimitry Andric   // then it handles all possible values of remaining variable/unfiltered bits
144881ad6265SDimitry Andric   // and for any value can determine if the bitpattern is a valid instruction
144981ad6265SDimitry Andric   // or not. This means OPC_Decode will be the final step in the decoding
145081ad6265SDimitry Andric   // process. If it is not complete, then the Fail return code from the
145181ad6265SDimitry Andric   // decoder method indicates that additional processing should be done to see
145281ad6265SDimitry Andric   // if there is any other instruction that also matches the bitpattern and
145381ad6265SDimitry Andric   // can decode it.
145481ad6265SDimitry Andric   TableInfo.Table.push_back(HasCompleteDecoder ? MCD::OPC_Decode :
145581ad6265SDimitry Andric       MCD::OPC_TryDecode);
145681ad6265SDimitry Andric   NumEncodingsSupported++;
145781ad6265SDimitry Andric   uint8_t Buffer[16], *p;
145881ad6265SDimitry Andric   encodeULEB128(Opc.Opcode, Buffer);
145981ad6265SDimitry Andric   for (p = Buffer; *p >= 128 ; ++p)
146081ad6265SDimitry Andric     TableInfo.Table.push_back(*p);
146181ad6265SDimitry Andric   TableInfo.Table.push_back(*p);
146281ad6265SDimitry Andric 
146381ad6265SDimitry Andric   SmallString<16> Bytes;
146481ad6265SDimitry Andric   raw_svector_ostream S(Bytes);
146581ad6265SDimitry Andric   encodeULEB128(DIdx, S);
146681ad6265SDimitry Andric 
146781ad6265SDimitry Andric   // Decoder index
146881ad6265SDimitry Andric   for (unsigned i = 0, e = Bytes.size(); i != e; ++i)
146981ad6265SDimitry Andric     TableInfo.Table.push_back(Bytes[i]);
147081ad6265SDimitry Andric 
147181ad6265SDimitry Andric   if (!HasCompleteDecoder) {
147281ad6265SDimitry Andric     // Push location for NumToSkip backpatching.
147381ad6265SDimitry Andric     TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
147481ad6265SDimitry Andric     // Allocate the space for the fixup.
147581ad6265SDimitry Andric     TableInfo.Table.push_back(0);
147681ad6265SDimitry Andric     TableInfo.Table.push_back(0);
147781ad6265SDimitry Andric     TableInfo.Table.push_back(0);
147881ad6265SDimitry Andric   }
147981ad6265SDimitry Andric }
148081ad6265SDimitry Andric 
148181ad6265SDimitry Andric // Emits table entries to decode the singleton, and then to decode the rest.
148281ad6265SDimitry Andric void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
148381ad6265SDimitry Andric                                             const Filter &Best) const {
148481ad6265SDimitry Andric   EncodingIDAndOpcode Opc = Best.getSingletonOpc();
148581ad6265SDimitry Andric 
148681ad6265SDimitry Andric   // complex singletons need predicate checks from the first singleton
148781ad6265SDimitry Andric   // to refer forward to the variable filterchooser that follows.
148881ad6265SDimitry Andric   TableInfo.FixupStack.emplace_back();
148981ad6265SDimitry Andric 
149081ad6265SDimitry Andric   emitSingletonTableEntry(TableInfo, Opc);
149181ad6265SDimitry Andric 
149281ad6265SDimitry Andric   resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
149381ad6265SDimitry Andric                      TableInfo.Table.size());
149481ad6265SDimitry Andric   TableInfo.FixupStack.pop_back();
149581ad6265SDimitry Andric 
149681ad6265SDimitry Andric   Best.getVariableFC().emitTableEntries(TableInfo);
149781ad6265SDimitry Andric }
149881ad6265SDimitry Andric 
149981ad6265SDimitry Andric // Assign a single filter and run with it.  Top level API client can initialize
150081ad6265SDimitry Andric // with a single filter to start the filtering process.
150181ad6265SDimitry Andric void FilterChooser::runSingleFilter(unsigned startBit, unsigned numBit,
150281ad6265SDimitry Andric                                     bool mixed) {
150381ad6265SDimitry Andric   Filters.clear();
150481ad6265SDimitry Andric   Filters.emplace_back(*this, startBit, numBit, true);
150581ad6265SDimitry Andric   BestIndex = 0; // Sole Filter instance to choose from.
150681ad6265SDimitry Andric   bestFilter().recurse();
150781ad6265SDimitry Andric }
150881ad6265SDimitry Andric 
150981ad6265SDimitry Andric // reportRegion is a helper function for filterProcessor to mark a region as
151081ad6265SDimitry Andric // eligible for use as a filter region.
151181ad6265SDimitry Andric void FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit,
151281ad6265SDimitry Andric                                  unsigned BitIndex, bool AllowMixed) {
151381ad6265SDimitry Andric   if (RA == ATTR_MIXED && AllowMixed)
151481ad6265SDimitry Andric     Filters.emplace_back(*this, StartBit, BitIndex - StartBit, true);
151581ad6265SDimitry Andric   else if (RA == ATTR_ALL_SET && !AllowMixed)
151681ad6265SDimitry Andric     Filters.emplace_back(*this, StartBit, BitIndex - StartBit, false);
151781ad6265SDimitry Andric }
151881ad6265SDimitry Andric 
151981ad6265SDimitry Andric // FilterProcessor scans the well-known encoding bits of the instructions and
152081ad6265SDimitry Andric // builds up a list of candidate filters.  It chooses the best filter and
152181ad6265SDimitry Andric // recursively descends down the decoding tree.
152281ad6265SDimitry Andric bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
152381ad6265SDimitry Andric   Filters.clear();
152481ad6265SDimitry Andric   BestIndex = -1;
152581ad6265SDimitry Andric   unsigned numInstructions = Opcodes.size();
152681ad6265SDimitry Andric 
152781ad6265SDimitry Andric   assert(numInstructions && "Filter created with no instructions");
152881ad6265SDimitry Andric 
152981ad6265SDimitry Andric   // No further filtering is necessary.
153081ad6265SDimitry Andric   if (numInstructions == 1)
153181ad6265SDimitry Andric     return true;
153281ad6265SDimitry Andric 
153381ad6265SDimitry Andric   // Heuristics.  See also doFilter()'s "Heuristics" comment when num of
153481ad6265SDimitry Andric   // instructions is 3.
153581ad6265SDimitry Andric   if (AllowMixed && !Greedy) {
153681ad6265SDimitry Andric     assert(numInstructions == 3);
153781ad6265SDimitry Andric 
153881ad6265SDimitry Andric     for (auto Opcode : Opcodes) {
153981ad6265SDimitry Andric       std::vector<unsigned> StartBits;
154081ad6265SDimitry Andric       std::vector<unsigned> EndBits;
154181ad6265SDimitry Andric       std::vector<uint64_t> FieldVals;
154281ad6265SDimitry Andric       insn_t Insn;
154381ad6265SDimitry Andric 
154481ad6265SDimitry Andric       insnWithID(Insn, Opcode.EncodingID);
154581ad6265SDimitry Andric 
154681ad6265SDimitry Andric       // Look for islands of undecoded bits of any instruction.
154781ad6265SDimitry Andric       if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) {
154881ad6265SDimitry Andric         // Found an instruction with island(s).  Now just assign a filter.
154981ad6265SDimitry Andric         runSingleFilter(StartBits[0], EndBits[0] - StartBits[0] + 1, true);
155081ad6265SDimitry Andric         return true;
155181ad6265SDimitry Andric       }
155281ad6265SDimitry Andric     }
155381ad6265SDimitry Andric   }
155481ad6265SDimitry Andric 
155581ad6265SDimitry Andric   unsigned BitIndex;
155681ad6265SDimitry Andric 
155781ad6265SDimitry Andric   // We maintain BIT_WIDTH copies of the bitAttrs automaton.
155881ad6265SDimitry Andric   // The automaton consumes the corresponding bit from each
155981ad6265SDimitry Andric   // instruction.
156081ad6265SDimitry Andric   //
156181ad6265SDimitry Andric   //   Input symbols: 0, 1, and _ (unset).
156281ad6265SDimitry Andric   //   States:        NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED.
156381ad6265SDimitry Andric   //   Initial state: NONE.
156481ad6265SDimitry Andric   //
156581ad6265SDimitry Andric   // (NONE) ------- [01] -> (ALL_SET)
156681ad6265SDimitry Andric   // (NONE) ------- _ ----> (ALL_UNSET)
156781ad6265SDimitry Andric   // (ALL_SET) ---- [01] -> (ALL_SET)
156881ad6265SDimitry Andric   // (ALL_SET) ---- _ ----> (MIXED)
156981ad6265SDimitry Andric   // (ALL_UNSET) -- [01] -> (MIXED)
157081ad6265SDimitry Andric   // (ALL_UNSET) -- _ ----> (ALL_UNSET)
157181ad6265SDimitry Andric   // (MIXED) ------ . ----> (MIXED)
157281ad6265SDimitry Andric   // (FILTERED)---- . ----> (FILTERED)
157381ad6265SDimitry Andric 
157481ad6265SDimitry Andric   std::vector<bitAttr_t> bitAttrs;
157581ad6265SDimitry Andric 
157681ad6265SDimitry Andric   // FILTERED bit positions provide no entropy and are not worthy of pursuing.
157781ad6265SDimitry Andric   // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position.
157881ad6265SDimitry Andric   for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex)
157981ad6265SDimitry Andric     if (FilterBitValues[BitIndex] == BIT_TRUE ||
158081ad6265SDimitry Andric         FilterBitValues[BitIndex] == BIT_FALSE)
158181ad6265SDimitry Andric       bitAttrs.push_back(ATTR_FILTERED);
158281ad6265SDimitry Andric     else
158381ad6265SDimitry Andric       bitAttrs.push_back(ATTR_NONE);
158481ad6265SDimitry Andric 
158581ad6265SDimitry Andric   for (unsigned InsnIndex = 0; InsnIndex < numInstructions; ++InsnIndex) {
158681ad6265SDimitry Andric     insn_t insn;
158781ad6265SDimitry Andric 
158881ad6265SDimitry Andric     insnWithID(insn, Opcodes[InsnIndex].EncodingID);
158981ad6265SDimitry Andric 
159081ad6265SDimitry Andric     for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
159181ad6265SDimitry Andric       switch (bitAttrs[BitIndex]) {
159281ad6265SDimitry Andric       case ATTR_NONE:
159381ad6265SDimitry Andric         if (insn[BitIndex] == BIT_UNSET)
159481ad6265SDimitry Andric           bitAttrs[BitIndex] = ATTR_ALL_UNSET;
159581ad6265SDimitry Andric         else
159681ad6265SDimitry Andric           bitAttrs[BitIndex] = ATTR_ALL_SET;
159781ad6265SDimitry Andric         break;
159881ad6265SDimitry Andric       case ATTR_ALL_SET:
159981ad6265SDimitry Andric         if (insn[BitIndex] == BIT_UNSET)
160081ad6265SDimitry Andric           bitAttrs[BitIndex] = ATTR_MIXED;
160181ad6265SDimitry Andric         break;
160281ad6265SDimitry Andric       case ATTR_ALL_UNSET:
160381ad6265SDimitry Andric         if (insn[BitIndex] != BIT_UNSET)
160481ad6265SDimitry Andric           bitAttrs[BitIndex] = ATTR_MIXED;
160581ad6265SDimitry Andric         break;
160681ad6265SDimitry Andric       case ATTR_MIXED:
160781ad6265SDimitry Andric       case ATTR_FILTERED:
160881ad6265SDimitry Andric         break;
160981ad6265SDimitry Andric       }
161081ad6265SDimitry Andric     }
161181ad6265SDimitry Andric   }
161281ad6265SDimitry Andric 
161381ad6265SDimitry Andric   // The regionAttr automaton consumes the bitAttrs automatons' state,
161481ad6265SDimitry Andric   // lowest-to-highest.
161581ad6265SDimitry Andric   //
161681ad6265SDimitry Andric   //   Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed)
161781ad6265SDimitry Andric   //   States:        NONE, ALL_SET, MIXED
161881ad6265SDimitry Andric   //   Initial state: NONE
161981ad6265SDimitry Andric   //
162081ad6265SDimitry Andric   // (NONE) ----- F --> (NONE)
162181ad6265SDimitry Andric   // (NONE) ----- S --> (ALL_SET)     ; and set region start
162281ad6265SDimitry Andric   // (NONE) ----- U --> (NONE)
162381ad6265SDimitry Andric   // (NONE) ----- M --> (MIXED)       ; and set region start
162481ad6265SDimitry Andric   // (ALL_SET) -- F --> (NONE)        ; and report an ALL_SET region
162581ad6265SDimitry Andric   // (ALL_SET) -- S --> (ALL_SET)
162681ad6265SDimitry Andric   // (ALL_SET) -- U --> (NONE)        ; and report an ALL_SET region
162781ad6265SDimitry Andric   // (ALL_SET) -- M --> (MIXED)       ; and report an ALL_SET region
162881ad6265SDimitry Andric   // (MIXED) ---- F --> (NONE)        ; and report a MIXED region
162981ad6265SDimitry Andric   // (MIXED) ---- S --> (ALL_SET)     ; and report a MIXED region
163081ad6265SDimitry Andric   // (MIXED) ---- U --> (NONE)        ; and report a MIXED region
163181ad6265SDimitry Andric   // (MIXED) ---- M --> (MIXED)
163281ad6265SDimitry Andric 
163381ad6265SDimitry Andric   bitAttr_t RA = ATTR_NONE;
163481ad6265SDimitry Andric   unsigned StartBit = 0;
163581ad6265SDimitry Andric 
163681ad6265SDimitry Andric   for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
163781ad6265SDimitry Andric     bitAttr_t bitAttr = bitAttrs[BitIndex];
163881ad6265SDimitry Andric 
163981ad6265SDimitry Andric     assert(bitAttr != ATTR_NONE && "Bit without attributes");
164081ad6265SDimitry Andric 
164181ad6265SDimitry Andric     switch (RA) {
164281ad6265SDimitry Andric     case ATTR_NONE:
164381ad6265SDimitry Andric       switch (bitAttr) {
164481ad6265SDimitry Andric       case ATTR_FILTERED:
164581ad6265SDimitry Andric         break;
164681ad6265SDimitry Andric       case ATTR_ALL_SET:
164781ad6265SDimitry Andric         StartBit = BitIndex;
164881ad6265SDimitry Andric         RA = ATTR_ALL_SET;
164981ad6265SDimitry Andric         break;
165081ad6265SDimitry Andric       case ATTR_ALL_UNSET:
165181ad6265SDimitry Andric         break;
165281ad6265SDimitry Andric       case ATTR_MIXED:
165381ad6265SDimitry Andric         StartBit = BitIndex;
165481ad6265SDimitry Andric         RA = ATTR_MIXED;
165581ad6265SDimitry Andric         break;
165681ad6265SDimitry Andric       default:
165781ad6265SDimitry Andric         llvm_unreachable("Unexpected bitAttr!");
165881ad6265SDimitry Andric       }
165981ad6265SDimitry Andric       break;
166081ad6265SDimitry Andric     case ATTR_ALL_SET:
166181ad6265SDimitry Andric       switch (bitAttr) {
166281ad6265SDimitry Andric       case ATTR_FILTERED:
166381ad6265SDimitry Andric         reportRegion(RA, StartBit, BitIndex, AllowMixed);
166481ad6265SDimitry Andric         RA = ATTR_NONE;
166581ad6265SDimitry Andric         break;
166681ad6265SDimitry Andric       case ATTR_ALL_SET:
166781ad6265SDimitry Andric         break;
166881ad6265SDimitry Andric       case ATTR_ALL_UNSET:
166981ad6265SDimitry Andric         reportRegion(RA, StartBit, BitIndex, AllowMixed);
167081ad6265SDimitry Andric         RA = ATTR_NONE;
167181ad6265SDimitry Andric         break;
167281ad6265SDimitry Andric       case ATTR_MIXED:
167381ad6265SDimitry Andric         reportRegion(RA, StartBit, BitIndex, AllowMixed);
167481ad6265SDimitry Andric         StartBit = BitIndex;
167581ad6265SDimitry Andric         RA = ATTR_MIXED;
167681ad6265SDimitry Andric         break;
167781ad6265SDimitry Andric       default:
167881ad6265SDimitry Andric         llvm_unreachable("Unexpected bitAttr!");
167981ad6265SDimitry Andric       }
168081ad6265SDimitry Andric       break;
168181ad6265SDimitry Andric     case ATTR_MIXED:
168281ad6265SDimitry Andric       switch (bitAttr) {
168381ad6265SDimitry Andric       case ATTR_FILTERED:
168481ad6265SDimitry Andric         reportRegion(RA, StartBit, BitIndex, AllowMixed);
168581ad6265SDimitry Andric         StartBit = BitIndex;
168681ad6265SDimitry Andric         RA = ATTR_NONE;
168781ad6265SDimitry Andric         break;
168881ad6265SDimitry Andric       case ATTR_ALL_SET:
168981ad6265SDimitry Andric         reportRegion(RA, StartBit, BitIndex, AllowMixed);
169081ad6265SDimitry Andric         StartBit = BitIndex;
169181ad6265SDimitry Andric         RA = ATTR_ALL_SET;
169281ad6265SDimitry Andric         break;
169381ad6265SDimitry Andric       case ATTR_ALL_UNSET:
169481ad6265SDimitry Andric         reportRegion(RA, StartBit, BitIndex, AllowMixed);
169581ad6265SDimitry Andric         RA = ATTR_NONE;
169681ad6265SDimitry Andric         break;
169781ad6265SDimitry Andric       case ATTR_MIXED:
169881ad6265SDimitry Andric         break;
169981ad6265SDimitry Andric       default:
170081ad6265SDimitry Andric         llvm_unreachable("Unexpected bitAttr!");
170181ad6265SDimitry Andric       }
170281ad6265SDimitry Andric       break;
170381ad6265SDimitry Andric     case ATTR_ALL_UNSET:
170481ad6265SDimitry Andric       llvm_unreachable("regionAttr state machine has no ATTR_UNSET state");
170581ad6265SDimitry Andric     case ATTR_FILTERED:
170681ad6265SDimitry Andric       llvm_unreachable("regionAttr state machine has no ATTR_FILTERED state");
170781ad6265SDimitry Andric     }
170881ad6265SDimitry Andric   }
170981ad6265SDimitry Andric 
171081ad6265SDimitry Andric   // At the end, if we're still in ALL_SET or MIXED states, report a region
171181ad6265SDimitry Andric   switch (RA) {
171281ad6265SDimitry Andric   case ATTR_NONE:
171381ad6265SDimitry Andric     break;
171481ad6265SDimitry Andric   case ATTR_FILTERED:
171581ad6265SDimitry Andric     break;
171681ad6265SDimitry Andric   case ATTR_ALL_SET:
171781ad6265SDimitry Andric     reportRegion(RA, StartBit, BitIndex, AllowMixed);
171881ad6265SDimitry Andric     break;
171981ad6265SDimitry Andric   case ATTR_ALL_UNSET:
172081ad6265SDimitry Andric     break;
172181ad6265SDimitry Andric   case ATTR_MIXED:
172281ad6265SDimitry Andric     reportRegion(RA, StartBit, BitIndex, AllowMixed);
172381ad6265SDimitry Andric     break;
172481ad6265SDimitry Andric   }
172581ad6265SDimitry Andric 
172681ad6265SDimitry Andric   // We have finished with the filter processings.  Now it's time to choose
172781ad6265SDimitry Andric   // the best performing filter.
172881ad6265SDimitry Andric   BestIndex = 0;
172981ad6265SDimitry Andric   bool AllUseless = true;
173081ad6265SDimitry Andric   unsigned BestScore = 0;
173181ad6265SDimitry Andric 
173281ad6265SDimitry Andric   for (unsigned i = 0, e = Filters.size(); i != e; ++i) {
173381ad6265SDimitry Andric     unsigned Usefulness = Filters[i].usefulness();
173481ad6265SDimitry Andric 
173581ad6265SDimitry Andric     if (Usefulness)
173681ad6265SDimitry Andric       AllUseless = false;
173781ad6265SDimitry Andric 
173881ad6265SDimitry Andric     if (Usefulness > BestScore) {
173981ad6265SDimitry Andric       BestIndex = i;
174081ad6265SDimitry Andric       BestScore = Usefulness;
174181ad6265SDimitry Andric     }
174281ad6265SDimitry Andric   }
174381ad6265SDimitry Andric 
174481ad6265SDimitry Andric   if (!AllUseless)
174581ad6265SDimitry Andric     bestFilter().recurse();
174681ad6265SDimitry Andric 
174781ad6265SDimitry Andric   return !AllUseless;
174881ad6265SDimitry Andric } // end of FilterChooser::filterProcessor(bool)
174981ad6265SDimitry Andric 
175081ad6265SDimitry Andric // Decides on the best configuration of filter(s) to use in order to decode
175181ad6265SDimitry Andric // the instructions.  A conflict of instructions may occur, in which case we
175281ad6265SDimitry Andric // dump the conflict set to the standard error.
175381ad6265SDimitry Andric void FilterChooser::doFilter() {
175481ad6265SDimitry Andric   unsigned Num = Opcodes.size();
175581ad6265SDimitry Andric   assert(Num && "FilterChooser created with no instructions");
175681ad6265SDimitry Andric 
175781ad6265SDimitry Andric   // Try regions of consecutive known bit values first.
175881ad6265SDimitry Andric   if (filterProcessor(false))
175981ad6265SDimitry Andric     return;
176081ad6265SDimitry Andric 
176181ad6265SDimitry Andric   // Then regions of mixed bits (both known and unitialized bit values allowed).
176281ad6265SDimitry Andric   if (filterProcessor(true))
176381ad6265SDimitry Andric     return;
176481ad6265SDimitry Andric 
176581ad6265SDimitry Andric   // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where
176681ad6265SDimitry Andric   // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a
176781ad6265SDimitry Andric   // well-known encoding pattern.  In such case, we backtrack and scan for the
176881ad6265SDimitry Andric   // the very first consecutive ATTR_ALL_SET region and assign a filter to it.
176981ad6265SDimitry Andric   if (Num == 3 && filterProcessor(true, false))
177081ad6265SDimitry Andric     return;
177181ad6265SDimitry Andric 
177281ad6265SDimitry Andric   // If we come to here, the instruction decoding has failed.
177381ad6265SDimitry Andric   // Set the BestIndex to -1 to indicate so.
177481ad6265SDimitry Andric   BestIndex = -1;
177581ad6265SDimitry Andric }
177681ad6265SDimitry Andric 
177781ad6265SDimitry Andric // emitTableEntries - Emit state machine entries to decode our share of
177881ad6265SDimitry Andric // instructions.
177981ad6265SDimitry Andric void FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const {
178081ad6265SDimitry Andric   if (Opcodes.size() == 1) {
178181ad6265SDimitry Andric     // There is only one instruction in the set, which is great!
178281ad6265SDimitry Andric     // Call emitSingletonDecoder() to see whether there are any remaining
178381ad6265SDimitry Andric     // encodings bits.
178481ad6265SDimitry Andric     emitSingletonTableEntry(TableInfo, Opcodes[0]);
178581ad6265SDimitry Andric     return;
178681ad6265SDimitry Andric   }
178781ad6265SDimitry Andric 
178881ad6265SDimitry Andric   // Choose the best filter to do the decodings!
178981ad6265SDimitry Andric   if (BestIndex != -1) {
179081ad6265SDimitry Andric     const Filter &Best = Filters[BestIndex];
179181ad6265SDimitry Andric     if (Best.getNumFiltered() == 1)
179281ad6265SDimitry Andric       emitSingletonTableEntry(TableInfo, Best);
179381ad6265SDimitry Andric     else
179481ad6265SDimitry Andric       Best.emitTableEntry(TableInfo);
179581ad6265SDimitry Andric     return;
179681ad6265SDimitry Andric   }
179781ad6265SDimitry Andric 
179881ad6265SDimitry Andric   // We don't know how to decode these instructions!  Dump the
179981ad6265SDimitry Andric   // conflict set and bail.
180081ad6265SDimitry Andric 
180181ad6265SDimitry Andric   // Print out useful conflict information for postmortem analysis.
180281ad6265SDimitry Andric   errs() << "Decoding Conflict:\n";
180381ad6265SDimitry Andric 
180481ad6265SDimitry Andric   dumpStack(errs(), "\t\t");
180581ad6265SDimitry Andric 
180681ad6265SDimitry Andric   for (auto Opcode : Opcodes) {
180781ad6265SDimitry Andric     errs() << '\t';
180881ad6265SDimitry Andric     emitNameWithID(errs(), Opcode.EncodingID);
180981ad6265SDimitry Andric     errs() << " ";
181081ad6265SDimitry Andric     dumpBits(
181181ad6265SDimitry Andric         errs(),
181281ad6265SDimitry Andric         getBitsField(*AllInstructions[Opcode.EncodingID].EncodingDef, "Inst"));
181381ad6265SDimitry Andric     errs() << '\n';
181481ad6265SDimitry Andric   }
181581ad6265SDimitry Andric }
181681ad6265SDimitry Andric 
181781ad6265SDimitry Andric static std::string findOperandDecoderMethod(Record *Record) {
181881ad6265SDimitry Andric   std::string Decoder;
181981ad6265SDimitry Andric 
182081ad6265SDimitry Andric   RecordVal *DecoderString = Record->getValue("DecoderMethod");
182181ad6265SDimitry Andric   StringInit *String = DecoderString ?
182281ad6265SDimitry Andric     dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
182381ad6265SDimitry Andric   if (String) {
182481ad6265SDimitry Andric     Decoder = std::string(String->getValue());
182581ad6265SDimitry Andric     if (!Decoder.empty())
182681ad6265SDimitry Andric       return Decoder;
182781ad6265SDimitry Andric   }
182881ad6265SDimitry Andric 
182981ad6265SDimitry Andric   if (Record->isSubClassOf("RegisterOperand"))
183081ad6265SDimitry Andric     Record = Record->getValueAsDef("RegClass");
183181ad6265SDimitry Andric 
183281ad6265SDimitry Andric   if (Record->isSubClassOf("RegisterClass")) {
183381ad6265SDimitry Andric     Decoder = "Decode" + Record->getName().str() + "RegisterClass";
183481ad6265SDimitry Andric   } else if (Record->isSubClassOf("PointerLikeRegClass")) {
183581ad6265SDimitry Andric     Decoder = "DecodePointerLikeRegClass" +
183681ad6265SDimitry Andric       utostr(Record->getValueAsInt("RegClassKind"));
183781ad6265SDimitry Andric   }
183881ad6265SDimitry Andric 
183981ad6265SDimitry Andric   return Decoder;
184081ad6265SDimitry Andric }
184181ad6265SDimitry Andric 
184281ad6265SDimitry Andric OperandInfo getOpInfo(Record *TypeRecord) {
184381ad6265SDimitry Andric   std::string Decoder = findOperandDecoderMethod(TypeRecord);
184481ad6265SDimitry Andric 
184581ad6265SDimitry Andric   RecordVal *HasCompleteDecoderVal = TypeRecord->getValue("hasCompleteDecoder");
184681ad6265SDimitry Andric   BitInit *HasCompleteDecoderBit =
184781ad6265SDimitry Andric       HasCompleteDecoderVal
184881ad6265SDimitry Andric           ? dyn_cast<BitInit>(HasCompleteDecoderVal->getValue())
184981ad6265SDimitry Andric           : nullptr;
185081ad6265SDimitry Andric   bool HasCompleteDecoder =
185181ad6265SDimitry Andric       HasCompleteDecoderBit ? HasCompleteDecoderBit->getValue() : true;
185281ad6265SDimitry Andric 
185381ad6265SDimitry Andric   return OperandInfo(Decoder, HasCompleteDecoder);
185481ad6265SDimitry Andric }
185581ad6265SDimitry Andric 
185681ad6265SDimitry Andric void parseVarLenInstOperand(const Record &Def,
185781ad6265SDimitry Andric                             std::vector<OperandInfo> &Operands,
185881ad6265SDimitry Andric                             const CodeGenInstruction &CGI) {
185981ad6265SDimitry Andric 
186081ad6265SDimitry Andric   const RecordVal *RV = Def.getValue("Inst");
186181ad6265SDimitry Andric   VarLenInst VLI(cast<DagInit>(RV->getValue()), RV);
186281ad6265SDimitry Andric   SmallVector<int> TiedTo;
186381ad6265SDimitry Andric 
186481ad6265SDimitry Andric   for (unsigned Idx = 0; Idx < CGI.Operands.size(); ++Idx) {
186581ad6265SDimitry Andric     auto &Op = CGI.Operands[Idx];
186681ad6265SDimitry Andric     if (Op.MIOperandInfo && Op.MIOperandInfo->getNumArgs() > 0)
186781ad6265SDimitry Andric       for (auto *Arg : Op.MIOperandInfo->getArgs())
186881ad6265SDimitry Andric         Operands.push_back(getOpInfo(cast<DefInit>(Arg)->getDef()));
186981ad6265SDimitry Andric     else
187081ad6265SDimitry Andric       Operands.push_back(getOpInfo(Op.Rec));
187181ad6265SDimitry Andric 
187281ad6265SDimitry Andric     int TiedReg = Op.getTiedRegister();
187381ad6265SDimitry Andric     TiedTo.push_back(-1);
187481ad6265SDimitry Andric     if (TiedReg != -1) {
187581ad6265SDimitry Andric       TiedTo[Idx] = TiedReg;
187681ad6265SDimitry Andric       TiedTo[TiedReg] = Idx;
187781ad6265SDimitry Andric     }
187881ad6265SDimitry Andric   }
187981ad6265SDimitry Andric 
188081ad6265SDimitry Andric   unsigned CurrBitPos = 0;
188181ad6265SDimitry Andric   for (auto &EncodingSegment : VLI) {
188281ad6265SDimitry Andric     unsigned Offset = 0;
188381ad6265SDimitry Andric     StringRef OpName;
188481ad6265SDimitry Andric 
188581ad6265SDimitry Andric     if (const StringInit *SI = dyn_cast<StringInit>(EncodingSegment.Value)) {
188681ad6265SDimitry Andric       OpName = SI->getValue();
188781ad6265SDimitry Andric     } else if (const DagInit *DI = dyn_cast<DagInit>(EncodingSegment.Value)) {
188881ad6265SDimitry Andric       OpName = cast<StringInit>(DI->getArg(0))->getValue();
188981ad6265SDimitry Andric       Offset = cast<IntInit>(DI->getArg(2))->getValue();
189081ad6265SDimitry Andric     }
189181ad6265SDimitry Andric 
189281ad6265SDimitry Andric     if (!OpName.empty()) {
189381ad6265SDimitry Andric       auto OpSubOpPair =
189481ad6265SDimitry Andric           const_cast<CodeGenInstruction &>(CGI).Operands.ParseOperandName(
189581ad6265SDimitry Andric               OpName);
189681ad6265SDimitry Andric       unsigned OpIdx = CGI.Operands.getFlattenedOperandNumber(OpSubOpPair);
189781ad6265SDimitry Andric       Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset);
1898bdd1243dSDimitry Andric       if (!EncodingSegment.CustomDecoder.empty())
1899bdd1243dSDimitry Andric         Operands[OpIdx].Decoder = EncodingSegment.CustomDecoder.str();
190081ad6265SDimitry Andric 
190181ad6265SDimitry Andric       int TiedReg = TiedTo[OpSubOpPair.first];
190281ad6265SDimitry Andric       if (TiedReg != -1) {
190381ad6265SDimitry Andric         unsigned OpIdx = CGI.Operands.getFlattenedOperandNumber(
190481ad6265SDimitry Andric             std::make_pair(TiedReg, OpSubOpPair.second));
190581ad6265SDimitry Andric         Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset);
190681ad6265SDimitry Andric       }
190781ad6265SDimitry Andric     }
190881ad6265SDimitry Andric 
190981ad6265SDimitry Andric     CurrBitPos += EncodingSegment.BitWidth;
191081ad6265SDimitry Andric   }
191181ad6265SDimitry Andric }
191281ad6265SDimitry Andric 
1913bdd1243dSDimitry Andric static void debugDumpRecord(const Record &Rec) {
1914bdd1243dSDimitry Andric   // Dump the record, so we can see what's going on...
1915bdd1243dSDimitry Andric   std::string E;
1916bdd1243dSDimitry Andric   raw_string_ostream S(E);
1917bdd1243dSDimitry Andric   S << "Dumping record for previous error:\n";
1918bdd1243dSDimitry Andric   S << Rec;
1919bdd1243dSDimitry Andric   PrintNote(E);
1920bdd1243dSDimitry Andric }
1921bdd1243dSDimitry Andric 
1922bdd1243dSDimitry Andric /// For an operand field named OpName: populate OpInfo.InitValue with the
1923bdd1243dSDimitry Andric /// constant-valued bit values, and OpInfo.Fields with the ranges of bits to
1924bdd1243dSDimitry Andric /// insert from the decoded instruction.
1925bdd1243dSDimitry Andric static void addOneOperandFields(const Record &EncodingDef, const BitsInit &Bits,
1926bdd1243dSDimitry Andric                                 std::map<std::string, std::string> &TiedNames,
1927bdd1243dSDimitry Andric                                 StringRef OpName, OperandInfo &OpInfo) {
1928bdd1243dSDimitry Andric   // Some bits of the operand may be required to be 1 depending on the
1929bdd1243dSDimitry Andric   // instruction's encoding. Collect those bits.
1930bdd1243dSDimitry Andric   if (const RecordVal *EncodedValue = EncodingDef.getValue(OpName))
1931bdd1243dSDimitry Andric     if (const BitsInit *OpBits = dyn_cast<BitsInit>(EncodedValue->getValue()))
1932bdd1243dSDimitry Andric       for (unsigned I = 0; I < OpBits->getNumBits(); ++I)
1933bdd1243dSDimitry Andric         if (const BitInit *OpBit = dyn_cast<BitInit>(OpBits->getBit(I)))
1934bdd1243dSDimitry Andric           if (OpBit->getValue())
1935bdd1243dSDimitry Andric             OpInfo.InitValue |= 1ULL << I;
1936bdd1243dSDimitry Andric 
1937bdd1243dSDimitry Andric   for (unsigned I = 0, J = 0; I != Bits.getNumBits(); I = J) {
1938bdd1243dSDimitry Andric     VarInit *Var;
1939bdd1243dSDimitry Andric     unsigned Offset = 0;
1940bdd1243dSDimitry Andric     for (; J != Bits.getNumBits(); ++J) {
1941bdd1243dSDimitry Andric       VarBitInit *BJ = dyn_cast<VarBitInit>(Bits.getBit(J));
1942bdd1243dSDimitry Andric       if (BJ) {
1943bdd1243dSDimitry Andric         Var = dyn_cast<VarInit>(BJ->getBitVar());
1944bdd1243dSDimitry Andric         if (I == J)
1945bdd1243dSDimitry Andric           Offset = BJ->getBitNum();
1946bdd1243dSDimitry Andric         else if (BJ->getBitNum() != Offset + J - I)
1947bdd1243dSDimitry Andric           break;
1948bdd1243dSDimitry Andric       } else {
1949bdd1243dSDimitry Andric         Var = dyn_cast<VarInit>(Bits.getBit(J));
1950bdd1243dSDimitry Andric       }
1951bdd1243dSDimitry Andric       if (!Var || (Var->getName() != OpName &&
1952bdd1243dSDimitry Andric                    Var->getName() != TiedNames[std::string(OpName)]))
1953bdd1243dSDimitry Andric         break;
1954bdd1243dSDimitry Andric     }
1955bdd1243dSDimitry Andric     if (I == J)
1956bdd1243dSDimitry Andric       ++J;
1957bdd1243dSDimitry Andric     else
1958bdd1243dSDimitry Andric       OpInfo.addField(I, J - I, Offset);
1959bdd1243dSDimitry Andric   }
1960bdd1243dSDimitry Andric }
1961bdd1243dSDimitry Andric 
196281ad6265SDimitry Andric static unsigned
196381ad6265SDimitry Andric populateInstruction(CodeGenTarget &Target, const Record &EncodingDef,
196481ad6265SDimitry Andric                     const CodeGenInstruction &CGI, unsigned Opc,
196581ad6265SDimitry Andric                     std::map<unsigned, std::vector<OperandInfo>> &Operands,
196681ad6265SDimitry Andric                     bool IsVarLenInst) {
196781ad6265SDimitry Andric   const Record &Def = *CGI.TheDef;
196881ad6265SDimitry Andric   // If all the bit positions are not specified; do not decode this instruction.
196981ad6265SDimitry Andric   // We are bound to fail!  For proper disassembly, the well-known encoding bits
197081ad6265SDimitry Andric   // of the instruction must be fully specified.
197181ad6265SDimitry Andric 
197281ad6265SDimitry Andric   BitsInit &Bits = getBitsField(EncodingDef, "Inst");
197381ad6265SDimitry Andric   if (Bits.allInComplete())
197481ad6265SDimitry Andric     return 0;
197581ad6265SDimitry Andric 
197681ad6265SDimitry Andric   std::vector<OperandInfo> InsnOperands;
197781ad6265SDimitry Andric 
197881ad6265SDimitry Andric   // If the instruction has specified a custom decoding hook, use that instead
197981ad6265SDimitry Andric   // of trying to auto-generate the decoder.
198081ad6265SDimitry Andric   StringRef InstDecoder = EncodingDef.getValueAsString("DecoderMethod");
198181ad6265SDimitry Andric   if (InstDecoder != "") {
198281ad6265SDimitry Andric     bool HasCompleteInstDecoder = EncodingDef.getValueAsBit("hasCompleteDecoder");
198381ad6265SDimitry Andric     InsnOperands.push_back(
198481ad6265SDimitry Andric         OperandInfo(std::string(InstDecoder), HasCompleteInstDecoder));
198581ad6265SDimitry Andric     Operands[Opc] = InsnOperands;
198681ad6265SDimitry Andric     return Bits.getNumBits();
198781ad6265SDimitry Andric   }
198881ad6265SDimitry Andric 
198981ad6265SDimitry Andric   // Generate a description of the operand of the instruction that we know
199081ad6265SDimitry Andric   // how to decode automatically.
199181ad6265SDimitry Andric   // FIXME: We'll need to have a way to manually override this as needed.
199281ad6265SDimitry Andric 
199381ad6265SDimitry Andric   // Gather the outputs/inputs of the instruction, so we can find their
199481ad6265SDimitry Andric   // positions in the encoding.  This assumes for now that they appear in the
199581ad6265SDimitry Andric   // MCInst in the order that they're listed.
199681ad6265SDimitry Andric   std::vector<std::pair<Init*, StringRef>> InOutOperands;
199781ad6265SDimitry Andric   DagInit *Out  = Def.getValueAsDag("OutOperandList");
199881ad6265SDimitry Andric   DagInit *In  = Def.getValueAsDag("InOperandList");
199981ad6265SDimitry Andric   for (unsigned i = 0; i < Out->getNumArgs(); ++i)
200081ad6265SDimitry Andric     InOutOperands.push_back(
200181ad6265SDimitry Andric         std::make_pair(Out->getArg(i), Out->getArgNameStr(i)));
200281ad6265SDimitry Andric   for (unsigned i = 0; i < In->getNumArgs(); ++i)
200381ad6265SDimitry Andric     InOutOperands.push_back(
200481ad6265SDimitry Andric         std::make_pair(In->getArg(i), In->getArgNameStr(i)));
200581ad6265SDimitry Andric 
200681ad6265SDimitry Andric   // Search for tied operands, so that we can correctly instantiate
200781ad6265SDimitry Andric   // operands that are not explicitly represented in the encoding.
200881ad6265SDimitry Andric   std::map<std::string, std::string> TiedNames;
200981ad6265SDimitry Andric   for (unsigned i = 0; i < CGI.Operands.size(); ++i) {
2010bdd1243dSDimitry Andric     auto &Op = CGI.Operands[i];
2011bdd1243dSDimitry Andric     for (unsigned j = 0; j < Op.Constraints.size(); ++j) {
2012bdd1243dSDimitry Andric       const CGIOperandList::ConstraintInfo &CI = Op.Constraints[j];
2013bdd1243dSDimitry Andric       if (CI.isTied()) {
2014bdd1243dSDimitry Andric         int tiedTo = CI.getTiedOperand();
201581ad6265SDimitry Andric         std::pair<unsigned, unsigned> SO =
201681ad6265SDimitry Andric             CGI.Operands.getSubOperandNumber(tiedTo);
2017bdd1243dSDimitry Andric         std::string TiedName = CGI.Operands[SO.first].SubOpNames[SO.second];
2018bdd1243dSDimitry Andric         if (TiedName.empty())
2019bdd1243dSDimitry Andric           TiedName = CGI.Operands[SO.first].Name;
2020bdd1243dSDimitry Andric         std::string MyName = Op.SubOpNames[j];
2021bdd1243dSDimitry Andric         if (MyName.empty())
2022bdd1243dSDimitry Andric           MyName = Op.Name;
2023bdd1243dSDimitry Andric 
2024bdd1243dSDimitry Andric         TiedNames[MyName] = TiedName;
2025bdd1243dSDimitry Andric         TiedNames[TiedName] = MyName;
2026bdd1243dSDimitry Andric       }
202781ad6265SDimitry Andric     }
202881ad6265SDimitry Andric   }
202981ad6265SDimitry Andric 
203081ad6265SDimitry Andric   if (IsVarLenInst) {
203181ad6265SDimitry Andric     parseVarLenInstOperand(EncodingDef, InsnOperands, CGI);
203281ad6265SDimitry Andric   } else {
203381ad6265SDimitry Andric     // For each operand, see if we can figure out where it is encoded.
203481ad6265SDimitry Andric     for (const auto &Op : InOutOperands) {
2035bdd1243dSDimitry Andric       Init *OpInit = Op.first;
2036bdd1243dSDimitry Andric       StringRef OpName = Op.second;
2037bdd1243dSDimitry Andric 
2038bdd1243dSDimitry Andric       // We're ready to find the instruction encoding locations for this operand.
203981ad6265SDimitry Andric 
2040bdd1243dSDimitry Andric       // First, find the operand type ("OpInit"), and sub-op names
2041bdd1243dSDimitry Andric       // ("SubArgDag") if present.
2042bdd1243dSDimitry Andric       DagInit *SubArgDag = dyn_cast<DagInit>(OpInit);
2043bdd1243dSDimitry Andric       if (SubArgDag)
2044bdd1243dSDimitry Andric         OpInit = SubArgDag->getOperator();
2045bdd1243dSDimitry Andric       Record *OpTypeRec = cast<DefInit>(OpInit)->getDef();
2046bdd1243dSDimitry Andric       // Lookup the sub-operands from the operand type record (note that only
2047bdd1243dSDimitry Andric       // Operand subclasses have MIOperandInfo, see CodeGenInstruction.cpp).
2048bdd1243dSDimitry Andric       DagInit *SubOps = OpTypeRec->isSubClassOf("Operand")
2049bdd1243dSDimitry Andric                             ? OpTypeRec->getValueAsDag("MIOperandInfo")
2050bdd1243dSDimitry Andric                             : nullptr;
205181ad6265SDimitry Andric 
2052bdd1243dSDimitry Andric       // Lookup the decoder method and construct a new OperandInfo to hold our result.
2053bdd1243dSDimitry Andric       OperandInfo OpInfo = getOpInfo(OpTypeRec);
205481ad6265SDimitry Andric 
2055bdd1243dSDimitry Andric       // If we have named sub-operands...
2056bdd1243dSDimitry Andric       if (SubArgDag) {
2057bdd1243dSDimitry Andric         // Then there should not be a custom decoder specified on the top-level
2058bdd1243dSDimitry Andric         // type.
2059bdd1243dSDimitry Andric         if (!OpInfo.Decoder.empty()) {
2060bdd1243dSDimitry Andric           PrintError(EncodingDef.getLoc(),
2061bdd1243dSDimitry Andric                      "DecoderEmitter: operand \"" + OpName + "\" has type \"" +
2062bdd1243dSDimitry Andric                          OpInit->getAsString() +
2063bdd1243dSDimitry Andric                          "\" with a custom DecoderMethod, but also named "
2064bdd1243dSDimitry Andric                          "sub-operands.");
2065bdd1243dSDimitry Andric           continue;
2066bdd1243dSDimitry Andric         }
206781ad6265SDimitry Andric 
2068bdd1243dSDimitry Andric         // Decode each of the sub-ops separately.
2069bdd1243dSDimitry Andric         assert(SubOps && SubArgDag->getNumArgs() == SubOps->getNumArgs());
2070bdd1243dSDimitry Andric         for (unsigned i = 0; i < SubOps->getNumArgs(); ++i) {
2071bdd1243dSDimitry Andric           StringRef SubOpName = SubArgDag->getArgNameStr(i);
2072bdd1243dSDimitry Andric           OperandInfo SubOpInfo =
2073bdd1243dSDimitry Andric               getOpInfo(cast<DefInit>(SubOps->getArg(i))->getDef());
207481ad6265SDimitry Andric 
2075bdd1243dSDimitry Andric           addOneOperandFields(EncodingDef, Bits, TiedNames, SubOpName,
2076bdd1243dSDimitry Andric                               SubOpInfo);
2077bdd1243dSDimitry Andric           InsnOperands.push_back(SubOpInfo);
207881ad6265SDimitry Andric         }
207981ad6265SDimitry Andric         continue;
208081ad6265SDimitry Andric       }
208181ad6265SDimitry Andric 
2082bdd1243dSDimitry Andric       // Otherwise, if we have an operand with sub-operands, but they aren't
2083bdd1243dSDimitry Andric       // named...
2084bdd1243dSDimitry Andric       if (SubOps && OpInfo.Decoder.empty()) {
2085bdd1243dSDimitry Andric         // If it's a single sub-operand, and no custom decoder, use the decoder
2086bdd1243dSDimitry Andric         // from the one sub-operand.
2087bdd1243dSDimitry Andric         if (SubOps->getNumArgs() == 1)
2088bdd1243dSDimitry Andric           OpInfo = getOpInfo(cast<DefInit>(SubOps->getArg(0))->getDef());
2089bdd1243dSDimitry Andric 
2090bdd1243dSDimitry Andric         // If we have multiple sub-ops, there'd better have a custom
2091bdd1243dSDimitry Andric         // decoder. (Otherwise we don't know how to populate them properly...)
2092bdd1243dSDimitry Andric         if (SubOps->getNumArgs() > 1) {
2093bdd1243dSDimitry Andric           PrintError(EncodingDef.getLoc(),
2094bdd1243dSDimitry Andric                      "DecoderEmitter: operand \"" + OpName +
2095bdd1243dSDimitry Andric                          "\" uses MIOperandInfo with multiple ops, but doesn't "
2096bdd1243dSDimitry Andric                          "have a custom decoder!");
2097bdd1243dSDimitry Andric           debugDumpRecord(EncodingDef);
209881ad6265SDimitry Andric           continue;
209981ad6265SDimitry Andric         }
210081ad6265SDimitry Andric       }
210181ad6265SDimitry Andric 
2102bdd1243dSDimitry Andric       addOneOperandFields(EncodingDef, Bits, TiedNames, OpName, OpInfo);
2103bdd1243dSDimitry Andric       // FIXME: it should be an error not to find a definition for a given
2104bdd1243dSDimitry Andric       // operand, rather than just failing to add it to the resulting
2105bdd1243dSDimitry Andric       // instruction! (This is a longstanding bug, which will be addressed in an
2106bdd1243dSDimitry Andric       // upcoming change.)
210781ad6265SDimitry Andric       if (OpInfo.numFields() > 0)
210881ad6265SDimitry Andric         InsnOperands.push_back(OpInfo);
210981ad6265SDimitry Andric     }
211081ad6265SDimitry Andric   }
211181ad6265SDimitry Andric   Operands[Opc] = InsnOperands;
211281ad6265SDimitry Andric 
211381ad6265SDimitry Andric #if 0
211481ad6265SDimitry Andric   LLVM_DEBUG({
211581ad6265SDimitry Andric       // Dumps the instruction encoding bits.
211681ad6265SDimitry Andric       dumpBits(errs(), Bits);
211781ad6265SDimitry Andric 
211881ad6265SDimitry Andric       errs() << '\n';
211981ad6265SDimitry Andric 
212081ad6265SDimitry Andric       // Dumps the list of operand info.
212181ad6265SDimitry Andric       for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) {
212281ad6265SDimitry Andric         const CGIOperandList::OperandInfo &Info = CGI.Operands[i];
212381ad6265SDimitry Andric         const std::string &OperandName = Info.Name;
212481ad6265SDimitry Andric         const Record &OperandDef = *Info.Rec;
212581ad6265SDimitry Andric 
212681ad6265SDimitry Andric         errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n";
212781ad6265SDimitry Andric       }
212881ad6265SDimitry Andric     });
212981ad6265SDimitry Andric #endif
213081ad6265SDimitry Andric 
213181ad6265SDimitry Andric   return Bits.getNumBits();
213281ad6265SDimitry Andric }
213381ad6265SDimitry Andric 
213481ad6265SDimitry Andric // emitFieldFromInstruction - Emit the templated helper function
213581ad6265SDimitry Andric // fieldFromInstruction().
213681ad6265SDimitry Andric // On Windows we make sure that this function is not inlined when
213781ad6265SDimitry Andric // using the VS compiler. It has a bug which causes the function
2138bdd1243dSDimitry Andric // to be optimized out in some circumstances. See llvm.org/pr38292
213981ad6265SDimitry Andric static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
214081ad6265SDimitry Andric   OS << "// Helper functions for extracting fields from encoded instructions.\n"
214181ad6265SDimitry Andric      << "// InsnType must either be integral or an APInt-like object that "
214281ad6265SDimitry Andric         "must:\n"
214381ad6265SDimitry Andric      << "// * be default-constructible and copy-constructible\n"
214481ad6265SDimitry Andric      << "// * be constructible from an APInt (this can be private)\n"
214581ad6265SDimitry Andric      << "// * Support insertBits(bits, startBit, numBits)\n"
214681ad6265SDimitry Andric      << "// * Support extractBitsAsZExtValue(numBits, startBit)\n"
214781ad6265SDimitry Andric      << "// * Support the ~, &, ==, and != operators with other objects of "
214881ad6265SDimitry Andric         "the same type\n"
214981ad6265SDimitry Andric      << "// * Support the != and bitwise & with uint64_t\n"
215081ad6265SDimitry Andric      << "// * Support put (<<) to raw_ostream&\n"
215181ad6265SDimitry Andric      << "template <typename InsnType>\n"
215281ad6265SDimitry Andric      << "#if defined(_MSC_VER) && !defined(__clang__)\n"
215381ad6265SDimitry Andric      << "__declspec(noinline)\n"
215481ad6265SDimitry Andric      << "#endif\n"
215581ad6265SDimitry Andric      << "static std::enable_if_t<std::is_integral<InsnType>::value, InsnType>\n"
215681ad6265SDimitry Andric      << "fieldFromInstruction(const InsnType &insn, unsigned startBit,\n"
215781ad6265SDimitry Andric      << "                     unsigned numBits) {\n"
215881ad6265SDimitry Andric      << "  assert(startBit + numBits <= 64 && \"Cannot support >64-bit "
215981ad6265SDimitry Andric         "extractions!\");\n"
216081ad6265SDimitry Andric      << "  assert(startBit + numBits <= (sizeof(InsnType) * 8) &&\n"
216181ad6265SDimitry Andric      << "         \"Instruction field out of bounds!\");\n"
216281ad6265SDimitry Andric      << "  InsnType fieldMask;\n"
216381ad6265SDimitry Andric      << "  if (numBits == sizeof(InsnType) * 8)\n"
216481ad6265SDimitry Andric      << "    fieldMask = (InsnType)(-1LL);\n"
216581ad6265SDimitry Andric      << "  else\n"
216681ad6265SDimitry Andric      << "    fieldMask = (((InsnType)1 << numBits) - 1) << startBit;\n"
216781ad6265SDimitry Andric      << "  return (insn & fieldMask) >> startBit;\n"
216881ad6265SDimitry Andric      << "}\n"
216981ad6265SDimitry Andric      << "\n"
217081ad6265SDimitry Andric      << "template <typename InsnType>\n"
217181ad6265SDimitry Andric      << "static std::enable_if_t<!std::is_integral<InsnType>::value, "
217281ad6265SDimitry Andric         "uint64_t>\n"
217381ad6265SDimitry Andric      << "fieldFromInstruction(const InsnType &insn, unsigned startBit,\n"
217481ad6265SDimitry Andric      << "                     unsigned numBits) {\n"
217581ad6265SDimitry Andric      << "  return insn.extractBitsAsZExtValue(numBits, startBit);\n"
217681ad6265SDimitry Andric      << "}\n\n";
217781ad6265SDimitry Andric }
217881ad6265SDimitry Andric 
217981ad6265SDimitry Andric // emitInsertBits - Emit the templated helper function insertBits().
218081ad6265SDimitry Andric static void emitInsertBits(formatted_raw_ostream &OS) {
218181ad6265SDimitry Andric   OS << "// Helper function for inserting bits extracted from an encoded "
218281ad6265SDimitry Andric         "instruction into\n"
218381ad6265SDimitry Andric      << "// a field.\n"
218481ad6265SDimitry Andric      << "template <typename InsnType>\n"
218581ad6265SDimitry Andric      << "static std::enable_if_t<std::is_integral<InsnType>::value>\n"
218681ad6265SDimitry Andric      << "insertBits(InsnType &field, InsnType bits, unsigned startBit, "
218781ad6265SDimitry Andric         "unsigned numBits) {\n"
218881ad6265SDimitry Andric      << "  assert(startBit + numBits <= sizeof field * 8);\n"
218981ad6265SDimitry Andric      << "  field |= (InsnType)bits << startBit;\n"
219081ad6265SDimitry Andric      << "}\n"
219181ad6265SDimitry Andric      << "\n"
219281ad6265SDimitry Andric      << "template <typename InsnType>\n"
219381ad6265SDimitry Andric      << "static std::enable_if_t<!std::is_integral<InsnType>::value>\n"
219481ad6265SDimitry Andric      << "insertBits(InsnType &field, uint64_t bits, unsigned startBit, "
219581ad6265SDimitry Andric         "unsigned numBits) {\n"
219681ad6265SDimitry Andric      << "  field.insertBits(bits, startBit, numBits);\n"
219781ad6265SDimitry Andric      << "}\n\n";
219881ad6265SDimitry Andric }
219981ad6265SDimitry Andric 
220081ad6265SDimitry Andric // emitDecodeInstruction - Emit the templated helper function
220181ad6265SDimitry Andric // decodeInstruction().
220281ad6265SDimitry Andric static void emitDecodeInstruction(formatted_raw_ostream &OS,
220381ad6265SDimitry Andric                                   bool IsVarLenInst) {
220481ad6265SDimitry Andric   OS << "template <typename InsnType>\n"
220581ad6265SDimitry Andric      << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], "
220681ad6265SDimitry Andric         "MCInst &MI,\n"
220781ad6265SDimitry Andric      << "                                      InsnType insn, uint64_t "
220881ad6265SDimitry Andric         "Address,\n"
220981ad6265SDimitry Andric      << "                                      const MCDisassembler *DisAsm,\n"
221081ad6265SDimitry Andric      << "                                      const MCSubtargetInfo &STI";
221181ad6265SDimitry Andric   if (IsVarLenInst) {
221281ad6265SDimitry Andric     OS << ",\n"
221381ad6265SDimitry Andric        << "                                      llvm::function_ref<void(APInt "
221481ad6265SDimitry Andric           "&,"
221581ad6265SDimitry Andric        << " uint64_t)> makeUp";
221681ad6265SDimitry Andric   }
221781ad6265SDimitry Andric   OS << ") {\n"
221881ad6265SDimitry Andric      << "  const FeatureBitset &Bits = STI.getFeatureBits();\n"
221981ad6265SDimitry Andric      << "\n"
222081ad6265SDimitry Andric      << "  const uint8_t *Ptr = DecodeTable;\n"
222181ad6265SDimitry Andric      << "  uint64_t CurFieldValue = 0;\n"
222281ad6265SDimitry Andric      << "  DecodeStatus S = MCDisassembler::Success;\n"
222381ad6265SDimitry Andric      << "  while (true) {\n"
222481ad6265SDimitry Andric      << "    ptrdiff_t Loc = Ptr - DecodeTable;\n"
222581ad6265SDimitry Andric      << "    switch (*Ptr) {\n"
222681ad6265SDimitry Andric      << "    default:\n"
222781ad6265SDimitry Andric      << "      errs() << Loc << \": Unexpected decode table opcode!\\n\";\n"
222881ad6265SDimitry Andric      << "      return MCDisassembler::Fail;\n"
222981ad6265SDimitry Andric      << "    case MCD::OPC_ExtractField: {\n"
223081ad6265SDimitry Andric      << "      unsigned Start = *++Ptr;\n"
223181ad6265SDimitry Andric      << "      unsigned Len = *++Ptr;\n"
223281ad6265SDimitry Andric      << "      ++Ptr;\n";
223381ad6265SDimitry Andric   if (IsVarLenInst)
223481ad6265SDimitry Andric     OS << "      makeUp(insn, Start + Len);\n";
223581ad6265SDimitry Andric   OS << "      CurFieldValue = fieldFromInstruction(insn, Start, Len);\n"
223681ad6265SDimitry Andric      << "      LLVM_DEBUG(dbgs() << Loc << \": OPC_ExtractField(\" << Start << "
223781ad6265SDimitry Andric         "\", \"\n"
223881ad6265SDimitry Andric      << "                   << Len << \"): \" << CurFieldValue << \"\\n\");\n"
223981ad6265SDimitry Andric      << "      break;\n"
224081ad6265SDimitry Andric      << "    }\n"
224181ad6265SDimitry Andric      << "    case MCD::OPC_FilterValue: {\n"
224281ad6265SDimitry Andric      << "      // Decode the field value.\n"
224381ad6265SDimitry Andric      << "      unsigned Len;\n"
224481ad6265SDimitry Andric      << "      uint64_t Val = decodeULEB128(++Ptr, &Len);\n"
224581ad6265SDimitry Andric      << "      Ptr += Len;\n"
224681ad6265SDimitry Andric      << "      // NumToSkip is a plain 24-bit integer.\n"
224781ad6265SDimitry Andric      << "      unsigned NumToSkip = *Ptr++;\n"
224881ad6265SDimitry Andric      << "      NumToSkip |= (*Ptr++) << 8;\n"
224981ad6265SDimitry Andric      << "      NumToSkip |= (*Ptr++) << 16;\n"
225081ad6265SDimitry Andric      << "\n"
225181ad6265SDimitry Andric      << "      // Perform the filter operation.\n"
225281ad6265SDimitry Andric      << "      if (Val != CurFieldValue)\n"
225381ad6265SDimitry Andric      << "        Ptr += NumToSkip;\n"
225481ad6265SDimitry Andric      << "      LLVM_DEBUG(dbgs() << Loc << \": OPC_FilterValue(\" << Val << "
225581ad6265SDimitry Andric         "\", \" << NumToSkip\n"
225681ad6265SDimitry Andric      << "                   << \"): \" << ((Val != CurFieldValue) ? \"FAIL:\" "
225781ad6265SDimitry Andric         ": \"PASS:\")\n"
225881ad6265SDimitry Andric      << "                   << \" continuing at \" << (Ptr - DecodeTable) << "
225981ad6265SDimitry Andric         "\"\\n\");\n"
226081ad6265SDimitry Andric      << "\n"
226181ad6265SDimitry Andric      << "      break;\n"
226281ad6265SDimitry Andric      << "    }\n"
226381ad6265SDimitry Andric      << "    case MCD::OPC_CheckField: {\n"
226481ad6265SDimitry Andric      << "      unsigned Start = *++Ptr;\n"
226581ad6265SDimitry Andric      << "      unsigned Len = *++Ptr;\n";
226681ad6265SDimitry Andric   if (IsVarLenInst)
226781ad6265SDimitry Andric     OS << "      makeUp(insn, Start + Len);\n";
226881ad6265SDimitry Andric   OS << "      uint64_t FieldValue = fieldFromInstruction(insn, Start, Len);\n"
226981ad6265SDimitry Andric      << "      // Decode the field value.\n"
227081ad6265SDimitry Andric      << "      unsigned PtrLen = 0;\n"
227181ad6265SDimitry Andric      << "      uint64_t ExpectedValue = decodeULEB128(++Ptr, &PtrLen);\n"
227281ad6265SDimitry Andric      << "      Ptr += PtrLen;\n"
227381ad6265SDimitry Andric      << "      // NumToSkip is a plain 24-bit integer.\n"
227481ad6265SDimitry Andric      << "      unsigned NumToSkip = *Ptr++;\n"
227581ad6265SDimitry Andric      << "      NumToSkip |= (*Ptr++) << 8;\n"
227681ad6265SDimitry Andric      << "      NumToSkip |= (*Ptr++) << 16;\n"
227781ad6265SDimitry Andric      << "\n"
227881ad6265SDimitry Andric      << "      // If the actual and expected values don't match, skip.\n"
227981ad6265SDimitry Andric      << "      if (ExpectedValue != FieldValue)\n"
228081ad6265SDimitry Andric      << "        Ptr += NumToSkip;\n"
228181ad6265SDimitry Andric      << "      LLVM_DEBUG(dbgs() << Loc << \": OPC_CheckField(\" << Start << "
228281ad6265SDimitry Andric         "\", \"\n"
228381ad6265SDimitry Andric      << "                   << Len << \", \" << ExpectedValue << \", \" << "
228481ad6265SDimitry Andric         "NumToSkip\n"
228581ad6265SDimitry Andric      << "                   << \"): FieldValue = \" << FieldValue << \", "
228681ad6265SDimitry Andric         "ExpectedValue = \"\n"
228781ad6265SDimitry Andric      << "                   << ExpectedValue << \": \"\n"
228881ad6265SDimitry Andric      << "                   << ((ExpectedValue == FieldValue) ? \"PASS\\n\" : "
228981ad6265SDimitry Andric         "\"FAIL\\n\"));\n"
229081ad6265SDimitry Andric      << "      break;\n"
229181ad6265SDimitry Andric      << "    }\n"
229281ad6265SDimitry Andric      << "    case MCD::OPC_CheckPredicate: {\n"
229381ad6265SDimitry Andric      << "      unsigned Len;\n"
229481ad6265SDimitry Andric      << "      // Decode the Predicate Index value.\n"
229581ad6265SDimitry Andric      << "      unsigned PIdx = decodeULEB128(++Ptr, &Len);\n"
229681ad6265SDimitry Andric      << "      Ptr += Len;\n"
229781ad6265SDimitry Andric      << "      // NumToSkip is a plain 24-bit integer.\n"
229881ad6265SDimitry Andric      << "      unsigned NumToSkip = *Ptr++;\n"
229981ad6265SDimitry Andric      << "      NumToSkip |= (*Ptr++) << 8;\n"
230081ad6265SDimitry Andric      << "      NumToSkip |= (*Ptr++) << 16;\n"
230181ad6265SDimitry Andric      << "      // Check the predicate.\n"
230281ad6265SDimitry Andric      << "      bool Pred;\n"
230381ad6265SDimitry Andric      << "      if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\n"
230481ad6265SDimitry Andric      << "        Ptr += NumToSkip;\n"
230581ad6265SDimitry Andric      << "      (void)Pred;\n"
230681ad6265SDimitry Andric      << "      LLVM_DEBUG(dbgs() << Loc << \": OPC_CheckPredicate(\" << PIdx "
230781ad6265SDimitry Andric         "<< \"): \"\n"
230881ad6265SDimitry Andric      << "            << (Pred ? \"PASS\\n\" : \"FAIL\\n\"));\n"
230981ad6265SDimitry Andric      << "\n"
231081ad6265SDimitry Andric      << "      break;\n"
231181ad6265SDimitry Andric      << "    }\n"
231281ad6265SDimitry Andric      << "    case MCD::OPC_Decode: {\n"
231381ad6265SDimitry Andric      << "      unsigned Len;\n"
231481ad6265SDimitry Andric      << "      // Decode the Opcode value.\n"
231581ad6265SDimitry Andric      << "      unsigned Opc = decodeULEB128(++Ptr, &Len);\n"
231681ad6265SDimitry Andric      << "      Ptr += Len;\n"
231781ad6265SDimitry Andric      << "      unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\n"
231881ad6265SDimitry Andric      << "      Ptr += Len;\n"
231981ad6265SDimitry Andric      << "\n"
232081ad6265SDimitry Andric      << "      MI.clear();\n"
232181ad6265SDimitry Andric      << "      MI.setOpcode(Opc);\n"
232281ad6265SDimitry Andric      << "      bool DecodeComplete;\n";
232381ad6265SDimitry Andric   if (IsVarLenInst) {
232481ad6265SDimitry Andric     OS << "      Len = InstrLenTable[Opc];\n"
232581ad6265SDimitry Andric        << "      makeUp(insn, Len);\n";
232681ad6265SDimitry Andric   }
232781ad6265SDimitry Andric   OS << "      S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, "
232881ad6265SDimitry Andric         "DecodeComplete);\n"
232981ad6265SDimitry Andric      << "      assert(DecodeComplete);\n"
233081ad6265SDimitry Andric      << "\n"
233181ad6265SDimitry Andric      << "      LLVM_DEBUG(dbgs() << Loc << \": OPC_Decode: opcode \" << Opc\n"
233281ad6265SDimitry Andric      << "                   << \", using decoder \" << DecodeIdx << \": \"\n"
233381ad6265SDimitry Andric      << "                   << (S != MCDisassembler::Fail ? \"PASS\" : "
233481ad6265SDimitry Andric         "\"FAIL\") << \"\\n\");\n"
233581ad6265SDimitry Andric      << "      return S;\n"
233681ad6265SDimitry Andric      << "    }\n"
233781ad6265SDimitry Andric      << "    case MCD::OPC_TryDecode: {\n"
233881ad6265SDimitry Andric      << "      unsigned Len;\n"
233981ad6265SDimitry Andric      << "      // Decode the Opcode value.\n"
234081ad6265SDimitry Andric      << "      unsigned Opc = decodeULEB128(++Ptr, &Len);\n"
234181ad6265SDimitry Andric      << "      Ptr += Len;\n"
234281ad6265SDimitry Andric      << "      unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\n"
234381ad6265SDimitry Andric      << "      Ptr += Len;\n"
234481ad6265SDimitry Andric      << "      // NumToSkip is a plain 24-bit integer.\n"
234581ad6265SDimitry Andric      << "      unsigned NumToSkip = *Ptr++;\n"
234681ad6265SDimitry Andric      << "      NumToSkip |= (*Ptr++) << 8;\n"
234781ad6265SDimitry Andric      << "      NumToSkip |= (*Ptr++) << 16;\n"
234881ad6265SDimitry Andric      << "\n"
234981ad6265SDimitry Andric      << "      // Perform the decode operation.\n"
235081ad6265SDimitry Andric      << "      MCInst TmpMI;\n"
235181ad6265SDimitry Andric      << "      TmpMI.setOpcode(Opc);\n"
235281ad6265SDimitry Andric      << "      bool DecodeComplete;\n"
235381ad6265SDimitry Andric      << "      S = decodeToMCInst(S, DecodeIdx, insn, TmpMI, Address, DisAsm, "
235481ad6265SDimitry Andric         "DecodeComplete);\n"
235581ad6265SDimitry Andric      << "      LLVM_DEBUG(dbgs() << Loc << \": OPC_TryDecode: opcode \" << "
235681ad6265SDimitry Andric         "Opc\n"
235781ad6265SDimitry Andric      << "                   << \", using decoder \" << DecodeIdx << \": \");\n"
235881ad6265SDimitry Andric      << "\n"
235981ad6265SDimitry Andric      << "      if (DecodeComplete) {\n"
236081ad6265SDimitry Andric      << "        // Decoding complete.\n"
236181ad6265SDimitry Andric      << "        LLVM_DEBUG(dbgs() << (S != MCDisassembler::Fail ? \"PASS\" : "
236281ad6265SDimitry Andric         "\"FAIL\") << \"\\n\");\n"
236381ad6265SDimitry Andric      << "        MI = TmpMI;\n"
236481ad6265SDimitry Andric      << "        return S;\n"
236581ad6265SDimitry Andric      << "      } else {\n"
236681ad6265SDimitry Andric      << "        assert(S == MCDisassembler::Fail);\n"
236781ad6265SDimitry Andric      << "        // If the decoding was incomplete, skip.\n"
236881ad6265SDimitry Andric      << "        Ptr += NumToSkip;\n"
236981ad6265SDimitry Andric      << "        LLVM_DEBUG(dbgs() << \"FAIL: continuing at \" << (Ptr - "
237081ad6265SDimitry Andric         "DecodeTable) << \"\\n\");\n"
237181ad6265SDimitry Andric      << "        // Reset decode status. This also drops a SoftFail status "
237281ad6265SDimitry Andric         "that could be\n"
237381ad6265SDimitry Andric      << "        // set before the decode attempt.\n"
237481ad6265SDimitry Andric      << "        S = MCDisassembler::Success;\n"
237581ad6265SDimitry Andric      << "      }\n"
237681ad6265SDimitry Andric      << "      break;\n"
237781ad6265SDimitry Andric      << "    }\n"
237881ad6265SDimitry Andric      << "    case MCD::OPC_SoftFail: {\n"
237981ad6265SDimitry Andric      << "      // Decode the mask values.\n"
238081ad6265SDimitry Andric      << "      unsigned Len;\n"
238181ad6265SDimitry Andric      << "      uint64_t PositiveMask = decodeULEB128(++Ptr, &Len);\n"
238281ad6265SDimitry Andric      << "      Ptr += Len;\n"
238381ad6265SDimitry Andric      << "      uint64_t NegativeMask = decodeULEB128(Ptr, &Len);\n"
238481ad6265SDimitry Andric      << "      Ptr += Len;\n"
238581ad6265SDimitry Andric      << "      bool Fail = (insn & PositiveMask) != 0 || (~insn & "
238681ad6265SDimitry Andric         "NegativeMask) != 0;\n"
238781ad6265SDimitry Andric      << "      if (Fail)\n"
238881ad6265SDimitry Andric      << "        S = MCDisassembler::SoftFail;\n"
238981ad6265SDimitry Andric      << "      LLVM_DEBUG(dbgs() << Loc << \": OPC_SoftFail: \" << (Fail ? "
239081ad6265SDimitry Andric         "\"FAIL\\n\" : \"PASS\\n\"));\n"
239181ad6265SDimitry Andric      << "      break;\n"
239281ad6265SDimitry Andric      << "    }\n"
239381ad6265SDimitry Andric      << "    case MCD::OPC_Fail: {\n"
239481ad6265SDimitry Andric      << "      LLVM_DEBUG(dbgs() << Loc << \": OPC_Fail\\n\");\n"
239581ad6265SDimitry Andric      << "      return MCDisassembler::Fail;\n"
239681ad6265SDimitry Andric      << "    }\n"
239781ad6265SDimitry Andric      << "    }\n"
239881ad6265SDimitry Andric      << "  }\n"
239981ad6265SDimitry Andric      << "  llvm_unreachable(\"bogosity detected in disassembler state "
240081ad6265SDimitry Andric         "machine!\");\n"
240181ad6265SDimitry Andric      << "}\n\n";
240281ad6265SDimitry Andric }
240381ad6265SDimitry Andric 
2404bdd1243dSDimitry Andric // Helper to propagate SoftFail status. Returns false if the status is Fail;
2405bdd1243dSDimitry Andric // callers are expected to early-exit in that condition. (Note, the '&' operator
2406bdd1243dSDimitry Andric // is correct to propagate the values of this enum; see comment on 'enum
2407bdd1243dSDimitry Andric // DecodeStatus'.)
2408bdd1243dSDimitry Andric static void emitCheck(formatted_raw_ostream &OS) {
2409bdd1243dSDimitry Andric   OS << "static bool Check(DecodeStatus &Out, DecodeStatus In) {\n"
2410bdd1243dSDimitry Andric      << "  Out = static_cast<DecodeStatus>(Out & In);\n"
2411bdd1243dSDimitry Andric      << "  return Out != MCDisassembler::Fail;\n"
2412bdd1243dSDimitry Andric      << "}\n\n";
2413bdd1243dSDimitry Andric }
2414bdd1243dSDimitry Andric 
241581ad6265SDimitry Andric // Emits disassembler code for instruction decoding.
241681ad6265SDimitry Andric void DecoderEmitter::run(raw_ostream &o) {
241781ad6265SDimitry Andric   formatted_raw_ostream OS(o);
241881ad6265SDimitry Andric   OS << "#include \"llvm/MC/MCInst.h\"\n";
241981ad6265SDimitry Andric   OS << "#include \"llvm/MC/MCSubtargetInfo.h\"\n";
242081ad6265SDimitry Andric   OS << "#include \"llvm/Support/DataTypes.h\"\n";
242181ad6265SDimitry Andric   OS << "#include \"llvm/Support/Debug.h\"\n";
242281ad6265SDimitry Andric   OS << "#include \"llvm/Support/LEB128.h\"\n";
242381ad6265SDimitry Andric   OS << "#include \"llvm/Support/raw_ostream.h\"\n";
2424*06c3fb27SDimitry Andric   OS << "#include \"llvm/TargetParser/SubtargetFeature.h\"\n";
242581ad6265SDimitry Andric   OS << "#include <assert.h>\n";
242681ad6265SDimitry Andric   OS << '\n';
242781ad6265SDimitry Andric   OS << "namespace llvm {\n\n";
242881ad6265SDimitry Andric 
242981ad6265SDimitry Andric   emitFieldFromInstruction(OS);
243081ad6265SDimitry Andric   emitInsertBits(OS);
2431bdd1243dSDimitry Andric   emitCheck(OS);
243281ad6265SDimitry Andric 
243381ad6265SDimitry Andric   Target.reverseBitsForLittleEndianEncoding();
243481ad6265SDimitry Andric 
243581ad6265SDimitry Andric   // Parameterize the decoders based on namespace and instruction width.
243681ad6265SDimitry Andric   std::set<StringRef> HwModeNames;
243781ad6265SDimitry Andric   const auto &NumberedInstructions = Target.getInstructionsByEnumValue();
243881ad6265SDimitry Andric   NumberedEncodings.reserve(NumberedInstructions.size());
243981ad6265SDimitry Andric   DenseMap<Record *, unsigned> IndexOfInstruction;
244081ad6265SDimitry Andric   // First, collect all HwModes referenced by the target.
244181ad6265SDimitry Andric   for (const auto &NumberedInstruction : NumberedInstructions) {
244281ad6265SDimitry Andric     IndexOfInstruction[NumberedInstruction->TheDef] = NumberedEncodings.size();
244381ad6265SDimitry Andric 
244481ad6265SDimitry Andric     if (const RecordVal *RV =
244581ad6265SDimitry Andric             NumberedInstruction->TheDef->getValue("EncodingInfos")) {
244681ad6265SDimitry Andric       if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
244781ad6265SDimitry Andric         const CodeGenHwModes &HWM = Target.getHwModes();
244881ad6265SDimitry Andric         EncodingInfoByHwMode EBM(DI->getDef(), HWM);
244981ad6265SDimitry Andric         for (auto &KV : EBM)
245081ad6265SDimitry Andric           HwModeNames.insert(HWM.getMode(KV.first).Name);
245181ad6265SDimitry Andric       }
245281ad6265SDimitry Andric     }
245381ad6265SDimitry Andric   }
245481ad6265SDimitry Andric 
245581ad6265SDimitry Andric   // If HwModeNames is empty, add the empty string so we always have one HwMode.
245681ad6265SDimitry Andric   if (HwModeNames.empty())
245781ad6265SDimitry Andric     HwModeNames.insert("");
245881ad6265SDimitry Andric 
245981ad6265SDimitry Andric   for (const auto &NumberedInstruction : NumberedInstructions) {
246081ad6265SDimitry Andric     IndexOfInstruction[NumberedInstruction->TheDef] = NumberedEncodings.size();
246181ad6265SDimitry Andric 
246281ad6265SDimitry Andric     if (const RecordVal *RV =
246381ad6265SDimitry Andric             NumberedInstruction->TheDef->getValue("EncodingInfos")) {
246481ad6265SDimitry Andric       if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
246581ad6265SDimitry Andric         const CodeGenHwModes &HWM = Target.getHwModes();
246681ad6265SDimitry Andric         EncodingInfoByHwMode EBM(DI->getDef(), HWM);
246781ad6265SDimitry Andric         for (auto &KV : EBM) {
246881ad6265SDimitry Andric           NumberedEncodings.emplace_back(KV.second, NumberedInstruction,
246981ad6265SDimitry Andric                                          HWM.getMode(KV.first).Name);
247081ad6265SDimitry Andric           HwModeNames.insert(HWM.getMode(KV.first).Name);
247181ad6265SDimitry Andric         }
247281ad6265SDimitry Andric         continue;
247381ad6265SDimitry Andric       }
247481ad6265SDimitry Andric     }
247581ad6265SDimitry Andric     // This instruction is encoded the same on all HwModes. Emit it for all
247681ad6265SDimitry Andric     // HwModes.
247781ad6265SDimitry Andric     for (StringRef HwModeName : HwModeNames)
247881ad6265SDimitry Andric       NumberedEncodings.emplace_back(NumberedInstruction->TheDef,
247981ad6265SDimitry Andric                                      NumberedInstruction, HwModeName);
248081ad6265SDimitry Andric   }
248181ad6265SDimitry Andric   for (const auto &NumberedAlias : RK.getAllDerivedDefinitions("AdditionalEncoding"))
248281ad6265SDimitry Andric     NumberedEncodings.emplace_back(
248381ad6265SDimitry Andric         NumberedAlias,
248481ad6265SDimitry Andric         &Target.getInstruction(NumberedAlias->getValueAsDef("AliasOf")));
248581ad6265SDimitry Andric 
248681ad6265SDimitry Andric   std::map<std::pair<std::string, unsigned>, std::vector<EncodingIDAndOpcode>>
248781ad6265SDimitry Andric       OpcMap;
248881ad6265SDimitry Andric   std::map<unsigned, std::vector<OperandInfo>> Operands;
248981ad6265SDimitry Andric   std::vector<unsigned> InstrLen;
249081ad6265SDimitry Andric 
249181ad6265SDimitry Andric   bool IsVarLenInst =
249281ad6265SDimitry Andric       any_of(NumberedInstructions, [](const CodeGenInstruction *CGI) {
249381ad6265SDimitry Andric         RecordVal *RV = CGI->TheDef->getValue("Inst");
249481ad6265SDimitry Andric         return RV && isa<DagInit>(RV->getValue());
249581ad6265SDimitry Andric       });
249681ad6265SDimitry Andric   unsigned MaxInstLen = 0;
249781ad6265SDimitry Andric 
249881ad6265SDimitry Andric   for (unsigned i = 0; i < NumberedEncodings.size(); ++i) {
249981ad6265SDimitry Andric     const Record *EncodingDef = NumberedEncodings[i].EncodingDef;
250081ad6265SDimitry Andric     const CodeGenInstruction *Inst = NumberedEncodings[i].Inst;
250181ad6265SDimitry Andric     const Record *Def = Inst->TheDef;
250281ad6265SDimitry Andric     unsigned Size = EncodingDef->getValueAsInt("Size");
250381ad6265SDimitry Andric     if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
250481ad6265SDimitry Andric         Def->getValueAsBit("isPseudo") ||
250581ad6265SDimitry Andric         Def->getValueAsBit("isAsmParserOnly") ||
250681ad6265SDimitry Andric         Def->getValueAsBit("isCodeGenOnly")) {
250781ad6265SDimitry Andric       NumEncodingsLackingDisasm++;
250881ad6265SDimitry Andric       continue;
250981ad6265SDimitry Andric     }
251081ad6265SDimitry Andric 
251181ad6265SDimitry Andric     if (i < NumberedInstructions.size())
251281ad6265SDimitry Andric       NumInstructions++;
251381ad6265SDimitry Andric     NumEncodings++;
251481ad6265SDimitry Andric 
251581ad6265SDimitry Andric     if (!Size && !IsVarLenInst)
251681ad6265SDimitry Andric       continue;
251781ad6265SDimitry Andric 
251881ad6265SDimitry Andric     if (IsVarLenInst)
251981ad6265SDimitry Andric       InstrLen.resize(NumberedInstructions.size(), 0);
252081ad6265SDimitry Andric 
252181ad6265SDimitry Andric     if (unsigned Len = populateInstruction(Target, *EncodingDef, *Inst, i,
252281ad6265SDimitry Andric                                            Operands, IsVarLenInst)) {
252381ad6265SDimitry Andric       if (IsVarLenInst) {
252481ad6265SDimitry Andric         MaxInstLen = std::max(MaxInstLen, Len);
252581ad6265SDimitry Andric         InstrLen[i] = Len;
252681ad6265SDimitry Andric       }
252781ad6265SDimitry Andric       std::string DecoderNamespace =
252881ad6265SDimitry Andric           std::string(EncodingDef->getValueAsString("DecoderNamespace"));
252981ad6265SDimitry Andric       if (!NumberedEncodings[i].HwModeName.empty())
253081ad6265SDimitry Andric         DecoderNamespace +=
253181ad6265SDimitry Andric             std::string("_") + NumberedEncodings[i].HwModeName.str();
253281ad6265SDimitry Andric       OpcMap[std::make_pair(DecoderNamespace, Size)].emplace_back(
253381ad6265SDimitry Andric           i, IndexOfInstruction.find(Def)->second);
253481ad6265SDimitry Andric     } else {
253581ad6265SDimitry Andric       NumEncodingsOmitted++;
253681ad6265SDimitry Andric     }
253781ad6265SDimitry Andric   }
253881ad6265SDimitry Andric 
253981ad6265SDimitry Andric   DecoderTableInfo TableInfo;
254081ad6265SDimitry Andric   for (const auto &Opc : OpcMap) {
254181ad6265SDimitry Andric     // Emit the decoder for this namespace+width combination.
254281ad6265SDimitry Andric     ArrayRef<EncodingAndInst> NumberedEncodingsRef(
254381ad6265SDimitry Andric         NumberedEncodings.data(), NumberedEncodings.size());
254481ad6265SDimitry Andric     FilterChooser FC(NumberedEncodingsRef, Opc.second, Operands,
254581ad6265SDimitry Andric                      IsVarLenInst ? MaxInstLen : 8 * Opc.first.second, this);
254681ad6265SDimitry Andric 
254781ad6265SDimitry Andric     // The decode table is cleared for each top level decoder function. The
254881ad6265SDimitry Andric     // predicates and decoders themselves, however, are shared across all
254981ad6265SDimitry Andric     // decoders to give more opportunities for uniqueing.
255081ad6265SDimitry Andric     TableInfo.Table.clear();
255181ad6265SDimitry Andric     TableInfo.FixupStack.clear();
255281ad6265SDimitry Andric     TableInfo.Table.reserve(16384);
255381ad6265SDimitry Andric     TableInfo.FixupStack.emplace_back();
255481ad6265SDimitry Andric     FC.emitTableEntries(TableInfo);
255581ad6265SDimitry Andric     // Any NumToSkip fixups in the top level scope can resolve to the
255681ad6265SDimitry Andric     // OPC_Fail at the end of the table.
255781ad6265SDimitry Andric     assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!");
255881ad6265SDimitry Andric     // Resolve any NumToSkip fixups in the current scope.
255981ad6265SDimitry Andric     resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
256081ad6265SDimitry Andric                        TableInfo.Table.size());
256181ad6265SDimitry Andric     TableInfo.FixupStack.clear();
256281ad6265SDimitry Andric 
256381ad6265SDimitry Andric     TableInfo.Table.push_back(MCD::OPC_Fail);
256481ad6265SDimitry Andric 
256581ad6265SDimitry Andric     // Print the table to the output stream.
256681ad6265SDimitry Andric     emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), Opc.first.first);
256781ad6265SDimitry Andric   }
256881ad6265SDimitry Andric 
256981ad6265SDimitry Andric   // For variable instruction, we emit a instruction length table
257081ad6265SDimitry Andric   // to let the decoder know how long the instructions are.
257181ad6265SDimitry Andric   // You can see example usage in M68k's disassembler.
257281ad6265SDimitry Andric   if (IsVarLenInst)
257381ad6265SDimitry Andric     emitInstrLenTable(OS, InstrLen);
257481ad6265SDimitry Andric   // Emit the predicate function.
257581ad6265SDimitry Andric   emitPredicateFunction(OS, TableInfo.Predicates, 0);
257681ad6265SDimitry Andric 
257781ad6265SDimitry Andric   // Emit the decoder function.
257881ad6265SDimitry Andric   emitDecoderFunction(OS, TableInfo.Decoders, 0);
257981ad6265SDimitry Andric 
258081ad6265SDimitry Andric   // Emit the main entry point for the decoder, decodeInstruction().
258181ad6265SDimitry Andric   emitDecodeInstruction(OS, IsVarLenInst);
258281ad6265SDimitry Andric 
258381ad6265SDimitry Andric   OS << "\n} // end namespace llvm\n";
258481ad6265SDimitry Andric }
258581ad6265SDimitry Andric 
258681ad6265SDimitry Andric namespace llvm {
258781ad6265SDimitry Andric 
258881ad6265SDimitry Andric void EmitDecoder(RecordKeeper &RK, raw_ostream &OS,
2589bdd1243dSDimitry Andric                  const std::string &PredicateNamespace) {
2590bdd1243dSDimitry Andric   DecoderEmitter(RK, PredicateNamespace).run(OS);
259181ad6265SDimitry Andric }
259281ad6265SDimitry Andric 
259381ad6265SDimitry Andric } // end namespace llvm
2594