//===---------------- DecoderEmitter.cpp - Decoder Generator --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// It contains the tablegen backend that emits the decoder functions for
// targets with fixed/variable length instruction set.
//
//===----------------------------------------------------------------------===//

#include "Common/CodeGenHwModes.h"
#include "Common/CodeGenInstruction.h"
#include "Common/CodeGenTarget.h"
#include "Common/InfoByHwMode.h"
#include "Common/VarLenCodeEmitterGen.h"
#include "TableGenBackends.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCDecoderOps.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace llvm;

#define DEBUG_TYPE "decoder-emitter"

extern cl::OptionCategory DisassemblerEmitterCat;

enum SuppressLevel {
  SUPPRESSION_DISABLE,
  SUPPRESSION_LEVEL1,
  SUPPRESSION_LEVEL2
};

static cl::opt<SuppressLevel> DecoderEmitterSuppressDuplicates(
    "suppress-per-hwmode-duplicates",
    cl::desc("Suppress duplication of instrs into per-HwMode decoder tables"),
    cl::values(
        clEnumValN(
            SUPPRESSION_DISABLE, "O0",
            "Do not prevent DecoderTable duplications caused by HwModes"),
        clEnumValN(
            SUPPRESSION_LEVEL1, "O1",
            "Remove duplicate DecoderTable entries generated due to HwModes"),
        clEnumValN(
            SUPPRESSION_LEVEL2, "O2",
            "Extract HwModes-specific instructions into new DecoderTables, "
            "significantly reducing Table Duplications")),
    cl::init(SUPPRESSION_DISABLE), cl::cat(DisassemblerEmitterCat));

static cl::opt<bool> LargeTable(
    "large-decoder-table",
    cl::desc("Use large decoder table format. This uses 24 bits for offset\n"
             "in the table instead of the default 16 bits."),
    cl::init(false), cl::cat(DisassemblerEmitterCat));

static cl::opt<bool> UseFnTableInDecodeToMCInst(
    "use-fn-table-in-decode-to-mcinst",
    cl::desc(
        "Use a table of function pointers instead of a switch case in the\n"
        "generated `decodeToMCInst` function. Helps improve compile time\n"
        "of the generated code."),
    cl::init(false), cl::cat(DisassemblerEmitterCat));

STATISTIC(NumEncodings, "Number of encodings considered");
STATISTIC(NumEncodingsLackingDisasm,
          "Number of encodings without disassembler info");
STATISTIC(NumInstructions, "Number of instructions considered");
STATISTIC(NumEncodingsSupported, "Number of encodings supported");
STATISTIC(NumEncodingsOmitted, "Number of encodings omitted");

static unsigned getNumToSkipInBytes() { return LargeTable ? 3 : 2; }

namespace {

struct EncodingField {
  unsigned Base, Width, Offset;
  EncodingField(unsigned B, unsigned W, unsigned O)
      : Base(B), Width(W), Offset(O) {}
};

struct OperandInfo {
  std::vector<EncodingField> Fields;
  std::string Decoder;
  bool HasCompleteDecoder;
  uint64_t InitValue = 0;

  OperandInfo(std::string D, bool HCD) : Decoder(D), HasCompleteDecoder(HCD) {}

  void addField(unsigned Base, unsigned Width, unsigned Offset) {
    Fields.push_back(EncodingField(Base, Width, Offset));
  }

  unsigned numFields() const { return Fields.size(); }

  typedef std::vector<EncodingField>::const_iterator const_iterator;

  const_iterator begin() const { return Fields.begin(); }
  const_iterator end() const { return Fields.end(); }
};

typedef std::vector<uint32_t> FixupList;
typedef std::vector<FixupList> FixupScopeList;
typedef SmallSetVector<CachedHashString, 16> PredicateSet;
typedef SmallSetVector<CachedHashString, 16> DecoderSet;

class DecoderTable {
public:
  DecoderTable() { Data.reserve(16384); }

  void clear() { Data.clear(); }
  void push_back(uint8_t Item) { Data.push_back(Item); }
  size_t size() const { return Data.size(); }
  const uint8_t *data() const { return Data.data(); }

  using const_iterator = std::vector<uint8_t>::const_iterator;
  const_iterator begin() const { return Data.begin(); }
  const_iterator end() const { return Data.end(); }

  // Insert a ULEB128 encoded value into the table.
  void insertULEB128(uint64_t Value) {
    // Encode and emit the value to filter against.
    uint8_t Buffer[16];
    unsigned Len = encodeULEB128(Value, Buffer);
    Data.insert(Data.end(), Buffer, Buffer + Len);
  }

  // Insert space for `NumToSkip` and return the position
  // in the table for patching.
  size_t insertNumToSkip() {
    size_t Size = Data.size();
    Data.insert(Data.end(), getNumToSkipInBytes(), 0);
    return Size;
  }

  void patchNumToSkip(size_t FixupIdx, uint32_t DestIdx) {
    // Calculate the distance from the byte following the fixup entry byte
    // to the destination. The Target is calculated from after the
    // `getNumToSkipInBytes()`-byte NumToSkip entry itself, so subtract
    // `getNumToSkipInBytes()` from the displacement here to account for that.
    assert(DestIdx >= FixupIdx + getNumToSkipInBytes() &&
           "Expecting a forward jump in the decoding table");
    uint32_t Delta = DestIdx - FixupIdx - getNumToSkipInBytes();
    if (!isUIntN(8 * getNumToSkipInBytes(), Delta))
      PrintFatalError(
          "disassembler decoding table too large, try --large-decoder-table");

    Data[FixupIdx] = static_cast<uint8_t>(Delta);
    Data[FixupIdx + 1] = static_cast<uint8_t>(Delta >> 8);
    if (getNumToSkipInBytes() == 3)
      Data[FixupIdx + 2] = static_cast<uint8_t>(Delta >> 16);
  }

private:
  std::vector<uint8_t> Data;
};

struct DecoderTableInfo {
  DecoderTable Table;
  FixupScopeList FixupStack;
  PredicateSet Predicates;
  DecoderSet Decoders;

  bool isOutermostScope() const { return FixupStack.size() == 1; }
};

struct EncodingAndInst {
  const Record *EncodingDef;
  const CodeGenInstruction *Inst;
  StringRef HwModeName;

  EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst,
                  StringRef HwModeName = "")
      : EncodingDef(EncodingDef), Inst(Inst), HwModeName(HwModeName) {}
};

struct EncodingIDAndOpcode {
  unsigned EncodingID;
  unsigned Opcode;

  EncodingIDAndOpcode() : EncodingID(0), Opcode(0) {}
  EncodingIDAndOpcode(unsigned EncodingID, unsigned Opcode)
      : EncodingID(EncodingID), Opcode(Opcode) {}
};

using EncodingIDsVec = std::vector<EncodingIDAndOpcode>;
using NamespacesHwModesMap = std::map<std::string, std::set<StringRef>>;

class DecoderEmitter {
  const RecordKeeper &RK;
  std::vector<EncodingAndInst> NumberedEncodings;

public:
  DecoderEmitter(const RecordKeeper &R, StringRef PredicateNamespace)
      : RK(R), Target(R), PredicateNamespace(PredicateNamespace) {}

  // Emit the decoder state machine table. Returns a mask of MCD decoder ops
  // that were emitted.
  unsigned emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
                     unsigned BitWidth, StringRef Namespace,
                     const EncodingIDsVec &EncodingIDs) const;
  void emitInstrLenTable(formatted_raw_ostream &OS,
                         ArrayRef<unsigned> InstrLen) const;
  void emitPredicateFunction(formatted_raw_ostream &OS,
                             PredicateSet &Predicates) const;
  void emitDecoderFunction(formatted_raw_ostream &OS,
                           DecoderSet &Decoders) const;

  // run - Output the code emitter
  void run(raw_ostream &o);

private:
  CodeGenTarget Target;

public:
  StringRef PredicateNamespace;
};

// The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system
// for a bit value.
//
// BIT_UNFILTERED is used as the init value for a filter position.  It is used
// only for filter processings.
struct BitValue {
  enum bit_value_t : uint8_t {
    BIT_FALSE,     // '0'
    BIT_TRUE,      // '1'
    BIT_UNSET,     // '?', printed as '_'
    BIT_UNFILTERED // unfiltered, printed as '.'
  };

  BitValue(bit_value_t V) : V(V) {}
  explicit BitValue(const Init *Init) {
    if (const auto *Bit = dyn_cast<BitInit>(Init))
      V = Bit->getValue() ? BIT_TRUE : BIT_FALSE;
    else
      V = BIT_UNSET;
  }
  BitValue(const BitsInit &Bits, unsigned Idx) : BitValue(Bits.getBit(Idx)) {}

  bool isSet() const { return V == BIT_TRUE || V == BIT_FALSE; }
  bool isUnset() const { return V == BIT_UNSET; }
  std::optional<uint64_t> getValue() const {
    if (isSet())
      return static_cast<uint64_t>(V);
    return std::nullopt;
  }

  // For printing a bit value.
  operator StringRef() const {
    switch (V) {
    case BIT_FALSE:
      return "0";
    case BIT_TRUE:
      return "1";
    case BIT_UNSET:
      return "_";
    case BIT_UNFILTERED:
      return ".";
    }
    llvm_unreachable("Unknow bit value");
  }

  bool operator==(bit_value_t Other) const { return Other == V; }
  bool operator!=(bit_value_t Other) const { return Other != V; }

private:
  bit_value_t V;
};

} // end anonymous namespace

static raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {
  if (Value.EncodingDef != Value.Inst->TheDef)
    OS << Value.EncodingDef->getName() << ":";
  OS << Value.Inst->TheDef->getName();
  return OS;
}

// Prints the bit value for each position.
static void dumpBits(raw_ostream &OS, const BitsInit &Bits) {
  for (const Init *Bit : reverse(Bits.getBits()))
    OS << BitValue(Bit);
}

static const BitsInit &getBitsField(const Record &Def, StringRef FieldName) {
  const RecordVal *RV = Def.getValue(FieldName);
  if (const BitsInit *Bits = dyn_cast<BitsInit>(RV->getValue()))
    return *Bits;

  // Handle variable length instructions.
  VarLenInst VLI(cast<DagInit>(RV->getValue()), RV);
  SmallVector<const Init *, 16> Bits;

  for (const auto &SI : VLI) {
    if (const BitsInit *BI = dyn_cast<BitsInit>(SI.Value))
      llvm::append_range(Bits, BI->getBits());
    else if (const BitInit *BI = dyn_cast<BitInit>(SI.Value))
      Bits.push_back(BI);
    else
      Bits.append(SI.BitWidth, UnsetInit::get(Def.getRecords()));
  }

  return *BitsInit::get(Def.getRecords(), Bits);
}

// Representation of the instruction to work on.
typedef std::vector<BitValue> insn_t;

namespace {

static constexpr uint64_t NO_FIXED_SEGMENTS_SENTINEL =
    std::numeric_limits<uint64_t>::max();

class FilterChooser;

/// Filter - Filter works with FilterChooser to produce the decoding tree for
/// the ISA.
///
/// It is useful to think of a Filter as governing the switch stmts of the
/// decoding tree in a certain level.  Each case stmt delegates to an inferior
/// FilterChooser to decide what further decoding logic to employ, or in another
/// words, what other remaining bits to look at.  The FilterChooser eventually
/// chooses a best Filter to do its job.
///
/// This recursive scheme ends when the number of Opcodes assigned to the
/// FilterChooser becomes 1 or if there is a conflict.  A conflict happens when
/// the Filter/FilterChooser combo does not know how to distinguish among the
/// Opcodes assigned.
///
/// An example of a conflict is
///
/// Conflict:
///                     111101000.00........00010000....
///                     111101000.00........0001........
///                     1111010...00........0001........
///                     1111010...00....................
///                     1111010.........................
///                     1111............................
///                     ................................
///     VST4q8a         111101000_00________00010000____
///     VST4q8b         111101000_00________00010000____
///
/// The Debug output shows the path that the decoding tree follows to reach the
/// the conclusion that there is a conflict.  VST4q8a is a vst4 to double-spaced
/// even registers, while VST4q8b is a vst4 to double-spaced odd registers.
///
/// The encoding info in the .td files does not specify this meta information,
/// which could have been used by the decoder to resolve the conflict.  The
/// decoder could try to decode the even/odd register numbering and assign to
/// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a"
/// version and return the Opcode since the two have the same Asm format string.
class Filter {
protected:
  const FilterChooser &Owner; // FilterChooser who owns this filter
  unsigned StartBit; // the starting bit position
  unsigned NumBits;  // number of bits to filter
  bool Mixed;        // a mixed region contains both set and unset bits

