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