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