  // Map of well-known segment value to the set of uid's with that value.
  std::map<uint64_t, std::vector<EncodingIDAndOpcode>> FilteredInstructions;

  // Set of uid's with non-constant segment values.
  std::vector<EncodingIDAndOpcode> VariableInstructions;

  // Map of well-known segment value to its delegate.
  std::map<uint64_t, std::unique_ptr<const FilterChooser>> FilterChooserMap;

  // Number of instructions which fall under FilteredInstructions category.
  unsigned NumFiltered;

  // Keeps track of the last opcode in the filtered bucket.
  EncodingIDAndOpcode LastOpcFiltered;

public:
  Filter(Filter &&f);
  Filter(const FilterChooser &owner, unsigned startBit, unsigned numBits,
         bool mixed);

  ~Filter() = default;

  unsigned getNumFiltered() const { return NumFiltered; }

  EncodingIDAndOpcode getSingletonOpc() const {
    assert(NumFiltered == 1);
    return LastOpcFiltered;
  }

  // Return the filter chooser for the group of instructions without constant
  // segment values.
  const FilterChooser &getVariableFC() const {
    assert(NumFiltered == 1 && FilterChooserMap.size() == 1);
    return *(FilterChooserMap.find(NO_FIXED_SEGMENTS_SENTINEL)->second);
  }

  // Divides the decoding task into sub tasks and delegates them to the
  // inferior FilterChooser's.
  //
  // A special case arises when there's only one entry in the filtered
  // instructions.  In order to unambiguously decode the singleton, we need to
  // match the remaining undecoded encoding bits against the singleton.
  void recurse();

  // Emit table entries to decode instructions given a segment or segments of
  // bits.
  void emitTableEntry(DecoderTableInfo &TableInfo) const;

  // Returns the number of fanout produced by the filter.  More fanout implies
  // the filter distinguishes more categories of instructions.
  unsigned usefulness() const;
}; // end class Filter

// These are states of our finite state machines used in FilterChooser's
// filterProcessor() which produces the filter candidates to use.
enum bitAttr_t {
  ATTR_NONE,
  ATTR_FILTERED,
  ATTR_ALL_SET,
  ATTR_ALL_UNSET,
  ATTR_MIXED
};

/// FilterChooser - FilterChooser chooses the best filter among a set of Filters
/// in order to perform the decoding of instructions at the current level.
///
/// Decoding proceeds from the top down.  Based on the well-known encoding bits
/// of instructions available, FilterChooser builds up the possible Filters that
/// can further the task of decoding by distinguishing among the remaining
/// candidate instructions.
///
/// Once a filter has been chosen, it is called upon to divide the decoding task
/// into sub-tasks and delegates them to its inferior FilterChoosers for further
/// processings.
///
/// It is useful to think of a Filter as governing the switch stmts of the
/// decoding tree.  And each case is delegated to an inferior FilterChooser to
/// decide what further remaining bits to look at.

class FilterChooser {
protected:
  friend class Filter;

  // Vector of codegen instructions to choose our filter.
  ArrayRef<EncodingAndInst> AllInstructions;

  // Vector of uid's for this filter chooser to work on.
  // The first member of the pair is the opcode id being decoded, the second is
  // the opcode id that should be emitted.
  ArrayRef<EncodingIDAndOpcode> Opcodes;

  // Lookup table for the operand decoding of instructions.
  const std::map<unsigned, std::vector<OperandInfo>> &Operands;

  // Vector of candidate filters.
  std::vector<Filter> Filters;

  // Array of bit values passed down from our parent.
  // Set to all BIT_UNFILTERED's for Parent == NULL.
  std::vector<BitValue> FilterBitValues;

  // Links to the FilterChooser above us in the decoding tree.
  const FilterChooser *Parent;

  // Index of the best filter from Filters.
  int BestIndex;

  // Width of instructions
  unsigned BitWidth;

  // Parent emitter
  const DecoderEmitter *Emitter;

  struct Island {
    unsigned StartBit;
    unsigned NumBits;
    uint64_t FieldVal;
  };

public:
  FilterChooser(ArrayRef<EncodingAndInst> Insts,
                ArrayRef<EncodingIDAndOpcode> IDs,
                const std::map<unsigned, std::vector<OperandInfo>> &Ops,
                unsigned BW, const DecoderEmitter *E)
      : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
        FilterBitValues(BW, BitValue::BIT_UNFILTERED), Parent(nullptr),
        BestIndex(-1), BitWidth(BW), Emitter(E) {
    doFilter();
  }

  FilterChooser(ArrayRef<EncodingAndInst> Insts,
                ArrayRef<EncodingIDAndOpcode> IDs,
                const std::map<unsigned, std::vector<OperandInfo>> &Ops,
                const std::vector<BitValue> &ParentFilterBitValues,
                const FilterChooser &parent)
      : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
        FilterBitValues(ParentFilterBitValues), Parent(&parent), BestIndex(-1),
        BitWidth(parent.BitWidth), Emitter(parent.Emitter) {
    doFilter();
  }

  FilterChooser(const FilterChooser &) = delete;
  void operator=(const FilterChooser &) = delete;

  unsigned getBitWidth() const { return BitWidth; }

protected:
  // Populates the insn given the uid.
  void insnWithID(insn_t &Insn, unsigned Opcode) const {
    const Record *EncodingDef = AllInstructions[Opcode].EncodingDef;
    const BitsInit &Bits = getBitsField(*EncodingDef, "Inst");
    Insn.resize(std::max(BitWidth, Bits.getNumBits()), BitValue::BIT_UNSET);
    // We may have a SoftFail bitmask, which specifies a mask where an encoding
    // may differ from the value in "Inst" and yet still be valid, but the
    // disassembler should return SoftFail instead of Success.
    //
    // This is used for marking UNPREDICTABLE instructions in the ARM world.
    const RecordVal *RV = EncodingDef->getValue("SoftFail");
    const BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
    for (unsigned i = 0; i < Bits.getNumBits(); ++i) {
      if (SFBits && BitValue(*SFBits, i) == BitValue::BIT_TRUE)
        Insn[i] = BitValue::BIT_UNSET;
      else
        Insn[i] = BitValue(Bits, i);
    }
  }

  // Populates the field of the insn given the start position and the number of
  // consecutive bits to scan for.
  //
  // Returns a pair of values (indicator, field), where the indicator is false
  // if there exists any uninitialized bit value in the range and true if all
  // bits are well-known. The second value is the potentially populated field.
  std::pair<bool, uint64_t> fieldFromInsn(const insn_t &Insn, unsigned StartBit,
                                          unsigned NumBits) const;

  /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
  /// filter array as a series of chars.
  void dumpFilterArray(raw_ostream &OS, ArrayRef<BitValue> Filter) const;

  /// dumpStack - dumpStack traverses the filter chooser chain and calls
  /// dumpFilterArray on each filter chooser up to the top level one.
  void dumpStack(raw_ostream &OS, const char *prefix) const;

  Filter &bestFilter() {
    assert(BestIndex != -1 && "BestIndex not set");
    return Filters[BestIndex];
  }

  bool PositionFiltered(unsigned Idx) const {
    return FilterBitValues[Idx].isSet();
  }

  // Calculates the island(s) needed to decode the instruction.
  // This returns a list of undecoded bits of an instructions, for example,
  // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
  // decoded bits in order to verify that the instruction matches the Opcode.
  unsigned getIslands(std::vector<Island> &Islands, const insn_t &Insn) const;

  // Emits code to check the Predicates member of an instruction are true.
  // Returns true if predicate matches were emitted, false otherwise.
  bool emitPredicateMatch(raw_ostream &OS, unsigned Opc) const;
  bool emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
                             raw_ostream &OS) const;

  bool doesOpcodeNeedPredicate(unsigned Opc) const;
  unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const;
  void emitPredicateTableEntry(DecoderTableInfo &TableInfo, unsigned Opc) const;

  void emitSoftFailTableEntry(DecoderTableInfo &TableInfo, unsigned Opc) const;

  // Emits table entries to decode the singleton.
  void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
                               EncodingIDAndOpcode Opc) const;

  // Emits code to decode the singleton, and then to decode the rest.
  void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
                               const Filter &Best) const;

  bool emitBinaryParser(raw_ostream &OS, indent Indent,
                        const OperandInfo &OpInfo) const;

  bool emitDecoder(raw_ostream &OS, indent Indent, unsigned Opc) const;
  std::pair<unsigned, bool> getDecoderIndex(DecoderSet &Decoders,
                                            unsigned Opc) const;

  // Assign a single filter and run with it.
  void runSingleFilter(unsigned startBit, unsigned numBit, bool mixed);

  // reportRegion is a helper function for filterProcessor to mark a region as
  // eligible for use as a filter region.
  void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex,
                    bool AllowMixed);

  // FilterProcessor scans the well-known encoding bits of the instructions and
  // builds up a list of candidate filters.  It chooses the best filter and
  // recursively descends down the decoding tree.
  bool filterProcessor(bool AllowMixed, bool Greedy = true);

  // Decides on the best configuration of filter(s) to use in order to decode
  // the instructions.  A conflict of instructions may occur, in which case we
  // dump the conflict set to the standard error.
  void doFilter();

public:
  // emitTableEntries - Emit state machine entries to decode our share of
  // instructions.
  void emitTableEntries(DecoderTableInfo &TableInfo) const;
};

} // end anonymous namespace

///////////////////////////
//                       //
// Filter Implementation //
//                       //
///////////////////////////

Filter::Filter(Filter &&f)
    : Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed),
      FilteredInstructions(std::move(f.FilteredInstructions)),
      VariableInstructions(std::move(f.VariableInstructions)),
      FilterChooserMap(std::move(f.FilterChooserMap)),
      NumFiltered(f.NumFiltered), LastOpcFiltered(f.LastOpcFiltered) {}

Filter::Filter(const FilterChooser &owner, unsigned startBit, unsigned numBits,
               bool mixed)
    : Owner(owner), StartBit(startBit), NumBits(numBits), Mixed(mixed) {
  assert(StartBit + NumBits - 1 < Owner.BitWidth);

  NumFiltered = 0;
  LastOpcFiltered = {0, 0};

  for (const auto &OpcPair : Owner.Opcodes) {
    insn_t Insn;

    // Populates the insn given the uid.
    Owner.insnWithID(Insn, OpcPair.EncodingID);

    // Scans the segment for possibly well-specified encoding bits.
    auto [Ok, Field] = Owner.fieldFromInsn(Insn, StartBit, NumBits);

    if (Ok) {
      // The encoding bits are well-known.  Lets add the uid of the
      // instruction into the bucket keyed off the constant field value.
      LastOpcFiltered = OpcPair;
      FilteredInstructions[Field].push_back(LastOpcFiltered);
      ++NumFiltered;
    } else {
      // Some of the encoding bit(s) are unspecified.  This contributes to
      // one additional member of "Variable" instructions.
      VariableInstructions.push_back(OpcPair);
    }
  }

  assert((FilteredInstructions.size() + VariableInstructions.size() > 0) &&
         "Filter returns no instruction categories");
}

// Divides the decoding task into sub tasks and delegates them to the
// inferior FilterChooser's.
//
// A special case arises when there's only one entry in the filtered
// instructions.  In order to unambiguously decode the singleton, we need to
// match the remaining undecoded encoding bits against the singleton.
void Filter::recurse() {
  // Starts by inheriting our parent filter chooser's filter bit values.
  std::vector<BitValue> BitValueArray(Owner.FilterBitValues);

  if (!VariableInstructions.empty()) {
    // Conservatively marks each segment position as BIT_UNSET.
    for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex)
      BitValueArray[StartBit + bitIndex] = BitValue::BIT_UNSET;

    // Delegates to an inferior filter chooser for further processing on this
    // group of instructions whose segment values are variable.
    FilterChooserMap.try_emplace(
        NO_FIXED_SEGMENTS_SENTINEL,
        std::make_unique<FilterChooser>(Owner.AllInstructions,
                                        VariableInstructions, Owner.Operands,
                                        BitValueArray, Owner));
  }

  // No need to recurse for a singleton filtered instruction.
  // See also Filter::emit*().
  if (getNumFiltered() == 1) {
    assert(FilterChooserMap.size() == 1);
    return;
  }

  // Otherwise, create sub choosers.
  for (const auto &Inst : FilteredInstructions) {
    // Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
    for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex)
      BitValueArray[StartBit + bitIndex] = Inst.first & (1ULL << bitIndex)
                                               ? BitValue::BIT_TRUE
                                               : BitValue::BIT_FALSE;

    // Delegates to an inferior filter chooser for further processing on this
    // category of instructions.
    FilterChooserMap.try_emplace(
        Inst.first,
        std::make_unique<FilterChooser>(Owner.AllInstructions, Inst.second,
                                        Owner.Operands, BitValueArray, Owner));
  }
}

