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*0fca6ea1SDimitry Andric #include "Common/CodeGenHwModes.h" 15*0fca6ea1SDimitry Andric #include "Common/CodeGenInstruction.h" 16*0fca6ea1SDimitry Andric #include "Common/CodeGenTarget.h" 17*0fca6ea1SDimitry Andric #include "Common/InfoByHwMode.h" 18*0fca6ea1SDimitry Andric #include "Common/VarLenCodeEmitterGen.h" 1906c3fb27SDimitry Andric #include "TableGenBackends.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" 25*0fca6ea1SDimitry Andric #include "llvm/ADT/SmallBitVector.h" 2681ad6265SDimitry Andric #include "llvm/ADT/SmallString.h" 2781ad6265SDimitry Andric #include "llvm/ADT/Statistic.h" 2881ad6265SDimitry Andric #include "llvm/ADT/StringExtras.h" 2981ad6265SDimitry Andric #include "llvm/ADT/StringRef.h" 3081ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h" 3181ad6265SDimitry Andric #include "llvm/Support/Casting.h" 32*0fca6ea1SDimitry Andric #include "llvm/Support/CommandLine.h" 3381ad6265SDimitry Andric #include "llvm/Support/Debug.h" 3481ad6265SDimitry Andric #include "llvm/Support/ErrorHandling.h" 3581ad6265SDimitry Andric #include "llvm/Support/FormattedStream.h" 3681ad6265SDimitry Andric #include "llvm/Support/LEB128.h" 3781ad6265SDimitry Andric #include "llvm/Support/raw_ostream.h" 3881ad6265SDimitry Andric #include "llvm/TableGen/Error.h" 3981ad6265SDimitry Andric #include "llvm/TableGen/Record.h" 4081ad6265SDimitry Andric #include <algorithm> 4181ad6265SDimitry Andric #include <cassert> 4281ad6265SDimitry Andric #include <cstddef> 4381ad6265SDimitry Andric #include <cstdint> 4481ad6265SDimitry Andric #include <map> 4581ad6265SDimitry Andric #include <memory> 4681ad6265SDimitry Andric #include <set> 4781ad6265SDimitry Andric #include <string> 4881ad6265SDimitry Andric #include <utility> 4981ad6265SDimitry Andric #include <vector> 5081ad6265SDimitry Andric 5181ad6265SDimitry Andric using namespace llvm; 5281ad6265SDimitry Andric 5381ad6265SDimitry Andric #define DEBUG_TYPE "decoder-emitter" 5481ad6265SDimitry Andric 55*0fca6ea1SDimitry Andric extern cl::OptionCategory DisassemblerEmitterCat; 56*0fca6ea1SDimitry Andric 57*0fca6ea1SDimitry Andric enum SuppressLevel { 58*0fca6ea1SDimitry Andric SUPPRESSION_DISABLE, 59*0fca6ea1SDimitry Andric SUPPRESSION_LEVEL1, 60*0fca6ea1SDimitry Andric SUPPRESSION_LEVEL2 61*0fca6ea1SDimitry Andric }; 62*0fca6ea1SDimitry Andric 63*0fca6ea1SDimitry Andric cl::opt<SuppressLevel> DecoderEmitterSuppressDuplicates( 64*0fca6ea1SDimitry Andric "suppress-per-hwmode-duplicates", 65*0fca6ea1SDimitry Andric cl::desc("Suppress duplication of instrs into per-HwMode decoder tables"), 66*0fca6ea1SDimitry Andric cl::values( 67*0fca6ea1SDimitry Andric clEnumValN( 68*0fca6ea1SDimitry Andric SUPPRESSION_DISABLE, "O0", 69*0fca6ea1SDimitry Andric "Do not prevent DecoderTable duplications caused by HwModes"), 70*0fca6ea1SDimitry Andric clEnumValN( 71*0fca6ea1SDimitry Andric SUPPRESSION_LEVEL1, "O1", 72*0fca6ea1SDimitry Andric "Remove duplicate DecoderTable entries generated due to HwModes"), 73*0fca6ea1SDimitry Andric clEnumValN( 74*0fca6ea1SDimitry Andric SUPPRESSION_LEVEL2, "O2", 75*0fca6ea1SDimitry Andric "Extract HwModes-specific instructions into new DecoderTables, " 76*0fca6ea1SDimitry Andric "significantly reducing Table Duplications")), 77*0fca6ea1SDimitry Andric cl::init(SUPPRESSION_DISABLE), cl::cat(DisassemblerEmitterCat)); 78*0fca6ea1SDimitry Andric 7981ad6265SDimitry Andric namespace { 8081ad6265SDimitry Andric 8181ad6265SDimitry Andric STATISTIC(NumEncodings, "Number of encodings considered"); 82*0fca6ea1SDimitry Andric STATISTIC(NumEncodingsLackingDisasm, 83*0fca6ea1SDimitry Andric "Number of encodings without disassembler info"); 8481ad6265SDimitry Andric STATISTIC(NumInstructions, "Number of instructions considered"); 8581ad6265SDimitry Andric STATISTIC(NumEncodingsSupported, "Number of encodings supported"); 8681ad6265SDimitry Andric STATISTIC(NumEncodingsOmitted, "Number of encodings omitted"); 8781ad6265SDimitry Andric 8881ad6265SDimitry Andric struct EncodingField { 8981ad6265SDimitry Andric unsigned Base, Width, Offset; 9081ad6265SDimitry Andric EncodingField(unsigned B, unsigned W, unsigned O) 9181ad6265SDimitry Andric : Base(B), Width(W), Offset(O) {} 9281ad6265SDimitry Andric }; 9381ad6265SDimitry Andric 9481ad6265SDimitry Andric struct OperandInfo { 9581ad6265SDimitry Andric std::vector<EncodingField> Fields; 9681ad6265SDimitry Andric std::string Decoder; 9781ad6265SDimitry Andric bool HasCompleteDecoder; 9881ad6265SDimitry Andric uint64_t InitValue; 9981ad6265SDimitry Andric 10081ad6265SDimitry Andric OperandInfo(std::string D, bool HCD) 10181ad6265SDimitry Andric : Decoder(std::move(D)), HasCompleteDecoder(HCD), InitValue(0) {} 10281ad6265SDimitry Andric 10381ad6265SDimitry Andric void addField(unsigned Base, unsigned Width, unsigned Offset) { 10481ad6265SDimitry Andric Fields.push_back(EncodingField(Base, Width, Offset)); 10581ad6265SDimitry Andric } 10681ad6265SDimitry Andric 10781ad6265SDimitry Andric unsigned numFields() const { return Fields.size(); } 10881ad6265SDimitry Andric 10981ad6265SDimitry Andric typedef std::vector<EncodingField>::const_iterator const_iterator; 11081ad6265SDimitry Andric 11181ad6265SDimitry Andric const_iterator begin() const { return Fields.begin(); } 11281ad6265SDimitry Andric const_iterator end() const { return Fields.end(); } 11381ad6265SDimitry Andric }; 11481ad6265SDimitry Andric 11581ad6265SDimitry Andric typedef std::vector<uint8_t> DecoderTable; 11681ad6265SDimitry Andric typedef uint32_t DecoderFixup; 11781ad6265SDimitry Andric typedef std::vector<DecoderFixup> FixupList; 11881ad6265SDimitry Andric typedef std::vector<FixupList> FixupScopeList; 11981ad6265SDimitry Andric typedef SmallSetVector<CachedHashString, 16> PredicateSet; 12081ad6265SDimitry Andric typedef SmallSetVector<CachedHashString, 16> DecoderSet; 12181ad6265SDimitry Andric struct DecoderTableInfo { 12281ad6265SDimitry Andric DecoderTable Table; 12381ad6265SDimitry Andric FixupScopeList FixupStack; 12481ad6265SDimitry Andric PredicateSet Predicates; 12581ad6265SDimitry Andric DecoderSet Decoders; 12681ad6265SDimitry Andric }; 12781ad6265SDimitry Andric 12881ad6265SDimitry Andric struct EncodingAndInst { 12981ad6265SDimitry Andric const Record *EncodingDef; 13081ad6265SDimitry Andric const CodeGenInstruction *Inst; 13181ad6265SDimitry Andric StringRef HwModeName; 13281ad6265SDimitry Andric 13381ad6265SDimitry Andric EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst, 13481ad6265SDimitry Andric StringRef HwModeName = "") 13581ad6265SDimitry Andric : EncodingDef(EncodingDef), Inst(Inst), HwModeName(HwModeName) {} 13681ad6265SDimitry Andric }; 13781ad6265SDimitry Andric 13881ad6265SDimitry Andric struct EncodingIDAndOpcode { 13981ad6265SDimitry Andric unsigned EncodingID; 14081ad6265SDimitry Andric unsigned Opcode; 14181ad6265SDimitry Andric 14281ad6265SDimitry Andric EncodingIDAndOpcode() : EncodingID(0), Opcode(0) {} 14381ad6265SDimitry Andric EncodingIDAndOpcode(unsigned EncodingID, unsigned Opcode) 14481ad6265SDimitry Andric : EncodingID(EncodingID), Opcode(Opcode) {} 14581ad6265SDimitry Andric }; 14681ad6265SDimitry Andric 147*0fca6ea1SDimitry Andric using EncodingIDsVec = std::vector<EncodingIDAndOpcode>; 148*0fca6ea1SDimitry Andric using NamespacesHwModesMap = std::map<std::string, std::set<StringRef>>; 149*0fca6ea1SDimitry Andric 15081ad6265SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) { 15181ad6265SDimitry Andric if (Value.EncodingDef != Value.Inst->TheDef) 15281ad6265SDimitry Andric OS << Value.EncodingDef->getName() << ":"; 15381ad6265SDimitry Andric OS << Value.Inst->TheDef->getName(); 15481ad6265SDimitry Andric return OS; 15581ad6265SDimitry Andric } 15681ad6265SDimitry Andric 15781ad6265SDimitry Andric class DecoderEmitter { 15881ad6265SDimitry Andric RecordKeeper &RK; 15981ad6265SDimitry Andric std::vector<EncodingAndInst> NumberedEncodings; 16081ad6265SDimitry Andric 16181ad6265SDimitry Andric public: 162bdd1243dSDimitry Andric DecoderEmitter(RecordKeeper &R, std::string PredicateNamespace) 163bdd1243dSDimitry Andric : RK(R), Target(R), PredicateNamespace(std::move(PredicateNamespace)) {} 16481ad6265SDimitry Andric 16581ad6265SDimitry Andric // Emit the decoder state machine table. 16681ad6265SDimitry Andric void emitTable(formatted_raw_ostream &o, DecoderTable &Table, 167*0fca6ea1SDimitry Andric unsigned Indentation, unsigned BitWidth, StringRef Namespace, 168*0fca6ea1SDimitry Andric const EncodingIDsVec &EncodingIDs) const; 16981ad6265SDimitry Andric void emitInstrLenTable(formatted_raw_ostream &OS, 17081ad6265SDimitry Andric std::vector<unsigned> &InstrLen) const; 17181ad6265SDimitry Andric void emitPredicateFunction(formatted_raw_ostream &OS, 17281ad6265SDimitry Andric PredicateSet &Predicates, 17381ad6265SDimitry Andric unsigned Indentation) const; 174*0fca6ea1SDimitry Andric void emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, 17581ad6265SDimitry Andric unsigned Indentation) const; 17681ad6265SDimitry Andric 17781ad6265SDimitry Andric // run - Output the code emitter 17881ad6265SDimitry Andric void run(raw_ostream &o); 17981ad6265SDimitry Andric 18081ad6265SDimitry Andric private: 18181ad6265SDimitry Andric CodeGenTarget Target; 18281ad6265SDimitry Andric 18381ad6265SDimitry Andric public: 18481ad6265SDimitry Andric std::string PredicateNamespace; 18581ad6265SDimitry Andric }; 18681ad6265SDimitry Andric 18781ad6265SDimitry Andric } // end anonymous namespace 18881ad6265SDimitry Andric 18981ad6265SDimitry Andric // The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system 19081ad6265SDimitry Andric // for a bit value. 19181ad6265SDimitry Andric // 19281ad6265SDimitry Andric // BIT_UNFILTERED is used as the init value for a filter position. It is used 19381ad6265SDimitry Andric // only for filter processings. 19481ad6265SDimitry Andric typedef enum { 19581ad6265SDimitry Andric BIT_TRUE, // '1' 19681ad6265SDimitry Andric BIT_FALSE, // '0' 19781ad6265SDimitry Andric BIT_UNSET, // '?' 19881ad6265SDimitry Andric BIT_UNFILTERED // unfiltered 19981ad6265SDimitry Andric } bit_value_t; 20081ad6265SDimitry Andric 20181ad6265SDimitry Andric static bool ValueSet(bit_value_t V) { 20281ad6265SDimitry Andric return (V == BIT_TRUE || V == BIT_FALSE); 20381ad6265SDimitry Andric } 20481ad6265SDimitry Andric 205*0fca6ea1SDimitry Andric static bool ValueNotSet(bit_value_t V) { return (V == BIT_UNSET); } 20681ad6265SDimitry Andric 20781ad6265SDimitry Andric static int Value(bit_value_t V) { 20881ad6265SDimitry Andric return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1); 20981ad6265SDimitry Andric } 21081ad6265SDimitry Andric 21181ad6265SDimitry Andric static bit_value_t bitFromBits(const BitsInit &bits, unsigned index) { 21281ad6265SDimitry Andric if (BitInit *bit = dyn_cast<BitInit>(bits.getBit(index))) 21381ad6265SDimitry Andric return bit->getValue() ? BIT_TRUE : BIT_FALSE; 21481ad6265SDimitry Andric 21581ad6265SDimitry Andric // The bit is uninitialized. 21681ad6265SDimitry Andric return BIT_UNSET; 21781ad6265SDimitry Andric } 21881ad6265SDimitry Andric 21981ad6265SDimitry Andric // Prints the bit value for each position. 22081ad6265SDimitry Andric static void dumpBits(raw_ostream &o, const BitsInit &bits) { 22181ad6265SDimitry Andric for (unsigned index = bits.getNumBits(); index > 0; --index) { 22281ad6265SDimitry Andric switch (bitFromBits(bits, index - 1)) { 22381ad6265SDimitry Andric case BIT_TRUE: 22481ad6265SDimitry Andric o << "1"; 22581ad6265SDimitry Andric break; 22681ad6265SDimitry Andric case BIT_FALSE: 22781ad6265SDimitry Andric o << "0"; 22881ad6265SDimitry Andric break; 22981ad6265SDimitry Andric case BIT_UNSET: 23081ad6265SDimitry Andric o << "_"; 23181ad6265SDimitry Andric break; 23281ad6265SDimitry Andric default: 23381ad6265SDimitry Andric llvm_unreachable("unexpected return value from bitFromBits"); 23481ad6265SDimitry Andric } 23581ad6265SDimitry Andric } 23681ad6265SDimitry Andric } 23781ad6265SDimitry Andric 23881ad6265SDimitry Andric static BitsInit &getBitsField(const Record &def, StringRef str) { 23981ad6265SDimitry Andric const RecordVal *RV = def.getValue(str); 24081ad6265SDimitry Andric if (BitsInit *Bits = dyn_cast<BitsInit>(RV->getValue())) 24181ad6265SDimitry Andric return *Bits; 24281ad6265SDimitry Andric 24381ad6265SDimitry Andric // variable length instruction 24481ad6265SDimitry Andric VarLenInst VLI = VarLenInst(cast<DagInit>(RV->getValue()), RV); 24581ad6265SDimitry Andric SmallVector<Init *, 16> Bits; 24681ad6265SDimitry Andric 247*0fca6ea1SDimitry Andric for (const auto &SI : VLI) { 24881ad6265SDimitry Andric if (const BitsInit *BI = dyn_cast<BitsInit>(SI.Value)) { 24981ad6265SDimitry Andric for (unsigned Idx = 0U; Idx < BI->getNumBits(); ++Idx) { 25081ad6265SDimitry Andric Bits.push_back(BI->getBit(Idx)); 25181ad6265SDimitry Andric } 25281ad6265SDimitry Andric } else if (const BitInit *BI = dyn_cast<BitInit>(SI.Value)) { 25381ad6265SDimitry Andric Bits.push_back(const_cast<BitInit *>(BI)); 25481ad6265SDimitry Andric } else { 25581ad6265SDimitry Andric for (unsigned Idx = 0U; Idx < SI.BitWidth; ++Idx) 25681ad6265SDimitry Andric Bits.push_back(UnsetInit::get(def.getRecords())); 25781ad6265SDimitry Andric } 25881ad6265SDimitry Andric } 25981ad6265SDimitry Andric 26081ad6265SDimitry Andric return *BitsInit::get(def.getRecords(), Bits); 26181ad6265SDimitry Andric } 26281ad6265SDimitry Andric 26381ad6265SDimitry Andric // Representation of the instruction to work on. 26481ad6265SDimitry Andric typedef std::vector<bit_value_t> insn_t; 26581ad6265SDimitry Andric 26681ad6265SDimitry Andric namespace { 26781ad6265SDimitry Andric 26881ad6265SDimitry Andric static const uint64_t NO_FIXED_SEGMENTS_SENTINEL = -1ULL; 26981ad6265SDimitry Andric 27081ad6265SDimitry Andric class FilterChooser; 27181ad6265SDimitry Andric 27281ad6265SDimitry Andric /// Filter - Filter works with FilterChooser to produce the decoding tree for 27381ad6265SDimitry Andric /// the ISA. 27481ad6265SDimitry Andric /// 27581ad6265SDimitry Andric /// It is useful to think of a Filter as governing the switch stmts of the 27681ad6265SDimitry Andric /// decoding tree in a certain level. Each case stmt delegates to an inferior 27781ad6265SDimitry Andric /// FilterChooser to decide what further decoding logic to employ, or in another 27881ad6265SDimitry Andric /// words, what other remaining bits to look at. The FilterChooser eventually 27981ad6265SDimitry Andric /// chooses a best Filter to do its job. 28081ad6265SDimitry Andric /// 28181ad6265SDimitry Andric /// This recursive scheme ends when the number of Opcodes assigned to the 28281ad6265SDimitry Andric /// FilterChooser becomes 1 or if there is a conflict. A conflict happens when 28381ad6265SDimitry Andric /// the Filter/FilterChooser combo does not know how to distinguish among the 28481ad6265SDimitry Andric /// Opcodes assigned. 28581ad6265SDimitry Andric /// 28681ad6265SDimitry Andric /// An example of a conflict is 28781ad6265SDimitry Andric /// 28881ad6265SDimitry Andric /// Conflict: 28981ad6265SDimitry Andric /// 111101000.00........00010000.... 29081ad6265SDimitry Andric /// 111101000.00........0001........ 29181ad6265SDimitry Andric /// 1111010...00........0001........ 29281ad6265SDimitry Andric /// 1111010...00.................... 29381ad6265SDimitry Andric /// 1111010......................... 29481ad6265SDimitry Andric /// 1111............................ 29581ad6265SDimitry Andric /// ................................ 29681ad6265SDimitry Andric /// VST4q8a 111101000_00________00010000____ 29781ad6265SDimitry Andric /// VST4q8b 111101000_00________00010000____ 29881ad6265SDimitry Andric /// 29981ad6265SDimitry Andric /// The Debug output shows the path that the decoding tree follows to reach the 30081ad6265SDimitry Andric /// the conclusion that there is a conflict. VST4q8a is a vst4 to double-spaced 30181ad6265SDimitry Andric /// even registers, while VST4q8b is a vst4 to double-spaced odd registers. 30281ad6265SDimitry Andric /// 30381ad6265SDimitry Andric /// The encoding info in the .td files does not specify this meta information, 30481ad6265SDimitry Andric /// which could have been used by the decoder to resolve the conflict. The 30581ad6265SDimitry Andric /// decoder could try to decode the even/odd register numbering and assign to 30681ad6265SDimitry Andric /// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a" 30781ad6265SDimitry Andric /// version and return the Opcode since the two have the same Asm format string. 30881ad6265SDimitry Andric class Filter { 30981ad6265SDimitry Andric protected: 310*0fca6ea1SDimitry Andric const FilterChooser 311*0fca6ea1SDimitry Andric *Owner; // points to the FilterChooser who owns this filter 31281ad6265SDimitry Andric unsigned StartBit; // the starting bit position 31381ad6265SDimitry Andric unsigned NumBits; // number of bits to filter 31481ad6265SDimitry Andric bool Mixed; // a mixed region contains both set and unset bits 31581ad6265SDimitry Andric 31681ad6265SDimitry Andric // Map of well-known segment value to the set of uid's with that value. 317*0fca6ea1SDimitry Andric std::map<uint64_t, std::vector<EncodingIDAndOpcode>> FilteredInstructions; 31881ad6265SDimitry Andric 31981ad6265SDimitry Andric // Set of uid's with non-constant segment values. 32081ad6265SDimitry Andric std::vector<EncodingIDAndOpcode> VariableInstructions; 32181ad6265SDimitry Andric 32281ad6265SDimitry Andric // Map of well-known segment value to its delegate. 32381ad6265SDimitry Andric std::map<uint64_t, std::unique_ptr<const FilterChooser>> FilterChooserMap; 32481ad6265SDimitry Andric 32581ad6265SDimitry Andric // Number of instructions which fall under FilteredInstructions category. 32681ad6265SDimitry Andric unsigned NumFiltered; 32781ad6265SDimitry Andric 32881ad6265SDimitry Andric // Keeps track of the last opcode in the filtered bucket. 32981ad6265SDimitry Andric EncodingIDAndOpcode LastOpcFiltered; 33081ad6265SDimitry Andric 33181ad6265SDimitry Andric public: 33281ad6265SDimitry Andric Filter(Filter &&f); 33381ad6265SDimitry Andric Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed); 33481ad6265SDimitry Andric 33581ad6265SDimitry Andric ~Filter() = default; 33681ad6265SDimitry Andric 33781ad6265SDimitry Andric unsigned getNumFiltered() const { return NumFiltered; } 33881ad6265SDimitry Andric 33981ad6265SDimitry Andric EncodingIDAndOpcode getSingletonOpc() const { 34081ad6265SDimitry Andric assert(NumFiltered == 1); 34181ad6265SDimitry Andric return LastOpcFiltered; 34281ad6265SDimitry Andric } 34381ad6265SDimitry Andric 34481ad6265SDimitry Andric // Return the filter chooser for the group of instructions without constant 34581ad6265SDimitry Andric // segment values. 34681ad6265SDimitry Andric const FilterChooser &getVariableFC() const { 34781ad6265SDimitry Andric assert(NumFiltered == 1); 34881ad6265SDimitry Andric assert(FilterChooserMap.size() == 1); 34981ad6265SDimitry Andric return *(FilterChooserMap.find(NO_FIXED_SEGMENTS_SENTINEL)->second); 35081ad6265SDimitry Andric } 35181ad6265SDimitry Andric 35281ad6265SDimitry Andric // Divides the decoding task into sub tasks and delegates them to the 35381ad6265SDimitry Andric // inferior FilterChooser's. 35481ad6265SDimitry Andric // 35581ad6265SDimitry Andric // A special case arises when there's only one entry in the filtered 35681ad6265SDimitry Andric // instructions. In order to unambiguously decode the singleton, we need to 35781ad6265SDimitry Andric // match the remaining undecoded encoding bits against the singleton. 35881ad6265SDimitry Andric void recurse(); 35981ad6265SDimitry Andric 36081ad6265SDimitry Andric // Emit table entries to decode instructions given a segment or segments of 36181ad6265SDimitry Andric // bits. 36281ad6265SDimitry Andric void emitTableEntry(DecoderTableInfo &TableInfo) const; 36381ad6265SDimitry Andric 36481ad6265SDimitry Andric // Returns the number of fanout produced by the filter. More fanout implies 36581ad6265SDimitry Andric // the filter distinguishes more categories of instructions. 36681ad6265SDimitry Andric unsigned usefulness() const; 36781ad6265SDimitry Andric }; // end class Filter 36881ad6265SDimitry Andric 36981ad6265SDimitry Andric } // end anonymous namespace 37081ad6265SDimitry Andric 37181ad6265SDimitry Andric // These are states of our finite state machines used in FilterChooser's 37281ad6265SDimitry Andric // filterProcessor() which produces the filter candidates to use. 37381ad6265SDimitry Andric typedef enum { 37481ad6265SDimitry Andric ATTR_NONE, 37581ad6265SDimitry Andric ATTR_FILTERED, 37681ad6265SDimitry Andric ATTR_ALL_SET, 37781ad6265SDimitry Andric ATTR_ALL_UNSET, 37881ad6265SDimitry Andric ATTR_MIXED 37981ad6265SDimitry Andric } bitAttr_t; 38081ad6265SDimitry Andric 38181ad6265SDimitry Andric /// FilterChooser - FilterChooser chooses the best filter among a set of Filters 38281ad6265SDimitry Andric /// in order to perform the decoding of instructions at the current level. 38381ad6265SDimitry Andric /// 38481ad6265SDimitry Andric /// Decoding proceeds from the top down. Based on the well-known encoding bits 38581ad6265SDimitry Andric /// of instructions available, FilterChooser builds up the possible Filters that 38681ad6265SDimitry Andric /// can further the task of decoding by distinguishing among the remaining 38781ad6265SDimitry Andric /// candidate instructions. 38881ad6265SDimitry Andric /// 38981ad6265SDimitry Andric /// Once a filter has been chosen, it is called upon to divide the decoding task 39081ad6265SDimitry Andric /// into sub-tasks and delegates them to its inferior FilterChoosers for further 39181ad6265SDimitry Andric /// processings. 39281ad6265SDimitry Andric /// 39381ad6265SDimitry Andric /// It is useful to think of a Filter as governing the switch stmts of the 39481ad6265SDimitry Andric /// decoding tree. And each case is delegated to an inferior FilterChooser to 39581ad6265SDimitry Andric /// decide what further remaining bits to look at. 39681ad6265SDimitry Andric namespace { 39781ad6265SDimitry Andric 39881ad6265SDimitry Andric class FilterChooser { 39981ad6265SDimitry Andric protected: 40081ad6265SDimitry Andric friend class Filter; 40181ad6265SDimitry Andric 40281ad6265SDimitry Andric // Vector of codegen instructions to choose our filter. 40381ad6265SDimitry Andric ArrayRef<EncodingAndInst> AllInstructions; 40481ad6265SDimitry Andric 40581ad6265SDimitry Andric // Vector of uid's for this filter chooser to work on. 40681ad6265SDimitry Andric // The first member of the pair is the opcode id being decoded, the second is 40781ad6265SDimitry Andric // the opcode id that should be emitted. 40881ad6265SDimitry Andric const std::vector<EncodingIDAndOpcode> &Opcodes; 40981ad6265SDimitry Andric 41081ad6265SDimitry Andric // Lookup table for the operand decoding of instructions. 41181ad6265SDimitry Andric const std::map<unsigned, std::vector<OperandInfo>> &Operands; 41281ad6265SDimitry Andric 41381ad6265SDimitry Andric // Vector of candidate filters. 41481ad6265SDimitry Andric std::vector<Filter> Filters; 41581ad6265SDimitry Andric 41681ad6265SDimitry Andric // Array of bit values passed down from our parent. 41781ad6265SDimitry Andric // Set to all BIT_UNFILTERED's for Parent == NULL. 41881ad6265SDimitry Andric std::vector<bit_value_t> FilterBitValues; 41981ad6265SDimitry Andric 42081ad6265SDimitry Andric // Links to the FilterChooser above us in the decoding tree. 42181ad6265SDimitry Andric const FilterChooser *Parent; 42281ad6265SDimitry Andric 42381ad6265SDimitry Andric // Index of the best filter from Filters. 42481ad6265SDimitry Andric int BestIndex; 42581ad6265SDimitry Andric 42681ad6265SDimitry Andric // Width of instructions 42781ad6265SDimitry Andric unsigned BitWidth; 42881ad6265SDimitry Andric 42981ad6265SDimitry Andric // Parent emitter 43081ad6265SDimitry Andric const DecoderEmitter *Emitter; 43181ad6265SDimitry Andric 43281ad6265SDimitry Andric public: 43381ad6265SDimitry Andric FilterChooser(ArrayRef<EncodingAndInst> Insts, 43481ad6265SDimitry Andric const std::vector<EncodingIDAndOpcode> &IDs, 43581ad6265SDimitry Andric const std::map<unsigned, std::vector<OperandInfo>> &Ops, 43681ad6265SDimitry Andric unsigned BW, const DecoderEmitter *E) 43781ad6265SDimitry Andric : AllInstructions(Insts), Opcodes(IDs), Operands(Ops), 43881ad6265SDimitry Andric FilterBitValues(BW, BIT_UNFILTERED), Parent(nullptr), BestIndex(-1), 43981ad6265SDimitry Andric BitWidth(BW), Emitter(E) { 44081ad6265SDimitry Andric doFilter(); 44181ad6265SDimitry Andric } 44281ad6265SDimitry Andric 44381ad6265SDimitry Andric FilterChooser(ArrayRef<EncodingAndInst> Insts, 44481ad6265SDimitry Andric const std::vector<EncodingIDAndOpcode> &IDs, 44581ad6265SDimitry Andric const std::map<unsigned, std::vector<OperandInfo>> &Ops, 44681ad6265SDimitry Andric const std::vector<bit_value_t> &ParentFilterBitValues, 44781ad6265SDimitry Andric const FilterChooser &parent) 44881ad6265SDimitry Andric : AllInstructions(Insts), Opcodes(IDs), Operands(Ops), 44981ad6265SDimitry Andric FilterBitValues(ParentFilterBitValues), Parent(&parent), BestIndex(-1), 45081ad6265SDimitry Andric BitWidth(parent.BitWidth), Emitter(parent.Emitter) { 45181ad6265SDimitry Andric doFilter(); 45281ad6265SDimitry Andric } 45381ad6265SDimitry Andric 45481ad6265SDimitry Andric FilterChooser(const FilterChooser &) = delete; 45581ad6265SDimitry Andric void operator=(const FilterChooser &) = delete; 45681ad6265SDimitry Andric 45781ad6265SDimitry Andric unsigned getBitWidth() const { return BitWidth; } 45881ad6265SDimitry Andric 45981ad6265SDimitry Andric protected: 46081ad6265SDimitry Andric // Populates the insn given the uid. 46181ad6265SDimitry Andric void insnWithID(insn_t &Insn, unsigned Opcode) const { 462*0fca6ea1SDimitry Andric const Record *EncodingDef = AllInstructions[Opcode].EncodingDef; 463*0fca6ea1SDimitry Andric BitsInit &Bits = getBitsField(*EncodingDef, "Inst"); 464*0fca6ea1SDimitry Andric Insn.resize(std::max(BitWidth, Bits.getNumBits()), BIT_UNSET); 46581ad6265SDimitry Andric // We may have a SoftFail bitmask, which specifies a mask where an encoding 46681ad6265SDimitry Andric // may differ from the value in "Inst" and yet still be valid, but the 46781ad6265SDimitry Andric // disassembler should return SoftFail instead of Success. 46881ad6265SDimitry Andric // 46981ad6265SDimitry Andric // This is used for marking UNPREDICTABLE instructions in the ARM world. 470*0fca6ea1SDimitry Andric const RecordVal *RV = EncodingDef->getValue("SoftFail"); 47181ad6265SDimitry Andric const BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr; 47281ad6265SDimitry Andric for (unsigned i = 0; i < Bits.getNumBits(); ++i) { 47381ad6265SDimitry Andric if (SFBits && bitFromBits(*SFBits, i) == BIT_TRUE) 47481ad6265SDimitry Andric Insn[i] = BIT_UNSET; 47581ad6265SDimitry Andric else 47681ad6265SDimitry Andric Insn[i] = bitFromBits(Bits, i); 47781ad6265SDimitry Andric } 47881ad6265SDimitry Andric } 47981ad6265SDimitry Andric 48081ad6265SDimitry Andric // Emit the name of the encoding/instruction pair. 48181ad6265SDimitry Andric void emitNameWithID(raw_ostream &OS, unsigned Opcode) const { 48281ad6265SDimitry Andric const Record *EncodingDef = AllInstructions[Opcode].EncodingDef; 48381ad6265SDimitry Andric const Record *InstDef = AllInstructions[Opcode].Inst->TheDef; 48481ad6265SDimitry Andric if (EncodingDef != InstDef) 48581ad6265SDimitry Andric OS << EncodingDef->getName() << ":"; 48681ad6265SDimitry Andric OS << InstDef->getName(); 48781ad6265SDimitry Andric } 48881ad6265SDimitry Andric 48981ad6265SDimitry Andric // Populates the field of the insn given the start position and the number of 49081ad6265SDimitry Andric // consecutive bits to scan for. 49181ad6265SDimitry Andric // 492*0fca6ea1SDimitry Andric // Returns a pair of values (indicator, field), where the indicator is false 493*0fca6ea1SDimitry Andric // if there exists any uninitialized bit value in the range and true if all 494*0fca6ea1SDimitry Andric // bits are well-known. The second value is the potentially populated field. 495*0fca6ea1SDimitry Andric std::pair<bool, uint64_t> fieldFromInsn(const insn_t &Insn, unsigned StartBit, 49681ad6265SDimitry Andric unsigned NumBits) const; 49781ad6265SDimitry Andric 49881ad6265SDimitry Andric /// dumpFilterArray - dumpFilterArray prints out debugging info for the given 49981ad6265SDimitry Andric /// filter array as a series of chars. 50081ad6265SDimitry Andric void dumpFilterArray(raw_ostream &o, 50181ad6265SDimitry Andric const std::vector<bit_value_t> &filter) const; 50281ad6265SDimitry Andric 50381ad6265SDimitry Andric /// dumpStack - dumpStack traverses the filter chooser chain and calls 50481ad6265SDimitry Andric /// dumpFilterArray on each filter chooser up to the top level one. 50581ad6265SDimitry Andric void dumpStack(raw_ostream &o, const char *prefix) const; 50681ad6265SDimitry Andric 50781ad6265SDimitry Andric Filter &bestFilter() { 50881ad6265SDimitry Andric assert(BestIndex != -1 && "BestIndex not set"); 50981ad6265SDimitry Andric return Filters[BestIndex]; 51081ad6265SDimitry Andric } 51181ad6265SDimitry Andric 51281ad6265SDimitry Andric bool PositionFiltered(unsigned i) const { 51381ad6265SDimitry Andric return ValueSet(FilterBitValues[i]); 51481ad6265SDimitry Andric } 51581ad6265SDimitry Andric 51681ad6265SDimitry Andric // Calculates the island(s) needed to decode the instruction. 51781ad6265SDimitry Andric // This returns a lit of undecoded bits of an instructions, for example, 51881ad6265SDimitry Andric // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be 51981ad6265SDimitry Andric // decoded bits in order to verify that the instruction matches the Opcode. 52081ad6265SDimitry Andric unsigned getIslands(std::vector<unsigned> &StartBits, 52181ad6265SDimitry Andric std::vector<unsigned> &EndBits, 52281ad6265SDimitry Andric std::vector<uint64_t> &FieldVals, 52381ad6265SDimitry Andric const insn_t &Insn) const; 52481ad6265SDimitry Andric 52581ad6265SDimitry Andric // Emits code to check the Predicates member of an instruction are true. 52681ad6265SDimitry Andric // Returns true if predicate matches were emitted, false otherwise. 52781ad6265SDimitry Andric bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation, 52881ad6265SDimitry Andric unsigned Opc) const; 52981ad6265SDimitry Andric bool emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp, 53081ad6265SDimitry Andric raw_ostream &OS) const; 53181ad6265SDimitry Andric 53281ad6265SDimitry Andric bool doesOpcodeNeedPredicate(unsigned Opc) const; 53381ad6265SDimitry Andric unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const; 534*0fca6ea1SDimitry Andric void emitPredicateTableEntry(DecoderTableInfo &TableInfo, unsigned Opc) const; 53581ad6265SDimitry Andric 536*0fca6ea1SDimitry Andric void emitSoftFailTableEntry(DecoderTableInfo &TableInfo, unsigned Opc) const; 53781ad6265SDimitry Andric 53881ad6265SDimitry Andric // Emits table entries to decode the singleton. 53981ad6265SDimitry Andric void emitSingletonTableEntry(DecoderTableInfo &TableInfo, 54081ad6265SDimitry Andric EncodingIDAndOpcode Opc) const; 54181ad6265SDimitry Andric 54281ad6265SDimitry Andric // Emits code to decode the singleton, and then to decode the rest. 54381ad6265SDimitry Andric void emitSingletonTableEntry(DecoderTableInfo &TableInfo, 54481ad6265SDimitry Andric const Filter &Best) const; 54581ad6265SDimitry Andric 54681ad6265SDimitry Andric void emitBinaryParser(raw_ostream &o, unsigned &Indentation, 54781ad6265SDimitry Andric const OperandInfo &OpInfo, 54881ad6265SDimitry Andric bool &OpHasCompleteDecoder) const; 54981ad6265SDimitry Andric 55081ad6265SDimitry Andric void emitDecoder(raw_ostream &OS, unsigned Indentation, unsigned Opc, 55181ad6265SDimitry Andric bool &HasCompleteDecoder) const; 55281ad6265SDimitry Andric unsigned getDecoderIndex(DecoderSet &Decoders, unsigned Opc, 55381ad6265SDimitry Andric bool &HasCompleteDecoder) const; 55481ad6265SDimitry Andric 55581ad6265SDimitry Andric // Assign a single filter and run with it. 55681ad6265SDimitry Andric void runSingleFilter(unsigned startBit, unsigned numBit, bool mixed); 55781ad6265SDimitry Andric 55881ad6265SDimitry Andric // reportRegion is a helper function for filterProcessor to mark a region as 55981ad6265SDimitry Andric // eligible for use as a filter region. 56081ad6265SDimitry Andric void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex, 56181ad6265SDimitry Andric bool AllowMixed); 56281ad6265SDimitry Andric 56381ad6265SDimitry Andric // FilterProcessor scans the well-known encoding bits of the instructions and 56481ad6265SDimitry Andric // builds up a list of candidate filters. It chooses the best filter and 56581ad6265SDimitry Andric // recursively descends down the decoding tree. 56681ad6265SDimitry Andric bool filterProcessor(bool AllowMixed, bool Greedy = true); 56781ad6265SDimitry Andric 56881ad6265SDimitry Andric // Decides on the best configuration of filter(s) to use in order to decode 56981ad6265SDimitry Andric // the instructions. A conflict of instructions may occur, in which case we 57081ad6265SDimitry Andric // dump the conflict set to the standard error. 57181ad6265SDimitry Andric void doFilter(); 57281ad6265SDimitry Andric 57381ad6265SDimitry Andric public: 57481ad6265SDimitry Andric // emitTableEntries - Emit state machine entries to decode our share of 57581ad6265SDimitry Andric // instructions. 57681ad6265SDimitry Andric void emitTableEntries(DecoderTableInfo &TableInfo) const; 57781ad6265SDimitry Andric }; 57881ad6265SDimitry Andric 57981ad6265SDimitry Andric } // end anonymous namespace 58081ad6265SDimitry Andric 58181ad6265SDimitry Andric /////////////////////////// 58281ad6265SDimitry Andric // // 58381ad6265SDimitry Andric // Filter Implementation // 58481ad6265SDimitry Andric // // 58581ad6265SDimitry Andric /////////////////////////// 58681ad6265SDimitry Andric 58781ad6265SDimitry Andric Filter::Filter(Filter &&f) 58881ad6265SDimitry Andric : Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed), 58981ad6265SDimitry Andric FilteredInstructions(std::move(f.FilteredInstructions)), 59081ad6265SDimitry Andric VariableInstructions(std::move(f.VariableInstructions)), 591*0fca6ea1SDimitry Andric FilterChooserMap(std::move(f.FilterChooserMap)), 592*0fca6ea1SDimitry Andric NumFiltered(f.NumFiltered), LastOpcFiltered(f.LastOpcFiltered) {} 59381ad6265SDimitry Andric 59481ad6265SDimitry Andric Filter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, 59581ad6265SDimitry Andric bool mixed) 59681ad6265SDimitry Andric : Owner(&owner), StartBit(startBit), NumBits(numBits), Mixed(mixed) { 59781ad6265SDimitry Andric assert(StartBit + NumBits - 1 < Owner->BitWidth); 59881ad6265SDimitry Andric 59981ad6265SDimitry Andric NumFiltered = 0; 60081ad6265SDimitry Andric LastOpcFiltered = {0, 0}; 60181ad6265SDimitry Andric 602*0fca6ea1SDimitry Andric for (const auto &OpcPair : Owner->Opcodes) { 60381ad6265SDimitry Andric insn_t Insn; 60481ad6265SDimitry Andric 60581ad6265SDimitry Andric // Populates the insn given the uid. 606*0fca6ea1SDimitry Andric Owner->insnWithID(Insn, OpcPair.EncodingID); 60781ad6265SDimitry Andric 60881ad6265SDimitry Andric // Scans the segment for possibly well-specified encoding bits. 609*0fca6ea1SDimitry Andric auto [Ok, Field] = Owner->fieldFromInsn(Insn, StartBit, NumBits); 61081ad6265SDimitry Andric 611*0fca6ea1SDimitry Andric if (Ok) { 61281ad6265SDimitry Andric // The encoding bits are well-known. Lets add the uid of the 61381ad6265SDimitry Andric // instruction into the bucket keyed off the constant field value. 614*0fca6ea1SDimitry Andric LastOpcFiltered = OpcPair; 61581ad6265SDimitry Andric FilteredInstructions[Field].push_back(LastOpcFiltered); 61681ad6265SDimitry Andric ++NumFiltered; 61781ad6265SDimitry Andric } else { 61881ad6265SDimitry Andric // Some of the encoding bit(s) are unspecified. This contributes to 61981ad6265SDimitry Andric // one additional member of "Variable" instructions. 620*0fca6ea1SDimitry Andric VariableInstructions.push_back(OpcPair); 62181ad6265SDimitry Andric } 62281ad6265SDimitry Andric } 62381ad6265SDimitry Andric 624*0fca6ea1SDimitry Andric assert((FilteredInstructions.size() + VariableInstructions.size() > 0) && 625*0fca6ea1SDimitry Andric "Filter returns no instruction categories"); 62681ad6265SDimitry Andric } 62781ad6265SDimitry Andric 62881ad6265SDimitry Andric // Divides the decoding task into sub tasks and delegates them to the 62981ad6265SDimitry Andric // inferior FilterChooser's. 63081ad6265SDimitry Andric // 63181ad6265SDimitry Andric // A special case arises when there's only one entry in the filtered 63281ad6265SDimitry Andric // instructions. In order to unambiguously decode the singleton, we need to 63381ad6265SDimitry Andric // match the remaining undecoded encoding bits against the singleton. 63481ad6265SDimitry Andric void Filter::recurse() { 63581ad6265SDimitry Andric // Starts by inheriting our parent filter chooser's filter bit values. 63681ad6265SDimitry Andric std::vector<bit_value_t> BitValueArray(Owner->FilterBitValues); 63781ad6265SDimitry Andric 63881ad6265SDimitry Andric if (!VariableInstructions.empty()) { 63981ad6265SDimitry Andric // Conservatively marks each segment position as BIT_UNSET. 64081ad6265SDimitry Andric for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) 64181ad6265SDimitry Andric BitValueArray[StartBit + bitIndex] = BIT_UNSET; 64281ad6265SDimitry Andric 64381ad6265SDimitry Andric // Delegates to an inferior filter chooser for further processing on this 64481ad6265SDimitry Andric // group of instructions whose segment values are variable. 645*0fca6ea1SDimitry Andric FilterChooserMap.insert(std::pair( 646*0fca6ea1SDimitry Andric NO_FIXED_SEGMENTS_SENTINEL, 64781ad6265SDimitry Andric std::make_unique<FilterChooser>(Owner->AllInstructions, 648*0fca6ea1SDimitry Andric VariableInstructions, Owner->Operands, 649*0fca6ea1SDimitry Andric BitValueArray, *Owner))); 65081ad6265SDimitry Andric } 65181ad6265SDimitry Andric 65281ad6265SDimitry Andric // No need to recurse for a singleton filtered instruction. 65381ad6265SDimitry Andric // See also Filter::emit*(). 65481ad6265SDimitry Andric if (getNumFiltered() == 1) { 65581ad6265SDimitry Andric assert(FilterChooserMap.size() == 1); 65681ad6265SDimitry Andric return; 65781ad6265SDimitry Andric } 65881ad6265SDimitry Andric 65981ad6265SDimitry Andric // Otherwise, create sub choosers. 66081ad6265SDimitry Andric for (const auto &Inst : FilteredInstructions) { 66181ad6265SDimitry Andric 66281ad6265SDimitry Andric // Marks all the segment positions with either BIT_TRUE or BIT_FALSE. 66381ad6265SDimitry Andric for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) { 66481ad6265SDimitry Andric if (Inst.first & (1ULL << bitIndex)) 66581ad6265SDimitry Andric BitValueArray[StartBit + bitIndex] = BIT_TRUE; 66681ad6265SDimitry Andric else 66781ad6265SDimitry Andric BitValueArray[StartBit + bitIndex] = BIT_FALSE; 66881ad6265SDimitry Andric } 66981ad6265SDimitry Andric 67081ad6265SDimitry Andric // Delegates to an inferior filter chooser for further processing on this 67181ad6265SDimitry Andric // category of instructions. 672*0fca6ea1SDimitry Andric FilterChooserMap.insert( 673*0fca6ea1SDimitry Andric std::pair(Inst.first, std::make_unique<FilterChooser>( 67481ad6265SDimitry Andric Owner->AllInstructions, Inst.second, 67581ad6265SDimitry Andric Owner->Operands, BitValueArray, *Owner))); 67681ad6265SDimitry Andric } 67781ad6265SDimitry Andric } 67881ad6265SDimitry Andric 67981ad6265SDimitry Andric static void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups, 68081ad6265SDimitry Andric uint32_t DestIdx) { 68181ad6265SDimitry Andric // Any NumToSkip fixups in the current scope can resolve to the 68281ad6265SDimitry Andric // current location. 683*0fca6ea1SDimitry Andric for (FixupList::const_reverse_iterator I = Fixups.rbegin(), E = Fixups.rend(); 68481ad6265SDimitry Andric I != E; ++I) { 68581ad6265SDimitry Andric // Calculate the distance from the byte following the fixup entry byte 68681ad6265SDimitry Andric // to the destination. The Target is calculated from after the 16-bit 68781ad6265SDimitry Andric // NumToSkip entry itself, so subtract two from the displacement here 68881ad6265SDimitry Andric // to account for that. 68981ad6265SDimitry Andric uint32_t FixupIdx = *I; 69081ad6265SDimitry Andric uint32_t Delta = DestIdx - FixupIdx - 3; 69181ad6265SDimitry Andric // Our NumToSkip entries are 24-bits. Make sure our table isn't too 69281ad6265SDimitry Andric // big. 69381ad6265SDimitry Andric assert(Delta < (1u << 24)); 69481ad6265SDimitry Andric Table[FixupIdx] = (uint8_t)Delta; 69581ad6265SDimitry Andric Table[FixupIdx + 1] = (uint8_t)(Delta >> 8); 69681ad6265SDimitry Andric Table[FixupIdx + 2] = (uint8_t)(Delta >> 16); 69781ad6265SDimitry Andric } 69881ad6265SDimitry Andric } 69981ad6265SDimitry Andric 70081ad6265SDimitry Andric // Emit table entries to decode instructions given a segment or segments 70181ad6265SDimitry Andric // of bits. 70281ad6265SDimitry Andric void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const { 703*0fca6ea1SDimitry Andric assert((NumBits < (1u << 8)) && "NumBits overflowed uint8 table entry!"); 70481ad6265SDimitry Andric TableInfo.Table.push_back(MCD::OPC_ExtractField); 705*0fca6ea1SDimitry Andric 706*0fca6ea1SDimitry Andric SmallString<16> SBytes; 707*0fca6ea1SDimitry Andric raw_svector_ostream S(SBytes); 708*0fca6ea1SDimitry Andric encodeULEB128(StartBit, S); 709*0fca6ea1SDimitry Andric TableInfo.Table.insert(TableInfo.Table.end(), SBytes.begin(), SBytes.end()); 71081ad6265SDimitry Andric TableInfo.Table.push_back(NumBits); 71181ad6265SDimitry Andric 71281ad6265SDimitry Andric // A new filter entry begins a new scope for fixup resolution. 71381ad6265SDimitry Andric TableInfo.FixupStack.emplace_back(); 71481ad6265SDimitry Andric 71581ad6265SDimitry Andric DecoderTable &Table = TableInfo.Table; 71681ad6265SDimitry Andric 71781ad6265SDimitry Andric size_t PrevFilter = 0; 71881ad6265SDimitry Andric bool HasFallthrough = false; 719*0fca6ea1SDimitry Andric for (const auto &Filter : FilterChooserMap) { 72081ad6265SDimitry Andric // Field value -1 implies a non-empty set of variable instructions. 72181ad6265SDimitry Andric // See also recurse(). 72281ad6265SDimitry Andric if (Filter.first == NO_FIXED_SEGMENTS_SENTINEL) { 72381ad6265SDimitry Andric HasFallthrough = true; 72481ad6265SDimitry Andric 72581ad6265SDimitry Andric // Each scope should always have at least one filter value to check 72681ad6265SDimitry Andric // for. 72781ad6265SDimitry Andric assert(PrevFilter != 0 && "empty filter set!"); 72881ad6265SDimitry Andric FixupList &CurScope = TableInfo.FixupStack.back(); 72981ad6265SDimitry Andric // Resolve any NumToSkip fixups in the current scope. 73081ad6265SDimitry Andric resolveTableFixups(Table, CurScope, Table.size()); 73181ad6265SDimitry Andric CurScope.clear(); 73281ad6265SDimitry Andric PrevFilter = 0; // Don't re-process the filter's fallthrough. 73381ad6265SDimitry Andric } else { 73481ad6265SDimitry Andric Table.push_back(MCD::OPC_FilterValue); 73581ad6265SDimitry Andric // Encode and emit the value to filter against. 73681ad6265SDimitry Andric uint8_t Buffer[16]; 73781ad6265SDimitry Andric unsigned Len = encodeULEB128(Filter.first, Buffer); 73881ad6265SDimitry Andric Table.insert(Table.end(), Buffer, Buffer + Len); 73981ad6265SDimitry Andric // Reserve space for the NumToSkip entry. We'll backpatch the value 74081ad6265SDimitry Andric // later. 74181ad6265SDimitry Andric PrevFilter = Table.size(); 74281ad6265SDimitry Andric Table.push_back(0); 74381ad6265SDimitry Andric Table.push_back(0); 74481ad6265SDimitry Andric Table.push_back(0); 74581ad6265SDimitry Andric } 74681ad6265SDimitry Andric 74781ad6265SDimitry Andric // We arrive at a category of instructions with the same segment value. 74881ad6265SDimitry Andric // Now delegate to the sub filter chooser for further decodings. 74981ad6265SDimitry Andric // The case may fallthrough, which happens if the remaining well-known 75081ad6265SDimitry Andric // encoding bits do not match exactly. 75181ad6265SDimitry Andric Filter.second->emitTableEntries(TableInfo); 75281ad6265SDimitry Andric 75381ad6265SDimitry Andric // Now that we've emitted the body of the handler, update the NumToSkip 75481ad6265SDimitry Andric // of the filter itself to be able to skip forward when false. Subtract 75581ad6265SDimitry Andric // two as to account for the width of the NumToSkip field itself. 75681ad6265SDimitry Andric if (PrevFilter) { 75781ad6265SDimitry Andric uint32_t NumToSkip = Table.size() - PrevFilter - 3; 758*0fca6ea1SDimitry Andric assert(NumToSkip < (1u << 24) && 759*0fca6ea1SDimitry Andric "disassembler decoding table too large!"); 76081ad6265SDimitry Andric Table[PrevFilter] = (uint8_t)NumToSkip; 76181ad6265SDimitry Andric Table[PrevFilter + 1] = (uint8_t)(NumToSkip >> 8); 76281ad6265SDimitry Andric Table[PrevFilter + 2] = (uint8_t)(NumToSkip >> 16); 76381ad6265SDimitry Andric } 76481ad6265SDimitry Andric } 76581ad6265SDimitry Andric 76681ad6265SDimitry Andric // Any remaining unresolved fixups bubble up to the parent fixup scope. 76781ad6265SDimitry Andric assert(TableInfo.FixupStack.size() > 1 && "fixup stack underflow!"); 76881ad6265SDimitry Andric FixupScopeList::iterator Source = TableInfo.FixupStack.end() - 1; 76981ad6265SDimitry Andric FixupScopeList::iterator Dest = Source - 1; 77081ad6265SDimitry Andric llvm::append_range(*Dest, *Source); 77181ad6265SDimitry Andric TableInfo.FixupStack.pop_back(); 77281ad6265SDimitry Andric 77381ad6265SDimitry Andric // If there is no fallthrough, then the final filter should get fixed 77481ad6265SDimitry Andric // up according to the enclosing scope rather than the current position. 77581ad6265SDimitry Andric if (!HasFallthrough) 77681ad6265SDimitry Andric TableInfo.FixupStack.back().push_back(PrevFilter); 77781ad6265SDimitry Andric } 77881ad6265SDimitry Andric 77981ad6265SDimitry Andric // Returns the number of fanout produced by the filter. More fanout implies 78081ad6265SDimitry Andric // the filter distinguishes more categories of instructions. 78181ad6265SDimitry Andric unsigned Filter::usefulness() const { 78281ad6265SDimitry Andric if (!VariableInstructions.empty()) 78381ad6265SDimitry Andric return FilteredInstructions.size(); 78481ad6265SDimitry Andric else 78581ad6265SDimitry Andric return FilteredInstructions.size() + 1; 78681ad6265SDimitry Andric } 78781ad6265SDimitry Andric 78881ad6265SDimitry Andric ////////////////////////////////// 78981ad6265SDimitry Andric // // 79081ad6265SDimitry Andric // Filterchooser Implementation // 79181ad6265SDimitry Andric // // 79281ad6265SDimitry Andric ////////////////////////////////// 79381ad6265SDimitry Andric 79481ad6265SDimitry Andric // Emit the decoder state machine table. 79581ad6265SDimitry Andric void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table, 79681ad6265SDimitry Andric unsigned Indentation, unsigned BitWidth, 797*0fca6ea1SDimitry Andric StringRef Namespace, 798*0fca6ea1SDimitry Andric const EncodingIDsVec &EncodingIDs) const { 799*0fca6ea1SDimitry Andric // We'll need to be able to map from a decoded opcode into the corresponding 800*0fca6ea1SDimitry Andric // EncodingID for this specific combination of BitWidth and Namespace. This 801*0fca6ea1SDimitry Andric // is used below to index into NumberedEncodings. 802*0fca6ea1SDimitry Andric DenseMap<unsigned, unsigned> OpcodeToEncodingID; 803*0fca6ea1SDimitry Andric OpcodeToEncodingID.reserve(EncodingIDs.size()); 804*0fca6ea1SDimitry Andric for (const auto &EI : EncodingIDs) 805*0fca6ea1SDimitry Andric OpcodeToEncodingID[EI.Opcode] = EI.EncodingID; 806*0fca6ea1SDimitry Andric 80781ad6265SDimitry Andric OS.indent(Indentation) << "static const uint8_t DecoderTable" << Namespace 80881ad6265SDimitry Andric << BitWidth << "[] = {\n"; 80981ad6265SDimitry Andric 81081ad6265SDimitry Andric Indentation += 2; 81181ad6265SDimitry Andric 812*0fca6ea1SDimitry Andric // Emit ULEB128 encoded value to OS, returning the number of bytes emitted. 813*0fca6ea1SDimitry Andric auto emitULEB128 = [](DecoderTable::const_iterator I, 814*0fca6ea1SDimitry Andric formatted_raw_ostream &OS) { 815*0fca6ea1SDimitry Andric unsigned Len = 0; 816*0fca6ea1SDimitry Andric while (*I >= 128) { 817*0fca6ea1SDimitry Andric OS << (unsigned)*I++ << ", "; 818*0fca6ea1SDimitry Andric Len++; 819*0fca6ea1SDimitry Andric } 820*0fca6ea1SDimitry Andric OS << (unsigned)*I++ << ", "; 821*0fca6ea1SDimitry Andric return Len + 1; 822*0fca6ea1SDimitry Andric }; 823*0fca6ea1SDimitry Andric 824*0fca6ea1SDimitry Andric // Emit 24-bit numtoskip value to OS, returning the NumToSkip value. 825*0fca6ea1SDimitry Andric auto emitNumToSkip = [](DecoderTable::const_iterator I, 826*0fca6ea1SDimitry Andric formatted_raw_ostream &OS) { 827*0fca6ea1SDimitry Andric uint8_t Byte = *I++; 828*0fca6ea1SDimitry Andric uint32_t NumToSkip = Byte; 829*0fca6ea1SDimitry Andric OS << (unsigned)Byte << ", "; 830*0fca6ea1SDimitry Andric Byte = *I++; 831*0fca6ea1SDimitry Andric OS << (unsigned)Byte << ", "; 832*0fca6ea1SDimitry Andric NumToSkip |= Byte << 8; 833*0fca6ea1SDimitry Andric Byte = *I++; 834*0fca6ea1SDimitry Andric OS << utostr(Byte) << ", "; 835*0fca6ea1SDimitry Andric NumToSkip |= Byte << 16; 836*0fca6ea1SDimitry Andric return NumToSkip; 837*0fca6ea1SDimitry Andric }; 838*0fca6ea1SDimitry Andric 83981ad6265SDimitry Andric // FIXME: We may be able to use the NumToSkip values to recover 84081ad6265SDimitry Andric // appropriate indentation levels. 84181ad6265SDimitry Andric DecoderTable::const_iterator I = Table.begin(); 84281ad6265SDimitry Andric DecoderTable::const_iterator E = Table.end(); 84381ad6265SDimitry Andric while (I != E) { 84481ad6265SDimitry Andric assert(I < E && "incomplete decode table entry!"); 84581ad6265SDimitry Andric 84681ad6265SDimitry Andric uint64_t Pos = I - Table.begin(); 84781ad6265SDimitry Andric OS << "/* " << Pos << " */"; 84881ad6265SDimitry Andric OS.PadToColumn(12); 84981ad6265SDimitry Andric 85081ad6265SDimitry Andric switch (*I) { 85181ad6265SDimitry Andric default: 85281ad6265SDimitry Andric PrintFatalError("invalid decode table opcode"); 85381ad6265SDimitry Andric case MCD::OPC_ExtractField: { 85481ad6265SDimitry Andric ++I; 855*0fca6ea1SDimitry Andric OS.indent(Indentation) << "MCD::OPC_ExtractField, "; 856*0fca6ea1SDimitry Andric 857*0fca6ea1SDimitry Andric // ULEB128 encoded start value. 858*0fca6ea1SDimitry Andric const char *ErrMsg = nullptr; 859*0fca6ea1SDimitry Andric unsigned Start = decodeULEB128(Table.data() + Pos + 1, nullptr, 860*0fca6ea1SDimitry Andric Table.data() + Table.size(), &ErrMsg); 861*0fca6ea1SDimitry Andric assert(ErrMsg == nullptr && "ULEB128 value too large!"); 862*0fca6ea1SDimitry Andric I += emitULEB128(I, OS); 863*0fca6ea1SDimitry Andric 86481ad6265SDimitry Andric unsigned Len = *I++; 865*0fca6ea1SDimitry Andric OS << Len << ", // Inst{"; 86681ad6265SDimitry Andric if (Len > 1) 86781ad6265SDimitry Andric OS << (Start + Len - 1) << "-"; 86881ad6265SDimitry Andric OS << Start << "} ...\n"; 86981ad6265SDimitry Andric break; 87081ad6265SDimitry Andric } 87181ad6265SDimitry Andric case MCD::OPC_FilterValue: { 87281ad6265SDimitry Andric ++I; 87381ad6265SDimitry Andric OS.indent(Indentation) << "MCD::OPC_FilterValue, "; 87481ad6265SDimitry Andric // The filter value is ULEB128 encoded. 875*0fca6ea1SDimitry Andric I += emitULEB128(I, OS); 87681ad6265SDimitry Andric 87781ad6265SDimitry Andric // 24-bit numtoskip value. 878*0fca6ea1SDimitry Andric uint32_t NumToSkip = emitNumToSkip(I, OS); 879*0fca6ea1SDimitry Andric I += 3; 88081ad6265SDimitry Andric OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n"; 88181ad6265SDimitry Andric break; 88281ad6265SDimitry Andric } 88381ad6265SDimitry Andric case MCD::OPC_CheckField: { 88481ad6265SDimitry Andric ++I; 885*0fca6ea1SDimitry Andric OS.indent(Indentation) << "MCD::OPC_CheckField, "; 886*0fca6ea1SDimitry Andric // ULEB128 encoded start value. 887*0fca6ea1SDimitry Andric I += emitULEB128(I, OS); 888*0fca6ea1SDimitry Andric // 8-bit length. 88981ad6265SDimitry Andric unsigned Len = *I++; 890*0fca6ea1SDimitry Andric OS << Len << ", "; 89181ad6265SDimitry Andric // ULEB128 encoded field value. 892*0fca6ea1SDimitry Andric I += emitULEB128(I, OS); 893*0fca6ea1SDimitry Andric 89481ad6265SDimitry Andric // 24-bit numtoskip value. 895*0fca6ea1SDimitry Andric uint32_t NumToSkip = emitNumToSkip(I, OS); 896*0fca6ea1SDimitry Andric I += 3; 89781ad6265SDimitry Andric OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n"; 89881ad6265SDimitry Andric break; 89981ad6265SDimitry Andric } 90081ad6265SDimitry Andric case MCD::OPC_CheckPredicate: { 90181ad6265SDimitry Andric ++I; 90281ad6265SDimitry Andric OS.indent(Indentation) << "MCD::OPC_CheckPredicate, "; 903*0fca6ea1SDimitry Andric I += emitULEB128(I, OS); 90481ad6265SDimitry Andric 90581ad6265SDimitry Andric // 24-bit numtoskip value. 906*0fca6ea1SDimitry Andric uint32_t NumToSkip = emitNumToSkip(I, OS); 907*0fca6ea1SDimitry Andric I += 3; 90881ad6265SDimitry Andric OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n"; 90981ad6265SDimitry Andric break; 91081ad6265SDimitry Andric } 91181ad6265SDimitry Andric case MCD::OPC_Decode: 91281ad6265SDimitry Andric case MCD::OPC_TryDecode: { 91381ad6265SDimitry Andric bool IsTry = *I == MCD::OPC_TryDecode; 91481ad6265SDimitry Andric ++I; 91581ad6265SDimitry Andric // Decode the Opcode value. 916*0fca6ea1SDimitry Andric const char *ErrMsg = nullptr; 917*0fca6ea1SDimitry Andric unsigned Opc = decodeULEB128(Table.data() + Pos + 1, nullptr, 918*0fca6ea1SDimitry Andric Table.data() + Table.size(), &ErrMsg); 919*0fca6ea1SDimitry Andric assert(ErrMsg == nullptr && "ULEB128 value too large!"); 920*0fca6ea1SDimitry Andric 921*0fca6ea1SDimitry Andric OS.indent(Indentation) 922*0fca6ea1SDimitry Andric << "MCD::OPC_" << (IsTry ? "Try" : "") << "Decode, "; 923*0fca6ea1SDimitry Andric I += emitULEB128(I, OS); 92481ad6265SDimitry Andric 92581ad6265SDimitry Andric // Decoder index. 926*0fca6ea1SDimitry Andric I += emitULEB128(I, OS); 927*0fca6ea1SDimitry Andric 928*0fca6ea1SDimitry Andric auto EncI = OpcodeToEncodingID.find(Opc); 929*0fca6ea1SDimitry Andric assert(EncI != OpcodeToEncodingID.end() && "no encoding entry"); 930*0fca6ea1SDimitry Andric auto EncodingID = EncI->second; 93181ad6265SDimitry Andric 93281ad6265SDimitry Andric if (!IsTry) { 933*0fca6ea1SDimitry Andric OS << "// Opcode: " << NumberedEncodings[EncodingID] << "\n"; 93481ad6265SDimitry Andric break; 93581ad6265SDimitry Andric } 93681ad6265SDimitry Andric 93781ad6265SDimitry Andric // Fallthrough for OPC_TryDecode. 93881ad6265SDimitry Andric 93981ad6265SDimitry Andric // 24-bit numtoskip value. 940*0fca6ea1SDimitry Andric uint32_t NumToSkip = emitNumToSkip(I, OS); 941*0fca6ea1SDimitry Andric I += 3; 94281ad6265SDimitry Andric 943*0fca6ea1SDimitry Andric OS << "// Opcode: " << NumberedEncodings[EncodingID] 94481ad6265SDimitry Andric << ", skip to: " << ((I - Table.begin()) + NumToSkip) << "\n"; 94581ad6265SDimitry Andric break; 94681ad6265SDimitry Andric } 94781ad6265SDimitry Andric case MCD::OPC_SoftFail: { 94881ad6265SDimitry Andric ++I; 94981ad6265SDimitry Andric OS.indent(Indentation) << "MCD::OPC_SoftFail"; 95081ad6265SDimitry Andric // Positive mask 95181ad6265SDimitry Andric uint64_t Value = 0; 95281ad6265SDimitry Andric unsigned Shift = 0; 95381ad6265SDimitry Andric do { 95481ad6265SDimitry Andric OS << ", " << (unsigned)*I; 955*0fca6ea1SDimitry Andric Value += ((uint64_t)(*I & 0x7f)) << Shift; 95681ad6265SDimitry Andric Shift += 7; 95781ad6265SDimitry Andric } while (*I++ >= 128); 95881ad6265SDimitry Andric if (Value > 127) { 95981ad6265SDimitry Andric OS << " /* 0x"; 96081ad6265SDimitry Andric OS.write_hex(Value); 96181ad6265SDimitry Andric OS << " */"; 96281ad6265SDimitry Andric } 96381ad6265SDimitry Andric // Negative mask 96481ad6265SDimitry Andric Value = 0; 96581ad6265SDimitry Andric Shift = 0; 96681ad6265SDimitry Andric do { 96781ad6265SDimitry Andric OS << ", " << (unsigned)*I; 968*0fca6ea1SDimitry Andric Value += ((uint64_t)(*I & 0x7f)) << Shift; 96981ad6265SDimitry Andric Shift += 7; 97081ad6265SDimitry Andric } while (*I++ >= 128); 97181ad6265SDimitry Andric if (Value > 127) { 97281ad6265SDimitry Andric OS << " /* 0x"; 97381ad6265SDimitry Andric OS.write_hex(Value); 97481ad6265SDimitry Andric OS << " */"; 97581ad6265SDimitry Andric } 97681ad6265SDimitry Andric OS << ",\n"; 97781ad6265SDimitry Andric break; 97881ad6265SDimitry Andric } 97981ad6265SDimitry Andric case MCD::OPC_Fail: { 98081ad6265SDimitry Andric ++I; 98181ad6265SDimitry Andric OS.indent(Indentation) << "MCD::OPC_Fail,\n"; 98281ad6265SDimitry Andric break; 98381ad6265SDimitry Andric } 98481ad6265SDimitry Andric } 98581ad6265SDimitry Andric } 98681ad6265SDimitry Andric OS.indent(Indentation) << "0\n"; 98781ad6265SDimitry Andric 98881ad6265SDimitry Andric Indentation -= 2; 98981ad6265SDimitry Andric 99081ad6265SDimitry Andric OS.indent(Indentation) << "};\n\n"; 99181ad6265SDimitry Andric } 99281ad6265SDimitry Andric 99381ad6265SDimitry Andric void DecoderEmitter::emitInstrLenTable(formatted_raw_ostream &OS, 99481ad6265SDimitry Andric std::vector<unsigned> &InstrLen) const { 99581ad6265SDimitry Andric OS << "static const uint8_t InstrLenTable[] = {\n"; 99681ad6265SDimitry Andric for (unsigned &Len : InstrLen) { 99781ad6265SDimitry Andric OS << Len << ",\n"; 99881ad6265SDimitry Andric } 99981ad6265SDimitry Andric OS << "};\n\n"; 100081ad6265SDimitry Andric } 100181ad6265SDimitry Andric 100281ad6265SDimitry Andric void DecoderEmitter::emitPredicateFunction(formatted_raw_ostream &OS, 100381ad6265SDimitry Andric PredicateSet &Predicates, 100481ad6265SDimitry Andric unsigned Indentation) const { 100581ad6265SDimitry Andric // The predicate function is just a big switch statement based on the 100681ad6265SDimitry Andric // input predicate index. 100781ad6265SDimitry Andric OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, " 100881ad6265SDimitry Andric << "const FeatureBitset &Bits) {\n"; 100981ad6265SDimitry Andric Indentation += 2; 101081ad6265SDimitry Andric if (!Predicates.empty()) { 101181ad6265SDimitry Andric OS.indent(Indentation) << "switch (Idx) {\n"; 1012*0fca6ea1SDimitry Andric OS.indent(Indentation) 1013*0fca6ea1SDimitry Andric << "default: llvm_unreachable(\"Invalid index!\");\n"; 101481ad6265SDimitry Andric unsigned Index = 0; 101581ad6265SDimitry Andric for (const auto &Predicate : Predicates) { 101681ad6265SDimitry Andric OS.indent(Indentation) << "case " << Index++ << ":\n"; 101781ad6265SDimitry Andric OS.indent(Indentation + 2) << "return (" << Predicate << ");\n"; 101881ad6265SDimitry Andric } 101981ad6265SDimitry Andric OS.indent(Indentation) << "}\n"; 102081ad6265SDimitry Andric } else { 102181ad6265SDimitry Andric // No case statement to emit 102281ad6265SDimitry Andric OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n"; 102381ad6265SDimitry Andric } 102481ad6265SDimitry Andric Indentation -= 2; 102581ad6265SDimitry Andric OS.indent(Indentation) << "}\n\n"; 102681ad6265SDimitry Andric } 102781ad6265SDimitry Andric 102881ad6265SDimitry Andric void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS, 102981ad6265SDimitry Andric DecoderSet &Decoders, 103081ad6265SDimitry Andric unsigned Indentation) const { 103181ad6265SDimitry Andric // The decoder function is just a big switch statement based on the 103281ad6265SDimitry Andric // input decoder index. 103381ad6265SDimitry Andric OS.indent(Indentation) << "template <typename InsnType>\n"; 103481ad6265SDimitry Andric OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S," 103581ad6265SDimitry Andric << " unsigned Idx, InsnType insn, MCInst &MI,\n"; 103681ad6265SDimitry Andric OS.indent(Indentation) 103781ad6265SDimitry Andric << " uint64_t " 103881ad6265SDimitry Andric << "Address, const MCDisassembler *Decoder, bool &DecodeComplete) {\n"; 103981ad6265SDimitry Andric Indentation += 2; 104081ad6265SDimitry Andric OS.indent(Indentation) << "DecodeComplete = true;\n"; 104181ad6265SDimitry Andric // TODO: When InsnType is large, using uint64_t limits all fields to 64 bits 104281ad6265SDimitry Andric // It would be better for emitBinaryParser to use a 64-bit tmp whenever 104381ad6265SDimitry Andric // possible but fall back to an InsnType-sized tmp for truly large fields. 104481ad6265SDimitry Andric OS.indent(Indentation) << "using TmpType = " 104581ad6265SDimitry Andric "std::conditional_t<std::is_integral<InsnType>::" 104681ad6265SDimitry Andric "value, InsnType, uint64_t>;\n"; 104781ad6265SDimitry Andric OS.indent(Indentation) << "TmpType tmp;\n"; 104881ad6265SDimitry Andric OS.indent(Indentation) << "switch (Idx) {\n"; 104981ad6265SDimitry Andric OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n"; 105081ad6265SDimitry Andric unsigned Index = 0; 105181ad6265SDimitry Andric for (const auto &Decoder : Decoders) { 105281ad6265SDimitry Andric OS.indent(Indentation) << "case " << Index++ << ":\n"; 105381ad6265SDimitry Andric OS << Decoder; 105481ad6265SDimitry Andric OS.indent(Indentation + 2) << "return S;\n"; 105581ad6265SDimitry Andric } 105681ad6265SDimitry Andric OS.indent(Indentation) << "}\n"; 105781ad6265SDimitry Andric Indentation -= 2; 1058*0fca6ea1SDimitry Andric OS.indent(Indentation) << "}\n"; 105981ad6265SDimitry Andric } 106081ad6265SDimitry Andric 106181ad6265SDimitry Andric // Populates the field of the insn given the start position and the number of 106281ad6265SDimitry Andric // consecutive bits to scan for. 106381ad6265SDimitry Andric // 1064*0fca6ea1SDimitry Andric // Returns a pair of values (indicator, field), where the indicator is false 1065*0fca6ea1SDimitry Andric // if there exists any uninitialized bit value in the range and true if all 1066*0fca6ea1SDimitry Andric // bits are well-known. The second value is the potentially populated field. 1067*0fca6ea1SDimitry Andric std::pair<bool, uint64_t> FilterChooser::fieldFromInsn(const insn_t &Insn, 1068*0fca6ea1SDimitry Andric unsigned StartBit, 1069*0fca6ea1SDimitry Andric unsigned NumBits) const { 1070*0fca6ea1SDimitry Andric uint64_t Field = 0; 107181ad6265SDimitry Andric 107281ad6265SDimitry Andric for (unsigned i = 0; i < NumBits; ++i) { 107381ad6265SDimitry Andric if (Insn[StartBit + i] == BIT_UNSET) 1074*0fca6ea1SDimitry Andric return {false, Field}; 107581ad6265SDimitry Andric 107681ad6265SDimitry Andric if (Insn[StartBit + i] == BIT_TRUE) 107781ad6265SDimitry Andric Field = Field | (1ULL << i); 107881ad6265SDimitry Andric } 107981ad6265SDimitry Andric 1080*0fca6ea1SDimitry Andric return {true, Field}; 108181ad6265SDimitry Andric } 108281ad6265SDimitry Andric 108381ad6265SDimitry Andric /// dumpFilterArray - dumpFilterArray prints out debugging info for the given 108481ad6265SDimitry Andric /// filter array as a series of chars. 1085*0fca6ea1SDimitry Andric void FilterChooser::dumpFilterArray( 1086*0fca6ea1SDimitry Andric raw_ostream &o, const std::vector<bit_value_t> &filter) const { 108781ad6265SDimitry Andric for (unsigned bitIndex = BitWidth; bitIndex > 0; bitIndex--) { 108881ad6265SDimitry Andric switch (filter[bitIndex - 1]) { 108981ad6265SDimitry Andric case BIT_UNFILTERED: 109081ad6265SDimitry Andric o << "."; 109181ad6265SDimitry Andric break; 109281ad6265SDimitry Andric case BIT_UNSET: 109381ad6265SDimitry Andric o << "_"; 109481ad6265SDimitry Andric break; 109581ad6265SDimitry Andric case BIT_TRUE: 109681ad6265SDimitry Andric o << "1"; 109781ad6265SDimitry Andric break; 109881ad6265SDimitry Andric case BIT_FALSE: 109981ad6265SDimitry Andric o << "0"; 110081ad6265SDimitry Andric break; 110181ad6265SDimitry Andric } 110281ad6265SDimitry Andric } 110381ad6265SDimitry Andric } 110481ad6265SDimitry Andric 110581ad6265SDimitry Andric /// dumpStack - dumpStack traverses the filter chooser chain and calls 110681ad6265SDimitry Andric /// dumpFilterArray on each filter chooser up to the top level one. 110781ad6265SDimitry Andric void FilterChooser::dumpStack(raw_ostream &o, const char *prefix) const { 110881ad6265SDimitry Andric const FilterChooser *current = this; 110981ad6265SDimitry Andric 111081ad6265SDimitry Andric while (current) { 111181ad6265SDimitry Andric o << prefix; 111281ad6265SDimitry Andric dumpFilterArray(o, current->FilterBitValues); 111381ad6265SDimitry Andric o << '\n'; 111481ad6265SDimitry Andric current = current->Parent; 111581ad6265SDimitry Andric } 111681ad6265SDimitry Andric } 111781ad6265SDimitry Andric 111881ad6265SDimitry Andric // Calculates the island(s) needed to decode the instruction. 111981ad6265SDimitry Andric // This returns a list of undecoded bits of an instructions, for example, 112081ad6265SDimitry Andric // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be 112181ad6265SDimitry Andric // decoded bits in order to verify that the instruction matches the Opcode. 112281ad6265SDimitry Andric unsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits, 112381ad6265SDimitry Andric std::vector<unsigned> &EndBits, 112481ad6265SDimitry Andric std::vector<uint64_t> &FieldVals, 112581ad6265SDimitry Andric const insn_t &Insn) const { 112681ad6265SDimitry Andric unsigned Num, BitNo; 112781ad6265SDimitry Andric Num = BitNo = 0; 112881ad6265SDimitry Andric 112981ad6265SDimitry Andric uint64_t FieldVal = 0; 113081ad6265SDimitry Andric 113181ad6265SDimitry Andric // 0: Init 113281ad6265SDimitry Andric // 1: Water (the bit value does not affect decoding) 113381ad6265SDimitry Andric // 2: Island (well-known bit value needed for decoding) 113481ad6265SDimitry Andric int State = 0; 113581ad6265SDimitry Andric 113681ad6265SDimitry Andric for (unsigned i = 0; i < BitWidth; ++i) { 113781ad6265SDimitry Andric int64_t Val = Value(Insn[i]); 113881ad6265SDimitry Andric bool Filtered = PositionFiltered(i); 113981ad6265SDimitry Andric switch (State) { 1140*0fca6ea1SDimitry Andric default: 1141*0fca6ea1SDimitry Andric llvm_unreachable("Unreachable code!"); 114281ad6265SDimitry Andric case 0: 114381ad6265SDimitry Andric case 1: 114481ad6265SDimitry Andric if (Filtered || Val == -1) 114581ad6265SDimitry Andric State = 1; // Still in Water 114681ad6265SDimitry Andric else { 114781ad6265SDimitry Andric State = 2; // Into the Island 114881ad6265SDimitry Andric BitNo = 0; 114981ad6265SDimitry Andric StartBits.push_back(i); 115081ad6265SDimitry Andric FieldVal = Val; 115181ad6265SDimitry Andric } 115281ad6265SDimitry Andric break; 115381ad6265SDimitry Andric case 2: 115481ad6265SDimitry Andric if (Filtered || Val == -1) { 115581ad6265SDimitry Andric State = 1; // Into the Water 115681ad6265SDimitry Andric EndBits.push_back(i - 1); 115781ad6265SDimitry Andric FieldVals.push_back(FieldVal); 115881ad6265SDimitry Andric ++Num; 115981ad6265SDimitry Andric } else { 116081ad6265SDimitry Andric State = 2; // Still in Island 116181ad6265SDimitry Andric ++BitNo; 116281ad6265SDimitry Andric FieldVal = FieldVal | Val << BitNo; 116381ad6265SDimitry Andric } 116481ad6265SDimitry Andric break; 116581ad6265SDimitry Andric } 116681ad6265SDimitry Andric } 116781ad6265SDimitry Andric // If we are still in Island after the loop, do some housekeeping. 116881ad6265SDimitry Andric if (State == 2) { 116981ad6265SDimitry Andric EndBits.push_back(BitWidth - 1); 117081ad6265SDimitry Andric FieldVals.push_back(FieldVal); 117181ad6265SDimitry Andric ++Num; 117281ad6265SDimitry Andric } 117381ad6265SDimitry Andric 117481ad6265SDimitry Andric assert(StartBits.size() == Num && EndBits.size() == Num && 117581ad6265SDimitry Andric FieldVals.size() == Num); 117681ad6265SDimitry Andric return Num; 117781ad6265SDimitry Andric } 117881ad6265SDimitry Andric 117981ad6265SDimitry Andric void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, 118081ad6265SDimitry Andric const OperandInfo &OpInfo, 118181ad6265SDimitry Andric bool &OpHasCompleteDecoder) const { 118281ad6265SDimitry Andric const std::string &Decoder = OpInfo.Decoder; 118381ad6265SDimitry Andric 118481ad6265SDimitry Andric bool UseInsertBits = OpInfo.numFields() != 1 || OpInfo.InitValue != 0; 118581ad6265SDimitry Andric 118681ad6265SDimitry Andric if (UseInsertBits) { 118781ad6265SDimitry Andric o.indent(Indentation) << "tmp = 0x"; 118881ad6265SDimitry Andric o.write_hex(OpInfo.InitValue); 118981ad6265SDimitry Andric o << ";\n"; 119081ad6265SDimitry Andric } 119181ad6265SDimitry Andric 119281ad6265SDimitry Andric for (const EncodingField &EF : OpInfo) { 119381ad6265SDimitry Andric o.indent(Indentation); 119481ad6265SDimitry Andric if (UseInsertBits) 119581ad6265SDimitry Andric o << "insertBits(tmp, "; 119681ad6265SDimitry Andric else 119781ad6265SDimitry Andric o << "tmp = "; 119881ad6265SDimitry Andric o << "fieldFromInstruction(insn, " << EF.Base << ", " << EF.Width << ')'; 119981ad6265SDimitry Andric if (UseInsertBits) 120081ad6265SDimitry Andric o << ", " << EF.Offset << ", " << EF.Width << ')'; 120181ad6265SDimitry Andric else if (EF.Offset != 0) 120281ad6265SDimitry Andric o << " << " << EF.Offset; 120381ad6265SDimitry Andric o << ";\n"; 120481ad6265SDimitry Andric } 120581ad6265SDimitry Andric 120681ad6265SDimitry Andric if (Decoder != "") { 120781ad6265SDimitry Andric OpHasCompleteDecoder = OpInfo.HasCompleteDecoder; 1208bdd1243dSDimitry Andric o.indent(Indentation) << "if (!Check(S, " << Decoder 1209bdd1243dSDimitry Andric << "(MI, tmp, Address, Decoder))) { " 1210bdd1243dSDimitry Andric << (OpHasCompleteDecoder ? "" 1211bdd1243dSDimitry Andric : "DecodeComplete = false; ") 121281ad6265SDimitry Andric << "return MCDisassembler::Fail; }\n"; 121381ad6265SDimitry Andric } else { 121481ad6265SDimitry Andric OpHasCompleteDecoder = true; 121581ad6265SDimitry Andric o.indent(Indentation) << "MI.addOperand(MCOperand::createImm(tmp));\n"; 121681ad6265SDimitry Andric } 121781ad6265SDimitry Andric } 121881ad6265SDimitry Andric 121981ad6265SDimitry Andric void FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation, 122081ad6265SDimitry Andric unsigned Opc, bool &HasCompleteDecoder) const { 122181ad6265SDimitry Andric HasCompleteDecoder = true; 122281ad6265SDimitry Andric 122381ad6265SDimitry Andric for (const auto &Op : Operands.find(Opc)->second) { 122481ad6265SDimitry Andric // If a custom instruction decoder was specified, use that. 122581ad6265SDimitry Andric if (Op.numFields() == 0 && !Op.Decoder.empty()) { 122681ad6265SDimitry Andric HasCompleteDecoder = Op.HasCompleteDecoder; 1227bdd1243dSDimitry Andric OS.indent(Indentation) 1228bdd1243dSDimitry Andric << "if (!Check(S, " << Op.Decoder 1229bdd1243dSDimitry Andric << "(MI, insn, Address, Decoder))) { " 1230bdd1243dSDimitry Andric << (HasCompleteDecoder ? "" : "DecodeComplete = false; ") 123181ad6265SDimitry Andric << "return MCDisassembler::Fail; }\n"; 123281ad6265SDimitry Andric break; 123381ad6265SDimitry Andric } 123481ad6265SDimitry Andric 123581ad6265SDimitry Andric bool OpHasCompleteDecoder; 123681ad6265SDimitry Andric emitBinaryParser(OS, Indentation, Op, OpHasCompleteDecoder); 123781ad6265SDimitry Andric if (!OpHasCompleteDecoder) 123881ad6265SDimitry Andric HasCompleteDecoder = false; 123981ad6265SDimitry Andric } 124081ad6265SDimitry Andric } 124181ad6265SDimitry Andric 1242*0fca6ea1SDimitry Andric unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders, unsigned Opc, 124381ad6265SDimitry Andric bool &HasCompleteDecoder) const { 124481ad6265SDimitry Andric // Build up the predicate string. 124581ad6265SDimitry Andric SmallString<256> Decoder; 124681ad6265SDimitry Andric // FIXME: emitDecoder() function can take a buffer directly rather than 124781ad6265SDimitry Andric // a stream. 124881ad6265SDimitry Andric raw_svector_ostream S(Decoder); 124981ad6265SDimitry Andric unsigned I = 4; 125081ad6265SDimitry Andric emitDecoder(S, I, Opc, HasCompleteDecoder); 125181ad6265SDimitry Andric 125281ad6265SDimitry Andric // Using the full decoder string as the key value here is a bit 125381ad6265SDimitry Andric // heavyweight, but is effective. If the string comparisons become a 125481ad6265SDimitry Andric // performance concern, we can implement a mangling of the predicate 125581ad6265SDimitry Andric // data easily enough with a map back to the actual string. That's 125681ad6265SDimitry Andric // overkill for now, though. 125781ad6265SDimitry Andric 125881ad6265SDimitry Andric // Make sure the predicate is in the table. 125981ad6265SDimitry Andric Decoders.insert(CachedHashString(Decoder)); 126081ad6265SDimitry Andric // Now figure out the index for when we write out the table. 126181ad6265SDimitry Andric DecoderSet::const_iterator P = find(Decoders, Decoder.str()); 126281ad6265SDimitry Andric return (unsigned)(P - Decoders.begin()); 126381ad6265SDimitry Andric } 126481ad6265SDimitry Andric 126581ad6265SDimitry Andric // If ParenIfBinOp is true, print a surrounding () if Val uses && or ||. 126681ad6265SDimitry Andric bool FilterChooser::emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp, 126781ad6265SDimitry Andric raw_ostream &OS) const { 1268*0fca6ea1SDimitry Andric if (const auto *D = dyn_cast<DefInit>(&Val)) { 126981ad6265SDimitry Andric if (!D->getDef()->isSubClassOf("SubtargetFeature")) 127081ad6265SDimitry Andric return true; 127181ad6265SDimitry Andric OS << "Bits[" << Emitter->PredicateNamespace << "::" << D->getAsString() 127281ad6265SDimitry Andric << "]"; 127381ad6265SDimitry Andric return false; 127481ad6265SDimitry Andric } 1275*0fca6ea1SDimitry Andric if (const auto *D = dyn_cast<DagInit>(&Val)) { 127681ad6265SDimitry Andric std::string Op = D->getOperator()->getAsString(); 127781ad6265SDimitry Andric if (Op == "not" && D->getNumArgs() == 1) { 127881ad6265SDimitry Andric OS << '!'; 127981ad6265SDimitry Andric return emitPredicateMatchAux(*D->getArg(0), true, OS); 128081ad6265SDimitry Andric } 128181ad6265SDimitry Andric if ((Op == "any_of" || Op == "all_of") && D->getNumArgs() > 0) { 128281ad6265SDimitry Andric bool Paren = D->getNumArgs() > 1 && std::exchange(ParenIfBinOp, true); 128381ad6265SDimitry Andric if (Paren) 128481ad6265SDimitry Andric OS << '('; 128581ad6265SDimitry Andric ListSeparator LS(Op == "any_of" ? " || " : " && "); 128681ad6265SDimitry Andric for (auto *Arg : D->getArgs()) { 128781ad6265SDimitry Andric OS << LS; 128881ad6265SDimitry Andric if (emitPredicateMatchAux(*Arg, ParenIfBinOp, OS)) 128981ad6265SDimitry Andric return true; 129081ad6265SDimitry Andric } 129181ad6265SDimitry Andric if (Paren) 129281ad6265SDimitry Andric OS << ')'; 129381ad6265SDimitry Andric return false; 129481ad6265SDimitry Andric } 129581ad6265SDimitry Andric } 129681ad6265SDimitry Andric return true; 129781ad6265SDimitry Andric } 129881ad6265SDimitry Andric 129981ad6265SDimitry Andric bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, 130081ad6265SDimitry Andric unsigned Opc) const { 130181ad6265SDimitry Andric ListInit *Predicates = 130281ad6265SDimitry Andric AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates"); 130381ad6265SDimitry Andric bool IsFirstEmission = true; 130481ad6265SDimitry Andric for (unsigned i = 0; i < Predicates->size(); ++i) { 130581ad6265SDimitry Andric Record *Pred = Predicates->getElementAsRecord(i); 130681ad6265SDimitry Andric if (!Pred->getValue("AssemblerMatcherPredicate")) 130781ad6265SDimitry Andric continue; 130881ad6265SDimitry Andric 130981ad6265SDimitry Andric if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue())) 131081ad6265SDimitry Andric continue; 131181ad6265SDimitry Andric 131281ad6265SDimitry Andric if (!IsFirstEmission) 131381ad6265SDimitry Andric o << " && "; 131481ad6265SDimitry Andric if (emitPredicateMatchAux(*Pred->getValueAsDag("AssemblerCondDag"), 131581ad6265SDimitry Andric Predicates->size() > 1, o)) 131681ad6265SDimitry Andric PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!"); 131781ad6265SDimitry Andric IsFirstEmission = false; 131881ad6265SDimitry Andric } 131981ad6265SDimitry Andric return !Predicates->empty(); 132081ad6265SDimitry Andric } 132181ad6265SDimitry Andric 132281ad6265SDimitry Andric bool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const { 132381ad6265SDimitry Andric ListInit *Predicates = 132481ad6265SDimitry Andric AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates"); 132581ad6265SDimitry Andric for (unsigned i = 0; i < Predicates->size(); ++i) { 132681ad6265SDimitry Andric Record *Pred = Predicates->getElementAsRecord(i); 132781ad6265SDimitry Andric if (!Pred->getValue("AssemblerMatcherPredicate")) 132881ad6265SDimitry Andric continue; 132981ad6265SDimitry Andric 133081ad6265SDimitry Andric if (isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue())) 133181ad6265SDimitry Andric return true; 133281ad6265SDimitry Andric } 133381ad6265SDimitry Andric return false; 133481ad6265SDimitry Andric } 133581ad6265SDimitry Andric 133681ad6265SDimitry Andric unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo, 133781ad6265SDimitry Andric StringRef Predicate) const { 133881ad6265SDimitry Andric // Using the full predicate string as the key value here is a bit 133981ad6265SDimitry Andric // heavyweight, but is effective. If the string comparisons become a 134081ad6265SDimitry Andric // performance concern, we can implement a mangling of the predicate 134181ad6265SDimitry Andric // data easily enough with a map back to the actual string. That's 134281ad6265SDimitry Andric // overkill for now, though. 134381ad6265SDimitry Andric 134481ad6265SDimitry Andric // Make sure the predicate is in the table. 134581ad6265SDimitry Andric TableInfo.Predicates.insert(CachedHashString(Predicate)); 134681ad6265SDimitry Andric // Now figure out the index for when we write out the table. 134781ad6265SDimitry Andric PredicateSet::const_iterator P = find(TableInfo.Predicates, Predicate); 134881ad6265SDimitry Andric return (unsigned)(P - TableInfo.Predicates.begin()); 134981ad6265SDimitry Andric } 135081ad6265SDimitry Andric 135181ad6265SDimitry Andric void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo, 135281ad6265SDimitry Andric unsigned Opc) const { 135381ad6265SDimitry Andric if (!doesOpcodeNeedPredicate(Opc)) 135481ad6265SDimitry Andric return; 135581ad6265SDimitry Andric 135681ad6265SDimitry Andric // Build up the predicate string. 135781ad6265SDimitry Andric SmallString<256> Predicate; 135881ad6265SDimitry Andric // FIXME: emitPredicateMatch() functions can take a buffer directly rather 135981ad6265SDimitry Andric // than a stream. 136081ad6265SDimitry Andric raw_svector_ostream PS(Predicate); 136181ad6265SDimitry Andric unsigned I = 0; 136281ad6265SDimitry Andric emitPredicateMatch(PS, I, Opc); 136381ad6265SDimitry Andric 136481ad6265SDimitry Andric // Figure out the index into the predicate table for the predicate just 136581ad6265SDimitry Andric // computed. 136681ad6265SDimitry Andric unsigned PIdx = getPredicateIndex(TableInfo, PS.str()); 136781ad6265SDimitry Andric SmallString<16> PBytes; 136881ad6265SDimitry Andric raw_svector_ostream S(PBytes); 136981ad6265SDimitry Andric encodeULEB128(PIdx, S); 137081ad6265SDimitry Andric 137181ad6265SDimitry Andric TableInfo.Table.push_back(MCD::OPC_CheckPredicate); 1372*0fca6ea1SDimitry Andric // Predicate index. 1373*0fca6ea1SDimitry Andric for (const auto PB : PBytes) 1374*0fca6ea1SDimitry Andric TableInfo.Table.push_back(PB); 137581ad6265SDimitry Andric // Push location for NumToSkip backpatching. 137681ad6265SDimitry Andric TableInfo.FixupStack.back().push_back(TableInfo.Table.size()); 137781ad6265SDimitry Andric TableInfo.Table.push_back(0); 137881ad6265SDimitry Andric TableInfo.Table.push_back(0); 137981ad6265SDimitry Andric TableInfo.Table.push_back(0); 138081ad6265SDimitry Andric } 138181ad6265SDimitry Andric 138281ad6265SDimitry Andric void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo, 138381ad6265SDimitry Andric unsigned Opc) const { 1384*0fca6ea1SDimitry Andric const Record *EncodingDef = AllInstructions[Opc].EncodingDef; 1385*0fca6ea1SDimitry Andric const RecordVal *RV = EncodingDef->getValue("SoftFail"); 138681ad6265SDimitry Andric BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr; 138781ad6265SDimitry Andric 1388*0fca6ea1SDimitry Andric if (!SFBits) 1389*0fca6ea1SDimitry Andric return; 1390*0fca6ea1SDimitry Andric BitsInit *InstBits = EncodingDef->getValueAsBitsInit("Inst"); 139181ad6265SDimitry Andric 139281ad6265SDimitry Andric APInt PositiveMask(BitWidth, 0ULL); 139381ad6265SDimitry Andric APInt NegativeMask(BitWidth, 0ULL); 139481ad6265SDimitry Andric for (unsigned i = 0; i < BitWidth; ++i) { 139581ad6265SDimitry Andric bit_value_t B = bitFromBits(*SFBits, i); 139681ad6265SDimitry Andric bit_value_t IB = bitFromBits(*InstBits, i); 139781ad6265SDimitry Andric 1398*0fca6ea1SDimitry Andric if (B != BIT_TRUE) 1399*0fca6ea1SDimitry Andric continue; 140081ad6265SDimitry Andric 140181ad6265SDimitry Andric switch (IB) { 140281ad6265SDimitry Andric case BIT_FALSE: 140381ad6265SDimitry Andric // The bit is meant to be false, so emit a check to see if it is true. 140481ad6265SDimitry Andric PositiveMask.setBit(i); 140581ad6265SDimitry Andric break; 140681ad6265SDimitry Andric case BIT_TRUE: 140781ad6265SDimitry Andric // The bit is meant to be true, so emit a check to see if it is false. 140881ad6265SDimitry Andric NegativeMask.setBit(i); 140981ad6265SDimitry Andric break; 141081ad6265SDimitry Andric default: 141181ad6265SDimitry Andric // The bit is not set; this must be an error! 141281ad6265SDimitry Andric errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in " 141381ad6265SDimitry Andric << AllInstructions[Opc] << " is set but Inst{" << i 141481ad6265SDimitry Andric << "} is unset!\n" 141581ad6265SDimitry Andric << " - You can only mark a bit as SoftFail if it is fully defined" 141681ad6265SDimitry Andric << " (1/0 - not '?') in Inst\n"; 141781ad6265SDimitry Andric return; 141881ad6265SDimitry Andric } 141981ad6265SDimitry Andric } 142081ad6265SDimitry Andric 142181ad6265SDimitry Andric bool NeedPositiveMask = PositiveMask.getBoolValue(); 142281ad6265SDimitry Andric bool NeedNegativeMask = NegativeMask.getBoolValue(); 142381ad6265SDimitry Andric 142481ad6265SDimitry Andric if (!NeedPositiveMask && !NeedNegativeMask) 142581ad6265SDimitry Andric return; 142681ad6265SDimitry Andric 142781ad6265SDimitry Andric TableInfo.Table.push_back(MCD::OPC_SoftFail); 142881ad6265SDimitry Andric 142981ad6265SDimitry Andric SmallString<16> MaskBytes; 143081ad6265SDimitry Andric raw_svector_ostream S(MaskBytes); 143181ad6265SDimitry Andric if (NeedPositiveMask) { 143281ad6265SDimitry Andric encodeULEB128(PositiveMask.getZExtValue(), S); 143381ad6265SDimitry Andric for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i) 143481ad6265SDimitry Andric TableInfo.Table.push_back(MaskBytes[i]); 143581ad6265SDimitry Andric } else 143681ad6265SDimitry Andric TableInfo.Table.push_back(0); 143781ad6265SDimitry Andric if (NeedNegativeMask) { 143881ad6265SDimitry Andric MaskBytes.clear(); 143981ad6265SDimitry Andric encodeULEB128(NegativeMask.getZExtValue(), S); 144081ad6265SDimitry Andric for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i) 144181ad6265SDimitry Andric TableInfo.Table.push_back(MaskBytes[i]); 144281ad6265SDimitry Andric } else 144381ad6265SDimitry Andric TableInfo.Table.push_back(0); 144481ad6265SDimitry Andric } 144581ad6265SDimitry Andric 144681ad6265SDimitry Andric // Emits table entries to decode the singleton. 144781ad6265SDimitry Andric void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo, 144881ad6265SDimitry Andric EncodingIDAndOpcode Opc) const { 144981ad6265SDimitry Andric std::vector<unsigned> StartBits; 145081ad6265SDimitry Andric std::vector<unsigned> EndBits; 145181ad6265SDimitry Andric std::vector<uint64_t> FieldVals; 145281ad6265SDimitry Andric insn_t Insn; 145381ad6265SDimitry Andric insnWithID(Insn, Opc.EncodingID); 145481ad6265SDimitry Andric 145581ad6265SDimitry Andric // Look for islands of undecoded bits of the singleton. 145681ad6265SDimitry Andric getIslands(StartBits, EndBits, FieldVals, Insn); 145781ad6265SDimitry Andric 145881ad6265SDimitry Andric unsigned Size = StartBits.size(); 145981ad6265SDimitry Andric 146081ad6265SDimitry Andric // Emit the predicate table entry if one is needed. 146181ad6265SDimitry Andric emitPredicateTableEntry(TableInfo, Opc.EncodingID); 146281ad6265SDimitry Andric 146381ad6265SDimitry Andric // Check any additional encoding fields needed. 146481ad6265SDimitry Andric for (unsigned I = Size; I != 0; --I) { 146581ad6265SDimitry Andric unsigned NumBits = EndBits[I - 1] - StartBits[I - 1] + 1; 1466*0fca6ea1SDimitry Andric assert((NumBits < (1u << 8)) && "NumBits overflowed uint8 table entry!"); 146781ad6265SDimitry Andric TableInfo.Table.push_back(MCD::OPC_CheckField); 1468*0fca6ea1SDimitry Andric uint8_t Buffer[16], *P; 1469*0fca6ea1SDimitry Andric encodeULEB128(StartBits[I - 1], Buffer); 1470*0fca6ea1SDimitry Andric for (P = Buffer; *P >= 128; ++P) 1471*0fca6ea1SDimitry Andric TableInfo.Table.push_back(*P); 1472*0fca6ea1SDimitry Andric TableInfo.Table.push_back(*P); 147381ad6265SDimitry Andric TableInfo.Table.push_back(NumBits); 147481ad6265SDimitry Andric encodeULEB128(FieldVals[I - 1], Buffer); 1475*0fca6ea1SDimitry Andric for (P = Buffer; *P >= 128; ++P) 1476*0fca6ea1SDimitry Andric TableInfo.Table.push_back(*P); 1477*0fca6ea1SDimitry Andric TableInfo.Table.push_back(*P); 147881ad6265SDimitry Andric // Push location for NumToSkip backpatching. 147981ad6265SDimitry Andric TableInfo.FixupStack.back().push_back(TableInfo.Table.size()); 148081ad6265SDimitry Andric // The fixup is always 24-bits, so go ahead and allocate the space 148181ad6265SDimitry Andric // in the table so all our relative position calculations work OK even 148281ad6265SDimitry Andric // before we fully resolve the real value here. 148381ad6265SDimitry Andric TableInfo.Table.push_back(0); 148481ad6265SDimitry Andric TableInfo.Table.push_back(0); 148581ad6265SDimitry Andric TableInfo.Table.push_back(0); 148681ad6265SDimitry Andric } 148781ad6265SDimitry Andric 148881ad6265SDimitry Andric // Check for soft failure of the match. 148981ad6265SDimitry Andric emitSoftFailTableEntry(TableInfo, Opc.EncodingID); 149081ad6265SDimitry Andric 149181ad6265SDimitry Andric bool HasCompleteDecoder; 149281ad6265SDimitry Andric unsigned DIdx = 149381ad6265SDimitry Andric getDecoderIndex(TableInfo.Decoders, Opc.EncodingID, HasCompleteDecoder); 149481ad6265SDimitry Andric 149581ad6265SDimitry Andric // Produce OPC_Decode or OPC_TryDecode opcode based on the information 149681ad6265SDimitry Andric // whether the instruction decoder is complete or not. If it is complete 149781ad6265SDimitry Andric // then it handles all possible values of remaining variable/unfiltered bits 149881ad6265SDimitry Andric // and for any value can determine if the bitpattern is a valid instruction 149981ad6265SDimitry Andric // or not. This means OPC_Decode will be the final step in the decoding 150081ad6265SDimitry Andric // process. If it is not complete, then the Fail return code from the 150181ad6265SDimitry Andric // decoder method indicates that additional processing should be done to see 150281ad6265SDimitry Andric // if there is any other instruction that also matches the bitpattern and 150381ad6265SDimitry Andric // can decode it. 1504*0fca6ea1SDimitry Andric TableInfo.Table.push_back(HasCompleteDecoder ? MCD::OPC_Decode 1505*0fca6ea1SDimitry Andric : MCD::OPC_TryDecode); 150681ad6265SDimitry Andric NumEncodingsSupported++; 150781ad6265SDimitry Andric uint8_t Buffer[16], *p; 150881ad6265SDimitry Andric encodeULEB128(Opc.Opcode, Buffer); 150981ad6265SDimitry Andric for (p = Buffer; *p >= 128; ++p) 151081ad6265SDimitry Andric TableInfo.Table.push_back(*p); 151181ad6265SDimitry Andric TableInfo.Table.push_back(*p); 151281ad6265SDimitry Andric 151381ad6265SDimitry Andric SmallString<16> Bytes; 151481ad6265SDimitry Andric raw_svector_ostream S(Bytes); 151581ad6265SDimitry Andric encodeULEB128(DIdx, S); 151681ad6265SDimitry Andric 1517*0fca6ea1SDimitry Andric // Decoder index. 1518*0fca6ea1SDimitry Andric for (const auto B : Bytes) 1519*0fca6ea1SDimitry Andric TableInfo.Table.push_back(B); 152081ad6265SDimitry Andric 152181ad6265SDimitry Andric if (!HasCompleteDecoder) { 152281ad6265SDimitry Andric // Push location for NumToSkip backpatching. 152381ad6265SDimitry Andric TableInfo.FixupStack.back().push_back(TableInfo.Table.size()); 152481ad6265SDimitry Andric // Allocate the space for the fixup. 152581ad6265SDimitry Andric TableInfo.Table.push_back(0); 152681ad6265SDimitry Andric TableInfo.Table.push_back(0); 152781ad6265SDimitry Andric TableInfo.Table.push_back(0); 152881ad6265SDimitry Andric } 152981ad6265SDimitry Andric } 153081ad6265SDimitry Andric 153181ad6265SDimitry Andric // Emits table entries to decode the singleton, and then to decode the rest. 153281ad6265SDimitry Andric void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo, 153381ad6265SDimitry Andric const Filter &Best) const { 153481ad6265SDimitry Andric EncodingIDAndOpcode Opc = Best.getSingletonOpc(); 153581ad6265SDimitry Andric 153681ad6265SDimitry Andric // complex singletons need predicate checks from the first singleton 153781ad6265SDimitry Andric // to refer forward to the variable filterchooser that follows. 153881ad6265SDimitry Andric TableInfo.FixupStack.emplace_back(); 153981ad6265SDimitry Andric 154081ad6265SDimitry Andric emitSingletonTableEntry(TableInfo, Opc); 154181ad6265SDimitry Andric 154281ad6265SDimitry Andric resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(), 154381ad6265SDimitry Andric TableInfo.Table.size()); 154481ad6265SDimitry Andric TableInfo.FixupStack.pop_back(); 154581ad6265SDimitry Andric 154681ad6265SDimitry Andric Best.getVariableFC().emitTableEntries(TableInfo); 154781ad6265SDimitry Andric } 154881ad6265SDimitry Andric 154981ad6265SDimitry Andric // Assign a single filter and run with it. Top level API client can initialize 155081ad6265SDimitry Andric // with a single filter to start the filtering process. 155181ad6265SDimitry Andric void FilterChooser::runSingleFilter(unsigned startBit, unsigned numBit, 155281ad6265SDimitry Andric bool mixed) { 155381ad6265SDimitry Andric Filters.clear(); 155481ad6265SDimitry Andric Filters.emplace_back(*this, startBit, numBit, true); 155581ad6265SDimitry Andric BestIndex = 0; // Sole Filter instance to choose from. 155681ad6265SDimitry Andric bestFilter().recurse(); 155781ad6265SDimitry Andric } 155881ad6265SDimitry Andric 155981ad6265SDimitry Andric // reportRegion is a helper function for filterProcessor to mark a region as 156081ad6265SDimitry Andric // eligible for use as a filter region. 156181ad6265SDimitry Andric void FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit, 156281ad6265SDimitry Andric unsigned BitIndex, bool AllowMixed) { 156381ad6265SDimitry Andric if (RA == ATTR_MIXED && AllowMixed) 156481ad6265SDimitry Andric Filters.emplace_back(*this, StartBit, BitIndex - StartBit, true); 156581ad6265SDimitry Andric else if (RA == ATTR_ALL_SET && !AllowMixed) 156681ad6265SDimitry Andric Filters.emplace_back(*this, StartBit, BitIndex - StartBit, false); 156781ad6265SDimitry Andric } 156881ad6265SDimitry Andric 156981ad6265SDimitry Andric // FilterProcessor scans the well-known encoding bits of the instructions and 157081ad6265SDimitry Andric // builds up a list of candidate filters. It chooses the best filter and 157181ad6265SDimitry Andric // recursively descends down the decoding tree. 157281ad6265SDimitry Andric bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) { 157381ad6265SDimitry Andric Filters.clear(); 157481ad6265SDimitry Andric BestIndex = -1; 157581ad6265SDimitry Andric unsigned numInstructions = Opcodes.size(); 157681ad6265SDimitry Andric 157781ad6265SDimitry Andric assert(numInstructions && "Filter created with no instructions"); 157881ad6265SDimitry Andric 157981ad6265SDimitry Andric // No further filtering is necessary. 158081ad6265SDimitry Andric if (numInstructions == 1) 158181ad6265SDimitry Andric return true; 158281ad6265SDimitry Andric 158381ad6265SDimitry Andric // Heuristics. See also doFilter()'s "Heuristics" comment when num of 158481ad6265SDimitry Andric // instructions is 3. 158581ad6265SDimitry Andric if (AllowMixed && !Greedy) { 158681ad6265SDimitry Andric assert(numInstructions == 3); 158781ad6265SDimitry Andric 1588*0fca6ea1SDimitry Andric for (const auto &Opcode : Opcodes) { 158981ad6265SDimitry Andric std::vector<unsigned> StartBits; 159081ad6265SDimitry Andric std::vector<unsigned> EndBits; 159181ad6265SDimitry Andric std::vector<uint64_t> FieldVals; 159281ad6265SDimitry Andric insn_t Insn; 159381ad6265SDimitry Andric 159481ad6265SDimitry Andric insnWithID(Insn, Opcode.EncodingID); 159581ad6265SDimitry Andric 159681ad6265SDimitry Andric // Look for islands of undecoded bits of any instruction. 159781ad6265SDimitry Andric if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) { 159881ad6265SDimitry Andric // Found an instruction with island(s). Now just assign a filter. 159981ad6265SDimitry Andric runSingleFilter(StartBits[0], EndBits[0] - StartBits[0] + 1, true); 160081ad6265SDimitry Andric return true; 160181ad6265SDimitry Andric } 160281ad6265SDimitry Andric } 160381ad6265SDimitry Andric } 160481ad6265SDimitry Andric 160581ad6265SDimitry Andric unsigned BitIndex; 160681ad6265SDimitry Andric 160781ad6265SDimitry Andric // We maintain BIT_WIDTH copies of the bitAttrs automaton. 160881ad6265SDimitry Andric // The automaton consumes the corresponding bit from each 160981ad6265SDimitry Andric // instruction. 161081ad6265SDimitry Andric // 161181ad6265SDimitry Andric // Input symbols: 0, 1, and _ (unset). 161281ad6265SDimitry Andric // States: NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED. 161381ad6265SDimitry Andric // Initial state: NONE. 161481ad6265SDimitry Andric // 161581ad6265SDimitry Andric // (NONE) ------- [01] -> (ALL_SET) 161681ad6265SDimitry Andric // (NONE) ------- _ ----> (ALL_UNSET) 161781ad6265SDimitry Andric // (ALL_SET) ---- [01] -> (ALL_SET) 161881ad6265SDimitry Andric // (ALL_SET) ---- _ ----> (MIXED) 161981ad6265SDimitry Andric // (ALL_UNSET) -- [01] -> (MIXED) 162081ad6265SDimitry Andric // (ALL_UNSET) -- _ ----> (ALL_UNSET) 162181ad6265SDimitry Andric // (MIXED) ------ . ----> (MIXED) 162281ad6265SDimitry Andric // (FILTERED)---- . ----> (FILTERED) 162381ad6265SDimitry Andric 162481ad6265SDimitry Andric std::vector<bitAttr_t> bitAttrs; 162581ad6265SDimitry Andric 162681ad6265SDimitry Andric // FILTERED bit positions provide no entropy and are not worthy of pursuing. 162781ad6265SDimitry Andric // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position. 162881ad6265SDimitry Andric for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) 162981ad6265SDimitry Andric if (FilterBitValues[BitIndex] == BIT_TRUE || 163081ad6265SDimitry Andric FilterBitValues[BitIndex] == BIT_FALSE) 163181ad6265SDimitry Andric bitAttrs.push_back(ATTR_FILTERED); 163281ad6265SDimitry Andric else 163381ad6265SDimitry Andric bitAttrs.push_back(ATTR_NONE); 163481ad6265SDimitry Andric 1635*0fca6ea1SDimitry Andric for (const auto &OpcPair : Opcodes) { 163681ad6265SDimitry Andric insn_t insn; 163781ad6265SDimitry Andric 1638*0fca6ea1SDimitry Andric insnWithID(insn, OpcPair.EncodingID); 163981ad6265SDimitry Andric 164081ad6265SDimitry Andric for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) { 164181ad6265SDimitry Andric switch (bitAttrs[BitIndex]) { 164281ad6265SDimitry Andric case ATTR_NONE: 164381ad6265SDimitry Andric if (insn[BitIndex] == BIT_UNSET) 164481ad6265SDimitry Andric bitAttrs[BitIndex] = ATTR_ALL_UNSET; 164581ad6265SDimitry Andric else 164681ad6265SDimitry Andric bitAttrs[BitIndex] = ATTR_ALL_SET; 164781ad6265SDimitry Andric break; 164881ad6265SDimitry Andric case ATTR_ALL_SET: 164981ad6265SDimitry Andric if (insn[BitIndex] == BIT_UNSET) 165081ad6265SDimitry Andric bitAttrs[BitIndex] = ATTR_MIXED; 165181ad6265SDimitry Andric break; 165281ad6265SDimitry Andric case ATTR_ALL_UNSET: 165381ad6265SDimitry Andric if (insn[BitIndex] != BIT_UNSET) 165481ad6265SDimitry Andric bitAttrs[BitIndex] = ATTR_MIXED; 165581ad6265SDimitry Andric break; 165681ad6265SDimitry Andric case ATTR_MIXED: 165781ad6265SDimitry Andric case ATTR_FILTERED: 165881ad6265SDimitry Andric break; 165981ad6265SDimitry Andric } 166081ad6265SDimitry Andric } 166181ad6265SDimitry Andric } 166281ad6265SDimitry Andric 166381ad6265SDimitry Andric // The regionAttr automaton consumes the bitAttrs automatons' state, 166481ad6265SDimitry Andric // lowest-to-highest. 166581ad6265SDimitry Andric // 166681ad6265SDimitry Andric // Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed) 166781ad6265SDimitry Andric // States: NONE, ALL_SET, MIXED 166881ad6265SDimitry Andric // Initial state: NONE 166981ad6265SDimitry Andric // 167081ad6265SDimitry Andric // (NONE) ----- F --> (NONE) 167181ad6265SDimitry Andric // (NONE) ----- S --> (ALL_SET) ; and set region start 167281ad6265SDimitry Andric // (NONE) ----- U --> (NONE) 167381ad6265SDimitry Andric // (NONE) ----- M --> (MIXED) ; and set region start 167481ad6265SDimitry Andric // (ALL_SET) -- F --> (NONE) ; and report an ALL_SET region 167581ad6265SDimitry Andric // (ALL_SET) -- S --> (ALL_SET) 167681ad6265SDimitry Andric // (ALL_SET) -- U --> (NONE) ; and report an ALL_SET region 167781ad6265SDimitry Andric // (ALL_SET) -- M --> (MIXED) ; and report an ALL_SET region 167881ad6265SDimitry Andric // (MIXED) ---- F --> (NONE) ; and report a MIXED region 167981ad6265SDimitry Andric // (MIXED) ---- S --> (ALL_SET) ; and report a MIXED region 168081ad6265SDimitry Andric // (MIXED) ---- U --> (NONE) ; and report a MIXED region 168181ad6265SDimitry Andric // (MIXED) ---- M --> (MIXED) 168281ad6265SDimitry Andric 168381ad6265SDimitry Andric bitAttr_t RA = ATTR_NONE; 168481ad6265SDimitry Andric unsigned StartBit = 0; 168581ad6265SDimitry Andric 168681ad6265SDimitry Andric for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) { 168781ad6265SDimitry Andric bitAttr_t bitAttr = bitAttrs[BitIndex]; 168881ad6265SDimitry Andric 168981ad6265SDimitry Andric assert(bitAttr != ATTR_NONE && "Bit without attributes"); 169081ad6265SDimitry Andric 169181ad6265SDimitry Andric switch (RA) { 169281ad6265SDimitry Andric case ATTR_NONE: 169381ad6265SDimitry Andric switch (bitAttr) { 169481ad6265SDimitry Andric case ATTR_FILTERED: 169581ad6265SDimitry Andric break; 169681ad6265SDimitry Andric case ATTR_ALL_SET: 169781ad6265SDimitry Andric StartBit = BitIndex; 169881ad6265SDimitry Andric RA = ATTR_ALL_SET; 169981ad6265SDimitry Andric break; 170081ad6265SDimitry Andric case ATTR_ALL_UNSET: 170181ad6265SDimitry Andric break; 170281ad6265SDimitry Andric case ATTR_MIXED: 170381ad6265SDimitry Andric StartBit = BitIndex; 170481ad6265SDimitry Andric RA = ATTR_MIXED; 170581ad6265SDimitry Andric break; 170681ad6265SDimitry Andric default: 170781ad6265SDimitry Andric llvm_unreachable("Unexpected bitAttr!"); 170881ad6265SDimitry Andric } 170981ad6265SDimitry Andric break; 171081ad6265SDimitry Andric case ATTR_ALL_SET: 171181ad6265SDimitry Andric switch (bitAttr) { 171281ad6265SDimitry Andric case ATTR_FILTERED: 171381ad6265SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed); 171481ad6265SDimitry Andric RA = ATTR_NONE; 171581ad6265SDimitry Andric break; 171681ad6265SDimitry Andric case ATTR_ALL_SET: 171781ad6265SDimitry Andric break; 171881ad6265SDimitry Andric case ATTR_ALL_UNSET: 171981ad6265SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed); 172081ad6265SDimitry Andric RA = ATTR_NONE; 172181ad6265SDimitry Andric break; 172281ad6265SDimitry Andric case ATTR_MIXED: 172381ad6265SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed); 172481ad6265SDimitry Andric StartBit = BitIndex; 172581ad6265SDimitry Andric RA = ATTR_MIXED; 172681ad6265SDimitry Andric break; 172781ad6265SDimitry Andric default: 172881ad6265SDimitry Andric llvm_unreachable("Unexpected bitAttr!"); 172981ad6265SDimitry Andric } 173081ad6265SDimitry Andric break; 173181ad6265SDimitry Andric case ATTR_MIXED: 173281ad6265SDimitry Andric switch (bitAttr) { 173381ad6265SDimitry Andric case ATTR_FILTERED: 173481ad6265SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed); 173581ad6265SDimitry Andric StartBit = BitIndex; 173681ad6265SDimitry Andric RA = ATTR_NONE; 173781ad6265SDimitry Andric break; 173881ad6265SDimitry Andric case ATTR_ALL_SET: 173981ad6265SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed); 174081ad6265SDimitry Andric StartBit = BitIndex; 174181ad6265SDimitry Andric RA = ATTR_ALL_SET; 174281ad6265SDimitry Andric break; 174381ad6265SDimitry Andric case ATTR_ALL_UNSET: 174481ad6265SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed); 174581ad6265SDimitry Andric RA = ATTR_NONE; 174681ad6265SDimitry Andric break; 174781ad6265SDimitry Andric case ATTR_MIXED: 174881ad6265SDimitry Andric break; 174981ad6265SDimitry Andric default: 175081ad6265SDimitry Andric llvm_unreachable("Unexpected bitAttr!"); 175181ad6265SDimitry Andric } 175281ad6265SDimitry Andric break; 175381ad6265SDimitry Andric case ATTR_ALL_UNSET: 175481ad6265SDimitry Andric llvm_unreachable("regionAttr state machine has no ATTR_UNSET state"); 175581ad6265SDimitry Andric case ATTR_FILTERED: 175681ad6265SDimitry Andric llvm_unreachable("regionAttr state machine has no ATTR_FILTERED state"); 175781ad6265SDimitry Andric } 175881ad6265SDimitry Andric } 175981ad6265SDimitry Andric 176081ad6265SDimitry Andric // At the end, if we're still in ALL_SET or MIXED states, report a region 176181ad6265SDimitry Andric switch (RA) { 176281ad6265SDimitry Andric case ATTR_NONE: 176381ad6265SDimitry Andric break; 176481ad6265SDimitry Andric case ATTR_FILTERED: 176581ad6265SDimitry Andric break; 176681ad6265SDimitry Andric case ATTR_ALL_SET: 176781ad6265SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed); 176881ad6265SDimitry Andric break; 176981ad6265SDimitry Andric case ATTR_ALL_UNSET: 177081ad6265SDimitry Andric break; 177181ad6265SDimitry Andric case ATTR_MIXED: 177281ad6265SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed); 177381ad6265SDimitry Andric break; 177481ad6265SDimitry Andric } 177581ad6265SDimitry Andric 177681ad6265SDimitry Andric // We have finished with the filter processings. Now it's time to choose 177781ad6265SDimitry Andric // the best performing filter. 177881ad6265SDimitry Andric BestIndex = 0; 177981ad6265SDimitry Andric bool AllUseless = true; 178081ad6265SDimitry Andric unsigned BestScore = 0; 178181ad6265SDimitry Andric 1782*0fca6ea1SDimitry Andric for (const auto &[Idx, Filter] : enumerate(Filters)) { 1783*0fca6ea1SDimitry Andric unsigned Usefulness = Filter.usefulness(); 178481ad6265SDimitry Andric 178581ad6265SDimitry Andric if (Usefulness) 178681ad6265SDimitry Andric AllUseless = false; 178781ad6265SDimitry Andric 178881ad6265SDimitry Andric if (Usefulness > BestScore) { 1789*0fca6ea1SDimitry Andric BestIndex = Idx; 179081ad6265SDimitry Andric BestScore = Usefulness; 179181ad6265SDimitry Andric } 179281ad6265SDimitry Andric } 179381ad6265SDimitry Andric 179481ad6265SDimitry Andric if (!AllUseless) 179581ad6265SDimitry Andric bestFilter().recurse(); 179681ad6265SDimitry Andric 179781ad6265SDimitry Andric return !AllUseless; 179881ad6265SDimitry Andric } // end of FilterChooser::filterProcessor(bool) 179981ad6265SDimitry Andric 180081ad6265SDimitry Andric // Decides on the best configuration of filter(s) to use in order to decode 180181ad6265SDimitry Andric // the instructions. A conflict of instructions may occur, in which case we 180281ad6265SDimitry Andric // dump the conflict set to the standard error. 180381ad6265SDimitry Andric void FilterChooser::doFilter() { 180481ad6265SDimitry Andric unsigned Num = Opcodes.size(); 180581ad6265SDimitry Andric assert(Num && "FilterChooser created with no instructions"); 180681ad6265SDimitry Andric 180781ad6265SDimitry Andric // Try regions of consecutive known bit values first. 180881ad6265SDimitry Andric if (filterProcessor(false)) 180981ad6265SDimitry Andric return; 181081ad6265SDimitry Andric 181181ad6265SDimitry Andric // Then regions of mixed bits (both known and unitialized bit values allowed). 181281ad6265SDimitry Andric if (filterProcessor(true)) 181381ad6265SDimitry Andric return; 181481ad6265SDimitry Andric 181581ad6265SDimitry Andric // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where 181681ad6265SDimitry Andric // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a 181781ad6265SDimitry Andric // well-known encoding pattern. In such case, we backtrack and scan for the 181881ad6265SDimitry Andric // the very first consecutive ATTR_ALL_SET region and assign a filter to it. 181981ad6265SDimitry Andric if (Num == 3 && filterProcessor(true, false)) 182081ad6265SDimitry Andric return; 182181ad6265SDimitry Andric 182281ad6265SDimitry Andric // If we come to here, the instruction decoding has failed. 182381ad6265SDimitry Andric // Set the BestIndex to -1 to indicate so. 182481ad6265SDimitry Andric BestIndex = -1; 182581ad6265SDimitry Andric } 182681ad6265SDimitry Andric 182781ad6265SDimitry Andric // emitTableEntries - Emit state machine entries to decode our share of 182881ad6265SDimitry Andric // instructions. 182981ad6265SDimitry Andric void FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const { 183081ad6265SDimitry Andric if (Opcodes.size() == 1) { 183181ad6265SDimitry Andric // There is only one instruction in the set, which is great! 183281ad6265SDimitry Andric // Call emitSingletonDecoder() to see whether there are any remaining 183381ad6265SDimitry Andric // encodings bits. 183481ad6265SDimitry Andric emitSingletonTableEntry(TableInfo, Opcodes[0]); 183581ad6265SDimitry Andric return; 183681ad6265SDimitry Andric } 183781ad6265SDimitry Andric 183881ad6265SDimitry Andric // Choose the best filter to do the decodings! 183981ad6265SDimitry Andric if (BestIndex != -1) { 184081ad6265SDimitry Andric const Filter &Best = Filters[BestIndex]; 184181ad6265SDimitry Andric if (Best.getNumFiltered() == 1) 184281ad6265SDimitry Andric emitSingletonTableEntry(TableInfo, Best); 184381ad6265SDimitry Andric else 184481ad6265SDimitry Andric Best.emitTableEntry(TableInfo); 184581ad6265SDimitry Andric return; 184681ad6265SDimitry Andric } 184781ad6265SDimitry Andric 184881ad6265SDimitry Andric // We don't know how to decode these instructions! Dump the 184981ad6265SDimitry Andric // conflict set and bail. 185081ad6265SDimitry Andric 185181ad6265SDimitry Andric // Print out useful conflict information for postmortem analysis. 185281ad6265SDimitry Andric errs() << "Decoding Conflict:\n"; 185381ad6265SDimitry Andric 185481ad6265SDimitry Andric dumpStack(errs(), "\t\t"); 185581ad6265SDimitry Andric 185681ad6265SDimitry Andric for (auto Opcode : Opcodes) { 185781ad6265SDimitry Andric errs() << '\t'; 185881ad6265SDimitry Andric emitNameWithID(errs(), Opcode.EncodingID); 185981ad6265SDimitry Andric errs() << " "; 186081ad6265SDimitry Andric dumpBits( 186181ad6265SDimitry Andric errs(), 186281ad6265SDimitry Andric getBitsField(*AllInstructions[Opcode.EncodingID].EncodingDef, "Inst")); 186381ad6265SDimitry Andric errs() << '\n'; 186481ad6265SDimitry Andric } 186581ad6265SDimitry Andric } 186681ad6265SDimitry Andric 186781ad6265SDimitry Andric static std::string findOperandDecoderMethod(Record *Record) { 186881ad6265SDimitry Andric std::string Decoder; 186981ad6265SDimitry Andric 187081ad6265SDimitry Andric RecordVal *DecoderString = Record->getValue("DecoderMethod"); 1871*0fca6ea1SDimitry Andric StringInit *String = 1872*0fca6ea1SDimitry Andric DecoderString ? dyn_cast<StringInit>(DecoderString->getValue()) : nullptr; 187381ad6265SDimitry Andric if (String) { 187481ad6265SDimitry Andric Decoder = std::string(String->getValue()); 187581ad6265SDimitry Andric if (!Decoder.empty()) 187681ad6265SDimitry Andric return Decoder; 187781ad6265SDimitry Andric } 187881ad6265SDimitry Andric 187981ad6265SDimitry Andric if (Record->isSubClassOf("RegisterOperand")) 1880*0fca6ea1SDimitry Andric // Allows use of a DecoderMethod in referenced RegisterClass if set. 1881*0fca6ea1SDimitry Andric return findOperandDecoderMethod(Record->getValueAsDef("RegClass")); 188281ad6265SDimitry Andric 188381ad6265SDimitry Andric if (Record->isSubClassOf("RegisterClass")) { 188481ad6265SDimitry Andric Decoder = "Decode" + Record->getName().str() + "RegisterClass"; 188581ad6265SDimitry Andric } else if (Record->isSubClassOf("PointerLikeRegClass")) { 188681ad6265SDimitry Andric Decoder = "DecodePointerLikeRegClass" + 188781ad6265SDimitry Andric utostr(Record->getValueAsInt("RegClassKind")); 188881ad6265SDimitry Andric } 188981ad6265SDimitry Andric 189081ad6265SDimitry Andric return Decoder; 189181ad6265SDimitry Andric } 189281ad6265SDimitry Andric 189381ad6265SDimitry Andric OperandInfo getOpInfo(Record *TypeRecord) { 189481ad6265SDimitry Andric std::string Decoder = findOperandDecoderMethod(TypeRecord); 189581ad6265SDimitry Andric 189681ad6265SDimitry Andric RecordVal *HasCompleteDecoderVal = TypeRecord->getValue("hasCompleteDecoder"); 189781ad6265SDimitry Andric BitInit *HasCompleteDecoderBit = 189881ad6265SDimitry Andric HasCompleteDecoderVal 189981ad6265SDimitry Andric ? dyn_cast<BitInit>(HasCompleteDecoderVal->getValue()) 190081ad6265SDimitry Andric : nullptr; 190181ad6265SDimitry Andric bool HasCompleteDecoder = 190281ad6265SDimitry Andric HasCompleteDecoderBit ? HasCompleteDecoderBit->getValue() : true; 190381ad6265SDimitry Andric 190481ad6265SDimitry Andric return OperandInfo(Decoder, HasCompleteDecoder); 190581ad6265SDimitry Andric } 190681ad6265SDimitry Andric 190781ad6265SDimitry Andric void parseVarLenInstOperand(const Record &Def, 190881ad6265SDimitry Andric std::vector<OperandInfo> &Operands, 190981ad6265SDimitry Andric const CodeGenInstruction &CGI) { 191081ad6265SDimitry Andric 191181ad6265SDimitry Andric const RecordVal *RV = Def.getValue("Inst"); 191281ad6265SDimitry Andric VarLenInst VLI(cast<DagInit>(RV->getValue()), RV); 191381ad6265SDimitry Andric SmallVector<int> TiedTo; 191481ad6265SDimitry Andric 1915*0fca6ea1SDimitry Andric for (const auto &[Idx, Op] : enumerate(CGI.Operands)) { 191681ad6265SDimitry Andric if (Op.MIOperandInfo && Op.MIOperandInfo->getNumArgs() > 0) 191781ad6265SDimitry Andric for (auto *Arg : Op.MIOperandInfo->getArgs()) 191881ad6265SDimitry Andric Operands.push_back(getOpInfo(cast<DefInit>(Arg)->getDef())); 191981ad6265SDimitry Andric else 192081ad6265SDimitry Andric Operands.push_back(getOpInfo(Op.Rec)); 192181ad6265SDimitry Andric 192281ad6265SDimitry Andric int TiedReg = Op.getTiedRegister(); 192381ad6265SDimitry Andric TiedTo.push_back(-1); 192481ad6265SDimitry Andric if (TiedReg != -1) { 192581ad6265SDimitry Andric TiedTo[Idx] = TiedReg; 192681ad6265SDimitry Andric TiedTo[TiedReg] = Idx; 192781ad6265SDimitry Andric } 192881ad6265SDimitry Andric } 192981ad6265SDimitry Andric 193081ad6265SDimitry Andric unsigned CurrBitPos = 0; 1931*0fca6ea1SDimitry Andric for (const auto &EncodingSegment : VLI) { 193281ad6265SDimitry Andric unsigned Offset = 0; 193381ad6265SDimitry Andric StringRef OpName; 193481ad6265SDimitry Andric 193581ad6265SDimitry Andric if (const StringInit *SI = dyn_cast<StringInit>(EncodingSegment.Value)) { 193681ad6265SDimitry Andric OpName = SI->getValue(); 193781ad6265SDimitry Andric } else if (const DagInit *DI = dyn_cast<DagInit>(EncodingSegment.Value)) { 193881ad6265SDimitry Andric OpName = cast<StringInit>(DI->getArg(0))->getValue(); 193981ad6265SDimitry Andric Offset = cast<IntInit>(DI->getArg(2))->getValue(); 194081ad6265SDimitry Andric } 194181ad6265SDimitry Andric 194281ad6265SDimitry Andric if (!OpName.empty()) { 194381ad6265SDimitry Andric auto OpSubOpPair = 194481ad6265SDimitry Andric const_cast<CodeGenInstruction &>(CGI).Operands.ParseOperandName( 194581ad6265SDimitry Andric OpName); 194681ad6265SDimitry Andric unsigned OpIdx = CGI.Operands.getFlattenedOperandNumber(OpSubOpPair); 194781ad6265SDimitry Andric Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset); 1948bdd1243dSDimitry Andric if (!EncodingSegment.CustomDecoder.empty()) 1949bdd1243dSDimitry Andric Operands[OpIdx].Decoder = EncodingSegment.CustomDecoder.str(); 195081ad6265SDimitry Andric 195181ad6265SDimitry Andric int TiedReg = TiedTo[OpSubOpPair.first]; 195281ad6265SDimitry Andric if (TiedReg != -1) { 195381ad6265SDimitry Andric unsigned OpIdx = CGI.Operands.getFlattenedOperandNumber( 1954*0fca6ea1SDimitry Andric std::pair(TiedReg, OpSubOpPair.second)); 195581ad6265SDimitry Andric Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset); 195681ad6265SDimitry Andric } 195781ad6265SDimitry Andric } 195881ad6265SDimitry Andric 195981ad6265SDimitry Andric CurrBitPos += EncodingSegment.BitWidth; 196081ad6265SDimitry Andric } 196181ad6265SDimitry Andric } 196281ad6265SDimitry Andric 1963bdd1243dSDimitry Andric static void debugDumpRecord(const Record &Rec) { 1964bdd1243dSDimitry Andric // Dump the record, so we can see what's going on... 1965bdd1243dSDimitry Andric std::string E; 1966bdd1243dSDimitry Andric raw_string_ostream S(E); 1967bdd1243dSDimitry Andric S << "Dumping record for previous error:\n"; 1968bdd1243dSDimitry Andric S << Rec; 1969bdd1243dSDimitry Andric PrintNote(E); 1970bdd1243dSDimitry Andric } 1971bdd1243dSDimitry Andric 1972bdd1243dSDimitry Andric /// For an operand field named OpName: populate OpInfo.InitValue with the 1973bdd1243dSDimitry Andric /// constant-valued bit values, and OpInfo.Fields with the ranges of bits to 1974bdd1243dSDimitry Andric /// insert from the decoded instruction. 1975bdd1243dSDimitry Andric static void addOneOperandFields(const Record &EncodingDef, const BitsInit &Bits, 1976bdd1243dSDimitry Andric std::map<std::string, std::string> &TiedNames, 1977bdd1243dSDimitry Andric StringRef OpName, OperandInfo &OpInfo) { 1978bdd1243dSDimitry Andric // Some bits of the operand may be required to be 1 depending on the 1979bdd1243dSDimitry Andric // instruction's encoding. Collect those bits. 1980bdd1243dSDimitry Andric if (const RecordVal *EncodedValue = EncodingDef.getValue(OpName)) 1981bdd1243dSDimitry Andric if (const BitsInit *OpBits = dyn_cast<BitsInit>(EncodedValue->getValue())) 1982bdd1243dSDimitry Andric for (unsigned I = 0; I < OpBits->getNumBits(); ++I) 1983bdd1243dSDimitry Andric if (const BitInit *OpBit = dyn_cast<BitInit>(OpBits->getBit(I))) 1984bdd1243dSDimitry Andric if (OpBit->getValue()) 1985bdd1243dSDimitry Andric OpInfo.InitValue |= 1ULL << I; 1986bdd1243dSDimitry Andric 1987bdd1243dSDimitry Andric for (unsigned I = 0, J = 0; I != Bits.getNumBits(); I = J) { 1988bdd1243dSDimitry Andric VarInit *Var; 1989bdd1243dSDimitry Andric unsigned Offset = 0; 1990bdd1243dSDimitry Andric for (; J != Bits.getNumBits(); ++J) { 1991bdd1243dSDimitry Andric VarBitInit *BJ = dyn_cast<VarBitInit>(Bits.getBit(J)); 1992bdd1243dSDimitry Andric if (BJ) { 1993bdd1243dSDimitry Andric Var = dyn_cast<VarInit>(BJ->getBitVar()); 1994bdd1243dSDimitry Andric if (I == J) 1995bdd1243dSDimitry Andric Offset = BJ->getBitNum(); 1996bdd1243dSDimitry Andric else if (BJ->getBitNum() != Offset + J - I) 1997bdd1243dSDimitry Andric break; 1998bdd1243dSDimitry Andric } else { 1999bdd1243dSDimitry Andric Var = dyn_cast<VarInit>(Bits.getBit(J)); 2000bdd1243dSDimitry Andric } 2001bdd1243dSDimitry Andric if (!Var || (Var->getName() != OpName && 2002bdd1243dSDimitry Andric Var->getName() != TiedNames[std::string(OpName)])) 2003bdd1243dSDimitry Andric break; 2004bdd1243dSDimitry Andric } 2005bdd1243dSDimitry Andric if (I == J) 2006bdd1243dSDimitry Andric ++J; 2007bdd1243dSDimitry Andric else 2008bdd1243dSDimitry Andric OpInfo.addField(I, J - I, Offset); 2009bdd1243dSDimitry Andric } 2010bdd1243dSDimitry Andric } 2011bdd1243dSDimitry Andric 201281ad6265SDimitry Andric static unsigned 201381ad6265SDimitry Andric populateInstruction(CodeGenTarget &Target, const Record &EncodingDef, 201481ad6265SDimitry Andric const CodeGenInstruction &CGI, unsigned Opc, 201581ad6265SDimitry Andric std::map<unsigned, std::vector<OperandInfo>> &Operands, 201681ad6265SDimitry Andric bool IsVarLenInst) { 201781ad6265SDimitry Andric const Record &Def = *CGI.TheDef; 201881ad6265SDimitry Andric // If all the bit positions are not specified; do not decode this instruction. 201981ad6265SDimitry Andric // We are bound to fail! For proper disassembly, the well-known encoding bits 202081ad6265SDimitry Andric // of the instruction must be fully specified. 202181ad6265SDimitry Andric 202281ad6265SDimitry Andric BitsInit &Bits = getBitsField(EncodingDef, "Inst"); 202381ad6265SDimitry Andric if (Bits.allInComplete()) 202481ad6265SDimitry Andric return 0; 202581ad6265SDimitry Andric 202681ad6265SDimitry Andric std::vector<OperandInfo> InsnOperands; 202781ad6265SDimitry Andric 202881ad6265SDimitry Andric // If the instruction has specified a custom decoding hook, use that instead 202981ad6265SDimitry Andric // of trying to auto-generate the decoder. 203081ad6265SDimitry Andric StringRef InstDecoder = EncodingDef.getValueAsString("DecoderMethod"); 203181ad6265SDimitry Andric if (InstDecoder != "") { 2032*0fca6ea1SDimitry Andric bool HasCompleteInstDecoder = 2033*0fca6ea1SDimitry Andric EncodingDef.getValueAsBit("hasCompleteDecoder"); 203481ad6265SDimitry Andric InsnOperands.push_back( 203581ad6265SDimitry Andric OperandInfo(std::string(InstDecoder), HasCompleteInstDecoder)); 203681ad6265SDimitry Andric Operands[Opc] = InsnOperands; 203781ad6265SDimitry Andric return Bits.getNumBits(); 203881ad6265SDimitry Andric } 203981ad6265SDimitry Andric 204081ad6265SDimitry Andric // Generate a description of the operand of the instruction that we know 204181ad6265SDimitry Andric // how to decode automatically. 204281ad6265SDimitry Andric // FIXME: We'll need to have a way to manually override this as needed. 204381ad6265SDimitry Andric 204481ad6265SDimitry Andric // Gather the outputs/inputs of the instruction, so we can find their 204581ad6265SDimitry Andric // positions in the encoding. This assumes for now that they appear in the 204681ad6265SDimitry Andric // MCInst in the order that they're listed. 204781ad6265SDimitry Andric std::vector<std::pair<Init *, StringRef>> InOutOperands; 204881ad6265SDimitry Andric DagInit *Out = Def.getValueAsDag("OutOperandList"); 204981ad6265SDimitry Andric DagInit *In = Def.getValueAsDag("InOperandList"); 2050*0fca6ea1SDimitry Andric for (const auto &[Idx, Arg] : enumerate(Out->getArgs())) 2051*0fca6ea1SDimitry Andric InOutOperands.push_back(std::pair(Arg, Out->getArgNameStr(Idx))); 2052*0fca6ea1SDimitry Andric for (const auto &[Idx, Arg] : enumerate(In->getArgs())) 2053*0fca6ea1SDimitry Andric InOutOperands.push_back(std::pair(Arg, In->getArgNameStr(Idx))); 205481ad6265SDimitry Andric 205581ad6265SDimitry Andric // Search for tied operands, so that we can correctly instantiate 205681ad6265SDimitry Andric // operands that are not explicitly represented in the encoding. 205781ad6265SDimitry Andric std::map<std::string, std::string> TiedNames; 2058*0fca6ea1SDimitry Andric for (const auto &[I, Op] : enumerate(CGI.Operands)) { 2059*0fca6ea1SDimitry Andric for (const auto &[J, CI] : enumerate(Op.Constraints)) { 2060bdd1243dSDimitry Andric if (CI.isTied()) { 206181ad6265SDimitry Andric std::pair<unsigned, unsigned> SO = 2062*0fca6ea1SDimitry Andric CGI.Operands.getSubOperandNumber(CI.getTiedOperand()); 2063bdd1243dSDimitry Andric std::string TiedName = CGI.Operands[SO.first].SubOpNames[SO.second]; 2064bdd1243dSDimitry Andric if (TiedName.empty()) 2065bdd1243dSDimitry Andric TiedName = CGI.Operands[SO.first].Name; 2066*0fca6ea1SDimitry Andric std::string MyName = Op.SubOpNames[J]; 2067bdd1243dSDimitry Andric if (MyName.empty()) 2068bdd1243dSDimitry Andric MyName = Op.Name; 2069bdd1243dSDimitry Andric 2070bdd1243dSDimitry Andric TiedNames[MyName] = TiedName; 2071bdd1243dSDimitry Andric TiedNames[TiedName] = MyName; 2072bdd1243dSDimitry Andric } 207381ad6265SDimitry Andric } 207481ad6265SDimitry Andric } 207581ad6265SDimitry Andric 207681ad6265SDimitry Andric if (IsVarLenInst) { 207781ad6265SDimitry Andric parseVarLenInstOperand(EncodingDef, InsnOperands, CGI); 207881ad6265SDimitry Andric } else { 207981ad6265SDimitry Andric // For each operand, see if we can figure out where it is encoded. 208081ad6265SDimitry Andric for (const auto &Op : InOutOperands) { 2081bdd1243dSDimitry Andric Init *OpInit = Op.first; 2082bdd1243dSDimitry Andric StringRef OpName = Op.second; 2083bdd1243dSDimitry Andric 2084*0fca6ea1SDimitry Andric // We're ready to find the instruction encoding locations for this 2085*0fca6ea1SDimitry Andric // operand. 208681ad6265SDimitry Andric 2087bdd1243dSDimitry Andric // First, find the operand type ("OpInit"), and sub-op names 2088bdd1243dSDimitry Andric // ("SubArgDag") if present. 2089bdd1243dSDimitry Andric DagInit *SubArgDag = dyn_cast<DagInit>(OpInit); 2090bdd1243dSDimitry Andric if (SubArgDag) 2091bdd1243dSDimitry Andric OpInit = SubArgDag->getOperator(); 2092bdd1243dSDimitry Andric Record *OpTypeRec = cast<DefInit>(OpInit)->getDef(); 2093bdd1243dSDimitry Andric // Lookup the sub-operands from the operand type record (note that only 2094bdd1243dSDimitry Andric // Operand subclasses have MIOperandInfo, see CodeGenInstruction.cpp). 2095bdd1243dSDimitry Andric DagInit *SubOps = OpTypeRec->isSubClassOf("Operand") 2096bdd1243dSDimitry Andric ? OpTypeRec->getValueAsDag("MIOperandInfo") 2097bdd1243dSDimitry Andric : nullptr; 209881ad6265SDimitry Andric 2099*0fca6ea1SDimitry Andric // Lookup the decoder method and construct a new OperandInfo to hold our 2100*0fca6ea1SDimitry Andric // result. 2101bdd1243dSDimitry Andric OperandInfo OpInfo = getOpInfo(OpTypeRec); 210281ad6265SDimitry Andric 2103bdd1243dSDimitry Andric // If we have named sub-operands... 2104bdd1243dSDimitry Andric if (SubArgDag) { 2105bdd1243dSDimitry Andric // Then there should not be a custom decoder specified on the top-level 2106bdd1243dSDimitry Andric // type. 2107bdd1243dSDimitry Andric if (!OpInfo.Decoder.empty()) { 2108bdd1243dSDimitry Andric PrintError(EncodingDef.getLoc(), 2109bdd1243dSDimitry Andric "DecoderEmitter: operand \"" + OpName + "\" has type \"" + 2110bdd1243dSDimitry Andric OpInit->getAsString() + 2111bdd1243dSDimitry Andric "\" with a custom DecoderMethod, but also named " 2112bdd1243dSDimitry Andric "sub-operands."); 2113bdd1243dSDimitry Andric continue; 2114bdd1243dSDimitry Andric } 211581ad6265SDimitry Andric 2116bdd1243dSDimitry Andric // Decode each of the sub-ops separately. 2117bdd1243dSDimitry Andric assert(SubOps && SubArgDag->getNumArgs() == SubOps->getNumArgs()); 2118*0fca6ea1SDimitry Andric for (const auto &[I, Arg] : enumerate(SubOps->getArgs())) { 2119*0fca6ea1SDimitry Andric StringRef SubOpName = SubArgDag->getArgNameStr(I); 2120*0fca6ea1SDimitry Andric OperandInfo SubOpInfo = getOpInfo(cast<DefInit>(Arg)->getDef()); 212181ad6265SDimitry Andric 2122bdd1243dSDimitry Andric addOneOperandFields(EncodingDef, Bits, TiedNames, SubOpName, 2123bdd1243dSDimitry Andric SubOpInfo); 2124bdd1243dSDimitry Andric InsnOperands.push_back(SubOpInfo); 212581ad6265SDimitry Andric } 212681ad6265SDimitry Andric continue; 212781ad6265SDimitry Andric } 212881ad6265SDimitry Andric 2129bdd1243dSDimitry Andric // Otherwise, if we have an operand with sub-operands, but they aren't 2130bdd1243dSDimitry Andric // named... 2131bdd1243dSDimitry Andric if (SubOps && OpInfo.Decoder.empty()) { 2132bdd1243dSDimitry Andric // If it's a single sub-operand, and no custom decoder, use the decoder 2133bdd1243dSDimitry Andric // from the one sub-operand. 2134bdd1243dSDimitry Andric if (SubOps->getNumArgs() == 1) 2135bdd1243dSDimitry Andric OpInfo = getOpInfo(cast<DefInit>(SubOps->getArg(0))->getDef()); 2136bdd1243dSDimitry Andric 2137bdd1243dSDimitry Andric // If we have multiple sub-ops, there'd better have a custom 2138bdd1243dSDimitry Andric // decoder. (Otherwise we don't know how to populate them properly...) 2139bdd1243dSDimitry Andric if (SubOps->getNumArgs() > 1) { 2140bdd1243dSDimitry Andric PrintError(EncodingDef.getLoc(), 2141bdd1243dSDimitry Andric "DecoderEmitter: operand \"" + OpName + 2142bdd1243dSDimitry Andric "\" uses MIOperandInfo with multiple ops, but doesn't " 2143bdd1243dSDimitry Andric "have a custom decoder!"); 2144bdd1243dSDimitry Andric debugDumpRecord(EncodingDef); 214581ad6265SDimitry Andric continue; 214681ad6265SDimitry Andric } 214781ad6265SDimitry Andric } 214881ad6265SDimitry Andric 2149bdd1243dSDimitry Andric addOneOperandFields(EncodingDef, Bits, TiedNames, OpName, OpInfo); 2150bdd1243dSDimitry Andric // FIXME: it should be an error not to find a definition for a given 2151bdd1243dSDimitry Andric // operand, rather than just failing to add it to the resulting 2152bdd1243dSDimitry Andric // instruction! (This is a longstanding bug, which will be addressed in an 2153bdd1243dSDimitry Andric // upcoming change.) 215481ad6265SDimitry Andric if (OpInfo.numFields() > 0) 215581ad6265SDimitry Andric InsnOperands.push_back(OpInfo); 215681ad6265SDimitry Andric } 215781ad6265SDimitry Andric } 215881ad6265SDimitry Andric Operands[Opc] = InsnOperands; 215981ad6265SDimitry Andric 216081ad6265SDimitry Andric #if 0 216181ad6265SDimitry Andric LLVM_DEBUG({ 216281ad6265SDimitry Andric // Dumps the instruction encoding bits. 216381ad6265SDimitry Andric dumpBits(errs(), Bits); 216481ad6265SDimitry Andric 216581ad6265SDimitry Andric errs() << '\n'; 216681ad6265SDimitry Andric 216781ad6265SDimitry Andric // Dumps the list of operand info. 216881ad6265SDimitry Andric for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) { 216981ad6265SDimitry Andric const CGIOperandList::OperandInfo &Info = CGI.Operands[i]; 217081ad6265SDimitry Andric const std::string &OperandName = Info.Name; 217181ad6265SDimitry Andric const Record &OperandDef = *Info.Rec; 217281ad6265SDimitry Andric 217381ad6265SDimitry Andric errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n"; 217481ad6265SDimitry Andric } 217581ad6265SDimitry Andric }); 217681ad6265SDimitry Andric #endif 217781ad6265SDimitry Andric 217881ad6265SDimitry Andric return Bits.getNumBits(); 217981ad6265SDimitry Andric } 218081ad6265SDimitry Andric 218181ad6265SDimitry Andric // emitFieldFromInstruction - Emit the templated helper function 218281ad6265SDimitry Andric // fieldFromInstruction(). 218381ad6265SDimitry Andric // On Windows we make sure that this function is not inlined when 218481ad6265SDimitry Andric // using the VS compiler. It has a bug which causes the function 2185bdd1243dSDimitry Andric // to be optimized out in some circumstances. See llvm.org/pr38292 218681ad6265SDimitry Andric static void emitFieldFromInstruction(formatted_raw_ostream &OS) { 2187*0fca6ea1SDimitry Andric OS << R"( 2188*0fca6ea1SDimitry Andric // Helper functions for extracting fields from encoded instructions. 2189*0fca6ea1SDimitry Andric // InsnType must either be integral or an APInt-like object that must: 2190*0fca6ea1SDimitry Andric // * be default-constructible and copy-constructible 2191*0fca6ea1SDimitry Andric // * be constructible from an APInt (this can be private) 2192*0fca6ea1SDimitry Andric // * Support insertBits(bits, startBit, numBits) 2193*0fca6ea1SDimitry Andric // * Support extractBitsAsZExtValue(numBits, startBit) 2194*0fca6ea1SDimitry Andric // * Support the ~, &, ==, and != operators with other objects of the same type 2195*0fca6ea1SDimitry Andric // * Support the != and bitwise & with uint64_t 2196*0fca6ea1SDimitry Andric // * Support put (<<) to raw_ostream& 2197*0fca6ea1SDimitry Andric template <typename InsnType> 2198*0fca6ea1SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__) 2199*0fca6ea1SDimitry Andric __declspec(noinline) 2200*0fca6ea1SDimitry Andric #endif 2201*0fca6ea1SDimitry Andric static std::enable_if_t<std::is_integral<InsnType>::value, InsnType> 2202*0fca6ea1SDimitry Andric fieldFromInstruction(const InsnType &insn, unsigned startBit, 2203*0fca6ea1SDimitry Andric unsigned numBits) { 2204*0fca6ea1SDimitry Andric assert(startBit + numBits <= 64 && "Cannot support >64-bit extractions!"); 2205*0fca6ea1SDimitry Andric assert(startBit + numBits <= (sizeof(InsnType) * 8) && 2206*0fca6ea1SDimitry Andric "Instruction field out of bounds!"); 2207*0fca6ea1SDimitry Andric InsnType fieldMask; 2208*0fca6ea1SDimitry Andric if (numBits == sizeof(InsnType) * 8) 2209*0fca6ea1SDimitry Andric fieldMask = (InsnType)(-1LL); 2210*0fca6ea1SDimitry Andric else 2211*0fca6ea1SDimitry Andric fieldMask = (((InsnType)1 << numBits) - 1) << startBit; 2212*0fca6ea1SDimitry Andric return (insn & fieldMask) >> startBit; 2213*0fca6ea1SDimitry Andric } 2214*0fca6ea1SDimitry Andric 2215*0fca6ea1SDimitry Andric template <typename InsnType> 2216*0fca6ea1SDimitry Andric static std::enable_if_t<!std::is_integral<InsnType>::value, uint64_t> 2217*0fca6ea1SDimitry Andric fieldFromInstruction(const InsnType &insn, unsigned startBit, 2218*0fca6ea1SDimitry Andric unsigned numBits) { 2219*0fca6ea1SDimitry Andric return insn.extractBitsAsZExtValue(numBits, startBit); 2220*0fca6ea1SDimitry Andric } 2221*0fca6ea1SDimitry Andric )"; 222281ad6265SDimitry Andric } 222381ad6265SDimitry Andric 222481ad6265SDimitry Andric // emitInsertBits - Emit the templated helper function insertBits(). 222581ad6265SDimitry Andric static void emitInsertBits(formatted_raw_ostream &OS) { 2226*0fca6ea1SDimitry Andric OS << R"( 2227*0fca6ea1SDimitry Andric // Helper function for inserting bits extracted from an encoded instruction into 2228*0fca6ea1SDimitry Andric // a field. 2229*0fca6ea1SDimitry Andric template <typename InsnType> 2230*0fca6ea1SDimitry Andric static std::enable_if_t<std::is_integral<InsnType>::value> 2231*0fca6ea1SDimitry Andric insertBits(InsnType &field, InsnType bits, unsigned startBit, unsigned numBits) { 2232*0fca6ea1SDimitry Andric assert(startBit + numBits <= sizeof field * 8); 2233*0fca6ea1SDimitry Andric field |= (InsnType)bits << startBit; 2234*0fca6ea1SDimitry Andric } 2235*0fca6ea1SDimitry Andric 2236*0fca6ea1SDimitry Andric template <typename InsnType> 2237*0fca6ea1SDimitry Andric static std::enable_if_t<!std::is_integral<InsnType>::value> 2238*0fca6ea1SDimitry Andric insertBits(InsnType &field, uint64_t bits, unsigned startBit, unsigned numBits) { 2239*0fca6ea1SDimitry Andric field.insertBits(bits, startBit, numBits); 2240*0fca6ea1SDimitry Andric } 2241*0fca6ea1SDimitry Andric )"; 224281ad6265SDimitry Andric } 224381ad6265SDimitry Andric 224481ad6265SDimitry Andric // emitDecodeInstruction - Emit the templated helper function 224581ad6265SDimitry Andric // decodeInstruction(). 224681ad6265SDimitry Andric static void emitDecodeInstruction(formatted_raw_ostream &OS, 224781ad6265SDimitry Andric bool IsVarLenInst) { 2248*0fca6ea1SDimitry Andric OS << R"( 2249*0fca6ea1SDimitry Andric template <typename InsnType> 2250*0fca6ea1SDimitry Andric static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI, 2251*0fca6ea1SDimitry Andric InsnType insn, uint64_t Address, 2252*0fca6ea1SDimitry Andric const MCDisassembler *DisAsm, 2253*0fca6ea1SDimitry Andric const MCSubtargetInfo &STI)"; 225481ad6265SDimitry Andric if (IsVarLenInst) { 225581ad6265SDimitry Andric OS << ",\n " 2256*0fca6ea1SDimitry Andric "llvm::function_ref<void(APInt &, uint64_t)> makeUp"; 225781ad6265SDimitry Andric } 2258*0fca6ea1SDimitry Andric OS << R"() { 2259*0fca6ea1SDimitry Andric const FeatureBitset &Bits = STI.getFeatureBits(); 2260*0fca6ea1SDimitry Andric 2261*0fca6ea1SDimitry Andric const uint8_t *Ptr = DecodeTable; 2262*0fca6ea1SDimitry Andric uint64_t CurFieldValue = 0; 2263*0fca6ea1SDimitry Andric DecodeStatus S = MCDisassembler::Success; 2264*0fca6ea1SDimitry Andric while (true) { 2265*0fca6ea1SDimitry Andric ptrdiff_t Loc = Ptr - DecodeTable; 2266*0fca6ea1SDimitry Andric switch (*Ptr) { 2267*0fca6ea1SDimitry Andric default: 2268*0fca6ea1SDimitry Andric errs() << Loc << ": Unexpected decode table opcode!\n"; 2269*0fca6ea1SDimitry Andric return MCDisassembler::Fail; 2270*0fca6ea1SDimitry Andric case MCD::OPC_ExtractField: { 2271*0fca6ea1SDimitry Andric // Decode the start value. 2272*0fca6ea1SDimitry Andric unsigned Start = decodeULEB128AndIncUnsafe(++Ptr); 2273*0fca6ea1SDimitry Andric unsigned Len = *Ptr++;)"; 227481ad6265SDimitry Andric if (IsVarLenInst) 2275*0fca6ea1SDimitry Andric OS << "\n makeUp(insn, Start + Len);"; 2276*0fca6ea1SDimitry Andric OS << R"( 2277*0fca6ea1SDimitry Andric CurFieldValue = fieldFromInstruction(insn, Start, Len); 2278*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_ExtractField(" << Start << ", " 2279*0fca6ea1SDimitry Andric << Len << "): " << CurFieldValue << "\n"); 2280*0fca6ea1SDimitry Andric break; 2281*0fca6ea1SDimitry Andric } 2282*0fca6ea1SDimitry Andric case MCD::OPC_FilterValue: { 2283*0fca6ea1SDimitry Andric // Decode the field value. 2284*0fca6ea1SDimitry Andric uint64_t Val = decodeULEB128AndIncUnsafe(++Ptr); 2285*0fca6ea1SDimitry Andric // NumToSkip is a plain 24-bit integer. 2286*0fca6ea1SDimitry Andric unsigned NumToSkip = *Ptr++; 2287*0fca6ea1SDimitry Andric NumToSkip |= (*Ptr++) << 8; 2288*0fca6ea1SDimitry Andric NumToSkip |= (*Ptr++) << 16; 2289*0fca6ea1SDimitry Andric 2290*0fca6ea1SDimitry Andric // Perform the filter operation. 2291*0fca6ea1SDimitry Andric if (Val != CurFieldValue) 2292*0fca6ea1SDimitry Andric Ptr += NumToSkip; 2293*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_FilterValue(" << Val << ", " << NumToSkip 2294*0fca6ea1SDimitry Andric << "): " << ((Val != CurFieldValue) ? "FAIL:" : "PASS:") 2295*0fca6ea1SDimitry Andric << " continuing at " << (Ptr - DecodeTable) << "\n"); 2296*0fca6ea1SDimitry Andric 2297*0fca6ea1SDimitry Andric break; 2298*0fca6ea1SDimitry Andric } 2299*0fca6ea1SDimitry Andric case MCD::OPC_CheckField: { 2300*0fca6ea1SDimitry Andric // Decode the start value. 2301*0fca6ea1SDimitry Andric unsigned Start = decodeULEB128AndIncUnsafe(++Ptr); 2302*0fca6ea1SDimitry Andric unsigned Len = *Ptr;)"; 230381ad6265SDimitry Andric if (IsVarLenInst) 2304*0fca6ea1SDimitry Andric OS << "\n makeUp(insn, Start + Len);"; 2305*0fca6ea1SDimitry Andric OS << R"( 2306*0fca6ea1SDimitry Andric uint64_t FieldValue = fieldFromInstruction(insn, Start, Len); 2307*0fca6ea1SDimitry Andric // Decode the field value. 2308*0fca6ea1SDimitry Andric unsigned PtrLen = 0; 2309*0fca6ea1SDimitry Andric uint64_t ExpectedValue = decodeULEB128(++Ptr, &PtrLen); 2310*0fca6ea1SDimitry Andric Ptr += PtrLen; 2311*0fca6ea1SDimitry Andric // NumToSkip is a plain 24-bit integer. 2312*0fca6ea1SDimitry Andric unsigned NumToSkip = *Ptr++; 2313*0fca6ea1SDimitry Andric NumToSkip |= (*Ptr++) << 8; 2314*0fca6ea1SDimitry Andric NumToSkip |= (*Ptr++) << 16; 2315*0fca6ea1SDimitry Andric 2316*0fca6ea1SDimitry Andric // If the actual and expected values don't match, skip. 2317*0fca6ea1SDimitry Andric if (ExpectedValue != FieldValue) 2318*0fca6ea1SDimitry Andric Ptr += NumToSkip; 2319*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_CheckField(" << Start << ", " 2320*0fca6ea1SDimitry Andric << Len << ", " << ExpectedValue << ", " << NumToSkip 2321*0fca6ea1SDimitry Andric << "): FieldValue = " << FieldValue << ", ExpectedValue = " 2322*0fca6ea1SDimitry Andric << ExpectedValue << ": " 2323*0fca6ea1SDimitry Andric << ((ExpectedValue == FieldValue) ? "PASS\n" : "FAIL\n")); 2324*0fca6ea1SDimitry Andric break; 2325*0fca6ea1SDimitry Andric } 2326*0fca6ea1SDimitry Andric case MCD::OPC_CheckPredicate: { 2327*0fca6ea1SDimitry Andric // Decode the Predicate Index value. 2328*0fca6ea1SDimitry Andric unsigned PIdx = decodeULEB128AndIncUnsafe(++Ptr); 2329*0fca6ea1SDimitry Andric // NumToSkip is a plain 24-bit integer. 2330*0fca6ea1SDimitry Andric unsigned NumToSkip = *Ptr++; 2331*0fca6ea1SDimitry Andric NumToSkip |= (*Ptr++) << 8; 2332*0fca6ea1SDimitry Andric NumToSkip |= (*Ptr++) << 16; 2333*0fca6ea1SDimitry Andric // Check the predicate. 2334*0fca6ea1SDimitry Andric bool Pred; 2335*0fca6ea1SDimitry Andric if (!(Pred = checkDecoderPredicate(PIdx, Bits))) 2336*0fca6ea1SDimitry Andric Ptr += NumToSkip; 2337*0fca6ea1SDimitry Andric (void)Pred; 2338*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_CheckPredicate(" << PIdx << "): " 2339*0fca6ea1SDimitry Andric << (Pred ? "PASS\n" : "FAIL\n")); 2340*0fca6ea1SDimitry Andric 2341*0fca6ea1SDimitry Andric break; 2342*0fca6ea1SDimitry Andric } 2343*0fca6ea1SDimitry Andric case MCD::OPC_Decode: { 2344*0fca6ea1SDimitry Andric // Decode the Opcode value. 2345*0fca6ea1SDimitry Andric unsigned Opc = decodeULEB128AndIncUnsafe(++Ptr); 2346*0fca6ea1SDimitry Andric unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr); 2347*0fca6ea1SDimitry Andric 2348*0fca6ea1SDimitry Andric MI.clear(); 2349*0fca6ea1SDimitry Andric MI.setOpcode(Opc); 2350*0fca6ea1SDimitry Andric bool DecodeComplete;)"; 235181ad6265SDimitry Andric if (IsVarLenInst) { 2352*0fca6ea1SDimitry Andric OS << "\n unsigned Len = InstrLenTable[Opc];\n" 2353*0fca6ea1SDimitry Andric << " makeUp(insn, Len);"; 235481ad6265SDimitry Andric } 2355*0fca6ea1SDimitry Andric OS << R"( 2356*0fca6ea1SDimitry Andric S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, DecodeComplete); 2357*0fca6ea1SDimitry Andric assert(DecodeComplete); 2358*0fca6ea1SDimitry Andric 2359*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_Decode: opcode " << Opc 2360*0fca6ea1SDimitry Andric << ", using decoder " << DecodeIdx << ": " 2361*0fca6ea1SDimitry Andric << (S != MCDisassembler::Fail ? "PASS" : "FAIL") << "\n"); 2362*0fca6ea1SDimitry Andric return S; 2363*0fca6ea1SDimitry Andric } 2364*0fca6ea1SDimitry Andric case MCD::OPC_TryDecode: { 2365*0fca6ea1SDimitry Andric // Decode the Opcode value. 2366*0fca6ea1SDimitry Andric unsigned Opc = decodeULEB128AndIncUnsafe(++Ptr); 2367*0fca6ea1SDimitry Andric unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr); 2368*0fca6ea1SDimitry Andric // NumToSkip is a plain 24-bit integer. 2369*0fca6ea1SDimitry Andric unsigned NumToSkip = *Ptr++; 2370*0fca6ea1SDimitry Andric NumToSkip |= (*Ptr++) << 8; 2371*0fca6ea1SDimitry Andric NumToSkip |= (*Ptr++) << 16; 2372*0fca6ea1SDimitry Andric 2373*0fca6ea1SDimitry Andric // Perform the decode operation. 2374*0fca6ea1SDimitry Andric MCInst TmpMI; 2375*0fca6ea1SDimitry Andric TmpMI.setOpcode(Opc); 2376*0fca6ea1SDimitry Andric bool DecodeComplete; 2377*0fca6ea1SDimitry Andric S = decodeToMCInst(S, DecodeIdx, insn, TmpMI, Address, DisAsm, DecodeComplete); 2378*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_TryDecode: opcode " << Opc 2379*0fca6ea1SDimitry Andric << ", using decoder " << DecodeIdx << ": "); 2380*0fca6ea1SDimitry Andric 2381*0fca6ea1SDimitry Andric if (DecodeComplete) { 2382*0fca6ea1SDimitry Andric // Decoding complete. 2383*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << (S != MCDisassembler::Fail ? "PASS" : "FAIL") << "\n"); 2384*0fca6ea1SDimitry Andric MI = TmpMI; 2385*0fca6ea1SDimitry Andric return S; 2386*0fca6ea1SDimitry Andric } else { 2387*0fca6ea1SDimitry Andric assert(S == MCDisassembler::Fail); 2388*0fca6ea1SDimitry Andric // If the decoding was incomplete, skip. 2389*0fca6ea1SDimitry Andric Ptr += NumToSkip; 2390*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << "FAIL: continuing at " << (Ptr - DecodeTable) << "\n"); 2391*0fca6ea1SDimitry Andric // Reset decode status. This also drops a SoftFail status that could be 2392*0fca6ea1SDimitry Andric // set before the decode attempt. 2393*0fca6ea1SDimitry Andric S = MCDisassembler::Success; 2394*0fca6ea1SDimitry Andric } 2395*0fca6ea1SDimitry Andric break; 2396*0fca6ea1SDimitry Andric } 2397*0fca6ea1SDimitry Andric case MCD::OPC_SoftFail: { 2398*0fca6ea1SDimitry Andric // Decode the mask values. 2399*0fca6ea1SDimitry Andric uint64_t PositiveMask = decodeULEB128AndIncUnsafe(++Ptr); 2400*0fca6ea1SDimitry Andric uint64_t NegativeMask = decodeULEB128AndIncUnsafe(Ptr); 2401*0fca6ea1SDimitry Andric bool Fail = (insn & PositiveMask) != 0 || (~insn & NegativeMask) != 0; 2402*0fca6ea1SDimitry Andric if (Fail) 2403*0fca6ea1SDimitry Andric S = MCDisassembler::SoftFail; 2404*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_SoftFail: " << (Fail ? "FAIL\n" : "PASS\n")); 2405*0fca6ea1SDimitry Andric break; 2406*0fca6ea1SDimitry Andric } 2407*0fca6ea1SDimitry Andric case MCD::OPC_Fail: { 2408*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_Fail\n"); 2409*0fca6ea1SDimitry Andric return MCDisassembler::Fail; 2410*0fca6ea1SDimitry Andric } 2411*0fca6ea1SDimitry Andric } 2412*0fca6ea1SDimitry Andric } 2413*0fca6ea1SDimitry Andric llvm_unreachable("bogosity detected in disassembler state machine!"); 2414*0fca6ea1SDimitry Andric } 2415*0fca6ea1SDimitry Andric 2416*0fca6ea1SDimitry Andric )"; 241781ad6265SDimitry Andric } 241881ad6265SDimitry Andric 2419bdd1243dSDimitry Andric // Helper to propagate SoftFail status. Returns false if the status is Fail; 2420bdd1243dSDimitry Andric // callers are expected to early-exit in that condition. (Note, the '&' operator 2421bdd1243dSDimitry Andric // is correct to propagate the values of this enum; see comment on 'enum 2422bdd1243dSDimitry Andric // DecodeStatus'.) 2423bdd1243dSDimitry Andric static void emitCheck(formatted_raw_ostream &OS) { 2424*0fca6ea1SDimitry Andric OS << R"( 2425*0fca6ea1SDimitry Andric static bool Check(DecodeStatus &Out, DecodeStatus In) { 2426*0fca6ea1SDimitry Andric Out = static_cast<DecodeStatus>(Out & In); 2427*0fca6ea1SDimitry Andric return Out != MCDisassembler::Fail; 2428*0fca6ea1SDimitry Andric } 2429*0fca6ea1SDimitry Andric 2430*0fca6ea1SDimitry Andric )"; 2431*0fca6ea1SDimitry Andric } 2432*0fca6ea1SDimitry Andric 2433*0fca6ea1SDimitry Andric // Collect all HwModes referenced by the target for encoding purposes, 2434*0fca6ea1SDimitry Andric // returning a vector of corresponding names. 2435*0fca6ea1SDimitry Andric static void collectHwModesReferencedForEncodings( 2436*0fca6ea1SDimitry Andric const CodeGenHwModes &HWM, std::vector<StringRef> &Names, 2437*0fca6ea1SDimitry Andric NamespacesHwModesMap &NamespacesWithHwModes) { 2438*0fca6ea1SDimitry Andric SmallBitVector BV(HWM.getNumModeIds()); 2439*0fca6ea1SDimitry Andric for (const auto &MS : HWM.getHwModeSelects()) { 2440*0fca6ea1SDimitry Andric for (const HwModeSelect::PairType &P : MS.second.Items) { 2441*0fca6ea1SDimitry Andric if (P.second->isSubClassOf("InstructionEncoding")) { 2442*0fca6ea1SDimitry Andric std::string DecoderNamespace = 2443*0fca6ea1SDimitry Andric std::string(P.second->getValueAsString("DecoderNamespace")); 2444*0fca6ea1SDimitry Andric if (P.first == DefaultMode) { 2445*0fca6ea1SDimitry Andric NamespacesWithHwModes[DecoderNamespace].insert(""); 2446*0fca6ea1SDimitry Andric } else { 2447*0fca6ea1SDimitry Andric NamespacesWithHwModes[DecoderNamespace].insert( 2448*0fca6ea1SDimitry Andric HWM.getMode(P.first).Name); 2449*0fca6ea1SDimitry Andric } 2450*0fca6ea1SDimitry Andric BV.set(P.first); 2451*0fca6ea1SDimitry Andric } 2452*0fca6ea1SDimitry Andric } 2453*0fca6ea1SDimitry Andric } 2454*0fca6ea1SDimitry Andric transform(BV.set_bits(), std::back_inserter(Names), [&HWM](const int &M) { 2455*0fca6ea1SDimitry Andric if (M == DefaultMode) 2456*0fca6ea1SDimitry Andric return StringRef(""); 2457*0fca6ea1SDimitry Andric return HWM.getModeName(M, /*IncludeDefault=*/true); 2458*0fca6ea1SDimitry Andric }); 2459*0fca6ea1SDimitry Andric } 2460*0fca6ea1SDimitry Andric 2461*0fca6ea1SDimitry Andric static void 2462*0fca6ea1SDimitry Andric handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr, 2463*0fca6ea1SDimitry Andric const std::vector<StringRef> &HwModeNames, 2464*0fca6ea1SDimitry Andric NamespacesHwModesMap &NamespacesWithHwModes, 2465*0fca6ea1SDimitry Andric std::vector<EncodingAndInst> &GlobalEncodings) { 2466*0fca6ea1SDimitry Andric const Record *InstDef = Instr->TheDef; 2467*0fca6ea1SDimitry Andric 2468*0fca6ea1SDimitry Andric switch (DecoderEmitterSuppressDuplicates) { 2469*0fca6ea1SDimitry Andric case SUPPRESSION_DISABLE: { 2470*0fca6ea1SDimitry Andric for (StringRef HwModeName : HwModeNames) 2471*0fca6ea1SDimitry Andric GlobalEncodings.emplace_back(InstDef, Instr, HwModeName); 2472*0fca6ea1SDimitry Andric break; 2473*0fca6ea1SDimitry Andric } 2474*0fca6ea1SDimitry Andric case SUPPRESSION_LEVEL1: { 2475*0fca6ea1SDimitry Andric std::string DecoderNamespace = 2476*0fca6ea1SDimitry Andric std::string(InstDef->getValueAsString("DecoderNamespace")); 2477*0fca6ea1SDimitry Andric auto It = NamespacesWithHwModes.find(DecoderNamespace); 2478*0fca6ea1SDimitry Andric if (It != NamespacesWithHwModes.end()) { 2479*0fca6ea1SDimitry Andric for (StringRef HwModeName : It->second) 2480*0fca6ea1SDimitry Andric GlobalEncodings.emplace_back(InstDef, Instr, HwModeName); 2481*0fca6ea1SDimitry Andric } else { 2482*0fca6ea1SDimitry Andric // Only emit the encoding once, as it's DecoderNamespace doesn't 2483*0fca6ea1SDimitry Andric // contain any HwModes. 2484*0fca6ea1SDimitry Andric GlobalEncodings.emplace_back(InstDef, Instr, ""); 2485*0fca6ea1SDimitry Andric } 2486*0fca6ea1SDimitry Andric break; 2487*0fca6ea1SDimitry Andric } 2488*0fca6ea1SDimitry Andric case SUPPRESSION_LEVEL2: 2489*0fca6ea1SDimitry Andric GlobalEncodings.emplace_back(InstDef, Instr, ""); 2490*0fca6ea1SDimitry Andric break; 2491*0fca6ea1SDimitry Andric } 2492bdd1243dSDimitry Andric } 2493bdd1243dSDimitry Andric 249481ad6265SDimitry Andric // Emits disassembler code for instruction decoding. 249581ad6265SDimitry Andric void DecoderEmitter::run(raw_ostream &o) { 249681ad6265SDimitry Andric formatted_raw_ostream OS(o); 2497*0fca6ea1SDimitry Andric OS << R"( 2498*0fca6ea1SDimitry Andric #include "llvm/MC/MCInst.h" 2499*0fca6ea1SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 2500*0fca6ea1SDimitry Andric #include "llvm/Support/DataTypes.h" 2501*0fca6ea1SDimitry Andric #include "llvm/Support/Debug.h" 2502*0fca6ea1SDimitry Andric #include "llvm/Support/LEB128.h" 2503*0fca6ea1SDimitry Andric #include "llvm/Support/raw_ostream.h" 2504*0fca6ea1SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h" 2505*0fca6ea1SDimitry Andric #include <assert.h> 2506*0fca6ea1SDimitry Andric 2507*0fca6ea1SDimitry Andric namespace llvm { 2508*0fca6ea1SDimitry Andric )"; 250981ad6265SDimitry Andric 251081ad6265SDimitry Andric emitFieldFromInstruction(OS); 251181ad6265SDimitry Andric emitInsertBits(OS); 2512bdd1243dSDimitry Andric emitCheck(OS); 251381ad6265SDimitry Andric 251481ad6265SDimitry Andric Target.reverseBitsForLittleEndianEncoding(); 251581ad6265SDimitry Andric 251681ad6265SDimitry Andric // Parameterize the decoders based on namespace and instruction width. 2517*0fca6ea1SDimitry Andric 2518*0fca6ea1SDimitry Andric // First, collect all encoding-related HwModes referenced by the target. 2519*0fca6ea1SDimitry Andric // And establish a mapping table between DecoderNamespace and HwMode. 2520*0fca6ea1SDimitry Andric // If HwModeNames is empty, add the empty string so we always have one HwMode. 2521*0fca6ea1SDimitry Andric const CodeGenHwModes &HWM = Target.getHwModes(); 2522*0fca6ea1SDimitry Andric std::vector<StringRef> HwModeNames; 2523*0fca6ea1SDimitry Andric NamespacesHwModesMap NamespacesWithHwModes; 2524*0fca6ea1SDimitry Andric collectHwModesReferencedForEncodings(HWM, HwModeNames, NamespacesWithHwModes); 2525*0fca6ea1SDimitry Andric if (HwModeNames.empty()) 2526*0fca6ea1SDimitry Andric HwModeNames.push_back(""); 2527*0fca6ea1SDimitry Andric 252881ad6265SDimitry Andric const auto &NumberedInstructions = Target.getInstructionsByEnumValue(); 252981ad6265SDimitry Andric NumberedEncodings.reserve(NumberedInstructions.size()); 253081ad6265SDimitry Andric for (const auto &NumberedInstruction : NumberedInstructions) { 2531*0fca6ea1SDimitry Andric const Record *InstDef = NumberedInstruction->TheDef; 2532*0fca6ea1SDimitry Andric if (const RecordVal *RV = InstDef->getValue("EncodingInfos")) { 253381ad6265SDimitry Andric if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) { 253481ad6265SDimitry Andric EncodingInfoByHwMode EBM(DI->getDef(), HWM); 2535*0fca6ea1SDimitry Andric for (auto &[ModeId, Encoding] : EBM) { 2536*0fca6ea1SDimitry Andric // DecoderTables with DefaultMode should not have any suffix. 2537*0fca6ea1SDimitry Andric if (ModeId == DefaultMode) { 2538*0fca6ea1SDimitry Andric NumberedEncodings.emplace_back(Encoding, NumberedInstruction, ""); 2539*0fca6ea1SDimitry Andric } else { 2540*0fca6ea1SDimitry Andric NumberedEncodings.emplace_back(Encoding, NumberedInstruction, 2541*0fca6ea1SDimitry Andric HWM.getMode(ModeId).Name); 2542*0fca6ea1SDimitry Andric } 254381ad6265SDimitry Andric } 254481ad6265SDimitry Andric continue; 254581ad6265SDimitry Andric } 254681ad6265SDimitry Andric } 2547*0fca6ea1SDimitry Andric // This instruction is encoded the same on all HwModes. 2548*0fca6ea1SDimitry Andric // According to user needs, provide varying degrees of suppression. 2549*0fca6ea1SDimitry Andric handleHwModesUnrelatedEncodings(NumberedInstruction, HwModeNames, 2550*0fca6ea1SDimitry Andric NamespacesWithHwModes, NumberedEncodings); 255181ad6265SDimitry Andric } 2552*0fca6ea1SDimitry Andric for (const auto &NumberedAlias : 2553*0fca6ea1SDimitry Andric RK.getAllDerivedDefinitions("AdditionalEncoding")) 255481ad6265SDimitry Andric NumberedEncodings.emplace_back( 255581ad6265SDimitry Andric NumberedAlias, 255681ad6265SDimitry Andric &Target.getInstruction(NumberedAlias->getValueAsDef("AliasOf"))); 255781ad6265SDimitry Andric 255881ad6265SDimitry Andric std::map<std::pair<std::string, unsigned>, std::vector<EncodingIDAndOpcode>> 255981ad6265SDimitry Andric OpcMap; 256081ad6265SDimitry Andric std::map<unsigned, std::vector<OperandInfo>> Operands; 256181ad6265SDimitry Andric std::vector<unsigned> InstrLen; 2562*0fca6ea1SDimitry Andric bool IsVarLenInst = Target.hasVariableLengthEncodings(); 256381ad6265SDimitry Andric unsigned MaxInstLen = 0; 256481ad6265SDimitry Andric 2565*0fca6ea1SDimitry Andric for (const auto &[NEI, NumberedEncoding] : enumerate(NumberedEncodings)) { 2566*0fca6ea1SDimitry Andric const Record *EncodingDef = NumberedEncoding.EncodingDef; 2567*0fca6ea1SDimitry Andric const CodeGenInstruction *Inst = NumberedEncoding.Inst; 256881ad6265SDimitry Andric const Record *Def = Inst->TheDef; 256981ad6265SDimitry Andric unsigned Size = EncodingDef->getValueAsInt("Size"); 257081ad6265SDimitry Andric if (Def->getValueAsString("Namespace") == "TargetOpcode" || 257181ad6265SDimitry Andric Def->getValueAsBit("isPseudo") || 257281ad6265SDimitry Andric Def->getValueAsBit("isAsmParserOnly") || 257381ad6265SDimitry Andric Def->getValueAsBit("isCodeGenOnly")) { 257481ad6265SDimitry Andric NumEncodingsLackingDisasm++; 257581ad6265SDimitry Andric continue; 257681ad6265SDimitry Andric } 257781ad6265SDimitry Andric 2578*0fca6ea1SDimitry Andric if (NEI < NumberedInstructions.size()) 257981ad6265SDimitry Andric NumInstructions++; 258081ad6265SDimitry Andric NumEncodings++; 258181ad6265SDimitry Andric 258281ad6265SDimitry Andric if (!Size && !IsVarLenInst) 258381ad6265SDimitry Andric continue; 258481ad6265SDimitry Andric 258581ad6265SDimitry Andric if (IsVarLenInst) 258681ad6265SDimitry Andric InstrLen.resize(NumberedInstructions.size(), 0); 258781ad6265SDimitry Andric 2588*0fca6ea1SDimitry Andric if (unsigned Len = populateInstruction(Target, *EncodingDef, *Inst, NEI, 258981ad6265SDimitry Andric Operands, IsVarLenInst)) { 259081ad6265SDimitry Andric if (IsVarLenInst) { 259181ad6265SDimitry Andric MaxInstLen = std::max(MaxInstLen, Len); 2592*0fca6ea1SDimitry Andric InstrLen[NEI] = Len; 259381ad6265SDimitry Andric } 259481ad6265SDimitry Andric std::string DecoderNamespace = 259581ad6265SDimitry Andric std::string(EncodingDef->getValueAsString("DecoderNamespace")); 2596*0fca6ea1SDimitry Andric if (!NumberedEncoding.HwModeName.empty()) 259781ad6265SDimitry Andric DecoderNamespace += 2598*0fca6ea1SDimitry Andric std::string("_") + NumberedEncoding.HwModeName.str(); 2599*0fca6ea1SDimitry Andric OpcMap[std::pair(DecoderNamespace, Size)].emplace_back( 2600*0fca6ea1SDimitry Andric NEI, Target.getInstrIntValue(Def)); 260181ad6265SDimitry Andric } else { 260281ad6265SDimitry Andric NumEncodingsOmitted++; 260381ad6265SDimitry Andric } 260481ad6265SDimitry Andric } 260581ad6265SDimitry Andric 260681ad6265SDimitry Andric DecoderTableInfo TableInfo; 260781ad6265SDimitry Andric for (const auto &Opc : OpcMap) { 260881ad6265SDimitry Andric // Emit the decoder for this namespace+width combination. 2609*0fca6ea1SDimitry Andric ArrayRef<EncodingAndInst> NumberedEncodingsRef(NumberedEncodings.data(), 2610*0fca6ea1SDimitry Andric NumberedEncodings.size()); 261181ad6265SDimitry Andric FilterChooser FC(NumberedEncodingsRef, Opc.second, Operands, 261281ad6265SDimitry Andric IsVarLenInst ? MaxInstLen : 8 * Opc.first.second, this); 261381ad6265SDimitry Andric 261481ad6265SDimitry Andric // The decode table is cleared for each top level decoder function. The 261581ad6265SDimitry Andric // predicates and decoders themselves, however, are shared across all 261681ad6265SDimitry Andric // decoders to give more opportunities for uniqueing. 261781ad6265SDimitry Andric TableInfo.Table.clear(); 261881ad6265SDimitry Andric TableInfo.FixupStack.clear(); 261981ad6265SDimitry Andric TableInfo.Table.reserve(16384); 262081ad6265SDimitry Andric TableInfo.FixupStack.emplace_back(); 262181ad6265SDimitry Andric FC.emitTableEntries(TableInfo); 262281ad6265SDimitry Andric // Any NumToSkip fixups in the top level scope can resolve to the 262381ad6265SDimitry Andric // OPC_Fail at the end of the table. 262481ad6265SDimitry Andric assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!"); 262581ad6265SDimitry Andric // Resolve any NumToSkip fixups in the current scope. 262681ad6265SDimitry Andric resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(), 262781ad6265SDimitry Andric TableInfo.Table.size()); 262881ad6265SDimitry Andric TableInfo.FixupStack.clear(); 262981ad6265SDimitry Andric 263081ad6265SDimitry Andric TableInfo.Table.push_back(MCD::OPC_Fail); 263181ad6265SDimitry Andric 263281ad6265SDimitry Andric // Print the table to the output stream. 2633*0fca6ea1SDimitry Andric emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), Opc.first.first, 2634*0fca6ea1SDimitry Andric Opc.second); 263581ad6265SDimitry Andric } 263681ad6265SDimitry Andric 263781ad6265SDimitry Andric // For variable instruction, we emit a instruction length table 263881ad6265SDimitry Andric // to let the decoder know how long the instructions are. 263981ad6265SDimitry Andric // You can see example usage in M68k's disassembler. 264081ad6265SDimitry Andric if (IsVarLenInst) 264181ad6265SDimitry Andric emitInstrLenTable(OS, InstrLen); 264281ad6265SDimitry Andric // Emit the predicate function. 264381ad6265SDimitry Andric emitPredicateFunction(OS, TableInfo.Predicates, 0); 264481ad6265SDimitry Andric 264581ad6265SDimitry Andric // Emit the decoder function. 264681ad6265SDimitry Andric emitDecoderFunction(OS, TableInfo.Decoders, 0); 264781ad6265SDimitry Andric 264881ad6265SDimitry Andric // Emit the main entry point for the decoder, decodeInstruction(). 264981ad6265SDimitry Andric emitDecodeInstruction(OS, IsVarLenInst); 265081ad6265SDimitry Andric 265181ad6265SDimitry Andric OS << "\n} // end namespace llvm\n"; 265281ad6265SDimitry Andric } 265381ad6265SDimitry Andric 265481ad6265SDimitry Andric namespace llvm { 265581ad6265SDimitry Andric 265681ad6265SDimitry Andric void EmitDecoder(RecordKeeper &RK, raw_ostream &OS, 2657bdd1243dSDimitry Andric const std::string &PredicateNamespace) { 2658bdd1243dSDimitry Andric DecoderEmitter(RK, PredicateNamespace).run(OS); 265981ad6265SDimitry Andric } 266081ad6265SDimitry Andric 266181ad6265SDimitry Andric } // end namespace llvm 2662