10b57cec5SDimitry Andric //===------------ FixedLenDecoderEmitter.cpp - Decoder Generator ----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // It contains the tablegen backend that emits the decoder functions for
100b57cec5SDimitry Andric // targets with fixed length instruction set.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "CodeGenInstruction.h"
150b57cec5SDimitry Andric #include "CodeGenTarget.h"
168bcb0991SDimitry Andric #include "InfoByHwMode.h"
170b57cec5SDimitry Andric #include "llvm/ADT/APInt.h"
180b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
190b57cec5SDimitry Andric #include "llvm/ADT/CachedHashString.h"
200b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
210b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
220b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
230b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
240b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
250b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
260b57cec5SDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h"
270b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
280b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
290b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
300b57cec5SDimitry Andric #include "llvm/Support/FormattedStream.h"
310b57cec5SDimitry Andric #include "llvm/Support/LEB128.h"
320b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
330b57cec5SDimitry Andric #include "llvm/TableGen/Error.h"
340b57cec5SDimitry Andric #include "llvm/TableGen/Record.h"
350b57cec5SDimitry Andric #include <algorithm>
360b57cec5SDimitry Andric #include <cassert>
370b57cec5SDimitry Andric #include <cstddef>
380b57cec5SDimitry Andric #include <cstdint>
390b57cec5SDimitry Andric #include <map>
400b57cec5SDimitry Andric #include <memory>
410b57cec5SDimitry Andric #include <set>
420b57cec5SDimitry Andric #include <string>
430b57cec5SDimitry Andric #include <utility>
440b57cec5SDimitry Andric #include <vector>
450b57cec5SDimitry Andric
460b57cec5SDimitry Andric using namespace llvm;
470b57cec5SDimitry Andric
480b57cec5SDimitry Andric #define DEBUG_TYPE "decoder-emitter"
490b57cec5SDimitry Andric
500b57cec5SDimitry Andric namespace {
510b57cec5SDimitry Andric
520b57cec5SDimitry Andric STATISTIC(NumEncodings, "Number of encodings considered");
530b57cec5SDimitry Andric STATISTIC(NumEncodingsLackingDisasm, "Number of encodings without disassembler info");
540b57cec5SDimitry Andric STATISTIC(NumInstructions, "Number of instructions considered");
550b57cec5SDimitry Andric STATISTIC(NumEncodingsSupported, "Number of encodings supported");
560b57cec5SDimitry Andric STATISTIC(NumEncodingsOmitted, "Number of encodings omitted");
570b57cec5SDimitry Andric
580b57cec5SDimitry Andric struct EncodingField {
590b57cec5SDimitry Andric unsigned Base, Width, Offset;
EncodingField__anon3051e32e0111::EncodingField600b57cec5SDimitry Andric EncodingField(unsigned B, unsigned W, unsigned O)
610b57cec5SDimitry Andric : Base(B), Width(W), Offset(O) { }
620b57cec5SDimitry Andric };
630b57cec5SDimitry Andric
640b57cec5SDimitry Andric struct OperandInfo {
650b57cec5SDimitry Andric std::vector<EncodingField> Fields;
660b57cec5SDimitry Andric std::string Decoder;
670b57cec5SDimitry Andric bool HasCompleteDecoder;
688bcb0991SDimitry Andric uint64_t InitValue;
690b57cec5SDimitry Andric
OperandInfo__anon3051e32e0111::OperandInfo700b57cec5SDimitry Andric OperandInfo(std::string D, bool HCD)
718bcb0991SDimitry Andric : Decoder(std::move(D)), HasCompleteDecoder(HCD), InitValue(0) {}
720b57cec5SDimitry Andric
addField__anon3051e32e0111::OperandInfo730b57cec5SDimitry Andric void addField(unsigned Base, unsigned Width, unsigned Offset) {
740b57cec5SDimitry Andric Fields.push_back(EncodingField(Base, Width, Offset));
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric
numFields__anon3051e32e0111::OperandInfo770b57cec5SDimitry Andric unsigned numFields() const { return Fields.size(); }
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric typedef std::vector<EncodingField>::const_iterator const_iterator;
800b57cec5SDimitry Andric
begin__anon3051e32e0111::OperandInfo810b57cec5SDimitry Andric const_iterator begin() const { return Fields.begin(); }
end__anon3051e32e0111::OperandInfo820b57cec5SDimitry Andric const_iterator end() const { return Fields.end(); }
830b57cec5SDimitry Andric };
840b57cec5SDimitry Andric
850b57cec5SDimitry Andric typedef std::vector<uint8_t> DecoderTable;
860b57cec5SDimitry Andric typedef uint32_t DecoderFixup;
870b57cec5SDimitry Andric typedef std::vector<DecoderFixup> FixupList;
880b57cec5SDimitry Andric typedef std::vector<FixupList> FixupScopeList;
890b57cec5SDimitry Andric typedef SmallSetVector<CachedHashString, 16> PredicateSet;
900b57cec5SDimitry Andric typedef SmallSetVector<CachedHashString, 16> DecoderSet;
910b57cec5SDimitry Andric struct DecoderTableInfo {
920b57cec5SDimitry Andric DecoderTable Table;
930b57cec5SDimitry Andric FixupScopeList FixupStack;
940b57cec5SDimitry Andric PredicateSet Predicates;
950b57cec5SDimitry Andric DecoderSet Decoders;
960b57cec5SDimitry Andric };
970b57cec5SDimitry Andric
980b57cec5SDimitry Andric struct EncodingAndInst {
990b57cec5SDimitry Andric const Record *EncodingDef;
1000b57cec5SDimitry Andric const CodeGenInstruction *Inst;
1018bcb0991SDimitry Andric StringRef HwModeName;
1020b57cec5SDimitry Andric
EncodingAndInst__anon3051e32e0111::EncodingAndInst1038bcb0991SDimitry Andric EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst,
1048bcb0991SDimitry Andric StringRef HwModeName = "")
1058bcb0991SDimitry Andric : EncodingDef(EncodingDef), Inst(Inst), HwModeName(HwModeName) {}
1060b57cec5SDimitry Andric };
1070b57cec5SDimitry Andric
1080b57cec5SDimitry Andric struct EncodingIDAndOpcode {
1090b57cec5SDimitry Andric unsigned EncodingID;
1100b57cec5SDimitry Andric unsigned Opcode;
1110b57cec5SDimitry Andric
EncodingIDAndOpcode__anon3051e32e0111::EncodingIDAndOpcode1120b57cec5SDimitry Andric EncodingIDAndOpcode() : EncodingID(0), Opcode(0) {}
EncodingIDAndOpcode__anon3051e32e0111::EncodingIDAndOpcode1130b57cec5SDimitry Andric EncodingIDAndOpcode(unsigned EncodingID, unsigned Opcode)
1140b57cec5SDimitry Andric : EncodingID(EncodingID), Opcode(Opcode) {}
1150b57cec5SDimitry Andric };
1160b57cec5SDimitry Andric
operator <<(raw_ostream & OS,const EncodingAndInst & Value)1170b57cec5SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {
1180b57cec5SDimitry Andric if (Value.EncodingDef != Value.Inst->TheDef)
1190b57cec5SDimitry Andric OS << Value.EncodingDef->getName() << ":";
1200b57cec5SDimitry Andric OS << Value.Inst->TheDef->getName();
1210b57cec5SDimitry Andric return OS;
1220b57cec5SDimitry Andric }
1230b57cec5SDimitry Andric
1240b57cec5SDimitry Andric class FixedLenDecoderEmitter {
1250b57cec5SDimitry Andric RecordKeeper &RK;
1260b57cec5SDimitry Andric std::vector<EncodingAndInst> NumberedEncodings;
1270b57cec5SDimitry Andric
1280b57cec5SDimitry Andric public:
1290b57cec5SDimitry Andric // Defaults preserved here for documentation, even though they aren't
1300b57cec5SDimitry Andric // strictly necessary given the way that this is currently being called.
FixedLenDecoderEmitter(RecordKeeper & R,std::string PredicateNamespace,std::string GPrefix="if (",std::string GPostfix=" == MCDisassembler::Fail)",std::string ROK="MCDisassembler::Success",std::string RFail="MCDisassembler::Fail",std::string L="")1310b57cec5SDimitry Andric FixedLenDecoderEmitter(RecordKeeper &R, std::string PredicateNamespace,
1320b57cec5SDimitry Andric std::string GPrefix = "if (",
1330b57cec5SDimitry Andric std::string GPostfix = " == MCDisassembler::Fail)",
1340b57cec5SDimitry Andric std::string ROK = "MCDisassembler::Success",
1350b57cec5SDimitry Andric std::string RFail = "MCDisassembler::Fail",
1360b57cec5SDimitry Andric std::string L = "")
1370b57cec5SDimitry Andric : RK(R), Target(R), PredicateNamespace(std::move(PredicateNamespace)),
1380b57cec5SDimitry Andric GuardPrefix(std::move(GPrefix)), GuardPostfix(std::move(GPostfix)),
1390b57cec5SDimitry Andric ReturnOK(std::move(ROK)), ReturnFail(std::move(RFail)),
1400b57cec5SDimitry Andric Locals(std::move(L)) {}
1410b57cec5SDimitry Andric
1420b57cec5SDimitry Andric // Emit the decoder state machine table.
1430b57cec5SDimitry Andric void emitTable(formatted_raw_ostream &o, DecoderTable &Table,
1440b57cec5SDimitry Andric unsigned Indentation, unsigned BitWidth,
1450b57cec5SDimitry Andric StringRef Namespace) const;
1460b57cec5SDimitry Andric void emitPredicateFunction(formatted_raw_ostream &OS,
1470b57cec5SDimitry Andric PredicateSet &Predicates,
1480b57cec5SDimitry Andric unsigned Indentation) const;
1490b57cec5SDimitry Andric void emitDecoderFunction(formatted_raw_ostream &OS,
1500b57cec5SDimitry Andric DecoderSet &Decoders,
1510b57cec5SDimitry Andric unsigned Indentation) const;
1520b57cec5SDimitry Andric
1530b57cec5SDimitry Andric // run - Output the code emitter
1540b57cec5SDimitry Andric void run(raw_ostream &o);
1550b57cec5SDimitry Andric
1560b57cec5SDimitry Andric private:
1570b57cec5SDimitry Andric CodeGenTarget Target;
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andric public:
1600b57cec5SDimitry Andric std::string PredicateNamespace;
1610b57cec5SDimitry Andric std::string GuardPrefix, GuardPostfix;
1620b57cec5SDimitry Andric std::string ReturnOK, ReturnFail;
1630b57cec5SDimitry Andric std::string Locals;
1640b57cec5SDimitry Andric };
1650b57cec5SDimitry Andric
1660b57cec5SDimitry Andric } // end anonymous namespace
1670b57cec5SDimitry Andric
1680b57cec5SDimitry Andric // The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system
1690b57cec5SDimitry Andric // for a bit value.
1700b57cec5SDimitry Andric //
1710b57cec5SDimitry Andric // BIT_UNFILTERED is used as the init value for a filter position. It is used
1720b57cec5SDimitry Andric // only for filter processings.
1730b57cec5SDimitry Andric typedef enum {
1740b57cec5SDimitry Andric BIT_TRUE, // '1'
1750b57cec5SDimitry Andric BIT_FALSE, // '0'
1760b57cec5SDimitry Andric BIT_UNSET, // '?'
1770b57cec5SDimitry Andric BIT_UNFILTERED // unfiltered
1780b57cec5SDimitry Andric } bit_value_t;
1790b57cec5SDimitry Andric
ValueSet(bit_value_t V)1800b57cec5SDimitry Andric static bool ValueSet(bit_value_t V) {
1810b57cec5SDimitry Andric return (V == BIT_TRUE || V == BIT_FALSE);
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric
ValueNotSet(bit_value_t V)1840b57cec5SDimitry Andric static bool ValueNotSet(bit_value_t V) {
1850b57cec5SDimitry Andric return (V == BIT_UNSET);
1860b57cec5SDimitry Andric }
1870b57cec5SDimitry Andric
Value(bit_value_t V)1880b57cec5SDimitry Andric static int Value(bit_value_t V) {
1890b57cec5SDimitry Andric return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1);
1900b57cec5SDimitry Andric }
1910b57cec5SDimitry Andric
bitFromBits(const BitsInit & bits,unsigned index)1920b57cec5SDimitry Andric static bit_value_t bitFromBits(const BitsInit &bits, unsigned index) {
1930b57cec5SDimitry Andric if (BitInit *bit = dyn_cast<BitInit>(bits.getBit(index)))
1940b57cec5SDimitry Andric return bit->getValue() ? BIT_TRUE : BIT_FALSE;
1950b57cec5SDimitry Andric
1960b57cec5SDimitry Andric // The bit is uninitialized.
1970b57cec5SDimitry Andric return BIT_UNSET;
1980b57cec5SDimitry Andric }
1990b57cec5SDimitry Andric
2000b57cec5SDimitry Andric // Prints the bit value for each position.
dumpBits(raw_ostream & o,const BitsInit & bits)2010b57cec5SDimitry Andric static void dumpBits(raw_ostream &o, const BitsInit &bits) {
2020b57cec5SDimitry Andric for (unsigned index = bits.getNumBits(); index > 0; --index) {
2030b57cec5SDimitry Andric switch (bitFromBits(bits, index - 1)) {
2040b57cec5SDimitry Andric case BIT_TRUE:
2050b57cec5SDimitry Andric o << "1";
2060b57cec5SDimitry Andric break;
2070b57cec5SDimitry Andric case BIT_FALSE:
2080b57cec5SDimitry Andric o << "0";
2090b57cec5SDimitry Andric break;
2100b57cec5SDimitry Andric case BIT_UNSET:
2110b57cec5SDimitry Andric o << "_";
2120b57cec5SDimitry Andric break;
2130b57cec5SDimitry Andric default:
2140b57cec5SDimitry Andric llvm_unreachable("unexpected return value from bitFromBits");
2150b57cec5SDimitry Andric }
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric
getBitsField(const Record & def,StringRef str)2190b57cec5SDimitry Andric static BitsInit &getBitsField(const Record &def, StringRef str) {
2200b57cec5SDimitry Andric BitsInit *bits = def.getValueAsBitsInit(str);
2210b57cec5SDimitry Andric return *bits;
2220b57cec5SDimitry Andric }
2230b57cec5SDimitry Andric
2240b57cec5SDimitry Andric // Representation of the instruction to work on.
2250b57cec5SDimitry Andric typedef std::vector<bit_value_t> insn_t;
2260b57cec5SDimitry Andric
2270b57cec5SDimitry Andric namespace {
2280b57cec5SDimitry Andric
229af732203SDimitry Andric static const uint64_t NO_FIXED_SEGMENTS_SENTINEL = -1ULL;
230af732203SDimitry Andric
2310b57cec5SDimitry Andric class FilterChooser;
2320b57cec5SDimitry Andric
2330b57cec5SDimitry Andric /// Filter - Filter works with FilterChooser to produce the decoding tree for
2340b57cec5SDimitry Andric /// the ISA.
2350b57cec5SDimitry Andric ///
2360b57cec5SDimitry Andric /// It is useful to think of a Filter as governing the switch stmts of the
2370b57cec5SDimitry Andric /// decoding tree in a certain level. Each case stmt delegates to an inferior
2380b57cec5SDimitry Andric /// FilterChooser to decide what further decoding logic to employ, or in another
2390b57cec5SDimitry Andric /// words, what other remaining bits to look at. The FilterChooser eventually
2400b57cec5SDimitry Andric /// chooses a best Filter to do its job.
2410b57cec5SDimitry Andric ///
2420b57cec5SDimitry Andric /// This recursive scheme ends when the number of Opcodes assigned to the
2430b57cec5SDimitry Andric /// FilterChooser becomes 1 or if there is a conflict. A conflict happens when
2440b57cec5SDimitry Andric /// the Filter/FilterChooser combo does not know how to distinguish among the
2450b57cec5SDimitry Andric /// Opcodes assigned.
2460b57cec5SDimitry Andric ///
2470b57cec5SDimitry Andric /// An example of a conflict is
2480b57cec5SDimitry Andric ///
2490b57cec5SDimitry Andric /// Conflict:
2500b57cec5SDimitry Andric /// 111101000.00........00010000....
2510b57cec5SDimitry Andric /// 111101000.00........0001........
2520b57cec5SDimitry Andric /// 1111010...00........0001........
2530b57cec5SDimitry Andric /// 1111010...00....................
2540b57cec5SDimitry Andric /// 1111010.........................
2550b57cec5SDimitry Andric /// 1111............................
2560b57cec5SDimitry Andric /// ................................
2570b57cec5SDimitry Andric /// VST4q8a 111101000_00________00010000____
2580b57cec5SDimitry Andric /// VST4q8b 111101000_00________00010000____
2590b57cec5SDimitry Andric ///
2600b57cec5SDimitry Andric /// The Debug output shows the path that the decoding tree follows to reach the
2610b57cec5SDimitry Andric /// the conclusion that there is a conflict. VST4q8a is a vst4 to double-spaced
2620b57cec5SDimitry Andric /// even registers, while VST4q8b is a vst4 to double-spaced odd registers.
2630b57cec5SDimitry Andric ///
2640b57cec5SDimitry Andric /// The encoding info in the .td files does not specify this meta information,
2650b57cec5SDimitry Andric /// which could have been used by the decoder to resolve the conflict. The
2660b57cec5SDimitry Andric /// decoder could try to decode the even/odd register numbering and assign to
2670b57cec5SDimitry Andric /// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a"
2680b57cec5SDimitry Andric /// version and return the Opcode since the two have the same Asm format string.
2690b57cec5SDimitry Andric class Filter {
2700b57cec5SDimitry Andric protected:
2710b57cec5SDimitry Andric const FilterChooser *Owner;// points to the FilterChooser who owns this filter
2720b57cec5SDimitry Andric unsigned StartBit; // the starting bit position
2730b57cec5SDimitry Andric unsigned NumBits; // number of bits to filter
2740b57cec5SDimitry Andric bool Mixed; // a mixed region contains both set and unset bits
2750b57cec5SDimitry Andric
2760b57cec5SDimitry Andric // Map of well-known segment value to the set of uid's with that value.
2770b57cec5SDimitry Andric std::map<uint64_t, std::vector<EncodingIDAndOpcode>>
2780b57cec5SDimitry Andric FilteredInstructions;
2790b57cec5SDimitry Andric
2800b57cec5SDimitry Andric // Set of uid's with non-constant segment values.
2810b57cec5SDimitry Andric std::vector<EncodingIDAndOpcode> VariableInstructions;
2820b57cec5SDimitry Andric
2830b57cec5SDimitry Andric // Map of well-known segment value to its delegate.
284af732203SDimitry Andric std::map<uint64_t, std::unique_ptr<const FilterChooser>> FilterChooserMap;
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andric // Number of instructions which fall under FilteredInstructions category.
2870b57cec5SDimitry Andric unsigned NumFiltered;
2880b57cec5SDimitry Andric
2890b57cec5SDimitry Andric // Keeps track of the last opcode in the filtered bucket.
2900b57cec5SDimitry Andric EncodingIDAndOpcode LastOpcFiltered;
2910b57cec5SDimitry Andric
2920b57cec5SDimitry Andric public:
2930b57cec5SDimitry Andric Filter(Filter &&f);
2940b57cec5SDimitry Andric Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed);
2950b57cec5SDimitry Andric
2960b57cec5SDimitry Andric ~Filter() = default;
2970b57cec5SDimitry Andric
getNumFiltered() const2980b57cec5SDimitry Andric unsigned getNumFiltered() const { return NumFiltered; }
2990b57cec5SDimitry Andric
getSingletonOpc() const3000b57cec5SDimitry Andric EncodingIDAndOpcode getSingletonOpc() const {
3010b57cec5SDimitry Andric assert(NumFiltered == 1);
3020b57cec5SDimitry Andric return LastOpcFiltered;
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric
3050b57cec5SDimitry Andric // Return the filter chooser for the group of instructions without constant
3060b57cec5SDimitry Andric // segment values.
getVariableFC() const3070b57cec5SDimitry Andric const FilterChooser &getVariableFC() const {
3080b57cec5SDimitry Andric assert(NumFiltered == 1);
3090b57cec5SDimitry Andric assert(FilterChooserMap.size() == 1);
310af732203SDimitry Andric return *(FilterChooserMap.find(NO_FIXED_SEGMENTS_SENTINEL)->second);
3110b57cec5SDimitry Andric }
3120b57cec5SDimitry Andric
3130b57cec5SDimitry Andric // Divides the decoding task into sub tasks and delegates them to the
3140b57cec5SDimitry Andric // inferior FilterChooser's.
3150b57cec5SDimitry Andric //
3160b57cec5SDimitry Andric // A special case arises when there's only one entry in the filtered
3170b57cec5SDimitry Andric // instructions. In order to unambiguously decode the singleton, we need to
3180b57cec5SDimitry Andric // match the remaining undecoded encoding bits against the singleton.
3190b57cec5SDimitry Andric void recurse();
3200b57cec5SDimitry Andric
3210b57cec5SDimitry Andric // Emit table entries to decode instructions given a segment or segments of
3220b57cec5SDimitry Andric // bits.
3230b57cec5SDimitry Andric void emitTableEntry(DecoderTableInfo &TableInfo) const;
3240b57cec5SDimitry Andric
3250b57cec5SDimitry Andric // Returns the number of fanout produced by the filter. More fanout implies
3260b57cec5SDimitry Andric // the filter distinguishes more categories of instructions.
3270b57cec5SDimitry Andric unsigned usefulness() const;
3280b57cec5SDimitry Andric }; // end class Filter
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andric } // end anonymous namespace
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andric // These are states of our finite state machines used in FilterChooser's
3330b57cec5SDimitry Andric // filterProcessor() which produces the filter candidates to use.
3340b57cec5SDimitry Andric typedef enum {
3350b57cec5SDimitry Andric ATTR_NONE,
3360b57cec5SDimitry Andric ATTR_FILTERED,
3370b57cec5SDimitry Andric ATTR_ALL_SET,
3380b57cec5SDimitry Andric ATTR_ALL_UNSET,
3390b57cec5SDimitry Andric ATTR_MIXED
3400b57cec5SDimitry Andric } bitAttr_t;
3410b57cec5SDimitry Andric
3420b57cec5SDimitry Andric /// FilterChooser - FilterChooser chooses the best filter among a set of Filters
3430b57cec5SDimitry Andric /// in order to perform the decoding of instructions at the current level.
3440b57cec5SDimitry Andric ///
3450b57cec5SDimitry Andric /// Decoding proceeds from the top down. Based on the well-known encoding bits
3460b57cec5SDimitry Andric /// of instructions available, FilterChooser builds up the possible Filters that
3470b57cec5SDimitry Andric /// can further the task of decoding by distinguishing among the remaining
3480b57cec5SDimitry Andric /// candidate instructions.
3490b57cec5SDimitry Andric ///
3500b57cec5SDimitry Andric /// Once a filter has been chosen, it is called upon to divide the decoding task
3510b57cec5SDimitry Andric /// into sub-tasks and delegates them to its inferior FilterChoosers for further
3520b57cec5SDimitry Andric /// processings.
3530b57cec5SDimitry Andric ///
3540b57cec5SDimitry Andric /// It is useful to think of a Filter as governing the switch stmts of the
3550b57cec5SDimitry Andric /// decoding tree. And each case is delegated to an inferior FilterChooser to
3560b57cec5SDimitry Andric /// decide what further remaining bits to look at.
3570b57cec5SDimitry Andric namespace {
3580b57cec5SDimitry Andric
3590b57cec5SDimitry Andric class FilterChooser {
3600b57cec5SDimitry Andric protected:
3610b57cec5SDimitry Andric friend class Filter;
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andric // Vector of codegen instructions to choose our filter.
3640b57cec5SDimitry Andric ArrayRef<EncodingAndInst> AllInstructions;
3650b57cec5SDimitry Andric
3660b57cec5SDimitry Andric // Vector of uid's for this filter chooser to work on.
3670b57cec5SDimitry Andric // The first member of the pair is the opcode id being decoded, the second is
3680b57cec5SDimitry Andric // the opcode id that should be emitted.
3690b57cec5SDimitry Andric const std::vector<EncodingIDAndOpcode> &Opcodes;
3700b57cec5SDimitry Andric
3710b57cec5SDimitry Andric // Lookup table for the operand decoding of instructions.
3720b57cec5SDimitry Andric const std::map<unsigned, std::vector<OperandInfo>> &Operands;
3730b57cec5SDimitry Andric
3740b57cec5SDimitry Andric // Vector of candidate filters.
3750b57cec5SDimitry Andric std::vector<Filter> Filters;
3760b57cec5SDimitry Andric
3770b57cec5SDimitry Andric // Array of bit values passed down from our parent.
3780b57cec5SDimitry Andric // Set to all BIT_UNFILTERED's for Parent == NULL.
3790b57cec5SDimitry Andric std::vector<bit_value_t> FilterBitValues;
3800b57cec5SDimitry Andric
3810b57cec5SDimitry Andric // Links to the FilterChooser above us in the decoding tree.
3820b57cec5SDimitry Andric const FilterChooser *Parent;
3830b57cec5SDimitry Andric
3840b57cec5SDimitry Andric // Index of the best filter from Filters.
3850b57cec5SDimitry Andric int BestIndex;
3860b57cec5SDimitry Andric
3870b57cec5SDimitry Andric // Width of instructions
3880b57cec5SDimitry Andric unsigned BitWidth;
3890b57cec5SDimitry Andric
3900b57cec5SDimitry Andric // Parent emitter
3910b57cec5SDimitry Andric const FixedLenDecoderEmitter *Emitter;
3920b57cec5SDimitry Andric
3930b57cec5SDimitry Andric public:
FilterChooser(ArrayRef<EncodingAndInst> Insts,const std::vector<EncodingIDAndOpcode> & IDs,const std::map<unsigned,std::vector<OperandInfo>> & Ops,unsigned BW,const FixedLenDecoderEmitter * E)3940b57cec5SDimitry Andric FilterChooser(ArrayRef<EncodingAndInst> Insts,
3950b57cec5SDimitry Andric const std::vector<EncodingIDAndOpcode> &IDs,
3960b57cec5SDimitry Andric const std::map<unsigned, std::vector<OperandInfo>> &Ops,
3970b57cec5SDimitry Andric unsigned BW, const FixedLenDecoderEmitter *E)
3980b57cec5SDimitry Andric : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
3990b57cec5SDimitry Andric FilterBitValues(BW, BIT_UNFILTERED), Parent(nullptr), BestIndex(-1),
4000b57cec5SDimitry Andric BitWidth(BW), Emitter(E) {
4010b57cec5SDimitry Andric doFilter();
4020b57cec5SDimitry Andric }
4030b57cec5SDimitry 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)4040b57cec5SDimitry Andric FilterChooser(ArrayRef<EncodingAndInst> Insts,
4050b57cec5SDimitry Andric const std::vector<EncodingIDAndOpcode> &IDs,
4060b57cec5SDimitry Andric const std::map<unsigned, std::vector<OperandInfo>> &Ops,
4070b57cec5SDimitry Andric const std::vector<bit_value_t> &ParentFilterBitValues,
4080b57cec5SDimitry Andric const FilterChooser &parent)
4090b57cec5SDimitry Andric : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
4100b57cec5SDimitry Andric FilterBitValues(ParentFilterBitValues), Parent(&parent), BestIndex(-1),
4110b57cec5SDimitry Andric BitWidth(parent.BitWidth), Emitter(parent.Emitter) {
4120b57cec5SDimitry Andric doFilter();
4130b57cec5SDimitry Andric }
4140b57cec5SDimitry Andric
4150b57cec5SDimitry Andric FilterChooser(const FilterChooser &) = delete;
4160b57cec5SDimitry Andric void operator=(const FilterChooser &) = delete;
4170b57cec5SDimitry Andric
getBitWidth() const4180b57cec5SDimitry Andric unsigned getBitWidth() const { return BitWidth; }
4190b57cec5SDimitry Andric
4200b57cec5SDimitry Andric protected:
4210b57cec5SDimitry Andric // Populates the insn given the uid.
insnWithID(insn_t & Insn,unsigned Opcode) const4220b57cec5SDimitry Andric void insnWithID(insn_t &Insn, unsigned Opcode) const {
4230b57cec5SDimitry Andric BitsInit &Bits = getBitsField(*AllInstructions[Opcode].EncodingDef, "Inst");
4240b57cec5SDimitry Andric
4250b57cec5SDimitry Andric // We may have a SoftFail bitmask, which specifies a mask where an encoding
4260b57cec5SDimitry Andric // may differ from the value in "Inst" and yet still be valid, but the
4270b57cec5SDimitry Andric // disassembler should return SoftFail instead of Success.
4280b57cec5SDimitry Andric //
4290b57cec5SDimitry Andric // This is used for marking UNPREDICTABLE instructions in the ARM world.
4300b57cec5SDimitry Andric BitsInit *SFBits =
4310b57cec5SDimitry Andric AllInstructions[Opcode].EncodingDef->getValueAsBitsInit("SoftFail");
4320b57cec5SDimitry Andric
4330b57cec5SDimitry Andric for (unsigned i = 0; i < BitWidth; ++i) {
4340b57cec5SDimitry Andric if (SFBits && bitFromBits(*SFBits, i) == BIT_TRUE)
4350b57cec5SDimitry Andric Insn.push_back(BIT_UNSET);
4360b57cec5SDimitry Andric else
4370b57cec5SDimitry Andric Insn.push_back(bitFromBits(Bits, i));
4380b57cec5SDimitry Andric }
4390b57cec5SDimitry Andric }
4400b57cec5SDimitry Andric
4410b57cec5SDimitry Andric // Emit the name of the encoding/instruction pair.
emitNameWithID(raw_ostream & OS,unsigned Opcode) const4420b57cec5SDimitry Andric void emitNameWithID(raw_ostream &OS, unsigned Opcode) const {
4430b57cec5SDimitry Andric const Record *EncodingDef = AllInstructions[Opcode].EncodingDef;
4440b57cec5SDimitry Andric const Record *InstDef = AllInstructions[Opcode].Inst->TheDef;
4450b57cec5SDimitry Andric if (EncodingDef != InstDef)
4460b57cec5SDimitry Andric OS << EncodingDef->getName() << ":";
4470b57cec5SDimitry Andric OS << InstDef->getName();
4480b57cec5SDimitry Andric }
4490b57cec5SDimitry Andric
4500b57cec5SDimitry Andric // Populates the field of the insn given the start position and the number of
4510b57cec5SDimitry Andric // consecutive bits to scan for.
4520b57cec5SDimitry Andric //
4530b57cec5SDimitry Andric // Returns false if there exists any uninitialized bit value in the range.
4540b57cec5SDimitry Andric // Returns true, otherwise.
4550b57cec5SDimitry Andric bool fieldFromInsn(uint64_t &Field, insn_t &Insn, unsigned StartBit,
4560b57cec5SDimitry Andric unsigned NumBits) const;
4570b57cec5SDimitry Andric
4580b57cec5SDimitry Andric /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
4590b57cec5SDimitry Andric /// filter array as a series of chars.
4600b57cec5SDimitry Andric void dumpFilterArray(raw_ostream &o,
4610b57cec5SDimitry Andric const std::vector<bit_value_t> & filter) const;
4620b57cec5SDimitry Andric
4630b57cec5SDimitry Andric /// dumpStack - dumpStack traverses the filter chooser chain and calls
4640b57cec5SDimitry Andric /// dumpFilterArray on each filter chooser up to the top level one.
4650b57cec5SDimitry Andric void dumpStack(raw_ostream &o, const char *prefix) const;
4660b57cec5SDimitry Andric
bestFilter()4670b57cec5SDimitry Andric Filter &bestFilter() {
4680b57cec5SDimitry Andric assert(BestIndex != -1 && "BestIndex not set");
4690b57cec5SDimitry Andric return Filters[BestIndex];
4700b57cec5SDimitry Andric }
4710b57cec5SDimitry Andric
PositionFiltered(unsigned i) const4720b57cec5SDimitry Andric bool PositionFiltered(unsigned i) const {
4730b57cec5SDimitry Andric return ValueSet(FilterBitValues[i]);
4740b57cec5SDimitry Andric }
4750b57cec5SDimitry Andric
4760b57cec5SDimitry Andric // Calculates the island(s) needed to decode the instruction.
4770b57cec5SDimitry Andric // This returns a lit of undecoded bits of an instructions, for example,
4780b57cec5SDimitry Andric // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
4790b57cec5SDimitry Andric // decoded bits in order to verify that the instruction matches the Opcode.
4800b57cec5SDimitry Andric unsigned getIslands(std::vector<unsigned> &StartBits,
4810b57cec5SDimitry Andric std::vector<unsigned> &EndBits,
4820b57cec5SDimitry Andric std::vector<uint64_t> &FieldVals,
4830b57cec5SDimitry Andric const insn_t &Insn) const;
4840b57cec5SDimitry Andric
4850b57cec5SDimitry Andric // Emits code to check the Predicates member of an instruction are true.
4860b57cec5SDimitry Andric // Returns true if predicate matches were emitted, false otherwise.
4870b57cec5SDimitry Andric bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
4880b57cec5SDimitry Andric unsigned Opc) const;
4890b57cec5SDimitry Andric
4900b57cec5SDimitry Andric bool doesOpcodeNeedPredicate(unsigned Opc) const;
4910b57cec5SDimitry Andric unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const;
4920b57cec5SDimitry Andric void emitPredicateTableEntry(DecoderTableInfo &TableInfo,
4930b57cec5SDimitry Andric unsigned Opc) const;
4940b57cec5SDimitry Andric
4950b57cec5SDimitry Andric void emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
4960b57cec5SDimitry Andric unsigned Opc) const;
4970b57cec5SDimitry Andric
4980b57cec5SDimitry Andric // Emits table entries to decode the singleton.
4990b57cec5SDimitry Andric void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
5000b57cec5SDimitry Andric EncodingIDAndOpcode Opc) const;
5010b57cec5SDimitry Andric
5020b57cec5SDimitry Andric // Emits code to decode the singleton, and then to decode the rest.
5030b57cec5SDimitry Andric void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
5040b57cec5SDimitry Andric const Filter &Best) const;
5050b57cec5SDimitry Andric
5060b57cec5SDimitry Andric void emitBinaryParser(raw_ostream &o, unsigned &Indentation,
5070b57cec5SDimitry Andric const OperandInfo &OpInfo,
5080b57cec5SDimitry Andric bool &OpHasCompleteDecoder) const;
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andric void emitDecoder(raw_ostream &OS, unsigned Indentation, unsigned Opc,
5110b57cec5SDimitry Andric bool &HasCompleteDecoder) const;
5120b57cec5SDimitry Andric unsigned getDecoderIndex(DecoderSet &Decoders, unsigned Opc,
5130b57cec5SDimitry Andric bool &HasCompleteDecoder) const;
5140b57cec5SDimitry Andric
5150b57cec5SDimitry Andric // Assign a single filter and run with it.
5160b57cec5SDimitry Andric void runSingleFilter(unsigned startBit, unsigned numBit, bool mixed);
5170b57cec5SDimitry Andric
5180b57cec5SDimitry Andric // reportRegion is a helper function for filterProcessor to mark a region as
5190b57cec5SDimitry Andric // eligible for use as a filter region.
5200b57cec5SDimitry Andric void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex,
5210b57cec5SDimitry Andric bool AllowMixed);
5220b57cec5SDimitry Andric
5230b57cec5SDimitry Andric // FilterProcessor scans the well-known encoding bits of the instructions and
5240b57cec5SDimitry Andric // builds up a list of candidate filters. It chooses the best filter and
5250b57cec5SDimitry Andric // recursively descends down the decoding tree.
5260b57cec5SDimitry Andric bool filterProcessor(bool AllowMixed, bool Greedy = true);
5270b57cec5SDimitry Andric
5280b57cec5SDimitry Andric // Decides on the best configuration of filter(s) to use in order to decode
5290b57cec5SDimitry Andric // the instructions. A conflict of instructions may occur, in which case we
5300b57cec5SDimitry Andric // dump the conflict set to the standard error.
5310b57cec5SDimitry Andric void doFilter();
5320b57cec5SDimitry Andric
5330b57cec5SDimitry Andric public:
5340b57cec5SDimitry Andric // emitTableEntries - Emit state machine entries to decode our share of
5350b57cec5SDimitry Andric // instructions.
5360b57cec5SDimitry Andric void emitTableEntries(DecoderTableInfo &TableInfo) const;
5370b57cec5SDimitry Andric };
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andric } // end anonymous namespace
5400b57cec5SDimitry Andric
5410b57cec5SDimitry Andric ///////////////////////////
5420b57cec5SDimitry Andric // //
5430b57cec5SDimitry Andric // Filter Implementation //
5440b57cec5SDimitry Andric // //
5450b57cec5SDimitry Andric ///////////////////////////
5460b57cec5SDimitry Andric
Filter(Filter && f)5470b57cec5SDimitry Andric Filter::Filter(Filter &&f)
5480b57cec5SDimitry Andric : Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed),
5490b57cec5SDimitry Andric FilteredInstructions(std::move(f.FilteredInstructions)),
5500b57cec5SDimitry Andric VariableInstructions(std::move(f.VariableInstructions)),
5510b57cec5SDimitry Andric FilterChooserMap(std::move(f.FilterChooserMap)), NumFiltered(f.NumFiltered),
5520b57cec5SDimitry Andric LastOpcFiltered(f.LastOpcFiltered) {
5530b57cec5SDimitry Andric }
5540b57cec5SDimitry Andric
Filter(FilterChooser & owner,unsigned startBit,unsigned numBits,bool mixed)5550b57cec5SDimitry Andric Filter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits,
5560b57cec5SDimitry Andric bool mixed)
5570b57cec5SDimitry Andric : Owner(&owner), StartBit(startBit), NumBits(numBits), Mixed(mixed) {
5580b57cec5SDimitry Andric assert(StartBit + NumBits - 1 < Owner->BitWidth);
5590b57cec5SDimitry Andric
5600b57cec5SDimitry Andric NumFiltered = 0;
5610b57cec5SDimitry Andric LastOpcFiltered = {0, 0};
5620b57cec5SDimitry Andric
5630b57cec5SDimitry Andric for (unsigned i = 0, e = Owner->Opcodes.size(); i != e; ++i) {
5640b57cec5SDimitry Andric insn_t Insn;
5650b57cec5SDimitry Andric
5660b57cec5SDimitry Andric // Populates the insn given the uid.
5670b57cec5SDimitry Andric Owner->insnWithID(Insn, Owner->Opcodes[i].EncodingID);
5680b57cec5SDimitry Andric
5690b57cec5SDimitry Andric uint64_t Field;
5700b57cec5SDimitry Andric // Scans the segment for possibly well-specified encoding bits.
5710b57cec5SDimitry Andric bool ok = Owner->fieldFromInsn(Field, Insn, StartBit, NumBits);
5720b57cec5SDimitry Andric
5730b57cec5SDimitry Andric if (ok) {
5740b57cec5SDimitry Andric // The encoding bits are well-known. Lets add the uid of the
5750b57cec5SDimitry Andric // instruction into the bucket keyed off the constant field value.
5760b57cec5SDimitry Andric LastOpcFiltered = Owner->Opcodes[i];
5770b57cec5SDimitry Andric FilteredInstructions[Field].push_back(LastOpcFiltered);
5780b57cec5SDimitry Andric ++NumFiltered;
5790b57cec5SDimitry Andric } else {
5800b57cec5SDimitry Andric // Some of the encoding bit(s) are unspecified. This contributes to
5810b57cec5SDimitry Andric // one additional member of "Variable" instructions.
5820b57cec5SDimitry Andric VariableInstructions.push_back(Owner->Opcodes[i]);
5830b57cec5SDimitry Andric }
5840b57cec5SDimitry Andric }
5850b57cec5SDimitry Andric
5860b57cec5SDimitry Andric assert((FilteredInstructions.size() + VariableInstructions.size() > 0)
5870b57cec5SDimitry Andric && "Filter returns no instruction categories");
5880b57cec5SDimitry Andric }
5890b57cec5SDimitry Andric
5900b57cec5SDimitry Andric // Divides the decoding task into sub tasks and delegates them to the
5910b57cec5SDimitry Andric // inferior FilterChooser's.
5920b57cec5SDimitry Andric //
5930b57cec5SDimitry Andric // A special case arises when there's only one entry in the filtered
5940b57cec5SDimitry Andric // instructions. In order to unambiguously decode the singleton, we need to
5950b57cec5SDimitry Andric // match the remaining undecoded encoding bits against the singleton.
recurse()5960b57cec5SDimitry Andric void Filter::recurse() {
5970b57cec5SDimitry Andric // Starts by inheriting our parent filter chooser's filter bit values.
5980b57cec5SDimitry Andric std::vector<bit_value_t> BitValueArray(Owner->FilterBitValues);
5990b57cec5SDimitry Andric
6000b57cec5SDimitry Andric if (!VariableInstructions.empty()) {
6010b57cec5SDimitry Andric // Conservatively marks each segment position as BIT_UNSET.
6020b57cec5SDimitry Andric for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex)
6030b57cec5SDimitry Andric BitValueArray[StartBit + bitIndex] = BIT_UNSET;
6040b57cec5SDimitry Andric
6050b57cec5SDimitry Andric // Delegates to an inferior filter chooser for further processing on this
6060b57cec5SDimitry Andric // group of instructions whose segment values are variable.
607af732203SDimitry Andric FilterChooserMap.insert(std::make_pair(NO_FIXED_SEGMENTS_SENTINEL,
608af732203SDimitry Andric std::make_unique<FilterChooser>(Owner->AllInstructions,
609af732203SDimitry Andric VariableInstructions, Owner->Operands, BitValueArray, *Owner)));
6100b57cec5SDimitry Andric }
6110b57cec5SDimitry Andric
6120b57cec5SDimitry Andric // No need to recurse for a singleton filtered instruction.
6130b57cec5SDimitry Andric // See also Filter::emit*().
6140b57cec5SDimitry Andric if (getNumFiltered() == 1) {
6150b57cec5SDimitry Andric assert(FilterChooserMap.size() == 1);
6160b57cec5SDimitry Andric return;
6170b57cec5SDimitry Andric }
6180b57cec5SDimitry Andric
6190b57cec5SDimitry Andric // Otherwise, create sub choosers.
6200b57cec5SDimitry Andric for (const auto &Inst : FilteredInstructions) {
6210b57cec5SDimitry Andric
6220b57cec5SDimitry Andric // Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
6230b57cec5SDimitry Andric for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) {
6240b57cec5SDimitry Andric if (Inst.first & (1ULL << bitIndex))
6250b57cec5SDimitry Andric BitValueArray[StartBit + bitIndex] = BIT_TRUE;
6260b57cec5SDimitry Andric else
6270b57cec5SDimitry Andric BitValueArray[StartBit + bitIndex] = BIT_FALSE;
6280b57cec5SDimitry Andric }
6290b57cec5SDimitry Andric
6300b57cec5SDimitry Andric // Delegates to an inferior filter chooser for further processing on this
6310b57cec5SDimitry Andric // category of instructions.
6320b57cec5SDimitry Andric FilterChooserMap.insert(std::make_pair(
6338bcb0991SDimitry Andric Inst.first, std::make_unique<FilterChooser>(
6340b57cec5SDimitry Andric Owner->AllInstructions, Inst.second,
6350b57cec5SDimitry Andric Owner->Operands, BitValueArray, *Owner)));
6360b57cec5SDimitry Andric }
6370b57cec5SDimitry Andric }
6380b57cec5SDimitry Andric
resolveTableFixups(DecoderTable & Table,const FixupList & Fixups,uint32_t DestIdx)6390b57cec5SDimitry Andric static void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups,
6400b57cec5SDimitry Andric uint32_t DestIdx) {
6410b57cec5SDimitry Andric // Any NumToSkip fixups in the current scope can resolve to the
6420b57cec5SDimitry Andric // current location.
6430b57cec5SDimitry Andric for (FixupList::const_reverse_iterator I = Fixups.rbegin(),
6440b57cec5SDimitry Andric E = Fixups.rend();
6450b57cec5SDimitry Andric I != E; ++I) {
6460b57cec5SDimitry Andric // Calculate the distance from the byte following the fixup entry byte
6470b57cec5SDimitry Andric // to the destination. The Target is calculated from after the 16-bit
6480b57cec5SDimitry Andric // NumToSkip entry itself, so subtract two from the displacement here
6490b57cec5SDimitry Andric // to account for that.
6500b57cec5SDimitry Andric uint32_t FixupIdx = *I;
6510b57cec5SDimitry Andric uint32_t Delta = DestIdx - FixupIdx - 3;
6520b57cec5SDimitry Andric // Our NumToSkip entries are 24-bits. Make sure our table isn't too
6530b57cec5SDimitry Andric // big.
6540b57cec5SDimitry Andric assert(Delta < (1u << 24));
6550b57cec5SDimitry Andric Table[FixupIdx] = (uint8_t)Delta;
6560b57cec5SDimitry Andric Table[FixupIdx + 1] = (uint8_t)(Delta >> 8);
6570b57cec5SDimitry Andric Table[FixupIdx + 2] = (uint8_t)(Delta >> 16);
6580b57cec5SDimitry Andric }
6590b57cec5SDimitry Andric }
6600b57cec5SDimitry Andric
6610b57cec5SDimitry Andric // Emit table entries to decode instructions given a segment or segments
6620b57cec5SDimitry Andric // of bits.
emitTableEntry(DecoderTableInfo & TableInfo) const6630b57cec5SDimitry Andric void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
6640b57cec5SDimitry Andric TableInfo.Table.push_back(MCD::OPC_ExtractField);
6650b57cec5SDimitry Andric TableInfo.Table.push_back(StartBit);
6660b57cec5SDimitry Andric TableInfo.Table.push_back(NumBits);
6670b57cec5SDimitry Andric
6680b57cec5SDimitry Andric // A new filter entry begins a new scope for fixup resolution.
6690b57cec5SDimitry Andric TableInfo.FixupStack.emplace_back();
6700b57cec5SDimitry Andric
6710b57cec5SDimitry Andric DecoderTable &Table = TableInfo.Table;
6720b57cec5SDimitry Andric
6730b57cec5SDimitry Andric size_t PrevFilter = 0;
6740b57cec5SDimitry Andric bool HasFallthrough = false;
6750b57cec5SDimitry Andric for (auto &Filter : FilterChooserMap) {
6760b57cec5SDimitry Andric // Field value -1 implies a non-empty set of variable instructions.
6770b57cec5SDimitry Andric // See also recurse().
678af732203SDimitry Andric if (Filter.first == NO_FIXED_SEGMENTS_SENTINEL) {
6790b57cec5SDimitry Andric HasFallthrough = true;
6800b57cec5SDimitry Andric
6810b57cec5SDimitry Andric // Each scope should always have at least one filter value to check
6820b57cec5SDimitry Andric // for.
6830b57cec5SDimitry Andric assert(PrevFilter != 0 && "empty filter set!");
6840b57cec5SDimitry Andric FixupList &CurScope = TableInfo.FixupStack.back();
6850b57cec5SDimitry Andric // Resolve any NumToSkip fixups in the current scope.
6860b57cec5SDimitry Andric resolveTableFixups(Table, CurScope, Table.size());
6870b57cec5SDimitry Andric CurScope.clear();
6880b57cec5SDimitry Andric PrevFilter = 0; // Don't re-process the filter's fallthrough.
6890b57cec5SDimitry Andric } else {
6900b57cec5SDimitry Andric Table.push_back(MCD::OPC_FilterValue);
6910b57cec5SDimitry Andric // Encode and emit the value to filter against.
6920b57cec5SDimitry Andric uint8_t Buffer[16];
6930b57cec5SDimitry Andric unsigned Len = encodeULEB128(Filter.first, Buffer);
6940b57cec5SDimitry Andric Table.insert(Table.end(), Buffer, Buffer + Len);
6950b57cec5SDimitry Andric // Reserve space for the NumToSkip entry. We'll backpatch the value
6960b57cec5SDimitry Andric // later.
6970b57cec5SDimitry Andric PrevFilter = Table.size();
6980b57cec5SDimitry Andric Table.push_back(0);
6990b57cec5SDimitry Andric Table.push_back(0);
7000b57cec5SDimitry Andric Table.push_back(0);
7010b57cec5SDimitry Andric }
7020b57cec5SDimitry Andric
7030b57cec5SDimitry Andric // We arrive at a category of instructions with the same segment value.
7040b57cec5SDimitry Andric // Now delegate to the sub filter chooser for further decodings.
7050b57cec5SDimitry Andric // The case may fallthrough, which happens if the remaining well-known
7060b57cec5SDimitry Andric // encoding bits do not match exactly.
7070b57cec5SDimitry Andric Filter.second->emitTableEntries(TableInfo);
7080b57cec5SDimitry Andric
7090b57cec5SDimitry Andric // Now that we've emitted the body of the handler, update the NumToSkip
7100b57cec5SDimitry Andric // of the filter itself to be able to skip forward when false. Subtract
7110b57cec5SDimitry Andric // two as to account for the width of the NumToSkip field itself.
7120b57cec5SDimitry Andric if (PrevFilter) {
7130b57cec5SDimitry Andric uint32_t NumToSkip = Table.size() - PrevFilter - 3;
7140b57cec5SDimitry Andric assert(NumToSkip < (1u << 24) && "disassembler decoding table too large!");
7150b57cec5SDimitry Andric Table[PrevFilter] = (uint8_t)NumToSkip;
7160b57cec5SDimitry Andric Table[PrevFilter + 1] = (uint8_t)(NumToSkip >> 8);
7170b57cec5SDimitry Andric Table[PrevFilter + 2] = (uint8_t)(NumToSkip >> 16);
7180b57cec5SDimitry Andric }
7190b57cec5SDimitry Andric }
7200b57cec5SDimitry Andric
7210b57cec5SDimitry Andric // Any remaining unresolved fixups bubble up to the parent fixup scope.
7220b57cec5SDimitry Andric assert(TableInfo.FixupStack.size() > 1 && "fixup stack underflow!");
7230b57cec5SDimitry Andric FixupScopeList::iterator Source = TableInfo.FixupStack.end() - 1;
7240b57cec5SDimitry Andric FixupScopeList::iterator Dest = Source - 1;
725af732203SDimitry Andric llvm::append_range(*Dest, *Source);
7260b57cec5SDimitry Andric TableInfo.FixupStack.pop_back();
7270b57cec5SDimitry Andric
7280b57cec5SDimitry Andric // If there is no fallthrough, then the final filter should get fixed
7290b57cec5SDimitry Andric // up according to the enclosing scope rather than the current position.
7300b57cec5SDimitry Andric if (!HasFallthrough)
7310b57cec5SDimitry Andric TableInfo.FixupStack.back().push_back(PrevFilter);
7320b57cec5SDimitry Andric }
7330b57cec5SDimitry Andric
7340b57cec5SDimitry Andric // Returns the number of fanout produced by the filter. More fanout implies
7350b57cec5SDimitry Andric // the filter distinguishes more categories of instructions.
usefulness() const7360b57cec5SDimitry Andric unsigned Filter::usefulness() const {
7370b57cec5SDimitry Andric if (!VariableInstructions.empty())
7380b57cec5SDimitry Andric return FilteredInstructions.size();
7390b57cec5SDimitry Andric else
7400b57cec5SDimitry Andric return FilteredInstructions.size() + 1;
7410b57cec5SDimitry Andric }
7420b57cec5SDimitry Andric
7430b57cec5SDimitry Andric //////////////////////////////////
7440b57cec5SDimitry Andric // //
7450b57cec5SDimitry Andric // Filterchooser Implementation //
7460b57cec5SDimitry Andric // //
7470b57cec5SDimitry Andric //////////////////////////////////
7480b57cec5SDimitry Andric
7490b57cec5SDimitry Andric // Emit the decoder state machine table.
emitTable(formatted_raw_ostream & OS,DecoderTable & Table,unsigned Indentation,unsigned BitWidth,StringRef Namespace) const7500b57cec5SDimitry Andric void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
7510b57cec5SDimitry Andric DecoderTable &Table,
7520b57cec5SDimitry Andric unsigned Indentation,
7530b57cec5SDimitry Andric unsigned BitWidth,
7540b57cec5SDimitry Andric StringRef Namespace) const {
7550b57cec5SDimitry Andric OS.indent(Indentation) << "static const uint8_t DecoderTable" << Namespace
7560b57cec5SDimitry Andric << BitWidth << "[] = {\n";
7570b57cec5SDimitry Andric
7580b57cec5SDimitry Andric Indentation += 2;
7590b57cec5SDimitry Andric
7600b57cec5SDimitry Andric // FIXME: We may be able to use the NumToSkip values to recover
7610b57cec5SDimitry Andric // appropriate indentation levels.
7620b57cec5SDimitry Andric DecoderTable::const_iterator I = Table.begin();
7630b57cec5SDimitry Andric DecoderTable::const_iterator E = Table.end();
7640b57cec5SDimitry Andric while (I != E) {
7650b57cec5SDimitry Andric assert (I < E && "incomplete decode table entry!");
7660b57cec5SDimitry Andric
7670b57cec5SDimitry Andric uint64_t Pos = I - Table.begin();
7680b57cec5SDimitry Andric OS << "/* " << Pos << " */";
7690b57cec5SDimitry Andric OS.PadToColumn(12);
7700b57cec5SDimitry Andric
7710b57cec5SDimitry Andric switch (*I) {
7720b57cec5SDimitry Andric default:
7730b57cec5SDimitry Andric PrintFatalError("invalid decode table opcode");
7740b57cec5SDimitry Andric case MCD::OPC_ExtractField: {
7750b57cec5SDimitry Andric ++I;
7760b57cec5SDimitry Andric unsigned Start = *I++;
7770b57cec5SDimitry Andric unsigned Len = *I++;
7780b57cec5SDimitry Andric OS.indent(Indentation) << "MCD::OPC_ExtractField, " << Start << ", "
7790b57cec5SDimitry Andric << Len << ", // Inst{";
7800b57cec5SDimitry Andric if (Len > 1)
7810b57cec5SDimitry Andric OS << (Start + Len - 1) << "-";
7820b57cec5SDimitry Andric OS << Start << "} ...\n";
7830b57cec5SDimitry Andric break;
7840b57cec5SDimitry Andric }
7850b57cec5SDimitry Andric case MCD::OPC_FilterValue: {
7860b57cec5SDimitry Andric ++I;
7870b57cec5SDimitry Andric OS.indent(Indentation) << "MCD::OPC_FilterValue, ";
7880b57cec5SDimitry Andric // The filter value is ULEB128 encoded.
7890b57cec5SDimitry Andric while (*I >= 128)
7900b57cec5SDimitry Andric OS << (unsigned)*I++ << ", ";
7910b57cec5SDimitry Andric OS << (unsigned)*I++ << ", ";
7920b57cec5SDimitry Andric
7930b57cec5SDimitry Andric // 24-bit numtoskip value.
7940b57cec5SDimitry Andric uint8_t Byte = *I++;
7950b57cec5SDimitry Andric uint32_t NumToSkip = Byte;
7960b57cec5SDimitry Andric OS << (unsigned)Byte << ", ";
7970b57cec5SDimitry Andric Byte = *I++;
7980b57cec5SDimitry Andric OS << (unsigned)Byte << ", ";
7990b57cec5SDimitry Andric NumToSkip |= Byte << 8;
8000b57cec5SDimitry Andric Byte = *I++;
8010b57cec5SDimitry Andric OS << utostr(Byte) << ", ";
8020b57cec5SDimitry Andric NumToSkip |= Byte << 16;
8030b57cec5SDimitry Andric OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
8040b57cec5SDimitry Andric break;
8050b57cec5SDimitry Andric }
8060b57cec5SDimitry Andric case MCD::OPC_CheckField: {
8070b57cec5SDimitry Andric ++I;
8080b57cec5SDimitry Andric unsigned Start = *I++;
8090b57cec5SDimitry Andric unsigned Len = *I++;
8100b57cec5SDimitry Andric OS.indent(Indentation) << "MCD::OPC_CheckField, " << Start << ", "
8110b57cec5SDimitry Andric << Len << ", ";// << Val << ", " << NumToSkip << ",\n";
8120b57cec5SDimitry Andric // ULEB128 encoded field value.
8130b57cec5SDimitry Andric for (; *I >= 128; ++I)
8140b57cec5SDimitry Andric OS << (unsigned)*I << ", ";
8150b57cec5SDimitry Andric OS << (unsigned)*I++ << ", ";
8160b57cec5SDimitry Andric // 24-bit numtoskip value.
8170b57cec5SDimitry Andric uint8_t Byte = *I++;
8180b57cec5SDimitry Andric uint32_t NumToSkip = Byte;
8190b57cec5SDimitry Andric OS << (unsigned)Byte << ", ";
8200b57cec5SDimitry Andric Byte = *I++;
8210b57cec5SDimitry Andric OS << (unsigned)Byte << ", ";
8220b57cec5SDimitry Andric NumToSkip |= Byte << 8;
8230b57cec5SDimitry Andric Byte = *I++;
8240b57cec5SDimitry Andric OS << utostr(Byte) << ", ";
8250b57cec5SDimitry Andric NumToSkip |= Byte << 16;
8260b57cec5SDimitry Andric OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
8270b57cec5SDimitry Andric break;
8280b57cec5SDimitry Andric }
8290b57cec5SDimitry Andric case MCD::OPC_CheckPredicate: {
8300b57cec5SDimitry Andric ++I;
8310b57cec5SDimitry Andric OS.indent(Indentation) << "MCD::OPC_CheckPredicate, ";
8320b57cec5SDimitry Andric for (; *I >= 128; ++I)
8330b57cec5SDimitry Andric OS << (unsigned)*I << ", ";
8340b57cec5SDimitry Andric OS << (unsigned)*I++ << ", ";
8350b57cec5SDimitry Andric
8360b57cec5SDimitry Andric // 24-bit numtoskip value.
8370b57cec5SDimitry Andric uint8_t Byte = *I++;
8380b57cec5SDimitry Andric uint32_t NumToSkip = Byte;
8390b57cec5SDimitry Andric OS << (unsigned)Byte << ", ";
8400b57cec5SDimitry Andric Byte = *I++;
8410b57cec5SDimitry Andric OS << (unsigned)Byte << ", ";
8420b57cec5SDimitry Andric NumToSkip |= Byte << 8;
8430b57cec5SDimitry Andric Byte = *I++;
8440b57cec5SDimitry Andric OS << utostr(Byte) << ", ";
8450b57cec5SDimitry Andric NumToSkip |= Byte << 16;
8460b57cec5SDimitry Andric OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
8470b57cec5SDimitry Andric break;
8480b57cec5SDimitry Andric }
8490b57cec5SDimitry Andric case MCD::OPC_Decode:
8500b57cec5SDimitry Andric case MCD::OPC_TryDecode: {
8510b57cec5SDimitry Andric bool IsTry = *I == MCD::OPC_TryDecode;
8520b57cec5SDimitry Andric ++I;
8530b57cec5SDimitry Andric // Extract the ULEB128 encoded Opcode to a buffer.
8540b57cec5SDimitry Andric uint8_t Buffer[16], *p = Buffer;
8550b57cec5SDimitry Andric while ((*p++ = *I++) >= 128)
8560b57cec5SDimitry Andric assert((p - Buffer) <= (ptrdiff_t)sizeof(Buffer)
8570b57cec5SDimitry Andric && "ULEB128 value too large!");
8580b57cec5SDimitry Andric // Decode the Opcode value.
8590b57cec5SDimitry Andric unsigned Opc = decodeULEB128(Buffer);
8600b57cec5SDimitry Andric OS.indent(Indentation) << "MCD::OPC_" << (IsTry ? "Try" : "")
8610b57cec5SDimitry Andric << "Decode, ";
8620b57cec5SDimitry Andric for (p = Buffer; *p >= 128; ++p)
8630b57cec5SDimitry Andric OS << (unsigned)*p << ", ";
8640b57cec5SDimitry Andric OS << (unsigned)*p << ", ";
8650b57cec5SDimitry Andric
8660b57cec5SDimitry Andric // Decoder index.
8670b57cec5SDimitry Andric for (; *I >= 128; ++I)
8680b57cec5SDimitry Andric OS << (unsigned)*I << ", ";
8690b57cec5SDimitry Andric OS << (unsigned)*I++ << ", ";
8700b57cec5SDimitry Andric
8710b57cec5SDimitry Andric if (!IsTry) {
8720b57cec5SDimitry Andric OS << "// Opcode: " << NumberedEncodings[Opc] << "\n";
8730b57cec5SDimitry Andric break;
8740b57cec5SDimitry Andric }
8750b57cec5SDimitry Andric
8760b57cec5SDimitry Andric // Fallthrough for OPC_TryDecode.
8770b57cec5SDimitry Andric
8780b57cec5SDimitry Andric // 24-bit numtoskip value.
8790b57cec5SDimitry Andric uint8_t Byte = *I++;
8800b57cec5SDimitry Andric uint32_t NumToSkip = Byte;
8810b57cec5SDimitry Andric OS << (unsigned)Byte << ", ";
8820b57cec5SDimitry Andric Byte = *I++;
8830b57cec5SDimitry Andric OS << (unsigned)Byte << ", ";
8840b57cec5SDimitry Andric NumToSkip |= Byte << 8;
8850b57cec5SDimitry Andric Byte = *I++;
8860b57cec5SDimitry Andric OS << utostr(Byte) << ", ";
8870b57cec5SDimitry Andric NumToSkip |= Byte << 16;
8880b57cec5SDimitry Andric
8890b57cec5SDimitry Andric OS << "// Opcode: " << NumberedEncodings[Opc]
8900b57cec5SDimitry Andric << ", skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
8910b57cec5SDimitry Andric break;
8920b57cec5SDimitry Andric }
8930b57cec5SDimitry Andric case MCD::OPC_SoftFail: {
8940b57cec5SDimitry Andric ++I;
8950b57cec5SDimitry Andric OS.indent(Indentation) << "MCD::OPC_SoftFail";
8960b57cec5SDimitry Andric // Positive mask
8970b57cec5SDimitry Andric uint64_t Value = 0;
8980b57cec5SDimitry Andric unsigned Shift = 0;
8990b57cec5SDimitry Andric do {
9000b57cec5SDimitry Andric OS << ", " << (unsigned)*I;
9010b57cec5SDimitry Andric Value += (*I & 0x7f) << Shift;
9020b57cec5SDimitry Andric Shift += 7;
9030b57cec5SDimitry Andric } while (*I++ >= 128);
9040b57cec5SDimitry Andric if (Value > 127) {
9050b57cec5SDimitry Andric OS << " /* 0x";
9060b57cec5SDimitry Andric OS.write_hex(Value);
9070b57cec5SDimitry Andric OS << " */";
9080b57cec5SDimitry Andric }
9090b57cec5SDimitry Andric // Negative mask
9100b57cec5SDimitry Andric Value = 0;
9110b57cec5SDimitry Andric Shift = 0;
9120b57cec5SDimitry Andric do {
9130b57cec5SDimitry Andric OS << ", " << (unsigned)*I;
9140b57cec5SDimitry Andric Value += (*I & 0x7f) << Shift;
9150b57cec5SDimitry Andric Shift += 7;
9160b57cec5SDimitry Andric } while (*I++ >= 128);
9170b57cec5SDimitry Andric if (Value > 127) {
9180b57cec5SDimitry Andric OS << " /* 0x";
9190b57cec5SDimitry Andric OS.write_hex(Value);
9200b57cec5SDimitry Andric OS << " */";
9210b57cec5SDimitry Andric }
9220b57cec5SDimitry Andric OS << ",\n";
9230b57cec5SDimitry Andric break;
9240b57cec5SDimitry Andric }
9250b57cec5SDimitry Andric case MCD::OPC_Fail: {
9260b57cec5SDimitry Andric ++I;
9270b57cec5SDimitry Andric OS.indent(Indentation) << "MCD::OPC_Fail,\n";
9280b57cec5SDimitry Andric break;
9290b57cec5SDimitry Andric }
9300b57cec5SDimitry Andric }
9310b57cec5SDimitry Andric }
9320b57cec5SDimitry Andric OS.indent(Indentation) << "0\n";
9330b57cec5SDimitry Andric
9340b57cec5SDimitry Andric Indentation -= 2;
9350b57cec5SDimitry Andric
9360b57cec5SDimitry Andric OS.indent(Indentation) << "};\n\n";
9370b57cec5SDimitry Andric }
9380b57cec5SDimitry Andric
9390b57cec5SDimitry Andric void FixedLenDecoderEmitter::
emitPredicateFunction(formatted_raw_ostream & OS,PredicateSet & Predicates,unsigned Indentation) const9400b57cec5SDimitry Andric emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
9410b57cec5SDimitry Andric unsigned Indentation) const {
9420b57cec5SDimitry Andric // The predicate function is just a big switch statement based on the
9430b57cec5SDimitry Andric // input predicate index.
9440b57cec5SDimitry Andric OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
9450b57cec5SDimitry Andric << "const FeatureBitset &Bits) {\n";
9460b57cec5SDimitry Andric Indentation += 2;
9470b57cec5SDimitry Andric if (!Predicates.empty()) {
9480b57cec5SDimitry Andric OS.indent(Indentation) << "switch (Idx) {\n";
9490b57cec5SDimitry Andric OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
9500b57cec5SDimitry Andric unsigned Index = 0;
9510b57cec5SDimitry Andric for (const auto &Predicate : Predicates) {
9520b57cec5SDimitry Andric OS.indent(Indentation) << "case " << Index++ << ":\n";
9530b57cec5SDimitry Andric OS.indent(Indentation+2) << "return (" << Predicate << ");\n";
9540b57cec5SDimitry Andric }
9550b57cec5SDimitry Andric OS.indent(Indentation) << "}\n";
9560b57cec5SDimitry Andric } else {
9570b57cec5SDimitry Andric // No case statement to emit
9580b57cec5SDimitry Andric OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n";
9590b57cec5SDimitry Andric }
9600b57cec5SDimitry Andric Indentation -= 2;
9610b57cec5SDimitry Andric OS.indent(Indentation) << "}\n\n";
9620b57cec5SDimitry Andric }
9630b57cec5SDimitry Andric
9640b57cec5SDimitry Andric void FixedLenDecoderEmitter::
emitDecoderFunction(formatted_raw_ostream & OS,DecoderSet & Decoders,unsigned Indentation) const9650b57cec5SDimitry Andric emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
9660b57cec5SDimitry Andric unsigned Indentation) const {
9670b57cec5SDimitry Andric // The decoder function is just a big switch statement based on the
9680b57cec5SDimitry Andric // input decoder index.
9690b57cec5SDimitry Andric OS.indent(Indentation) << "template <typename InsnType>\n";
9700b57cec5SDimitry Andric OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S,"
9710b57cec5SDimitry Andric << " unsigned Idx, InsnType insn, MCInst &MI,\n";
9720b57cec5SDimitry Andric OS.indent(Indentation) << " uint64_t "
9730b57cec5SDimitry Andric << "Address, const void *Decoder, bool &DecodeComplete) {\n";
9740b57cec5SDimitry Andric Indentation += 2;
9750b57cec5SDimitry Andric OS.indent(Indentation) << "DecodeComplete = true;\n";
976*5f7ddb14SDimitry Andric // TODO: When InsnType is large, using uint64_t limits all fields to 64 bits
977*5f7ddb14SDimitry Andric // It would be better for emitBinaryParser to use a 64-bit tmp whenever
978*5f7ddb14SDimitry Andric // possible but fall back to an InsnType-sized tmp for truly large fields.
979*5f7ddb14SDimitry Andric OS.indent(Indentation) << "using TmpType = "
980*5f7ddb14SDimitry Andric "std::conditional_t<std::is_integral<InsnType>::"
981*5f7ddb14SDimitry Andric "value, InsnType, uint64_t>;\n";
982*5f7ddb14SDimitry Andric OS.indent(Indentation) << "TmpType tmp;\n";
9830b57cec5SDimitry Andric OS.indent(Indentation) << "switch (Idx) {\n";
9840b57cec5SDimitry Andric OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
9850b57cec5SDimitry Andric unsigned Index = 0;
9860b57cec5SDimitry Andric for (const auto &Decoder : Decoders) {
9870b57cec5SDimitry Andric OS.indent(Indentation) << "case " << Index++ << ":\n";
9880b57cec5SDimitry Andric OS << Decoder;
9890b57cec5SDimitry Andric OS.indent(Indentation+2) << "return S;\n";
9900b57cec5SDimitry Andric }
9910b57cec5SDimitry Andric OS.indent(Indentation) << "}\n";
9920b57cec5SDimitry Andric Indentation -= 2;
9930b57cec5SDimitry Andric OS.indent(Indentation) << "}\n\n";
9940b57cec5SDimitry Andric }
9950b57cec5SDimitry Andric
9960b57cec5SDimitry Andric // Populates the field of the insn given the start position and the number of
9970b57cec5SDimitry Andric // consecutive bits to scan for.
9980b57cec5SDimitry Andric //
9990b57cec5SDimitry Andric // Returns false if and on the first uninitialized bit value encountered.
10000b57cec5SDimitry Andric // Returns true, otherwise.
fieldFromInsn(uint64_t & Field,insn_t & Insn,unsigned StartBit,unsigned NumBits) const10010b57cec5SDimitry Andric bool FilterChooser::fieldFromInsn(uint64_t &Field, insn_t &Insn,
10020b57cec5SDimitry Andric unsigned StartBit, unsigned NumBits) const {
10030b57cec5SDimitry Andric Field = 0;
10040b57cec5SDimitry Andric
10050b57cec5SDimitry Andric for (unsigned i = 0; i < NumBits; ++i) {
10060b57cec5SDimitry Andric if (Insn[StartBit + i] == BIT_UNSET)
10070b57cec5SDimitry Andric return false;
10080b57cec5SDimitry Andric
10090b57cec5SDimitry Andric if (Insn[StartBit + i] == BIT_TRUE)
10100b57cec5SDimitry Andric Field = Field | (1ULL << i);
10110b57cec5SDimitry Andric }
10120b57cec5SDimitry Andric
10130b57cec5SDimitry Andric return true;
10140b57cec5SDimitry Andric }
10150b57cec5SDimitry Andric
10160b57cec5SDimitry Andric /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
10170b57cec5SDimitry Andric /// filter array as a series of chars.
dumpFilterArray(raw_ostream & o,const std::vector<bit_value_t> & filter) const10180b57cec5SDimitry Andric void FilterChooser::dumpFilterArray(raw_ostream &o,
10190b57cec5SDimitry Andric const std::vector<bit_value_t> &filter) const {
10200b57cec5SDimitry Andric for (unsigned bitIndex = BitWidth; bitIndex > 0; bitIndex--) {
10210b57cec5SDimitry Andric switch (filter[bitIndex - 1]) {
10220b57cec5SDimitry Andric case BIT_UNFILTERED:
10230b57cec5SDimitry Andric o << ".";
10240b57cec5SDimitry Andric break;
10250b57cec5SDimitry Andric case BIT_UNSET:
10260b57cec5SDimitry Andric o << "_";
10270b57cec5SDimitry Andric break;
10280b57cec5SDimitry Andric case BIT_TRUE:
10290b57cec5SDimitry Andric o << "1";
10300b57cec5SDimitry Andric break;
10310b57cec5SDimitry Andric case BIT_FALSE:
10320b57cec5SDimitry Andric o << "0";
10330b57cec5SDimitry Andric break;
10340b57cec5SDimitry Andric }
10350b57cec5SDimitry Andric }
10360b57cec5SDimitry Andric }
10370b57cec5SDimitry Andric
10380b57cec5SDimitry Andric /// dumpStack - dumpStack traverses the filter chooser chain and calls
10390b57cec5SDimitry Andric /// dumpFilterArray on each filter chooser up to the top level one.
dumpStack(raw_ostream & o,const char * prefix) const10400b57cec5SDimitry Andric void FilterChooser::dumpStack(raw_ostream &o, const char *prefix) const {
10410b57cec5SDimitry Andric const FilterChooser *current = this;
10420b57cec5SDimitry Andric
10430b57cec5SDimitry Andric while (current) {
10440b57cec5SDimitry Andric o << prefix;
10450b57cec5SDimitry Andric dumpFilterArray(o, current->FilterBitValues);
10460b57cec5SDimitry Andric o << '\n';
10470b57cec5SDimitry Andric current = current->Parent;
10480b57cec5SDimitry Andric }
10490b57cec5SDimitry Andric }
10500b57cec5SDimitry Andric
10510b57cec5SDimitry Andric // Calculates the island(s) needed to decode the instruction.
10520b57cec5SDimitry Andric // This returns a list of undecoded bits of an instructions, for example,
10530b57cec5SDimitry Andric // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
10540b57cec5SDimitry 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) const10550b57cec5SDimitry Andric unsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits,
10560b57cec5SDimitry Andric std::vector<unsigned> &EndBits,
10570b57cec5SDimitry Andric std::vector<uint64_t> &FieldVals,
10580b57cec5SDimitry Andric const insn_t &Insn) const {
10590b57cec5SDimitry Andric unsigned Num, BitNo;
10600b57cec5SDimitry Andric Num = BitNo = 0;
10610b57cec5SDimitry Andric
10620b57cec5SDimitry Andric uint64_t FieldVal = 0;
10630b57cec5SDimitry Andric
10640b57cec5SDimitry Andric // 0: Init
10650b57cec5SDimitry Andric // 1: Water (the bit value does not affect decoding)
10660b57cec5SDimitry Andric // 2: Island (well-known bit value needed for decoding)
10670b57cec5SDimitry Andric int State = 0;
10680b57cec5SDimitry Andric
10690b57cec5SDimitry Andric for (unsigned i = 0; i < BitWidth; ++i) {
1070480093f4SDimitry Andric int64_t Val = Value(Insn[i]);
10710b57cec5SDimitry Andric bool Filtered = PositionFiltered(i);
10720b57cec5SDimitry Andric switch (State) {
10730b57cec5SDimitry Andric default: llvm_unreachable("Unreachable code!");
10740b57cec5SDimitry Andric case 0:
10750b57cec5SDimitry Andric case 1:
10760b57cec5SDimitry Andric if (Filtered || Val == -1)
10770b57cec5SDimitry Andric State = 1; // Still in Water
10780b57cec5SDimitry Andric else {
10790b57cec5SDimitry Andric State = 2; // Into the Island
10800b57cec5SDimitry Andric BitNo = 0;
10810b57cec5SDimitry Andric StartBits.push_back(i);
10820b57cec5SDimitry Andric FieldVal = Val;
10830b57cec5SDimitry Andric }
10840b57cec5SDimitry Andric break;
10850b57cec5SDimitry Andric case 2:
10860b57cec5SDimitry Andric if (Filtered || Val == -1) {
10870b57cec5SDimitry Andric State = 1; // Into the Water
10880b57cec5SDimitry Andric EndBits.push_back(i - 1);
10890b57cec5SDimitry Andric FieldVals.push_back(FieldVal);
10900b57cec5SDimitry Andric ++Num;
10910b57cec5SDimitry Andric } else {
10920b57cec5SDimitry Andric State = 2; // Still in Island
10930b57cec5SDimitry Andric ++BitNo;
10940b57cec5SDimitry Andric FieldVal = FieldVal | Val << BitNo;
10950b57cec5SDimitry Andric }
10960b57cec5SDimitry Andric break;
10970b57cec5SDimitry Andric }
10980b57cec5SDimitry Andric }
10990b57cec5SDimitry Andric // If we are still in Island after the loop, do some housekeeping.
11000b57cec5SDimitry Andric if (State == 2) {
11010b57cec5SDimitry Andric EndBits.push_back(BitWidth - 1);
11020b57cec5SDimitry Andric FieldVals.push_back(FieldVal);
11030b57cec5SDimitry Andric ++Num;
11040b57cec5SDimitry Andric }
11050b57cec5SDimitry Andric
11060b57cec5SDimitry Andric assert(StartBits.size() == Num && EndBits.size() == Num &&
11070b57cec5SDimitry Andric FieldVals.size() == Num);
11080b57cec5SDimitry Andric return Num;
11090b57cec5SDimitry Andric }
11100b57cec5SDimitry Andric
emitBinaryParser(raw_ostream & o,unsigned & Indentation,const OperandInfo & OpInfo,bool & OpHasCompleteDecoder) const11110b57cec5SDimitry Andric void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
11120b57cec5SDimitry Andric const OperandInfo &OpInfo,
11130b57cec5SDimitry Andric bool &OpHasCompleteDecoder) const {
11140b57cec5SDimitry Andric const std::string &Decoder = OpInfo.Decoder;
11150b57cec5SDimitry Andric
1116*5f7ddb14SDimitry Andric bool UseInsertBits = OpInfo.numFields() != 1 || OpInfo.InitValue != 0;
1117*5f7ddb14SDimitry Andric
1118*5f7ddb14SDimitry Andric if (UseInsertBits) {
11198bcb0991SDimitry Andric o.indent(Indentation) << "tmp = 0x";
11208bcb0991SDimitry Andric o.write_hex(OpInfo.InitValue);
11218bcb0991SDimitry Andric o << ";\n";
11228bcb0991SDimitry Andric }
11230b57cec5SDimitry Andric
11240b57cec5SDimitry Andric for (const EncodingField &EF : OpInfo) {
1125*5f7ddb14SDimitry Andric o.indent(Indentation);
1126*5f7ddb14SDimitry Andric if (UseInsertBits)
1127*5f7ddb14SDimitry Andric o << "insertBits(tmp, ";
1128*5f7ddb14SDimitry Andric else
1129*5f7ddb14SDimitry Andric o << "tmp = ";
1130*5f7ddb14SDimitry Andric o << "fieldFromInstruction(insn, " << EF.Base << ", " << EF.Width << ')';
1131*5f7ddb14SDimitry Andric if (UseInsertBits)
1132*5f7ddb14SDimitry Andric o << ", " << EF.Offset << ", " << EF.Width << ')';
1133*5f7ddb14SDimitry Andric else if (EF.Offset != 0)
11340b57cec5SDimitry Andric o << " << " << EF.Offset;
11350b57cec5SDimitry Andric o << ";\n";
11360b57cec5SDimitry Andric }
11370b57cec5SDimitry Andric
11380b57cec5SDimitry Andric if (Decoder != "") {
11390b57cec5SDimitry Andric OpHasCompleteDecoder = OpInfo.HasCompleteDecoder;
11400b57cec5SDimitry Andric o.indent(Indentation) << Emitter->GuardPrefix << Decoder
11410b57cec5SDimitry Andric << "(MI, tmp, Address, Decoder)"
11420b57cec5SDimitry Andric << Emitter->GuardPostfix
11430b57cec5SDimitry Andric << " { " << (OpHasCompleteDecoder ? "" : "DecodeComplete = false; ")
11440b57cec5SDimitry Andric << "return MCDisassembler::Fail; }\n";
11450b57cec5SDimitry Andric } else {
11460b57cec5SDimitry Andric OpHasCompleteDecoder = true;
11470b57cec5SDimitry Andric o.indent(Indentation) << "MI.addOperand(MCOperand::createImm(tmp));\n";
11480b57cec5SDimitry Andric }
11490b57cec5SDimitry Andric }
11500b57cec5SDimitry Andric
emitDecoder(raw_ostream & OS,unsigned Indentation,unsigned Opc,bool & HasCompleteDecoder) const11510b57cec5SDimitry Andric void FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation,
11520b57cec5SDimitry Andric unsigned Opc, bool &HasCompleteDecoder) const {
11530b57cec5SDimitry Andric HasCompleteDecoder = true;
11540b57cec5SDimitry Andric
11550b57cec5SDimitry Andric for (const auto &Op : Operands.find(Opc)->second) {
11560b57cec5SDimitry Andric // If a custom instruction decoder was specified, use that.
11570b57cec5SDimitry Andric if (Op.numFields() == 0 && !Op.Decoder.empty()) {
11580b57cec5SDimitry Andric HasCompleteDecoder = Op.HasCompleteDecoder;
11590b57cec5SDimitry Andric OS.indent(Indentation) << Emitter->GuardPrefix << Op.Decoder
11600b57cec5SDimitry Andric << "(MI, insn, Address, Decoder)"
11610b57cec5SDimitry Andric << Emitter->GuardPostfix
11620b57cec5SDimitry Andric << " { " << (HasCompleteDecoder ? "" : "DecodeComplete = false; ")
11630b57cec5SDimitry Andric << "return MCDisassembler::Fail; }\n";
11640b57cec5SDimitry Andric break;
11650b57cec5SDimitry Andric }
11660b57cec5SDimitry Andric
11670b57cec5SDimitry Andric bool OpHasCompleteDecoder;
11680b57cec5SDimitry Andric emitBinaryParser(OS, Indentation, Op, OpHasCompleteDecoder);
11690b57cec5SDimitry Andric if (!OpHasCompleteDecoder)
11700b57cec5SDimitry Andric HasCompleteDecoder = false;
11710b57cec5SDimitry Andric }
11720b57cec5SDimitry Andric }
11730b57cec5SDimitry Andric
getDecoderIndex(DecoderSet & Decoders,unsigned Opc,bool & HasCompleteDecoder) const11740b57cec5SDimitry Andric unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders,
11750b57cec5SDimitry Andric unsigned Opc,
11760b57cec5SDimitry Andric bool &HasCompleteDecoder) const {
11770b57cec5SDimitry Andric // Build up the predicate string.
11780b57cec5SDimitry Andric SmallString<256> Decoder;
11790b57cec5SDimitry Andric // FIXME: emitDecoder() function can take a buffer directly rather than
11800b57cec5SDimitry Andric // a stream.
11810b57cec5SDimitry Andric raw_svector_ostream S(Decoder);
11820b57cec5SDimitry Andric unsigned I = 4;
11830b57cec5SDimitry Andric emitDecoder(S, I, Opc, HasCompleteDecoder);
11840b57cec5SDimitry Andric
11850b57cec5SDimitry Andric // Using the full decoder string as the key value here is a bit
11860b57cec5SDimitry Andric // heavyweight, but is effective. If the string comparisons become a
11870b57cec5SDimitry Andric // performance concern, we can implement a mangling of the predicate
11880b57cec5SDimitry Andric // data easily enough with a map back to the actual string. That's
11890b57cec5SDimitry Andric // overkill for now, though.
11900b57cec5SDimitry Andric
11910b57cec5SDimitry Andric // Make sure the predicate is in the table.
11920b57cec5SDimitry Andric Decoders.insert(CachedHashString(Decoder));
11930b57cec5SDimitry Andric // Now figure out the index for when we write out the table.
11940b57cec5SDimitry Andric DecoderSet::const_iterator P = find(Decoders, Decoder.str());
11950b57cec5SDimitry Andric return (unsigned)(P - Decoders.begin());
11960b57cec5SDimitry Andric }
11970b57cec5SDimitry Andric
emitPredicateMatch(raw_ostream & o,unsigned & Indentation,unsigned Opc) const11980b57cec5SDimitry Andric bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
11990b57cec5SDimitry Andric unsigned Opc) const {
12000b57cec5SDimitry Andric ListInit *Predicates =
12010b57cec5SDimitry Andric AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
12020b57cec5SDimitry Andric bool IsFirstEmission = true;
12030b57cec5SDimitry Andric for (unsigned i = 0; i < Predicates->size(); ++i) {
12040b57cec5SDimitry Andric Record *Pred = Predicates->getElementAsRecord(i);
12050b57cec5SDimitry Andric if (!Pred->getValue("AssemblerMatcherPredicate"))
12060b57cec5SDimitry Andric continue;
12070b57cec5SDimitry Andric
1208af732203SDimitry Andric if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
12090b57cec5SDimitry Andric continue;
12100b57cec5SDimitry Andric
12115ffd83dbSDimitry Andric const DagInit *D = Pred->getValueAsDag("AssemblerCondDag");
12125ffd83dbSDimitry Andric std::string CombineType = D->getOperator()->getAsString();
12135ffd83dbSDimitry Andric if (CombineType != "any_of" && CombineType != "all_of")
12145ffd83dbSDimitry Andric PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
12155ffd83dbSDimitry Andric if (D->getNumArgs() == 0)
12165ffd83dbSDimitry Andric PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
12175ffd83dbSDimitry Andric bool IsOr = CombineType == "any_of";
12185ffd83dbSDimitry Andric
12190b57cec5SDimitry Andric if (!IsFirstEmission)
12200b57cec5SDimitry Andric o << " && ";
12210b57cec5SDimitry Andric
12225ffd83dbSDimitry Andric if (IsOr)
12235ffd83dbSDimitry Andric o << "(";
12245ffd83dbSDimitry Andric
1225*5f7ddb14SDimitry Andric ListSeparator LS(IsOr ? " || " : " && ");
12265ffd83dbSDimitry Andric for (auto *Arg : D->getArgs()) {
1227*5f7ddb14SDimitry Andric o << LS;
12285ffd83dbSDimitry Andric if (auto *NotArg = dyn_cast<DagInit>(Arg)) {
12295ffd83dbSDimitry Andric if (NotArg->getOperator()->getAsString() != "not" ||
12305ffd83dbSDimitry Andric NotArg->getNumArgs() != 1)
12315ffd83dbSDimitry Andric PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
12325ffd83dbSDimitry Andric Arg = NotArg->getArg(0);
12335ffd83dbSDimitry Andric o << "!";
12345ffd83dbSDimitry Andric }
12355ffd83dbSDimitry Andric if (!isa<DefInit>(Arg) ||
12365ffd83dbSDimitry Andric !cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature"))
12375ffd83dbSDimitry Andric PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
12385ffd83dbSDimitry Andric o << "Bits[" << Emitter->PredicateNamespace << "::" << Arg->getAsString()
12395ffd83dbSDimitry Andric << "]";
12405ffd83dbSDimitry Andric }
12415ffd83dbSDimitry Andric
12425ffd83dbSDimitry Andric if (IsOr)
12435ffd83dbSDimitry Andric o << ")";
12445ffd83dbSDimitry Andric
12450b57cec5SDimitry Andric IsFirstEmission = false;
12460b57cec5SDimitry Andric }
12470b57cec5SDimitry Andric return !Predicates->empty();
12480b57cec5SDimitry Andric }
12490b57cec5SDimitry Andric
doesOpcodeNeedPredicate(unsigned Opc) const12500b57cec5SDimitry Andric bool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const {
12510b57cec5SDimitry Andric ListInit *Predicates =
12520b57cec5SDimitry Andric AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
12530b57cec5SDimitry Andric for (unsigned i = 0; i < Predicates->size(); ++i) {
12540b57cec5SDimitry Andric Record *Pred = Predicates->getElementAsRecord(i);
12550b57cec5SDimitry Andric if (!Pred->getValue("AssemblerMatcherPredicate"))
12560b57cec5SDimitry Andric continue;
12570b57cec5SDimitry Andric
1258*5f7ddb14SDimitry Andric if (isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
12590b57cec5SDimitry Andric return true;
12600b57cec5SDimitry Andric }
12610b57cec5SDimitry Andric return false;
12620b57cec5SDimitry Andric }
12630b57cec5SDimitry Andric
getPredicateIndex(DecoderTableInfo & TableInfo,StringRef Predicate) const12640b57cec5SDimitry Andric unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo,
12650b57cec5SDimitry Andric StringRef Predicate) const {
12660b57cec5SDimitry Andric // Using the full predicate string as the key value here is a bit
12670b57cec5SDimitry Andric // heavyweight, but is effective. If the string comparisons become a
12680b57cec5SDimitry Andric // performance concern, we can implement a mangling of the predicate
12690b57cec5SDimitry Andric // data easily enough with a map back to the actual string. That's
12700b57cec5SDimitry Andric // overkill for now, though.
12710b57cec5SDimitry Andric
12720b57cec5SDimitry Andric // Make sure the predicate is in the table.
12730b57cec5SDimitry Andric TableInfo.Predicates.insert(CachedHashString(Predicate));
12740b57cec5SDimitry Andric // Now figure out the index for when we write out the table.
12750b57cec5SDimitry Andric PredicateSet::const_iterator P = find(TableInfo.Predicates, Predicate);
12760b57cec5SDimitry Andric return (unsigned)(P - TableInfo.Predicates.begin());
12770b57cec5SDimitry Andric }
12780b57cec5SDimitry Andric
emitPredicateTableEntry(DecoderTableInfo & TableInfo,unsigned Opc) const12790b57cec5SDimitry Andric void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo,
12800b57cec5SDimitry Andric unsigned Opc) const {
12810b57cec5SDimitry Andric if (!doesOpcodeNeedPredicate(Opc))
12820b57cec5SDimitry Andric return;
12830b57cec5SDimitry Andric
12840b57cec5SDimitry Andric // Build up the predicate string.
12850b57cec5SDimitry Andric SmallString<256> Predicate;
12860b57cec5SDimitry Andric // FIXME: emitPredicateMatch() functions can take a buffer directly rather
12870b57cec5SDimitry Andric // than a stream.
12880b57cec5SDimitry Andric raw_svector_ostream PS(Predicate);
12890b57cec5SDimitry Andric unsigned I = 0;
12900b57cec5SDimitry Andric emitPredicateMatch(PS, I, Opc);
12910b57cec5SDimitry Andric
12920b57cec5SDimitry Andric // Figure out the index into the predicate table for the predicate just
12930b57cec5SDimitry Andric // computed.
12940b57cec5SDimitry Andric unsigned PIdx = getPredicateIndex(TableInfo, PS.str());
12950b57cec5SDimitry Andric SmallString<16> PBytes;
12960b57cec5SDimitry Andric raw_svector_ostream S(PBytes);
12970b57cec5SDimitry Andric encodeULEB128(PIdx, S);
12980b57cec5SDimitry Andric
12990b57cec5SDimitry Andric TableInfo.Table.push_back(MCD::OPC_CheckPredicate);
13000b57cec5SDimitry Andric // Predicate index
13010b57cec5SDimitry Andric for (unsigned i = 0, e = PBytes.size(); i != e; ++i)
13020b57cec5SDimitry Andric TableInfo.Table.push_back(PBytes[i]);
13030b57cec5SDimitry Andric // Push location for NumToSkip backpatching.
13040b57cec5SDimitry Andric TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
13050b57cec5SDimitry Andric TableInfo.Table.push_back(0);
13060b57cec5SDimitry Andric TableInfo.Table.push_back(0);
13070b57cec5SDimitry Andric TableInfo.Table.push_back(0);
13080b57cec5SDimitry Andric }
13090b57cec5SDimitry Andric
emitSoftFailTableEntry(DecoderTableInfo & TableInfo,unsigned Opc) const13100b57cec5SDimitry Andric void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
13110b57cec5SDimitry Andric unsigned Opc) const {
13120b57cec5SDimitry Andric BitsInit *SFBits =
13130b57cec5SDimitry Andric AllInstructions[Opc].EncodingDef->getValueAsBitsInit("SoftFail");
13140b57cec5SDimitry Andric if (!SFBits) return;
13150b57cec5SDimitry Andric BitsInit *InstBits =
13160b57cec5SDimitry Andric AllInstructions[Opc].EncodingDef->getValueAsBitsInit("Inst");
13170b57cec5SDimitry Andric
13180b57cec5SDimitry Andric APInt PositiveMask(BitWidth, 0ULL);
13190b57cec5SDimitry Andric APInt NegativeMask(BitWidth, 0ULL);
13200b57cec5SDimitry Andric for (unsigned i = 0; i < BitWidth; ++i) {
13210b57cec5SDimitry Andric bit_value_t B = bitFromBits(*SFBits, i);
13220b57cec5SDimitry Andric bit_value_t IB = bitFromBits(*InstBits, i);
13230b57cec5SDimitry Andric
13240b57cec5SDimitry Andric if (B != BIT_TRUE) continue;
13250b57cec5SDimitry Andric
13260b57cec5SDimitry Andric switch (IB) {
13270b57cec5SDimitry Andric case BIT_FALSE:
13280b57cec5SDimitry Andric // The bit is meant to be false, so emit a check to see if it is true.
13290b57cec5SDimitry Andric PositiveMask.setBit(i);
13300b57cec5SDimitry Andric break;
13310b57cec5SDimitry Andric case BIT_TRUE:
13320b57cec5SDimitry Andric // The bit is meant to be true, so emit a check to see if it is false.
13330b57cec5SDimitry Andric NegativeMask.setBit(i);
13340b57cec5SDimitry Andric break;
13350b57cec5SDimitry Andric default:
13360b57cec5SDimitry Andric // The bit is not set; this must be an error!
13370b57cec5SDimitry Andric errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in "
13380b57cec5SDimitry Andric << AllInstructions[Opc] << " is set but Inst{" << i
13390b57cec5SDimitry Andric << "} is unset!\n"
13400b57cec5SDimitry Andric << " - You can only mark a bit as SoftFail if it is fully defined"
13410b57cec5SDimitry Andric << " (1/0 - not '?') in Inst\n";
13420b57cec5SDimitry Andric return;
13430b57cec5SDimitry Andric }
13440b57cec5SDimitry Andric }
13450b57cec5SDimitry Andric
13460b57cec5SDimitry Andric bool NeedPositiveMask = PositiveMask.getBoolValue();
13470b57cec5SDimitry Andric bool NeedNegativeMask = NegativeMask.getBoolValue();
13480b57cec5SDimitry Andric
13490b57cec5SDimitry Andric if (!NeedPositiveMask && !NeedNegativeMask)
13500b57cec5SDimitry Andric return;
13510b57cec5SDimitry Andric
13520b57cec5SDimitry Andric TableInfo.Table.push_back(MCD::OPC_SoftFail);
13530b57cec5SDimitry Andric
13540b57cec5SDimitry Andric SmallString<16> MaskBytes;
13550b57cec5SDimitry Andric raw_svector_ostream S(MaskBytes);
13560b57cec5SDimitry Andric if (NeedPositiveMask) {
13570b57cec5SDimitry Andric encodeULEB128(PositiveMask.getZExtValue(), S);
13580b57cec5SDimitry Andric for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i)
13590b57cec5SDimitry Andric TableInfo.Table.push_back(MaskBytes[i]);
13600b57cec5SDimitry Andric } else
13610b57cec5SDimitry Andric TableInfo.Table.push_back(0);
13620b57cec5SDimitry Andric if (NeedNegativeMask) {
13630b57cec5SDimitry Andric MaskBytes.clear();
13640b57cec5SDimitry Andric encodeULEB128(NegativeMask.getZExtValue(), S);
13650b57cec5SDimitry Andric for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i)
13660b57cec5SDimitry Andric TableInfo.Table.push_back(MaskBytes[i]);
13670b57cec5SDimitry Andric } else
13680b57cec5SDimitry Andric TableInfo.Table.push_back(0);
13690b57cec5SDimitry Andric }
13700b57cec5SDimitry Andric
13710b57cec5SDimitry Andric // Emits table entries to decode the singleton.
emitSingletonTableEntry(DecoderTableInfo & TableInfo,EncodingIDAndOpcode Opc) const13720b57cec5SDimitry Andric void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
13730b57cec5SDimitry Andric EncodingIDAndOpcode Opc) const {
13740b57cec5SDimitry Andric std::vector<unsigned> StartBits;
13750b57cec5SDimitry Andric std::vector<unsigned> EndBits;
13760b57cec5SDimitry Andric std::vector<uint64_t> FieldVals;
13770b57cec5SDimitry Andric insn_t Insn;
13780b57cec5SDimitry Andric insnWithID(Insn, Opc.EncodingID);
13790b57cec5SDimitry Andric
13800b57cec5SDimitry Andric // Look for islands of undecoded bits of the singleton.
13810b57cec5SDimitry Andric getIslands(StartBits, EndBits, FieldVals, Insn);
13820b57cec5SDimitry Andric
13830b57cec5SDimitry Andric unsigned Size = StartBits.size();
13840b57cec5SDimitry Andric
13850b57cec5SDimitry Andric // Emit the predicate table entry if one is needed.
13860b57cec5SDimitry Andric emitPredicateTableEntry(TableInfo, Opc.EncodingID);
13870b57cec5SDimitry Andric
13880b57cec5SDimitry Andric // Check any additional encoding fields needed.
13890b57cec5SDimitry Andric for (unsigned I = Size; I != 0; --I) {
13900b57cec5SDimitry Andric unsigned NumBits = EndBits[I-1] - StartBits[I-1] + 1;
13910b57cec5SDimitry Andric TableInfo.Table.push_back(MCD::OPC_CheckField);
13920b57cec5SDimitry Andric TableInfo.Table.push_back(StartBits[I-1]);
13930b57cec5SDimitry Andric TableInfo.Table.push_back(NumBits);
13940b57cec5SDimitry Andric uint8_t Buffer[16], *p;
13950b57cec5SDimitry Andric encodeULEB128(FieldVals[I-1], Buffer);
13960b57cec5SDimitry Andric for (p = Buffer; *p >= 128 ; ++p)
13970b57cec5SDimitry Andric TableInfo.Table.push_back(*p);
13980b57cec5SDimitry Andric TableInfo.Table.push_back(*p);
13990b57cec5SDimitry Andric // Push location for NumToSkip backpatching.
14000b57cec5SDimitry Andric TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
14010b57cec5SDimitry Andric // The fixup is always 24-bits, so go ahead and allocate the space
14020b57cec5SDimitry Andric // in the table so all our relative position calculations work OK even
14030b57cec5SDimitry Andric // before we fully resolve the real value here.
14040b57cec5SDimitry Andric TableInfo.Table.push_back(0);
14050b57cec5SDimitry Andric TableInfo.Table.push_back(0);
14060b57cec5SDimitry Andric TableInfo.Table.push_back(0);
14070b57cec5SDimitry Andric }
14080b57cec5SDimitry Andric
14090b57cec5SDimitry Andric // Check for soft failure of the match.
14100b57cec5SDimitry Andric emitSoftFailTableEntry(TableInfo, Opc.EncodingID);
14110b57cec5SDimitry Andric
14120b57cec5SDimitry Andric bool HasCompleteDecoder;
14130b57cec5SDimitry Andric unsigned DIdx =
14140b57cec5SDimitry Andric getDecoderIndex(TableInfo.Decoders, Opc.EncodingID, HasCompleteDecoder);
14150b57cec5SDimitry Andric
14160b57cec5SDimitry Andric // Produce OPC_Decode or OPC_TryDecode opcode based on the information
14170b57cec5SDimitry Andric // whether the instruction decoder is complete or not. If it is complete
14180b57cec5SDimitry Andric // then it handles all possible values of remaining variable/unfiltered bits
14190b57cec5SDimitry Andric // and for any value can determine if the bitpattern is a valid instruction
14200b57cec5SDimitry Andric // or not. This means OPC_Decode will be the final step in the decoding
14210b57cec5SDimitry Andric // process. If it is not complete, then the Fail return code from the
14220b57cec5SDimitry Andric // decoder method indicates that additional processing should be done to see
14230b57cec5SDimitry Andric // if there is any other instruction that also matches the bitpattern and
14240b57cec5SDimitry Andric // can decode it.
14250b57cec5SDimitry Andric TableInfo.Table.push_back(HasCompleteDecoder ? MCD::OPC_Decode :
14260b57cec5SDimitry Andric MCD::OPC_TryDecode);
14270b57cec5SDimitry Andric NumEncodingsSupported++;
14280b57cec5SDimitry Andric uint8_t Buffer[16], *p;
14290b57cec5SDimitry Andric encodeULEB128(Opc.Opcode, Buffer);
14300b57cec5SDimitry Andric for (p = Buffer; *p >= 128 ; ++p)
14310b57cec5SDimitry Andric TableInfo.Table.push_back(*p);
14320b57cec5SDimitry Andric TableInfo.Table.push_back(*p);
14330b57cec5SDimitry Andric
14340b57cec5SDimitry Andric SmallString<16> Bytes;
14350b57cec5SDimitry Andric raw_svector_ostream S(Bytes);
14360b57cec5SDimitry Andric encodeULEB128(DIdx, S);
14370b57cec5SDimitry Andric
14380b57cec5SDimitry Andric // Decoder index
14390b57cec5SDimitry Andric for (unsigned i = 0, e = Bytes.size(); i != e; ++i)
14400b57cec5SDimitry Andric TableInfo.Table.push_back(Bytes[i]);
14410b57cec5SDimitry Andric
14420b57cec5SDimitry Andric if (!HasCompleteDecoder) {
14430b57cec5SDimitry Andric // Push location for NumToSkip backpatching.
14440b57cec5SDimitry Andric TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
14450b57cec5SDimitry Andric // Allocate the space for the fixup.
14460b57cec5SDimitry Andric TableInfo.Table.push_back(0);
14470b57cec5SDimitry Andric TableInfo.Table.push_back(0);
14480b57cec5SDimitry Andric TableInfo.Table.push_back(0);
14490b57cec5SDimitry Andric }
14500b57cec5SDimitry Andric }
14510b57cec5SDimitry Andric
14520b57cec5SDimitry Andric // Emits table entries to decode the singleton, and then to decode the rest.
emitSingletonTableEntry(DecoderTableInfo & TableInfo,const Filter & Best) const14530b57cec5SDimitry Andric void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
14540b57cec5SDimitry Andric const Filter &Best) const {
14550b57cec5SDimitry Andric EncodingIDAndOpcode Opc = Best.getSingletonOpc();
14560b57cec5SDimitry Andric
14570b57cec5SDimitry Andric // complex singletons need predicate checks from the first singleton
14580b57cec5SDimitry Andric // to refer forward to the variable filterchooser that follows.
14590b57cec5SDimitry Andric TableInfo.FixupStack.emplace_back();
14600b57cec5SDimitry Andric
14610b57cec5SDimitry Andric emitSingletonTableEntry(TableInfo, Opc);
14620b57cec5SDimitry Andric
14630b57cec5SDimitry Andric resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
14640b57cec5SDimitry Andric TableInfo.Table.size());
14650b57cec5SDimitry Andric TableInfo.FixupStack.pop_back();
14660b57cec5SDimitry Andric
14670b57cec5SDimitry Andric Best.getVariableFC().emitTableEntries(TableInfo);
14680b57cec5SDimitry Andric }
14690b57cec5SDimitry Andric
14700b57cec5SDimitry Andric // Assign a single filter and run with it. Top level API client can initialize
14710b57cec5SDimitry Andric // with a single filter to start the filtering process.
runSingleFilter(unsigned startBit,unsigned numBit,bool mixed)14720b57cec5SDimitry Andric void FilterChooser::runSingleFilter(unsigned startBit, unsigned numBit,
14730b57cec5SDimitry Andric bool mixed) {
14740b57cec5SDimitry Andric Filters.clear();
14750b57cec5SDimitry Andric Filters.emplace_back(*this, startBit, numBit, true);
14760b57cec5SDimitry Andric BestIndex = 0; // Sole Filter instance to choose from.
14770b57cec5SDimitry Andric bestFilter().recurse();
14780b57cec5SDimitry Andric }
14790b57cec5SDimitry Andric
14800b57cec5SDimitry Andric // reportRegion is a helper function for filterProcessor to mark a region as
14810b57cec5SDimitry Andric // eligible for use as a filter region.
reportRegion(bitAttr_t RA,unsigned StartBit,unsigned BitIndex,bool AllowMixed)14820b57cec5SDimitry Andric void FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit,
14830b57cec5SDimitry Andric unsigned BitIndex, bool AllowMixed) {
14840b57cec5SDimitry Andric if (RA == ATTR_MIXED && AllowMixed)
14850b57cec5SDimitry Andric Filters.emplace_back(*this, StartBit, BitIndex - StartBit, true);
14860b57cec5SDimitry Andric else if (RA == ATTR_ALL_SET && !AllowMixed)
14870b57cec5SDimitry Andric Filters.emplace_back(*this, StartBit, BitIndex - StartBit, false);
14880b57cec5SDimitry Andric }
14890b57cec5SDimitry Andric
14900b57cec5SDimitry Andric // FilterProcessor scans the well-known encoding bits of the instructions and
14910b57cec5SDimitry Andric // builds up a list of candidate filters. It chooses the best filter and
14920b57cec5SDimitry Andric // recursively descends down the decoding tree.
filterProcessor(bool AllowMixed,bool Greedy)14930b57cec5SDimitry Andric bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
14940b57cec5SDimitry Andric Filters.clear();
14950b57cec5SDimitry Andric BestIndex = -1;
14960b57cec5SDimitry Andric unsigned numInstructions = Opcodes.size();
14970b57cec5SDimitry Andric
14980b57cec5SDimitry Andric assert(numInstructions && "Filter created with no instructions");
14990b57cec5SDimitry Andric
15000b57cec5SDimitry Andric // No further filtering is necessary.
15010b57cec5SDimitry Andric if (numInstructions == 1)
15020b57cec5SDimitry Andric return true;
15030b57cec5SDimitry Andric
15040b57cec5SDimitry Andric // Heuristics. See also doFilter()'s "Heuristics" comment when num of
15050b57cec5SDimitry Andric // instructions is 3.
15060b57cec5SDimitry Andric if (AllowMixed && !Greedy) {
15070b57cec5SDimitry Andric assert(numInstructions == 3);
15080b57cec5SDimitry Andric
1509*5f7ddb14SDimitry Andric for (auto Opcode : Opcodes) {
15100b57cec5SDimitry Andric std::vector<unsigned> StartBits;
15110b57cec5SDimitry Andric std::vector<unsigned> EndBits;
15120b57cec5SDimitry Andric std::vector<uint64_t> FieldVals;
15130b57cec5SDimitry Andric insn_t Insn;
15140b57cec5SDimitry Andric
1515*5f7ddb14SDimitry Andric insnWithID(Insn, Opcode.EncodingID);
15160b57cec5SDimitry Andric
15170b57cec5SDimitry Andric // Look for islands of undecoded bits of any instruction.
15180b57cec5SDimitry Andric if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) {
15190b57cec5SDimitry Andric // Found an instruction with island(s). Now just assign a filter.
15200b57cec5SDimitry Andric runSingleFilter(StartBits[0], EndBits[0] - StartBits[0] + 1, true);
15210b57cec5SDimitry Andric return true;
15220b57cec5SDimitry Andric }
15230b57cec5SDimitry Andric }
15240b57cec5SDimitry Andric }
15250b57cec5SDimitry Andric
15260b57cec5SDimitry Andric unsigned BitIndex;
15270b57cec5SDimitry Andric
15280b57cec5SDimitry Andric // We maintain BIT_WIDTH copies of the bitAttrs automaton.
15290b57cec5SDimitry Andric // The automaton consumes the corresponding bit from each
15300b57cec5SDimitry Andric // instruction.
15310b57cec5SDimitry Andric //
15320b57cec5SDimitry Andric // Input symbols: 0, 1, and _ (unset).
15330b57cec5SDimitry Andric // States: NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED.
15340b57cec5SDimitry Andric // Initial state: NONE.
15350b57cec5SDimitry Andric //
15360b57cec5SDimitry Andric // (NONE) ------- [01] -> (ALL_SET)
15370b57cec5SDimitry Andric // (NONE) ------- _ ----> (ALL_UNSET)
15380b57cec5SDimitry Andric // (ALL_SET) ---- [01] -> (ALL_SET)
15390b57cec5SDimitry Andric // (ALL_SET) ---- _ ----> (MIXED)
15400b57cec5SDimitry Andric // (ALL_UNSET) -- [01] -> (MIXED)
15410b57cec5SDimitry Andric // (ALL_UNSET) -- _ ----> (ALL_UNSET)
15420b57cec5SDimitry Andric // (MIXED) ------ . ----> (MIXED)
15430b57cec5SDimitry Andric // (FILTERED)---- . ----> (FILTERED)
15440b57cec5SDimitry Andric
15450b57cec5SDimitry Andric std::vector<bitAttr_t> bitAttrs;
15460b57cec5SDimitry Andric
15470b57cec5SDimitry Andric // FILTERED bit positions provide no entropy and are not worthy of pursuing.
15480b57cec5SDimitry Andric // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position.
15490b57cec5SDimitry Andric for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex)
15500b57cec5SDimitry Andric if (FilterBitValues[BitIndex] == BIT_TRUE ||
15510b57cec5SDimitry Andric FilterBitValues[BitIndex] == BIT_FALSE)
15520b57cec5SDimitry Andric bitAttrs.push_back(ATTR_FILTERED);
15530b57cec5SDimitry Andric else
15540b57cec5SDimitry Andric bitAttrs.push_back(ATTR_NONE);
15550b57cec5SDimitry Andric
15560b57cec5SDimitry Andric for (unsigned InsnIndex = 0; InsnIndex < numInstructions; ++InsnIndex) {
15570b57cec5SDimitry Andric insn_t insn;
15580b57cec5SDimitry Andric
15590b57cec5SDimitry Andric insnWithID(insn, Opcodes[InsnIndex].EncodingID);
15600b57cec5SDimitry Andric
15610b57cec5SDimitry Andric for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
15620b57cec5SDimitry Andric switch (bitAttrs[BitIndex]) {
15630b57cec5SDimitry Andric case ATTR_NONE:
15640b57cec5SDimitry Andric if (insn[BitIndex] == BIT_UNSET)
15650b57cec5SDimitry Andric bitAttrs[BitIndex] = ATTR_ALL_UNSET;
15660b57cec5SDimitry Andric else
15670b57cec5SDimitry Andric bitAttrs[BitIndex] = ATTR_ALL_SET;
15680b57cec5SDimitry Andric break;
15690b57cec5SDimitry Andric case ATTR_ALL_SET:
15700b57cec5SDimitry Andric if (insn[BitIndex] == BIT_UNSET)
15710b57cec5SDimitry Andric bitAttrs[BitIndex] = ATTR_MIXED;
15720b57cec5SDimitry Andric break;
15730b57cec5SDimitry Andric case ATTR_ALL_UNSET:
15740b57cec5SDimitry Andric if (insn[BitIndex] != BIT_UNSET)
15750b57cec5SDimitry Andric bitAttrs[BitIndex] = ATTR_MIXED;
15760b57cec5SDimitry Andric break;
15770b57cec5SDimitry Andric case ATTR_MIXED:
15780b57cec5SDimitry Andric case ATTR_FILTERED:
15790b57cec5SDimitry Andric break;
15800b57cec5SDimitry Andric }
15810b57cec5SDimitry Andric }
15820b57cec5SDimitry Andric }
15830b57cec5SDimitry Andric
15840b57cec5SDimitry Andric // The regionAttr automaton consumes the bitAttrs automatons' state,
15850b57cec5SDimitry Andric // lowest-to-highest.
15860b57cec5SDimitry Andric //
15870b57cec5SDimitry Andric // Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed)
15880b57cec5SDimitry Andric // States: NONE, ALL_SET, MIXED
15890b57cec5SDimitry Andric // Initial state: NONE
15900b57cec5SDimitry Andric //
15910b57cec5SDimitry Andric // (NONE) ----- F --> (NONE)
15920b57cec5SDimitry Andric // (NONE) ----- S --> (ALL_SET) ; and set region start
15930b57cec5SDimitry Andric // (NONE) ----- U --> (NONE)
15940b57cec5SDimitry Andric // (NONE) ----- M --> (MIXED) ; and set region start
15950b57cec5SDimitry Andric // (ALL_SET) -- F --> (NONE) ; and report an ALL_SET region
15960b57cec5SDimitry Andric // (ALL_SET) -- S --> (ALL_SET)
15970b57cec5SDimitry Andric // (ALL_SET) -- U --> (NONE) ; and report an ALL_SET region
15980b57cec5SDimitry Andric // (ALL_SET) -- M --> (MIXED) ; and report an ALL_SET region
15990b57cec5SDimitry Andric // (MIXED) ---- F --> (NONE) ; and report a MIXED region
16000b57cec5SDimitry Andric // (MIXED) ---- S --> (ALL_SET) ; and report a MIXED region
16010b57cec5SDimitry Andric // (MIXED) ---- U --> (NONE) ; and report a MIXED region
16020b57cec5SDimitry Andric // (MIXED) ---- M --> (MIXED)
16030b57cec5SDimitry Andric
16040b57cec5SDimitry Andric bitAttr_t RA = ATTR_NONE;
16050b57cec5SDimitry Andric unsigned StartBit = 0;
16060b57cec5SDimitry Andric
16070b57cec5SDimitry Andric for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
16080b57cec5SDimitry Andric bitAttr_t bitAttr = bitAttrs[BitIndex];
16090b57cec5SDimitry Andric
16100b57cec5SDimitry Andric assert(bitAttr != ATTR_NONE && "Bit without attributes");
16110b57cec5SDimitry Andric
16120b57cec5SDimitry Andric switch (RA) {
16130b57cec5SDimitry Andric case ATTR_NONE:
16140b57cec5SDimitry Andric switch (bitAttr) {
16150b57cec5SDimitry Andric case ATTR_FILTERED:
16160b57cec5SDimitry Andric break;
16170b57cec5SDimitry Andric case ATTR_ALL_SET:
16180b57cec5SDimitry Andric StartBit = BitIndex;
16190b57cec5SDimitry Andric RA = ATTR_ALL_SET;
16200b57cec5SDimitry Andric break;
16210b57cec5SDimitry Andric case ATTR_ALL_UNSET:
16220b57cec5SDimitry Andric break;
16230b57cec5SDimitry Andric case ATTR_MIXED:
16240b57cec5SDimitry Andric StartBit = BitIndex;
16250b57cec5SDimitry Andric RA = ATTR_MIXED;
16260b57cec5SDimitry Andric break;
16270b57cec5SDimitry Andric default:
16280b57cec5SDimitry Andric llvm_unreachable("Unexpected bitAttr!");
16290b57cec5SDimitry Andric }
16300b57cec5SDimitry Andric break;
16310b57cec5SDimitry Andric case ATTR_ALL_SET:
16320b57cec5SDimitry Andric switch (bitAttr) {
16330b57cec5SDimitry Andric case ATTR_FILTERED:
16340b57cec5SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
16350b57cec5SDimitry Andric RA = ATTR_NONE;
16360b57cec5SDimitry Andric break;
16370b57cec5SDimitry Andric case ATTR_ALL_SET:
16380b57cec5SDimitry Andric break;
16390b57cec5SDimitry Andric case ATTR_ALL_UNSET:
16400b57cec5SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
16410b57cec5SDimitry Andric RA = ATTR_NONE;
16420b57cec5SDimitry Andric break;
16430b57cec5SDimitry Andric case ATTR_MIXED:
16440b57cec5SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
16450b57cec5SDimitry Andric StartBit = BitIndex;
16460b57cec5SDimitry Andric RA = ATTR_MIXED;
16470b57cec5SDimitry Andric break;
16480b57cec5SDimitry Andric default:
16490b57cec5SDimitry Andric llvm_unreachable("Unexpected bitAttr!");
16500b57cec5SDimitry Andric }
16510b57cec5SDimitry Andric break;
16520b57cec5SDimitry Andric case ATTR_MIXED:
16530b57cec5SDimitry Andric switch (bitAttr) {
16540b57cec5SDimitry Andric case ATTR_FILTERED:
16550b57cec5SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
16560b57cec5SDimitry Andric StartBit = BitIndex;
16570b57cec5SDimitry Andric RA = ATTR_NONE;
16580b57cec5SDimitry Andric break;
16590b57cec5SDimitry Andric case ATTR_ALL_SET:
16600b57cec5SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
16610b57cec5SDimitry Andric StartBit = BitIndex;
16620b57cec5SDimitry Andric RA = ATTR_ALL_SET;
16630b57cec5SDimitry Andric break;
16640b57cec5SDimitry Andric case ATTR_ALL_UNSET:
16650b57cec5SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
16660b57cec5SDimitry Andric RA = ATTR_NONE;
16670b57cec5SDimitry Andric break;
16680b57cec5SDimitry Andric case ATTR_MIXED:
16690b57cec5SDimitry Andric break;
16700b57cec5SDimitry Andric default:
16710b57cec5SDimitry Andric llvm_unreachable("Unexpected bitAttr!");
16720b57cec5SDimitry Andric }
16730b57cec5SDimitry Andric break;
16740b57cec5SDimitry Andric case ATTR_ALL_UNSET:
16750b57cec5SDimitry Andric llvm_unreachable("regionAttr state machine has no ATTR_UNSET state");
16760b57cec5SDimitry Andric case ATTR_FILTERED:
16770b57cec5SDimitry Andric llvm_unreachable("regionAttr state machine has no ATTR_FILTERED state");
16780b57cec5SDimitry Andric }
16790b57cec5SDimitry Andric }
16800b57cec5SDimitry Andric
16810b57cec5SDimitry Andric // At the end, if we're still in ALL_SET or MIXED states, report a region
16820b57cec5SDimitry Andric switch (RA) {
16830b57cec5SDimitry Andric case ATTR_NONE:
16840b57cec5SDimitry Andric break;
16850b57cec5SDimitry Andric case ATTR_FILTERED:
16860b57cec5SDimitry Andric break;
16870b57cec5SDimitry Andric case ATTR_ALL_SET:
16880b57cec5SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
16890b57cec5SDimitry Andric break;
16900b57cec5SDimitry Andric case ATTR_ALL_UNSET:
16910b57cec5SDimitry Andric break;
16920b57cec5SDimitry Andric case ATTR_MIXED:
16930b57cec5SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
16940b57cec5SDimitry Andric break;
16950b57cec5SDimitry Andric }
16960b57cec5SDimitry Andric
16970b57cec5SDimitry Andric // We have finished with the filter processings. Now it's time to choose
16980b57cec5SDimitry Andric // the best performing filter.
16990b57cec5SDimitry Andric BestIndex = 0;
17000b57cec5SDimitry Andric bool AllUseless = true;
17010b57cec5SDimitry Andric unsigned BestScore = 0;
17020b57cec5SDimitry Andric
17030b57cec5SDimitry Andric for (unsigned i = 0, e = Filters.size(); i != e; ++i) {
17040b57cec5SDimitry Andric unsigned Usefulness = Filters[i].usefulness();
17050b57cec5SDimitry Andric
17060b57cec5SDimitry Andric if (Usefulness)
17070b57cec5SDimitry Andric AllUseless = false;
17080b57cec5SDimitry Andric
17090b57cec5SDimitry Andric if (Usefulness > BestScore) {
17100b57cec5SDimitry Andric BestIndex = i;
17110b57cec5SDimitry Andric BestScore = Usefulness;
17120b57cec5SDimitry Andric }
17130b57cec5SDimitry Andric }
17140b57cec5SDimitry Andric
17150b57cec5SDimitry Andric if (!AllUseless)
17160b57cec5SDimitry Andric bestFilter().recurse();
17170b57cec5SDimitry Andric
17180b57cec5SDimitry Andric return !AllUseless;
17190b57cec5SDimitry Andric } // end of FilterChooser::filterProcessor(bool)
17200b57cec5SDimitry Andric
17210b57cec5SDimitry Andric // Decides on the best configuration of filter(s) to use in order to decode
17220b57cec5SDimitry Andric // the instructions. A conflict of instructions may occur, in which case we
17230b57cec5SDimitry Andric // dump the conflict set to the standard error.
doFilter()17240b57cec5SDimitry Andric void FilterChooser::doFilter() {
17250b57cec5SDimitry Andric unsigned Num = Opcodes.size();
17260b57cec5SDimitry Andric assert(Num && "FilterChooser created with no instructions");
17270b57cec5SDimitry Andric
17280b57cec5SDimitry Andric // Try regions of consecutive known bit values first.
17290b57cec5SDimitry Andric if (filterProcessor(false))
17300b57cec5SDimitry Andric return;
17310b57cec5SDimitry Andric
17320b57cec5SDimitry Andric // Then regions of mixed bits (both known and unitialized bit values allowed).
17330b57cec5SDimitry Andric if (filterProcessor(true))
17340b57cec5SDimitry Andric return;
17350b57cec5SDimitry Andric
17360b57cec5SDimitry Andric // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where
17370b57cec5SDimitry Andric // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a
17380b57cec5SDimitry Andric // well-known encoding pattern. In such case, we backtrack and scan for the
17390b57cec5SDimitry Andric // the very first consecutive ATTR_ALL_SET region and assign a filter to it.
17400b57cec5SDimitry Andric if (Num == 3 && filterProcessor(true, false))
17410b57cec5SDimitry Andric return;
17420b57cec5SDimitry Andric
17430b57cec5SDimitry Andric // If we come to here, the instruction decoding has failed.
17440b57cec5SDimitry Andric // Set the BestIndex to -1 to indicate so.
17450b57cec5SDimitry Andric BestIndex = -1;
17460b57cec5SDimitry Andric }
17470b57cec5SDimitry Andric
17480b57cec5SDimitry Andric // emitTableEntries - Emit state machine entries to decode our share of
17490b57cec5SDimitry Andric // instructions.
emitTableEntries(DecoderTableInfo & TableInfo) const17500b57cec5SDimitry Andric void FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const {
17510b57cec5SDimitry Andric if (Opcodes.size() == 1) {
17520b57cec5SDimitry Andric // There is only one instruction in the set, which is great!
17530b57cec5SDimitry Andric // Call emitSingletonDecoder() to see whether there are any remaining
17540b57cec5SDimitry Andric // encodings bits.
17550b57cec5SDimitry Andric emitSingletonTableEntry(TableInfo, Opcodes[0]);
17560b57cec5SDimitry Andric return;
17570b57cec5SDimitry Andric }
17580b57cec5SDimitry Andric
17590b57cec5SDimitry Andric // Choose the best filter to do the decodings!
17600b57cec5SDimitry Andric if (BestIndex != -1) {
17610b57cec5SDimitry Andric const Filter &Best = Filters[BestIndex];
17620b57cec5SDimitry Andric if (Best.getNumFiltered() == 1)
17630b57cec5SDimitry Andric emitSingletonTableEntry(TableInfo, Best);
17640b57cec5SDimitry Andric else
17650b57cec5SDimitry Andric Best.emitTableEntry(TableInfo);
17660b57cec5SDimitry Andric return;
17670b57cec5SDimitry Andric }
17680b57cec5SDimitry Andric
17690b57cec5SDimitry Andric // We don't know how to decode these instructions! Dump the
17700b57cec5SDimitry Andric // conflict set and bail.
17710b57cec5SDimitry Andric
17720b57cec5SDimitry Andric // Print out useful conflict information for postmortem analysis.
17730b57cec5SDimitry Andric errs() << "Decoding Conflict:\n";
17740b57cec5SDimitry Andric
17750b57cec5SDimitry Andric dumpStack(errs(), "\t\t");
17760b57cec5SDimitry Andric
1777*5f7ddb14SDimitry Andric for (auto Opcode : Opcodes) {
17780b57cec5SDimitry Andric errs() << '\t';
1779*5f7ddb14SDimitry Andric emitNameWithID(errs(), Opcode.EncodingID);
17800b57cec5SDimitry Andric errs() << " ";
17810b57cec5SDimitry Andric dumpBits(
17820b57cec5SDimitry Andric errs(),
1783*5f7ddb14SDimitry Andric getBitsField(*AllInstructions[Opcode.EncodingID].EncodingDef, "Inst"));
17840b57cec5SDimitry Andric errs() << '\n';
17850b57cec5SDimitry Andric }
17860b57cec5SDimitry Andric }
17870b57cec5SDimitry Andric
findOperandDecoderMethod(TypedInit * TI)17880b57cec5SDimitry Andric static std::string findOperandDecoderMethod(TypedInit *TI) {
17890b57cec5SDimitry Andric std::string Decoder;
17900b57cec5SDimitry Andric
17910b57cec5SDimitry Andric Record *Record = cast<DefInit>(TI)->getDef();
17920b57cec5SDimitry Andric
17930b57cec5SDimitry Andric RecordVal *DecoderString = Record->getValue("DecoderMethod");
17940b57cec5SDimitry Andric StringInit *String = DecoderString ?
17950b57cec5SDimitry Andric dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
17960b57cec5SDimitry Andric if (String) {
17975ffd83dbSDimitry Andric Decoder = std::string(String->getValue());
17980b57cec5SDimitry Andric if (!Decoder.empty())
17990b57cec5SDimitry Andric return Decoder;
18000b57cec5SDimitry Andric }
18010b57cec5SDimitry Andric
18020b57cec5SDimitry Andric if (Record->isSubClassOf("RegisterOperand"))
18030b57cec5SDimitry Andric Record = Record->getValueAsDef("RegClass");
18040b57cec5SDimitry Andric
18050b57cec5SDimitry Andric if (Record->isSubClassOf("RegisterClass")) {
18060b57cec5SDimitry Andric Decoder = "Decode" + Record->getName().str() + "RegisterClass";
18070b57cec5SDimitry Andric } else if (Record->isSubClassOf("PointerLikeRegClass")) {
18080b57cec5SDimitry Andric Decoder = "DecodePointerLikeRegClass" +
18090b57cec5SDimitry Andric utostr(Record->getValueAsInt("RegClassKind"));
18100b57cec5SDimitry Andric }
18110b57cec5SDimitry Andric
18120b57cec5SDimitry Andric return Decoder;
18130b57cec5SDimitry Andric }
18140b57cec5SDimitry Andric
18150b57cec5SDimitry Andric static bool
populateInstruction(CodeGenTarget & Target,const Record & EncodingDef,const CodeGenInstruction & CGI,unsigned Opc,std::map<unsigned,std::vector<OperandInfo>> & Operands)18160b57cec5SDimitry Andric populateInstruction(CodeGenTarget &Target, const Record &EncodingDef,
18170b57cec5SDimitry Andric const CodeGenInstruction &CGI, unsigned Opc,
18180b57cec5SDimitry Andric std::map<unsigned, std::vector<OperandInfo>> &Operands) {
18190b57cec5SDimitry Andric const Record &Def = *CGI.TheDef;
18200b57cec5SDimitry Andric // If all the bit positions are not specified; do not decode this instruction.
18210b57cec5SDimitry Andric // We are bound to fail! For proper disassembly, the well-known encoding bits
18220b57cec5SDimitry Andric // of the instruction must be fully specified.
18230b57cec5SDimitry Andric
18240b57cec5SDimitry Andric BitsInit &Bits = getBitsField(EncodingDef, "Inst");
18250b57cec5SDimitry Andric if (Bits.allInComplete()) return false;
18260b57cec5SDimitry Andric
18270b57cec5SDimitry Andric std::vector<OperandInfo> InsnOperands;
18280b57cec5SDimitry Andric
18290b57cec5SDimitry Andric // If the instruction has specified a custom decoding hook, use that instead
18300b57cec5SDimitry Andric // of trying to auto-generate the decoder.
18310b57cec5SDimitry Andric StringRef InstDecoder = EncodingDef.getValueAsString("DecoderMethod");
18320b57cec5SDimitry Andric if (InstDecoder != "") {
18330b57cec5SDimitry Andric bool HasCompleteInstDecoder = EncodingDef.getValueAsBit("hasCompleteDecoder");
18345ffd83dbSDimitry Andric InsnOperands.push_back(
18355ffd83dbSDimitry Andric OperandInfo(std::string(InstDecoder), HasCompleteInstDecoder));
18360b57cec5SDimitry Andric Operands[Opc] = InsnOperands;
18370b57cec5SDimitry Andric return true;
18380b57cec5SDimitry Andric }
18390b57cec5SDimitry Andric
18400b57cec5SDimitry Andric // Generate a description of the operand of the instruction that we know
18410b57cec5SDimitry Andric // how to decode automatically.
18420b57cec5SDimitry Andric // FIXME: We'll need to have a way to manually override this as needed.
18430b57cec5SDimitry Andric
18440b57cec5SDimitry Andric // Gather the outputs/inputs of the instruction, so we can find their
18450b57cec5SDimitry Andric // positions in the encoding. This assumes for now that they appear in the
18460b57cec5SDimitry Andric // MCInst in the order that they're listed.
18470b57cec5SDimitry Andric std::vector<std::pair<Init*, StringRef>> InOutOperands;
18480b57cec5SDimitry Andric DagInit *Out = Def.getValueAsDag("OutOperandList");
18490b57cec5SDimitry Andric DagInit *In = Def.getValueAsDag("InOperandList");
18500b57cec5SDimitry Andric for (unsigned i = 0; i < Out->getNumArgs(); ++i)
18510b57cec5SDimitry Andric InOutOperands.push_back(std::make_pair(Out->getArg(i),
18520b57cec5SDimitry Andric Out->getArgNameStr(i)));
18530b57cec5SDimitry Andric for (unsigned i = 0; i < In->getNumArgs(); ++i)
18540b57cec5SDimitry Andric InOutOperands.push_back(std::make_pair(In->getArg(i),
18550b57cec5SDimitry Andric In->getArgNameStr(i)));
18560b57cec5SDimitry Andric
18570b57cec5SDimitry Andric // Search for tied operands, so that we can correctly instantiate
18580b57cec5SDimitry Andric // operands that are not explicitly represented in the encoding.
18590b57cec5SDimitry Andric std::map<std::string, std::string> TiedNames;
18600b57cec5SDimitry Andric for (unsigned i = 0; i < CGI.Operands.size(); ++i) {
18610b57cec5SDimitry Andric int tiedTo = CGI.Operands[i].getTiedRegister();
18620b57cec5SDimitry Andric if (tiedTo != -1) {
18630b57cec5SDimitry Andric std::pair<unsigned, unsigned> SO =
18640b57cec5SDimitry Andric CGI.Operands.getSubOperandNumber(tiedTo);
18655ffd83dbSDimitry Andric TiedNames[std::string(InOutOperands[i].second)] =
18665ffd83dbSDimitry Andric std::string(InOutOperands[SO.first].second);
18675ffd83dbSDimitry Andric TiedNames[std::string(InOutOperands[SO.first].second)] =
18685ffd83dbSDimitry Andric std::string(InOutOperands[i].second);
18690b57cec5SDimitry Andric }
18700b57cec5SDimitry Andric }
18710b57cec5SDimitry Andric
18720b57cec5SDimitry Andric std::map<std::string, std::vector<OperandInfo>> NumberedInsnOperands;
18730b57cec5SDimitry Andric std::set<std::string> NumberedInsnOperandsNoTie;
18740b57cec5SDimitry Andric if (Target.getInstructionSet()->
18750b57cec5SDimitry Andric getValueAsBit("decodePositionallyEncodedOperands")) {
18760b57cec5SDimitry Andric const std::vector<RecordVal> &Vals = Def.getValues();
18770b57cec5SDimitry Andric unsigned NumberedOp = 0;
18780b57cec5SDimitry Andric
18790b57cec5SDimitry Andric std::set<unsigned> NamedOpIndices;
18800b57cec5SDimitry Andric if (Target.getInstructionSet()->
18810b57cec5SDimitry Andric getValueAsBit("noNamedPositionallyEncodedOperands"))
18820b57cec5SDimitry Andric // Collect the set of operand indices that might correspond to named
18830b57cec5SDimitry Andric // operand, and skip these when assigning operands based on position.
18840b57cec5SDimitry Andric for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
18850b57cec5SDimitry Andric unsigned OpIdx;
18860b57cec5SDimitry Andric if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx))
18870b57cec5SDimitry Andric continue;
18880b57cec5SDimitry Andric
18890b57cec5SDimitry Andric NamedOpIndices.insert(OpIdx);
18900b57cec5SDimitry Andric }
18910b57cec5SDimitry Andric
18920b57cec5SDimitry Andric for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
18930b57cec5SDimitry Andric // Ignore fixed fields in the record, we're looking for values like:
18940b57cec5SDimitry Andric // bits<5> RST = { ?, ?, ?, ?, ? };
1895af732203SDimitry Andric if (Vals[i].isNonconcreteOK() || Vals[i].getValue()->isComplete())
18960b57cec5SDimitry Andric continue;
18970b57cec5SDimitry Andric
18980b57cec5SDimitry Andric // Determine if Vals[i] actually contributes to the Inst encoding.
18990b57cec5SDimitry Andric unsigned bi = 0;
19000b57cec5SDimitry Andric for (; bi < Bits.getNumBits(); ++bi) {
19010b57cec5SDimitry Andric VarInit *Var = nullptr;
19020b57cec5SDimitry Andric VarBitInit *BI = dyn_cast<VarBitInit>(Bits.getBit(bi));
19030b57cec5SDimitry Andric if (BI)
19040b57cec5SDimitry Andric Var = dyn_cast<VarInit>(BI->getBitVar());
19050b57cec5SDimitry Andric else
19060b57cec5SDimitry Andric Var = dyn_cast<VarInit>(Bits.getBit(bi));
19070b57cec5SDimitry Andric
19080b57cec5SDimitry Andric if (Var && Var->getName() == Vals[i].getName())
19090b57cec5SDimitry Andric break;
19100b57cec5SDimitry Andric }
19110b57cec5SDimitry Andric
19120b57cec5SDimitry Andric if (bi == Bits.getNumBits())
19130b57cec5SDimitry Andric continue;
19140b57cec5SDimitry Andric
19150b57cec5SDimitry Andric // Skip variables that correspond to explicitly-named operands.
19160b57cec5SDimitry Andric unsigned OpIdx;
19170b57cec5SDimitry Andric if (CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx))
19180b57cec5SDimitry Andric continue;
19190b57cec5SDimitry Andric
19200b57cec5SDimitry Andric // Get the bit range for this operand:
19210b57cec5SDimitry Andric unsigned bitStart = bi++, bitWidth = 1;
19220b57cec5SDimitry Andric for (; bi < Bits.getNumBits(); ++bi) {
19230b57cec5SDimitry Andric VarInit *Var = nullptr;
19240b57cec5SDimitry Andric VarBitInit *BI = dyn_cast<VarBitInit>(Bits.getBit(bi));
19250b57cec5SDimitry Andric if (BI)
19260b57cec5SDimitry Andric Var = dyn_cast<VarInit>(BI->getBitVar());
19270b57cec5SDimitry Andric else
19280b57cec5SDimitry Andric Var = dyn_cast<VarInit>(Bits.getBit(bi));
19290b57cec5SDimitry Andric
19300b57cec5SDimitry Andric if (!Var)
19310b57cec5SDimitry Andric break;
19320b57cec5SDimitry Andric
19330b57cec5SDimitry Andric if (Var->getName() != Vals[i].getName())
19340b57cec5SDimitry Andric break;
19350b57cec5SDimitry Andric
19360b57cec5SDimitry Andric ++bitWidth;
19370b57cec5SDimitry Andric }
19380b57cec5SDimitry Andric
19390b57cec5SDimitry Andric unsigned NumberOps = CGI.Operands.size();
19400b57cec5SDimitry Andric while (NumberedOp < NumberOps &&
19410b57cec5SDimitry Andric (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) ||
19420b57cec5SDimitry Andric (!NamedOpIndices.empty() && NamedOpIndices.count(
19430b57cec5SDimitry Andric CGI.Operands.getSubOperandNumber(NumberedOp).first))))
19440b57cec5SDimitry Andric ++NumberedOp;
19450b57cec5SDimitry Andric
19460b57cec5SDimitry Andric OpIdx = NumberedOp++;
19470b57cec5SDimitry Andric
19480b57cec5SDimitry Andric // OpIdx now holds the ordered operand number of Vals[i].
19490b57cec5SDimitry Andric std::pair<unsigned, unsigned> SO =
19500b57cec5SDimitry Andric CGI.Operands.getSubOperandNumber(OpIdx);
19510b57cec5SDimitry Andric const std::string &Name = CGI.Operands[SO.first].Name;
19520b57cec5SDimitry Andric
19530b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Numbered operand mapping for " << Def.getName()
19540b57cec5SDimitry Andric << ": " << Name << "(" << SO.first << ", " << SO.second
19550b57cec5SDimitry Andric << ") => " << Vals[i].getName() << "\n");
19560b57cec5SDimitry Andric
19570b57cec5SDimitry Andric std::string Decoder;
19580b57cec5SDimitry Andric Record *TypeRecord = CGI.Operands[SO.first].Rec;
19590b57cec5SDimitry Andric
19600b57cec5SDimitry Andric RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod");
19610b57cec5SDimitry Andric StringInit *String = DecoderString ?
19620b57cec5SDimitry Andric dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
19630b57cec5SDimitry Andric if (String && String->getValue() != "")
19645ffd83dbSDimitry Andric Decoder = std::string(String->getValue());
19650b57cec5SDimitry Andric
19660b57cec5SDimitry Andric if (Decoder == "" &&
19670b57cec5SDimitry Andric CGI.Operands[SO.first].MIOperandInfo &&
19680b57cec5SDimitry Andric CGI.Operands[SO.first].MIOperandInfo->getNumArgs()) {
19690b57cec5SDimitry Andric Init *Arg = CGI.Operands[SO.first].MIOperandInfo->
19700b57cec5SDimitry Andric getArg(SO.second);
19710b57cec5SDimitry Andric if (DefInit *DI = cast<DefInit>(Arg))
19720b57cec5SDimitry Andric TypeRecord = DI->getDef();
19730b57cec5SDimitry Andric }
19740b57cec5SDimitry Andric
19750b57cec5SDimitry Andric bool isReg = false;
19760b57cec5SDimitry Andric if (TypeRecord->isSubClassOf("RegisterOperand"))
19770b57cec5SDimitry Andric TypeRecord = TypeRecord->getValueAsDef("RegClass");
19780b57cec5SDimitry Andric if (TypeRecord->isSubClassOf("RegisterClass")) {
19790b57cec5SDimitry Andric Decoder = "Decode" + TypeRecord->getName().str() + "RegisterClass";
19800b57cec5SDimitry Andric isReg = true;
19810b57cec5SDimitry Andric } else if (TypeRecord->isSubClassOf("PointerLikeRegClass")) {
19820b57cec5SDimitry Andric Decoder = "DecodePointerLikeRegClass" +
19830b57cec5SDimitry Andric utostr(TypeRecord->getValueAsInt("RegClassKind"));
19840b57cec5SDimitry Andric isReg = true;
19850b57cec5SDimitry Andric }
19860b57cec5SDimitry Andric
19870b57cec5SDimitry Andric DecoderString = TypeRecord->getValue("DecoderMethod");
19880b57cec5SDimitry Andric String = DecoderString ?
19890b57cec5SDimitry Andric dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
19900b57cec5SDimitry Andric if (!isReg && String && String->getValue() != "")
19915ffd83dbSDimitry Andric Decoder = std::string(String->getValue());
19920b57cec5SDimitry Andric
19930b57cec5SDimitry Andric RecordVal *HasCompleteDecoderVal =
19940b57cec5SDimitry Andric TypeRecord->getValue("hasCompleteDecoder");
19950b57cec5SDimitry Andric BitInit *HasCompleteDecoderBit = HasCompleteDecoderVal ?
19960b57cec5SDimitry Andric dyn_cast<BitInit>(HasCompleteDecoderVal->getValue()) : nullptr;
19970b57cec5SDimitry Andric bool HasCompleteDecoder = HasCompleteDecoderBit ?
19980b57cec5SDimitry Andric HasCompleteDecoderBit->getValue() : true;
19990b57cec5SDimitry Andric
20000b57cec5SDimitry Andric OperandInfo OpInfo(Decoder, HasCompleteDecoder);
20010b57cec5SDimitry Andric OpInfo.addField(bitStart, bitWidth, 0);
20020b57cec5SDimitry Andric
20030b57cec5SDimitry Andric NumberedInsnOperands[Name].push_back(OpInfo);
20040b57cec5SDimitry Andric
20050b57cec5SDimitry Andric // FIXME: For complex operands with custom decoders we can't handle tied
20060b57cec5SDimitry Andric // sub-operands automatically. Skip those here and assume that this is
20070b57cec5SDimitry Andric // fixed up elsewhere.
20080b57cec5SDimitry Andric if (CGI.Operands[SO.first].MIOperandInfo &&
20090b57cec5SDimitry Andric CGI.Operands[SO.first].MIOperandInfo->getNumArgs() > 1 &&
20100b57cec5SDimitry Andric String && String->getValue() != "")
20110b57cec5SDimitry Andric NumberedInsnOperandsNoTie.insert(Name);
20120b57cec5SDimitry Andric }
20130b57cec5SDimitry Andric }
20140b57cec5SDimitry Andric
20150b57cec5SDimitry Andric // For each operand, see if we can figure out where it is encoded.
20160b57cec5SDimitry Andric for (const auto &Op : InOutOperands) {
20175ffd83dbSDimitry Andric if (!NumberedInsnOperands[std::string(Op.second)].empty()) {
2018af732203SDimitry Andric llvm::append_range(InsnOperands,
2019af732203SDimitry Andric NumberedInsnOperands[std::string(Op.second)]);
20200b57cec5SDimitry Andric continue;
20210b57cec5SDimitry Andric }
20225ffd83dbSDimitry Andric if (!NumberedInsnOperands[TiedNames[std::string(Op.second)]].empty()) {
20235ffd83dbSDimitry Andric if (!NumberedInsnOperandsNoTie.count(TiedNames[std::string(Op.second)])) {
20240b57cec5SDimitry Andric // Figure out to which (sub)operand we're tied.
20255ffd83dbSDimitry Andric unsigned i =
20265ffd83dbSDimitry Andric CGI.Operands.getOperandNamed(TiedNames[std::string(Op.second)]);
20270b57cec5SDimitry Andric int tiedTo = CGI.Operands[i].getTiedRegister();
20280b57cec5SDimitry Andric if (tiedTo == -1) {
20290b57cec5SDimitry Andric i = CGI.Operands.getOperandNamed(Op.second);
20300b57cec5SDimitry Andric tiedTo = CGI.Operands[i].getTiedRegister();
20310b57cec5SDimitry Andric }
20320b57cec5SDimitry Andric
20330b57cec5SDimitry Andric if (tiedTo != -1) {
20340b57cec5SDimitry Andric std::pair<unsigned, unsigned> SO =
20350b57cec5SDimitry Andric CGI.Operands.getSubOperandNumber(tiedTo);
20360b57cec5SDimitry Andric
20375ffd83dbSDimitry Andric InsnOperands.push_back(
20385ffd83dbSDimitry Andric NumberedInsnOperands[TiedNames[std::string(Op.second)]]
20390b57cec5SDimitry Andric [SO.second]);
20400b57cec5SDimitry Andric }
20410b57cec5SDimitry Andric }
20420b57cec5SDimitry Andric continue;
20430b57cec5SDimitry Andric }
20440b57cec5SDimitry Andric
20450b57cec5SDimitry Andric TypedInit *TI = cast<TypedInit>(Op.first);
20460b57cec5SDimitry Andric
20470b57cec5SDimitry Andric // At this point, we can locate the decoder field, but we need to know how
20480b57cec5SDimitry Andric // to interpret it. As a first step, require the target to provide
20490b57cec5SDimitry Andric // callbacks for decoding register classes.
20500b57cec5SDimitry Andric std::string Decoder = findOperandDecoderMethod(TI);
20510b57cec5SDimitry Andric Record *TypeRecord = cast<DefInit>(TI)->getDef();
20520b57cec5SDimitry Andric
20530b57cec5SDimitry Andric RecordVal *HasCompleteDecoderVal =
20540b57cec5SDimitry Andric TypeRecord->getValue("hasCompleteDecoder");
20550b57cec5SDimitry Andric BitInit *HasCompleteDecoderBit = HasCompleteDecoderVal ?
20560b57cec5SDimitry Andric dyn_cast<BitInit>(HasCompleteDecoderVal->getValue()) : nullptr;
20570b57cec5SDimitry Andric bool HasCompleteDecoder = HasCompleteDecoderBit ?
20580b57cec5SDimitry Andric HasCompleteDecoderBit->getValue() : true;
20590b57cec5SDimitry Andric
20600b57cec5SDimitry Andric OperandInfo OpInfo(Decoder, HasCompleteDecoder);
20618bcb0991SDimitry Andric
20628bcb0991SDimitry Andric // Some bits of the operand may be required to be 1 depending on the
20638bcb0991SDimitry Andric // instruction's encoding. Collect those bits.
20648bcb0991SDimitry Andric if (const RecordVal *EncodedValue = EncodingDef.getValue(Op.second))
20658bcb0991SDimitry Andric if (const BitsInit *OpBits = dyn_cast<BitsInit>(EncodedValue->getValue()))
20668bcb0991SDimitry Andric for (unsigned I = 0; I < OpBits->getNumBits(); ++I)
20678bcb0991SDimitry Andric if (const BitInit *OpBit = dyn_cast<BitInit>(OpBits->getBit(I)))
20688bcb0991SDimitry Andric if (OpBit->getValue())
20698bcb0991SDimitry Andric OpInfo.InitValue |= 1ULL << I;
20708bcb0991SDimitry Andric
20710b57cec5SDimitry Andric unsigned Base = ~0U;
20720b57cec5SDimitry Andric unsigned Width = 0;
20730b57cec5SDimitry Andric unsigned Offset = 0;
20740b57cec5SDimitry Andric
20750b57cec5SDimitry Andric for (unsigned bi = 0; bi < Bits.getNumBits(); ++bi) {
20760b57cec5SDimitry Andric VarInit *Var = nullptr;
20770b57cec5SDimitry Andric VarBitInit *BI = dyn_cast<VarBitInit>(Bits.getBit(bi));
20780b57cec5SDimitry Andric if (BI)
20790b57cec5SDimitry Andric Var = dyn_cast<VarInit>(BI->getBitVar());
20800b57cec5SDimitry Andric else
20810b57cec5SDimitry Andric Var = dyn_cast<VarInit>(Bits.getBit(bi));
20820b57cec5SDimitry Andric
20830b57cec5SDimitry Andric if (!Var) {
20840b57cec5SDimitry Andric if (Base != ~0U) {
20850b57cec5SDimitry Andric OpInfo.addField(Base, Width, Offset);
20860b57cec5SDimitry Andric Base = ~0U;
20870b57cec5SDimitry Andric Width = 0;
20880b57cec5SDimitry Andric Offset = 0;
20890b57cec5SDimitry Andric }
20900b57cec5SDimitry Andric continue;
20910b57cec5SDimitry Andric }
20920b57cec5SDimitry Andric
20930b57cec5SDimitry Andric if (Var->getName() != Op.second &&
20945ffd83dbSDimitry Andric Var->getName() != TiedNames[std::string(Op.second)]) {
20950b57cec5SDimitry Andric if (Base != ~0U) {
20960b57cec5SDimitry Andric OpInfo.addField(Base, Width, Offset);
20970b57cec5SDimitry Andric Base = ~0U;
20980b57cec5SDimitry Andric Width = 0;
20990b57cec5SDimitry Andric Offset = 0;
21000b57cec5SDimitry Andric }
21010b57cec5SDimitry Andric continue;
21020b57cec5SDimitry Andric }
21030b57cec5SDimitry Andric
21040b57cec5SDimitry Andric if (Base == ~0U) {
21050b57cec5SDimitry Andric Base = bi;
21060b57cec5SDimitry Andric Width = 1;
21070b57cec5SDimitry Andric Offset = BI ? BI->getBitNum() : 0;
21080b57cec5SDimitry Andric } else if (BI && BI->getBitNum() != Offset + Width) {
21090b57cec5SDimitry Andric OpInfo.addField(Base, Width, Offset);
21100b57cec5SDimitry Andric Base = bi;
21110b57cec5SDimitry Andric Width = 1;
21120b57cec5SDimitry Andric Offset = BI->getBitNum();
21130b57cec5SDimitry Andric } else {
21140b57cec5SDimitry Andric ++Width;
21150b57cec5SDimitry Andric }
21160b57cec5SDimitry Andric }
21170b57cec5SDimitry Andric
21180b57cec5SDimitry Andric if (Base != ~0U)
21190b57cec5SDimitry Andric OpInfo.addField(Base, Width, Offset);
21200b57cec5SDimitry Andric
21210b57cec5SDimitry Andric if (OpInfo.numFields() > 0)
21220b57cec5SDimitry Andric InsnOperands.push_back(OpInfo);
21230b57cec5SDimitry Andric }
21240b57cec5SDimitry Andric
21250b57cec5SDimitry Andric Operands[Opc] = InsnOperands;
21260b57cec5SDimitry Andric
21270b57cec5SDimitry Andric #if 0
21280b57cec5SDimitry Andric LLVM_DEBUG({
21290b57cec5SDimitry Andric // Dumps the instruction encoding bits.
21300b57cec5SDimitry Andric dumpBits(errs(), Bits);
21310b57cec5SDimitry Andric
21320b57cec5SDimitry Andric errs() << '\n';
21330b57cec5SDimitry Andric
21340b57cec5SDimitry Andric // Dumps the list of operand info.
21350b57cec5SDimitry Andric for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) {
21360b57cec5SDimitry Andric const CGIOperandList::OperandInfo &Info = CGI.Operands[i];
21370b57cec5SDimitry Andric const std::string &OperandName = Info.Name;
21380b57cec5SDimitry Andric const Record &OperandDef = *Info.Rec;
21390b57cec5SDimitry Andric
21400b57cec5SDimitry Andric errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n";
21410b57cec5SDimitry Andric }
21420b57cec5SDimitry Andric });
21430b57cec5SDimitry Andric #endif
21440b57cec5SDimitry Andric
21450b57cec5SDimitry Andric return true;
21460b57cec5SDimitry Andric }
21470b57cec5SDimitry Andric
21480b57cec5SDimitry Andric // emitFieldFromInstruction - Emit the templated helper function
21490b57cec5SDimitry Andric // fieldFromInstruction().
21500b57cec5SDimitry Andric // On Windows we make sure that this function is not inlined when
21510b57cec5SDimitry Andric // using the VS compiler. It has a bug which causes the function
21520b57cec5SDimitry Andric // to be optimized out in some circustances. See llvm.org/pr38292
emitFieldFromInstruction(formatted_raw_ostream & OS)21530b57cec5SDimitry Andric static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
21540b57cec5SDimitry Andric OS << "// Helper functions for extracting fields from encoded instructions.\n"
21550b57cec5SDimitry Andric << "// InsnType must either be integral or an APInt-like object that "
21560b57cec5SDimitry Andric "must:\n"
21570b57cec5SDimitry Andric << "// * be default-constructible and copy-constructible\n"
21580b57cec5SDimitry Andric << "// * be constructible from a uint64_t\n"
21590b57cec5SDimitry Andric << "// * be constructible from an APInt (this can be private)\n"
2160*5f7ddb14SDimitry Andric << "// * Support insertBits(bits, startBit, numBits)\n"
2161*5f7ddb14SDimitry Andric << "// * Support extractBitsAsZExtValue(numBits, startBit)\n"
2162*5f7ddb14SDimitry Andric << "// * be convertible to bool\n"
2163*5f7ddb14SDimitry Andric << "// * Support the ~, &, ==, and != operators with other objects of "
21640b57cec5SDimitry Andric "the same type\n"
21650b57cec5SDimitry Andric << "// * Support put (<<) to raw_ostream&\n"
21660b57cec5SDimitry Andric << "template <typename InsnType>\n"
21670b57cec5SDimitry Andric << "#if defined(_MSC_VER) && !defined(__clang__)\n"
21680b57cec5SDimitry Andric << "__declspec(noinline)\n"
21690b57cec5SDimitry Andric << "#endif\n"
2170*5f7ddb14SDimitry Andric << "static std::enable_if_t<std::is_integral<InsnType>::value, InsnType>\n"
2171*5f7ddb14SDimitry Andric << "fieldFromInstruction(const InsnType &insn, unsigned startBit,\n"
2172*5f7ddb14SDimitry Andric << " unsigned numBits) {\n"
21730b57cec5SDimitry Andric << " assert(startBit + numBits <= 64 && \"Cannot support >64-bit "
21740b57cec5SDimitry Andric "extractions!\");\n"
21750b57cec5SDimitry Andric << " assert(startBit + numBits <= (sizeof(InsnType) * 8) &&\n"
21760b57cec5SDimitry Andric << " \"Instruction field out of bounds!\");\n"
21770b57cec5SDimitry Andric << " InsnType fieldMask;\n"
21780b57cec5SDimitry Andric << " if (numBits == sizeof(InsnType) * 8)\n"
21790b57cec5SDimitry Andric << " fieldMask = (InsnType)(-1LL);\n"
21800b57cec5SDimitry Andric << " else\n"
21810b57cec5SDimitry Andric << " fieldMask = (((InsnType)1 << numBits) - 1) << startBit;\n"
21820b57cec5SDimitry Andric << " return (insn & fieldMask) >> startBit;\n"
21830b57cec5SDimitry Andric << "}\n"
21840b57cec5SDimitry Andric << "\n"
21850b57cec5SDimitry Andric << "template <typename InsnType>\n"
2186*5f7ddb14SDimitry Andric << "static std::enable_if_t<!std::is_integral<InsnType>::value, "
2187*5f7ddb14SDimitry Andric "uint64_t>\n"
2188*5f7ddb14SDimitry Andric << "fieldFromInstruction(const InsnType &insn, unsigned startBit,\n"
2189*5f7ddb14SDimitry Andric << " unsigned numBits) {\n"
2190*5f7ddb14SDimitry Andric << " return insn.extractBitsAsZExtValue(numBits, startBit);\n"
2191*5f7ddb14SDimitry Andric << "}\n\n";
2192*5f7ddb14SDimitry Andric }
2193*5f7ddb14SDimitry Andric
2194*5f7ddb14SDimitry Andric // emitInsertBits - Emit the templated helper function insertBits().
emitInsertBits(formatted_raw_ostream & OS)2195*5f7ddb14SDimitry Andric static void emitInsertBits(formatted_raw_ostream &OS) {
2196*5f7ddb14SDimitry Andric OS << "// Helper function for inserting bits extracted from an encoded "
2197*5f7ddb14SDimitry Andric "instruction into\n"
2198*5f7ddb14SDimitry Andric << "// a field.\n"
2199*5f7ddb14SDimitry Andric << "template <typename InsnType>\n"
2200*5f7ddb14SDimitry Andric << "static std::enable_if_t<std::is_integral<InsnType>::value>\n"
2201*5f7ddb14SDimitry Andric << "insertBits(InsnType &field, InsnType bits, unsigned startBit, "
2202*5f7ddb14SDimitry Andric "unsigned numBits) {\n"
2203*5f7ddb14SDimitry Andric << " assert(startBit + numBits <= sizeof field * 8);\n"
2204*5f7ddb14SDimitry Andric << " field |= (InsnType)bits << startBit;\n"
22050b57cec5SDimitry Andric << "}\n"
22060b57cec5SDimitry Andric << "\n"
22070b57cec5SDimitry Andric << "template <typename InsnType>\n"
2208*5f7ddb14SDimitry Andric << "static std::enable_if_t<!std::is_integral<InsnType>::value>\n"
2209*5f7ddb14SDimitry Andric << "insertBits(InsnType &field, uint64_t bits, unsigned startBit, "
2210*5f7ddb14SDimitry Andric "unsigned numBits) {\n"
2211*5f7ddb14SDimitry Andric << " field.insertBits(bits, startBit, numBits);\n"
22120b57cec5SDimitry Andric << "}\n\n";
22130b57cec5SDimitry Andric }
22140b57cec5SDimitry Andric
22150b57cec5SDimitry Andric // emitDecodeInstruction - Emit the templated helper function
22160b57cec5SDimitry Andric // decodeInstruction().
emitDecodeInstruction(formatted_raw_ostream & OS)22170b57cec5SDimitry Andric static void emitDecodeInstruction(formatted_raw_ostream &OS) {
22180b57cec5SDimitry Andric OS << "template <typename InsnType>\n"
22190b57cec5SDimitry Andric << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], "
22200b57cec5SDimitry Andric "MCInst &MI,\n"
22210b57cec5SDimitry Andric << " InsnType insn, uint64_t "
22220b57cec5SDimitry Andric "Address,\n"
22230b57cec5SDimitry Andric << " const void *DisAsm,\n"
22240b57cec5SDimitry Andric << " const MCSubtargetInfo &STI) {\n"
22250b57cec5SDimitry Andric << " const FeatureBitset &Bits = STI.getFeatureBits();\n"
22260b57cec5SDimitry Andric << "\n"
22270b57cec5SDimitry Andric << " const uint8_t *Ptr = DecodeTable;\n"
22280b57cec5SDimitry Andric << " InsnType CurFieldValue = 0;\n"
22290b57cec5SDimitry Andric << " DecodeStatus S = MCDisassembler::Success;\n"
22300b57cec5SDimitry Andric << " while (true) {\n"
22310b57cec5SDimitry Andric << " ptrdiff_t Loc = Ptr - DecodeTable;\n"
22320b57cec5SDimitry Andric << " switch (*Ptr) {\n"
22330b57cec5SDimitry Andric << " default:\n"
22340b57cec5SDimitry Andric << " errs() << Loc << \": Unexpected decode table opcode!\\n\";\n"
22350b57cec5SDimitry Andric << " return MCDisassembler::Fail;\n"
22360b57cec5SDimitry Andric << " case MCD::OPC_ExtractField: {\n"
22370b57cec5SDimitry Andric << " unsigned Start = *++Ptr;\n"
22380b57cec5SDimitry Andric << " unsigned Len = *++Ptr;\n"
22390b57cec5SDimitry Andric << " ++Ptr;\n"
22400b57cec5SDimitry Andric << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\n"
22410b57cec5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_ExtractField(\" << Start << "
22420b57cec5SDimitry Andric "\", \"\n"
22430b57cec5SDimitry Andric << " << Len << \"): \" << CurFieldValue << \"\\n\");\n"
22440b57cec5SDimitry Andric << " break;\n"
22450b57cec5SDimitry Andric << " }\n"
22460b57cec5SDimitry Andric << " case MCD::OPC_FilterValue: {\n"
22470b57cec5SDimitry Andric << " // Decode the field value.\n"
22480b57cec5SDimitry Andric << " unsigned Len;\n"
22490b57cec5SDimitry Andric << " InsnType Val = decodeULEB128(++Ptr, &Len);\n"
22500b57cec5SDimitry Andric << " Ptr += Len;\n"
22510b57cec5SDimitry Andric << " // NumToSkip is a plain 24-bit integer.\n"
22520b57cec5SDimitry Andric << " unsigned NumToSkip = *Ptr++;\n"
22530b57cec5SDimitry Andric << " NumToSkip |= (*Ptr++) << 8;\n"
22540b57cec5SDimitry Andric << " NumToSkip |= (*Ptr++) << 16;\n"
22550b57cec5SDimitry Andric << "\n"
22560b57cec5SDimitry Andric << " // Perform the filter operation.\n"
22570b57cec5SDimitry Andric << " if (Val != CurFieldValue)\n"
22580b57cec5SDimitry Andric << " Ptr += NumToSkip;\n"
22590b57cec5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_FilterValue(\" << Val << "
22600b57cec5SDimitry Andric "\", \" << NumToSkip\n"
22610b57cec5SDimitry Andric << " << \"): \" << ((Val != CurFieldValue) ? \"FAIL:\" "
22620b57cec5SDimitry Andric ": \"PASS:\")\n"
22630b57cec5SDimitry Andric << " << \" continuing at \" << (Ptr - DecodeTable) << "
22640b57cec5SDimitry Andric "\"\\n\");\n"
22650b57cec5SDimitry Andric << "\n"
22660b57cec5SDimitry Andric << " break;\n"
22670b57cec5SDimitry Andric << " }\n"
22680b57cec5SDimitry Andric << " case MCD::OPC_CheckField: {\n"
22690b57cec5SDimitry Andric << " unsigned Start = *++Ptr;\n"
22700b57cec5SDimitry Andric << " unsigned Len = *++Ptr;\n"
22710b57cec5SDimitry Andric << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\n"
22720b57cec5SDimitry Andric << " // Decode the field value.\n"
22730b57cec5SDimitry Andric << " InsnType ExpectedValue = decodeULEB128(++Ptr, &Len);\n"
22740b57cec5SDimitry Andric << " Ptr += Len;\n"
22750b57cec5SDimitry Andric << " // NumToSkip is a plain 24-bit integer.\n"
22760b57cec5SDimitry Andric << " unsigned NumToSkip = *Ptr++;\n"
22770b57cec5SDimitry Andric << " NumToSkip |= (*Ptr++) << 8;\n"
22780b57cec5SDimitry Andric << " NumToSkip |= (*Ptr++) << 16;\n"
22790b57cec5SDimitry Andric << "\n"
22800b57cec5SDimitry Andric << " // If the actual and expected values don't match, skip.\n"
22810b57cec5SDimitry Andric << " if (ExpectedValue != FieldValue)\n"
22820b57cec5SDimitry Andric << " Ptr += NumToSkip;\n"
22830b57cec5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_CheckField(\" << Start << "
22840b57cec5SDimitry Andric "\", \"\n"
22850b57cec5SDimitry Andric << " << Len << \", \" << ExpectedValue << \", \" << "
22860b57cec5SDimitry Andric "NumToSkip\n"
22870b57cec5SDimitry Andric << " << \"): FieldValue = \" << FieldValue << \", "
22880b57cec5SDimitry Andric "ExpectedValue = \"\n"
22890b57cec5SDimitry Andric << " << ExpectedValue << \": \"\n"
22900b57cec5SDimitry Andric << " << ((ExpectedValue == FieldValue) ? \"PASS\\n\" : "
22910b57cec5SDimitry Andric "\"FAIL\\n\"));\n"
22920b57cec5SDimitry Andric << " break;\n"
22930b57cec5SDimitry Andric << " }\n"
22940b57cec5SDimitry Andric << " case MCD::OPC_CheckPredicate: {\n"
22950b57cec5SDimitry Andric << " unsigned Len;\n"
22960b57cec5SDimitry Andric << " // Decode the Predicate Index value.\n"
22970b57cec5SDimitry Andric << " unsigned PIdx = decodeULEB128(++Ptr, &Len);\n"
22980b57cec5SDimitry Andric << " Ptr += Len;\n"
22990b57cec5SDimitry Andric << " // NumToSkip is a plain 24-bit integer.\n"
23000b57cec5SDimitry Andric << " unsigned NumToSkip = *Ptr++;\n"
23010b57cec5SDimitry Andric << " NumToSkip |= (*Ptr++) << 8;\n"
23020b57cec5SDimitry Andric << " NumToSkip |= (*Ptr++) << 16;\n"
23030b57cec5SDimitry Andric << " // Check the predicate.\n"
23040b57cec5SDimitry Andric << " bool Pred;\n"
23050b57cec5SDimitry Andric << " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\n"
23060b57cec5SDimitry Andric << " Ptr += NumToSkip;\n"
23070b57cec5SDimitry Andric << " (void)Pred;\n"
23080b57cec5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_CheckPredicate(\" << PIdx "
23090b57cec5SDimitry Andric "<< \"): \"\n"
23100b57cec5SDimitry Andric << " << (Pred ? \"PASS\\n\" : \"FAIL\\n\"));\n"
23110b57cec5SDimitry Andric << "\n"
23120b57cec5SDimitry Andric << " break;\n"
23130b57cec5SDimitry Andric << " }\n"
23140b57cec5SDimitry Andric << " case MCD::OPC_Decode: {\n"
23150b57cec5SDimitry Andric << " unsigned Len;\n"
23160b57cec5SDimitry Andric << " // Decode the Opcode value.\n"
23170b57cec5SDimitry Andric << " unsigned Opc = decodeULEB128(++Ptr, &Len);\n"
23180b57cec5SDimitry Andric << " Ptr += Len;\n"
23190b57cec5SDimitry Andric << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\n"
23200b57cec5SDimitry Andric << " Ptr += Len;\n"
23210b57cec5SDimitry Andric << "\n"
23220b57cec5SDimitry Andric << " MI.clear();\n"
23230b57cec5SDimitry Andric << " MI.setOpcode(Opc);\n"
23240b57cec5SDimitry Andric << " bool DecodeComplete;\n"
23250b57cec5SDimitry Andric << " S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, "
23260b57cec5SDimitry Andric "DecodeComplete);\n"
23270b57cec5SDimitry Andric << " assert(DecodeComplete);\n"
23280b57cec5SDimitry Andric << "\n"
23290b57cec5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_Decode: opcode \" << Opc\n"
23300b57cec5SDimitry Andric << " << \", using decoder \" << DecodeIdx << \": \"\n"
23310b57cec5SDimitry Andric << " << (S != MCDisassembler::Fail ? \"PASS\" : "
23320b57cec5SDimitry Andric "\"FAIL\") << \"\\n\");\n"
23330b57cec5SDimitry Andric << " return S;\n"
23340b57cec5SDimitry Andric << " }\n"
23350b57cec5SDimitry Andric << " case MCD::OPC_TryDecode: {\n"
23360b57cec5SDimitry Andric << " unsigned Len;\n"
23370b57cec5SDimitry Andric << " // Decode the Opcode value.\n"
23380b57cec5SDimitry Andric << " unsigned Opc = decodeULEB128(++Ptr, &Len);\n"
23390b57cec5SDimitry Andric << " Ptr += Len;\n"
23400b57cec5SDimitry Andric << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\n"
23410b57cec5SDimitry Andric << " Ptr += Len;\n"
23420b57cec5SDimitry Andric << " // NumToSkip is a plain 24-bit integer.\n"
23430b57cec5SDimitry Andric << " unsigned NumToSkip = *Ptr++;\n"
23440b57cec5SDimitry Andric << " NumToSkip |= (*Ptr++) << 8;\n"
23450b57cec5SDimitry Andric << " NumToSkip |= (*Ptr++) << 16;\n"
23460b57cec5SDimitry Andric << "\n"
23470b57cec5SDimitry Andric << " // Perform the decode operation.\n"
23480b57cec5SDimitry Andric << " MCInst TmpMI;\n"
23490b57cec5SDimitry Andric << " TmpMI.setOpcode(Opc);\n"
23500b57cec5SDimitry Andric << " bool DecodeComplete;\n"
23510b57cec5SDimitry Andric << " S = decodeToMCInst(S, DecodeIdx, insn, TmpMI, Address, DisAsm, "
23520b57cec5SDimitry Andric "DecodeComplete);\n"
23530b57cec5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_TryDecode: opcode \" << "
23540b57cec5SDimitry Andric "Opc\n"
23550b57cec5SDimitry Andric << " << \", using decoder \" << DecodeIdx << \": \");\n"
23560b57cec5SDimitry Andric << "\n"
23570b57cec5SDimitry Andric << " if (DecodeComplete) {\n"
23580b57cec5SDimitry Andric << " // Decoding complete.\n"
23590b57cec5SDimitry Andric << " LLVM_DEBUG(dbgs() << (S != MCDisassembler::Fail ? \"PASS\" : "
23600b57cec5SDimitry Andric "\"FAIL\") << \"\\n\");\n"
23610b57cec5SDimitry Andric << " MI = TmpMI;\n"
23620b57cec5SDimitry Andric << " return S;\n"
23630b57cec5SDimitry Andric << " } else {\n"
23640b57cec5SDimitry Andric << " assert(S == MCDisassembler::Fail);\n"
23650b57cec5SDimitry Andric << " // If the decoding was incomplete, skip.\n"
23660b57cec5SDimitry Andric << " Ptr += NumToSkip;\n"
23670b57cec5SDimitry Andric << " LLVM_DEBUG(dbgs() << \"FAIL: continuing at \" << (Ptr - "
23680b57cec5SDimitry Andric "DecodeTable) << \"\\n\");\n"
23690b57cec5SDimitry Andric << " // Reset decode status. This also drops a SoftFail status "
23700b57cec5SDimitry Andric "that could be\n"
23710b57cec5SDimitry Andric << " // set before the decode attempt.\n"
23720b57cec5SDimitry Andric << " S = MCDisassembler::Success;\n"
23730b57cec5SDimitry Andric << " }\n"
23740b57cec5SDimitry Andric << " break;\n"
23750b57cec5SDimitry Andric << " }\n"
23760b57cec5SDimitry Andric << " case MCD::OPC_SoftFail: {\n"
23770b57cec5SDimitry Andric << " // Decode the mask values.\n"
23780b57cec5SDimitry Andric << " unsigned Len;\n"
23790b57cec5SDimitry Andric << " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\n"
23800b57cec5SDimitry Andric << " Ptr += Len;\n"
23810b57cec5SDimitry Andric << " InsnType NegativeMask = decodeULEB128(Ptr, &Len);\n"
23820b57cec5SDimitry Andric << " Ptr += Len;\n"
23830b57cec5SDimitry Andric << " bool Fail = (insn & PositiveMask) || (~insn & NegativeMask);\n"
23840b57cec5SDimitry Andric << " if (Fail)\n"
23850b57cec5SDimitry Andric << " S = MCDisassembler::SoftFail;\n"
23860b57cec5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_SoftFail: \" << (Fail ? "
23870b57cec5SDimitry Andric "\"FAIL\\n\" : \"PASS\\n\"));\n"
23880b57cec5SDimitry Andric << " break;\n"
23890b57cec5SDimitry Andric << " }\n"
23900b57cec5SDimitry Andric << " case MCD::OPC_Fail: {\n"
23910b57cec5SDimitry Andric << " LLVM_DEBUG(dbgs() << Loc << \": OPC_Fail\\n\");\n"
23920b57cec5SDimitry Andric << " return MCDisassembler::Fail;\n"
23930b57cec5SDimitry Andric << " }\n"
23940b57cec5SDimitry Andric << " }\n"
23950b57cec5SDimitry Andric << " }\n"
23960b57cec5SDimitry Andric << " llvm_unreachable(\"bogosity detected in disassembler state "
23970b57cec5SDimitry Andric "machine!\");\n"
23980b57cec5SDimitry Andric << "}\n\n";
23990b57cec5SDimitry Andric }
24000b57cec5SDimitry Andric
24010b57cec5SDimitry Andric // Emits disassembler code for instruction decoding.
run(raw_ostream & o)24020b57cec5SDimitry Andric void FixedLenDecoderEmitter::run(raw_ostream &o) {
24030b57cec5SDimitry Andric formatted_raw_ostream OS(o);
24040b57cec5SDimitry Andric OS << "#include \"llvm/MC/MCInst.h\"\n";
24050b57cec5SDimitry Andric OS << "#include \"llvm/Support/DataTypes.h\"\n";
2406af732203SDimitry Andric OS << "#include \"llvm/Support/Debug.h\"\n";
24070b57cec5SDimitry Andric OS << "#include \"llvm/Support/LEB128.h\"\n";
24080b57cec5SDimitry Andric OS << "#include \"llvm/Support/raw_ostream.h\"\n";
24090b57cec5SDimitry Andric OS << "#include <assert.h>\n";
24100b57cec5SDimitry Andric OS << '\n';
24110b57cec5SDimitry Andric OS << "namespace llvm {\n\n";
24120b57cec5SDimitry Andric
24130b57cec5SDimitry Andric emitFieldFromInstruction(OS);
2414*5f7ddb14SDimitry Andric emitInsertBits(OS);
24150b57cec5SDimitry Andric
24160b57cec5SDimitry Andric Target.reverseBitsForLittleEndianEncoding();
24170b57cec5SDimitry Andric
24180b57cec5SDimitry Andric // Parameterize the decoders based on namespace and instruction width.
24198bcb0991SDimitry Andric std::set<StringRef> HwModeNames;
24200b57cec5SDimitry Andric const auto &NumberedInstructions = Target.getInstructionsByEnumValue();
24210b57cec5SDimitry Andric NumberedEncodings.reserve(NumberedInstructions.size());
24220b57cec5SDimitry Andric DenseMap<Record *, unsigned> IndexOfInstruction;
24238bcb0991SDimitry Andric // First, collect all HwModes referenced by the target.
24240b57cec5SDimitry Andric for (const auto &NumberedInstruction : NumberedInstructions) {
24250b57cec5SDimitry Andric IndexOfInstruction[NumberedInstruction->TheDef] = NumberedEncodings.size();
24268bcb0991SDimitry Andric
24278bcb0991SDimitry Andric if (const RecordVal *RV =
24288bcb0991SDimitry Andric NumberedInstruction->TheDef->getValue("EncodingInfos")) {
24298bcb0991SDimitry Andric if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
24308bcb0991SDimitry Andric const CodeGenHwModes &HWM = Target.getHwModes();
24318bcb0991SDimitry Andric EncodingInfoByHwMode EBM(DI->getDef(), HWM);
2432*5f7ddb14SDimitry Andric for (auto &KV : EBM)
24338bcb0991SDimitry Andric HwModeNames.insert(HWM.getMode(KV.first).Name);
24348bcb0991SDimitry Andric }
24358bcb0991SDimitry Andric }
24368bcb0991SDimitry Andric }
24378bcb0991SDimitry Andric
24388bcb0991SDimitry Andric // If HwModeNames is empty, add the empty string so we always have one HwMode.
24398bcb0991SDimitry Andric if (HwModeNames.empty())
24408bcb0991SDimitry Andric HwModeNames.insert("");
24418bcb0991SDimitry Andric
24428bcb0991SDimitry Andric for (const auto &NumberedInstruction : NumberedInstructions) {
24438bcb0991SDimitry Andric IndexOfInstruction[NumberedInstruction->TheDef] = NumberedEncodings.size();
24448bcb0991SDimitry Andric
24458bcb0991SDimitry Andric if (const RecordVal *RV =
24468bcb0991SDimitry Andric NumberedInstruction->TheDef->getValue("EncodingInfos")) {
24478bcb0991SDimitry Andric if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
24488bcb0991SDimitry Andric const CodeGenHwModes &HWM = Target.getHwModes();
24498bcb0991SDimitry Andric EncodingInfoByHwMode EBM(DI->getDef(), HWM);
2450*5f7ddb14SDimitry Andric for (auto &KV : EBM) {
24518bcb0991SDimitry Andric NumberedEncodings.emplace_back(KV.second, NumberedInstruction,
24528bcb0991SDimitry Andric HWM.getMode(KV.first).Name);
24538bcb0991SDimitry Andric HwModeNames.insert(HWM.getMode(KV.first).Name);
24548bcb0991SDimitry Andric }
24558bcb0991SDimitry Andric continue;
24568bcb0991SDimitry Andric }
24578bcb0991SDimitry Andric }
24588bcb0991SDimitry Andric // This instruction is encoded the same on all HwModes. Emit it for all
24598bcb0991SDimitry Andric // HwModes.
24608bcb0991SDimitry Andric for (StringRef HwModeName : HwModeNames)
24618bcb0991SDimitry Andric NumberedEncodings.emplace_back(NumberedInstruction->TheDef,
24628bcb0991SDimitry Andric NumberedInstruction, HwModeName);
24630b57cec5SDimitry Andric }
24640b57cec5SDimitry Andric for (const auto &NumberedAlias : RK.getAllDerivedDefinitions("AdditionalEncoding"))
24650b57cec5SDimitry Andric NumberedEncodings.emplace_back(
24660b57cec5SDimitry Andric NumberedAlias,
24670b57cec5SDimitry Andric &Target.getInstruction(NumberedAlias->getValueAsDef("AliasOf")));
24680b57cec5SDimitry Andric
24690b57cec5SDimitry Andric std::map<std::pair<std::string, unsigned>, std::vector<EncodingIDAndOpcode>>
24700b57cec5SDimitry Andric OpcMap;
24710b57cec5SDimitry Andric std::map<unsigned, std::vector<OperandInfo>> Operands;
24720b57cec5SDimitry Andric
24730b57cec5SDimitry Andric for (unsigned i = 0; i < NumberedEncodings.size(); ++i) {
24740b57cec5SDimitry Andric const Record *EncodingDef = NumberedEncodings[i].EncodingDef;
24750b57cec5SDimitry Andric const CodeGenInstruction *Inst = NumberedEncodings[i].Inst;
24760b57cec5SDimitry Andric const Record *Def = Inst->TheDef;
24770b57cec5SDimitry Andric unsigned Size = EncodingDef->getValueAsInt("Size");
24780b57cec5SDimitry Andric if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
24790b57cec5SDimitry Andric Def->getValueAsBit("isPseudo") ||
24800b57cec5SDimitry Andric Def->getValueAsBit("isAsmParserOnly") ||
24810b57cec5SDimitry Andric Def->getValueAsBit("isCodeGenOnly")) {
24820b57cec5SDimitry Andric NumEncodingsLackingDisasm++;
24830b57cec5SDimitry Andric continue;
24840b57cec5SDimitry Andric }
24850b57cec5SDimitry Andric
24860b57cec5SDimitry Andric if (i < NumberedInstructions.size())
24870b57cec5SDimitry Andric NumInstructions++;
24880b57cec5SDimitry Andric NumEncodings++;
24890b57cec5SDimitry Andric
24908bcb0991SDimitry Andric if (!Size)
24918bcb0991SDimitry Andric continue;
24920b57cec5SDimitry Andric
24930b57cec5SDimitry Andric if (populateInstruction(Target, *EncodingDef, *Inst, i, Operands)) {
24948bcb0991SDimitry Andric std::string DecoderNamespace =
24955ffd83dbSDimitry Andric std::string(EncodingDef->getValueAsString("DecoderNamespace"));
24968bcb0991SDimitry Andric if (!NumberedEncodings[i].HwModeName.empty())
24978bcb0991SDimitry Andric DecoderNamespace +=
24988bcb0991SDimitry Andric std::string("_") + NumberedEncodings[i].HwModeName.str();
24998bcb0991SDimitry Andric OpcMap[std::make_pair(DecoderNamespace, Size)].emplace_back(
25008bcb0991SDimitry Andric i, IndexOfInstruction.find(Def)->second);
25018bcb0991SDimitry Andric } else {
25020b57cec5SDimitry Andric NumEncodingsOmitted++;
25030b57cec5SDimitry Andric }
25040b57cec5SDimitry Andric }
25050b57cec5SDimitry Andric
25060b57cec5SDimitry Andric DecoderTableInfo TableInfo;
25070b57cec5SDimitry Andric for (const auto &Opc : OpcMap) {
25080b57cec5SDimitry Andric // Emit the decoder for this namespace+width combination.
25090b57cec5SDimitry Andric ArrayRef<EncodingAndInst> NumberedEncodingsRef(
25100b57cec5SDimitry Andric NumberedEncodings.data(), NumberedEncodings.size());
25110b57cec5SDimitry Andric FilterChooser FC(NumberedEncodingsRef, Opc.second, Operands,
25120b57cec5SDimitry Andric 8 * Opc.first.second, this);
25130b57cec5SDimitry Andric
25140b57cec5SDimitry Andric // The decode table is cleared for each top level decoder function. The
25150b57cec5SDimitry Andric // predicates and decoders themselves, however, are shared across all
25160b57cec5SDimitry Andric // decoders to give more opportunities for uniqueing.
25170b57cec5SDimitry Andric TableInfo.Table.clear();
25180b57cec5SDimitry Andric TableInfo.FixupStack.clear();
25190b57cec5SDimitry Andric TableInfo.Table.reserve(16384);
25200b57cec5SDimitry Andric TableInfo.FixupStack.emplace_back();
25210b57cec5SDimitry Andric FC.emitTableEntries(TableInfo);
25220b57cec5SDimitry Andric // Any NumToSkip fixups in the top level scope can resolve to the
25230b57cec5SDimitry Andric // OPC_Fail at the end of the table.
25240b57cec5SDimitry Andric assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!");
25250b57cec5SDimitry Andric // Resolve any NumToSkip fixups in the current scope.
25260b57cec5SDimitry Andric resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
25270b57cec5SDimitry Andric TableInfo.Table.size());
25280b57cec5SDimitry Andric TableInfo.FixupStack.clear();
25290b57cec5SDimitry Andric
25300b57cec5SDimitry Andric TableInfo.Table.push_back(MCD::OPC_Fail);
25310b57cec5SDimitry Andric
25320b57cec5SDimitry Andric // Print the table to the output stream.
25330b57cec5SDimitry Andric emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), Opc.first.first);
25340b57cec5SDimitry Andric OS.flush();
25350b57cec5SDimitry Andric }
25360b57cec5SDimitry Andric
25370b57cec5SDimitry Andric // Emit the predicate function.
25380b57cec5SDimitry Andric emitPredicateFunction(OS, TableInfo.Predicates, 0);
25390b57cec5SDimitry Andric
25400b57cec5SDimitry Andric // Emit the decoder function.
25410b57cec5SDimitry Andric emitDecoderFunction(OS, TableInfo.Decoders, 0);
25420b57cec5SDimitry Andric
25430b57cec5SDimitry Andric // Emit the main entry point for the decoder, decodeInstruction().
25440b57cec5SDimitry Andric emitDecodeInstruction(OS);
25450b57cec5SDimitry Andric
25468bcb0991SDimitry Andric OS << "\n} // end namespace llvm\n";
25470b57cec5SDimitry Andric }
25480b57cec5SDimitry Andric
25490b57cec5SDimitry Andric namespace llvm {
25500b57cec5SDimitry Andric
EmitFixedLenDecoder(RecordKeeper & RK,raw_ostream & OS,const std::string & PredicateNamespace,const std::string & GPrefix,const std::string & GPostfix,const std::string & ROK,const std::string & RFail,const std::string & L)25510b57cec5SDimitry Andric void EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS,
25520b57cec5SDimitry Andric const std::string &PredicateNamespace,
25530b57cec5SDimitry Andric const std::string &GPrefix,
25540b57cec5SDimitry Andric const std::string &GPostfix, const std::string &ROK,
25550b57cec5SDimitry Andric const std::string &RFail, const std::string &L) {
25560b57cec5SDimitry Andric FixedLenDecoderEmitter(RK, PredicateNamespace, GPrefix, GPostfix,
25570b57cec5SDimitry Andric ROK, RFail, L).run(OS);
25580b57cec5SDimitry Andric }
25590b57cec5SDimitry Andric
25600b57cec5SDimitry Andric } // end namespace llvm
2561