static void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups,
                               uint32_t DestIdx) {
  // Any NumToSkip fixups in the current scope can resolve to the
  // current location.
  for (uint32_t FixupIdx : Fixups)
    Table.patchNumToSkip(FixupIdx, DestIdx);
}

// Emit table entries to decode instructions given a segment or segments
// of bits.
void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
  assert(isUInt<8>(NumBits) && "NumBits overflowed uint8 table entry!");
  TableInfo.Table.push_back(MCD::OPC_ExtractField);

  TableInfo.Table.insertULEB128(StartBit);
  TableInfo.Table.push_back(NumBits);

  // If the NO_FIXED_SEGMENTS_SENTINEL is present, we need to add a new scope
  // for this filter. Otherwise, we can skip adding a new scope and any
  // patching added will automatically be added to the enclosing scope.

  // If NO_FIXED_SEGMENTS_SENTINEL is present, it will be last entry in
  // FilterChooserMap.

  const uint64_t LastFilter = FilterChooserMap.rbegin()->first;
  bool HasFallthrough = LastFilter == NO_FIXED_SEGMENTS_SENTINEL;
  if (HasFallthrough)
    TableInfo.FixupStack.emplace_back();

  DecoderTable &Table = TableInfo.Table;

  size_t PrevFilter = 0;
  for (const auto &[FilterVal, Delegate] : FilterChooserMap) {
    // Field value NO_FIXED_SEGMENTS_SENTINEL implies a non-empty set of
    // variable instructions. See also recurse().
    if (FilterVal == NO_FIXED_SEGMENTS_SENTINEL) {
      // Each scope should always have at least one filter value to check
      // for.
      assert(PrevFilter != 0 && "empty filter set!");
      FixupList &CurScope = TableInfo.FixupStack.back();
      // Resolve any NumToSkip fixups in the current scope.
      resolveTableFixups(Table, CurScope, Table.size());

      // Delete the scope we have added here.
      TableInfo.FixupStack.pop_back();

      PrevFilter = 0; // Don't re-process the filter's fallthrough.
    } else {
      // The last filtervalue emitted can be OPC_FilterValue if we are at
      // outermost scope.
      const uint8_t DecoderOp =
          FilterVal == LastFilter && TableInfo.isOutermostScope()
              ? MCD::OPC_FilterValueOrFail
              : MCD::OPC_FilterValue;
      Table.push_back(DecoderOp);
      Table.insertULEB128(FilterVal);
      if (DecoderOp == MCD::OPC_FilterValue) {
        // Reserve space for the NumToSkip entry. We'll backpatch the value
        // later.
        PrevFilter = Table.insertNumToSkip();
      } else {
        PrevFilter = 0;
      }
    }

    // We arrive at a category of instructions with the same segment value.
    // Now delegate to the sub filter chooser for further decodings.
    // The case may fallthrough, which happens if the remaining well-known
    // encoding bits do not match exactly.
    Delegate->emitTableEntries(TableInfo);

    // Now that we've emitted the body of the handler, update the NumToSkip
    // of the filter itself to be able to skip forward when false.
    if (PrevFilter)
      Table.patchNumToSkip(PrevFilter, Table.size());
  }

  // If there is no fallthrough and the final filter was not in the outermost
  // scope, then it must be fixed up according to the enclosing scope rather
  // than the current position.
  if (PrevFilter)
    TableInfo.FixupStack.back().push_back(PrevFilter);
}

// Returns the number of fanout produced by the filter.  More fanout implies
// the filter distinguishes more categories of instructions.
unsigned Filter::usefulness() const {
  return FilteredInstructions.size() + VariableInstructions.empty();
}

//////////////////////////////////
//                              //
// Filterchooser Implementation //
//                              //
//////////////////////////////////

// Emit the decoder state machine table. Returns a mask of MCD decoder ops
// that were emitted.
unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
                                   DecoderTable &Table, unsigned BitWidth,
                                   StringRef Namespace,
                                   const EncodingIDsVec &EncodingIDs) const {
  // We'll need to be able to map from a decoded opcode into the corresponding
  // EncodingID for this specific combination of BitWidth and Namespace. This
  // is used below to index into NumberedEncodings.
  DenseMap<unsigned, unsigned> OpcodeToEncodingID;
  OpcodeToEncodingID.reserve(EncodingIDs.size());
  for (const auto &EI : EncodingIDs)
    OpcodeToEncodingID[EI.Opcode] = EI.EncodingID;

  OS << "static const uint8_t DecoderTable" << Namespace << BitWidth
     << "[] = {\n";

  // Emit ULEB128 encoded value to OS, returning the number of bytes emitted.
  auto emitULEB128 = [](DecoderTable::const_iterator &I,
                        formatted_raw_ostream &OS) {
    while (*I >= 128)
      OS << (unsigned)*I++ << ", ";
    OS << (unsigned)*I++ << ", ";
  };

  // Emit `getNumToSkipInBytes()`-byte numtoskip value to OS, returning the
  // NumToSkip value.
  auto emitNumToSkip = [](DecoderTable::const_iterator &I,
                          formatted_raw_ostream &OS) {
    uint8_t Byte = *I++;
    uint32_t NumToSkip = Byte;
    OS << (unsigned)Byte << ", ";
    Byte = *I++;
    OS << (unsigned)Byte << ", ";
    NumToSkip |= Byte << 8;
    if (getNumToSkipInBytes() == 3) {
      Byte = *I++;
      OS << (unsigned)(Byte) << ", ";
      NumToSkip |= Byte << 16;
    }
    return NumToSkip;
  };

  // FIXME: We may be able to use the NumToSkip values to recover
  // appropriate indentation levels.
  DecoderTable::const_iterator I = Table.begin();
  DecoderTable::const_iterator E = Table.end();
  const uint8_t *const EndPtr = Table.data() + Table.size();

  auto emitNumToSkipComment = [&](uint32_t NumToSkip, bool InComment = false) {
    uint32_t Index = ((I - Table.begin()) + NumToSkip);
    OS << (InComment ? ", " : "// ");
    OS << "Skip to: " << Index;
    if (*(I + NumToSkip) == MCD::OPC_Fail)
      OS << " (Fail)";
  };

  unsigned OpcodeMask = 0;

  while (I != E) {
    assert(I < E && "incomplete decode table entry!");

    uint64_t Pos = I - Table.begin();
    OS << "/* " << Pos << " */";
    OS.PadToColumn(12);

    const uint8_t DecoderOp = *I++;
    OpcodeMask |= (1 << DecoderOp);
    switch (DecoderOp) {
    default:
      PrintFatalError("Invalid decode table opcode: " + Twine((int)DecoderOp) +
                      " at index " + Twine(Pos));
    case MCD::OPC_ExtractField: {
      OS << "  MCD::OPC_ExtractField, ";

      // ULEB128 encoded start value.
      const char *ErrMsg = nullptr;
      unsigned Start = decodeULEB128(&*I, nullptr, EndPtr, &ErrMsg);
      assert(ErrMsg == nullptr && "ULEB128 value too large!");
      emitULEB128(I, OS);

      unsigned Len = *I++;
      OS << Len << ",  // Inst{";
      if (Len > 1)
        OS << (Start + Len - 1) << "-";
      OS << Start << "} ...\n";
      break;
    }
    case MCD::OPC_FilterValue:
    case MCD::OPC_FilterValueOrFail: {
      bool IsFail = DecoderOp == MCD::OPC_FilterValueOrFail;
      OS << "  MCD::OPC_FilterValue" << (IsFail ? "OrFail, " : ", ");
      // The filter value is ULEB128 encoded.
      emitULEB128(I, OS);

      if (!IsFail) {
        uint32_t NumToSkip = emitNumToSkip(I, OS);
        emitNumToSkipComment(NumToSkip);
      }
      OS << '\n';
      break;
    }
    case MCD::OPC_CheckField:
    case MCD::OPC_CheckFieldOrFail: {
      bool IsFail = DecoderOp == MCD::OPC_CheckFieldOrFail;
      OS << "  MCD::OPC_CheckField" << (IsFail ? "OrFail, " : ", ");
      // ULEB128 encoded start value.
      emitULEB128(I, OS);
      // 8-bit length.
      unsigned Len = *I++;
      OS << Len << ", ";
      // ULEB128 encoded field value.
      emitULEB128(I, OS);

      if (!IsFail) {
        uint32_t NumToSkip = emitNumToSkip(I, OS);
        emitNumToSkipComment(NumToSkip);
      }
      OS << '\n';
      break;
    }
    case MCD::OPC_CheckPredicate:
    case MCD::OPC_CheckPredicateOrFail: {
      bool IsFail = DecoderOp == MCD::OPC_CheckPredicateOrFail;

      OS << "  MCD::OPC_CheckPredicate" << (IsFail ? "OrFail, " : ", ");
      emitULEB128(I, OS);

      if (!IsFail) {
        uint32_t NumToSkip = emitNumToSkip(I, OS);
        emitNumToSkipComment(NumToSkip);
      }
      OS << '\n';
      break;
    }
    case MCD::OPC_Decode:
    case MCD::OPC_TryDecode:
    case MCD::OPC_TryDecodeOrFail: {
      bool IsFail = DecoderOp == MCD::OPC_TryDecodeOrFail;
      bool IsTry = DecoderOp == MCD::OPC_TryDecode || IsFail;
      // Decode the Opcode value.
      const char *ErrMsg = nullptr;
      unsigned Opc = decodeULEB128(&*I, nullptr, EndPtr, &ErrMsg);
      assert(ErrMsg == nullptr && "ULEB128 value too large!");

      OS << "  MCD::OPC_" << (IsTry ? "Try" : "") << "Decode"
         << (IsFail ? "OrFail, " : ", ");
      emitULEB128(I, OS);

      // Decoder index.
      unsigned DecodeIdx = decodeULEB128(&*I, nullptr, EndPtr, &ErrMsg);
      assert(ErrMsg == nullptr && "ULEB128 value too large!");
      emitULEB128(I, OS);

      auto EncI = OpcodeToEncodingID.find(Opc);
      assert(EncI != OpcodeToEncodingID.end() && "no encoding entry");
      auto EncodingID = EncI->second;

      if (!IsTry) {
        OS << "// Opcode: " << NumberedEncodings[EncodingID]
           << ", DecodeIdx: " << DecodeIdx << '\n';
        break;
      }

      // Fallthrough for OPC_TryDecode.
      if (!IsFail) {
        uint32_t NumToSkip = emitNumToSkip(I, OS);
        OS << "// Opcode: " << NumberedEncodings[EncodingID]
           << ", DecodeIdx: " << DecodeIdx;
        emitNumToSkipComment(NumToSkip, /*InComment=*/true);
      }
      OS << '\n';
      break;
    }
    case MCD::OPC_SoftFail: {
      OS << "  MCD::OPC_SoftFail, ";
      // Decode the positive mask.
      const char *ErrMsg = nullptr;
      uint64_t PositiveMask = decodeULEB128(&*I, nullptr, EndPtr, &ErrMsg);
      assert(ErrMsg == nullptr && "ULEB128 value too large!");
      emitULEB128(I, OS);

      // Decode the negative mask.
      uint64_t NegativeMask = decodeULEB128(&*I, nullptr, EndPtr, &ErrMsg);
      assert(ErrMsg == nullptr && "ULEB128 value too large!");
      emitULEB128(I, OS);
      OS << "// +ve mask: 0x";
      OS.write_hex(PositiveMask);
      OS << ", -ve mask: 0x";
      OS.write_hex(NegativeMask);
      OS << '\n';
      break;
    }
    case MCD::OPC_Fail:
      OS << "  MCD::OPC_Fail,\n";
      break;
    }
  }
  OS << "  0\n";
  OS << "};\n\n";

  return OpcodeMask;
}

void DecoderEmitter::emitInstrLenTable(formatted_raw_ostream &OS,
                                       ArrayRef<unsigned> InstrLen) const {
  OS << "static const uint8_t InstrLenTable[] = {\n";
  for (unsigned Len : InstrLen)
    OS << Len << ",\n";
  OS << "};\n\n";
}

