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