12754fe60SDimitry Andric //===------------ FixedLenDecoderEmitter.cpp - Decoder Generator ----------===//
22754fe60SDimitry Andric //
32754fe60SDimitry Andric // The LLVM Compiler Infrastructure
42754fe60SDimitry Andric //
52754fe60SDimitry Andric // This file is distributed under the University of Illinois Open Source
62754fe60SDimitry Andric // License. See LICENSE.TXT for details.
72754fe60SDimitry Andric //
82754fe60SDimitry Andric //===----------------------------------------------------------------------===//
92754fe60SDimitry Andric //
102754fe60SDimitry Andric // It contains the tablegen backend that emits the decoder functions for
112754fe60SDimitry Andric // targets with fixed length instruction set.
122754fe60SDimitry Andric //
132754fe60SDimitry Andric //===----------------------------------------------------------------------===//
142754fe60SDimitry Andric
15d88c1a5aSDimitry Andric #include "CodeGenInstruction.h"
162754fe60SDimitry Andric #include "CodeGenTarget.h"
17dff0c46cSDimitry Andric #include "llvm/ADT/APInt.h"
18d88c1a5aSDimitry Andric #include "llvm/ADT/ArrayRef.h"
19d88c1a5aSDimitry Andric #include "llvm/ADT/CachedHashString.h"
207ae0e2c9SDimitry Andric #include "llvm/ADT/SmallString.h"
21d88c1a5aSDimitry Andric #include "llvm/ADT/SetVector.h"
22d88c1a5aSDimitry Andric #include "llvm/ADT/STLExtras.h"
232754fe60SDimitry Andric #include "llvm/ADT/StringExtras.h"
247ae0e2c9SDimitry Andric #include "llvm/ADT/StringRef.h"
257ae0e2c9SDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h"
26d88c1a5aSDimitry Andric #include "llvm/Support/Casting.h"
272754fe60SDimitry Andric #include "llvm/Support/Debug.h"
28d88c1a5aSDimitry Andric #include "llvm/Support/ErrorHandling.h"
297ae0e2c9SDimitry Andric #include "llvm/Support/FormattedStream.h"
307ae0e2c9SDimitry Andric #include "llvm/Support/LEB128.h"
312754fe60SDimitry Andric #include "llvm/Support/raw_ostream.h"
32139f7f9bSDimitry Andric #include "llvm/TableGen/Error.h"
33139f7f9bSDimitry Andric #include "llvm/TableGen/Record.h"
34d88c1a5aSDimitry Andric #include <algorithm>
35d88c1a5aSDimitry Andric #include <cassert>
36d88c1a5aSDimitry Andric #include <cstddef>
37d88c1a5aSDimitry Andric #include <cstdint>
382754fe60SDimitry Andric #include <map>
39d88c1a5aSDimitry Andric #include <memory>
40d88c1a5aSDimitry Andric #include <set>
412754fe60SDimitry Andric #include <string>
423ca95b02SDimitry Andric #include <utility>
43139f7f9bSDimitry Andric #include <vector>
442754fe60SDimitry Andric
452754fe60SDimitry Andric using namespace llvm;
462754fe60SDimitry Andric
4791bc56edSDimitry Andric #define DEBUG_TYPE "decoder-emitter"
4891bc56edSDimitry Andric
497ae0e2c9SDimitry Andric namespace {
50d88c1a5aSDimitry Andric
517ae0e2c9SDimitry Andric struct EncodingField {
527ae0e2c9SDimitry Andric unsigned Base, Width, Offset;
EncodingField__anonc01b33bf0111::EncodingField537ae0e2c9SDimitry Andric EncodingField(unsigned B, unsigned W, unsigned O)
547ae0e2c9SDimitry Andric : Base(B), Width(W), Offset(O) { }
557ae0e2c9SDimitry Andric };
567ae0e2c9SDimitry Andric
577ae0e2c9SDimitry Andric struct OperandInfo {
587ae0e2c9SDimitry Andric std::vector<EncodingField> Fields;
597ae0e2c9SDimitry Andric std::string Decoder;
607d523365SDimitry Andric bool HasCompleteDecoder;
617ae0e2c9SDimitry Andric
OperandInfo__anonc01b33bf0111::OperandInfo627d523365SDimitry Andric OperandInfo(std::string D, bool HCD)
633ca95b02SDimitry Andric : Decoder(std::move(D)), HasCompleteDecoder(HCD) {}
647ae0e2c9SDimitry Andric
addField__anonc01b33bf0111::OperandInfo657ae0e2c9SDimitry Andric void addField(unsigned Base, unsigned Width, unsigned Offset) {
667ae0e2c9SDimitry Andric Fields.push_back(EncodingField(Base, Width, Offset));
677ae0e2c9SDimitry Andric }
687ae0e2c9SDimitry Andric
numFields__anonc01b33bf0111::OperandInfo697ae0e2c9SDimitry Andric unsigned numFields() const { return Fields.size(); }
707ae0e2c9SDimitry Andric
717ae0e2c9SDimitry Andric typedef std::vector<EncodingField>::const_iterator const_iterator;
727ae0e2c9SDimitry Andric
begin__anonc01b33bf0111::OperandInfo737ae0e2c9SDimitry Andric const_iterator begin() const { return Fields.begin(); }
end__anonc01b33bf0111::OperandInfo747ae0e2c9SDimitry Andric const_iterator end() const { return Fields.end(); }
757ae0e2c9SDimitry Andric };
767ae0e2c9SDimitry Andric
777ae0e2c9SDimitry Andric typedef std::vector<uint8_t> DecoderTable;
787ae0e2c9SDimitry Andric typedef uint32_t DecoderFixup;
797ae0e2c9SDimitry Andric typedef std::vector<DecoderFixup> FixupList;
807ae0e2c9SDimitry Andric typedef std::vector<FixupList> FixupScopeList;
81d88c1a5aSDimitry Andric typedef SmallSetVector<CachedHashString, 16> PredicateSet;
82d88c1a5aSDimitry Andric typedef SmallSetVector<CachedHashString, 16> DecoderSet;
837ae0e2c9SDimitry Andric struct DecoderTableInfo {
847ae0e2c9SDimitry Andric DecoderTable Table;
857ae0e2c9SDimitry Andric FixupScopeList FixupStack;
867ae0e2c9SDimitry Andric PredicateSet Predicates;
877ae0e2c9SDimitry Andric DecoderSet Decoders;
887ae0e2c9SDimitry Andric };
897ae0e2c9SDimitry Andric
90*b5893f02SDimitry Andric struct EncodingAndInst {
91*b5893f02SDimitry Andric const Record *EncodingDef;
92*b5893f02SDimitry Andric const CodeGenInstruction *Inst;
93*b5893f02SDimitry Andric
EncodingAndInst__anonc01b33bf0111::EncodingAndInst94*b5893f02SDimitry Andric EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst)
95*b5893f02SDimitry Andric : EncodingDef(EncodingDef), Inst(Inst) {}
96*b5893f02SDimitry Andric };
97*b5893f02SDimitry Andric
operator <<(raw_ostream & OS,const EncodingAndInst & Value)98*b5893f02SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {
99*b5893f02SDimitry Andric if (Value.EncodingDef != Value.Inst->TheDef)
100*b5893f02SDimitry Andric OS << Value.EncodingDef->getName() << ":";
101*b5893f02SDimitry Andric OS << Value.Inst->TheDef->getName();
102*b5893f02SDimitry Andric return OS;
103*b5893f02SDimitry Andric }
104*b5893f02SDimitry Andric
1057ae0e2c9SDimitry Andric class FixedLenDecoderEmitter {
106*b5893f02SDimitry Andric std::vector<EncodingAndInst> NumberedEncodings;
1077ae0e2c9SDimitry Andric
108d88c1a5aSDimitry Andric public:
1097ae0e2c9SDimitry Andric // Defaults preserved here for documentation, even though they aren't
1107ae0e2c9SDimitry Andric // strictly necessary given the way that this is currently being called.
FixedLenDecoderEmitter(RecordKeeper & R,std::string PredicateNamespace,std::string GPrefix="if (",std::string GPostfix=" == MCDisassembler::Fail)",std::string ROK="MCDisassembler::Success",std::string RFail="MCDisassembler::Fail",std::string L="")1113ca95b02SDimitry Andric FixedLenDecoderEmitter(RecordKeeper &R, std::string PredicateNamespace,
1127ae0e2c9SDimitry Andric std::string GPrefix = "if (",
1137d523365SDimitry Andric std::string GPostfix = " == MCDisassembler::Fail)",
1147ae0e2c9SDimitry Andric std::string ROK = "MCDisassembler::Success",
1157ae0e2c9SDimitry Andric std::string RFail = "MCDisassembler::Fail",
1163ca95b02SDimitry Andric std::string L = "")
1173ca95b02SDimitry Andric : Target(R), PredicateNamespace(std::move(PredicateNamespace)),
1183ca95b02SDimitry Andric GuardPrefix(std::move(GPrefix)), GuardPostfix(std::move(GPostfix)),
1193ca95b02SDimitry Andric ReturnOK(std::move(ROK)), ReturnFail(std::move(RFail)),
1203ca95b02SDimitry Andric Locals(std::move(L)) {}
1217ae0e2c9SDimitry Andric
1227ae0e2c9SDimitry Andric // Emit the decoder state machine table.
1237ae0e2c9SDimitry Andric void emitTable(formatted_raw_ostream &o, DecoderTable &Table,
1247ae0e2c9SDimitry Andric unsigned Indentation, unsigned BitWidth,
1257ae0e2c9SDimitry Andric StringRef Namespace) const;
1267ae0e2c9SDimitry Andric void emitPredicateFunction(formatted_raw_ostream &OS,
1277ae0e2c9SDimitry Andric PredicateSet &Predicates,
1287ae0e2c9SDimitry Andric unsigned Indentation) const;
1297ae0e2c9SDimitry Andric void emitDecoderFunction(formatted_raw_ostream &OS,
1307ae0e2c9SDimitry Andric DecoderSet &Decoders,
1317ae0e2c9SDimitry Andric unsigned Indentation) const;
1327ae0e2c9SDimitry Andric
1337ae0e2c9SDimitry Andric // run - Output the code emitter
1347ae0e2c9SDimitry Andric void run(raw_ostream &o);
1357ae0e2c9SDimitry Andric
1367ae0e2c9SDimitry Andric private:
1377ae0e2c9SDimitry Andric CodeGenTarget Target;
138d88c1a5aSDimitry Andric
1397ae0e2c9SDimitry Andric public:
1407ae0e2c9SDimitry Andric std::string PredicateNamespace;
1417ae0e2c9SDimitry Andric std::string GuardPrefix, GuardPostfix;
1427ae0e2c9SDimitry Andric std::string ReturnOK, ReturnFail;
1437ae0e2c9SDimitry Andric std::string Locals;
1447ae0e2c9SDimitry Andric };
145d88c1a5aSDimitry Andric
146d88c1a5aSDimitry Andric } // end anonymous namespace
1477ae0e2c9SDimitry Andric
1482754fe60SDimitry Andric // The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system
1492754fe60SDimitry Andric // for a bit value.
1502754fe60SDimitry Andric //
1512754fe60SDimitry Andric // BIT_UNFILTERED is used as the init value for a filter position. It is used
1522754fe60SDimitry Andric // only for filter processings.
1532754fe60SDimitry Andric typedef enum {
1542754fe60SDimitry Andric BIT_TRUE, // '1'
1552754fe60SDimitry Andric BIT_FALSE, // '0'
1562754fe60SDimitry Andric BIT_UNSET, // '?'
1572754fe60SDimitry Andric BIT_UNFILTERED // unfiltered
1582754fe60SDimitry Andric } bit_value_t;
1592754fe60SDimitry Andric
ValueSet(bit_value_t V)1602754fe60SDimitry Andric static bool ValueSet(bit_value_t V) {
1612754fe60SDimitry Andric return (V == BIT_TRUE || V == BIT_FALSE);
1622754fe60SDimitry Andric }
163d88c1a5aSDimitry Andric
ValueNotSet(bit_value_t V)1642754fe60SDimitry Andric static bool ValueNotSet(bit_value_t V) {
1652754fe60SDimitry Andric return (V == BIT_UNSET);
1662754fe60SDimitry Andric }
167d88c1a5aSDimitry Andric
Value(bit_value_t V)1682754fe60SDimitry Andric static int Value(bit_value_t V) {
1692754fe60SDimitry Andric return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1);
1702754fe60SDimitry Andric }
171d88c1a5aSDimitry Andric
bitFromBits(const BitsInit & bits,unsigned index)172dff0c46cSDimitry Andric static bit_value_t bitFromBits(const BitsInit &bits, unsigned index) {
1733861d79fSDimitry Andric if (BitInit *bit = dyn_cast<BitInit>(bits.getBit(index)))
1742754fe60SDimitry Andric return bit->getValue() ? BIT_TRUE : BIT_FALSE;
1752754fe60SDimitry Andric
1762754fe60SDimitry Andric // The bit is uninitialized.
1772754fe60SDimitry Andric return BIT_UNSET;
1782754fe60SDimitry Andric }
179d88c1a5aSDimitry Andric
1802754fe60SDimitry Andric // Prints the bit value for each position.
dumpBits(raw_ostream & o,const BitsInit & bits)181dff0c46cSDimitry Andric static void dumpBits(raw_ostream &o, const BitsInit &bits) {
1827ae0e2c9SDimitry Andric for (unsigned index = bits.getNumBits(); index > 0; --index) {
1832754fe60SDimitry Andric switch (bitFromBits(bits, index - 1)) {
1842754fe60SDimitry Andric case BIT_TRUE:
1852754fe60SDimitry Andric o << "1";
1862754fe60SDimitry Andric break;
1872754fe60SDimitry Andric case BIT_FALSE:
1882754fe60SDimitry Andric o << "0";
1892754fe60SDimitry Andric break;
1902754fe60SDimitry Andric case BIT_UNSET:
1912754fe60SDimitry Andric o << "_";
1922754fe60SDimitry Andric break;
1932754fe60SDimitry Andric default:
194dff0c46cSDimitry Andric llvm_unreachable("unexpected return value from bitFromBits");
1952754fe60SDimitry Andric }
1962754fe60SDimitry Andric }
1972754fe60SDimitry Andric }
1982754fe60SDimitry Andric
getBitsField(const Record & def,StringRef str)199d88c1a5aSDimitry Andric static BitsInit &getBitsField(const Record &def, StringRef str) {
2002754fe60SDimitry Andric BitsInit *bits = def.getValueAsBitsInit(str);
2012754fe60SDimitry Andric return *bits;
2022754fe60SDimitry Andric }
2032754fe60SDimitry Andric
2042754fe60SDimitry Andric // Representation of the instruction to work on.
2056122f3e6SDimitry Andric typedef std::vector<bit_value_t> insn_t;
2062754fe60SDimitry Andric
207d88c1a5aSDimitry Andric namespace {
208d88c1a5aSDimitry Andric
209d88c1a5aSDimitry Andric class FilterChooser;
210d88c1a5aSDimitry Andric
2112754fe60SDimitry Andric /// Filter - Filter works with FilterChooser to produce the decoding tree for
2122754fe60SDimitry Andric /// the ISA.
2132754fe60SDimitry Andric ///
2142754fe60SDimitry Andric /// It is useful to think of a Filter as governing the switch stmts of the
2152754fe60SDimitry Andric /// decoding tree in a certain level. Each case stmt delegates to an inferior
2162754fe60SDimitry Andric /// FilterChooser to decide what further decoding logic to employ, or in another
2172754fe60SDimitry Andric /// words, what other remaining bits to look at. The FilterChooser eventually
2182754fe60SDimitry Andric /// chooses a best Filter to do its job.
2192754fe60SDimitry Andric ///
2202754fe60SDimitry Andric /// This recursive scheme ends when the number of Opcodes assigned to the
2212754fe60SDimitry Andric /// FilterChooser becomes 1 or if there is a conflict. A conflict happens when
2222754fe60SDimitry Andric /// the Filter/FilterChooser combo does not know how to distinguish among the
2232754fe60SDimitry Andric /// Opcodes assigned.
2242754fe60SDimitry Andric ///
2252754fe60SDimitry Andric /// An example of a conflict is
2262754fe60SDimitry Andric ///
2272754fe60SDimitry Andric /// Conflict:
2282754fe60SDimitry Andric /// 111101000.00........00010000....
2292754fe60SDimitry Andric /// 111101000.00........0001........
2302754fe60SDimitry Andric /// 1111010...00........0001........
2312754fe60SDimitry Andric /// 1111010...00....................
2322754fe60SDimitry Andric /// 1111010.........................
2332754fe60SDimitry Andric /// 1111............................
2342754fe60SDimitry Andric /// ................................
2352754fe60SDimitry Andric /// VST4q8a 111101000_00________00010000____
2362754fe60SDimitry Andric /// VST4q8b 111101000_00________00010000____
2372754fe60SDimitry Andric ///
2382754fe60SDimitry Andric /// The Debug output shows the path that the decoding tree follows to reach the
2392754fe60SDimitry Andric /// the conclusion that there is a conflict. VST4q8a is a vst4 to double-spaced
240875ed548SDimitry Andric /// even registers, while VST4q8b is a vst4 to double-spaced odd registers.
2412754fe60SDimitry Andric ///
2422754fe60SDimitry Andric /// The encoding info in the .td files does not specify this meta information,
2432754fe60SDimitry Andric /// which could have been used by the decoder to resolve the conflict. The
2442754fe60SDimitry Andric /// decoder could try to decode the even/odd register numbering and assign to
2452754fe60SDimitry Andric /// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a"
2462754fe60SDimitry Andric /// version and return the Opcode since the two have the same Asm format string.
2472754fe60SDimitry Andric class Filter {
2482754fe60SDimitry Andric protected:
249dff0c46cSDimitry Andric const FilterChooser *Owner;// points to the FilterChooser who owns this filter
2502754fe60SDimitry Andric unsigned StartBit; // the starting bit position
2512754fe60SDimitry Andric unsigned NumBits; // number of bits to filter
2522754fe60SDimitry Andric bool Mixed; // a mixed region contains both set and unset bits
2532754fe60SDimitry Andric
2542754fe60SDimitry Andric // Map of well-known segment value to the set of uid's with that value.
2552754fe60SDimitry Andric std::map<uint64_t, std::vector<unsigned>> FilteredInstructions;
2562754fe60SDimitry Andric
2572754fe60SDimitry Andric // Set of uid's with non-constant segment values.
2582754fe60SDimitry Andric std::vector<unsigned> VariableInstructions;
2592754fe60SDimitry Andric
2602754fe60SDimitry Andric // Map of well-known segment value to its delegate.
26139d628a0SDimitry Andric std::map<unsigned, std::unique_ptr<const FilterChooser>> FilterChooserMap;
2622754fe60SDimitry Andric
2632754fe60SDimitry Andric // Number of instructions which fall under FilteredInstructions category.
2642754fe60SDimitry Andric unsigned NumFiltered;
2652754fe60SDimitry Andric
2662754fe60SDimitry Andric // Keeps track of the last opcode in the filtered bucket.
2672754fe60SDimitry Andric unsigned LastOpcFiltered;
2682754fe60SDimitry Andric
2692754fe60SDimitry Andric public:
270d88c1a5aSDimitry Andric Filter(Filter &&f);
271d88c1a5aSDimitry Andric Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed);
272d88c1a5aSDimitry Andric
273d88c1a5aSDimitry Andric ~Filter() = default;
274d88c1a5aSDimitry Andric
getNumFiltered() const275dff0c46cSDimitry Andric unsigned getNumFiltered() const { return NumFiltered; }
276d88c1a5aSDimitry Andric
getSingletonOpc() const277dff0c46cSDimitry Andric unsigned getSingletonOpc() const {
2782754fe60SDimitry Andric assert(NumFiltered == 1);
2792754fe60SDimitry Andric return LastOpcFiltered;
2802754fe60SDimitry Andric }
281d88c1a5aSDimitry Andric
2822754fe60SDimitry Andric // Return the filter chooser for the group of instructions without constant
2832754fe60SDimitry Andric // segment values.
getVariableFC() const284dff0c46cSDimitry Andric const FilterChooser &getVariableFC() const {
2852754fe60SDimitry Andric assert(NumFiltered == 1);
2862754fe60SDimitry Andric assert(FilterChooserMap.size() == 1);
2872754fe60SDimitry Andric return *(FilterChooserMap.find((unsigned)-1)->second);
2882754fe60SDimitry Andric }
2892754fe60SDimitry Andric
2902754fe60SDimitry Andric // Divides the decoding task into sub tasks and delegates them to the
2912754fe60SDimitry Andric // inferior FilterChooser's.
2922754fe60SDimitry Andric //
2932754fe60SDimitry Andric // A special case arises when there's only one entry in the filtered
2942754fe60SDimitry Andric // instructions. In order to unambiguously decode the singleton, we need to
2952754fe60SDimitry Andric // match the remaining undecoded encoding bits against the singleton.
2962754fe60SDimitry Andric void recurse();
2972754fe60SDimitry Andric
2987ae0e2c9SDimitry Andric // Emit table entries to decode instructions given a segment or segments of
2997ae0e2c9SDimitry Andric // bits.
3007ae0e2c9SDimitry Andric void emitTableEntry(DecoderTableInfo &TableInfo) const;
3012754fe60SDimitry Andric
3022754fe60SDimitry Andric // Returns the number of fanout produced by the filter. More fanout implies
3032754fe60SDimitry Andric // the filter distinguishes more categories of instructions.
3042754fe60SDimitry Andric unsigned usefulness() const;
305d88c1a5aSDimitry Andric }; // end class Filter
306d88c1a5aSDimitry Andric
307d88c1a5aSDimitry Andric } // end anonymous namespace
3082754fe60SDimitry Andric
3092754fe60SDimitry Andric // These are states of our finite state machines used in FilterChooser's
3102754fe60SDimitry Andric // filterProcessor() which produces the filter candidates to use.
3112754fe60SDimitry Andric typedef enum {
3122754fe60SDimitry Andric ATTR_NONE,
3132754fe60SDimitry Andric ATTR_FILTERED,
3142754fe60SDimitry Andric ATTR_ALL_SET,
3152754fe60SDimitry Andric ATTR_ALL_UNSET,
3162754fe60SDimitry Andric ATTR_MIXED
3172754fe60SDimitry Andric } bitAttr_t;
3182754fe60SDimitry Andric
3192754fe60SDimitry Andric /// FilterChooser - FilterChooser chooses the best filter among a set of Filters
3202754fe60SDimitry Andric /// in order to perform the decoding of instructions at the current level.
3212754fe60SDimitry Andric ///
3222754fe60SDimitry Andric /// Decoding proceeds from the top down. Based on the well-known encoding bits
3232754fe60SDimitry Andric /// of instructions available, FilterChooser builds up the possible Filters that
3242754fe60SDimitry Andric /// can further the task of decoding by distinguishing among the remaining
3252754fe60SDimitry Andric /// candidate instructions.
3262754fe60SDimitry Andric ///
3272754fe60SDimitry Andric /// Once a filter has been chosen, it is called upon to divide the decoding task
3282754fe60SDimitry Andric /// into sub-tasks and delegates them to its inferior FilterChoosers for further
3292754fe60SDimitry Andric /// processings.
3302754fe60SDimitry Andric ///
3312754fe60SDimitry Andric /// It is useful to think of a Filter as governing the switch stmts of the
3322754fe60SDimitry Andric /// decoding tree. And each case is delegated to an inferior FilterChooser to
3332754fe60SDimitry Andric /// decide what further remaining bits to look at.
3347ae0e2c9SDimitry Andric namespace {
335d88c1a5aSDimitry Andric
3362754fe60SDimitry Andric class FilterChooser {
3372754fe60SDimitry Andric protected:
3382754fe60SDimitry Andric friend class Filter;
3392754fe60SDimitry Andric
3402754fe60SDimitry Andric // Vector of codegen instructions to choose our filter.
341*b5893f02SDimitry Andric ArrayRef<EncodingAndInst> AllInstructions;
3422754fe60SDimitry Andric
3432754fe60SDimitry Andric // Vector of uid's for this filter chooser to work on.
344dff0c46cSDimitry Andric const std::vector<unsigned> &Opcodes;
3452754fe60SDimitry Andric
3462754fe60SDimitry Andric // Lookup table for the operand decoding of instructions.
347dff0c46cSDimitry Andric const std::map<unsigned, std::vector<OperandInfo>> &Operands;
3482754fe60SDimitry Andric
3492754fe60SDimitry Andric // Vector of candidate filters.
3502754fe60SDimitry Andric std::vector<Filter> Filters;
3512754fe60SDimitry Andric
3522754fe60SDimitry Andric // Array of bit values passed down from our parent.
3532754fe60SDimitry Andric // Set to all BIT_UNFILTERED's for Parent == NULL.
3546122f3e6SDimitry Andric std::vector<bit_value_t> FilterBitValues;
3552754fe60SDimitry Andric
3562754fe60SDimitry Andric // Links to the FilterChooser above us in the decoding tree.
357dff0c46cSDimitry Andric const FilterChooser *Parent;
3582754fe60SDimitry Andric
3592754fe60SDimitry Andric // Index of the best filter from Filters.
3602754fe60SDimitry Andric int BestIndex;
3612754fe60SDimitry Andric
3626122f3e6SDimitry Andric // Width of instructions
3636122f3e6SDimitry Andric unsigned BitWidth;
3646122f3e6SDimitry Andric
3656122f3e6SDimitry Andric // Parent emitter
3666122f3e6SDimitry Andric const FixedLenDecoderEmitter *Emitter;
3676122f3e6SDimitry Andric
3682754fe60SDimitry Andric public:
FilterChooser(ArrayRef<EncodingAndInst> Insts,const std::vector<unsigned> & IDs,const std::map<unsigned,std::vector<OperandInfo>> & Ops,unsigned BW,const FixedLenDecoderEmitter * E)369*b5893f02SDimitry Andric FilterChooser(ArrayRef<EncodingAndInst> Insts,
3702754fe60SDimitry Andric const std::vector<unsigned> &IDs,
371dff0c46cSDimitry Andric const std::map<unsigned, std::vector<OperandInfo>> &Ops,
372*b5893f02SDimitry Andric unsigned BW, const FixedLenDecoderEmitter *E)
373d88c1a5aSDimitry Andric : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
37439d628a0SDimitry Andric FilterBitValues(BW, BIT_UNFILTERED), Parent(nullptr), BestIndex(-1),
37539d628a0SDimitry Andric BitWidth(BW), Emitter(E) {
3762754fe60SDimitry Andric doFilter();
3772754fe60SDimitry Andric }
3782754fe60SDimitry Andric
FilterChooser(ArrayRef<EncodingAndInst> Insts,const std::vector<unsigned> & IDs,const std::map<unsigned,std::vector<OperandInfo>> & Ops,const std::vector<bit_value_t> & ParentFilterBitValues,const FilterChooser & parent)379*b5893f02SDimitry Andric FilterChooser(ArrayRef<EncodingAndInst> Insts,
3802754fe60SDimitry Andric const std::vector<unsigned> &IDs,
381dff0c46cSDimitry Andric const std::map<unsigned, std::vector<OperandInfo>> &Ops,
382dff0c46cSDimitry Andric const std::vector<bit_value_t> &ParentFilterBitValues,
383dff0c46cSDimitry Andric const FilterChooser &parent)
384dff0c46cSDimitry Andric : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
385d88c1a5aSDimitry Andric FilterBitValues(ParentFilterBitValues), Parent(&parent), BestIndex(-1),
386d88c1a5aSDimitry Andric BitWidth(parent.BitWidth), Emitter(parent.Emitter) {
3872754fe60SDimitry Andric doFilter();
3882754fe60SDimitry Andric }
3892754fe60SDimitry Andric
390d88c1a5aSDimitry Andric FilterChooser(const FilterChooser &) = delete;
391d88c1a5aSDimitry Andric void operator=(const FilterChooser &) = delete;
392d88c1a5aSDimitry Andric
getBitWidth() const3937ae0e2c9SDimitry Andric unsigned getBitWidth() const { return BitWidth; }
3942754fe60SDimitry Andric
3952754fe60SDimitry Andric protected:
3962754fe60SDimitry Andric // Populates the insn given the uid.
insnWithID(insn_t & Insn,unsigned Opcode) const3972754fe60SDimitry Andric void insnWithID(insn_t &Insn, unsigned Opcode) const {
398*b5893f02SDimitry Andric BitsInit &Bits = getBitsField(*AllInstructions[Opcode].EncodingDef, "Inst");
3992754fe60SDimitry Andric
400dff0c46cSDimitry Andric // We may have a SoftFail bitmask, which specifies a mask where an encoding
401dff0c46cSDimitry Andric // may differ from the value in "Inst" and yet still be valid, but the
402dff0c46cSDimitry Andric // disassembler should return SoftFail instead of Success.
403dff0c46cSDimitry Andric //
404dff0c46cSDimitry Andric // This is used for marking UNPREDICTABLE instructions in the ARM world.
405dff0c46cSDimitry Andric BitsInit *SFBits =
406*b5893f02SDimitry Andric AllInstructions[Opcode].EncodingDef->getValueAsBitsInit("SoftFail");
407dff0c46cSDimitry Andric
408dff0c46cSDimitry Andric for (unsigned i = 0; i < BitWidth; ++i) {
409dff0c46cSDimitry Andric if (SFBits && bitFromBits(*SFBits, i) == BIT_TRUE)
410dff0c46cSDimitry Andric Insn.push_back(BIT_UNSET);
411dff0c46cSDimitry Andric else
4126122f3e6SDimitry Andric Insn.push_back(bitFromBits(Bits, i));
4132754fe60SDimitry Andric }
414dff0c46cSDimitry Andric }
4152754fe60SDimitry Andric
4162754fe60SDimitry Andric // Populates the field of the insn given the start position and the number of
4172754fe60SDimitry Andric // consecutive bits to scan for.
4182754fe60SDimitry Andric //
4192754fe60SDimitry Andric // Returns false if there exists any uninitialized bit value in the range.
4202754fe60SDimitry Andric // Returns true, otherwise.
4212754fe60SDimitry Andric bool fieldFromInsn(uint64_t &Field, insn_t &Insn, unsigned StartBit,
4222754fe60SDimitry Andric unsigned NumBits) const;
4232754fe60SDimitry Andric
4242754fe60SDimitry Andric /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
4252754fe60SDimitry Andric /// filter array as a series of chars.
426dff0c46cSDimitry Andric void dumpFilterArray(raw_ostream &o,
427dff0c46cSDimitry Andric const std::vector<bit_value_t> & filter) const;
4282754fe60SDimitry Andric
4292754fe60SDimitry Andric /// dumpStack - dumpStack traverses the filter chooser chain and calls
4302754fe60SDimitry Andric /// dumpFilterArray on each filter chooser up to the top level one.
431dff0c46cSDimitry Andric void dumpStack(raw_ostream &o, const char *prefix) const;
4322754fe60SDimitry Andric
bestFilter()4332754fe60SDimitry Andric Filter &bestFilter() {
4342754fe60SDimitry Andric assert(BestIndex != -1 && "BestIndex not set");
4352754fe60SDimitry Andric return Filters[BestIndex];
4362754fe60SDimitry Andric }
4372754fe60SDimitry Andric
PositionFiltered(unsigned i) const438dff0c46cSDimitry Andric bool PositionFiltered(unsigned i) const {
4392754fe60SDimitry Andric return ValueSet(FilterBitValues[i]);
4402754fe60SDimitry Andric }
4412754fe60SDimitry Andric
4422754fe60SDimitry Andric // Calculates the island(s) needed to decode the instruction.
4432754fe60SDimitry Andric // This returns a lit of undecoded bits of an instructions, for example,
4442754fe60SDimitry Andric // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
4452754fe60SDimitry Andric // decoded bits in order to verify that the instruction matches the Opcode.
4462754fe60SDimitry Andric unsigned getIslands(std::vector<unsigned> &StartBits,
447dff0c46cSDimitry Andric std::vector<unsigned> &EndBits,
448dff0c46cSDimitry Andric std::vector<uint64_t> &FieldVals,
449dff0c46cSDimitry Andric const insn_t &Insn) const;
4502754fe60SDimitry Andric
4516122f3e6SDimitry Andric // Emits code to check the Predicates member of an instruction are true.
4526122f3e6SDimitry Andric // Returns true if predicate matches were emitted, false otherwise.
453dff0c46cSDimitry Andric bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
454dff0c46cSDimitry Andric unsigned Opc) const;
455dff0c46cSDimitry Andric
4567ae0e2c9SDimitry Andric bool doesOpcodeNeedPredicate(unsigned Opc) const;
4577ae0e2c9SDimitry Andric unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const;
4587ae0e2c9SDimitry Andric void emitPredicateTableEntry(DecoderTableInfo &TableInfo,
459dff0c46cSDimitry Andric unsigned Opc) const;
4606122f3e6SDimitry Andric
4617ae0e2c9SDimitry Andric void emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
4627ae0e2c9SDimitry Andric unsigned Opc) const;
4637ae0e2c9SDimitry Andric
4647ae0e2c9SDimitry Andric // Emits table entries to decode the singleton.
4657ae0e2c9SDimitry Andric void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
466dff0c46cSDimitry Andric unsigned Opc) const;
4672754fe60SDimitry Andric
4682754fe60SDimitry Andric // Emits code to decode the singleton, and then to decode the rest.
4697ae0e2c9SDimitry Andric void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
470dff0c46cSDimitry Andric const Filter &Best) const;
4712754fe60SDimitry Andric
4726122f3e6SDimitry Andric void emitBinaryParser(raw_ostream &o, unsigned &Indentation,
4737d523365SDimitry Andric const OperandInfo &OpInfo,
4747d523365SDimitry Andric bool &OpHasCompleteDecoder) const;
4756122f3e6SDimitry Andric
4767d523365SDimitry Andric void emitDecoder(raw_ostream &OS, unsigned Indentation, unsigned Opc,
4777d523365SDimitry Andric bool &HasCompleteDecoder) const;
4787d523365SDimitry Andric unsigned getDecoderIndex(DecoderSet &Decoders, unsigned Opc,
4797d523365SDimitry Andric bool &HasCompleteDecoder) const;
4807ae0e2c9SDimitry Andric
4812754fe60SDimitry Andric // Assign a single filter and run with it.
482dff0c46cSDimitry Andric void runSingleFilter(unsigned startBit, unsigned numBit, bool mixed);
4832754fe60SDimitry Andric
4842754fe60SDimitry Andric // reportRegion is a helper function for filterProcessor to mark a region as
4852754fe60SDimitry Andric // eligible for use as a filter region.
4862754fe60SDimitry Andric void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex,
4872754fe60SDimitry Andric bool AllowMixed);
4882754fe60SDimitry Andric
4892754fe60SDimitry Andric // FilterProcessor scans the well-known encoding bits of the instructions and
4902754fe60SDimitry Andric // builds up a list of candidate filters. It chooses the best filter and
4912754fe60SDimitry Andric // recursively descends down the decoding tree.
4922754fe60SDimitry Andric bool filterProcessor(bool AllowMixed, bool Greedy = true);
4932754fe60SDimitry Andric
4942754fe60SDimitry Andric // Decides on the best configuration of filter(s) to use in order to decode
4952754fe60SDimitry Andric // the instructions. A conflict of instructions may occur, in which case we
4962754fe60SDimitry Andric // dump the conflict set to the standard error.
4972754fe60SDimitry Andric void doFilter();
4982754fe60SDimitry Andric
4997ae0e2c9SDimitry Andric public:
5007ae0e2c9SDimitry Andric // emitTableEntries - Emit state machine entries to decode our share of
5017ae0e2c9SDimitry Andric // instructions.
5027ae0e2c9SDimitry Andric void emitTableEntries(DecoderTableInfo &TableInfo) const;
5032754fe60SDimitry Andric };
504d88c1a5aSDimitry Andric
505d88c1a5aSDimitry Andric } // end anonymous namespace
5062754fe60SDimitry Andric
5072754fe60SDimitry Andric ///////////////////////////
5082754fe60SDimitry Andric // //
509dff0c46cSDimitry Andric // Filter Implementation //
5102754fe60SDimitry Andric // //
5112754fe60SDimitry Andric ///////////////////////////
5122754fe60SDimitry Andric
Filter(Filter && f)51339d628a0SDimitry Andric Filter::Filter(Filter &&f)
514dff0c46cSDimitry Andric : Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed),
51539d628a0SDimitry Andric FilteredInstructions(std::move(f.FilteredInstructions)),
51639d628a0SDimitry Andric VariableInstructions(std::move(f.VariableInstructions)),
51739d628a0SDimitry Andric FilterChooserMap(std::move(f.FilterChooserMap)), NumFiltered(f.NumFiltered),
518dff0c46cSDimitry Andric LastOpcFiltered(f.LastOpcFiltered) {
5192754fe60SDimitry Andric }
5202754fe60SDimitry Andric
Filter(FilterChooser & owner,unsigned startBit,unsigned numBits,bool mixed)5212754fe60SDimitry Andric Filter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits,
522dff0c46cSDimitry Andric bool mixed)
523dff0c46cSDimitry Andric : Owner(&owner), StartBit(startBit), NumBits(numBits), Mixed(mixed) {
5246122f3e6SDimitry Andric assert(StartBit + NumBits - 1 < Owner->BitWidth);
5252754fe60SDimitry Andric
5262754fe60SDimitry Andric NumFiltered = 0;
5272754fe60SDimitry Andric LastOpcFiltered = 0;
5282754fe60SDimitry Andric
5292754fe60SDimitry Andric for (unsigned i = 0, e = Owner->Opcodes.size(); i != e; ++i) {
5302754fe60SDimitry Andric insn_t Insn;
5312754fe60SDimitry Andric
5322754fe60SDimitry Andric // Populates the insn given the uid.
5332754fe60SDimitry Andric Owner->insnWithID(Insn, Owner->Opcodes[i]);
5342754fe60SDimitry Andric
5352754fe60SDimitry Andric uint64_t Field;
5362754fe60SDimitry Andric // Scans the segment for possibly well-specified encoding bits.
5372754fe60SDimitry Andric bool ok = Owner->fieldFromInsn(Field, Insn, StartBit, NumBits);
5382754fe60SDimitry Andric
5392754fe60SDimitry Andric if (ok) {
5402754fe60SDimitry Andric // The encoding bits are well-known. Lets add the uid of the
5412754fe60SDimitry Andric // instruction into the bucket keyed off the constant field value.
5422754fe60SDimitry Andric LastOpcFiltered = Owner->Opcodes[i];
5432754fe60SDimitry Andric FilteredInstructions[Field].push_back(LastOpcFiltered);
5442754fe60SDimitry Andric ++NumFiltered;
5452754fe60SDimitry Andric } else {
546dff0c46cSDimitry Andric // Some of the encoding bit(s) are unspecified. This contributes to
5472754fe60SDimitry Andric // one additional member of "Variable" instructions.
5482754fe60SDimitry Andric VariableInstructions.push_back(Owner->Opcodes[i]);
5492754fe60SDimitry Andric }
5502754fe60SDimitry Andric }
5512754fe60SDimitry Andric
5522754fe60SDimitry Andric assert((FilteredInstructions.size() + VariableInstructions.size() > 0)
5532754fe60SDimitry Andric && "Filter returns no instruction categories");
5542754fe60SDimitry Andric }
5552754fe60SDimitry Andric
5562754fe60SDimitry Andric // Divides the decoding task into sub tasks and delegates them to the
5572754fe60SDimitry Andric // inferior FilterChooser's.
5582754fe60SDimitry Andric //
5592754fe60SDimitry Andric // A special case arises when there's only one entry in the filtered
5602754fe60SDimitry Andric // instructions. In order to unambiguously decode the singleton, we need to
5612754fe60SDimitry Andric // match the remaining undecoded encoding bits against the singleton.
recurse()5622754fe60SDimitry Andric void Filter::recurse() {
5632754fe60SDimitry Andric // Starts by inheriting our parent filter chooser's filter bit values.
5646122f3e6SDimitry Andric std::vector<bit_value_t> BitValueArray(Owner->FilterBitValues);
5652754fe60SDimitry Andric
566ff0cc061SDimitry Andric if (!VariableInstructions.empty()) {
5672754fe60SDimitry Andric // Conservatively marks each segment position as BIT_UNSET.
5687ae0e2c9SDimitry Andric for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex)
5692754fe60SDimitry Andric BitValueArray[StartBit + bitIndex] = BIT_UNSET;
5702754fe60SDimitry Andric
5713b0f4066SDimitry Andric // Delegates to an inferior filter chooser for further processing on this
5722754fe60SDimitry Andric // group of instructions whose segment values are variable.
57339d628a0SDimitry Andric FilterChooserMap.insert(
57439d628a0SDimitry Andric std::make_pair(-1U, llvm::make_unique<FilterChooser>(
57539d628a0SDimitry Andric Owner->AllInstructions, VariableInstructions,
57639d628a0SDimitry Andric Owner->Operands, BitValueArray, *Owner)));
5772754fe60SDimitry Andric }
5782754fe60SDimitry Andric
5792754fe60SDimitry Andric // No need to recurse for a singleton filtered instruction.
5807ae0e2c9SDimitry Andric // See also Filter::emit*().
5812754fe60SDimitry Andric if (getNumFiltered() == 1) {
5822754fe60SDimitry Andric assert(FilterChooserMap.size() == 1);
5832754fe60SDimitry Andric return;
5842754fe60SDimitry Andric }
5852754fe60SDimitry Andric
5862754fe60SDimitry Andric // Otherwise, create sub choosers.
58739d628a0SDimitry Andric for (const auto &Inst : FilteredInstructions) {
5882754fe60SDimitry Andric
5892754fe60SDimitry Andric // Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
5907ae0e2c9SDimitry Andric for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) {
59139d628a0SDimitry Andric if (Inst.first & (1ULL << bitIndex))
5922754fe60SDimitry Andric BitValueArray[StartBit + bitIndex] = BIT_TRUE;
5932754fe60SDimitry Andric else
5942754fe60SDimitry Andric BitValueArray[StartBit + bitIndex] = BIT_FALSE;
5952754fe60SDimitry Andric }
5962754fe60SDimitry Andric
5973b0f4066SDimitry Andric // Delegates to an inferior filter chooser for further processing on this
5982754fe60SDimitry Andric // category of instructions.
59939d628a0SDimitry Andric FilterChooserMap.insert(std::make_pair(
60039d628a0SDimitry Andric Inst.first, llvm::make_unique<FilterChooser>(
60139d628a0SDimitry Andric Owner->AllInstructions, Inst.second,
60239d628a0SDimitry Andric Owner->Operands, BitValueArray, *Owner)));
6032754fe60SDimitry Andric }
6042754fe60SDimitry Andric }
6052754fe60SDimitry Andric
resolveTableFixups(DecoderTable & Table,const FixupList & Fixups,uint32_t DestIdx)6067ae0e2c9SDimitry Andric static void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups,
6077ae0e2c9SDimitry Andric uint32_t DestIdx) {
6087ae0e2c9SDimitry Andric // Any NumToSkip fixups in the current scope can resolve to the
6097ae0e2c9SDimitry Andric // current location.
6107ae0e2c9SDimitry Andric for (FixupList::const_reverse_iterator I = Fixups.rbegin(),
6117ae0e2c9SDimitry Andric E = Fixups.rend();
6127ae0e2c9SDimitry Andric I != E; ++I) {
6137ae0e2c9SDimitry Andric // Calculate the distance from the byte following the fixup entry byte
6147ae0e2c9SDimitry Andric // to the destination. The Target is calculated from after the 16-bit
6157ae0e2c9SDimitry Andric // NumToSkip entry itself, so subtract two from the displacement here
6167ae0e2c9SDimitry Andric // to account for that.
6177ae0e2c9SDimitry Andric uint32_t FixupIdx = *I;
6184ba319b5SDimitry Andric uint32_t Delta = DestIdx - FixupIdx - 3;
6194ba319b5SDimitry Andric // Our NumToSkip entries are 24-bits. Make sure our table isn't too
6207ae0e2c9SDimitry Andric // big.
6214ba319b5SDimitry Andric assert(Delta < (1u << 24));
6227ae0e2c9SDimitry Andric Table[FixupIdx] = (uint8_t)Delta;
6237ae0e2c9SDimitry Andric Table[FixupIdx + 1] = (uint8_t)(Delta >> 8);
6244ba319b5SDimitry Andric Table[FixupIdx + 2] = (uint8_t)(Delta >> 16);
6257ae0e2c9SDimitry Andric }
6267ae0e2c9SDimitry Andric }
6272754fe60SDimitry Andric
6287ae0e2c9SDimitry Andric // Emit table entries to decode instructions given a segment or segments
6297ae0e2c9SDimitry Andric // of bits.
emitTableEntry(DecoderTableInfo & TableInfo) const6307ae0e2c9SDimitry Andric void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
6317ae0e2c9SDimitry Andric TableInfo.Table.push_back(MCD::OPC_ExtractField);
6327ae0e2c9SDimitry Andric TableInfo.Table.push_back(StartBit);
6337ae0e2c9SDimitry Andric TableInfo.Table.push_back(NumBits);
6342754fe60SDimitry Andric
6357ae0e2c9SDimitry Andric // A new filter entry begins a new scope for fixup resolution.
63697bc6c73SDimitry Andric TableInfo.FixupStack.emplace_back();
6372754fe60SDimitry Andric
6387ae0e2c9SDimitry Andric DecoderTable &Table = TableInfo.Table;
6397ae0e2c9SDimitry Andric
6407ae0e2c9SDimitry Andric size_t PrevFilter = 0;
6417ae0e2c9SDimitry Andric bool HasFallthrough = false;
64239d628a0SDimitry Andric for (auto &Filter : FilterChooserMap) {
6432754fe60SDimitry Andric // Field value -1 implies a non-empty set of variable instructions.
6442754fe60SDimitry Andric // See also recurse().
64539d628a0SDimitry Andric if (Filter.first == (unsigned)-1) {
6467ae0e2c9SDimitry Andric HasFallthrough = true;
6472754fe60SDimitry Andric
6487ae0e2c9SDimitry Andric // Each scope should always have at least one filter value to check
6497ae0e2c9SDimitry Andric // for.
6507ae0e2c9SDimitry Andric assert(PrevFilter != 0 && "empty filter set!");
6517ae0e2c9SDimitry Andric FixupList &CurScope = TableInfo.FixupStack.back();
6527ae0e2c9SDimitry Andric // Resolve any NumToSkip fixups in the current scope.
6537ae0e2c9SDimitry Andric resolveTableFixups(Table, CurScope, Table.size());
6547ae0e2c9SDimitry Andric CurScope.clear();
6557ae0e2c9SDimitry Andric PrevFilter = 0; // Don't re-process the filter's fallthrough.
6567ae0e2c9SDimitry Andric } else {
6577ae0e2c9SDimitry Andric Table.push_back(MCD::OPC_FilterValue);
6587ae0e2c9SDimitry Andric // Encode and emit the value to filter against.
6594ba319b5SDimitry Andric uint8_t Buffer[16];
66039d628a0SDimitry Andric unsigned Len = encodeULEB128(Filter.first, Buffer);
6617ae0e2c9SDimitry Andric Table.insert(Table.end(), Buffer, Buffer + Len);
6627ae0e2c9SDimitry Andric // Reserve space for the NumToSkip entry. We'll backpatch the value
6637ae0e2c9SDimitry Andric // later.
6647ae0e2c9SDimitry Andric PrevFilter = Table.size();
6657ae0e2c9SDimitry Andric Table.push_back(0);
6667ae0e2c9SDimitry Andric Table.push_back(0);
6674ba319b5SDimitry Andric Table.push_back(0);
6687ae0e2c9SDimitry Andric }
6692754fe60SDimitry Andric
6702754fe60SDimitry Andric // We arrive at a category of instructions with the same segment value.
6712754fe60SDimitry Andric // Now delegate to the sub filter chooser for further decodings.
6722754fe60SDimitry Andric // The case may fallthrough, which happens if the remaining well-known
6732754fe60SDimitry Andric // encoding bits do not match exactly.
67439d628a0SDimitry Andric Filter.second->emitTableEntries(TableInfo);
6752754fe60SDimitry Andric
6767ae0e2c9SDimitry Andric // Now that we've emitted the body of the handler, update the NumToSkip
6777ae0e2c9SDimitry Andric // of the filter itself to be able to skip forward when false. Subtract
6787ae0e2c9SDimitry Andric // two as to account for the width of the NumToSkip field itself.
6797ae0e2c9SDimitry Andric if (PrevFilter) {
6804ba319b5SDimitry Andric uint32_t NumToSkip = Table.size() - PrevFilter - 3;
6814ba319b5SDimitry Andric assert(NumToSkip < (1u << 24) && "disassembler decoding table too large!");
6827ae0e2c9SDimitry Andric Table[PrevFilter] = (uint8_t)NumToSkip;
6837ae0e2c9SDimitry Andric Table[PrevFilter + 1] = (uint8_t)(NumToSkip >> 8);
6844ba319b5SDimitry Andric Table[PrevFilter + 2] = (uint8_t)(NumToSkip >> 16);
6857ae0e2c9SDimitry Andric }
6862754fe60SDimitry Andric }
6872754fe60SDimitry Andric
6887ae0e2c9SDimitry Andric // Any remaining unresolved fixups bubble up to the parent fixup scope.
6897ae0e2c9SDimitry Andric assert(TableInfo.FixupStack.size() > 1 && "fixup stack underflow!");
6907ae0e2c9SDimitry Andric FixupScopeList::iterator Source = TableInfo.FixupStack.end() - 1;
6917ae0e2c9SDimitry Andric FixupScopeList::iterator Dest = Source - 1;
6927ae0e2c9SDimitry Andric Dest->insert(Dest->end(), Source->begin(), Source->end());
6937ae0e2c9SDimitry Andric TableInfo.FixupStack.pop_back();
6947ae0e2c9SDimitry Andric
6957ae0e2c9SDimitry Andric // If there is no fallthrough, then the final filter should get fixed
6967ae0e2c9SDimitry Andric // up according to the enclosing scope rather than the current position.
6977ae0e2c9SDimitry Andric if (!HasFallthrough)
6987ae0e2c9SDimitry Andric TableInfo.FixupStack.back().push_back(PrevFilter);
6992754fe60SDimitry Andric }
7002754fe60SDimitry Andric
7012754fe60SDimitry Andric // Returns the number of fanout produced by the filter. More fanout implies
7022754fe60SDimitry Andric // the filter distinguishes more categories of instructions.
usefulness() const7032754fe60SDimitry Andric unsigned Filter::usefulness() const {
704ff0cc061SDimitry Andric if (!VariableInstructions.empty())
7052754fe60SDimitry Andric return FilteredInstructions.size();
7062754fe60SDimitry Andric else
7072754fe60SDimitry Andric return FilteredInstructions.size() + 1;
7082754fe60SDimitry Andric }
7092754fe60SDimitry Andric
7102754fe60SDimitry Andric //////////////////////////////////
7112754fe60SDimitry Andric // //
7122754fe60SDimitry Andric // Filterchooser Implementation //
7132754fe60SDimitry Andric // //
7142754fe60SDimitry Andric //////////////////////////////////
7152754fe60SDimitry Andric
7167ae0e2c9SDimitry Andric // Emit the decoder state machine table.
emitTable(formatted_raw_ostream & OS,DecoderTable & Table,unsigned Indentation,unsigned BitWidth,StringRef Namespace) const7177ae0e2c9SDimitry Andric void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
7187ae0e2c9SDimitry Andric DecoderTable &Table,
7197ae0e2c9SDimitry Andric unsigned Indentation,
7207ae0e2c9SDimitry Andric unsigned BitWidth,
7217ae0e2c9SDimitry Andric StringRef Namespace) const {
7227ae0e2c9SDimitry Andric OS.indent(Indentation) << "static const uint8_t DecoderTable" << Namespace
7237ae0e2c9SDimitry Andric << BitWidth << "[] = {\n";
7242754fe60SDimitry Andric
7257ae0e2c9SDimitry Andric Indentation += 2;
7262754fe60SDimitry Andric
7277ae0e2c9SDimitry Andric // FIXME: We may be able to use the NumToSkip values to recover
7287ae0e2c9SDimitry Andric // appropriate indentation levels.
7297ae0e2c9SDimitry Andric DecoderTable::const_iterator I = Table.begin();
7307ae0e2c9SDimitry Andric DecoderTable::const_iterator E = Table.end();
7317ae0e2c9SDimitry Andric while (I != E) {
7327ae0e2c9SDimitry Andric assert (I < E && "incomplete decode table entry!");
7332754fe60SDimitry Andric
7347ae0e2c9SDimitry Andric uint64_t Pos = I - Table.begin();
7357ae0e2c9SDimitry Andric OS << "/* " << Pos << " */";
7367ae0e2c9SDimitry Andric OS.PadToColumn(12);
7372754fe60SDimitry Andric
7387ae0e2c9SDimitry Andric switch (*I) {
7397ae0e2c9SDimitry Andric default:
7403861d79fSDimitry Andric PrintFatalError("invalid decode table opcode");
7417ae0e2c9SDimitry Andric case MCD::OPC_ExtractField: {
7427ae0e2c9SDimitry Andric ++I;
7437ae0e2c9SDimitry Andric unsigned Start = *I++;
7447ae0e2c9SDimitry Andric unsigned Len = *I++;
7457ae0e2c9SDimitry Andric OS.indent(Indentation) << "MCD::OPC_ExtractField, " << Start << ", "
7467ae0e2c9SDimitry Andric << Len << ", // Inst{";
7477ae0e2c9SDimitry Andric if (Len > 1)
7487ae0e2c9SDimitry Andric OS << (Start + Len - 1) << "-";
7497ae0e2c9SDimitry Andric OS << Start << "} ...\n";
7507ae0e2c9SDimitry Andric break;
7517ae0e2c9SDimitry Andric }
7527ae0e2c9SDimitry Andric case MCD::OPC_FilterValue: {
7537ae0e2c9SDimitry Andric ++I;
7547ae0e2c9SDimitry Andric OS.indent(Indentation) << "MCD::OPC_FilterValue, ";
7557ae0e2c9SDimitry Andric // The filter value is ULEB128 encoded.
7567ae0e2c9SDimitry Andric while (*I >= 128)
7573ca95b02SDimitry Andric OS << (unsigned)*I++ << ", ";
7583ca95b02SDimitry Andric OS << (unsigned)*I++ << ", ";
7597ae0e2c9SDimitry Andric
7604ba319b5SDimitry Andric // 24-bit numtoskip value.
7617ae0e2c9SDimitry Andric uint8_t Byte = *I++;
7627ae0e2c9SDimitry Andric uint32_t NumToSkip = Byte;
7633ca95b02SDimitry Andric OS << (unsigned)Byte << ", ";
7647ae0e2c9SDimitry Andric Byte = *I++;
7653ca95b02SDimitry Andric OS << (unsigned)Byte << ", ";
7667ae0e2c9SDimitry Andric NumToSkip |= Byte << 8;
7674ba319b5SDimitry Andric Byte = *I++;
7684ba319b5SDimitry Andric OS << utostr(Byte) << ", ";
7694ba319b5SDimitry Andric NumToSkip |= Byte << 16;
7707ae0e2c9SDimitry Andric OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
7717ae0e2c9SDimitry Andric break;
7727ae0e2c9SDimitry Andric }
7737ae0e2c9SDimitry Andric case MCD::OPC_CheckField: {
7747ae0e2c9SDimitry Andric ++I;
7757ae0e2c9SDimitry Andric unsigned Start = *I++;
7767ae0e2c9SDimitry Andric unsigned Len = *I++;
7777ae0e2c9SDimitry Andric OS.indent(Indentation) << "MCD::OPC_CheckField, " << Start << ", "
7787ae0e2c9SDimitry Andric << Len << ", ";// << Val << ", " << NumToSkip << ",\n";
7797ae0e2c9SDimitry Andric // ULEB128 encoded field value.
7807ae0e2c9SDimitry Andric for (; *I >= 128; ++I)
7813ca95b02SDimitry Andric OS << (unsigned)*I << ", ";
7823ca95b02SDimitry Andric OS << (unsigned)*I++ << ", ";
7834ba319b5SDimitry Andric // 24-bit numtoskip value.
7847ae0e2c9SDimitry Andric uint8_t Byte = *I++;
7857ae0e2c9SDimitry Andric uint32_t NumToSkip = Byte;
7863ca95b02SDimitry Andric OS << (unsigned)Byte << ", ";
7877ae0e2c9SDimitry Andric Byte = *I++;
7883ca95b02SDimitry Andric OS << (unsigned)Byte << ", ";
7897ae0e2c9SDimitry Andric NumToSkip |= Byte << 8;
7904ba319b5SDimitry Andric Byte = *I++;
7914ba319b5SDimitry Andric OS << utostr(Byte) << ", ";
7924ba319b5SDimitry Andric NumToSkip |= Byte << 16;
7937ae0e2c9SDimitry Andric OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
7947ae0e2c9SDimitry Andric break;
7957ae0e2c9SDimitry Andric }
7967ae0e2c9SDimitry Andric case MCD::OPC_CheckPredicate: {
7977ae0e2c9SDimitry Andric ++I;
7987ae0e2c9SDimitry Andric OS.indent(Indentation) << "MCD::OPC_CheckPredicate, ";
7997ae0e2c9SDimitry Andric for (; *I >= 128; ++I)
8003ca95b02SDimitry Andric OS << (unsigned)*I << ", ";
8013ca95b02SDimitry Andric OS << (unsigned)*I++ << ", ";
8027ae0e2c9SDimitry Andric
8034ba319b5SDimitry Andric // 24-bit numtoskip value.
8047ae0e2c9SDimitry Andric uint8_t Byte = *I++;
8057ae0e2c9SDimitry Andric uint32_t NumToSkip = Byte;
8063ca95b02SDimitry Andric OS << (unsigned)Byte << ", ";
8077ae0e2c9SDimitry Andric Byte = *I++;
8083ca95b02SDimitry Andric OS << (unsigned)Byte << ", ";
8097ae0e2c9SDimitry Andric NumToSkip |= Byte << 8;
8104ba319b5SDimitry Andric Byte = *I++;
8114ba319b5SDimitry Andric OS << utostr(Byte) << ", ";
8124ba319b5SDimitry Andric NumToSkip |= Byte << 16;
8137ae0e2c9SDimitry Andric OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
8147ae0e2c9SDimitry Andric break;
8157ae0e2c9SDimitry Andric }
8167d523365SDimitry Andric case MCD::OPC_Decode:
8177d523365SDimitry Andric case MCD::OPC_TryDecode: {
8187d523365SDimitry Andric bool IsTry = *I == MCD::OPC_TryDecode;
8197ae0e2c9SDimitry Andric ++I;
8207ae0e2c9SDimitry Andric // Extract the ULEB128 encoded Opcode to a buffer.
8214ba319b5SDimitry Andric uint8_t Buffer[16], *p = Buffer;
8227ae0e2c9SDimitry Andric while ((*p++ = *I++) >= 128)
8237ae0e2c9SDimitry Andric assert((p - Buffer) <= (ptrdiff_t)sizeof(Buffer)
8247ae0e2c9SDimitry Andric && "ULEB128 value too large!");
8257ae0e2c9SDimitry Andric // Decode the Opcode value.
8267ae0e2c9SDimitry Andric unsigned Opc = decodeULEB128(Buffer);
8277d523365SDimitry Andric OS.indent(Indentation) << "MCD::OPC_" << (IsTry ? "Try" : "")
8287d523365SDimitry Andric << "Decode, ";
8297ae0e2c9SDimitry Andric for (p = Buffer; *p >= 128; ++p)
8303ca95b02SDimitry Andric OS << (unsigned)*p << ", ";
8313ca95b02SDimitry Andric OS << (unsigned)*p << ", ";
8327ae0e2c9SDimitry Andric
8337ae0e2c9SDimitry Andric // Decoder index.
8347ae0e2c9SDimitry Andric for (; *I >= 128; ++I)
8353ca95b02SDimitry Andric OS << (unsigned)*I << ", ";
8363ca95b02SDimitry Andric OS << (unsigned)*I++ << ", ";
8377ae0e2c9SDimitry Andric
8387d523365SDimitry Andric if (!IsTry) {
839*b5893f02SDimitry Andric OS << "// Opcode: " << NumberedEncodings[Opc] << "\n";
8407ae0e2c9SDimitry Andric break;
8417ae0e2c9SDimitry Andric }
8427d523365SDimitry Andric
8437d523365SDimitry Andric // Fallthrough for OPC_TryDecode.
8447d523365SDimitry Andric
8454ba319b5SDimitry Andric // 24-bit numtoskip value.
8467d523365SDimitry Andric uint8_t Byte = *I++;
8477d523365SDimitry Andric uint32_t NumToSkip = Byte;
8483ca95b02SDimitry Andric OS << (unsigned)Byte << ", ";
8497d523365SDimitry Andric Byte = *I++;
8503ca95b02SDimitry Andric OS << (unsigned)Byte << ", ";
8517d523365SDimitry Andric NumToSkip |= Byte << 8;
8524ba319b5SDimitry Andric Byte = *I++;
8534ba319b5SDimitry Andric OS << utostr(Byte) << ", ";
8544ba319b5SDimitry Andric NumToSkip |= Byte << 16;
8557d523365SDimitry Andric
856*b5893f02SDimitry Andric OS << "// Opcode: " << NumberedEncodings[Opc]
8577d523365SDimitry Andric << ", skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
8587d523365SDimitry Andric break;
8597d523365SDimitry Andric }
8607ae0e2c9SDimitry Andric case MCD::OPC_SoftFail: {
8617ae0e2c9SDimitry Andric ++I;
8627ae0e2c9SDimitry Andric OS.indent(Indentation) << "MCD::OPC_SoftFail";
8637ae0e2c9SDimitry Andric // Positive mask
8647ae0e2c9SDimitry Andric uint64_t Value = 0;
8657ae0e2c9SDimitry Andric unsigned Shift = 0;
8667ae0e2c9SDimitry Andric do {
8673ca95b02SDimitry Andric OS << ", " << (unsigned)*I;
8687ae0e2c9SDimitry Andric Value += (*I & 0x7f) << Shift;
8697ae0e2c9SDimitry Andric Shift += 7;
8707ae0e2c9SDimitry Andric } while (*I++ >= 128);
8713ca95b02SDimitry Andric if (Value > 127) {
8723ca95b02SDimitry Andric OS << " /* 0x";
8733ca95b02SDimitry Andric OS.write_hex(Value);
8743ca95b02SDimitry Andric OS << " */";
8753ca95b02SDimitry Andric }
8767ae0e2c9SDimitry Andric // Negative mask
8777ae0e2c9SDimitry Andric Value = 0;
8787ae0e2c9SDimitry Andric Shift = 0;
8797ae0e2c9SDimitry Andric do {
8803ca95b02SDimitry Andric OS << ", " << (unsigned)*I;
8817ae0e2c9SDimitry Andric Value += (*I & 0x7f) << Shift;
8827ae0e2c9SDimitry Andric Shift += 7;
8837ae0e2c9SDimitry Andric } while (*I++ >= 128);
8843ca95b02SDimitry Andric if (Value > 127) {
8853ca95b02SDimitry Andric OS << " /* 0x";
8863ca95b02SDimitry Andric OS.write_hex(Value);
8873ca95b02SDimitry Andric OS << " */";
8883ca95b02SDimitry Andric }
8897ae0e2c9SDimitry Andric OS << ",\n";
8907ae0e2c9SDimitry Andric break;
8917ae0e2c9SDimitry Andric }
8927ae0e2c9SDimitry Andric case MCD::OPC_Fail: {
8937ae0e2c9SDimitry Andric ++I;
8947ae0e2c9SDimitry Andric OS.indent(Indentation) << "MCD::OPC_Fail,\n";
8957ae0e2c9SDimitry Andric break;
8967ae0e2c9SDimitry Andric }
8977ae0e2c9SDimitry Andric }
8987ae0e2c9SDimitry Andric }
8997ae0e2c9SDimitry Andric OS.indent(Indentation) << "0\n";
9007ae0e2c9SDimitry Andric
9017ae0e2c9SDimitry Andric Indentation -= 2;
9027ae0e2c9SDimitry Andric
9037ae0e2c9SDimitry Andric OS.indent(Indentation) << "};\n\n";
9047ae0e2c9SDimitry Andric }
9057ae0e2c9SDimitry Andric
9067ae0e2c9SDimitry Andric void FixedLenDecoderEmitter::
emitPredicateFunction(formatted_raw_ostream & OS,PredicateSet & Predicates,unsigned Indentation) const9077ae0e2c9SDimitry Andric emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
9087ae0e2c9SDimitry Andric unsigned Indentation) const {
9097ae0e2c9SDimitry Andric // The predicate function is just a big switch statement based on the
9107ae0e2c9SDimitry Andric // input predicate index.
9117ae0e2c9SDimitry Andric OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
912ff0cc061SDimitry Andric << "const FeatureBitset& Bits) {\n";
9137ae0e2c9SDimitry Andric Indentation += 2;
914f785676fSDimitry Andric if (!Predicates.empty()) {
9157ae0e2c9SDimitry Andric OS.indent(Indentation) << "switch (Idx) {\n";
9167ae0e2c9SDimitry Andric OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
9177ae0e2c9SDimitry Andric unsigned Index = 0;
91839d628a0SDimitry Andric for (const auto &Predicate : Predicates) {
91939d628a0SDimitry Andric OS.indent(Indentation) << "case " << Index++ << ":\n";
92039d628a0SDimitry Andric OS.indent(Indentation+2) << "return (" << Predicate << ");\n";
9217ae0e2c9SDimitry Andric }
9227ae0e2c9SDimitry Andric OS.indent(Indentation) << "}\n";
923f785676fSDimitry Andric } else {
924f785676fSDimitry Andric // No case statement to emit
925f785676fSDimitry Andric OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n";
926f785676fSDimitry Andric }
9277ae0e2c9SDimitry Andric Indentation -= 2;
9287ae0e2c9SDimitry Andric OS.indent(Indentation) << "}\n\n";
9297ae0e2c9SDimitry Andric }
9307ae0e2c9SDimitry Andric
9317ae0e2c9SDimitry Andric void FixedLenDecoderEmitter::
emitDecoderFunction(formatted_raw_ostream & OS,DecoderSet & Decoders,unsigned Indentation) const9327ae0e2c9SDimitry Andric emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
9337ae0e2c9SDimitry Andric unsigned Indentation) const {
9347ae0e2c9SDimitry Andric // The decoder function is just a big switch statement based on the
9357ae0e2c9SDimitry Andric // input decoder index.
9367ae0e2c9SDimitry Andric OS.indent(Indentation) << "template<typename InsnType>\n";
9377ae0e2c9SDimitry Andric OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S,"
9387ae0e2c9SDimitry Andric << " unsigned Idx, InsnType insn, MCInst &MI,\n";
9397ae0e2c9SDimitry Andric OS.indent(Indentation) << " uint64_t "
9407d523365SDimitry Andric << "Address, const void *Decoder, bool &DecodeComplete) {\n";
9417ae0e2c9SDimitry Andric Indentation += 2;
9427d523365SDimitry Andric OS.indent(Indentation) << "DecodeComplete = true;\n";
9437ae0e2c9SDimitry Andric OS.indent(Indentation) << "InsnType tmp;\n";
9447ae0e2c9SDimitry Andric OS.indent(Indentation) << "switch (Idx) {\n";
9457ae0e2c9SDimitry Andric OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
9467ae0e2c9SDimitry Andric unsigned Index = 0;
94739d628a0SDimitry Andric for (const auto &Decoder : Decoders) {
94839d628a0SDimitry Andric OS.indent(Indentation) << "case " << Index++ << ":\n";
94939d628a0SDimitry Andric OS << Decoder;
9507ae0e2c9SDimitry Andric OS.indent(Indentation+2) << "return S;\n";
9517ae0e2c9SDimitry Andric }
9527ae0e2c9SDimitry Andric OS.indent(Indentation) << "}\n";
9537ae0e2c9SDimitry Andric Indentation -= 2;
9547ae0e2c9SDimitry Andric OS.indent(Indentation) << "}\n\n";
9552754fe60SDimitry Andric }
9562754fe60SDimitry Andric
9572754fe60SDimitry Andric // Populates the field of the insn given the start position and the number of
9582754fe60SDimitry Andric // consecutive bits to scan for.
9592754fe60SDimitry Andric //
9602754fe60SDimitry Andric // Returns false if and on the first uninitialized bit value encountered.
9612754fe60SDimitry Andric // Returns true, otherwise.
fieldFromInsn(uint64_t & Field,insn_t & Insn,unsigned StartBit,unsigned NumBits) const9622754fe60SDimitry Andric bool FilterChooser::fieldFromInsn(uint64_t &Field, insn_t &Insn,
9632754fe60SDimitry Andric unsigned StartBit, unsigned NumBits) const {
9642754fe60SDimitry Andric Field = 0;
9652754fe60SDimitry Andric
9662754fe60SDimitry Andric for (unsigned i = 0; i < NumBits; ++i) {
9672754fe60SDimitry Andric if (Insn[StartBit + i] == BIT_UNSET)
9682754fe60SDimitry Andric return false;
9692754fe60SDimitry Andric
9702754fe60SDimitry Andric if (Insn[StartBit + i] == BIT_TRUE)
9712754fe60SDimitry Andric Field = Field | (1ULL << i);
9722754fe60SDimitry Andric }
9732754fe60SDimitry Andric
9742754fe60SDimitry Andric return true;
9752754fe60SDimitry Andric }
9762754fe60SDimitry Andric
9772754fe60SDimitry Andric /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
9782754fe60SDimitry Andric /// filter array as a series of chars.
dumpFilterArray(raw_ostream & o,const std::vector<bit_value_t> & filter) const9792754fe60SDimitry Andric void FilterChooser::dumpFilterArray(raw_ostream &o,
980dff0c46cSDimitry Andric const std::vector<bit_value_t> &filter) const {
9817ae0e2c9SDimitry Andric for (unsigned bitIndex = BitWidth; bitIndex > 0; bitIndex--) {
9822754fe60SDimitry Andric switch (filter[bitIndex - 1]) {
9832754fe60SDimitry Andric case BIT_UNFILTERED:
9842754fe60SDimitry Andric o << ".";
9852754fe60SDimitry Andric break;
9862754fe60SDimitry Andric case BIT_UNSET:
9872754fe60SDimitry Andric o << "_";
9882754fe60SDimitry Andric break;
9892754fe60SDimitry Andric case BIT_TRUE:
9902754fe60SDimitry Andric o << "1";
9912754fe60SDimitry Andric break;
9922754fe60SDimitry Andric case BIT_FALSE:
9932754fe60SDimitry Andric o << "0";
9942754fe60SDimitry Andric break;
9952754fe60SDimitry Andric }
9962754fe60SDimitry Andric }
9972754fe60SDimitry Andric }
9982754fe60SDimitry Andric
9992754fe60SDimitry Andric /// dumpStack - dumpStack traverses the filter chooser chain and calls
10002754fe60SDimitry Andric /// dumpFilterArray on each filter chooser up to the top level one.
dumpStack(raw_ostream & o,const char * prefix) const1001dff0c46cSDimitry Andric void FilterChooser::dumpStack(raw_ostream &o, const char *prefix) const {
1002dff0c46cSDimitry Andric const FilterChooser *current = this;
10032754fe60SDimitry Andric
10042754fe60SDimitry Andric while (current) {
10052754fe60SDimitry Andric o << prefix;
10062754fe60SDimitry Andric dumpFilterArray(o, current->FilterBitValues);
10072754fe60SDimitry Andric o << '\n';
10082754fe60SDimitry Andric current = current->Parent;
10092754fe60SDimitry Andric }
10102754fe60SDimitry Andric }
10112754fe60SDimitry Andric
10122754fe60SDimitry Andric // Calculates the island(s) needed to decode the instruction.
10132754fe60SDimitry Andric // This returns a list of undecoded bits of an instructions, for example,
10142754fe60SDimitry Andric // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
10152754fe60SDimitry Andric // decoded bits in order to verify that the instruction matches the Opcode.
getIslands(std::vector<unsigned> & StartBits,std::vector<unsigned> & EndBits,std::vector<uint64_t> & FieldVals,const insn_t & Insn) const10162754fe60SDimitry Andric unsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits,
1017dff0c46cSDimitry Andric std::vector<unsigned> &EndBits,
1018dff0c46cSDimitry Andric std::vector<uint64_t> &FieldVals,
1019dff0c46cSDimitry Andric const insn_t &Insn) const {
10202754fe60SDimitry Andric unsigned Num, BitNo;
10212754fe60SDimitry Andric Num = BitNo = 0;
10222754fe60SDimitry Andric
10232754fe60SDimitry Andric uint64_t FieldVal = 0;
10242754fe60SDimitry Andric
10252754fe60SDimitry Andric // 0: Init
10262754fe60SDimitry Andric // 1: Water (the bit value does not affect decoding)
10272754fe60SDimitry Andric // 2: Island (well-known bit value needed for decoding)
10282754fe60SDimitry Andric int State = 0;
10292754fe60SDimitry Andric int Val = -1;
10302754fe60SDimitry Andric
10316122f3e6SDimitry Andric for (unsigned i = 0; i < BitWidth; ++i) {
10322754fe60SDimitry Andric Val = Value(Insn[i]);
10332754fe60SDimitry Andric bool Filtered = PositionFiltered(i);
10342754fe60SDimitry Andric switch (State) {
1035dff0c46cSDimitry Andric default: llvm_unreachable("Unreachable code!");
10362754fe60SDimitry Andric case 0:
10372754fe60SDimitry Andric case 1:
10382754fe60SDimitry Andric if (Filtered || Val == -1)
10392754fe60SDimitry Andric State = 1; // Still in Water
10402754fe60SDimitry Andric else {
10412754fe60SDimitry Andric State = 2; // Into the Island
10422754fe60SDimitry Andric BitNo = 0;
10432754fe60SDimitry Andric StartBits.push_back(i);
10442754fe60SDimitry Andric FieldVal = Val;
10452754fe60SDimitry Andric }
10462754fe60SDimitry Andric break;
10472754fe60SDimitry Andric case 2:
10482754fe60SDimitry Andric if (Filtered || Val == -1) {
10492754fe60SDimitry Andric State = 1; // Into the Water
10502754fe60SDimitry Andric EndBits.push_back(i - 1);
10512754fe60SDimitry Andric FieldVals.push_back(FieldVal);
10522754fe60SDimitry Andric ++Num;
10532754fe60SDimitry Andric } else {
10542754fe60SDimitry Andric State = 2; // Still in Island
10552754fe60SDimitry Andric ++BitNo;
10562754fe60SDimitry Andric FieldVal = FieldVal | Val << BitNo;
10572754fe60SDimitry Andric }
10582754fe60SDimitry Andric break;
10592754fe60SDimitry Andric }
10602754fe60SDimitry Andric }
10612754fe60SDimitry Andric // If we are still in Island after the loop, do some housekeeping.
10622754fe60SDimitry Andric if (State == 2) {
10636122f3e6SDimitry Andric EndBits.push_back(BitWidth - 1);
10642754fe60SDimitry Andric FieldVals.push_back(FieldVal);
10652754fe60SDimitry Andric ++Num;
10662754fe60SDimitry Andric }
10672754fe60SDimitry Andric
10682754fe60SDimitry Andric assert(StartBits.size() == Num && EndBits.size() == Num &&
10692754fe60SDimitry Andric FieldVals.size() == Num);
10702754fe60SDimitry Andric return Num;
10712754fe60SDimitry Andric }
10722754fe60SDimitry Andric
emitBinaryParser(raw_ostream & o,unsigned & Indentation,const OperandInfo & OpInfo,bool & OpHasCompleteDecoder) const10736122f3e6SDimitry Andric void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
10747d523365SDimitry Andric const OperandInfo &OpInfo,
10757d523365SDimitry Andric bool &OpHasCompleteDecoder) const {
1076dff0c46cSDimitry Andric const std::string &Decoder = OpInfo.Decoder;
10776122f3e6SDimitry Andric
107839d628a0SDimitry Andric if (OpInfo.numFields() != 1)
10796122f3e6SDimitry Andric o.indent(Indentation) << "tmp = 0;\n";
108039d628a0SDimitry Andric
108139d628a0SDimitry Andric for (const EncodingField &EF : OpInfo) {
108239d628a0SDimitry Andric o.indent(Indentation) << "tmp ";
108339d628a0SDimitry Andric if (OpInfo.numFields() != 1) o << '|';
108439d628a0SDimitry Andric o << "= fieldFromInstruction"
108539d628a0SDimitry Andric << "(insn, " << EF.Base << ", " << EF.Width << ')';
108639d628a0SDimitry Andric if (OpInfo.numFields() != 1 || EF.Offset != 0)
108739d628a0SDimitry Andric o << " << " << EF.Offset;
108839d628a0SDimitry Andric o << ";\n";
10896122f3e6SDimitry Andric }
10906122f3e6SDimitry Andric
10917d523365SDimitry Andric if (Decoder != "") {
10927d523365SDimitry Andric OpHasCompleteDecoder = OpInfo.HasCompleteDecoder;
10937ae0e2c9SDimitry Andric o.indent(Indentation) << Emitter->GuardPrefix << Decoder
1094dff0c46cSDimitry Andric << "(MI, tmp, Address, Decoder)"
10957d523365SDimitry Andric << Emitter->GuardPostfix
10967d523365SDimitry Andric << " { " << (OpHasCompleteDecoder ? "" : "DecodeComplete = false; ")
10977d523365SDimitry Andric << "return MCDisassembler::Fail; }\n";
10987d523365SDimitry Andric } else {
10997d523365SDimitry Andric OpHasCompleteDecoder = true;
1100ff0cc061SDimitry Andric o.indent(Indentation) << "MI.addOperand(MCOperand::createImm(tmp));\n";
11017d523365SDimitry Andric }
11026122f3e6SDimitry Andric }
11036122f3e6SDimitry Andric
emitDecoder(raw_ostream & OS,unsigned Indentation,unsigned Opc,bool & HasCompleteDecoder) const11047ae0e2c9SDimitry Andric void FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation,
11057d523365SDimitry Andric unsigned Opc, bool &HasCompleteDecoder) const {
11067d523365SDimitry Andric HasCompleteDecoder = true;
11077d523365SDimitry Andric
110839d628a0SDimitry Andric for (const auto &Op : Operands.find(Opc)->second) {
11097ae0e2c9SDimitry Andric // If a custom instruction decoder was specified, use that.
1110d88c1a5aSDimitry Andric if (Op.numFields() == 0 && !Op.Decoder.empty()) {
11117d523365SDimitry Andric HasCompleteDecoder = Op.HasCompleteDecoder;
111239d628a0SDimitry Andric OS.indent(Indentation) << Emitter->GuardPrefix << Op.Decoder
11137ae0e2c9SDimitry Andric << "(MI, insn, Address, Decoder)"
11147d523365SDimitry Andric << Emitter->GuardPostfix
11157d523365SDimitry Andric << " { " << (HasCompleteDecoder ? "" : "DecodeComplete = false; ")
11167d523365SDimitry Andric << "return MCDisassembler::Fail; }\n";
11177ae0e2c9SDimitry Andric break;
11187ae0e2c9SDimitry Andric }
11197ae0e2c9SDimitry Andric
11207d523365SDimitry Andric bool OpHasCompleteDecoder;
11217d523365SDimitry Andric emitBinaryParser(OS, Indentation, Op, OpHasCompleteDecoder);
11227d523365SDimitry Andric if (!OpHasCompleteDecoder)
11237d523365SDimitry Andric HasCompleteDecoder = false;
11247ae0e2c9SDimitry Andric }
11257ae0e2c9SDimitry Andric }
11267ae0e2c9SDimitry Andric
getDecoderIndex(DecoderSet & Decoders,unsigned Opc,bool & HasCompleteDecoder) const11277ae0e2c9SDimitry Andric unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders,
11287d523365SDimitry Andric unsigned Opc,
11297d523365SDimitry Andric bool &HasCompleteDecoder) const {
11307ae0e2c9SDimitry Andric // Build up the predicate string.
11317ae0e2c9SDimitry Andric SmallString<256> Decoder;
11327ae0e2c9SDimitry Andric // FIXME: emitDecoder() function can take a buffer directly rather than
11337ae0e2c9SDimitry Andric // a stream.
11347ae0e2c9SDimitry Andric raw_svector_ostream S(Decoder);
11357ae0e2c9SDimitry Andric unsigned I = 4;
11367d523365SDimitry Andric emitDecoder(S, I, Opc, HasCompleteDecoder);
11377ae0e2c9SDimitry Andric
11387ae0e2c9SDimitry Andric // Using the full decoder string as the key value here is a bit
11397ae0e2c9SDimitry Andric // heavyweight, but is effective. If the string comparisons become a
11407ae0e2c9SDimitry Andric // performance concern, we can implement a mangling of the predicate
11417d523365SDimitry Andric // data easily enough with a map back to the actual string. That's
11427ae0e2c9SDimitry Andric // overkill for now, though.
11437ae0e2c9SDimitry Andric
11447ae0e2c9SDimitry Andric // Make sure the predicate is in the table.
1145d88c1a5aSDimitry Andric Decoders.insert(CachedHashString(Decoder));
11467ae0e2c9SDimitry Andric // Now figure out the index for when we write out the table.
1147d88c1a5aSDimitry Andric DecoderSet::const_iterator P = find(Decoders, Decoder.str());
11487ae0e2c9SDimitry Andric return (unsigned)(P - Decoders.begin());
11497ae0e2c9SDimitry Andric }
11507ae0e2c9SDimitry Andric
emitSinglePredicateMatch(raw_ostream & o,StringRef str,const std::string & PredicateNamespace)11516122f3e6SDimitry Andric static void emitSinglePredicateMatch(raw_ostream &o, StringRef str,
1152dff0c46cSDimitry Andric const std::string &PredicateNamespace) {
11536122f3e6SDimitry Andric if (str[0] == '!')
1154ff0cc061SDimitry Andric o << "!Bits[" << PredicateNamespace << "::"
1155ff0cc061SDimitry Andric << str.slice(1,str.size()) << "]";
11566122f3e6SDimitry Andric else
1157ff0cc061SDimitry Andric o << "Bits[" << PredicateNamespace << "::" << str << "]";
11586122f3e6SDimitry Andric }
11596122f3e6SDimitry Andric
emitPredicateMatch(raw_ostream & o,unsigned & Indentation,unsigned Opc) const11606122f3e6SDimitry Andric bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
1161dff0c46cSDimitry Andric unsigned Opc) const {
1162dff0c46cSDimitry Andric ListInit *Predicates =
1163*b5893f02SDimitry Andric AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
1164ff0cc061SDimitry Andric bool IsFirstEmission = true;
116597bc6c73SDimitry Andric for (unsigned i = 0; i < Predicates->size(); ++i) {
11666122f3e6SDimitry Andric Record *Pred = Predicates->getElementAsRecord(i);
11676122f3e6SDimitry Andric if (!Pred->getValue("AssemblerMatcherPredicate"))
11686122f3e6SDimitry Andric continue;
11696122f3e6SDimitry Andric
1170f9448bf3SDimitry Andric StringRef P = Pred->getValueAsString("AssemblerCondString");
11716122f3e6SDimitry Andric
1172f9448bf3SDimitry Andric if (P.empty())
11736122f3e6SDimitry Andric continue;
11746122f3e6SDimitry Andric
1175ff0cc061SDimitry Andric if (!IsFirstEmission)
11766122f3e6SDimitry Andric o << " && ";
11776122f3e6SDimitry Andric
1178f9448bf3SDimitry Andric std::pair<StringRef, StringRef> pairs = P.split(',');
1179d88c1a5aSDimitry Andric while (!pairs.second.empty()) {
11806122f3e6SDimitry Andric emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace);
11816122f3e6SDimitry Andric o << " && ";
11826122f3e6SDimitry Andric pairs = pairs.second.split(',');
11836122f3e6SDimitry Andric }
11846122f3e6SDimitry Andric emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace);
1185ff0cc061SDimitry Andric IsFirstEmission = false;
11866122f3e6SDimitry Andric }
118797bc6c73SDimitry Andric return !Predicates->empty();
11886122f3e6SDimitry Andric }
11896122f3e6SDimitry Andric
doesOpcodeNeedPredicate(unsigned Opc) const11907ae0e2c9SDimitry Andric bool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const {
11917ae0e2c9SDimitry Andric ListInit *Predicates =
1192*b5893f02SDimitry Andric AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
119397bc6c73SDimitry Andric for (unsigned i = 0; i < Predicates->size(); ++i) {
11947ae0e2c9SDimitry Andric Record *Pred = Predicates->getElementAsRecord(i);
11957ae0e2c9SDimitry Andric if (!Pred->getValue("AssemblerMatcherPredicate"))
11967ae0e2c9SDimitry Andric continue;
11977ae0e2c9SDimitry Andric
1198f9448bf3SDimitry Andric StringRef P = Pred->getValueAsString("AssemblerCondString");
11997ae0e2c9SDimitry Andric
1200f9448bf3SDimitry Andric if (P.empty())
12017ae0e2c9SDimitry Andric continue;
12027ae0e2c9SDimitry Andric
12037ae0e2c9SDimitry Andric return true;
12047ae0e2c9SDimitry Andric }
12057ae0e2c9SDimitry Andric return false;
12067ae0e2c9SDimitry Andric }
12077ae0e2c9SDimitry Andric
getPredicateIndex(DecoderTableInfo & TableInfo,StringRef Predicate) const12087ae0e2c9SDimitry Andric unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo,
12097ae0e2c9SDimitry Andric StringRef Predicate) const {
12107ae0e2c9SDimitry Andric // Using the full predicate string as the key value here is a bit
12117ae0e2c9SDimitry Andric // heavyweight, but is effective. If the string comparisons become a
12127ae0e2c9SDimitry Andric // performance concern, we can implement a mangling of the predicate
12137d523365SDimitry Andric // data easily enough with a map back to the actual string. That's
12147ae0e2c9SDimitry Andric // overkill for now, though.
12157ae0e2c9SDimitry Andric
12167ae0e2c9SDimitry Andric // Make sure the predicate is in the table.
1217d88c1a5aSDimitry Andric TableInfo.Predicates.insert(CachedHashString(Predicate));
12187ae0e2c9SDimitry Andric // Now figure out the index for when we write out the table.
1219d88c1a5aSDimitry Andric PredicateSet::const_iterator P = find(TableInfo.Predicates, Predicate);
12207ae0e2c9SDimitry Andric return (unsigned)(P - TableInfo.Predicates.begin());
12217ae0e2c9SDimitry Andric }
12227ae0e2c9SDimitry Andric
emitPredicateTableEntry(DecoderTableInfo & TableInfo,unsigned Opc) const12237ae0e2c9SDimitry Andric void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo,
12247ae0e2c9SDimitry Andric unsigned Opc) const {
12257ae0e2c9SDimitry Andric if (!doesOpcodeNeedPredicate(Opc))
12267ae0e2c9SDimitry Andric return;
12277ae0e2c9SDimitry Andric
12287ae0e2c9SDimitry Andric // Build up the predicate string.
12297ae0e2c9SDimitry Andric SmallString<256> Predicate;
12307ae0e2c9SDimitry Andric // FIXME: emitPredicateMatch() functions can take a buffer directly rather
12317ae0e2c9SDimitry Andric // than a stream.
12327ae0e2c9SDimitry Andric raw_svector_ostream PS(Predicate);
12337ae0e2c9SDimitry Andric unsigned I = 0;
12347ae0e2c9SDimitry Andric emitPredicateMatch(PS, I, Opc);
12357ae0e2c9SDimitry Andric
12367ae0e2c9SDimitry Andric // Figure out the index into the predicate table for the predicate just
12377ae0e2c9SDimitry Andric // computed.
12387ae0e2c9SDimitry Andric unsigned PIdx = getPredicateIndex(TableInfo, PS.str());
12397ae0e2c9SDimitry Andric SmallString<16> PBytes;
12407ae0e2c9SDimitry Andric raw_svector_ostream S(PBytes);
12417ae0e2c9SDimitry Andric encodeULEB128(PIdx, S);
12427ae0e2c9SDimitry Andric
12437ae0e2c9SDimitry Andric TableInfo.Table.push_back(MCD::OPC_CheckPredicate);
12447ae0e2c9SDimitry Andric // Predicate index
12457ae0e2c9SDimitry Andric for (unsigned i = 0, e = PBytes.size(); i != e; ++i)
12467ae0e2c9SDimitry Andric TableInfo.Table.push_back(PBytes[i]);
12477ae0e2c9SDimitry Andric // Push location for NumToSkip backpatching.
12487ae0e2c9SDimitry Andric TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
12497ae0e2c9SDimitry Andric TableInfo.Table.push_back(0);
12507ae0e2c9SDimitry Andric TableInfo.Table.push_back(0);
12514ba319b5SDimitry Andric TableInfo.Table.push_back(0);
12527ae0e2c9SDimitry Andric }
12537ae0e2c9SDimitry Andric
emitSoftFailTableEntry(DecoderTableInfo & TableInfo,unsigned Opc) const12547ae0e2c9SDimitry Andric void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
1255dff0c46cSDimitry Andric unsigned Opc) const {
1256dff0c46cSDimitry Andric BitsInit *SFBits =
1257*b5893f02SDimitry Andric AllInstructions[Opc].EncodingDef->getValueAsBitsInit("SoftFail");
1258dff0c46cSDimitry Andric if (!SFBits) return;
1259*b5893f02SDimitry Andric BitsInit *InstBits =
1260*b5893f02SDimitry Andric AllInstructions[Opc].EncodingDef->getValueAsBitsInit("Inst");
1261dff0c46cSDimitry Andric
1262dff0c46cSDimitry Andric APInt PositiveMask(BitWidth, 0ULL);
1263dff0c46cSDimitry Andric APInt NegativeMask(BitWidth, 0ULL);
1264dff0c46cSDimitry Andric for (unsigned i = 0; i < BitWidth; ++i) {
1265dff0c46cSDimitry Andric bit_value_t B = bitFromBits(*SFBits, i);
1266dff0c46cSDimitry Andric bit_value_t IB = bitFromBits(*InstBits, i);
1267dff0c46cSDimitry Andric
1268dff0c46cSDimitry Andric if (B != BIT_TRUE) continue;
1269dff0c46cSDimitry Andric
1270dff0c46cSDimitry Andric switch (IB) {
1271dff0c46cSDimitry Andric case BIT_FALSE:
1272dff0c46cSDimitry Andric // The bit is meant to be false, so emit a check to see if it is true.
1273dff0c46cSDimitry Andric PositiveMask.setBit(i);
1274dff0c46cSDimitry Andric break;
1275dff0c46cSDimitry Andric case BIT_TRUE:
1276dff0c46cSDimitry Andric // The bit is meant to be true, so emit a check to see if it is false.
1277dff0c46cSDimitry Andric NegativeMask.setBit(i);
1278dff0c46cSDimitry Andric break;
1279dff0c46cSDimitry Andric default:
1280dff0c46cSDimitry Andric // The bit is not set; this must be an error!
1281*b5893f02SDimitry Andric errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in "
1282*b5893f02SDimitry Andric << AllInstructions[Opc] << " is set but Inst{" << i
1283*b5893f02SDimitry Andric << "} is unset!\n"
1284dff0c46cSDimitry Andric << " - You can only mark a bit as SoftFail if it is fully defined"
1285dff0c46cSDimitry Andric << " (1/0 - not '?') in Inst\n";
12867ae0e2c9SDimitry Andric return;
1287dff0c46cSDimitry Andric }
1288dff0c46cSDimitry Andric }
1289dff0c46cSDimitry Andric
1290dff0c46cSDimitry Andric bool NeedPositiveMask = PositiveMask.getBoolValue();
1291dff0c46cSDimitry Andric bool NeedNegativeMask = NegativeMask.getBoolValue();
1292dff0c46cSDimitry Andric
1293dff0c46cSDimitry Andric if (!NeedPositiveMask && !NeedNegativeMask)
1294dff0c46cSDimitry Andric return;
1295dff0c46cSDimitry Andric
12967ae0e2c9SDimitry Andric TableInfo.Table.push_back(MCD::OPC_SoftFail);
1297dff0c46cSDimitry Andric
12987ae0e2c9SDimitry Andric SmallString<16> MaskBytes;
12997ae0e2c9SDimitry Andric raw_svector_ostream S(MaskBytes);
13007ae0e2c9SDimitry Andric if (NeedPositiveMask) {
13017ae0e2c9SDimitry Andric encodeULEB128(PositiveMask.getZExtValue(), S);
13027ae0e2c9SDimitry Andric for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i)
13037ae0e2c9SDimitry Andric TableInfo.Table.push_back(MaskBytes[i]);
13047ae0e2c9SDimitry Andric } else
13057ae0e2c9SDimitry Andric TableInfo.Table.push_back(0);
13067ae0e2c9SDimitry Andric if (NeedNegativeMask) {
13077ae0e2c9SDimitry Andric MaskBytes.clear();
13087ae0e2c9SDimitry Andric encodeULEB128(NegativeMask.getZExtValue(), S);
13097ae0e2c9SDimitry Andric for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i)
13107ae0e2c9SDimitry Andric TableInfo.Table.push_back(MaskBytes[i]);
13117ae0e2c9SDimitry Andric } else
13127ae0e2c9SDimitry Andric TableInfo.Table.push_back(0);
1313dff0c46cSDimitry Andric }
1314dff0c46cSDimitry Andric
13157ae0e2c9SDimitry Andric // Emits table entries to decode the singleton.
emitSingletonTableEntry(DecoderTableInfo & TableInfo,unsigned Opc) const13167ae0e2c9SDimitry Andric void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1317dff0c46cSDimitry Andric unsigned Opc) const {
13182754fe60SDimitry Andric std::vector<unsigned> StartBits;
13192754fe60SDimitry Andric std::vector<unsigned> EndBits;
13202754fe60SDimitry Andric std::vector<uint64_t> FieldVals;
13212754fe60SDimitry Andric insn_t Insn;
13222754fe60SDimitry Andric insnWithID(Insn, Opc);
13232754fe60SDimitry Andric
13242754fe60SDimitry Andric // Look for islands of undecoded bits of the singleton.
13252754fe60SDimitry Andric getIslands(StartBits, EndBits, FieldVals, Insn);
13262754fe60SDimitry Andric
13272754fe60SDimitry Andric unsigned Size = StartBits.size();
13282754fe60SDimitry Andric
13297ae0e2c9SDimitry Andric // Emit the predicate table entry if one is needed.
13307ae0e2c9SDimitry Andric emitPredicateTableEntry(TableInfo, Opc);
13317ae0e2c9SDimitry Andric
13327ae0e2c9SDimitry Andric // Check any additional encoding fields needed.
13337ae0e2c9SDimitry Andric for (unsigned I = Size; I != 0; --I) {
13347ae0e2c9SDimitry Andric unsigned NumBits = EndBits[I-1] - StartBits[I-1] + 1;
13357ae0e2c9SDimitry Andric TableInfo.Table.push_back(MCD::OPC_CheckField);
13367ae0e2c9SDimitry Andric TableInfo.Table.push_back(StartBits[I-1]);
13377ae0e2c9SDimitry Andric TableInfo.Table.push_back(NumBits);
13384ba319b5SDimitry Andric uint8_t Buffer[16], *p;
13397ae0e2c9SDimitry Andric encodeULEB128(FieldVals[I-1], Buffer);
13407ae0e2c9SDimitry Andric for (p = Buffer; *p >= 128 ; ++p)
13417ae0e2c9SDimitry Andric TableInfo.Table.push_back(*p);
13427ae0e2c9SDimitry Andric TableInfo.Table.push_back(*p);
13437ae0e2c9SDimitry Andric // Push location for NumToSkip backpatching.
13447ae0e2c9SDimitry Andric TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
13454ba319b5SDimitry Andric // The fixup is always 24-bits, so go ahead and allocate the space
13467ae0e2c9SDimitry Andric // in the table so all our relative position calculations work OK even
13477ae0e2c9SDimitry Andric // before we fully resolve the real value here.
13487ae0e2c9SDimitry Andric TableInfo.Table.push_back(0);
13497ae0e2c9SDimitry Andric TableInfo.Table.push_back(0);
13504ba319b5SDimitry Andric TableInfo.Table.push_back(0);
13512754fe60SDimitry Andric }
13522754fe60SDimitry Andric
13537ae0e2c9SDimitry Andric // Check for soft failure of the match.
13547ae0e2c9SDimitry Andric emitSoftFailTableEntry(TableInfo, Opc);
13557ae0e2c9SDimitry Andric
13567d523365SDimitry Andric bool HasCompleteDecoder;
13577d523365SDimitry Andric unsigned DIdx = getDecoderIndex(TableInfo.Decoders, Opc, HasCompleteDecoder);
13587d523365SDimitry Andric
13597d523365SDimitry Andric // Produce OPC_Decode or OPC_TryDecode opcode based on the information
13607d523365SDimitry Andric // whether the instruction decoder is complete or not. If it is complete
13617d523365SDimitry Andric // then it handles all possible values of remaining variable/unfiltered bits
13627d523365SDimitry Andric // and for any value can determine if the bitpattern is a valid instruction
13637d523365SDimitry Andric // or not. This means OPC_Decode will be the final step in the decoding
13647d523365SDimitry Andric // process. If it is not complete, then the Fail return code from the
13657d523365SDimitry Andric // decoder method indicates that additional processing should be done to see
13667d523365SDimitry Andric // if there is any other instruction that also matches the bitpattern and
13677d523365SDimitry Andric // can decode it.
13687d523365SDimitry Andric TableInfo.Table.push_back(HasCompleteDecoder ? MCD::OPC_Decode :
13697d523365SDimitry Andric MCD::OPC_TryDecode);
13704ba319b5SDimitry Andric uint8_t Buffer[16], *p;
13717ae0e2c9SDimitry Andric encodeULEB128(Opc, Buffer);
13727ae0e2c9SDimitry Andric for (p = Buffer; *p >= 128 ; ++p)
13737ae0e2c9SDimitry Andric TableInfo.Table.push_back(*p);
13747ae0e2c9SDimitry Andric TableInfo.Table.push_back(*p);
13757ae0e2c9SDimitry Andric
13767ae0e2c9SDimitry Andric SmallString<16> Bytes;
13777ae0e2c9SDimitry Andric raw_svector_ostream S(Bytes);
13787ae0e2c9SDimitry Andric encodeULEB128(DIdx, S);
13797ae0e2c9SDimitry Andric
13807ae0e2c9SDimitry Andric // Decoder index
13817ae0e2c9SDimitry Andric for (unsigned i = 0, e = Bytes.size(); i != e; ++i)
13827ae0e2c9SDimitry Andric TableInfo.Table.push_back(Bytes[i]);
13837d523365SDimitry Andric
13847d523365SDimitry Andric if (!HasCompleteDecoder) {
13857d523365SDimitry Andric // Push location for NumToSkip backpatching.
13867d523365SDimitry Andric TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
13877d523365SDimitry Andric // Allocate the space for the fixup.
13887d523365SDimitry Andric TableInfo.Table.push_back(0);
13897d523365SDimitry Andric TableInfo.Table.push_back(0);
13904ba319b5SDimitry Andric TableInfo.Table.push_back(0);
13917d523365SDimitry Andric }
13922754fe60SDimitry Andric }
13932754fe60SDimitry Andric
13947ae0e2c9SDimitry Andric // Emits table entries to decode the singleton, and then to decode the rest.
emitSingletonTableEntry(DecoderTableInfo & TableInfo,const Filter & Best) const13957ae0e2c9SDimitry Andric void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1396dff0c46cSDimitry Andric const Filter &Best) const {
13972754fe60SDimitry Andric unsigned Opc = Best.getSingletonOpc();
13982754fe60SDimitry Andric
13997ae0e2c9SDimitry Andric // complex singletons need predicate checks from the first singleton
14007ae0e2c9SDimitry Andric // to refer forward to the variable filterchooser that follows.
140197bc6c73SDimitry Andric TableInfo.FixupStack.emplace_back();
14022754fe60SDimitry Andric
14037ae0e2c9SDimitry Andric emitSingletonTableEntry(TableInfo, Opc);
14042754fe60SDimitry Andric
14057ae0e2c9SDimitry Andric resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
14067ae0e2c9SDimitry Andric TableInfo.Table.size());
14077ae0e2c9SDimitry Andric TableInfo.FixupStack.pop_back();
14087ae0e2c9SDimitry Andric
14097ae0e2c9SDimitry Andric Best.getVariableFC().emitTableEntries(TableInfo);
14102754fe60SDimitry Andric }
14112754fe60SDimitry Andric
14122754fe60SDimitry Andric // Assign a single filter and run with it. Top level API client can initialize
14132754fe60SDimitry Andric // with a single filter to start the filtering process.
runSingleFilter(unsigned startBit,unsigned numBit,bool mixed)1414dff0c46cSDimitry Andric void FilterChooser::runSingleFilter(unsigned startBit, unsigned numBit,
1415dff0c46cSDimitry Andric bool mixed) {
14162754fe60SDimitry Andric Filters.clear();
141797bc6c73SDimitry Andric Filters.emplace_back(*this, startBit, numBit, true);
14182754fe60SDimitry Andric BestIndex = 0; // Sole Filter instance to choose from.
14192754fe60SDimitry Andric bestFilter().recurse();
14202754fe60SDimitry Andric }
14212754fe60SDimitry Andric
14222754fe60SDimitry Andric // reportRegion is a helper function for filterProcessor to mark a region as
14232754fe60SDimitry Andric // eligible for use as a filter region.
reportRegion(bitAttr_t RA,unsigned StartBit,unsigned BitIndex,bool AllowMixed)14242754fe60SDimitry Andric void FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit,
14252754fe60SDimitry Andric unsigned BitIndex, bool AllowMixed) {
14262754fe60SDimitry Andric if (RA == ATTR_MIXED && AllowMixed)
142797bc6c73SDimitry Andric Filters.emplace_back(*this, StartBit, BitIndex - StartBit, true);
14282754fe60SDimitry Andric else if (RA == ATTR_ALL_SET && !AllowMixed)
142997bc6c73SDimitry Andric Filters.emplace_back(*this, StartBit, BitIndex - StartBit, false);
14302754fe60SDimitry Andric }
14312754fe60SDimitry Andric
14322754fe60SDimitry Andric // FilterProcessor scans the well-known encoding bits of the instructions and
14332754fe60SDimitry Andric // builds up a list of candidate filters. It chooses the best filter and
14342754fe60SDimitry Andric // recursively descends down the decoding tree.
filterProcessor(bool AllowMixed,bool Greedy)14352754fe60SDimitry Andric bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
14362754fe60SDimitry Andric Filters.clear();
14372754fe60SDimitry Andric BestIndex = -1;
14382754fe60SDimitry Andric unsigned numInstructions = Opcodes.size();
14392754fe60SDimitry Andric
14402754fe60SDimitry Andric assert(numInstructions && "Filter created with no instructions");
14412754fe60SDimitry Andric
14422754fe60SDimitry Andric // No further filtering is necessary.
14432754fe60SDimitry Andric if (numInstructions == 1)
14442754fe60SDimitry Andric return true;
14452754fe60SDimitry Andric
14462754fe60SDimitry Andric // Heuristics. See also doFilter()'s "Heuristics" comment when num of
14472754fe60SDimitry Andric // instructions is 3.
14482754fe60SDimitry Andric if (AllowMixed && !Greedy) {
14492754fe60SDimitry Andric assert(numInstructions == 3);
14502754fe60SDimitry Andric
14512754fe60SDimitry Andric for (unsigned i = 0; i < Opcodes.size(); ++i) {
14522754fe60SDimitry Andric std::vector<unsigned> StartBits;
14532754fe60SDimitry Andric std::vector<unsigned> EndBits;
14542754fe60SDimitry Andric std::vector<uint64_t> FieldVals;
14552754fe60SDimitry Andric insn_t Insn;
14562754fe60SDimitry Andric
14572754fe60SDimitry Andric insnWithID(Insn, Opcodes[i]);
14582754fe60SDimitry Andric
14592754fe60SDimitry Andric // Look for islands of undecoded bits of any instruction.
14602754fe60SDimitry Andric if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) {
14612754fe60SDimitry Andric // Found an instruction with island(s). Now just assign a filter.
1462dff0c46cSDimitry Andric runSingleFilter(StartBits[0], EndBits[0] - StartBits[0] + 1, true);
14632754fe60SDimitry Andric return true;
14642754fe60SDimitry Andric }
14652754fe60SDimitry Andric }
14662754fe60SDimitry Andric }
14672754fe60SDimitry Andric
14687ae0e2c9SDimitry Andric unsigned BitIndex;
14692754fe60SDimitry Andric
14702754fe60SDimitry Andric // We maintain BIT_WIDTH copies of the bitAttrs automaton.
14712754fe60SDimitry Andric // The automaton consumes the corresponding bit from each
14722754fe60SDimitry Andric // instruction.
14732754fe60SDimitry Andric //
14742754fe60SDimitry Andric // Input symbols: 0, 1, and _ (unset).
14752754fe60SDimitry Andric // States: NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED.
14762754fe60SDimitry Andric // Initial state: NONE.
14772754fe60SDimitry Andric //
14782754fe60SDimitry Andric // (NONE) ------- [01] -> (ALL_SET)
14792754fe60SDimitry Andric // (NONE) ------- _ ----> (ALL_UNSET)
14802754fe60SDimitry Andric // (ALL_SET) ---- [01] -> (ALL_SET)
14812754fe60SDimitry Andric // (ALL_SET) ---- _ ----> (MIXED)
14822754fe60SDimitry Andric // (ALL_UNSET) -- [01] -> (MIXED)
14832754fe60SDimitry Andric // (ALL_UNSET) -- _ ----> (ALL_UNSET)
14842754fe60SDimitry Andric // (MIXED) ------ . ----> (MIXED)
14852754fe60SDimitry Andric // (FILTERED)---- . ----> (FILTERED)
14862754fe60SDimitry Andric
14876122f3e6SDimitry Andric std::vector<bitAttr_t> bitAttrs;
14882754fe60SDimitry Andric
14892754fe60SDimitry Andric // FILTERED bit positions provide no entropy and are not worthy of pursuing.
14902754fe60SDimitry Andric // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position.
14916122f3e6SDimitry Andric for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex)
14922754fe60SDimitry Andric if (FilterBitValues[BitIndex] == BIT_TRUE ||
14932754fe60SDimitry Andric FilterBitValues[BitIndex] == BIT_FALSE)
14946122f3e6SDimitry Andric bitAttrs.push_back(ATTR_FILTERED);
14952754fe60SDimitry Andric else
14966122f3e6SDimitry Andric bitAttrs.push_back(ATTR_NONE);
14972754fe60SDimitry Andric
14987ae0e2c9SDimitry Andric for (unsigned InsnIndex = 0; InsnIndex < numInstructions; ++InsnIndex) {
14992754fe60SDimitry Andric insn_t insn;
15002754fe60SDimitry Andric
15012754fe60SDimitry Andric insnWithID(insn, Opcodes[InsnIndex]);
15022754fe60SDimitry Andric
15036122f3e6SDimitry Andric for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
15042754fe60SDimitry Andric switch (bitAttrs[BitIndex]) {
15052754fe60SDimitry Andric case ATTR_NONE:
15062754fe60SDimitry Andric if (insn[BitIndex] == BIT_UNSET)
15072754fe60SDimitry Andric bitAttrs[BitIndex] = ATTR_ALL_UNSET;
15082754fe60SDimitry Andric else
15092754fe60SDimitry Andric bitAttrs[BitIndex] = ATTR_ALL_SET;
15102754fe60SDimitry Andric break;
15112754fe60SDimitry Andric case ATTR_ALL_SET:
15122754fe60SDimitry Andric if (insn[BitIndex] == BIT_UNSET)
15132754fe60SDimitry Andric bitAttrs[BitIndex] = ATTR_MIXED;
15142754fe60SDimitry Andric break;
15152754fe60SDimitry Andric case ATTR_ALL_UNSET:
15162754fe60SDimitry Andric if (insn[BitIndex] != BIT_UNSET)
15172754fe60SDimitry Andric bitAttrs[BitIndex] = ATTR_MIXED;
15182754fe60SDimitry Andric break;
15192754fe60SDimitry Andric case ATTR_MIXED:
15202754fe60SDimitry Andric case ATTR_FILTERED:
15212754fe60SDimitry Andric break;
15222754fe60SDimitry Andric }
15232754fe60SDimitry Andric }
15242754fe60SDimitry Andric }
15252754fe60SDimitry Andric
15262754fe60SDimitry Andric // The regionAttr automaton consumes the bitAttrs automatons' state,
15272754fe60SDimitry Andric // lowest-to-highest.
15282754fe60SDimitry Andric //
15292754fe60SDimitry Andric // Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed)
15302754fe60SDimitry Andric // States: NONE, ALL_SET, MIXED
15312754fe60SDimitry Andric // Initial state: NONE
15322754fe60SDimitry Andric //
15332754fe60SDimitry Andric // (NONE) ----- F --> (NONE)
15342754fe60SDimitry Andric // (NONE) ----- S --> (ALL_SET) ; and set region start
15352754fe60SDimitry Andric // (NONE) ----- U --> (NONE)
15362754fe60SDimitry Andric // (NONE) ----- M --> (MIXED) ; and set region start
15372754fe60SDimitry Andric // (ALL_SET) -- F --> (NONE) ; and report an ALL_SET region
15382754fe60SDimitry Andric // (ALL_SET) -- S --> (ALL_SET)
15392754fe60SDimitry Andric // (ALL_SET) -- U --> (NONE) ; and report an ALL_SET region
15402754fe60SDimitry Andric // (ALL_SET) -- M --> (MIXED) ; and report an ALL_SET region
15412754fe60SDimitry Andric // (MIXED) ---- F --> (NONE) ; and report a MIXED region
15422754fe60SDimitry Andric // (MIXED) ---- S --> (ALL_SET) ; and report a MIXED region
15432754fe60SDimitry Andric // (MIXED) ---- U --> (NONE) ; and report a MIXED region
15442754fe60SDimitry Andric // (MIXED) ---- M --> (MIXED)
15452754fe60SDimitry Andric
15462754fe60SDimitry Andric bitAttr_t RA = ATTR_NONE;
15472754fe60SDimitry Andric unsigned StartBit = 0;
15482754fe60SDimitry Andric
15497ae0e2c9SDimitry Andric for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
15502754fe60SDimitry Andric bitAttr_t bitAttr = bitAttrs[BitIndex];
15512754fe60SDimitry Andric
15522754fe60SDimitry Andric assert(bitAttr != ATTR_NONE && "Bit without attributes");
15532754fe60SDimitry Andric
15542754fe60SDimitry Andric switch (RA) {
15552754fe60SDimitry Andric case ATTR_NONE:
15562754fe60SDimitry Andric switch (bitAttr) {
15572754fe60SDimitry Andric case ATTR_FILTERED:
15582754fe60SDimitry Andric break;
15592754fe60SDimitry Andric case ATTR_ALL_SET:
15602754fe60SDimitry Andric StartBit = BitIndex;
15612754fe60SDimitry Andric RA = ATTR_ALL_SET;
15622754fe60SDimitry Andric break;
15632754fe60SDimitry Andric case ATTR_ALL_UNSET:
15642754fe60SDimitry Andric break;
15652754fe60SDimitry Andric case ATTR_MIXED:
15662754fe60SDimitry Andric StartBit = BitIndex;
15672754fe60SDimitry Andric RA = ATTR_MIXED;
15682754fe60SDimitry Andric break;
15692754fe60SDimitry Andric default:
1570dff0c46cSDimitry Andric llvm_unreachable("Unexpected bitAttr!");
15712754fe60SDimitry Andric }
15722754fe60SDimitry Andric break;
15732754fe60SDimitry Andric case ATTR_ALL_SET:
15742754fe60SDimitry Andric switch (bitAttr) {
15752754fe60SDimitry Andric case ATTR_FILTERED:
15762754fe60SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
15772754fe60SDimitry Andric RA = ATTR_NONE;
15782754fe60SDimitry Andric break;
15792754fe60SDimitry Andric case ATTR_ALL_SET:
15802754fe60SDimitry Andric break;
15812754fe60SDimitry Andric case ATTR_ALL_UNSET:
15822754fe60SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
15832754fe60SDimitry Andric RA = ATTR_NONE;
15842754fe60SDimitry Andric break;
15852754fe60SDimitry Andric case ATTR_MIXED:
15862754fe60SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
15872754fe60SDimitry Andric StartBit = BitIndex;
15882754fe60SDimitry Andric RA = ATTR_MIXED;
15892754fe60SDimitry Andric break;
15902754fe60SDimitry Andric default:
1591dff0c46cSDimitry Andric llvm_unreachable("Unexpected bitAttr!");
15922754fe60SDimitry Andric }
15932754fe60SDimitry Andric break;
15942754fe60SDimitry Andric case ATTR_MIXED:
15952754fe60SDimitry Andric switch (bitAttr) {
15962754fe60SDimitry Andric case ATTR_FILTERED:
15972754fe60SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
15982754fe60SDimitry Andric StartBit = BitIndex;
15992754fe60SDimitry Andric RA = ATTR_NONE;
16002754fe60SDimitry Andric break;
16012754fe60SDimitry Andric case ATTR_ALL_SET:
16022754fe60SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
16032754fe60SDimitry Andric StartBit = BitIndex;
16042754fe60SDimitry Andric RA = ATTR_ALL_SET;
16052754fe60SDimitry Andric break;
16062754fe60SDimitry Andric case ATTR_ALL_UNSET:
16072754fe60SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
16082754fe60SDimitry Andric RA = ATTR_NONE;
16092754fe60SDimitry Andric break;
16102754fe60SDimitry Andric case ATTR_MIXED:
16112754fe60SDimitry Andric break;
16122754fe60SDimitry Andric default:
1613dff0c46cSDimitry Andric llvm_unreachable("Unexpected bitAttr!");
16142754fe60SDimitry Andric }
16152754fe60SDimitry Andric break;
16162754fe60SDimitry Andric case ATTR_ALL_UNSET:
1617dff0c46cSDimitry Andric llvm_unreachable("regionAttr state machine has no ATTR_UNSET state");
16182754fe60SDimitry Andric case ATTR_FILTERED:
1619dff0c46cSDimitry Andric llvm_unreachable("regionAttr state machine has no ATTR_FILTERED state");
16202754fe60SDimitry Andric }
16212754fe60SDimitry Andric }
16222754fe60SDimitry Andric
16232754fe60SDimitry Andric // At the end, if we're still in ALL_SET or MIXED states, report a region
16242754fe60SDimitry Andric switch (RA) {
16252754fe60SDimitry Andric case ATTR_NONE:
16262754fe60SDimitry Andric break;
16272754fe60SDimitry Andric case ATTR_FILTERED:
16282754fe60SDimitry Andric break;
16292754fe60SDimitry Andric case ATTR_ALL_SET:
16302754fe60SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
16312754fe60SDimitry Andric break;
16322754fe60SDimitry Andric case ATTR_ALL_UNSET:
16332754fe60SDimitry Andric break;
16342754fe60SDimitry Andric case ATTR_MIXED:
16352754fe60SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
16362754fe60SDimitry Andric break;
16372754fe60SDimitry Andric }
16382754fe60SDimitry Andric
16392754fe60SDimitry Andric // We have finished with the filter processings. Now it's time to choose
16402754fe60SDimitry Andric // the best performing filter.
16412754fe60SDimitry Andric BestIndex = 0;
16422754fe60SDimitry Andric bool AllUseless = true;
16432754fe60SDimitry Andric unsigned BestScore = 0;
16442754fe60SDimitry Andric
16452754fe60SDimitry Andric for (unsigned i = 0, e = Filters.size(); i != e; ++i) {
16462754fe60SDimitry Andric unsigned Usefulness = Filters[i].usefulness();
16472754fe60SDimitry Andric
16482754fe60SDimitry Andric if (Usefulness)
16492754fe60SDimitry Andric AllUseless = false;
16502754fe60SDimitry Andric
16512754fe60SDimitry Andric if (Usefulness > BestScore) {
16522754fe60SDimitry Andric BestIndex = i;
16532754fe60SDimitry Andric BestScore = Usefulness;
16542754fe60SDimitry Andric }
16552754fe60SDimitry Andric }
16562754fe60SDimitry Andric
16572754fe60SDimitry Andric if (!AllUseless)
16582754fe60SDimitry Andric bestFilter().recurse();
16592754fe60SDimitry Andric
16602754fe60SDimitry Andric return !AllUseless;
16612754fe60SDimitry Andric } // end of FilterChooser::filterProcessor(bool)
16622754fe60SDimitry Andric
16632754fe60SDimitry Andric // Decides on the best configuration of filter(s) to use in order to decode
16642754fe60SDimitry Andric // the instructions. A conflict of instructions may occur, in which case we
16652754fe60SDimitry Andric // dump the conflict set to the standard error.
doFilter()16662754fe60SDimitry Andric void FilterChooser::doFilter() {
16672754fe60SDimitry Andric unsigned Num = Opcodes.size();
16682754fe60SDimitry Andric assert(Num && "FilterChooser created with no instructions");
16692754fe60SDimitry Andric
16702754fe60SDimitry Andric // Try regions of consecutive known bit values first.
16712754fe60SDimitry Andric if (filterProcessor(false))
16722754fe60SDimitry Andric return;
16732754fe60SDimitry Andric
16742754fe60SDimitry Andric // Then regions of mixed bits (both known and unitialized bit values allowed).
16752754fe60SDimitry Andric if (filterProcessor(true))
16762754fe60SDimitry Andric return;
16772754fe60SDimitry Andric
16782754fe60SDimitry Andric // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where
16792754fe60SDimitry Andric // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a
16802754fe60SDimitry Andric // well-known encoding pattern. In such case, we backtrack and scan for the
16812754fe60SDimitry Andric // the very first consecutive ATTR_ALL_SET region and assign a filter to it.
16822754fe60SDimitry Andric if (Num == 3 && filterProcessor(true, false))
16832754fe60SDimitry Andric return;
16842754fe60SDimitry Andric
16852754fe60SDimitry Andric // If we come to here, the instruction decoding has failed.
16862754fe60SDimitry Andric // Set the BestIndex to -1 to indicate so.
16872754fe60SDimitry Andric BestIndex = -1;
16882754fe60SDimitry Andric }
16892754fe60SDimitry Andric
16907ae0e2c9SDimitry Andric // emitTableEntries - Emit state machine entries to decode our share of
16917ae0e2c9SDimitry Andric // instructions.
emitTableEntries(DecoderTableInfo & TableInfo) const16927ae0e2c9SDimitry Andric void FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const {
16937ae0e2c9SDimitry Andric if (Opcodes.size() == 1) {
16942754fe60SDimitry Andric // There is only one instruction in the set, which is great!
16952754fe60SDimitry Andric // Call emitSingletonDecoder() to see whether there are any remaining
16962754fe60SDimitry Andric // encodings bits.
16977ae0e2c9SDimitry Andric emitSingletonTableEntry(TableInfo, Opcodes[0]);
16987ae0e2c9SDimitry Andric return;
16997ae0e2c9SDimitry Andric }
17002754fe60SDimitry Andric
17012754fe60SDimitry Andric // Choose the best filter to do the decodings!
17022754fe60SDimitry Andric if (BestIndex != -1) {
1703dff0c46cSDimitry Andric const Filter &Best = Filters[BestIndex];
17042754fe60SDimitry Andric if (Best.getNumFiltered() == 1)
17057ae0e2c9SDimitry Andric emitSingletonTableEntry(TableInfo, Best);
17062754fe60SDimitry Andric else
17077ae0e2c9SDimitry Andric Best.emitTableEntry(TableInfo);
17087ae0e2c9SDimitry Andric return;
17092754fe60SDimitry Andric }
17102754fe60SDimitry Andric
17117ae0e2c9SDimitry Andric // We don't know how to decode these instructions! Dump the
17127ae0e2c9SDimitry Andric // conflict set and bail.
17132754fe60SDimitry Andric
17142754fe60SDimitry Andric // Print out useful conflict information for postmortem analysis.
17152754fe60SDimitry Andric errs() << "Decoding Conflict:\n";
17162754fe60SDimitry Andric
17172754fe60SDimitry Andric dumpStack(errs(), "\t\t");
17182754fe60SDimitry Andric
1719dff0c46cSDimitry Andric for (unsigned i = 0; i < Opcodes.size(); ++i) {
1720*b5893f02SDimitry Andric errs() << '\t' << AllInstructions[Opcodes[i]] << " ";
17212754fe60SDimitry Andric dumpBits(errs(),
1722*b5893f02SDimitry Andric getBitsField(*AllInstructions[Opcodes[i]].EncodingDef, "Inst"));
17232754fe60SDimitry Andric errs() << '\n';
17242754fe60SDimitry Andric }
17252754fe60SDimitry Andric }
17262754fe60SDimitry Andric
findOperandDecoderMethod(TypedInit * TI)1727d88c1a5aSDimitry Andric static std::string findOperandDecoderMethod(TypedInit *TI) {
1728d88c1a5aSDimitry Andric std::string Decoder;
1729d88c1a5aSDimitry Andric
17304ba319b5SDimitry Andric Record *Record = cast<DefInit>(TI)->getDef();
1731d88c1a5aSDimitry Andric
17324ba319b5SDimitry Andric RecordVal *DecoderString = Record->getValue("DecoderMethod");
1733d88c1a5aSDimitry Andric StringInit *String = DecoderString ?
1734d88c1a5aSDimitry Andric dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
1735d88c1a5aSDimitry Andric if (String) {
1736d88c1a5aSDimitry Andric Decoder = String->getValue();
1737d88c1a5aSDimitry Andric if (!Decoder.empty())
1738d88c1a5aSDimitry Andric return Decoder;
1739d88c1a5aSDimitry Andric }
1740d88c1a5aSDimitry Andric
17414ba319b5SDimitry Andric if (Record->isSubClassOf("RegisterOperand"))
17424ba319b5SDimitry Andric Record = Record->getValueAsDef("RegClass");
1743d88c1a5aSDimitry Andric
17444ba319b5SDimitry Andric if (Record->isSubClassOf("RegisterClass")) {
17454ba319b5SDimitry Andric Decoder = "Decode" + Record->getName().str() + "RegisterClass";
17464ba319b5SDimitry Andric } else if (Record->isSubClassOf("PointerLikeRegClass")) {
1747d88c1a5aSDimitry Andric Decoder = "DecodePointerLikeRegClass" +
17484ba319b5SDimitry Andric utostr(Record->getValueAsInt("RegClassKind"));
1749d88c1a5aSDimitry Andric }
1750d88c1a5aSDimitry Andric
1751d88c1a5aSDimitry Andric return Decoder;
1752d88c1a5aSDimitry Andric }
1753d88c1a5aSDimitry Andric
populateInstruction(CodeGenTarget & Target,const CodeGenInstruction & CGI,unsigned Opc,std::map<unsigned,std::vector<OperandInfo>> & Operands)175491bc56edSDimitry Andric static bool populateInstruction(CodeGenTarget &Target,
175591bc56edSDimitry Andric const CodeGenInstruction &CGI, unsigned Opc,
17566122f3e6SDimitry Andric std::map<unsigned, std::vector<OperandInfo>> &Operands){
17572754fe60SDimitry Andric const Record &Def = *CGI.TheDef;
17582754fe60SDimitry Andric // If all the bit positions are not specified; do not decode this instruction.
17592754fe60SDimitry Andric // We are bound to fail! For proper disassembly, the well-known encoding bits
17602754fe60SDimitry Andric // of the instruction must be fully specified.
17612754fe60SDimitry Andric
176217a519f9SDimitry Andric BitsInit &Bits = getBitsField(Def, "Inst");
176317a519f9SDimitry Andric if (Bits.allInComplete()) return false;
176417a519f9SDimitry Andric
17652754fe60SDimitry Andric std::vector<OperandInfo> InsnOperands;
17662754fe60SDimitry Andric
17672754fe60SDimitry Andric // If the instruction has specified a custom decoding hook, use that instead
17682754fe60SDimitry Andric // of trying to auto-generate the decoder.
1769f9448bf3SDimitry Andric StringRef InstDecoder = Def.getValueAsString("DecoderMethod");
17702754fe60SDimitry Andric if (InstDecoder != "") {
17717d523365SDimitry Andric bool HasCompleteInstDecoder = Def.getValueAsBit("hasCompleteDecoder");
17727d523365SDimitry Andric InsnOperands.push_back(OperandInfo(InstDecoder, HasCompleteInstDecoder));
17732754fe60SDimitry Andric Operands[Opc] = InsnOperands;
17742754fe60SDimitry Andric return true;
17752754fe60SDimitry Andric }
17762754fe60SDimitry Andric
17772754fe60SDimitry Andric // Generate a description of the operand of the instruction that we know
17782754fe60SDimitry Andric // how to decode automatically.
17792754fe60SDimitry Andric // FIXME: We'll need to have a way to manually override this as needed.
17802754fe60SDimitry Andric
17812754fe60SDimitry Andric // Gather the outputs/inputs of the instruction, so we can find their
17822754fe60SDimitry Andric // positions in the encoding. This assumes for now that they appear in the
17832754fe60SDimitry Andric // MCInst in the order that they're listed.
1784d88c1a5aSDimitry Andric std::vector<std::pair<Init*, StringRef>> InOutOperands;
17852754fe60SDimitry Andric DagInit *Out = Def.getValueAsDag("OutOperandList");
17862754fe60SDimitry Andric DagInit *In = Def.getValueAsDag("InOperandList");
17872754fe60SDimitry Andric for (unsigned i = 0; i < Out->getNumArgs(); ++i)
1788d88c1a5aSDimitry Andric InOutOperands.push_back(std::make_pair(Out->getArg(i),
1789d88c1a5aSDimitry Andric Out->getArgNameStr(i)));
17902754fe60SDimitry Andric for (unsigned i = 0; i < In->getNumArgs(); ++i)
1791d88c1a5aSDimitry Andric InOutOperands.push_back(std::make_pair(In->getArg(i),
1792d88c1a5aSDimitry Andric In->getArgNameStr(i)));
17932754fe60SDimitry Andric
17946122f3e6SDimitry Andric // Search for tied operands, so that we can correctly instantiate
17956122f3e6SDimitry Andric // operands that are not explicitly represented in the encoding.
17966122f3e6SDimitry Andric std::map<std::string, std::string> TiedNames;
17976122f3e6SDimitry Andric for (unsigned i = 0; i < CGI.Operands.size(); ++i) {
17986122f3e6SDimitry Andric int tiedTo = CGI.Operands[i].getTiedRegister();
17996122f3e6SDimitry Andric if (tiedTo != -1) {
180091bc56edSDimitry Andric std::pair<unsigned, unsigned> SO =
180191bc56edSDimitry Andric CGI.Operands.getSubOperandNumber(tiedTo);
180291bc56edSDimitry Andric TiedNames[InOutOperands[i].second] = InOutOperands[SO.first].second;
180391bc56edSDimitry Andric TiedNames[InOutOperands[SO.first].second] = InOutOperands[i].second;
180491bc56edSDimitry Andric }
180591bc56edSDimitry Andric }
180691bc56edSDimitry Andric
180791bc56edSDimitry Andric std::map<std::string, std::vector<OperandInfo>> NumberedInsnOperands;
180891bc56edSDimitry Andric std::set<std::string> NumberedInsnOperandsNoTie;
180991bc56edSDimitry Andric if (Target.getInstructionSet()->
181091bc56edSDimitry Andric getValueAsBit("decodePositionallyEncodedOperands")) {
181191bc56edSDimitry Andric const std::vector<RecordVal> &Vals = Def.getValues();
181291bc56edSDimitry Andric unsigned NumberedOp = 0;
181391bc56edSDimitry Andric
181491bc56edSDimitry Andric std::set<unsigned> NamedOpIndices;
181591bc56edSDimitry Andric if (Target.getInstructionSet()->
181691bc56edSDimitry Andric getValueAsBit("noNamedPositionallyEncodedOperands"))
181791bc56edSDimitry Andric // Collect the set of operand indices that might correspond to named
181891bc56edSDimitry Andric // operand, and skip these when assigning operands based on position.
181991bc56edSDimitry Andric for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
182091bc56edSDimitry Andric unsigned OpIdx;
182191bc56edSDimitry Andric if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx))
182291bc56edSDimitry Andric continue;
182391bc56edSDimitry Andric
182491bc56edSDimitry Andric NamedOpIndices.insert(OpIdx);
182591bc56edSDimitry Andric }
182691bc56edSDimitry Andric
182791bc56edSDimitry Andric for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
182891bc56edSDimitry Andric // Ignore fixed fields in the record, we're looking for values like:
182991bc56edSDimitry Andric // bits<5> RST = { ?, ?, ?, ?, ? };
183091bc56edSDimitry Andric if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete())
183191bc56edSDimitry Andric continue;
183291bc56edSDimitry Andric
183391bc56edSDimitry Andric // Determine if Vals[i] actually contributes to the Inst encoding.
183491bc56edSDimitry Andric unsigned bi = 0;
183591bc56edSDimitry Andric for (; bi < Bits.getNumBits(); ++bi) {
183691bc56edSDimitry Andric VarInit *Var = nullptr;
183791bc56edSDimitry Andric VarBitInit *BI = dyn_cast<VarBitInit>(Bits.getBit(bi));
183891bc56edSDimitry Andric if (BI)
183991bc56edSDimitry Andric Var = dyn_cast<VarInit>(BI->getBitVar());
184091bc56edSDimitry Andric else
184191bc56edSDimitry Andric Var = dyn_cast<VarInit>(Bits.getBit(bi));
184291bc56edSDimitry Andric
184391bc56edSDimitry Andric if (Var && Var->getName() == Vals[i].getName())
184491bc56edSDimitry Andric break;
184591bc56edSDimitry Andric }
184691bc56edSDimitry Andric
184791bc56edSDimitry Andric if (bi == Bits.getNumBits())
184891bc56edSDimitry Andric continue;
184991bc56edSDimitry Andric
185091bc56edSDimitry Andric // Skip variables that correspond to explicitly-named operands.
185191bc56edSDimitry Andric unsigned OpIdx;
185291bc56edSDimitry Andric if (CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx))
185391bc56edSDimitry Andric continue;
185491bc56edSDimitry Andric
185591bc56edSDimitry Andric // Get the bit range for this operand:
185691bc56edSDimitry Andric unsigned bitStart = bi++, bitWidth = 1;
185791bc56edSDimitry Andric for (; bi < Bits.getNumBits(); ++bi) {
185891bc56edSDimitry Andric VarInit *Var = nullptr;
185991bc56edSDimitry Andric VarBitInit *BI = dyn_cast<VarBitInit>(Bits.getBit(bi));
186091bc56edSDimitry Andric if (BI)
186191bc56edSDimitry Andric Var = dyn_cast<VarInit>(BI->getBitVar());
186291bc56edSDimitry Andric else
186391bc56edSDimitry Andric Var = dyn_cast<VarInit>(Bits.getBit(bi));
186491bc56edSDimitry Andric
186591bc56edSDimitry Andric if (!Var)
186691bc56edSDimitry Andric break;
186791bc56edSDimitry Andric
186891bc56edSDimitry Andric if (Var->getName() != Vals[i].getName())
186991bc56edSDimitry Andric break;
187091bc56edSDimitry Andric
187191bc56edSDimitry Andric ++bitWidth;
187291bc56edSDimitry Andric }
187391bc56edSDimitry Andric
187491bc56edSDimitry Andric unsigned NumberOps = CGI.Operands.size();
187591bc56edSDimitry Andric while (NumberedOp < NumberOps &&
187691bc56edSDimitry Andric (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) ||
1877ff0cc061SDimitry Andric (!NamedOpIndices.empty() && NamedOpIndices.count(
187891bc56edSDimitry Andric CGI.Operands.getSubOperandNumber(NumberedOp).first))))
187991bc56edSDimitry Andric ++NumberedOp;
188091bc56edSDimitry Andric
188191bc56edSDimitry Andric OpIdx = NumberedOp++;
188291bc56edSDimitry Andric
188391bc56edSDimitry Andric // OpIdx now holds the ordered operand number of Vals[i].
188491bc56edSDimitry Andric std::pair<unsigned, unsigned> SO =
188591bc56edSDimitry Andric CGI.Operands.getSubOperandNumber(OpIdx);
188691bc56edSDimitry Andric const std::string &Name = CGI.Operands[SO.first].Name;
188791bc56edSDimitry Andric
18884ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Numbered operand mapping for " << Def.getName()
18894ba319b5SDimitry Andric << ": " << Name << "(" << SO.first << ", " << SO.second
18904ba319b5SDimitry Andric << ") => " << Vals[i].getName() << "\n");
189191bc56edSDimitry Andric
1892d88c1a5aSDimitry Andric std::string Decoder;
189391bc56edSDimitry Andric Record *TypeRecord = CGI.Operands[SO.first].Rec;
189491bc56edSDimitry Andric
189591bc56edSDimitry Andric RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod");
189691bc56edSDimitry Andric StringInit *String = DecoderString ?
189791bc56edSDimitry Andric dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
189891bc56edSDimitry Andric if (String && String->getValue() != "")
189991bc56edSDimitry Andric Decoder = String->getValue();
190091bc56edSDimitry Andric
190191bc56edSDimitry Andric if (Decoder == "" &&
190291bc56edSDimitry Andric CGI.Operands[SO.first].MIOperandInfo &&
190391bc56edSDimitry Andric CGI.Operands[SO.first].MIOperandInfo->getNumArgs()) {
190491bc56edSDimitry Andric Init *Arg = CGI.Operands[SO.first].MIOperandInfo->
190591bc56edSDimitry Andric getArg(SO.second);
19064ba319b5SDimitry Andric if (DefInit *DI = cast<DefInit>(Arg))
19074ba319b5SDimitry Andric TypeRecord = DI->getDef();
190891bc56edSDimitry Andric }
190991bc56edSDimitry Andric
191091bc56edSDimitry Andric bool isReg = false;
191191bc56edSDimitry Andric if (TypeRecord->isSubClassOf("RegisterOperand"))
191291bc56edSDimitry Andric TypeRecord = TypeRecord->getValueAsDef("RegClass");
191391bc56edSDimitry Andric if (TypeRecord->isSubClassOf("RegisterClass")) {
1914d88c1a5aSDimitry Andric Decoder = "Decode" + TypeRecord->getName().str() + "RegisterClass";
191591bc56edSDimitry Andric isReg = true;
191691bc56edSDimitry Andric } else if (TypeRecord->isSubClassOf("PointerLikeRegClass")) {
191791bc56edSDimitry Andric Decoder = "DecodePointerLikeRegClass" +
191891bc56edSDimitry Andric utostr(TypeRecord->getValueAsInt("RegClassKind"));
191991bc56edSDimitry Andric isReg = true;
192091bc56edSDimitry Andric }
192191bc56edSDimitry Andric
192291bc56edSDimitry Andric DecoderString = TypeRecord->getValue("DecoderMethod");
192391bc56edSDimitry Andric String = DecoderString ?
192491bc56edSDimitry Andric dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
192591bc56edSDimitry Andric if (!isReg && String && String->getValue() != "")
192691bc56edSDimitry Andric Decoder = String->getValue();
192791bc56edSDimitry Andric
19287d523365SDimitry Andric RecordVal *HasCompleteDecoderVal =
19297d523365SDimitry Andric TypeRecord->getValue("hasCompleteDecoder");
19307d523365SDimitry Andric BitInit *HasCompleteDecoderBit = HasCompleteDecoderVal ?
19317d523365SDimitry Andric dyn_cast<BitInit>(HasCompleteDecoderVal->getValue()) : nullptr;
19327d523365SDimitry Andric bool HasCompleteDecoder = HasCompleteDecoderBit ?
19337d523365SDimitry Andric HasCompleteDecoderBit->getValue() : true;
19347d523365SDimitry Andric
19357d523365SDimitry Andric OperandInfo OpInfo(Decoder, HasCompleteDecoder);
193691bc56edSDimitry Andric OpInfo.addField(bitStart, bitWidth, 0);
193791bc56edSDimitry Andric
193891bc56edSDimitry Andric NumberedInsnOperands[Name].push_back(OpInfo);
193991bc56edSDimitry Andric
194091bc56edSDimitry Andric // FIXME: For complex operands with custom decoders we can't handle tied
194191bc56edSDimitry Andric // sub-operands automatically. Skip those here and assume that this is
194291bc56edSDimitry Andric // fixed up elsewhere.
194391bc56edSDimitry Andric if (CGI.Operands[SO.first].MIOperandInfo &&
194491bc56edSDimitry Andric CGI.Operands[SO.first].MIOperandInfo->getNumArgs() > 1 &&
194591bc56edSDimitry Andric String && String->getValue() != "")
194691bc56edSDimitry Andric NumberedInsnOperandsNoTie.insert(Name);
19476122f3e6SDimitry Andric }
19486122f3e6SDimitry Andric }
19496122f3e6SDimitry Andric
19502754fe60SDimitry Andric // For each operand, see if we can figure out where it is encoded.
195139d628a0SDimitry Andric for (const auto &Op : InOutOperands) {
195239d628a0SDimitry Andric if (!NumberedInsnOperands[Op.second].empty()) {
195391bc56edSDimitry Andric InsnOperands.insert(InsnOperands.end(),
195439d628a0SDimitry Andric NumberedInsnOperands[Op.second].begin(),
195539d628a0SDimitry Andric NumberedInsnOperands[Op.second].end());
195691bc56edSDimitry Andric continue;
195739d628a0SDimitry Andric }
195839d628a0SDimitry Andric if (!NumberedInsnOperands[TiedNames[Op.second]].empty()) {
195939d628a0SDimitry Andric if (!NumberedInsnOperandsNoTie.count(TiedNames[Op.second])) {
196091bc56edSDimitry Andric // Figure out to which (sub)operand we're tied.
196139d628a0SDimitry Andric unsigned i = CGI.Operands.getOperandNamed(TiedNames[Op.second]);
196291bc56edSDimitry Andric int tiedTo = CGI.Operands[i].getTiedRegister();
196391bc56edSDimitry Andric if (tiedTo == -1) {
196439d628a0SDimitry Andric i = CGI.Operands.getOperandNamed(Op.second);
196591bc56edSDimitry Andric tiedTo = CGI.Operands[i].getTiedRegister();
196691bc56edSDimitry Andric }
196791bc56edSDimitry Andric
196891bc56edSDimitry Andric if (tiedTo != -1) {
196991bc56edSDimitry Andric std::pair<unsigned, unsigned> SO =
197091bc56edSDimitry Andric CGI.Operands.getSubOperandNumber(tiedTo);
197191bc56edSDimitry Andric
197239d628a0SDimitry Andric InsnOperands.push_back(NumberedInsnOperands[TiedNames[Op.second]]
197391bc56edSDimitry Andric [SO.second]);
197491bc56edSDimitry Andric }
197591bc56edSDimitry Andric }
197691bc56edSDimitry Andric continue;
197791bc56edSDimitry Andric }
197891bc56edSDimitry Andric
197939d628a0SDimitry Andric TypedInit *TI = cast<TypedInit>(Op.first);
19802754fe60SDimitry Andric
1981d88c1a5aSDimitry Andric // At this point, we can locate the decoder field, but we need to know how
1982d88c1a5aSDimitry Andric // to interpret it. As a first step, require the target to provide
1983d88c1a5aSDimitry Andric // callbacks for decoding register classes.
1984d88c1a5aSDimitry Andric std::string Decoder = findOperandDecoderMethod(TI);
19854ba319b5SDimitry Andric Record *TypeRecord = cast<DefInit>(TI)->getDef();
19866122f3e6SDimitry Andric
19877d523365SDimitry Andric RecordVal *HasCompleteDecoderVal =
19887d523365SDimitry Andric TypeRecord->getValue("hasCompleteDecoder");
19897d523365SDimitry Andric BitInit *HasCompleteDecoderBit = HasCompleteDecoderVal ?
19907d523365SDimitry Andric dyn_cast<BitInit>(HasCompleteDecoderVal->getValue()) : nullptr;
19917d523365SDimitry Andric bool HasCompleteDecoder = HasCompleteDecoderBit ?
19927d523365SDimitry Andric HasCompleteDecoderBit->getValue() : true;
19937d523365SDimitry Andric
19947d523365SDimitry Andric OperandInfo OpInfo(Decoder, HasCompleteDecoder);
19956122f3e6SDimitry Andric unsigned Base = ~0U;
19966122f3e6SDimitry Andric unsigned Width = 0;
19976122f3e6SDimitry Andric unsigned Offset = 0;
19986122f3e6SDimitry Andric
19996122f3e6SDimitry Andric for (unsigned bi = 0; bi < Bits.getNumBits(); ++bi) {
200091bc56edSDimitry Andric VarInit *Var = nullptr;
20013861d79fSDimitry Andric VarBitInit *BI = dyn_cast<VarBitInit>(Bits.getBit(bi));
20026122f3e6SDimitry Andric if (BI)
20033861d79fSDimitry Andric Var = dyn_cast<VarInit>(BI->getBitVar());
20046122f3e6SDimitry Andric else
20053861d79fSDimitry Andric Var = dyn_cast<VarInit>(Bits.getBit(bi));
20066122f3e6SDimitry Andric
20076122f3e6SDimitry Andric if (!Var) {
20086122f3e6SDimitry Andric if (Base != ~0U) {
20096122f3e6SDimitry Andric OpInfo.addField(Base, Width, Offset);
20106122f3e6SDimitry Andric Base = ~0U;
20116122f3e6SDimitry Andric Width = 0;
20126122f3e6SDimitry Andric Offset = 0;
20136122f3e6SDimitry Andric }
20146122f3e6SDimitry Andric continue;
20152754fe60SDimitry Andric }
20162754fe60SDimitry Andric
201739d628a0SDimitry Andric if (Var->getName() != Op.second &&
201839d628a0SDimitry Andric Var->getName() != TiedNames[Op.second]) {
20192754fe60SDimitry Andric if (Base != ~0U) {
20206122f3e6SDimitry Andric OpInfo.addField(Base, Width, Offset);
20216122f3e6SDimitry Andric Base = ~0U;
20226122f3e6SDimitry Andric Width = 0;
20236122f3e6SDimitry Andric Offset = 0;
20242754fe60SDimitry Andric }
20256122f3e6SDimitry Andric continue;
20266122f3e6SDimitry Andric }
20276122f3e6SDimitry Andric
20286122f3e6SDimitry Andric if (Base == ~0U) {
20296122f3e6SDimitry Andric Base = bi;
20306122f3e6SDimitry Andric Width = 1;
20316122f3e6SDimitry Andric Offset = BI ? BI->getBitNum() : 0;
20326122f3e6SDimitry Andric } else if (BI && BI->getBitNum() != Offset + Width) {
20336122f3e6SDimitry Andric OpInfo.addField(Base, Width, Offset);
20346122f3e6SDimitry Andric Base = bi;
20356122f3e6SDimitry Andric Width = 1;
20366122f3e6SDimitry Andric Offset = BI->getBitNum();
20376122f3e6SDimitry Andric } else {
20386122f3e6SDimitry Andric ++Width;
20396122f3e6SDimitry Andric }
20406122f3e6SDimitry Andric }
20416122f3e6SDimitry Andric
20426122f3e6SDimitry Andric if (Base != ~0U)
20436122f3e6SDimitry Andric OpInfo.addField(Base, Width, Offset);
20446122f3e6SDimitry Andric
20456122f3e6SDimitry Andric if (OpInfo.numFields() > 0)
20466122f3e6SDimitry Andric InsnOperands.push_back(OpInfo);
20472754fe60SDimitry Andric }
20482754fe60SDimitry Andric
20492754fe60SDimitry Andric Operands[Opc] = InsnOperands;
20502754fe60SDimitry Andric
20512754fe60SDimitry Andric #if 0
20524ba319b5SDimitry Andric LLVM_DEBUG({
20532754fe60SDimitry Andric // Dumps the instruction encoding bits.
20542754fe60SDimitry Andric dumpBits(errs(), Bits);
20552754fe60SDimitry Andric
20562754fe60SDimitry Andric errs() << '\n';
20572754fe60SDimitry Andric
20582754fe60SDimitry Andric // Dumps the list of operand info.
20592754fe60SDimitry Andric for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) {
20602754fe60SDimitry Andric const CGIOperandList::OperandInfo &Info = CGI.Operands[i];
20612754fe60SDimitry Andric const std::string &OperandName = Info.Name;
20622754fe60SDimitry Andric const Record &OperandDef = *Info.Rec;
20632754fe60SDimitry Andric
20642754fe60SDimitry Andric errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n";
20652754fe60SDimitry Andric }
20662754fe60SDimitry Andric });
20672754fe60SDimitry Andric #endif
20682754fe60SDimitry Andric
20692754fe60SDimitry Andric return true;
20702754fe60SDimitry Andric }
20712754fe60SDimitry Andric
20727ae0e2c9SDimitry Andric // emitFieldFromInstruction - Emit the templated helper function
20737ae0e2c9SDimitry Andric // fieldFromInstruction().
20744ba319b5SDimitry Andric // On Windows we make sure that this function is not inlined when
20754ba319b5SDimitry Andric // using the VS compiler. It has a bug which causes the function
20764ba319b5SDimitry Andric // to be optimized out in some circustances. See llvm.org/pr38292
emitFieldFromInstruction(formatted_raw_ostream & OS)20777ae0e2c9SDimitry Andric static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
2078*b5893f02SDimitry Andric OS << "// Helper functions for extracting fields from encoded instructions.\n"
2079*b5893f02SDimitry Andric << "// InsnType must either be integral or an APInt-like object that "
2080*b5893f02SDimitry Andric "must:\n"
2081*b5893f02SDimitry Andric << "// * Have a static const max_size_in_bits equal to the number of bits "
2082*b5893f02SDimitry Andric "in the\n"
2083*b5893f02SDimitry Andric << "// encoding.\n"
2084*b5893f02SDimitry Andric << "// * be default-constructible and copy-constructible\n"
2085*b5893f02SDimitry Andric << "// * be constructible from a uint64_t\n"
2086*b5893f02SDimitry Andric << "// * be constructible from an APInt (this can be private)\n"
2087*b5893f02SDimitry Andric << "// * Support getBitsSet(loBit, hiBit)\n"
2088*b5893f02SDimitry Andric << "// * be convertible to uint64_t\n"
2089*b5893f02SDimitry Andric << "// * Support the ~, &, ==, !=, and |= operators with other objects of "
2090*b5893f02SDimitry Andric "the same type\n"
2091*b5893f02SDimitry Andric << "// * Support shift (<<, >>) with signed and unsigned integers on the "
2092*b5893f02SDimitry Andric "RHS\n"
2093*b5893f02SDimitry Andric << "// * Support put (<<) to raw_ostream&\n"
20947ae0e2c9SDimitry Andric << "template<typename InsnType>\n"
20954ba319b5SDimitry Andric << "#if defined(_MSC_VER) && !defined(__clang__)\n"
20964ba319b5SDimitry Andric << "__declspec(noinline)\n"
20974ba319b5SDimitry Andric << "#endif\n"
2098*b5893f02SDimitry Andric << "static InsnType fieldFromInstruction(InsnType insn, unsigned "
2099*b5893f02SDimitry Andric "startBit,\n"
2100*b5893f02SDimitry Andric << " unsigned numBits, "
2101*b5893f02SDimitry Andric "std::true_type) {\n"
2102*b5893f02SDimitry Andric << " assert(startBit + numBits <= 64 && \"Cannot support >64-bit "
2103*b5893f02SDimitry Andric "extractions!\");\n"
21047ae0e2c9SDimitry Andric << " assert(startBit + numBits <= (sizeof(InsnType) * 8) &&\n"
21057ae0e2c9SDimitry Andric << " \"Instruction field out of bounds!\");\n"
21067ae0e2c9SDimitry Andric << " InsnType fieldMask;\n"
21077ae0e2c9SDimitry Andric << " if (numBits == sizeof(InsnType) * 8)\n"
21087ae0e2c9SDimitry Andric << " fieldMask = (InsnType)(-1LL);\n"
21097ae0e2c9SDimitry Andric << " else\n"
2110139f7f9bSDimitry Andric << " fieldMask = (((InsnType)1 << numBits) - 1) << startBit;\n"
21117ae0e2c9SDimitry Andric << " return (insn & fieldMask) >> startBit;\n"
2112*b5893f02SDimitry Andric << "}\n"
2113*b5893f02SDimitry Andric << "\n"
2114*b5893f02SDimitry Andric << "template<typename InsnType>\n"
2115*b5893f02SDimitry Andric << "static InsnType fieldFromInstruction(InsnType insn, unsigned "
2116*b5893f02SDimitry Andric "startBit,\n"
2117*b5893f02SDimitry Andric << " unsigned numBits, "
2118*b5893f02SDimitry Andric "std::false_type) {\n"
2119*b5893f02SDimitry Andric << " assert(startBit + numBits <= InsnType::max_size_in_bits && "
2120*b5893f02SDimitry Andric "\"Instruction field out of bounds!\");\n"
2121*b5893f02SDimitry Andric << " InsnType fieldMask = InsnType::getBitsSet(0, numBits);\n"
2122*b5893f02SDimitry Andric << " return (insn >> startBit) & fieldMask;\n"
2123*b5893f02SDimitry Andric << "}\n"
2124*b5893f02SDimitry Andric << "\n"
2125*b5893f02SDimitry Andric << "template<typename InsnType>\n"
2126*b5893f02SDimitry Andric << "static InsnType fieldFromInstruction(InsnType insn, unsigned "
2127*b5893f02SDimitry Andric "startBit,\n"
2128*b5893f02SDimitry Andric << " unsigned numBits) {\n"
2129*b5893f02SDimitry Andric << " return fieldFromInstruction(insn, startBit, numBits, "
2130*b5893f02SDimitry Andric "std::is_integral<InsnType>());\n"
21317ae0e2c9SDimitry Andric << "}\n\n";
21327ae0e2c9SDimitry Andric }
21332754fe60SDimitry Andric
21347ae0e2c9SDimitry Andric // emitDecodeInstruction - Emit the templated helper function
21357ae0e2c9SDimitry Andric // decodeInstruction().
emitDecodeInstruction(formatted_raw_ostream & OS)21367ae0e2c9SDimitry Andric static void emitDecodeInstruction(formatted_raw_ostream &OS) {
21377ae0e2c9SDimitry Andric OS << "template<typename InsnType>\n"
21384ba319b5SDimitry Andric << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], "
21394ba319b5SDimitry Andric "MCInst &MI,\n"
21404ba319b5SDimitry Andric << " InsnType insn, uint64_t "
21414ba319b5SDimitry Andric "Address,\n"
21427ae0e2c9SDimitry Andric << " const void *DisAsm,\n"
21437ae0e2c9SDimitry Andric << " const MCSubtargetInfo &STI) {\n"
2144ff0cc061SDimitry Andric << " const FeatureBitset& Bits = STI.getFeatureBits();\n"
21457ae0e2c9SDimitry Andric << "\n"
21467ae0e2c9SDimitry Andric << " const uint8_t *Ptr = DecodeTable;\n"
21473861d79fSDimitry Andric << " uint32_t CurFieldValue = 0;\n"
21487ae0e2c9SDimitry Andric << " DecodeStatus S = MCDisassembler::Success;\n"
2149d88c1a5aSDimitry Andric << " while (true) {\n"
21507ae0e2c9SDimitry Andric << " ptrdiff_t Loc = Ptr - DecodeTable;\n"
21517ae0e2c9SDimitry Andric << " switch (*Ptr) {\n"
21527ae0e2c9SDimitry Andric << " default:\n"
21537ae0e2c9SDimitry Andric << " errs() << Loc << \": Unexpected decode table opcode!\\n\";\n"
21547ae0e2c9SDimitry Andric << " return MCDisassembler::Fail;\n"
21557ae0e2c9SDimitry Andric << " case MCD::OPC_ExtractField: {\n"
21567ae0e2c9SDimitry Andric << " unsigned Start = *++Ptr;\n"
21577ae0e2c9SDimitry Andric << " unsigned Len = *++Ptr;\n"
21587ae0e2c9SDimitry Andric << " ++Ptr;\n"
21597ae0e2c9SDimitry Andric << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\n"
21604ba319b5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_ExtractField(\" << Start << "
21614ba319b5SDimitry Andric "\", \"\n"
21627ae0e2c9SDimitry Andric << " << Len << \"): \" << CurFieldValue << \"\\n\");\n"
21637ae0e2c9SDimitry Andric << " break;\n"
21647ae0e2c9SDimitry Andric << " }\n"
21657ae0e2c9SDimitry Andric << " case MCD::OPC_FilterValue: {\n"
21667ae0e2c9SDimitry Andric << " // Decode the field value.\n"
21677ae0e2c9SDimitry Andric << " unsigned Len;\n"
21687ae0e2c9SDimitry Andric << " InsnType Val = decodeULEB128(++Ptr, &Len);\n"
21697ae0e2c9SDimitry Andric << " Ptr += Len;\n"
21704ba319b5SDimitry Andric << " // NumToSkip is a plain 24-bit integer.\n"
21717ae0e2c9SDimitry Andric << " unsigned NumToSkip = *Ptr++;\n"
21727ae0e2c9SDimitry Andric << " NumToSkip |= (*Ptr++) << 8;\n"
21734ba319b5SDimitry Andric << " NumToSkip |= (*Ptr++) << 16;\n"
21747ae0e2c9SDimitry Andric << "\n"
21757ae0e2c9SDimitry Andric << " // Perform the filter operation.\n"
21767ae0e2c9SDimitry Andric << " if (Val != CurFieldValue)\n"
21777ae0e2c9SDimitry Andric << " Ptr += NumToSkip;\n"
21784ba319b5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_FilterValue(\" << Val << "
21794ba319b5SDimitry Andric "\", \" << NumToSkip\n"
21804ba319b5SDimitry Andric << " << \"): \" << ((Val != CurFieldValue) ? \"FAIL:\" "
21814ba319b5SDimitry Andric ": \"PASS:\")\n"
21824ba319b5SDimitry Andric << " << \" continuing at \" << (Ptr - DecodeTable) << "
21834ba319b5SDimitry Andric "\"\\n\");\n"
21847ae0e2c9SDimitry Andric << "\n"
21857ae0e2c9SDimitry Andric << " break;\n"
21867ae0e2c9SDimitry Andric << " }\n"
21877ae0e2c9SDimitry Andric << " case MCD::OPC_CheckField: {\n"
21887ae0e2c9SDimitry Andric << " unsigned Start = *++Ptr;\n"
21897ae0e2c9SDimitry Andric << " unsigned Len = *++Ptr;\n"
21907ae0e2c9SDimitry Andric << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\n"
21917ae0e2c9SDimitry Andric << " // Decode the field value.\n"
21927ae0e2c9SDimitry Andric << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\n"
21937ae0e2c9SDimitry Andric << " Ptr += Len;\n"
21944ba319b5SDimitry Andric << " // NumToSkip is a plain 24-bit integer.\n"
21957ae0e2c9SDimitry Andric << " unsigned NumToSkip = *Ptr++;\n"
21967ae0e2c9SDimitry Andric << " NumToSkip |= (*Ptr++) << 8;\n"
21974ba319b5SDimitry Andric << " NumToSkip |= (*Ptr++) << 16;\n"
21987ae0e2c9SDimitry Andric << "\n"
21997ae0e2c9SDimitry Andric << " // If the actual and expected values don't match, skip.\n"
22007ae0e2c9SDimitry Andric << " if (ExpectedValue != FieldValue)\n"
22017ae0e2c9SDimitry Andric << " Ptr += NumToSkip;\n"
22024ba319b5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_CheckField(\" << Start << "
22034ba319b5SDimitry Andric "\", \"\n"
22044ba319b5SDimitry Andric << " << Len << \", \" << ExpectedValue << \", \" << "
22054ba319b5SDimitry Andric "NumToSkip\n"
22064ba319b5SDimitry Andric << " << \"): FieldValue = \" << FieldValue << \", "
22074ba319b5SDimitry Andric "ExpectedValue = \"\n"
22087ae0e2c9SDimitry Andric << " << ExpectedValue << \": \"\n"
22094ba319b5SDimitry Andric << " << ((ExpectedValue == FieldValue) ? \"PASS\\n\" : "
22104ba319b5SDimitry Andric "\"FAIL\\n\"));\n"
22117ae0e2c9SDimitry Andric << " break;\n"
22127ae0e2c9SDimitry Andric << " }\n"
22137ae0e2c9SDimitry Andric << " case MCD::OPC_CheckPredicate: {\n"
22147ae0e2c9SDimitry Andric << " unsigned Len;\n"
22157ae0e2c9SDimitry Andric << " // Decode the Predicate Index value.\n"
22167ae0e2c9SDimitry Andric << " unsigned PIdx = decodeULEB128(++Ptr, &Len);\n"
22177ae0e2c9SDimitry Andric << " Ptr += Len;\n"
22184ba319b5SDimitry Andric << " // NumToSkip is a plain 24-bit integer.\n"
22197ae0e2c9SDimitry Andric << " unsigned NumToSkip = *Ptr++;\n"
22207ae0e2c9SDimitry Andric << " NumToSkip |= (*Ptr++) << 8;\n"
22214ba319b5SDimitry Andric << " NumToSkip |= (*Ptr++) << 16;\n"
22227ae0e2c9SDimitry Andric << " // Check the predicate.\n"
22237ae0e2c9SDimitry Andric << " bool Pred;\n"
22247ae0e2c9SDimitry Andric << " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\n"
22257ae0e2c9SDimitry Andric << " Ptr += NumToSkip;\n"
22267ae0e2c9SDimitry Andric << " (void)Pred;\n"
22274ba319b5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_CheckPredicate(\" << PIdx "
22284ba319b5SDimitry Andric "<< \"): \"\n"
22297ae0e2c9SDimitry Andric << " << (Pred ? \"PASS\\n\" : \"FAIL\\n\"));\n"
22307ae0e2c9SDimitry Andric << "\n"
22317ae0e2c9SDimitry Andric << " break;\n"
22327ae0e2c9SDimitry Andric << " }\n"
22337ae0e2c9SDimitry Andric << " case MCD::OPC_Decode: {\n"
22347ae0e2c9SDimitry Andric << " unsigned Len;\n"
22357ae0e2c9SDimitry Andric << " // Decode the Opcode value.\n"
22367ae0e2c9SDimitry Andric << " unsigned Opc = decodeULEB128(++Ptr, &Len);\n"
22377ae0e2c9SDimitry Andric << " Ptr += Len;\n"
22387ae0e2c9SDimitry Andric << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\n"
22397ae0e2c9SDimitry Andric << " Ptr += Len;\n"
22407ae0e2c9SDimitry Andric << "\n"
22417d523365SDimitry Andric << " MI.clear();\n"
22427ae0e2c9SDimitry Andric << " MI.setOpcode(Opc);\n"
22437d523365SDimitry Andric << " bool DecodeComplete;\n"
22444ba319b5SDimitry Andric << " S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, "
22454ba319b5SDimitry Andric "DecodeComplete);\n"
22467d523365SDimitry Andric << " assert(DecodeComplete);\n"
22477d523365SDimitry Andric << "\n"
22484ba319b5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_Decode: opcode \" << Opc\n"
22497d523365SDimitry Andric << " << \", using decoder \" << DecodeIdx << \": \"\n"
22504ba319b5SDimitry Andric << " << (S != MCDisassembler::Fail ? \"PASS\" : "
22514ba319b5SDimitry Andric "\"FAIL\") << \"\\n\");\n"
22527d523365SDimitry Andric << " return S;\n"
22537d523365SDimitry Andric << " }\n"
22547d523365SDimitry Andric << " case MCD::OPC_TryDecode: {\n"
22557d523365SDimitry Andric << " unsigned Len;\n"
22567d523365SDimitry Andric << " // Decode the Opcode value.\n"
22577d523365SDimitry Andric << " unsigned Opc = decodeULEB128(++Ptr, &Len);\n"
22587d523365SDimitry Andric << " Ptr += Len;\n"
22597d523365SDimitry Andric << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\n"
22607d523365SDimitry Andric << " Ptr += Len;\n"
22614ba319b5SDimitry Andric << " // NumToSkip is a plain 24-bit integer.\n"
22627d523365SDimitry Andric << " unsigned NumToSkip = *Ptr++;\n"
22637d523365SDimitry Andric << " NumToSkip |= (*Ptr++) << 8;\n"
22644ba319b5SDimitry Andric << " NumToSkip |= (*Ptr++) << 16;\n"
22657d523365SDimitry Andric << "\n"
22667d523365SDimitry Andric << " // Perform the decode operation.\n"
22677d523365SDimitry Andric << " MCInst TmpMI;\n"
22687d523365SDimitry Andric << " TmpMI.setOpcode(Opc);\n"
22697d523365SDimitry Andric << " bool DecodeComplete;\n"
22704ba319b5SDimitry Andric << " S = decodeToMCInst(S, DecodeIdx, insn, TmpMI, Address, DisAsm, "
22714ba319b5SDimitry Andric "DecodeComplete);\n"
22724ba319b5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_TryDecode: opcode \" << "
22734ba319b5SDimitry Andric "Opc\n"
22747d523365SDimitry Andric << " << \", using decoder \" << DecodeIdx << \": \");\n"
22757d523365SDimitry Andric << "\n"
22767d523365SDimitry Andric << " if (DecodeComplete) {\n"
22777d523365SDimitry Andric << " // Decoding complete.\n"
22784ba319b5SDimitry Andric << " LLVM_DEBUG(dbgs() << (S != MCDisassembler::Fail ? \"PASS\" : "
22794ba319b5SDimitry Andric "\"FAIL\") << \"\\n\");\n"
22807d523365SDimitry Andric << " MI = TmpMI;\n"
22817d523365SDimitry Andric << " return S;\n"
22827d523365SDimitry Andric << " } else {\n"
22837d523365SDimitry Andric << " assert(S == MCDisassembler::Fail);\n"
22847d523365SDimitry Andric << " // If the decoding was incomplete, skip.\n"
22857d523365SDimitry Andric << " Ptr += NumToSkip;\n"
22864ba319b5SDimitry Andric << " LLVM_DEBUG(dbgs() << \"FAIL: continuing at \" << (Ptr - "
22874ba319b5SDimitry Andric "DecodeTable) << \"\\n\");\n"
22884ba319b5SDimitry Andric << " // Reset decode status. This also drops a SoftFail status "
22894ba319b5SDimitry Andric "that could be\n"
22907d523365SDimitry Andric << " // set before the decode attempt.\n"
22917d523365SDimitry Andric << " S = MCDisassembler::Success;\n"
22927d523365SDimitry Andric << " }\n"
22937d523365SDimitry Andric << " break;\n"
22947ae0e2c9SDimitry Andric << " }\n"
22957ae0e2c9SDimitry Andric << " case MCD::OPC_SoftFail: {\n"
22967ae0e2c9SDimitry Andric << " // Decode the mask values.\n"
22977ae0e2c9SDimitry Andric << " unsigned Len;\n"
22987ae0e2c9SDimitry Andric << " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\n"
22997ae0e2c9SDimitry Andric << " Ptr += Len;\n"
23007ae0e2c9SDimitry Andric << " InsnType NegativeMask = decodeULEB128(Ptr, &Len);\n"
23017ae0e2c9SDimitry Andric << " Ptr += Len;\n"
23027ae0e2c9SDimitry Andric << " bool Fail = (insn & PositiveMask) || (~insn & NegativeMask);\n"
23037ae0e2c9SDimitry Andric << " if (Fail)\n"
23047ae0e2c9SDimitry Andric << " S = MCDisassembler::SoftFail;\n"
23054ba319b5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_SoftFail: \" << (Fail ? "
23064ba319b5SDimitry Andric "\"FAIL\\n\":\"PASS\\n\"));\n"
23077ae0e2c9SDimitry Andric << " break;\n"
23087ae0e2c9SDimitry Andric << " }\n"
23097ae0e2c9SDimitry Andric << " case MCD::OPC_Fail: {\n"
23104ba319b5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_Fail\\n\");\n"
23117ae0e2c9SDimitry Andric << " return MCDisassembler::Fail;\n"
23127ae0e2c9SDimitry Andric << " }\n"
23137ae0e2c9SDimitry Andric << " }\n"
23147ae0e2c9SDimitry Andric << " }\n"
23154ba319b5SDimitry Andric << " llvm_unreachable(\"bogosity detected in disassembler state "
23164ba319b5SDimitry Andric "machine!\");\n"
23177ae0e2c9SDimitry Andric << "}\n\n";
23182754fe60SDimitry Andric }
23192754fe60SDimitry Andric
23202754fe60SDimitry Andric // Emits disassembler code for instruction decoding.
run(raw_ostream & o)2321dff0c46cSDimitry Andric void FixedLenDecoderEmitter::run(raw_ostream &o) {
23227ae0e2c9SDimitry Andric formatted_raw_ostream OS(o);
23237ae0e2c9SDimitry Andric OS << "#include \"llvm/MC/MCInst.h\"\n";
23247ae0e2c9SDimitry Andric OS << "#include \"llvm/Support/Debug.h\"\n";
23257ae0e2c9SDimitry Andric OS << "#include \"llvm/Support/DataTypes.h\"\n";
23267ae0e2c9SDimitry Andric OS << "#include \"llvm/Support/LEB128.h\"\n";
23277ae0e2c9SDimitry Andric OS << "#include \"llvm/Support/raw_ostream.h\"\n";
23287ae0e2c9SDimitry Andric OS << "#include <assert.h>\n";
23297ae0e2c9SDimitry Andric OS << '\n';
23307ae0e2c9SDimitry Andric OS << "namespace llvm {\n\n";
23317ae0e2c9SDimitry Andric
23327ae0e2c9SDimitry Andric emitFieldFromInstruction(OS);
23332754fe60SDimitry Andric
233491bc56edSDimitry Andric Target.reverseBitsForLittleEndianEncoding();
233591bc56edSDimitry Andric
23366122f3e6SDimitry Andric // Parameterize the decoders based on namespace and instruction width.
2337*b5893f02SDimitry Andric const auto &NumberedInstructions = Target.getInstructionsByEnumValue();
2338*b5893f02SDimitry Andric NumberedEncodings.reserve(NumberedInstructions.size());
2339*b5893f02SDimitry Andric for (const auto &NumberedInstruction : NumberedInstructions)
2340*b5893f02SDimitry Andric NumberedEncodings.emplace_back(NumberedInstruction->TheDef, NumberedInstruction);
2341*b5893f02SDimitry Andric
23426122f3e6SDimitry Andric std::map<std::pair<std::string, unsigned>,
23436122f3e6SDimitry Andric std::vector<unsigned>> OpcMap;
23446122f3e6SDimitry Andric std::map<unsigned, std::vector<OperandInfo>> Operands;
23456122f3e6SDimitry Andric
2346*b5893f02SDimitry Andric for (unsigned i = 0; i < NumberedEncodings.size(); ++i) {
2347*b5893f02SDimitry Andric const CodeGenInstruction *Inst = NumberedEncodings[i].Inst;
2348dff0c46cSDimitry Andric const Record *Def = Inst->TheDef;
23496122f3e6SDimitry Andric unsigned Size = Def->getValueAsInt("Size");
23506122f3e6SDimitry Andric if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
23516122f3e6SDimitry Andric Def->getValueAsBit("isPseudo") ||
23526122f3e6SDimitry Andric Def->getValueAsBit("isAsmParserOnly") ||
23536122f3e6SDimitry Andric Def->getValueAsBit("isCodeGenOnly"))
23546122f3e6SDimitry Andric continue;
23556122f3e6SDimitry Andric
2356f9448bf3SDimitry Andric StringRef DecoderNamespace = Def->getValueAsString("DecoderNamespace");
23576122f3e6SDimitry Andric
23586122f3e6SDimitry Andric if (Size) {
235991bc56edSDimitry Andric if (populateInstruction(Target, *Inst, i, Operands)) {
23606122f3e6SDimitry Andric OpcMap[std::make_pair(DecoderNamespace, Size)].push_back(i);
23616122f3e6SDimitry Andric }
23626122f3e6SDimitry Andric }
23636122f3e6SDimitry Andric }
23646122f3e6SDimitry Andric
23657ae0e2c9SDimitry Andric DecoderTableInfo TableInfo;
236639d628a0SDimitry Andric for (const auto &Opc : OpcMap) {
23676122f3e6SDimitry Andric // Emit the decoder for this namespace+width combination.
2368*b5893f02SDimitry Andric ArrayRef<EncodingAndInst> NumberedEncodingsRef(NumberedEncodings.data(),
2369*b5893f02SDimitry Andric NumberedEncodings.size());
2370*b5893f02SDimitry Andric FilterChooser FC(NumberedEncodingsRef, Opc.second, Operands,
237139d628a0SDimitry Andric 8 * Opc.first.second, this);
23727ae0e2c9SDimitry Andric
23737ae0e2c9SDimitry Andric // The decode table is cleared for each top level decoder function. The
23747ae0e2c9SDimitry Andric // predicates and decoders themselves, however, are shared across all
23757ae0e2c9SDimitry Andric // decoders to give more opportunities for uniqueing.
23767ae0e2c9SDimitry Andric TableInfo.Table.clear();
23777ae0e2c9SDimitry Andric TableInfo.FixupStack.clear();
23787ae0e2c9SDimitry Andric TableInfo.Table.reserve(16384);
237997bc6c73SDimitry Andric TableInfo.FixupStack.emplace_back();
23807ae0e2c9SDimitry Andric FC.emitTableEntries(TableInfo);
23817ae0e2c9SDimitry Andric // Any NumToSkip fixups in the top level scope can resolve to the
23827ae0e2c9SDimitry Andric // OPC_Fail at the end of the table.
23837ae0e2c9SDimitry Andric assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!");
23847ae0e2c9SDimitry Andric // Resolve any NumToSkip fixups in the current scope.
23857ae0e2c9SDimitry Andric resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
23867ae0e2c9SDimitry Andric TableInfo.Table.size());
23877ae0e2c9SDimitry Andric TableInfo.FixupStack.clear();
23887ae0e2c9SDimitry Andric
23897ae0e2c9SDimitry Andric TableInfo.Table.push_back(MCD::OPC_Fail);
23907ae0e2c9SDimitry Andric
23917ae0e2c9SDimitry Andric // Print the table to the output stream.
239239d628a0SDimitry Andric emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), Opc.first.first);
23937ae0e2c9SDimitry Andric OS.flush();
23946122f3e6SDimitry Andric }
23952754fe60SDimitry Andric
23967ae0e2c9SDimitry Andric // Emit the predicate function.
23977ae0e2c9SDimitry Andric emitPredicateFunction(OS, TableInfo.Predicates, 0);
23987ae0e2c9SDimitry Andric
23997ae0e2c9SDimitry Andric // Emit the decoder function.
24007ae0e2c9SDimitry Andric emitDecoderFunction(OS, TableInfo.Decoders, 0);
24017ae0e2c9SDimitry Andric
24027ae0e2c9SDimitry Andric // Emit the main entry point for the decoder, decodeInstruction().
24037ae0e2c9SDimitry Andric emitDecodeInstruction(OS);
24047ae0e2c9SDimitry Andric
24057ae0e2c9SDimitry Andric OS << "\n} // End llvm namespace\n";
24062754fe60SDimitry Andric }
24077ae0e2c9SDimitry Andric
24087ae0e2c9SDimitry Andric namespace llvm {
24097ae0e2c9SDimitry Andric
EmitFixedLenDecoder(RecordKeeper & RK,raw_ostream & OS,const std::string & PredicateNamespace,const std::string & GPrefix,const std::string & GPostfix,const std::string & ROK,const std::string & RFail,const std::string & L)24107ae0e2c9SDimitry Andric void EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS,
24113ca95b02SDimitry Andric const std::string &PredicateNamespace,
24123ca95b02SDimitry Andric const std::string &GPrefix,
24133ca95b02SDimitry Andric const std::string &GPostfix, const std::string &ROK,
24143ca95b02SDimitry Andric const std::string &RFail, const std::string &L) {
24157ae0e2c9SDimitry Andric FixedLenDecoderEmitter(RK, PredicateNamespace, GPrefix, GPostfix,
24167ae0e2c9SDimitry Andric ROK, RFail, L).run(OS);
24177ae0e2c9SDimitry Andric }
24187ae0e2c9SDimitry Andric
2419d88c1a5aSDimitry Andric } // end namespace llvm
2420