void DecoderEmitter::emitPredicateFunction(formatted_raw_ostream &OS,
                                           PredicateSet &Predicates) const {
  // The predicate function is just a big switch statement based on the
  // input predicate index.
  OS << "static bool checkDecoderPredicate(unsigned Idx, const FeatureBitset "
        "&Bits) {\n";
  OS << "  switch (Idx) {\n";
  OS << "  default: llvm_unreachable(\"Invalid index!\");\n";
  for (const auto &[Index, Predicate] : enumerate(Predicates)) {
    OS << "  case " << Index << ":\n";
    OS << "    return (" << Predicate << ");\n";
  }
  OS << "  }\n";
  OS << "}\n\n";
}

void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
                                         DecoderSet &Decoders) const {
  // The decoder function is just a big switch statement or a table of function
  // pointers based on the input decoder index.

  // TODO: When InsnType is large, using uint64_t limits all fields to 64 bits
  // It would be better for emitBinaryParser to use a 64-bit tmp whenever
  // possible but fall back to an InsnType-sized tmp for truly large fields.
  StringRef TmpTypeDecl =
      "using TmpType = std::conditional_t<std::is_integral<InsnType>::value, "
      "InsnType, uint64_t>;\n";
  StringRef DecodeParams =
      "DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const "
      "MCDisassembler *Decoder, bool &DecodeComplete";

  if (UseFnTableInDecodeToMCInst) {
    // Emit a function for each case first.
    for (const auto &[Index, Decoder] : enumerate(Decoders)) {
      OS << "template <typename InsnType>\n";
      OS << "DecodeStatus decodeFn" << Index << "(" << DecodeParams << ") {\n";
      OS << "  " << TmpTypeDecl;
      OS << "  [[maybe_unused]] TmpType tmp;\n";
      OS << Decoder;
      OS << "  return S;\n";
      OS << "}\n\n";
    }
  }

  OS << "// Handling " << Decoders.size() << " cases.\n";
  OS << "template <typename InsnType>\n";
  OS << "static DecodeStatus decodeToMCInst(unsigned Idx, " << DecodeParams
     << ") {\n";
  OS << "  DecodeComplete = true;\n";

  if (UseFnTableInDecodeToMCInst) {
    // Build a table of function pointers.
    OS << "  using DecodeFnTy = DecodeStatus (*)(" << DecodeParams << ");\n";
    OS << "  static constexpr DecodeFnTy decodeFnTable[] = {\n";
    for (size_t Index : llvm::seq(Decoders.size()))
      OS << "    decodeFn" << Index << ",\n";
    OS << "  };\n";
    OS << "  if (Idx >= " << Decoders.size() << ")\n";
    OS << "    llvm_unreachable(\"Invalid index!\");\n";
    OS << "  return decodeFnTable[Idx](S, insn, MI, Address, Decoder, "
          "DecodeComplete);\n";
  } else {
    OS << "  " << TmpTypeDecl;
    OS << "  TmpType tmp;\n";
    OS << "  switch (Idx) {\n";
    OS << "  default: llvm_unreachable(\"Invalid index!\");\n";
    for (const auto &[Index, Decoder] : enumerate(Decoders)) {
      OS << "  case " << Index << ":\n";
      OS << Decoder;
      OS << "    return S;\n";
    }
    OS << "  }\n";
  }
  OS << "}\n";
}

// Populates the field of the insn given the start position and the number of
// consecutive bits to scan for.
//
// Returns a pair of values (indicator, field), where the indicator is false
// if there exists any uninitialized bit value in the range and true if all
// bits are well-known. The second value is the potentially populated field.
std::pair<bool, uint64_t> FilterChooser::fieldFromInsn(const insn_t &Insn,
                                                       unsigned StartBit,
                                                       unsigned NumBits) const {
  uint64_t Field = 0;

  for (unsigned i = 0; i < NumBits; ++i) {
    if (Insn[StartBit + i] == BitValue::BIT_UNSET)
      return {false, Field};

    if (Insn[StartBit + i] == BitValue::BIT_TRUE)
      Field = Field | (1ULL << i);
  }

  return {true, Field};
}

/// dumpFilterArray - dumpFilterArray prints out debugging info for the given
/// filter array as a series of chars.
void FilterChooser::dumpFilterArray(raw_ostream &OS,
                                    ArrayRef<BitValue> Filter) const {
  for (unsigned bitIndex = BitWidth; bitIndex > 0; bitIndex--)
    OS << Filter[bitIndex - 1];
}

/// dumpStack - dumpStack traverses the filter chooser chain and calls
/// dumpFilterArray on each filter chooser up to the top level one.
void FilterChooser::dumpStack(raw_ostream &OS, const char *prefix) const {
  const FilterChooser *current = this;

  while (current) {
    OS << prefix;
    dumpFilterArray(OS, current->FilterBitValues);
    OS << '\n';
    current = current->Parent;
  }
}

// Calculates the island(s) needed to decode the instruction.
// This returns a list of undecoded bits of an instructions, for example,
// Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
// decoded bits in order to verify that the instruction matches the Opcode.
unsigned FilterChooser::getIslands(std::vector<Island> &Islands,
                                   const insn_t &Insn) const {
  uint64_t FieldVal;
  unsigned StartBit;

  // 0: Init
  // 1: Water (the bit value does not affect decoding)
  // 2: Island (well-known bit value needed for decoding)
  unsigned State = 0;

  for (unsigned i = 0; i < BitWidth; ++i) {
    std::optional<uint64_t> Val = Insn[i].getValue();
    bool Filtered = PositionFiltered(i);
    switch (State) {
    default:
      llvm_unreachable("Unreachable code!");
    case 0:
    case 1:
      if (Filtered || !Val) {
        State = 1; // Still in Water
      } else {
        State = 2; // Into the Island
        StartBit = i;
        FieldVal = *Val;
      }
      break;
    case 2:
      if (Filtered || !Val) {
        State = 1; // Into the Water
        Islands.push_back({StartBit, i - StartBit, FieldVal});
      } else {
        State = 2; // Still in Island
        FieldVal |= *Val << (i - StartBit);
      }
      break;
    }
  }
  // If we are still in Island after the loop, do some housekeeping.
  if (State == 2)
    Islands.push_back({StartBit, BitWidth - StartBit, FieldVal});

  return Islands.size();
}

bool FilterChooser::emitBinaryParser(raw_ostream &OS, indent Indent,
                                     const OperandInfo &OpInfo) const {
  const std::string &Decoder = OpInfo.Decoder;

  bool UseInsertBits = OpInfo.numFields() != 1 || OpInfo.InitValue != 0;

  if (UseInsertBits) {
    OS << Indent << "tmp = 0x";
    OS.write_hex(OpInfo.InitValue);
    OS << ";\n";
  }

  for (const EncodingField &EF : OpInfo) {
    OS << Indent;
    if (UseInsertBits)
      OS << "insertBits(tmp, ";
    else
      OS << "tmp = ";
    OS << "fieldFromInstruction(insn, " << EF.Base << ", " << EF.Width << ')';
    if (UseInsertBits)
      OS << ", " << EF.Offset << ", " << EF.Width << ')';
    else if (EF.Offset != 0)
      OS << " << " << EF.Offset;
    OS << ";\n";
  }

  bool OpHasCompleteDecoder;
  if (!Decoder.empty()) {
    OpHasCompleteDecoder = OpInfo.HasCompleteDecoder;
    OS << Indent << "if (!Check(S, " << Decoder
       << "(MI, tmp, Address, Decoder))) { "
       << (OpHasCompleteDecoder ? "" : "DecodeComplete = false; ")
       << "return MCDisassembler::Fail; }\n";
  } else {
    OpHasCompleteDecoder = true;
    OS << Indent << "MI.addOperand(MCOperand::createImm(tmp));\n";
  }
  return OpHasCompleteDecoder;
}

bool FilterChooser::emitDecoder(raw_ostream &OS, indent Indent,
                                unsigned Opc) const {
  bool HasCompleteDecoder = true;

  for (const auto &Op : Operands.find(Opc)->second) {
    // If a custom instruction decoder was specified, use that.
    if (Op.numFields() == 0 && !Op.Decoder.empty()) {
      HasCompleteDecoder = Op.HasCompleteDecoder;
      OS << Indent << "if (!Check(S, " << Op.Decoder
         << "(MI, insn, Address, Decoder))) { "
         << (HasCompleteDecoder ? "" : "DecodeComplete = false; ")
         << "return MCDisassembler::Fail; }\n";
      break;
    }

    HasCompleteDecoder &= emitBinaryParser(OS, Indent, Op);
  }
  return HasCompleteDecoder;
}

std::pair<unsigned, bool> FilterChooser::getDecoderIndex(DecoderSet &Decoders,
                                                         unsigned Opc) const {
  // Build up the predicate string.
  SmallString<256> Decoder;
  // FIXME: emitDecoder() function can take a buffer directly rather than
  // a stream.
  raw_svector_ostream S(Decoder);
  indent Indent(UseFnTableInDecodeToMCInst ? 2 : 4);
  bool HasCompleteDecoder = emitDecoder(S, Indent, Opc);

  // Using the full decoder string as the key value here is a bit
  // heavyweight, but is effective. If the string comparisons become a
  // performance concern, we can implement a mangling of the predicate
  // data easily enough with a map back to the actual string. That's
  // overkill for now, though.

  // Make sure the predicate is in the table.
  Decoders.insert(CachedHashString(Decoder));
  // Now figure out the index for when we write out the table.
  DecoderSet::const_iterator P = find(Decoders, Decoder.str());
  return {(unsigned)(P - Decoders.begin()), HasCompleteDecoder};
}

// If ParenIfBinOp is true, print a surrounding () if Val uses && or ||.
bool FilterChooser::emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
                                          raw_ostream &OS) const {
  if (const auto *D = dyn_cast<DefInit>(&Val)) {
    if (!D->getDef()->isSubClassOf("SubtargetFeature"))
      return true;
    OS << "Bits[" << Emitter->PredicateNamespace << "::" << D->getAsString()
       << "]";
    return false;
  }
  if (const auto *D = dyn_cast<DagInit>(&Val)) {
    std::string Op = D->getOperator()->getAsString();
    if (Op == "not" && D->getNumArgs() == 1) {
      OS << '!';
      return emitPredicateMatchAux(*D->getArg(0), true, OS);
    }
    if ((Op == "any_of" || Op == "all_of") && D->getNumArgs() > 0) {
      bool Paren = D->getNumArgs() > 1 && std::exchange(ParenIfBinOp, true);
      if (Paren)
        OS << '(';
      ListSeparator LS(Op == "any_of" ? " || " : " && ");
      for (auto *Arg : D->getArgs()) {
        OS << LS;
        if (emitPredicateMatchAux(*Arg, ParenIfBinOp, OS))
          return true;
      }
      if (Paren)
        OS << ')';
      return false;
    }
  }
  return true;
}

bool FilterChooser::emitPredicateMatch(raw_ostream &OS, unsigned Opc) const {
  const ListInit *Predicates =
      AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
  bool IsFirstEmission = true;
  for (unsigned i = 0; i < Predicates->size(); ++i) {
    const Record *Pred = Predicates->getElementAsRecord(i);
    if (!Pred->getValue("AssemblerMatcherPredicate"))
      continue;

    if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
      continue;

    if (!IsFirstEmission)
      OS << " && ";
    if (emitPredicateMatchAux(*Pred->getValueAsDag("AssemblerCondDag"),
                              Predicates->size() > 1, OS))
      PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
    IsFirstEmission = false;
  }
  return !Predicates->empty();
}

bool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const {
  const ListInit *Predicates =
      AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
  for (unsigned i = 0; i < Predicates->size(); ++i) {
    const Record *Pred = Predicates->getElementAsRecord(i);
    if (!Pred->getValue("AssemblerMatcherPredicate"))
      continue;

    if (isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
      return true;
  }
  return false;
}

unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo,
                                          StringRef Predicate) const {
  // Using the full predicate string as the key value here is a bit
  // heavyweight, but is effective. If the string comparisons become a
  // performance concern, we can implement a mangling of the predicate
  // data easily enough with a map back to the actual string. That's
  // overkill for now, though.

  // Make sure the predicate is in the table.
  TableInfo.Predicates.insert(CachedHashString(Predicate));
  // Now figure out the index for when we write out the table.
  PredicateSet::const_iterator P = find(TableInfo.Predicates, Predicate);
  return (unsigned)(P - TableInfo.Predicates.begin());
}

void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo,
                                            unsigned Opc) const {
  if (!doesOpcodeNeedPredicate(Opc))
    return;

  // Build up the predicate string.
  SmallString<256> Predicate;
  // FIXME: emitPredicateMatch() functions can take a buffer directly rather
  // than a stream.
  raw_svector_ostream PS(Predicate);
  emitPredicateMatch(PS, Opc);

  // Figure out the index into the predicate table for the predicate just
  // computed.
  unsigned PIdx = getPredicateIndex(TableInfo, PS.str());

  const uint8_t DecoderOp = TableInfo.isOutermostScope()
                                ? MCD::OPC_CheckPredicateOrFail
                                : MCD::OPC_CheckPredicate;
  TableInfo.Table.push_back(DecoderOp);
  TableInfo.Table.insertULEB128(PIdx);

  if (DecoderOp == MCD::OPC_CheckPredicate) {
    // Push location for NumToSkip backpatching.
    TableInfo.FixupStack.back().push_back(TableInfo.Table.insertNumToSkip());
  }
}

void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
                                           unsigned Opc) const {
  const Record *EncodingDef = AllInstructions[Opc].EncodingDef;
  const RecordVal *RV = EncodingDef->getValue("SoftFail");
  const BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;

  if (!SFBits)
    return;
  const BitsInit *InstBits = EncodingDef->getValueAsBitsInit("Inst");

  APInt PositiveMask(BitWidth, 0ULL);
  APInt NegativeMask(BitWidth, 0ULL);
  for (unsigned i = 0; i < BitWidth; ++i) {
    BitValue B(*SFBits, i);
    BitValue IB(*InstBits, i);

    if (B != BitValue::BIT_TRUE)
      continue;

    if (IB == BitValue::BIT_FALSE) {
      // The bit is meant to be false, so emit a check to see if it is true.
      PositiveMask.setBit(i);
    } else if (IB == BitValue::BIT_TRUE) {
      // The bit is meant to be true, so emit a check to see if it is false.
      NegativeMask.setBit(i);
    } else {
      // The bit is not set; this must be an error!
      errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in "
             << AllInstructions[Opc] << " is set but Inst{" << i
             << "} is unset!\n"
             << "  - You can only mark a bit as SoftFail if it is fully defined"
             << " (1/0 - not '?') in Inst\n";
      return;
    }
  }

  bool NeedPositiveMask = PositiveMask.getBoolValue();
  bool NeedNegativeMask = NegativeMask.getBoolValue();

  if (!NeedPositiveMask && !NeedNegativeMask)
    return;

  TableInfo.Table.push_back(MCD::OPC_SoftFail);
  TableInfo.Table.insertULEB128(PositiveMask.getZExtValue());
  TableInfo.Table.insertULEB128(NegativeMask.getZExtValue());
}

// Emits table entries to decode the singleton.
void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
                                            EncodingIDAndOpcode Opc) const {
  std::vector<Island> Islands;
  insn_t Insn;
  insnWithID(Insn, Opc.EncodingID);

  // Look for islands of undecoded bits of the singleton.
  getIslands(Islands, Insn);

  // Emit the predicate table entry if one is needed.
  emitPredicateTableEntry(TableInfo, Opc.EncodingID);

  // Check any additional encoding fields needed.
  for (const Island &Ilnd : reverse(Islands)) {
    unsigned NumBits = Ilnd.NumBits;
    assert(isUInt<8>(NumBits) && "NumBits overflowed uint8 table entry!");
    const uint8_t DecoderOp = TableInfo.isOutermostScope()
                                  ? MCD::OPC_CheckFieldOrFail
                                  : MCD::OPC_CheckField;
    TableInfo.Table.push_back(DecoderOp);

    TableInfo.Table.insertULEB128(Ilnd.StartBit);
    TableInfo.Table.push_back(NumBits);
    TableInfo.Table.insertULEB128(Ilnd.FieldVal);

    if (DecoderOp == MCD::OPC_CheckField) {
      // Allocate space in the table for fixup so all our relative position
      // calculations work OK even before we fully resolve the real value here.

      // Push location for NumToSkip backpatching.
      TableInfo.FixupStack.back().push_back(TableInfo.Table.insertNumToSkip());
    }
  }

  // Check for soft failure of the match.
  emitSoftFailTableEntry(TableInfo, Opc.EncodingID);

  auto [DIdx, HasCompleteDecoder] =
      getDecoderIndex(TableInfo.Decoders, Opc.EncodingID);

  // Produce OPC_Decode or OPC_TryDecode opcode based on the information
  // whether the instruction decoder is complete or not. If it is complete
  // then it handles all possible values of remaining variable/unfiltered bits
  // and for any value can determine if the bitpattern is a valid instruction
  // or not. This means OPC_Decode will be the final step in the decoding
  // process. If it is not complete, then the Fail return code from the
  // decoder method indicates that additional processing should be done to see
  // if there is any other instruction that also matches the bitpattern and
  // can decode it.
  const uint8_t DecoderOp = HasCompleteDecoder ? MCD::OPC_Decode
                                               : (TableInfo.isOutermostScope()
                                                      ? MCD::OPC_TryDecodeOrFail
                                                      : MCD::OPC_TryDecode);
  TableInfo.Table.push_back(DecoderOp);
  NumEncodingsSupported++;
  TableInfo.Table.insertULEB128(Opc.Opcode);
  TableInfo.Table.insertULEB128(DIdx);

  if (DecoderOp == MCD::OPC_TryDecode) {
    // Push location for NumToSkip backpatching.
    TableInfo.FixupStack.back().push_back(TableInfo.Table.insertNumToSkip());
  }
}

// Emits table entries to decode the singleton, and then to decode the rest.
void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
                                            const Filter &Best) const {
  EncodingIDAndOpcode Opc = Best.getSingletonOpc();

  // complex singletons need predicate checks from the first singleton
  // to refer forward to the variable filterchooser that follows.
  TableInfo.FixupStack.emplace_back();

  emitSingletonTableEntry(TableInfo, Opc);

  resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
                     TableInfo.Table.size());
  TableInfo.FixupStack.pop_back();

  Best.getVariableFC().emitTableEntries(TableInfo);
}

// Assign a single filter and run with it.  Top level API client can initialize
// with a single filter to start the filtering process.
void FilterChooser::runSingleFilter(unsigned startBit, unsigned numBit,
                                    bool mixed) {
  Filters.clear();
  Filters.emplace_back(*this, startBit, numBit, true);
  BestIndex = 0; // Sole Filter instance to choose from.
  bestFilter().recurse();
}

// reportRegion is a helper function for filterProcessor to mark a region as
// eligible for use as a filter region.
void FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit,
                                 unsigned BitIndex, bool AllowMixed) {
  if (RA == ATTR_MIXED && AllowMixed)
    Filters.emplace_back(*this, StartBit, BitIndex - StartBit, true);
  else if (RA == ATTR_ALL_SET && !AllowMixed)
    Filters.emplace_back(*this, StartBit, BitIndex - StartBit, false);
}

// FilterProcessor scans the well-known encoding bits of the instructions and
// builds up a list of candidate filters.  It chooses the best filter and
// recursively descends down the decoding tree.
bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
  Filters.clear();
  BestIndex = -1;
  unsigned numInstructions = Opcodes.size();

  assert(numInstructions && "Filter created with no instructions");

  // No further filtering is necessary.
  if (numInstructions == 1)
    return true;

  // Heuristics.  See also doFilter()'s "Heuristics" comment when num of
  // instructions is 3.
  if (AllowMixed && !Greedy) {
    assert(numInstructions == 3);

    for (const auto &Opcode : Opcodes) {
      std::vector<Island> Islands;
      insn_t Insn;

      insnWithID(Insn, Opcode.EncodingID);

      // Look for islands of undecoded bits of any instruction.
      if (getIslands(Islands, Insn) > 0) {
        // Found an instruction with island(s).  Now just assign a filter.
        runSingleFilter(Islands[0].StartBit, Islands[0].NumBits, true);
        return true;
      }
    }
  }

  unsigned BitIndex;

  // We maintain BIT_WIDTH copies of the bitAttrs automaton.
  // The automaton consumes the corresponding bit from each
  // instruction.
  //
  //   Input symbols: 0, 1, and _ (unset).
  //   States:        NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED.
  //   Initial state: NONE.
  //
  // (NONE) ------- [01] -> (ALL_SET)
  // (NONE) ------- _ ----> (ALL_UNSET)
  // (ALL_SET) ---- [01] -> (ALL_SET)
  // (ALL_SET) ---- _ ----> (MIXED)
  // (ALL_UNSET) -- [01] -> (MIXED)
  // (ALL_UNSET) -- _ ----> (ALL_UNSET)
  // (MIXED) ------ . ----> (MIXED)
  // (FILTERED)---- . ----> (FILTERED)

  std::vector<bitAttr_t> bitAttrs(BitWidth, ATTR_NONE);

  // FILTERED bit positions provide no entropy and are not worthy of pursuing.
  // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position.
  for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex)
    if (FilterBitValues[BitIndex].isSet())
      bitAttrs[BitIndex] = ATTR_FILTERED;

  for (const auto &OpcPair : Opcodes) {
    insn_t insn;

    insnWithID(insn, OpcPair.EncodingID);

    for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
      switch (bitAttrs[BitIndex]) {
      case ATTR_NONE:
        if (insn[BitIndex] == BitValue::BIT_UNSET)
          bitAttrs[BitIndex] = ATTR_ALL_UNSET;
        else
          bitAttrs[BitIndex] = ATTR_ALL_SET;
        break;
      case ATTR_ALL_SET:
        if (insn[BitIndex] == BitValue::BIT_UNSET)
          bitAttrs[BitIndex] = ATTR_MIXED;
        break;
      case ATTR_ALL_UNSET:
        if (insn[BitIndex] != BitValue::BIT_UNSET)
          bitAttrs[BitIndex] = ATTR_MIXED;
        break;
      case ATTR_MIXED:
      case ATTR_FILTERED:
        break;
      }
    }
  }

  // The regionAttr automaton consumes the bitAttrs automatons' state,
  // lowest-to-highest.
  //
  //   Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed)
  //   States:        NONE, ALL_SET, MIXED
  //   Initial state: NONE
  //
  // (NONE) ----- F --> (NONE)
  // (NONE) ----- S --> (ALL_SET)     ; and set region start
  // (NONE) ----- U --> (NONE)
  // (NONE) ----- M --> (MIXED)       ; and set region start
  // (ALL_SET) -- F --> (NONE)        ; and report an ALL_SET region
  // (ALL_SET) -- S --> (ALL_SET)
  // (ALL_SET) -- U --> (NONE)        ; and report an ALL_SET region
  // (ALL_SET) -- M --> (MIXED)       ; and report an ALL_SET region
  // (MIXED) ---- F --> (NONE)        ; and report a MIXED region
  // (MIXED) ---- S --> (ALL_SET)     ; and report a MIXED region
  // (MIXED) ---- U --> (NONE)        ; and report a MIXED region
  // (MIXED) ---- M --> (MIXED)

  bitAttr_t RA = ATTR_NONE;
  unsigned StartBit = 0;

  for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
    bitAttr_t bitAttr = bitAttrs[BitIndex];

    assert(bitAttr != ATTR_NONE && "Bit without attributes");

    switch (RA) {
    case ATTR_NONE:
      switch (bitAttr) {
      case ATTR_FILTERED:
        break;
      case ATTR_ALL_SET:
        StartBit = BitIndex;
        RA = ATTR_ALL_SET;
        break;
      case ATTR_ALL_UNSET:
        break;
      case ATTR_MIXED:
        StartBit = BitIndex;
        RA = ATTR_MIXED;
        break;
      default:
        llvm_unreachable("Unexpected bitAttr!");
      }
      break;
    case ATTR_ALL_SET:
      switch (bitAttr) {
      case ATTR_FILTERED:
        reportRegion(RA, StartBit, BitIndex, AllowMixed);
        RA = ATTR_NONE;
        break;
      case ATTR_ALL_SET:
        break;
      case ATTR_ALL_UNSET:
        reportRegion(RA, StartBit, BitIndex, AllowMixed);
        RA = ATTR_NONE;
        break;
      case ATTR_MIXED:
        reportRegion(RA, StartBit, BitIndex, AllowMixed);
        StartBit = BitIndex;
        RA = ATTR_MIXED;
        break;
      default:
        llvm_unreachable("Unexpected bitAttr!");
      }
      break;
    case ATTR_MIXED:
      switch (bitAttr) {
      case ATTR_FILTERED:
        reportRegion(RA, StartBit, BitIndex, AllowMixed);
        StartBit = BitIndex;
        RA = ATTR_NONE;
        break;
      case ATTR_ALL_SET:
        reportRegion(RA, StartBit, BitIndex, AllowMixed);
        StartBit = BitIndex;
        RA = ATTR_ALL_SET;
        break;
      case ATTR_ALL_UNSET:
        reportRegion(RA, StartBit, BitIndex, AllowMixed);
        RA = ATTR_NONE;
        break;
      case ATTR_MIXED:
        break;
      default:
        llvm_unreachable("Unexpected bitAttr!");
      }
      break;
    case ATTR_ALL_UNSET:
      llvm_unreachable("regionAttr state machine has no ATTR_UNSET state");
    case ATTR_FILTERED:
      llvm_unreachable("regionAttr state machine has no ATTR_FILTERED state");
    }
  }

  // At the end, if we're still in ALL_SET or MIXED states, report a region
  switch (RA) {
  case ATTR_NONE:
    break;
  case ATTR_FILTERED:
    break;
  case ATTR_ALL_SET:
    reportRegion(RA, StartBit, BitIndex, AllowMixed);
    break;
  case ATTR_ALL_UNSET:
    break;
  case ATTR_MIXED:
    reportRegion(RA, StartBit, BitIndex, AllowMixed);
    break;
  }

  // We have finished with the filter processings.  Now it's time to choose
  // the best performing filter.
  BestIndex = 0;
  bool AllUseless = true;
  unsigned BestScore = 0;

  for (const auto &[Idx, Filter] : enumerate(Filters)) {
    unsigned Usefulness = Filter.usefulness();

    if (Usefulness)
      AllUseless = false;

    if (Usefulness > BestScore) {
      BestIndex = Idx;
      BestScore = Usefulness;
    }
  }

  if (!AllUseless)
    bestFilter().recurse();

  return !AllUseless;
} // end of FilterChooser::filterProcessor(bool)

// Decides on the best configuration of filter(s) to use in order to decode
// the instructions.  A conflict of instructions may occur, in which case we
// dump the conflict set to the standard error.
void FilterChooser::doFilter() {
  unsigned Num = Opcodes.size();
  assert(Num && "FilterChooser created with no instructions");

  // Try regions of consecutive known bit values first.
  if (filterProcessor(false))
    return;

  // Then regions of mixed bits (both known and unitialized bit values allowed).
  if (filterProcessor(true))
    return;

  // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where
  // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a
  // well-known encoding pattern.  In such case, we backtrack and scan for the
  // the very first consecutive ATTR_ALL_SET region and assign a filter to it.
  if (Num == 3 && filterProcessor(true, false))
    return;

  // If we come to here, the instruction decoding has failed.
  // Set the BestIndex to -1 to indicate so.
  BestIndex = -1;
}

// emitTableEntries - Emit state machine entries to decode our share of
// instructions.
void FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const {
  if (Opcodes.size() == 1) {
    // There is only one instruction in the set, which is great!
    // Call emitSingletonDecoder() to see whether there are any remaining
    // encodings bits.
    emitSingletonTableEntry(TableInfo, Opcodes[0]);
    return;
  }

  // Choose the best filter to do the decodings!
  if (BestIndex != -1) {
    const Filter &Best = Filters[BestIndex];
    if (Best.getNumFiltered() == 1)
      emitSingletonTableEntry(TableInfo, Best);
    else
      Best.emitTableEntry(TableInfo);
    return;
  }

  // We don't know how to decode these instructions! Dump the
  // conflict set and bail.

  // Print out useful conflict information for postmortem analysis.
  errs() << "Decoding Conflict:\n";

  dumpStack(errs(), "\t\t");

  for (auto Opcode : Opcodes) {
    const EncodingAndInst &Enc = AllInstructions[Opcode.EncodingID];
    errs() << '\t' << Enc << ' ';
    dumpBits(errs(), getBitsField(*Enc.EncodingDef, "Inst"));
    errs() << '\n';
  }
  PrintFatalError("Decoding conflict encountered");
}

static std::string findOperandDecoderMethod(const Record *Record) {
  std::string Decoder;

  const RecordVal *DecoderString = Record->getValue("DecoderMethod");
  const StringInit *String =
      DecoderString ? dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
  if (String) {
    Decoder = String->getValue().str();
    if (!Decoder.empty())
      return Decoder;
  }

  if (Record->isSubClassOf("RegisterOperand"))
    // Allows use of a DecoderMethod in referenced RegisterClass if set.
    return findOperandDecoderMethod(Record->getValueAsDef("RegClass"));

  if (Record->isSubClassOf("RegisterClass")) {
    Decoder = "Decode" + Record->getName().str() + "RegisterClass";
  } else if (Record->isSubClassOf("PointerLikeRegClass")) {
    Decoder = "DecodePointerLikeRegClass" +
              utostr(Record->getValueAsInt("RegClassKind"));
  }

  return Decoder;
}

OperandInfo getOpInfo(const Record *TypeRecord) {
  const RecordVal *HasCompleteDecoderVal =
      TypeRecord->getValue("hasCompleteDecoder");
  const BitInit *HasCompleteDecoderBit =
      HasCompleteDecoderVal
          ? dyn_cast<BitInit>(HasCompleteDecoderVal->getValue())
          : nullptr;
  bool HasCompleteDecoder =
      HasCompleteDecoderBit ? HasCompleteDecoderBit->getValue() : true;

  return OperandInfo(findOperandDecoderMethod(TypeRecord), HasCompleteDecoder);
}

static void parseVarLenInstOperand(const Record &Def,
                                   std::vector<OperandInfo> &Operands,
                                   const CodeGenInstruction &CGI) {

  const RecordVal *RV = Def.getValue("Inst");
  VarLenInst VLI(cast<DagInit>(RV->getValue()), RV);
  SmallVector<int> TiedTo;

  for (const auto &[Idx, Op] : enumerate(CGI.Operands)) {
    if (Op.MIOperandInfo && Op.MIOperandInfo->getNumArgs() > 0)
      for (auto *Arg : Op.MIOperandInfo->getArgs())
        Operands.push_back(getOpInfo(cast<DefInit>(Arg)->getDef()));
    else
      Operands.push_back(getOpInfo(Op.Rec));

    int TiedReg = Op.getTiedRegister();
    TiedTo.push_back(-1);
    if (TiedReg != -1) {
      TiedTo[Idx] = TiedReg;
      TiedTo[TiedReg] = Idx;
    }
  }

  unsigned CurrBitPos = 0;
  for (const auto &EncodingSegment : VLI) {
    unsigned Offset = 0;
    StringRef OpName;

    if (const StringInit *SI = dyn_cast<StringInit>(EncodingSegment.Value)) {
      OpName = SI->getValue();
    } else if (const DagInit *DI = dyn_cast<DagInit>(EncodingSegment.Value)) {
      OpName = cast<StringInit>(DI->getArg(0))->getValue();
      Offset = cast<IntInit>(DI->getArg(2))->getValue();
    }

    if (!OpName.empty()) {
      auto OpSubOpPair =
          const_cast<CodeGenInstruction &>(CGI).Operands.ParseOperandName(
              OpName);
      unsigned OpIdx = CGI.Operands.getFlattenedOperandNumber(OpSubOpPair);
      Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset);
      if (!EncodingSegment.CustomDecoder.empty())
        Operands[OpIdx].Decoder = EncodingSegment.CustomDecoder.str();

      int TiedReg = TiedTo[OpSubOpPair.first];
      if (TiedReg != -1) {
        unsigned OpIdx = CGI.Operands.getFlattenedOperandNumber(
            {TiedReg, OpSubOpPair.second});
        Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset);
      }
    }

    CurrBitPos += EncodingSegment.BitWidth;
  }
}

static void debugDumpRecord(const Record &Rec) {
  // Dump the record, so we can see what's going on.
  PrintNote([&Rec](raw_ostream &OS) {
    OS << "Dumping record for previous error:\n";
    OS << Rec;
  });
}

/// For an operand field named OpName: populate OpInfo.InitValue with the
/// constant-valued bit values, and OpInfo.Fields with the ranges of bits to
/// insert from the decoded instruction.
static void addOneOperandFields(const Record &EncodingDef, const BitsInit &Bits,
                                std::map<StringRef, StringRef> &TiedNames,
                                StringRef OpName, OperandInfo &OpInfo) {
  // Some bits of the operand may be required to be 1 depending on the
  // instruction's encoding. Collect those bits.
  if (const RecordVal *EncodedValue = EncodingDef.getValue(OpName))
    if (const BitsInit *OpBits = dyn_cast<BitsInit>(EncodedValue->getValue()))
      for (unsigned I = 0; I < OpBits->getNumBits(); ++I)
        if (const BitInit *OpBit = dyn_cast<BitInit>(OpBits->getBit(I)))
          if (OpBit->getValue())
            OpInfo.InitValue |= 1ULL << I;

  for (unsigned I = 0, J = 0; I != Bits.getNumBits(); I = J) {
    const VarInit *Var;
    unsigned Offset = 0;
    for (; J != Bits.getNumBits(); ++J) {
      const VarBitInit *BJ = dyn_cast<VarBitInit>(Bits.getBit(J));
      if (BJ) {
        Var = dyn_cast<VarInit>(BJ->getBitVar());
        if (I == J)
          Offset = BJ->getBitNum();
        else if (BJ->getBitNum() != Offset + J - I)
          break;
      } else {
        Var = dyn_cast<VarInit>(Bits.getBit(J));
      }
      if (!Var ||
          (Var->getName() != OpName && Var->getName() != TiedNames[OpName]))
        break;
    }
    if (I == J)
      ++J;
    else
      OpInfo.addField(I, J - I, Offset);
  }
}

static unsigned
populateInstruction(const CodeGenTarget &Target, const Record &EncodingDef,
                    const CodeGenInstruction &CGI, unsigned Opc,
                    std::map<unsigned, std::vector<OperandInfo>> &Operands,
                    bool IsVarLenInst) {
  const Record &Def = *CGI.TheDef;
  // If all the bit positions are not specified; do not decode this instruction.
  // We are bound to fail!  For proper disassembly, the well-known encoding bits
  // of the instruction must be fully specified.

  const BitsInit &Bits = getBitsField(EncodingDef, "Inst");
  if (Bits.allInComplete())
    return 0;

  std::vector<OperandInfo> InsnOperands;

  // If the instruction has specified a custom decoding hook, use that instead
  // of trying to auto-generate the decoder.
  StringRef InstDecoder = EncodingDef.getValueAsString("DecoderMethod");
  if (!InstDecoder.empty()) {
    bool HasCompleteInstDecoder =
        EncodingDef.getValueAsBit("hasCompleteDecoder");
    InsnOperands.push_back(
        OperandInfo(InstDecoder.str(), HasCompleteInstDecoder));
    Operands[Opc] = std::move(InsnOperands);
    return Bits.getNumBits();
  }

  // Generate a description of the operand of the instruction that we know
  // how to decode automatically.
  // FIXME: We'll need to have a way to manually override this as needed.

  // Gather the outputs/inputs of the instruction, so we can find their
  // positions in the encoding.  This assumes for now that they appear in the
  // MCInst in the order that they're listed.
  std::vector<std::pair<const Init *, StringRef>> InOutOperands;
  const DagInit *Out = Def.getValueAsDag("OutOperandList");
  const DagInit *In = Def.getValueAsDag("InOperandList");
  for (const auto &[Idx, Arg] : enumerate(Out->getArgs()))
    InOutOperands.emplace_back(Arg, Out->getArgNameStr(Idx));
  for (const auto &[Idx, Arg] : enumerate(In->getArgs()))
    InOutOperands.emplace_back(Arg, In->getArgNameStr(Idx));

  // Search for tied operands, so that we can correctly instantiate
  // operands that are not explicitly represented in the encoding.
  std::map<StringRef, StringRef> TiedNames;
  for (const auto &Op : CGI.Operands) {
    for (const auto &[J, CI] : enumerate(Op.Constraints)) {
      if (!CI.isTied())
        continue;
      std::pair<unsigned, unsigned> SO =
          CGI.Operands.getSubOperandNumber(CI.getTiedOperand());
      StringRef TiedName = CGI.Operands[SO.first].SubOpNames[SO.second];
      if (TiedName.empty())
        TiedName = CGI.Operands[SO.first].Name;
      StringRef MyName = Op.SubOpNames[J];
      if (MyName.empty())
        MyName = Op.Name;

      TiedNames[MyName] = TiedName;
      TiedNames[TiedName] = MyName;
    }
  }

  if (IsVarLenInst) {
    parseVarLenInstOperand(EncodingDef, InsnOperands, CGI);
  } else {
    // For each operand, see if we can figure out where it is encoded.
    for (const auto &Op : InOutOperands) {
      const Init *OpInit = Op.first;
      StringRef OpName = Op.second;

      // We're ready to find the instruction encoding locations for this
      // operand.

      // First, find the operand type ("OpInit"), and sub-op names
      // ("SubArgDag") if present.
      const DagInit *SubArgDag = dyn_cast<DagInit>(OpInit);
      if (SubArgDag)
        OpInit = SubArgDag->getOperator();
      const Record *OpTypeRec = cast<DefInit>(OpInit)->getDef();
      // Lookup the sub-operands from the operand type record (note that only
      // Operand subclasses have MIOperandInfo, see CodeGenInstruction.cpp).
      const DagInit *SubOps = OpTypeRec->isSubClassOf("Operand")
                                  ? OpTypeRec->getValueAsDag("MIOperandInfo")
                                  : nullptr;

      // Lookup the decoder method and construct a new OperandInfo to hold our
      // result.
      OperandInfo OpInfo = getOpInfo(OpTypeRec);

      // If we have named sub-operands...
      if (SubArgDag) {
        // Then there should not be a custom decoder specified on the top-level
        // type.
        if (!OpInfo.Decoder.empty()) {
          PrintError(EncodingDef.getLoc(),
                     "DecoderEmitter: operand \"" + OpName + "\" has type \"" +
                         OpInit->getAsString() +
                         "\" with a custom DecoderMethod, but also named "
                         "sub-operands.");
          continue;
        }

        // Decode each of the sub-ops separately.
        assert(SubOps && SubArgDag->getNumArgs() == SubOps->getNumArgs());
        for (const auto &[I, Arg] : enumerate(SubOps->getArgs())) {
          StringRef SubOpName = SubArgDag->getArgNameStr(I);
          OperandInfo SubOpInfo = getOpInfo(cast<DefInit>(Arg)->getDef());

          addOneOperandFields(EncodingDef, Bits, TiedNames, SubOpName,
                              SubOpInfo);
          InsnOperands.push_back(std::move(SubOpInfo));
        }
        continue;
      }

      // Otherwise, if we have an operand with sub-operands, but they aren't
      // named...
      if (SubOps && OpInfo.Decoder.empty()) {
        // If it's a single sub-operand, and no custom decoder, use the decoder
        // from the one sub-operand.
        if (SubOps->getNumArgs() == 1)
          OpInfo = getOpInfo(cast<DefInit>(SubOps->getArg(0))->getDef());

        // If we have multiple sub-ops, there'd better have a custom
        // decoder. (Otherwise we don't know how to populate them properly...)
        if (SubOps->getNumArgs() > 1) {
          PrintError(EncodingDef.getLoc(),
                     "DecoderEmitter: operand \"" + OpName +
                         "\" uses MIOperandInfo with multiple ops, but doesn't "
                         "have a custom decoder!");
          debugDumpRecord(EncodingDef);
          continue;
        }
      }

      addOneOperandFields(EncodingDef, Bits, TiedNames, OpName, OpInfo);
      // FIXME: it should be an error not to find a definition for a given
      // operand, rather than just failing to add it to the resulting
      // instruction! (This is a longstanding bug, which will be addressed in an
      // upcoming change.)
      if (OpInfo.numFields() > 0)
        InsnOperands.push_back(std::move(OpInfo));
    }
  }
  Operands[Opc] = std::move(InsnOperands);

#if 0
  LLVM_DEBUG({
      // Dumps the instruction encoding bits.
      dumpBits(errs(), Bits);

      errs() << '\n';

      // Dumps the list of operand info.
      for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) {
        const CGIOperandList::OperandInfo &Info = CGI.Operands[i];
        const std::string &OperandName = Info.Name;
        const Record &OperandDef = *Info.Rec;

        errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n";
      }
    });
#endif

  return Bits.getNumBits();
}

// emitFieldFromInstruction - Emit the templated helper function
// fieldFromInstruction().
// On Windows we make sure that this function is not inlined when
// using the VS compiler. It has a bug which causes the function
// to be optimized out in some circumstances. See llvm.org/pr38292
static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
  OS << R"(
// Helper functions for extracting fields from encoded instructions.
// InsnType must either be integral or an APInt-like object that must:
// * be default-constructible and copy-constructible
// * Support extractBitsAsZExtValue(numBits, startBit)
// * Support the ~, &, ==, and != operators with other objects of the same type
// * Support the != and bitwise & with uint64_t
template <typename InsnType>
#if defined(_MSC_VER) && !defined(__clang__)
__declspec(noinline)
#endif
static std::enable_if_t<std::is_integral<InsnType>::value, InsnType>
fieldFromInstruction(const InsnType &insn, unsigned startBit,
                     unsigned numBits) {
  assert(startBit + numBits <= 64 && "Cannot support >64-bit extractions!");
  assert(startBit + numBits <= (sizeof(InsnType) * 8) &&
         "Instruction field out of bounds!");
  InsnType fieldMask;
  if (numBits == sizeof(InsnType) * 8)
    fieldMask = (InsnType)(-1LL);
  else
    fieldMask = (((InsnType)1 << numBits) - 1) << startBit;
  return (insn & fieldMask) >> startBit;
}

template <typename InsnType>
static std::enable_if_t<!std::is_integral<InsnType>::value, uint64_t>
fieldFromInstruction(const InsnType &insn, unsigned startBit,
                     unsigned numBits) {
  return insn.extractBitsAsZExtValue(numBits, startBit);
}
)";
}

// emitInsertBits - Emit the templated helper function insertBits().
static void emitInsertBits(formatted_raw_ostream &OS) {
  OS << R"(
// Helper function for inserting bits extracted from an encoded instruction into
// an integer-typed field.
template <typename IntType>
static std::enable_if_t<std::is_integral_v<IntType>, void>
insertBits(IntType &field, IntType bits, unsigned startBit, unsigned numBits) {
  // Check that no bit beyond numBits is set, so that a simple bitwise |
  // is sufficient.
  assert((~(((IntType)1 << numBits) - 1) & bits) == 0 &&
           "bits has more than numBits bits set");
  assert(startBit + numBits <= sizeof(IntType) * 8);
  (void)numBits;
  field |= bits << startBit;
}
)";
}

// emitDecodeInstruction - Emit the templated helper function
// decodeInstruction().
static void emitDecodeInstruction(formatted_raw_ostream &OS, bool IsVarLenInst,
                                  unsigned OpcodeMask) {
  const bool HasTryDecode = OpcodeMask & ((1 << MCD::OPC_TryDecode) |
                                          (1 << MCD::OPC_TryDecodeOrFail));
  const bool HasCheckPredicate =
      OpcodeMask &
      ((1 << MCD::OPC_CheckPredicate) | (1 << MCD::OPC_CheckPredicateOrFail));
  const bool HasSoftFail = OpcodeMask & (1 << MCD::OPC_SoftFail);

  OS << R"(
static unsigned decodeNumToSkip(const uint8_t *&Ptr) {
  unsigned NumToSkip = *Ptr++;
  NumToSkip |= (*Ptr++) << 8;
)";
  if (getNumToSkipInBytes() == 3)
    OS << "  NumToSkip |= (*Ptr++) << 16;\n";
  OS << R"(  return NumToSkip;
}

template <typename InsnType>
static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
                                      InsnType insn, uint64_t Address,
                                      const MCDisassembler *DisAsm,
                                      const MCSubtargetInfo &STI)";
  if (IsVarLenInst) {
    OS << ",\n                                      "
          "llvm::function_ref<void(APInt &, uint64_t)> makeUp";
  }
  OS << ") {\n";
  if (HasCheckPredicate)
    OS << "  const FeatureBitset &Bits = STI.getFeatureBits();\n";

  OS << R"(
  const uint8_t *Ptr = DecodeTable;
  uint64_t CurFieldValue = 0;
  DecodeStatus S = MCDisassembler::Success;
  while (true) {
    ptrdiff_t Loc = Ptr - DecodeTable;
    const uint8_t DecoderOp = *Ptr++;
    switch (DecoderOp) {
    default:
      errs() << Loc << ": Unexpected decode table opcode: "
             << (int)DecoderOp << '\n';
      return MCDisassembler::Fail;
    case MCD::OPC_ExtractField: {
      // Decode the start value.
      unsigned Start = decodeULEB128AndIncUnsafe(Ptr);
      unsigned Len = *Ptr++;)";
  if (IsVarLenInst)
    OS << "\n      makeUp(insn, Start + Len);";
  OS << R"(
      CurFieldValue = fieldFromInstruction(insn, Start, Len);
      LLVM_DEBUG(dbgs() << Loc << ": OPC_ExtractField(" << Start << ", "
                   << Len << "): " << CurFieldValue << "\n");
      break;
    }
    case MCD::OPC_FilterValue:
    case MCD::OPC_FilterValueOrFail: {
      bool IsFail = DecoderOp == MCD::OPC_FilterValueOrFail;
      // Decode the field value.
      uint64_t Val = decodeULEB128AndIncUnsafe(Ptr);
      bool Failed = Val != CurFieldValue;
      unsigned NumToSkip = IsFail ? 0 : decodeNumToSkip(Ptr);

      // Note: Print NumToSkip even for OPC_FilterValueOrFail to simplify debug
      // prints.
      LLVM_DEBUG({
        StringRef OpName = IsFail ? "OPC_FilterValueOrFail" : "OPC_FilterValue";
        dbgs() << Loc << ": " << OpName << '(' << Val << ", " << NumToSkip
                << ") " << (Failed ? "FAIL:" : "PASS:")
                << " continuing at " << (Ptr - DecodeTable) << '\n';
      });

      // Perform the filter operation.
      if (Failed) {
        if (IsFail)
          return MCDisassembler::Fail;
        Ptr += NumToSkip;
      }
      break;
    }
    case MCD::OPC_CheckField:
    case MCD::OPC_CheckFieldOrFail: {
      bool IsFail = DecoderOp == MCD::OPC_CheckFieldOrFail;
      // Decode the start value.
      unsigned Start = decodeULEB128AndIncUnsafe(Ptr);
      unsigned Len = *Ptr;)";
  if (IsVarLenInst)
    OS << "\n      makeUp(insn, Start + Len);";
  OS << R"(
      uint64_t FieldValue = fieldFromInstruction(insn, Start, Len);
      // Decode the field value.
      unsigned PtrLen = 0;
      uint64_t ExpectedValue = decodeULEB128(++Ptr, &PtrLen);
      Ptr += PtrLen;
      bool Failed = ExpectedValue != FieldValue;
      unsigned NumToSkip = IsFail ? 0 : decodeNumToSkip(Ptr);

      LLVM_DEBUG({
        StringRef OpName = IsFail ? "OPC_CheckFieldOrFail" : "OPC_CheckField";
        dbgs() << Loc << ": " << OpName << '(' << Start << ", " << Len << ", "
                << ExpectedValue << ", " << NumToSkip << "): FieldValue = "
                << FieldValue << ", ExpectedValue = " << ExpectedValue << ": "
                << (Failed ? "FAIL\n" : "PASS\n");
      });

      // If the actual and expected values don't match, skip or fail.
      if (Failed) {
        if (IsFail)
          return MCDisassembler::Fail;
        Ptr += NumToSkip;
      }
      break;
    })";
  if (HasCheckPredicate) {
    OS << R"(
    case MCD::OPC_CheckPredicate:
    case MCD::OPC_CheckPredicateOrFail: {
      bool IsFail = DecoderOp == MCD::OPC_CheckPredicateOrFail;
      // Decode the Predicate Index value.
      unsigned PIdx = decodeULEB128AndIncUnsafe(Ptr);
      unsigned NumToSkip = IsFail ? 0 : decodeNumToSkip(Ptr);
      // Check the predicate.
      bool Failed = !checkDecoderPredicate(PIdx, Bits);

      LLVM_DEBUG({
        StringRef OpName = IsFail ? "OPC_CheckPredicateOrFail" : "OPC_CheckPredicate";
        dbgs() << Loc << ": " << OpName << '(' << PIdx << ", " << NumToSkip
               << "): " << (Failed ? "FAIL\n" : "PASS\n");
      });

      if (Failed) {
        if (IsFail)
          return MCDisassembler::Fail;
        Ptr += NumToSkip;
      }
      break;
    })";
  }
  OS << R"(
    case MCD::OPC_Decode: {
      // Decode the Opcode value.
      unsigned Opc = decodeULEB128AndIncUnsafe(Ptr);
      unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);

      MI.clear();
      MI.setOpcode(Opc);
      bool DecodeComplete;)";
  if (IsVarLenInst) {
    OS << "\n      unsigned Len = InstrLenTable[Opc];\n"
       << "      makeUp(insn, Len);";
  }
  OS << R"(
      S = decodeToMCInst(DecodeIdx, S, insn, MI, Address, DisAsm, DecodeComplete);
      assert(DecodeComplete);

      LLVM_DEBUG(dbgs() << Loc << ": OPC_Decode: opcode " << Opc
                   << ", using decoder " << DecodeIdx << ": "
                   << (S != MCDisassembler::Fail ? "PASS\n" : "FAIL\n"));
      return S;
    })";
  if (HasTryDecode) {
    OS << R"(
    case MCD::OPC_TryDecode:
    case MCD::OPC_TryDecodeOrFail: {
      bool IsFail = DecoderOp == MCD::OPC_TryDecodeOrFail;
      // Decode the Opcode value.
      unsigned Opc = decodeULEB128AndIncUnsafe(Ptr);
      unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
      unsigned NumToSkip = IsFail ? 0 : decodeNumToSkip(Ptr);

      // Perform the decode operation.
      MCInst TmpMI;
      TmpMI.setOpcode(Opc);
      bool DecodeComplete;
      S = decodeToMCInst(DecodeIdx, S, insn, TmpMI, Address, DisAsm, DecodeComplete);
      LLVM_DEBUG(dbgs() << Loc << ": OPC_TryDecode: opcode " << Opc
                   << ", using decoder " << DecodeIdx << ": ");

      if (DecodeComplete) {
        // Decoding complete.
        LLVM_DEBUG(dbgs() << (S != MCDisassembler::Fail ? "PASS\n" : "FAIL\n"));
        MI = TmpMI;
        return S;
      }
      assert(S == MCDisassembler::Fail);
      if (IsFail) {
        LLVM_DEBUG(dbgs() << "FAIL: returning FAIL\n");
        return MCDisassembler::Fail;
      }
      // If the decoding was incomplete, skip.
      Ptr += NumToSkip;
      LLVM_DEBUG(dbgs() << "FAIL: continuing at " << (Ptr - DecodeTable) << "\n");
      // Reset decode status. This also drops a SoftFail status that could be
      // set before the decode attempt.
      S = MCDisassembler::Success;
      break;
    })";
  }
  if (HasSoftFail) {
    OS << R"(
      case MCD::OPC_SoftFail: {
        // Decode the mask values.
        uint64_t PositiveMask = decodeULEB128AndIncUnsafe(Ptr);
        uint64_t NegativeMask = decodeULEB128AndIncUnsafe(Ptr);
        bool Failed = (insn & PositiveMask) != 0 || (~insn & NegativeMask) != 0;
        if (Failed)
          S = MCDisassembler::SoftFail;
        LLVM_DEBUG(dbgs() << Loc << ": OPC_SoftFail: " << (Failed ? "FAIL\n" : "PASS\n"));
        break;
  })";
  }
  OS << R"(
    case MCD::OPC_Fail: {
      LLVM_DEBUG(dbgs() << Loc << ": OPC_Fail\n");
      return MCDisassembler::Fail;
    }
    }
  }
  llvm_unreachable("bogosity detected in disassembler state machine!");
}

)";
}

// Helper to propagate SoftFail status. Returns false if the status is Fail;
// callers are expected to early-exit in that condition. (Note, the '&' operator
// is correct to propagate the values of this enum; see comment on 'enum
// DecodeStatus'.)
static void emitCheck(formatted_raw_ostream &OS) {
  OS << R"(
static bool Check(DecodeStatus &Out, DecodeStatus In) {
  Out = static_cast<DecodeStatus>(Out & In);
  return Out != MCDisassembler::Fail;
}

)";
}

// Collect all HwModes referenced by the target for encoding purposes,
// returning a vector of corresponding names.
static void collectHwModesReferencedForEncodings(
    const CodeGenHwModes &HWM, std::vector<StringRef> &Names,
    NamespacesHwModesMap &NamespacesWithHwModes) {
  SmallBitVector BV(HWM.getNumModeIds());
  for (const auto &MS : HWM.getHwModeSelects()) {
    for (const HwModeSelect::PairType &P : MS.second.Items) {
      if (P.second->isSubClassOf("InstructionEncoding")) {
        std::string DecoderNamespace =
            P.second->getValueAsString("DecoderNamespace").str();
        if (P.first == DefaultMode) {
          NamespacesWithHwModes[DecoderNamespace].insert("");
        } else {
          NamespacesWithHwModes[DecoderNamespace].insert(
              HWM.getMode(P.first).Name);
        }
        BV.set(P.first);
      }
    }
  }
  transform(BV.set_bits(), std::back_inserter(Names), [&HWM](const int &M) {
    if (M == DefaultMode)
      return StringRef("");
    return HWM.getModeName(M, /*IncludeDefault=*/true);
  });
}

static void
handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
                                ArrayRef<StringRef> HwModeNames,
                                NamespacesHwModesMap &NamespacesWithHwModes,
                                std::vector<EncodingAndInst> &GlobalEncodings) {
  const Record *InstDef = Instr->TheDef;

  switch (DecoderEmitterSuppressDuplicates) {
  case SUPPRESSION_DISABLE: {
    for (StringRef HwModeName : HwModeNames)
      GlobalEncodings.emplace_back(InstDef, Instr, HwModeName);
    break;
  }
  case SUPPRESSION_LEVEL1: {
    std::string DecoderNamespace =
        InstDef->getValueAsString("DecoderNamespace").str();
    auto It = NamespacesWithHwModes.find(DecoderNamespace);
    if (It != NamespacesWithHwModes.end()) {
      for (StringRef HwModeName : It->second)
        GlobalEncodings.emplace_back(InstDef, Instr, HwModeName);
    } else {
      // Only emit the encoding once, as it's DecoderNamespace doesn't
      // contain any HwModes.
      GlobalEncodings.emplace_back(InstDef, Instr, "");
    }
    break;
  }
  case SUPPRESSION_LEVEL2:
    GlobalEncodings.emplace_back(InstDef, Instr, "");
    break;
  }
}

// Emits disassembler code for instruction decoding.
void DecoderEmitter::run(raw_ostream &o) {
  formatted_raw_ostream OS(o);
  OS << R"(
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/SubtargetFeature.h"
#include <assert.h>

namespace {
)";

  emitFieldFromInstruction(OS);
  emitInsertBits(OS);
  emitCheck(OS);

  Target.reverseBitsForLittleEndianEncoding();

  // Parameterize the decoders based on namespace and instruction width.

  // First, collect all encoding-related HwModes referenced by the target.
  // And establish a mapping table between DecoderNamespace and HwMode.
  // If HwModeNames is empty, add the empty string so we always have one HwMode.
  const CodeGenHwModes &HWM = Target.getHwModes();
  std::vector<StringRef> HwModeNames;
  NamespacesHwModesMap NamespacesWithHwModes;
  collectHwModesReferencedForEncodings(HWM, HwModeNames, NamespacesWithHwModes);
  if (HwModeNames.empty())
    HwModeNames.push_back("");

  const auto &NumberedInstructions = Target.getInstructions();
  NumberedEncodings.reserve(NumberedInstructions.size());
  for (const auto &NumberedInstruction : NumberedInstructions) {
    const Record *InstDef = NumberedInstruction->TheDef;
    if (const RecordVal *RV = InstDef->getValue("EncodingInfos")) {
      if (const DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
        EncodingInfoByHwMode EBM(DI->getDef(), HWM);
        for (auto &[ModeId, Encoding] : EBM) {
          // DecoderTables with DefaultMode should not have any suffix.
          if (ModeId == DefaultMode) {
            NumberedEncodings.emplace_back(Encoding, NumberedInstruction, "");
          } else {
            NumberedEncodings.emplace_back(Encoding, NumberedInstruction,
                                           HWM.getMode(ModeId).Name);
          }
        }
        continue;
      }
    }
    // This instruction is encoded the same on all HwModes.
    // According to user needs, provide varying degrees of suppression.
    handleHwModesUnrelatedEncodings(NumberedInstruction, HwModeNames,
                                    NamespacesWithHwModes, NumberedEncodings);
  }
  for (const Record *NumberedAlias :
       RK.getAllDerivedDefinitions("AdditionalEncoding"))
    NumberedEncodings.emplace_back(
        NumberedAlias,
        &Target.getInstruction(NumberedAlias->getValueAsDef("AliasOf")));

  std::map<std::pair<std::string, unsigned>, std::vector<EncodingIDAndOpcode>>
      OpcMap;
  std::map<unsigned, std::vector<OperandInfo>> Operands;
  std::vector<unsigned> InstrLen;
  bool IsVarLenInst = Target.hasVariableLengthEncodings();
  unsigned MaxInstLen = 0;

  for (const auto &[NEI, NumberedEncoding] : enumerate(NumberedEncodings)) {
    const Record *EncodingDef = NumberedEncoding.EncodingDef;
    const CodeGenInstruction *Inst = NumberedEncoding.Inst;
    const Record *Def = Inst->TheDef;
    unsigned Size = EncodingDef->getValueAsInt("Size");
    if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
        Def->getValueAsBit("isPseudo") ||
        Def->getValueAsBit("isAsmParserOnly") ||
        Def->getValueAsBit("isCodeGenOnly")) {
      NumEncodingsLackingDisasm++;
      continue;
    }

    if (NEI < NumberedInstructions.size())
      NumInstructions++;
    NumEncodings++;

    if (!Size && !IsVarLenInst)
      continue;

    if (IsVarLenInst)
      InstrLen.resize(NumberedInstructions.size(), 0);

    if (unsigned Len = populateInstruction(Target, *EncodingDef, *Inst, NEI,
                                           Operands, IsVarLenInst)) {
      if (IsVarLenInst) {
        MaxInstLen = std::max(MaxInstLen, Len);
        InstrLen[NEI] = Len;
      }
      std::string DecoderNamespace =
          EncodingDef->getValueAsString("DecoderNamespace").str();
      if (!NumberedEncoding.HwModeName.empty())
        DecoderNamespace += "_" + NumberedEncoding.HwModeName.str();
      OpcMap[{DecoderNamespace, Size}].emplace_back(
          NEI, Target.getInstrIntValue(Def));
    } else {
      NumEncodingsOmitted++;
    }
  }

  DecoderTableInfo TableInfo;
  unsigned OpcodeMask = 0;
  for (const auto &[NSAndByteSize, EncodingIDs] : OpcMap) {
    const std::string &DecoderNamespace = NSAndByteSize.first;
    const unsigned BitWidth = 8 * NSAndByteSize.second;
    // Emit the decoder for this namespace+width combination.
    FilterChooser FC(NumberedEncodings, EncodingIDs, Operands,
                     IsVarLenInst ? MaxInstLen : BitWidth, this);

    // The decode table is cleared for each top level decoder function. The
    // predicates and decoders themselves, however, are shared across all
    // decoders to give more opportunities for uniqueing.
    TableInfo.Table.clear();
    TableInfo.FixupStack.clear();
    TableInfo.FixupStack.emplace_back();
    FC.emitTableEntries(TableInfo);
    // Any NumToSkip fixups in the top level scope can resolve to the
    // OPC_Fail at the end of the table.
    assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!");
    // Resolve any NumToSkip fixups in the current scope.
    resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
                       TableInfo.Table.size());
    TableInfo.FixupStack.clear();

    TableInfo.Table.push_back(MCD::OPC_Fail);

    // Print the table to the output stream.
    OpcodeMask |= emitTable(OS, TableInfo.Table, FC.getBitWidth(),
                            DecoderNamespace, EncodingIDs);
  }

  // For variable instruction, we emit a instruction length table
  // to let the decoder know how long the instructions are.
  // You can see example usage in M68k's disassembler.
  if (IsVarLenInst)
    emitInstrLenTable(OS, InstrLen);

  const bool HasCheckPredicate =
      OpcodeMask &
      ((1 << MCD::OPC_CheckPredicate) | (1 << MCD::OPC_CheckPredicateOrFail));

  // Emit the predicate function.
  if (HasCheckPredicate)
    emitPredicateFunction(OS, TableInfo.Predicates);

  // Emit the decoder function.
  emitDecoderFunction(OS, TableInfo.Decoders);

  // Emit the main entry point for the decoder, decodeInstruction().
  emitDecodeInstruction(OS, IsVarLenInst, OpcodeMask);

  OS << "\n} // namespace\n";
}

void llvm::EmitDecoder(const RecordKeeper &RK, raw_ostream &OS,
                       StringRef PredicateNamespace) {
  DecoderEmitter(RK, PredicateNamespace).run(OS);
}
