xref: /freebsd-src/contrib/llvm-project/llvm/utils/TableGen/RegisterInfoEmitter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- RegisterInfoEmitter.cpp - Generate a Register File Desc. -*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This tablegen backend is responsible for emitting a description of a target
100b57cec5SDimitry Andric // register file for a code generator.  It uses instances of the Register,
110b57cec5SDimitry Andric // RegisterAliases, and RegisterClass classes to gather this information.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
15*0fca6ea1SDimitry Andric #include "Basic/SequenceToOffsetTable.h"
16*0fca6ea1SDimitry Andric #include "Common/CodeGenHwModes.h"
17*0fca6ea1SDimitry Andric #include "Common/CodeGenRegisters.h"
18*0fca6ea1SDimitry Andric #include "Common/CodeGenTarget.h"
19*0fca6ea1SDimitry Andric #include "Common/InfoByHwMode.h"
20*0fca6ea1SDimitry Andric #include "Common/Types.h"
210b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
220b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h"
230b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
240b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
250b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
260b57cec5SDimitry Andric #include "llvm/ADT/SparseBitVector.h"
270b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
28*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/MachineValueType.h"
290b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
300b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
310b57cec5SDimitry Andric #include "llvm/Support/Format.h"
320b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
330b57cec5SDimitry Andric #include "llvm/TableGen/Error.h"
340b57cec5SDimitry Andric #include "llvm/TableGen/Record.h"
350b57cec5SDimitry Andric #include "llvm/TableGen/SetTheory.h"
360b57cec5SDimitry Andric #include "llvm/TableGen/TableGenBackend.h"
370b57cec5SDimitry Andric #include <algorithm>
380b57cec5SDimitry Andric #include <cassert>
390b57cec5SDimitry Andric #include <cstddef>
400b57cec5SDimitry Andric #include <cstdint>
410b57cec5SDimitry Andric #include <deque>
420b57cec5SDimitry Andric #include <iterator>
430b57cec5SDimitry Andric #include <set>
440b57cec5SDimitry Andric #include <string>
450b57cec5SDimitry Andric #include <vector>
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric using namespace llvm;
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric cl::OptionCategory RegisterInfoCat("Options for -gen-register-info");
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric static cl::opt<bool>
520b57cec5SDimitry Andric     RegisterInfoDebug("register-info-debug", cl::init(false),
530b57cec5SDimitry Andric                       cl::desc("Dump register information to help debugging"),
540b57cec5SDimitry Andric                       cl::cat(RegisterInfoCat));
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric namespace {
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric class RegisterInfoEmitter {
590b57cec5SDimitry Andric   CodeGenTarget Target;
600b57cec5SDimitry Andric   RecordKeeper &Records;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric public:
630b57cec5SDimitry Andric   RegisterInfoEmitter(RecordKeeper &R) : Target(R), Records(R) {
640b57cec5SDimitry Andric     CodeGenRegBank &RegBank = Target.getRegBank();
650b57cec5SDimitry Andric     RegBank.computeDerivedInfo();
660b57cec5SDimitry Andric   }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   // runEnums - Print out enum values for all of the registers.
690b57cec5SDimitry Andric   void runEnums(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank);
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   // runMCDesc - Print out MC register descriptions.
720b57cec5SDimitry Andric   void runMCDesc(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank);
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   // runTargetHeader - Emit a header fragment for the register info emitter.
750b57cec5SDimitry Andric   void runTargetHeader(raw_ostream &o, CodeGenTarget &Target,
760b57cec5SDimitry Andric                        CodeGenRegBank &Bank);
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   // runTargetDesc - Output the target register and register file descriptions.
790b57cec5SDimitry Andric   void runTargetDesc(raw_ostream &o, CodeGenTarget &Target,
800b57cec5SDimitry Andric                      CodeGenRegBank &Bank);
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   // run - Output the register file description.
830b57cec5SDimitry Andric   void run(raw_ostream &o);
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   void debugDump(raw_ostream &OS);
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric private:
880b57cec5SDimitry Andric   void EmitRegMapping(raw_ostream &o, const std::deque<CodeGenRegister> &Regs,
890b57cec5SDimitry Andric                       bool isCtor);
900b57cec5SDimitry Andric   void EmitRegMappingTables(raw_ostream &o,
910b57cec5SDimitry Andric                             const std::deque<CodeGenRegister> &Regs,
920b57cec5SDimitry Andric                             bool isCtor);
930b57cec5SDimitry Andric   void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
940b57cec5SDimitry Andric                            const std::string &ClassName);
950b57cec5SDimitry Andric   void emitComposeSubRegIndices(raw_ostream &OS, CodeGenRegBank &RegBank,
960b57cec5SDimitry Andric                                 const std::string &ClassName);
970b57cec5SDimitry Andric   void emitComposeSubRegIndexLaneMask(raw_ostream &OS, CodeGenRegBank &RegBank,
980b57cec5SDimitry Andric                                       const std::string &ClassName);
990b57cec5SDimitry Andric };
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric } // end anonymous namespace
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric // runEnums - Print out enum values for all of the registers.
104*0fca6ea1SDimitry Andric void RegisterInfoEmitter::runEnums(raw_ostream &OS, CodeGenTarget &Target,
105*0fca6ea1SDimitry Andric                                    CodeGenRegBank &Bank) {
1060b57cec5SDimitry Andric   const auto &Registers = Bank.getRegisters();
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric   // Register enums are stored as uint16_t in the tables. Make sure we'll fit.
1090b57cec5SDimitry Andric   assert(Registers.size() <= 0xffff && "Too many regs to fit in tables");
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric   StringRef Namespace = Registers.front().TheDef->getValueAsString("Namespace");
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric   emitSourceFileHeader("Target Register Enum Values", OS);
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   OS << "\n#ifdef GET_REGINFO_ENUM\n";
1160b57cec5SDimitry Andric   OS << "#undef GET_REGINFO_ENUM\n\n";
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   OS << "namespace llvm {\n\n";
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric   OS << "class MCRegisterClass;\n"
1210b57cec5SDimitry Andric      << "extern const MCRegisterClass " << Target.getName()
1220b57cec5SDimitry Andric      << "MCRegisterClasses[];\n\n";
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   if (!Namespace.empty())
1250b57cec5SDimitry Andric     OS << "namespace " << Namespace << " {\n";
1260b57cec5SDimitry Andric   OS << "enum {\n  NoRegister,\n";
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric   for (const auto &Reg : Registers)
1290b57cec5SDimitry Andric     OS << "  " << Reg.getName() << " = " << Reg.EnumValue << ",\n";
1300b57cec5SDimitry Andric   assert(Registers.size() == Registers.back().EnumValue &&
1310b57cec5SDimitry Andric          "Register enum value mismatch!");
132e8d8bef9SDimitry Andric   OS << "  NUM_TARGET_REGS // " << Registers.size() + 1 << "\n";
1330b57cec5SDimitry Andric   OS << "};\n";
1340b57cec5SDimitry Andric   if (!Namespace.empty())
1350b57cec5SDimitry Andric     OS << "} // end namespace " << Namespace << "\n";
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   const auto &RegisterClasses = Bank.getRegClasses();
1380b57cec5SDimitry Andric   if (!RegisterClasses.empty()) {
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric     // RegisterClass enums are stored as uint16_t in the tables.
1410b57cec5SDimitry Andric     assert(RegisterClasses.size() <= 0xffff &&
1420b57cec5SDimitry Andric            "Too many register classes to fit in tables");
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric     OS << "\n// Register classes\n\n";
1450b57cec5SDimitry Andric     if (!Namespace.empty())
1460b57cec5SDimitry Andric       OS << "namespace " << Namespace << " {\n";
1470b57cec5SDimitry Andric     OS << "enum {\n";
1480b57cec5SDimitry Andric     for (const auto &RC : RegisterClasses)
1495f757f3fSDimitry Andric       OS << "  " << RC.getIdName() << " = " << RC.EnumValue << ",\n";
1500b57cec5SDimitry Andric     OS << "\n};\n";
1510b57cec5SDimitry Andric     if (!Namespace.empty())
1520b57cec5SDimitry Andric       OS << "} // end namespace " << Namespace << "\n\n";
1530b57cec5SDimitry Andric   }
1540b57cec5SDimitry Andric 
155*0fca6ea1SDimitry Andric   const std::vector<Record *> &RegAltNameIndices =
156*0fca6ea1SDimitry Andric       Target.getRegAltNameIndices();
1570b57cec5SDimitry Andric   // If the only definition is the default NoRegAltName, we don't need to
1580b57cec5SDimitry Andric   // emit anything.
1590b57cec5SDimitry Andric   if (RegAltNameIndices.size() > 1) {
1600b57cec5SDimitry Andric     OS << "\n// Register alternate name indices\n\n";
1610b57cec5SDimitry Andric     if (!Namespace.empty())
1620b57cec5SDimitry Andric       OS << "namespace " << Namespace << " {\n";
1630b57cec5SDimitry Andric     OS << "enum {\n";
1640b57cec5SDimitry Andric     for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i)
1650b57cec5SDimitry Andric       OS << "  " << RegAltNameIndices[i]->getName() << ",\t// " << i << "\n";
1660b57cec5SDimitry Andric     OS << "  NUM_TARGET_REG_ALT_NAMES = " << RegAltNameIndices.size() << "\n";
1670b57cec5SDimitry Andric     OS << "};\n";
1680b57cec5SDimitry Andric     if (!Namespace.empty())
1690b57cec5SDimitry Andric       OS << "} // end namespace " << Namespace << "\n\n";
1700b57cec5SDimitry Andric   }
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric   auto &SubRegIndices = Bank.getSubRegIndices();
1730b57cec5SDimitry Andric   if (!SubRegIndices.empty()) {
1740b57cec5SDimitry Andric     OS << "\n// Subregister indices\n\n";
1750b57cec5SDimitry Andric     std::string Namespace = SubRegIndices.front().getNamespace();
1760b57cec5SDimitry Andric     if (!Namespace.empty())
1770b57cec5SDimitry Andric       OS << "namespace " << Namespace << " {\n";
1785ffd83dbSDimitry Andric     OS << "enum : uint16_t {\n  NoSubRegister,\n";
1790b57cec5SDimitry Andric     unsigned i = 0;
1800b57cec5SDimitry Andric     for (const auto &Idx : SubRegIndices)
1810b57cec5SDimitry Andric       OS << "  " << Idx.getName() << ",\t// " << ++i << "\n";
1820b57cec5SDimitry Andric     OS << "  NUM_TARGET_SUBREGS\n};\n";
1830b57cec5SDimitry Andric     if (!Namespace.empty())
1840b57cec5SDimitry Andric       OS << "} // end namespace " << Namespace << "\n\n";
1850b57cec5SDimitry Andric   }
1860b57cec5SDimitry Andric 
1875ffd83dbSDimitry Andric   OS << "// Register pressure sets enum.\n";
1885ffd83dbSDimitry Andric   if (!Namespace.empty())
1895ffd83dbSDimitry Andric     OS << "namespace " << Namespace << " {\n";
1905ffd83dbSDimitry Andric   OS << "enum RegisterPressureSets {\n";
1915ffd83dbSDimitry Andric   unsigned NumSets = Bank.getNumRegPressureSets();
1925ffd83dbSDimitry Andric   for (unsigned i = 0; i < NumSets; ++i) {
1935ffd83dbSDimitry Andric     const RegUnitSet &RegUnits = Bank.getRegSetAt(i);
1945ffd83dbSDimitry Andric     OS << "  " << RegUnits.Name << " = " << i << ",\n";
1955ffd83dbSDimitry Andric   }
1965ffd83dbSDimitry Andric   OS << "};\n";
1975ffd83dbSDimitry Andric   if (!Namespace.empty())
1985ffd83dbSDimitry Andric     OS << "} // end namespace " << Namespace << '\n';
1995ffd83dbSDimitry Andric   OS << '\n';
2005ffd83dbSDimitry Andric 
2010b57cec5SDimitry Andric   OS << "} // end namespace llvm\n\n";
2020b57cec5SDimitry Andric   OS << "#endif // GET_REGINFO_ENUM\n\n";
2030b57cec5SDimitry Andric }
2040b57cec5SDimitry Andric 
205*0fca6ea1SDimitry Andric static void printInt(raw_ostream &OS, int Val) { OS << Val; }
2060b57cec5SDimitry Andric 
207*0fca6ea1SDimitry Andric void RegisterInfoEmitter::EmitRegUnitPressure(raw_ostream &OS,
208*0fca6ea1SDimitry Andric                                               const CodeGenRegBank &RegBank,
2090b57cec5SDimitry Andric                                               const std::string &ClassName) {
2100b57cec5SDimitry Andric   unsigned NumRCs = RegBank.getRegClasses().size();
2110b57cec5SDimitry Andric   unsigned NumSets = RegBank.getNumRegPressureSets();
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   OS << "/// Get the weight in units of pressure for this register class.\n"
2140b57cec5SDimitry Andric      << "const RegClassWeight &" << ClassName << "::\n"
2150b57cec5SDimitry Andric      << "getRegClassWeight(const TargetRegisterClass *RC) const {\n"
2160b57cec5SDimitry Andric      << "  static const RegClassWeight RCWeightTable[] = {\n";
2170b57cec5SDimitry Andric   for (const auto &RC : RegBank.getRegClasses()) {
2180b57cec5SDimitry Andric     const CodeGenRegister::Vec &Regs = RC.getMembers();
2195ffd83dbSDimitry Andric     OS << "    {" << RC.getWeight(RegBank) << ", ";
2200b57cec5SDimitry Andric     if (Regs.empty() || RC.Artificial)
2215ffd83dbSDimitry Andric       OS << '0';
2220b57cec5SDimitry Andric     else {
2230b57cec5SDimitry Andric       std::vector<unsigned> RegUnits;
2240b57cec5SDimitry Andric       RC.buildRegUnitSet(RegBank, RegUnits);
2255ffd83dbSDimitry Andric       OS << RegBank.getRegUnitSetWeight(RegUnits);
2260b57cec5SDimitry Andric     }
2270b57cec5SDimitry Andric     OS << "},  \t// " << RC.getName() << "\n";
2280b57cec5SDimitry Andric   }
2290b57cec5SDimitry Andric   OS << "  };\n"
2300b57cec5SDimitry Andric      << "  return RCWeightTable[RC->getID()];\n"
2310b57cec5SDimitry Andric      << "}\n\n";
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   // Reasonable targets (not ARMv7) have unit weight for all units, so don't
2340b57cec5SDimitry Andric   // bother generating a table.
2350b57cec5SDimitry Andric   bool RegUnitsHaveUnitWeight = true;
2360b57cec5SDimitry Andric   for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
2370b57cec5SDimitry Andric        UnitIdx < UnitEnd; ++UnitIdx) {
2380b57cec5SDimitry Andric     if (RegBank.getRegUnit(UnitIdx).Weight > 1)
2390b57cec5SDimitry Andric       RegUnitsHaveUnitWeight = false;
2400b57cec5SDimitry Andric   }
2410b57cec5SDimitry Andric   OS << "/// Get the weight in units of pressure for this register unit.\n"
2420b57cec5SDimitry Andric      << "unsigned " << ClassName << "::\n"
2430b57cec5SDimitry Andric      << "getRegUnitWeight(unsigned RegUnit) const {\n"
2440b57cec5SDimitry Andric      << "  assert(RegUnit < " << RegBank.getNumNativeRegUnits()
2450b57cec5SDimitry Andric      << " && \"invalid register unit\");\n";
2460b57cec5SDimitry Andric   if (!RegUnitsHaveUnitWeight) {
2470b57cec5SDimitry Andric     OS << "  static const uint8_t RUWeightTable[] = {\n    ";
2480b57cec5SDimitry Andric     for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
2490b57cec5SDimitry Andric          UnitIdx < UnitEnd; ++UnitIdx) {
2500b57cec5SDimitry Andric       const RegUnit &RU = RegBank.getRegUnit(UnitIdx);
2510b57cec5SDimitry Andric       assert(RU.Weight < 256 && "RegUnit too heavy");
2520b57cec5SDimitry Andric       OS << RU.Weight << ", ";
2530b57cec5SDimitry Andric     }
2540b57cec5SDimitry Andric     OS << "};\n"
2550b57cec5SDimitry Andric        << "  return RUWeightTable[RegUnit];\n";
256*0fca6ea1SDimitry Andric   } else {
2570b57cec5SDimitry Andric     OS << "  // All register units have unit weight.\n"
2580b57cec5SDimitry Andric        << "  return 1;\n";
2590b57cec5SDimitry Andric   }
2600b57cec5SDimitry Andric   OS << "}\n\n";
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric   OS << "\n"
2630b57cec5SDimitry Andric      << "// Get the number of dimensions of register pressure.\n"
2640b57cec5SDimitry Andric      << "unsigned " << ClassName << "::getNumRegPressureSets() const {\n"
2650b57cec5SDimitry Andric      << "  return " << NumSets << ";\n}\n\n";
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric   OS << "// Get the name of this register unit pressure set.\n"
2680b57cec5SDimitry Andric      << "const char *" << ClassName << "::\n"
2690b57cec5SDimitry Andric      << "getRegPressureSetName(unsigned Idx) const {\n"
27081ad6265SDimitry Andric      << "  static const char *PressureNameTable[] = {\n";
2710b57cec5SDimitry Andric   unsigned MaxRegUnitWeight = 0;
2720b57cec5SDimitry Andric   for (unsigned i = 0; i < NumSets; ++i) {
2730b57cec5SDimitry Andric     const RegUnitSet &RegUnits = RegBank.getRegSetAt(i);
2740b57cec5SDimitry Andric     MaxRegUnitWeight = std::max(MaxRegUnitWeight, RegUnits.Weight);
2750b57cec5SDimitry Andric     OS << "    \"" << RegUnits.Name << "\",\n";
2760b57cec5SDimitry Andric   }
2770b57cec5SDimitry Andric   OS << "  };\n"
2780b57cec5SDimitry Andric      << "  return PressureNameTable[Idx];\n"
2790b57cec5SDimitry Andric      << "}\n\n";
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   OS << "// Get the register unit pressure limit for this dimension.\n"
2820b57cec5SDimitry Andric      << "// This limit must be adjusted dynamically for reserved registers.\n"
2830b57cec5SDimitry Andric      << "unsigned " << ClassName << "::\n"
2840b57cec5SDimitry Andric      << "getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const "
2850b57cec5SDimitry Andric         "{\n"
2860b57cec5SDimitry Andric      << "  static const " << getMinimalTypeForRange(MaxRegUnitWeight, 32)
2870b57cec5SDimitry Andric      << " PressureLimitTable[] = {\n";
2880b57cec5SDimitry Andric   for (unsigned i = 0; i < NumSets; ++i) {
2890b57cec5SDimitry Andric     const RegUnitSet &RegUnits = RegBank.getRegSetAt(i);
290*0fca6ea1SDimitry Andric     OS << "    " << RegUnits.Weight << ",  \t// " << i << ": " << RegUnits.Name
291*0fca6ea1SDimitry Andric        << "\n";
2920b57cec5SDimitry Andric   }
2930b57cec5SDimitry Andric   OS << "  };\n"
2940b57cec5SDimitry Andric      << "  return PressureLimitTable[Idx];\n"
2950b57cec5SDimitry Andric      << "}\n\n";
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric   SequenceToOffsetTable<std::vector<int>> PSetsSeqs;
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   // This table may be larger than NumRCs if some register units needed a list
3000b57cec5SDimitry Andric   // of unit sets that did not correspond to a register class.
3010b57cec5SDimitry Andric   unsigned NumRCUnitSets = RegBank.getNumRegClassPressureSetLists();
3020b57cec5SDimitry Andric   std::vector<std::vector<int>> PSets(NumRCUnitSets);
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric   for (unsigned i = 0, e = NumRCUnitSets; i != e; ++i) {
3050b57cec5SDimitry Andric     ArrayRef<unsigned> PSetIDs = RegBank.getRCPressureSetIDs(i);
3060b57cec5SDimitry Andric     PSets[i].reserve(PSetIDs.size());
307fe6060f1SDimitry Andric     for (unsigned PSetID : PSetIDs) {
308fe6060f1SDimitry Andric       PSets[i].push_back(RegBank.getRegPressureSet(PSetID).Order);
3090b57cec5SDimitry Andric     }
3100b57cec5SDimitry Andric     llvm::sort(PSets[i]);
3110b57cec5SDimitry Andric     PSetsSeqs.add(PSets[i]);
3120b57cec5SDimitry Andric   }
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   PSetsSeqs.layout();
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric   OS << "/// Table of pressure sets per register class or unit.\n"
3170b57cec5SDimitry Andric      << "static const int RCSetsTable[] = {\n";
3180b57cec5SDimitry Andric   PSetsSeqs.emit(OS, printInt, "-1");
3190b57cec5SDimitry Andric   OS << "};\n\n";
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   OS << "/// Get the dimensions of register pressure impacted by this "
3220b57cec5SDimitry Andric      << "register class.\n"
3230b57cec5SDimitry Andric      << "/// Returns a -1 terminated array of pressure set IDs\n"
3240b57cec5SDimitry Andric      << "const int *" << ClassName << "::\n"
3250b57cec5SDimitry Andric      << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n";
3260b57cec5SDimitry Andric   OS << "  static const " << getMinimalTypeForRange(PSetsSeqs.size() - 1, 32)
3270b57cec5SDimitry Andric      << " RCSetStartTable[] = {\n    ";
3280b57cec5SDimitry Andric   for (unsigned i = 0, e = NumRCs; i != e; ++i) {
3290b57cec5SDimitry Andric     OS << PSetsSeqs.get(PSets[i]) << ",";
3300b57cec5SDimitry Andric   }
3310b57cec5SDimitry Andric   OS << "};\n"
3320b57cec5SDimitry Andric      << "  return &RCSetsTable[RCSetStartTable[RC->getID()]];\n"
3330b57cec5SDimitry Andric      << "}\n\n";
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric   OS << "/// Get the dimensions of register pressure impacted by this "
3360b57cec5SDimitry Andric      << "register unit.\n"
3370b57cec5SDimitry Andric      << "/// Returns a -1 terminated array of pressure set IDs\n"
3380b57cec5SDimitry Andric      << "const int *" << ClassName << "::\n"
3390b57cec5SDimitry Andric      << "getRegUnitPressureSets(unsigned RegUnit) const {\n"
3400b57cec5SDimitry Andric      << "  assert(RegUnit < " << RegBank.getNumNativeRegUnits()
3410b57cec5SDimitry Andric      << " && \"invalid register unit\");\n";
3420b57cec5SDimitry Andric   OS << "  static const " << getMinimalTypeForRange(PSetsSeqs.size() - 1, 32)
3430b57cec5SDimitry Andric      << " RUSetStartTable[] = {\n    ";
3440b57cec5SDimitry Andric   for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
3450b57cec5SDimitry Andric        UnitIdx < UnitEnd; ++UnitIdx) {
3460b57cec5SDimitry Andric     OS << PSetsSeqs.get(PSets[RegBank.getRegUnit(UnitIdx).RegClassUnitSetsIdx])
3470b57cec5SDimitry Andric        << ",";
3480b57cec5SDimitry Andric   }
3490b57cec5SDimitry Andric   OS << "};\n"
3500b57cec5SDimitry Andric      << "  return &RCSetsTable[RUSetStartTable[RegUnit]];\n"
3510b57cec5SDimitry Andric      << "}\n\n";
3520b57cec5SDimitry Andric }
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric using DwarfRegNumsMapPair = std::pair<Record *, std::vector<int64_t>>;
3550b57cec5SDimitry Andric using DwarfRegNumsVecTy = std::vector<DwarfRegNumsMapPair>;
3560b57cec5SDimitry Andric 
357e8d8bef9SDimitry Andric static void finalizeDwarfRegNumsKeys(DwarfRegNumsVecTy &DwarfRegNums) {
3580b57cec5SDimitry Andric   // Sort and unique to get a map-like vector. We want the last assignment to
3590b57cec5SDimitry Andric   // match previous behaviour.
360e8d8bef9SDimitry Andric   llvm::stable_sort(DwarfRegNums, on_first<LessRecordRegister>());
3610b57cec5SDimitry Andric   // Warn about duplicate assignments.
3620b57cec5SDimitry Andric   const Record *LastSeenReg = nullptr;
3630b57cec5SDimitry Andric   for (const auto &X : DwarfRegNums) {
3640b57cec5SDimitry Andric     const auto &Reg = X.first;
3650b57cec5SDimitry Andric     // The only way LessRecordRegister can return equal is if they're the same
3660b57cec5SDimitry Andric     // string. Use simple equality instead.
3670b57cec5SDimitry Andric     if (LastSeenReg && Reg->getName() == LastSeenReg->getName())
3680b57cec5SDimitry Andric       PrintWarning(Reg->getLoc(), Twine("DWARF numbers for register ") +
3690b57cec5SDimitry Andric                                       getQualifiedName(Reg) +
3700b57cec5SDimitry Andric                                       "specified multiple times");
3710b57cec5SDimitry Andric     LastSeenReg = Reg;
3720b57cec5SDimitry Andric   }
373*0fca6ea1SDimitry Andric   auto Last = llvm::unique(DwarfRegNums, [](const DwarfRegNumsMapPair &A,
374*0fca6ea1SDimitry Andric                                             const DwarfRegNumsMapPair &B) {
3750b57cec5SDimitry Andric     return A.first->getName() == B.first->getName();
3760b57cec5SDimitry Andric   });
3770b57cec5SDimitry Andric   DwarfRegNums.erase(Last, DwarfRegNums.end());
3780b57cec5SDimitry Andric }
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric void RegisterInfoEmitter::EmitRegMappingTables(
3810b57cec5SDimitry Andric     raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) {
3820b57cec5SDimitry Andric   // Collect all information about dwarf register numbers
3830b57cec5SDimitry Andric   DwarfRegNumsVecTy DwarfRegNums;
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric   // First, just pull all provided information to the map
3860b57cec5SDimitry Andric   unsigned maxLength = 0;
3870b57cec5SDimitry Andric   for (auto &RE : Regs) {
3880b57cec5SDimitry Andric     Record *Reg = RE.TheDef;
3890b57cec5SDimitry Andric     std::vector<int64_t> RegNums = Reg->getValueAsListOfInts("DwarfNumbers");
3900b57cec5SDimitry Andric     maxLength = std::max((size_t)maxLength, RegNums.size());
3910b57cec5SDimitry Andric     DwarfRegNums.emplace_back(Reg, std::move(RegNums));
3920b57cec5SDimitry Andric   }
3930b57cec5SDimitry Andric   finalizeDwarfRegNumsKeys(DwarfRegNums);
3940b57cec5SDimitry Andric 
3950b57cec5SDimitry Andric   if (!maxLength)
3960b57cec5SDimitry Andric     return;
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric   // Now we know maximal length of number list. Append -1's, where needed
399fe6060f1SDimitry Andric   for (auto &DwarfRegNum : DwarfRegNums)
400fe6060f1SDimitry Andric     for (unsigned I = DwarfRegNum.second.size(), E = maxLength; I != E; ++I)
401fe6060f1SDimitry Andric       DwarfRegNum.second.push_back(-1);
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric   StringRef Namespace = Regs.front().TheDef->getValueAsString("Namespace");
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric   OS << "// " << Namespace << " Dwarf<->LLVM register mappings.\n";
4060b57cec5SDimitry Andric 
4070b57cec5SDimitry Andric   // Emit reverse information about the dwarf register numbers.
4080b57cec5SDimitry Andric   for (unsigned j = 0; j < 2; ++j) {
409fe6060f1SDimitry Andric     for (unsigned I = 0, E = maxLength; I != E; ++I) {
4100b57cec5SDimitry Andric       OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;
4110b57cec5SDimitry Andric       OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");
412fe6060f1SDimitry Andric       OS << I << "Dwarf2L[]";
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric       if (!isCtor) {
4150b57cec5SDimitry Andric         OS << " = {\n";
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric         // Store the mapping sorted by the LLVM reg num so lookup can be done
4180b57cec5SDimitry Andric         // with a binary search.
4190b57cec5SDimitry Andric         std::map<uint64_t, Record *> Dwarf2LMap;
420fe6060f1SDimitry Andric         for (auto &DwarfRegNum : DwarfRegNums) {
421fe6060f1SDimitry Andric           int DwarfRegNo = DwarfRegNum.second[I];
4220b57cec5SDimitry Andric           if (DwarfRegNo < 0)
4230b57cec5SDimitry Andric             continue;
424fe6060f1SDimitry Andric           Dwarf2LMap[DwarfRegNo] = DwarfRegNum.first;
4250b57cec5SDimitry Andric         }
4260b57cec5SDimitry Andric 
427fe6060f1SDimitry Andric         for (auto &I : Dwarf2LMap)
428fe6060f1SDimitry Andric           OS << "  { " << I.first << "U, " << getQualifiedName(I.second)
4290b57cec5SDimitry Andric              << " },\n";
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric         OS << "};\n";
4320b57cec5SDimitry Andric       } else {
4330b57cec5SDimitry Andric         OS << ";\n";
4340b57cec5SDimitry Andric       }
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric       // We have to store the size in a const global, it's used in multiple
4370b57cec5SDimitry Andric       // places.
4380b57cec5SDimitry Andric       OS << "extern const unsigned " << Namespace
439fe6060f1SDimitry Andric          << (j == 0 ? "DwarfFlavour" : "EHFlavour") << I << "Dwarf2LSize";
4400b57cec5SDimitry Andric       if (!isCtor)
441bdd1243dSDimitry Andric         OS << " = std::size(" << Namespace
442fe6060f1SDimitry Andric            << (j == 0 ? "DwarfFlavour" : "EHFlavour") << I << "Dwarf2L);\n\n";
4430b57cec5SDimitry Andric       else
4440b57cec5SDimitry Andric         OS << ";\n\n";
4450b57cec5SDimitry Andric     }
4460b57cec5SDimitry Andric   }
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric   for (auto &RE : Regs) {
4490b57cec5SDimitry Andric     Record *Reg = RE.TheDef;
4500b57cec5SDimitry Andric     const RecordVal *V = Reg->getValue("DwarfAlias");
4510b57cec5SDimitry Andric     if (!V || !V->getValue())
4520b57cec5SDimitry Andric       continue;
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric     DefInit *DI = cast<DefInit>(V->getValue());
4550b57cec5SDimitry Andric     Record *Alias = DI->getDef();
456e8d8bef9SDimitry Andric     const auto &AliasIter = llvm::lower_bound(
457e8d8bef9SDimitry Andric         DwarfRegNums, Alias, [](const DwarfRegNumsMapPair &A, const Record *B) {
4580b57cec5SDimitry Andric           return LessRecordRegister()(A.first, B);
4590b57cec5SDimitry Andric         });
4600b57cec5SDimitry Andric     assert(AliasIter != DwarfRegNums.end() && AliasIter->first == Alias &&
4610b57cec5SDimitry Andric            "Expected Alias to be present in map");
462e8d8bef9SDimitry Andric     const auto &RegIter = llvm::lower_bound(
463e8d8bef9SDimitry Andric         DwarfRegNums, Reg, [](const DwarfRegNumsMapPair &A, const Record *B) {
4640b57cec5SDimitry Andric           return LessRecordRegister()(A.first, B);
4650b57cec5SDimitry Andric         });
4660b57cec5SDimitry Andric     assert(RegIter != DwarfRegNums.end() && RegIter->first == Reg &&
4670b57cec5SDimitry Andric            "Expected Reg to be present in map");
4680b57cec5SDimitry Andric     RegIter->second = AliasIter->second;
4690b57cec5SDimitry Andric   }
4700b57cec5SDimitry Andric 
4710b57cec5SDimitry Andric   // Emit information about the dwarf register numbers.
4720b57cec5SDimitry Andric   for (unsigned j = 0; j < 2; ++j) {
4730b57cec5SDimitry Andric     for (unsigned i = 0, e = maxLength; i != e; ++i) {
4740b57cec5SDimitry Andric       OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;
4750b57cec5SDimitry Andric       OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");
4760b57cec5SDimitry Andric       OS << i << "L2Dwarf[]";
4770b57cec5SDimitry Andric       if (!isCtor) {
4780b57cec5SDimitry Andric         OS << " = {\n";
4790b57cec5SDimitry Andric         // Store the mapping sorted by the Dwarf reg num so lookup can be done
4800b57cec5SDimitry Andric         // with a binary search.
481fe6060f1SDimitry Andric         for (auto &DwarfRegNum : DwarfRegNums) {
482fe6060f1SDimitry Andric           int RegNo = DwarfRegNum.second[i];
4830b57cec5SDimitry Andric           if (RegNo == -1) // -1 is the default value, don't emit a mapping.
4840b57cec5SDimitry Andric             continue;
4850b57cec5SDimitry Andric 
486fe6060f1SDimitry Andric           OS << "  { " << getQualifiedName(DwarfRegNum.first) << ", " << RegNo
4870b57cec5SDimitry Andric              << "U },\n";
4880b57cec5SDimitry Andric         }
4890b57cec5SDimitry Andric         OS << "};\n";
4900b57cec5SDimitry Andric       } else {
4910b57cec5SDimitry Andric         OS << ";\n";
4920b57cec5SDimitry Andric       }
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric       // We have to store the size in a const global, it's used in multiple
4950b57cec5SDimitry Andric       // places.
4960b57cec5SDimitry Andric       OS << "extern const unsigned " << Namespace
4970b57cec5SDimitry Andric          << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "L2DwarfSize";
4980b57cec5SDimitry Andric       if (!isCtor)
499bdd1243dSDimitry Andric         OS << " = std::size(" << Namespace
5000b57cec5SDimitry Andric            << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "L2Dwarf);\n\n";
5010b57cec5SDimitry Andric       else
5020b57cec5SDimitry Andric         OS << ";\n\n";
5030b57cec5SDimitry Andric     }
5040b57cec5SDimitry Andric   }
5050b57cec5SDimitry Andric }
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric void RegisterInfoEmitter::EmitRegMapping(
5080b57cec5SDimitry Andric     raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) {
5090b57cec5SDimitry Andric   // Emit the initializer so the tables from EmitRegMappingTables get wired up
5100b57cec5SDimitry Andric   // to the MCRegisterInfo object.
5110b57cec5SDimitry Andric   unsigned maxLength = 0;
5120b57cec5SDimitry Andric   for (auto &RE : Regs) {
5130b57cec5SDimitry Andric     Record *Reg = RE.TheDef;
5140b57cec5SDimitry Andric     maxLength = std::max((size_t)maxLength,
5150b57cec5SDimitry Andric                          Reg->getValueAsListOfInts("DwarfNumbers").size());
5160b57cec5SDimitry Andric   }
5170b57cec5SDimitry Andric 
5180b57cec5SDimitry Andric   if (!maxLength)
5190b57cec5SDimitry Andric     return;
5200b57cec5SDimitry Andric 
5210b57cec5SDimitry Andric   StringRef Namespace = Regs.front().TheDef->getValueAsString("Namespace");
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric   // Emit reverse information about the dwarf register numbers.
5240b57cec5SDimitry Andric   for (unsigned j = 0; j < 2; ++j) {
5250b57cec5SDimitry Andric     OS << "  switch (";
5260b57cec5SDimitry Andric     if (j == 0)
5270b57cec5SDimitry Andric       OS << "DwarfFlavour";
5280b57cec5SDimitry Andric     else
5290b57cec5SDimitry Andric       OS << "EHFlavour";
5300b57cec5SDimitry Andric     OS << ") {\n"
5310b57cec5SDimitry Andric        << "  default:\n"
5320b57cec5SDimitry Andric        << "    llvm_unreachable(\"Unknown DWARF flavour\");\n";
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric     for (unsigned i = 0, e = maxLength; i != e; ++i) {
5350b57cec5SDimitry Andric       OS << "  case " << i << ":\n";
5360b57cec5SDimitry Andric       OS << "    ";
5370b57cec5SDimitry Andric       if (!isCtor)
5380b57cec5SDimitry Andric         OS << "RI->";
5390b57cec5SDimitry Andric       std::string Tmp;
540*0fca6ea1SDimitry Andric       raw_string_ostream(Tmp)
541*0fca6ea1SDimitry Andric           << Namespace << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
5420b57cec5SDimitry Andric           << "Dwarf2L";
5430b57cec5SDimitry Andric       OS << "mapDwarfRegsToLLVMRegs(" << Tmp << ", " << Tmp << "Size, ";
5440b57cec5SDimitry Andric       if (j == 0)
5450b57cec5SDimitry Andric         OS << "false";
5460b57cec5SDimitry Andric       else
5470b57cec5SDimitry Andric         OS << "true";
5480b57cec5SDimitry Andric       OS << ");\n";
5490b57cec5SDimitry Andric       OS << "    break;\n";
5500b57cec5SDimitry Andric     }
5510b57cec5SDimitry Andric     OS << "  }\n";
5520b57cec5SDimitry Andric   }
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric   // Emit information about the dwarf register numbers.
5550b57cec5SDimitry Andric   for (unsigned j = 0; j < 2; ++j) {
5560b57cec5SDimitry Andric     OS << "  switch (";
5570b57cec5SDimitry Andric     if (j == 0)
5580b57cec5SDimitry Andric       OS << "DwarfFlavour";
5590b57cec5SDimitry Andric     else
5600b57cec5SDimitry Andric       OS << "EHFlavour";
5610b57cec5SDimitry Andric     OS << ") {\n"
5620b57cec5SDimitry Andric        << "  default:\n"
5630b57cec5SDimitry Andric        << "    llvm_unreachable(\"Unknown DWARF flavour\");\n";
5640b57cec5SDimitry Andric 
5650b57cec5SDimitry Andric     for (unsigned i = 0, e = maxLength; i != e; ++i) {
5660b57cec5SDimitry Andric       OS << "  case " << i << ":\n";
5670b57cec5SDimitry Andric       OS << "    ";
5680b57cec5SDimitry Andric       if (!isCtor)
5690b57cec5SDimitry Andric         OS << "RI->";
5700b57cec5SDimitry Andric       std::string Tmp;
571*0fca6ea1SDimitry Andric       raw_string_ostream(Tmp)
572*0fca6ea1SDimitry Andric           << Namespace << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
5730b57cec5SDimitry Andric           << "L2Dwarf";
5740b57cec5SDimitry Andric       OS << "mapLLVMRegsToDwarfRegs(" << Tmp << ", " << Tmp << "Size, ";
5750b57cec5SDimitry Andric       if (j == 0)
5760b57cec5SDimitry Andric         OS << "false";
5770b57cec5SDimitry Andric       else
5780b57cec5SDimitry Andric         OS << "true";
5790b57cec5SDimitry Andric       OS << ");\n";
5800b57cec5SDimitry Andric       OS << "    break;\n";
5810b57cec5SDimitry Andric     }
5820b57cec5SDimitry Andric     OS << "  }\n";
5830b57cec5SDimitry Andric   }
5840b57cec5SDimitry Andric }
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric // Print a BitVector as a sequence of hex numbers using a little-endian mapping.
5870b57cec5SDimitry Andric // Width is the number of bits per hex number.
588*0fca6ea1SDimitry Andric static void printBitVectorAsHex(raw_ostream &OS, const BitVector &Bits,
5890b57cec5SDimitry Andric                                 unsigned Width) {
5900b57cec5SDimitry Andric   assert(Width <= 32 && "Width too large");
5910b57cec5SDimitry Andric   unsigned Digits = (Width + 3) / 4;
5920b57cec5SDimitry Andric   for (unsigned i = 0, e = Bits.size(); i < e; i += Width) {
5930b57cec5SDimitry Andric     unsigned Value = 0;
5940b57cec5SDimitry Andric     for (unsigned j = 0; j != Width && i + j != e; ++j)
5950b57cec5SDimitry Andric       Value |= Bits.test(i + j) << j;
5960b57cec5SDimitry Andric     OS << format("0x%0*x, ", Digits, Value);
5970b57cec5SDimitry Andric   }
5980b57cec5SDimitry Andric }
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric // Helper to emit a set of bits into a constant byte array.
6010b57cec5SDimitry Andric class BitVectorEmitter {
6020b57cec5SDimitry Andric   BitVector Values;
603*0fca6ea1SDimitry Andric 
6040b57cec5SDimitry Andric public:
6050b57cec5SDimitry Andric   void add(unsigned v) {
6060b57cec5SDimitry Andric     if (v >= Values.size())
6070b57cec5SDimitry Andric       Values.resize(((v / 8) + 1) * 8); // Round up to the next byte.
6080b57cec5SDimitry Andric     Values[v] = true;
6090b57cec5SDimitry Andric   }
6100b57cec5SDimitry Andric 
611*0fca6ea1SDimitry Andric   void print(raw_ostream &OS) { printBitVectorAsHex(OS, Values, 8); }
6120b57cec5SDimitry Andric };
6130b57cec5SDimitry Andric 
6140b57cec5SDimitry Andric static void printSimpleValueType(raw_ostream &OS, MVT::SimpleValueType VT) {
6150b57cec5SDimitry Andric   OS << getEnumName(VT);
6160b57cec5SDimitry Andric }
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric static void printSubRegIndex(raw_ostream &OS, const CodeGenSubRegIndex *Idx) {
6190b57cec5SDimitry Andric   OS << Idx->EnumValue;
6200b57cec5SDimitry Andric }
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric // Differentially encoded register and regunit lists allow for better
6230b57cec5SDimitry Andric // compression on regular register banks. The sequence is computed from the
6240b57cec5SDimitry Andric // differential list as:
6250b57cec5SDimitry Andric //
6260b57cec5SDimitry Andric //   out[0] = InitVal;
6270b57cec5SDimitry Andric //   out[n+1] = out[n] + diff[n]; // n = 0, 1, ...
6280b57cec5SDimitry Andric //
6290b57cec5SDimitry Andric // The initial value depends on the specific list. The list is terminated by a
6300b57cec5SDimitry Andric // 0 differential which means we can't encode repeated elements.
6310b57cec5SDimitry Andric 
63206c3fb27SDimitry Andric typedef SmallVector<int16_t, 4> DiffVec;
6330b57cec5SDimitry Andric typedef SmallVector<LaneBitmask, 4> MaskVec;
6340b57cec5SDimitry Andric 
63506c3fb27SDimitry Andric // Fills V with differentials between every two consecutive elements of List.
63606c3fb27SDimitry Andric static DiffVec &diffEncode(DiffVec &V, SparseBitVector<> List) {
6370b57cec5SDimitry Andric   assert(V.empty() && "Clear DiffVec before diffEncode.");
63806c3fb27SDimitry Andric   SparseBitVector<>::iterator I = List.begin(), E = List.end();
63906c3fb27SDimitry Andric   unsigned Val = *I;
64006c3fb27SDimitry Andric   while (++I != E) {
64106c3fb27SDimitry Andric     unsigned Cur = *I;
6420b57cec5SDimitry Andric     V.push_back(Cur - Val);
6430b57cec5SDimitry Andric     Val = Cur;
6440b57cec5SDimitry Andric   }
6450b57cec5SDimitry Andric   return V;
6460b57cec5SDimitry Andric }
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric template <typename Iter>
649*0fca6ea1SDimitry Andric static DiffVec &diffEncode(DiffVec &V, unsigned InitVal, Iter Begin, Iter End) {
6500b57cec5SDimitry Andric   assert(V.empty() && "Clear DiffVec before diffEncode.");
65106c3fb27SDimitry Andric   unsigned Val = InitVal;
6520b57cec5SDimitry Andric   for (Iter I = Begin; I != End; ++I) {
65306c3fb27SDimitry Andric     unsigned Cur = (*I)->EnumValue;
6540b57cec5SDimitry Andric     V.push_back(Cur - Val);
6550b57cec5SDimitry Andric     Val = Cur;
6560b57cec5SDimitry Andric   }
6570b57cec5SDimitry Andric   return V;
6580b57cec5SDimitry Andric }
6590b57cec5SDimitry Andric 
66006c3fb27SDimitry Andric static void printDiff16(raw_ostream &OS, int16_t Val) { OS << Val; }
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric static void printMask(raw_ostream &OS, LaneBitmask Val) {
6630b57cec5SDimitry Andric   OS << "LaneBitmask(0x" << PrintLaneMask(Val) << ')';
6640b57cec5SDimitry Andric }
6650b57cec5SDimitry Andric 
6660b57cec5SDimitry Andric // Try to combine Idx's compose map into Vec if it is compatible.
6670b57cec5SDimitry Andric // Return false if it's not possible.
6680b57cec5SDimitry Andric static bool combine(const CodeGenSubRegIndex *Idx,
6690b57cec5SDimitry Andric                     SmallVectorImpl<CodeGenSubRegIndex *> &Vec) {
6700b57cec5SDimitry Andric   const CodeGenSubRegIndex::CompMap &Map = Idx->getComposites();
6710b57cec5SDimitry Andric   for (const auto &I : Map) {
6720b57cec5SDimitry Andric     CodeGenSubRegIndex *&Entry = Vec[I.first->EnumValue - 1];
6730b57cec5SDimitry Andric     if (Entry && Entry != I.second)
6740b57cec5SDimitry Andric       return false;
6750b57cec5SDimitry Andric   }
6760b57cec5SDimitry Andric 
6770b57cec5SDimitry Andric   // All entries are compatible. Make it so.
6780b57cec5SDimitry Andric   for (const auto &I : Map) {
6790b57cec5SDimitry Andric     auto *&Entry = Vec[I.first->EnumValue - 1];
680*0fca6ea1SDimitry Andric     assert((!Entry || Entry == I.second) && "Expected EnumValue to be unique");
6810b57cec5SDimitry Andric     Entry = I.second;
6820b57cec5SDimitry Andric   }
6830b57cec5SDimitry Andric   return true;
6840b57cec5SDimitry Andric }
6850b57cec5SDimitry Andric 
686*0fca6ea1SDimitry Andric void RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS,
6870b57cec5SDimitry Andric                                                    CodeGenRegBank &RegBank,
6880b57cec5SDimitry Andric                                                    const std::string &ClName) {
6890b57cec5SDimitry Andric   const auto &SubRegIndices = RegBank.getSubRegIndices();
6900b57cec5SDimitry Andric   OS << "unsigned " << ClName
6910b57cec5SDimitry Andric      << "::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {\n";
6920b57cec5SDimitry Andric 
6930b57cec5SDimitry Andric   // Many sub-register indexes are composition-compatible, meaning that
6940b57cec5SDimitry Andric   //
6950b57cec5SDimitry Andric   //   compose(IdxA, IdxB) == compose(IdxA', IdxB)
6960b57cec5SDimitry Andric   //
6970b57cec5SDimitry Andric   // for many IdxA, IdxA' pairs. Not all sub-register indexes can be composed.
6980b57cec5SDimitry Andric   // The illegal entries can be use as wildcards to compress the table further.
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   // Map each Sub-register index to a compatible table row.
7010b57cec5SDimitry Andric   SmallVector<unsigned, 4> RowMap;
7020b57cec5SDimitry Andric   SmallVector<SmallVector<CodeGenSubRegIndex *, 4>, 4> Rows;
7030b57cec5SDimitry Andric 
7040b57cec5SDimitry Andric   auto SubRegIndicesSize =
7050b57cec5SDimitry Andric       std::distance(SubRegIndices.begin(), SubRegIndices.end());
7060b57cec5SDimitry Andric   for (const auto &Idx : SubRegIndices) {
7070b57cec5SDimitry Andric     unsigned Found = ~0u;
7080b57cec5SDimitry Andric     for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
7090b57cec5SDimitry Andric       if (combine(&Idx, Rows[r])) {
7100b57cec5SDimitry Andric         Found = r;
7110b57cec5SDimitry Andric         break;
7120b57cec5SDimitry Andric       }
7130b57cec5SDimitry Andric     }
7140b57cec5SDimitry Andric     if (Found == ~0u) {
7150b57cec5SDimitry Andric       Found = Rows.size();
7160b57cec5SDimitry Andric       Rows.resize(Found + 1);
7170b57cec5SDimitry Andric       Rows.back().resize(SubRegIndicesSize);
7180b57cec5SDimitry Andric       combine(&Idx, Rows.back());
7190b57cec5SDimitry Andric     }
7200b57cec5SDimitry Andric     RowMap.push_back(Found);
7210b57cec5SDimitry Andric   }
7220b57cec5SDimitry Andric 
7230b57cec5SDimitry Andric   // Output the row map if there is multiple rows.
7240b57cec5SDimitry Andric   if (Rows.size() > 1) {
7250b57cec5SDimitry Andric     OS << "  static const " << getMinimalTypeForRange(Rows.size(), 32)
7260b57cec5SDimitry Andric        << " RowMap[" << SubRegIndicesSize << "] = {\n    ";
7270b57cec5SDimitry Andric     for (unsigned i = 0, e = SubRegIndicesSize; i != e; ++i)
7280b57cec5SDimitry Andric       OS << RowMap[i] << ", ";
7290b57cec5SDimitry Andric     OS << "\n  };\n";
7300b57cec5SDimitry Andric   }
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric   // Output the rows.
7330b57cec5SDimitry Andric   OS << "  static const " << getMinimalTypeForRange(SubRegIndicesSize + 1, 32)
7340b57cec5SDimitry Andric      << " Rows[" << Rows.size() << "][" << SubRegIndicesSize << "] = {\n";
7350b57cec5SDimitry Andric   for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
7360b57cec5SDimitry Andric     OS << "    { ";
7370b57cec5SDimitry Andric     for (unsigned i = 0, e = SubRegIndicesSize; i != e; ++i)
7380b57cec5SDimitry Andric       if (Rows[r][i])
739480093f4SDimitry Andric         OS << Rows[r][i]->getQualifiedName() << ", ";
7400b57cec5SDimitry Andric       else
7410b57cec5SDimitry Andric         OS << "0, ";
7420b57cec5SDimitry Andric     OS << "},\n";
7430b57cec5SDimitry Andric   }
7440b57cec5SDimitry Andric   OS << "  };\n\n";
7450b57cec5SDimitry Andric 
74681ad6265SDimitry Andric   OS << "  --IdxA; assert(IdxA < " << SubRegIndicesSize << "); (void) IdxA;\n"
7470b57cec5SDimitry Andric      << "  --IdxB; assert(IdxB < " << SubRegIndicesSize << ");\n";
7480b57cec5SDimitry Andric   if (Rows.size() > 1)
7490b57cec5SDimitry Andric     OS << "  return Rows[RowMap[IdxA]][IdxB];\n";
7500b57cec5SDimitry Andric   else
7510b57cec5SDimitry Andric     OS << "  return Rows[0][IdxB];\n";
7520b57cec5SDimitry Andric   OS << "}\n\n";
7530b57cec5SDimitry Andric }
7540b57cec5SDimitry Andric 
755*0fca6ea1SDimitry Andric void RegisterInfoEmitter::emitComposeSubRegIndexLaneMask(
756*0fca6ea1SDimitry Andric     raw_ostream &OS, CodeGenRegBank &RegBank, const std::string &ClName) {
7570b57cec5SDimitry Andric   // See the comments in computeSubRegLaneMasks() for our goal here.
7580b57cec5SDimitry Andric   const auto &SubRegIndices = RegBank.getSubRegIndices();
7590b57cec5SDimitry Andric 
7600b57cec5SDimitry Andric   // Create a list of Mask+Rotate operations, with equivalent entries merged.
7610b57cec5SDimitry Andric   SmallVector<unsigned, 4> SubReg2SequenceIndexMap;
7620b57cec5SDimitry Andric   SmallVector<SmallVector<MaskRolPair, 1>, 4> Sequences;
7630b57cec5SDimitry Andric   for (const auto &Idx : SubRegIndices) {
764*0fca6ea1SDimitry Andric     const SmallVector<MaskRolPair, 1> &IdxSequence =
765*0fca6ea1SDimitry Andric         Idx.CompositionLaneMaskTransform;
7660b57cec5SDimitry Andric 
7670b57cec5SDimitry Andric     unsigned Found = ~0u;
7680b57cec5SDimitry Andric     unsigned SIdx = 0;
7690b57cec5SDimitry Andric     unsigned NextSIdx;
7700b57cec5SDimitry Andric     for (size_t s = 0, se = Sequences.size(); s != se; ++s, SIdx = NextSIdx) {
7710b57cec5SDimitry Andric       SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
7720b57cec5SDimitry Andric       NextSIdx = SIdx + Sequence.size() + 1;
7730b57cec5SDimitry Andric       if (Sequence == IdxSequence) {
7740b57cec5SDimitry Andric         Found = SIdx;
7750b57cec5SDimitry Andric         break;
7760b57cec5SDimitry Andric       }
7770b57cec5SDimitry Andric     }
7780b57cec5SDimitry Andric     if (Found == ~0u) {
7790b57cec5SDimitry Andric       Sequences.push_back(IdxSequence);
7800b57cec5SDimitry Andric       Found = SIdx;
7810b57cec5SDimitry Andric     }
7820b57cec5SDimitry Andric     SubReg2SequenceIndexMap.push_back(Found);
7830b57cec5SDimitry Andric   }
7840b57cec5SDimitry Andric 
7850b57cec5SDimitry Andric   OS << "  struct MaskRolOp {\n"
7860b57cec5SDimitry Andric         "    LaneBitmask Mask;\n"
7870b57cec5SDimitry Andric         "    uint8_t  RotateLeft;\n"
7880b57cec5SDimitry Andric         "  };\n"
7890b57cec5SDimitry Andric         "  static const MaskRolOp LaneMaskComposeSequences[] = {\n";
7900b57cec5SDimitry Andric   unsigned Idx = 0;
7910b57cec5SDimitry Andric   for (size_t s = 0, se = Sequences.size(); s != se; ++s) {
7920b57cec5SDimitry Andric     OS << "    ";
7930b57cec5SDimitry Andric     const SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
7940b57cec5SDimitry Andric     for (size_t p = 0, pe = Sequence.size(); p != pe; ++p) {
7950b57cec5SDimitry Andric       const MaskRolPair &P = Sequence[p];
7960b57cec5SDimitry Andric       printMask(OS << "{ ", P.Mask);
7970b57cec5SDimitry Andric       OS << format(", %2u }, ", P.RotateLeft);
7980b57cec5SDimitry Andric     }
7990b57cec5SDimitry Andric     OS << "{ LaneBitmask::getNone(), 0 }";
8000b57cec5SDimitry Andric     if (s + 1 != se)
8010b57cec5SDimitry Andric       OS << ", ";
8020b57cec5SDimitry Andric     OS << "  // Sequence " << Idx << "\n";
8030b57cec5SDimitry Andric     Idx += Sequence.size() + 1;
8040b57cec5SDimitry Andric   }
805*0fca6ea1SDimitry Andric   auto *IntType =
806*0fca6ea1SDimitry Andric       getMinimalTypeForRange(*llvm::max_element(SubReg2SequenceIndexMap));
8070b57cec5SDimitry Andric   OS << "  };\n"
80881ad6265SDimitry Andric         "  static const "
80981ad6265SDimitry Andric      << IntType << " CompositeSequences[] = {\n";
8100b57cec5SDimitry Andric   for (size_t i = 0, e = SubRegIndices.size(); i != e; ++i) {
8110b57cec5SDimitry Andric     OS << "    ";
81281ad6265SDimitry Andric     OS << SubReg2SequenceIndexMap[i];
8130b57cec5SDimitry Andric     if (i + 1 != e)
8140b57cec5SDimitry Andric       OS << ",";
8150b57cec5SDimitry Andric     OS << " // to " << SubRegIndices[i].getName() << "\n";
8160b57cec5SDimitry Andric   }
8170b57cec5SDimitry Andric   OS << "  };\n\n";
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   OS << "LaneBitmask " << ClName
8200b57cec5SDimitry Andric      << "::composeSubRegIndexLaneMaskImpl(unsigned IdxA, LaneBitmask LaneMask)"
8210b57cec5SDimitry Andric         " const {\n"
822*0fca6ea1SDimitry Andric         "  --IdxA; assert(IdxA < "
823*0fca6ea1SDimitry Andric      << SubRegIndices.size()
8240b57cec5SDimitry Andric      << " && \"Subregister index out of bounds\");\n"
8250b57cec5SDimitry Andric         "  LaneBitmask Result;\n"
82681ad6265SDimitry Andric         "  for (const MaskRolOp *Ops =\n"
82781ad6265SDimitry Andric         "       &LaneMaskComposeSequences[CompositeSequences[IdxA]];\n"
82881ad6265SDimitry Andric         "       Ops->Mask.any(); ++Ops) {\n"
829*0fca6ea1SDimitry Andric         "    LaneBitmask::Type M = LaneMask.getAsInteger() & "
830*0fca6ea1SDimitry Andric         "Ops->Mask.getAsInteger();\n"
8310b57cec5SDimitry Andric         "    if (unsigned S = Ops->RotateLeft)\n"
832*0fca6ea1SDimitry Andric         "      Result |= LaneBitmask((M << S) | (M >> (LaneBitmask::BitWidth - "
833*0fca6ea1SDimitry Andric         "S)));\n"
8340b57cec5SDimitry Andric         "    else\n"
8350b57cec5SDimitry Andric         "      Result |= LaneBitmask(M);\n"
8360b57cec5SDimitry Andric         "  }\n"
8370b57cec5SDimitry Andric         "  return Result;\n"
8380b57cec5SDimitry Andric         "}\n\n";
8390b57cec5SDimitry Andric 
8400b57cec5SDimitry Andric   OS << "LaneBitmask " << ClName
8410b57cec5SDimitry Andric      << "::reverseComposeSubRegIndexLaneMaskImpl(unsigned IdxA, "
8420b57cec5SDimitry Andric         " LaneBitmask LaneMask) const {\n"
8430b57cec5SDimitry Andric         "  LaneMask &= getSubRegIndexLaneMask(IdxA);\n"
844*0fca6ea1SDimitry Andric         "  --IdxA; assert(IdxA < "
845*0fca6ea1SDimitry Andric      << SubRegIndices.size()
8460b57cec5SDimitry Andric      << " && \"Subregister index out of bounds\");\n"
8470b57cec5SDimitry Andric         "  LaneBitmask Result;\n"
84881ad6265SDimitry Andric         "  for (const MaskRolOp *Ops =\n"
84981ad6265SDimitry Andric         "       &LaneMaskComposeSequences[CompositeSequences[IdxA]];\n"
85081ad6265SDimitry Andric         "       Ops->Mask.any(); ++Ops) {\n"
8510b57cec5SDimitry Andric         "    LaneBitmask::Type M = LaneMask.getAsInteger();\n"
8520b57cec5SDimitry Andric         "    if (unsigned S = Ops->RotateLeft)\n"
853*0fca6ea1SDimitry Andric         "      Result |= LaneBitmask((M >> S) | (M << (LaneBitmask::BitWidth - "
854*0fca6ea1SDimitry Andric         "S)));\n"
8550b57cec5SDimitry Andric         "    else\n"
8560b57cec5SDimitry Andric         "      Result |= LaneBitmask(M);\n"
8570b57cec5SDimitry Andric         "  }\n"
8580b57cec5SDimitry Andric         "  return Result;\n"
8590b57cec5SDimitry Andric         "}\n\n";
8600b57cec5SDimitry Andric }
8610b57cec5SDimitry Andric 
8620b57cec5SDimitry Andric //
8630b57cec5SDimitry Andric // runMCDesc - Print out MC register descriptions.
8640b57cec5SDimitry Andric //
865*0fca6ea1SDimitry Andric void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
8660b57cec5SDimitry Andric                                     CodeGenRegBank &RegBank) {
8670b57cec5SDimitry Andric   emitSourceFileHeader("MC Register Information", OS);
8680b57cec5SDimitry Andric 
8690b57cec5SDimitry Andric   OS << "\n#ifdef GET_REGINFO_MC_DESC\n";
8700b57cec5SDimitry Andric   OS << "#undef GET_REGINFO_MC_DESC\n\n";
8710b57cec5SDimitry Andric 
8720b57cec5SDimitry Andric   const auto &Regs = RegBank.getRegisters();
8730b57cec5SDimitry Andric 
8740b57cec5SDimitry Andric   auto &SubRegIndices = RegBank.getSubRegIndices();
8750b57cec5SDimitry Andric   // The lists of sub-registers and super-registers go in the same array.  That
8760b57cec5SDimitry Andric   // allows us to share suffixes.
8770b57cec5SDimitry Andric   typedef std::vector<const CodeGenRegister *> RegVec;
8780b57cec5SDimitry Andric 
8790b57cec5SDimitry Andric   // Differentially encoded lists.
8800b57cec5SDimitry Andric   SequenceToOffsetTable<DiffVec> DiffSeqs;
8810b57cec5SDimitry Andric   SmallVector<DiffVec, 4> SubRegLists(Regs.size());
8820b57cec5SDimitry Andric   SmallVector<DiffVec, 4> SuperRegLists(Regs.size());
8830b57cec5SDimitry Andric   SmallVector<DiffVec, 4> RegUnitLists(Regs.size());
8840b57cec5SDimitry Andric 
8850b57cec5SDimitry Andric   // List of lane masks accompanying register unit sequences.
8860b57cec5SDimitry Andric   SequenceToOffsetTable<MaskVec> LaneMaskSeqs;
8870b57cec5SDimitry Andric   SmallVector<MaskVec, 4> RegUnitLaneMasks(Regs.size());
8880b57cec5SDimitry Andric 
8890b57cec5SDimitry Andric   // Keep track of sub-register names as well. These are not differentially
8900b57cec5SDimitry Andric   // encoded.
8910b57cec5SDimitry Andric   typedef SmallVector<const CodeGenSubRegIndex *, 4> SubRegIdxVec;
8928bcb0991SDimitry Andric   SequenceToOffsetTable<SubRegIdxVec, deref<std::less<>>> SubRegIdxSeqs;
8930b57cec5SDimitry Andric   SmallVector<SubRegIdxVec, 4> SubRegIdxLists(Regs.size());
8940b57cec5SDimitry Andric 
8950b57cec5SDimitry Andric   SequenceToOffsetTable<std::string> RegStrings;
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric   // Precompute register lists for the SequenceToOffsetTable.
8980b57cec5SDimitry Andric   unsigned i = 0;
8990b57cec5SDimitry Andric   for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I, ++i) {
9000b57cec5SDimitry Andric     const auto &Reg = *I;
9015ffd83dbSDimitry Andric     RegStrings.add(std::string(Reg.getName()));
9020b57cec5SDimitry Andric 
9030b57cec5SDimitry Andric     // Compute the ordered sub-register list.
9040b57cec5SDimitry Andric     SetVector<const CodeGenRegister *> SR;
9050b57cec5SDimitry Andric     Reg.addSubRegsPreOrder(SR, RegBank);
9060b57cec5SDimitry Andric     diffEncode(SubRegLists[i], Reg.EnumValue, SR.begin(), SR.end());
9070b57cec5SDimitry Andric     DiffSeqs.add(SubRegLists[i]);
9080b57cec5SDimitry Andric 
9090b57cec5SDimitry Andric     // Compute the corresponding sub-register indexes.
9100b57cec5SDimitry Andric     SubRegIdxVec &SRIs = SubRegIdxLists[i];
9110b57cec5SDimitry Andric     for (const CodeGenRegister *S : SR)
9120b57cec5SDimitry Andric       SRIs.push_back(Reg.getSubRegIndex(S));
9130b57cec5SDimitry Andric     SubRegIdxSeqs.add(SRIs);
9140b57cec5SDimitry Andric 
9150b57cec5SDimitry Andric     // Super-registers are already computed.
9160b57cec5SDimitry Andric     const RegVec &SuperRegList = Reg.getSuperRegs();
9170b57cec5SDimitry Andric     diffEncode(SuperRegLists[i], Reg.EnumValue, SuperRegList.begin(),
9180b57cec5SDimitry Andric                SuperRegList.end());
9190b57cec5SDimitry Andric     DiffSeqs.add(SuperRegLists[i]);
9200b57cec5SDimitry Andric 
92106c3fb27SDimitry Andric     const SparseBitVector<> &RUs = Reg.getNativeRegUnits();
92206c3fb27SDimitry Andric     DiffSeqs.add(diffEncode(RegUnitLists[i], RUs));
9230b57cec5SDimitry Andric 
9240b57cec5SDimitry Andric     const auto &RUMasks = Reg.getRegUnitLaneMasks();
9250b57cec5SDimitry Andric     MaskVec &LaneMaskVec = RegUnitLaneMasks[i];
9260b57cec5SDimitry Andric     assert(LaneMaskVec.empty());
927e8d8bef9SDimitry Andric     llvm::append_range(LaneMaskVec, RUMasks);
9280b57cec5SDimitry Andric     LaneMaskSeqs.add(LaneMaskVec);
9290b57cec5SDimitry Andric   }
9300b57cec5SDimitry Andric 
9310b57cec5SDimitry Andric   // Compute the final layout of the sequence table.
9320b57cec5SDimitry Andric   DiffSeqs.layout();
9330b57cec5SDimitry Andric   LaneMaskSeqs.layout();
9340b57cec5SDimitry Andric   SubRegIdxSeqs.layout();
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric   OS << "namespace llvm {\n\n";
9370b57cec5SDimitry Andric 
9385ffd83dbSDimitry Andric   const std::string &TargetName = std::string(Target.getName());
9390b57cec5SDimitry Andric 
9400b57cec5SDimitry Andric   // Emit the shared table of differential lists.
94106c3fb27SDimitry Andric   OS << "extern const int16_t " << TargetName << "RegDiffLists[] = {\n";
9420b57cec5SDimitry Andric   DiffSeqs.emit(OS, printDiff16);
9430b57cec5SDimitry Andric   OS << "};\n\n";
9440b57cec5SDimitry Andric 
9450b57cec5SDimitry Andric   // Emit the shared table of regunit lane mask sequences.
9460b57cec5SDimitry Andric   OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[] = {\n";
9475f757f3fSDimitry Andric   // TODO: Omit the terminator since it is never used. The length of this list
9485f757f3fSDimitry Andric   // is known implicitly from the corresponding reg unit list.
9490b57cec5SDimitry Andric   LaneMaskSeqs.emit(OS, printMask, "LaneBitmask::getAll()");
9500b57cec5SDimitry Andric   OS << "};\n\n";
9510b57cec5SDimitry Andric 
9520b57cec5SDimitry Andric   // Emit the table of sub-register indexes.
9530b57cec5SDimitry Andric   OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n";
9540b57cec5SDimitry Andric   SubRegIdxSeqs.emit(OS, printSubRegIndex);
9550b57cec5SDimitry Andric   OS << "};\n\n";
9560b57cec5SDimitry Andric 
9570b57cec5SDimitry Andric   // Emit the string table.
9580b57cec5SDimitry Andric   RegStrings.layout();
9595ffd83dbSDimitry Andric   RegStrings.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName +
9605ffd83dbSDimitry Andric                                           "RegStrings[]");
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric   OS << "extern const MCRegisterDesc " << TargetName
9630b57cec5SDimitry Andric      << "RegDesc[] = { // Descriptors\n";
964*0fca6ea1SDimitry Andric   OS << "  { " << RegStrings.get("") << ", 0, 0, 0, 0, 0, 0 },\n";
9650b57cec5SDimitry Andric 
9660b57cec5SDimitry Andric   // Emit the register descriptors now.
9670b57cec5SDimitry Andric   i = 0;
9680b57cec5SDimitry Andric   for (const auto &Reg : Regs) {
96906c3fb27SDimitry Andric     unsigned FirstRU = Reg.getNativeRegUnits().find_first();
97006c3fb27SDimitry Andric     unsigned Offset = DiffSeqs.get(RegUnitLists[i]);
97106c3fb27SDimitry Andric     // The value must be kept in sync with MCRegisterInfo.h.
97206c3fb27SDimitry Andric     constexpr unsigned RegUnitBits = 12;
97306c3fb27SDimitry Andric     assert(isUInt<RegUnitBits>(FirstRU) && "Too many regunits");
97406c3fb27SDimitry Andric     assert(isUInt<32 - RegUnitBits>(Offset) && "Offset is too big");
9755ffd83dbSDimitry Andric     OS << "  { " << RegStrings.get(std::string(Reg.getName())) << ", "
9760b57cec5SDimitry Andric        << DiffSeqs.get(SubRegLists[i]) << ", " << DiffSeqs.get(SuperRegLists[i])
9770b57cec5SDimitry Andric        << ", " << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", "
97806c3fb27SDimitry Andric        << (Offset << RegUnitBits | FirstRU) << ", "
979*0fca6ea1SDimitry Andric        << LaneMaskSeqs.get(RegUnitLaneMasks[i]) << ", " << Reg.Constant
980*0fca6ea1SDimitry Andric        << " },\n";
9810b57cec5SDimitry Andric     ++i;
9820b57cec5SDimitry Andric   }
9830b57cec5SDimitry Andric   OS << "};\n\n"; // End of register descriptors...
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric   // Emit the table of register unit roots. Each regunit has one or two root
9860b57cec5SDimitry Andric   // registers.
9870b57cec5SDimitry Andric   OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2] = {\n";
9880b57cec5SDimitry Andric   for (unsigned i = 0, e = RegBank.getNumNativeRegUnits(); i != e; ++i) {
9890b57cec5SDimitry Andric     ArrayRef<const CodeGenRegister *> Roots = RegBank.getRegUnit(i).getRoots();
9900b57cec5SDimitry Andric     assert(!Roots.empty() && "All regunits must have a root register.");
9910b57cec5SDimitry Andric     assert(Roots.size() <= 2 && "More than two roots not supported yet.");
992fe6060f1SDimitry Andric     OS << "  { ";
993fe6060f1SDimitry Andric     ListSeparator LS;
994fe6060f1SDimitry Andric     for (const CodeGenRegister *R : Roots)
995fe6060f1SDimitry Andric       OS << LS << getQualifiedName(R->TheDef);
9960b57cec5SDimitry Andric     OS << " },\n";
9970b57cec5SDimitry Andric   }
9980b57cec5SDimitry Andric   OS << "};\n\n";
9990b57cec5SDimitry Andric 
10000b57cec5SDimitry Andric   const auto &RegisterClasses = RegBank.getRegClasses();
10010b57cec5SDimitry Andric 
10020b57cec5SDimitry Andric   // Loop over all of the register classes... emitting each one.
10030b57cec5SDimitry Andric   OS << "namespace {     // Register classes...\n";
10040b57cec5SDimitry Andric 
10050b57cec5SDimitry Andric   SequenceToOffsetTable<std::string> RegClassStrings;
10060b57cec5SDimitry Andric 
10070b57cec5SDimitry Andric   // Emit the register enum value arrays for each RegisterClass
10080b57cec5SDimitry Andric   for (const auto &RC : RegisterClasses) {
10090b57cec5SDimitry Andric     ArrayRef<Record *> Order = RC.getOrder();
10100b57cec5SDimitry Andric 
10110b57cec5SDimitry Andric     // Give the register class a legal C name if it's anonymous.
10120b57cec5SDimitry Andric     const std::string &Name = RC.getName();
10130b57cec5SDimitry Andric 
10140b57cec5SDimitry Andric     RegClassStrings.add(Name);
10150b57cec5SDimitry Andric 
101681ad6265SDimitry Andric     // Emit the register list now (unless it would be a zero-length array).
101781ad6265SDimitry Andric     if (!Order.empty()) {
10180b57cec5SDimitry Andric       OS << "  // " << Name << " Register Class...\n"
101981ad6265SDimitry Andric          << "  const MCPhysReg " << Name << "[] = {\n    ";
10200b57cec5SDimitry Andric       for (Record *Reg : Order) {
10210b57cec5SDimitry Andric         OS << getQualifiedName(Reg) << ", ";
10220b57cec5SDimitry Andric       }
10230b57cec5SDimitry Andric       OS << "\n  };\n\n";
10240b57cec5SDimitry Andric 
10250b57cec5SDimitry Andric       OS << "  // " << Name << " Bit set.\n"
102681ad6265SDimitry Andric          << "  const uint8_t " << Name << "Bits[] = {\n    ";
10270b57cec5SDimitry Andric       BitVectorEmitter BVE;
10280b57cec5SDimitry Andric       for (Record *Reg : Order) {
10290b57cec5SDimitry Andric         BVE.add(Target.getRegBank().getReg(Reg)->EnumValue);
10300b57cec5SDimitry Andric       }
10310b57cec5SDimitry Andric       BVE.print(OS);
10320b57cec5SDimitry Andric       OS << "\n  };\n\n";
103381ad6265SDimitry Andric     }
10340b57cec5SDimitry Andric   }
10350b57cec5SDimitry Andric   OS << "} // end anonymous namespace\n\n";
10360b57cec5SDimitry Andric 
10370b57cec5SDimitry Andric   RegClassStrings.layout();
10385ffd83dbSDimitry Andric   RegClassStrings.emitStringLiteralDef(
10395ffd83dbSDimitry Andric       OS, Twine("extern const char ") + TargetName + "RegClassStrings[]");
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric   OS << "extern const MCRegisterClass " << TargetName
10420b57cec5SDimitry Andric      << "MCRegisterClasses[] = {\n";
10430b57cec5SDimitry Andric 
10440b57cec5SDimitry Andric   for (const auto &RC : RegisterClasses) {
104581ad6265SDimitry Andric     ArrayRef<Record *> Order = RC.getOrder();
104681ad6265SDimitry Andric     std::string RCName = Order.empty() ? "nullptr" : RC.getName();
104781ad6265SDimitry Andric     std::string RCBitsName = Order.empty() ? "nullptr" : RC.getName() + "Bits";
104881ad6265SDimitry Andric     std::string RCBitsSize = Order.empty() ? "0" : "sizeof(" + RCBitsName + ")";
10490b57cec5SDimitry Andric     assert(isInt<8>(RC.CopyCost) && "Copy cost too large.");
1050fe6060f1SDimitry Andric     uint32_t RegSize = 0;
1051fe6060f1SDimitry Andric     if (RC.RSI.isSimple())
1052fe6060f1SDimitry Andric       RegSize = RC.RSI.getSimple().RegSize;
105381ad6265SDimitry Andric     OS << "  { " << RCName << ", " << RCBitsName << ", "
1054fe6060f1SDimitry Andric        << RegClassStrings.get(RC.getName()) << ", " << RC.getOrder().size()
10555f757f3fSDimitry Andric        << ", " << RCBitsSize << ", " << RC.getQualifiedIdName() << ", "
10565f757f3fSDimitry Andric        << RegSize << ", " << RC.CopyCost << ", "
1057*0fca6ea1SDimitry Andric        << (RC.Allocatable ? "true" : "false") << ", "
1058*0fca6ea1SDimitry Andric        << (RC.getBaseClassOrder() ? "true" : "false") << " },\n";
10590b57cec5SDimitry Andric   }
10600b57cec5SDimitry Andric 
10610b57cec5SDimitry Andric   OS << "};\n\n";
10620b57cec5SDimitry Andric 
10630b57cec5SDimitry Andric   EmitRegMappingTables(OS, Regs, false);
10640b57cec5SDimitry Andric 
10650b57cec5SDimitry Andric   // Emit Reg encoding table
10660b57cec5SDimitry Andric   OS << "extern const uint16_t " << TargetName;
10670b57cec5SDimitry Andric   OS << "RegEncodingTable[] = {\n";
10680b57cec5SDimitry Andric   // Add entry for NoRegister
10690b57cec5SDimitry Andric   OS << "  0,\n";
10700b57cec5SDimitry Andric   for (const auto &RE : Regs) {
10710b57cec5SDimitry Andric     Record *Reg = RE.TheDef;
10720b57cec5SDimitry Andric     BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
10730b57cec5SDimitry Andric     uint64_t Value = 0;
10740b57cec5SDimitry Andric     for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
10750b57cec5SDimitry Andric       if (BitInit *B = dyn_cast<BitInit>(BI->getBit(b)))
10760b57cec5SDimitry Andric         Value |= (uint64_t)B->getValue() << b;
10770b57cec5SDimitry Andric     }
10780b57cec5SDimitry Andric     OS << "  " << Value << ",\n";
10790b57cec5SDimitry Andric   }
10800b57cec5SDimitry Andric   OS << "};\n"; // End of HW encoding table
10810b57cec5SDimitry Andric 
10820b57cec5SDimitry Andric   // MCRegisterInfo initialization routine.
10830b57cec5SDimitry Andric   OS << "static inline void Init" << TargetName
10840b57cec5SDimitry Andric      << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
10850b57cec5SDimitry Andric      << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0, unsigned PC = 0) "
10860b57cec5SDimitry Andric         "{\n"
10870b57cec5SDimitry Andric      << "  RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
10880b57cec5SDimitry Andric      << Regs.size() + 1 << ", RA, PC, " << TargetName << "MCRegisterClasses, "
10890b57cec5SDimitry Andric      << RegisterClasses.size() << ", " << TargetName << "RegUnitRoots, "
10900b57cec5SDimitry Andric      << RegBank.getNumNativeRegUnits() << ", " << TargetName << "RegDiffLists, "
10910b57cec5SDimitry Andric      << TargetName << "LaneMaskLists, " << TargetName << "RegStrings, "
10920b57cec5SDimitry Andric      << TargetName << "RegClassStrings, " << TargetName << "SubRegIdxLists, "
10930b57cec5SDimitry Andric      << (std::distance(SubRegIndices.begin(), SubRegIndices.end()) + 1) << ",\n"
1094*0fca6ea1SDimitry Andric      << TargetName << "RegEncodingTable);\n\n";
10950b57cec5SDimitry Andric 
10960b57cec5SDimitry Andric   EmitRegMapping(OS, Regs, false);
10970b57cec5SDimitry Andric 
10980b57cec5SDimitry Andric   OS << "}\n\n";
10990b57cec5SDimitry Andric 
11000b57cec5SDimitry Andric   OS << "} // end namespace llvm\n\n";
11010b57cec5SDimitry Andric   OS << "#endif // GET_REGINFO_MC_DESC\n\n";
11020b57cec5SDimitry Andric }
11030b57cec5SDimitry Andric 
1104*0fca6ea1SDimitry Andric void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS,
1105*0fca6ea1SDimitry Andric                                           CodeGenTarget &Target,
11060b57cec5SDimitry Andric                                           CodeGenRegBank &RegBank) {
11070b57cec5SDimitry Andric   emitSourceFileHeader("Register Information Header Fragment", OS);
11080b57cec5SDimitry Andric 
11090b57cec5SDimitry Andric   OS << "\n#ifdef GET_REGINFO_HEADER\n";
11100b57cec5SDimitry Andric   OS << "#undef GET_REGINFO_HEADER\n\n";
11110b57cec5SDimitry Andric 
11125ffd83dbSDimitry Andric   const std::string &TargetName = std::string(Target.getName());
11130b57cec5SDimitry Andric   std::string ClassName = TargetName + "GenRegisterInfo";
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric   OS << "#include \"llvm/CodeGen/TargetRegisterInfo.h\"\n\n";
11160b57cec5SDimitry Andric 
11170b57cec5SDimitry Andric   OS << "namespace llvm {\n\n";
11180b57cec5SDimitry Andric 
11190b57cec5SDimitry Andric   OS << "class " << TargetName << "FrameLowering;\n\n";
11200b57cec5SDimitry Andric 
11210b57cec5SDimitry Andric   OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
11220b57cec5SDimitry Andric      << "  explicit " << ClassName
11230b57cec5SDimitry Andric      << "(unsigned RA, unsigned D = 0, unsigned E = 0,\n"
11240b57cec5SDimitry Andric      << "      unsigned PC = 0, unsigned HwMode = 0);\n";
11250b57cec5SDimitry Andric   if (!RegBank.getSubRegIndices().empty()) {
11260b57cec5SDimitry Andric     OS << "  unsigned composeSubRegIndicesImpl"
11270b57cec5SDimitry Andric        << "(unsigned, unsigned) const override;\n"
11280b57cec5SDimitry Andric        << "  LaneBitmask composeSubRegIndexLaneMaskImpl"
11290b57cec5SDimitry Andric        << "(unsigned, LaneBitmask) const override;\n"
11300b57cec5SDimitry Andric        << "  LaneBitmask reverseComposeSubRegIndexLaneMaskImpl"
11310b57cec5SDimitry Andric        << "(unsigned, LaneBitmask) const override;\n"
11320b57cec5SDimitry Andric        << "  const TargetRegisterClass *getSubClassWithSubReg"
1133bdd1243dSDimitry Andric        << "(const TargetRegisterClass *, unsigned) const override;\n"
1134bdd1243dSDimitry Andric        << "  const TargetRegisterClass *getSubRegisterClass"
11350b57cec5SDimitry Andric        << "(const TargetRegisterClass *, unsigned) const override;\n";
11360b57cec5SDimitry Andric   }
11370b57cec5SDimitry Andric   OS << "  const RegClassWeight &getRegClassWeight("
11380b57cec5SDimitry Andric      << "const TargetRegisterClass *RC) const override;\n"
11390b57cec5SDimitry Andric      << "  unsigned getRegUnitWeight(unsigned RegUnit) const override;\n"
11400b57cec5SDimitry Andric      << "  unsigned getNumRegPressureSets() const override;\n"
11410b57cec5SDimitry Andric      << "  const char *getRegPressureSetName(unsigned Idx) const override;\n"
11420b57cec5SDimitry Andric      << "  unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned "
11430b57cec5SDimitry Andric         "Idx) const override;\n"
11440b57cec5SDimitry Andric      << "  const int *getRegClassPressureSets("
11450b57cec5SDimitry Andric      << "const TargetRegisterClass *RC) const override;\n"
11460b57cec5SDimitry Andric      << "  const int *getRegUnitPressureSets("
11470b57cec5SDimitry Andric      << "unsigned RegUnit) const override;\n"
11480b57cec5SDimitry Andric      << "  ArrayRef<const char *> getRegMaskNames() const override;\n"
11490b57cec5SDimitry Andric      << "  ArrayRef<const uint32_t *> getRegMasks() const override;\n"
115081ad6265SDimitry Andric      << "  bool isGeneralPurposeRegister(const MachineFunction &, "
115181ad6265SDimitry Andric      << "MCRegister) const override;\n"
115281ad6265SDimitry Andric      << "  bool isFixedRegister(const MachineFunction &, "
115381ad6265SDimitry Andric      << "MCRegister) const override;\n"
115481ad6265SDimitry Andric      << "  bool isArgumentRegister(const MachineFunction &, "
115581ad6265SDimitry Andric      << "MCRegister) const override;\n"
1156bdd1243dSDimitry Andric      << "  bool isConstantPhysReg(MCRegister PhysReg) const override final;\n"
11570b57cec5SDimitry Andric      << "  /// Devirtualized TargetFrameLowering.\n"
11580b57cec5SDimitry Andric      << "  static const " << TargetName << "FrameLowering *getFrameLowering(\n"
1159bdd1243dSDimitry Andric      << "      const MachineFunction &MF);\n";
11600b57cec5SDimitry Andric 
11610b57cec5SDimitry Andric   const auto &RegisterClasses = RegBank.getRegClasses();
1162*0fca6ea1SDimitry Andric   if (llvm::any_of(RegisterClasses,
1163*0fca6ea1SDimitry Andric                    [](const auto &RC) { return RC.getBaseClassOrder(); })) {
1164*0fca6ea1SDimitry Andric     OS << "  const TargetRegisterClass *getPhysRegBaseClass(MCRegister Reg) "
1165*0fca6ea1SDimitry Andric           "const override;\n";
1166bdd1243dSDimitry Andric   }
1167bdd1243dSDimitry Andric 
1168bdd1243dSDimitry Andric   OS << "};\n\n";
11690b57cec5SDimitry Andric 
11700b57cec5SDimitry Andric   if (!RegisterClasses.empty()) {
11710b57cec5SDimitry Andric     OS << "namespace " << RegisterClasses.front().Namespace
11720b57cec5SDimitry Andric        << " { // Register classes\n";
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric     for (const auto &RC : RegisterClasses) {
11750b57cec5SDimitry Andric       const std::string &Name = RC.getName();
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric       // Output the extern for the instance.
11780b57cec5SDimitry Andric       OS << "  extern const TargetRegisterClass " << Name << "RegClass;\n";
11790b57cec5SDimitry Andric     }
11800b57cec5SDimitry Andric     OS << "} // end namespace " << RegisterClasses.front().Namespace << "\n\n";
11810b57cec5SDimitry Andric   }
11820b57cec5SDimitry Andric   OS << "} // end namespace llvm\n\n";
11830b57cec5SDimitry Andric   OS << "#endif // GET_REGINFO_HEADER\n\n";
11840b57cec5SDimitry Andric }
11850b57cec5SDimitry Andric 
11860b57cec5SDimitry Andric //
11870b57cec5SDimitry Andric // runTargetDesc - Output the target register and register file descriptions.
11880b57cec5SDimitry Andric //
1189*0fca6ea1SDimitry Andric void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
11900b57cec5SDimitry Andric                                         CodeGenRegBank &RegBank) {
11910b57cec5SDimitry Andric   emitSourceFileHeader("Target Register and Register Classes Information", OS);
11920b57cec5SDimitry Andric 
11930b57cec5SDimitry Andric   OS << "\n#ifdef GET_REGINFO_TARGET_DESC\n";
11940b57cec5SDimitry Andric   OS << "#undef GET_REGINFO_TARGET_DESC\n\n";
11950b57cec5SDimitry Andric 
11960b57cec5SDimitry Andric   OS << "namespace llvm {\n\n";
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric   // Get access to MCRegisterClass data.
11990b57cec5SDimitry Andric   OS << "extern const MCRegisterClass " << Target.getName()
12000b57cec5SDimitry Andric      << "MCRegisterClasses[];\n";
12010b57cec5SDimitry Andric 
12020b57cec5SDimitry Andric   // Start out by emitting each of the register classes.
12030b57cec5SDimitry Andric   const auto &RegisterClasses = RegBank.getRegClasses();
12040b57cec5SDimitry Andric   const auto &SubRegIndices = RegBank.getSubRegIndices();
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric   // Collect all registers belonging to any allocatable class.
12070b57cec5SDimitry Andric   std::set<Record *> AllocatableRegs;
12080b57cec5SDimitry Andric 
12090b57cec5SDimitry Andric   // Collect allocatable registers.
12100b57cec5SDimitry Andric   for (const auto &RC : RegisterClasses) {
12110b57cec5SDimitry Andric     ArrayRef<Record *> Order = RC.getOrder();
12120b57cec5SDimitry Andric 
12130b57cec5SDimitry Andric     if (RC.Allocatable)
12140b57cec5SDimitry Andric       AllocatableRegs.insert(Order.begin(), Order.end());
12150b57cec5SDimitry Andric   }
12160b57cec5SDimitry Andric 
12170b57cec5SDimitry Andric   const CodeGenHwModes &CGH = Target.getHwModes();
12180b57cec5SDimitry Andric   unsigned NumModes = CGH.getNumModeIds();
12190b57cec5SDimitry Andric 
12200b57cec5SDimitry Andric   // Build a shared array of value types.
12210b57cec5SDimitry Andric   SequenceToOffsetTable<std::vector<MVT::SimpleValueType>> VTSeqs;
12220b57cec5SDimitry Andric   for (unsigned M = 0; M < NumModes; ++M) {
12230b57cec5SDimitry Andric     for (const auto &RC : RegisterClasses) {
12240b57cec5SDimitry Andric       std::vector<MVT::SimpleValueType> S;
12250b57cec5SDimitry Andric       for (const ValueTypeByHwMode &VVT : RC.VTs)
122606c3fb27SDimitry Andric         if (VVT.hasDefault() || VVT.hasMode(M))
12270b57cec5SDimitry Andric           S.push_back(VVT.get(M).SimpleTy);
12280b57cec5SDimitry Andric       VTSeqs.add(S);
12290b57cec5SDimitry Andric     }
12300b57cec5SDimitry Andric   }
12310b57cec5SDimitry Andric   VTSeqs.layout();
12320b57cec5SDimitry Andric   OS << "\nstatic const MVT::SimpleValueType VTLists[] = {\n";
12330b57cec5SDimitry Andric   VTSeqs.emit(OS, printSimpleValueType, "MVT::Other");
12340b57cec5SDimitry Andric   OS << "};\n";
12350b57cec5SDimitry Andric 
12360b57cec5SDimitry Andric   // Emit SubRegIndex names, skipping 0.
123781ad6265SDimitry Andric   OS << "\nstatic const char *SubRegIndexNameTable[] = { \"";
12380b57cec5SDimitry Andric 
12390b57cec5SDimitry Andric   for (const auto &Idx : SubRegIndices) {
12400b57cec5SDimitry Andric     OS << Idx.getName();
12410b57cec5SDimitry Andric     OS << "\", \"";
12420b57cec5SDimitry Andric   }
12430b57cec5SDimitry Andric   OS << "\" };\n\n";
12440b57cec5SDimitry Andric 
1245*0fca6ea1SDimitry Andric   // Emit the table of sub-register index sizes.
1246*0fca6ea1SDimitry Andric   OS << "static const TargetRegisterInfo::SubRegCoveredBits "
1247*0fca6ea1SDimitry Andric         "SubRegIdxRangeTable[] = {\n";
1248*0fca6ea1SDimitry Andric   for (unsigned M = 0; M < NumModes; ++M) {
1249*0fca6ea1SDimitry Andric     OS << "  { " << (uint16_t)-1 << ", " << (uint16_t)-1 << " },\n";
1250*0fca6ea1SDimitry Andric     for (const auto &Idx : SubRegIndices) {
1251*0fca6ea1SDimitry Andric       const SubRegRange &Range = Idx.Range.get(M);
1252*0fca6ea1SDimitry Andric       OS << "  { " << Range.Offset << ", " << Range.Size << " },\t// "
1253*0fca6ea1SDimitry Andric          << Idx.getName() << "\n";
1254*0fca6ea1SDimitry Andric     }
1255*0fca6ea1SDimitry Andric   }
1256*0fca6ea1SDimitry Andric   OS << "};\n\n";
1257*0fca6ea1SDimitry Andric 
12580b57cec5SDimitry Andric   // Emit SubRegIndex lane masks, including 0.
12590b57cec5SDimitry Andric   OS << "\nstatic const LaneBitmask SubRegIndexLaneMaskTable[] = {\n  "
12600b57cec5SDimitry Andric         "LaneBitmask::getAll(),\n";
12610b57cec5SDimitry Andric   for (const auto &Idx : SubRegIndices) {
12620b57cec5SDimitry Andric     printMask(OS << "  ", Idx.LaneMask);
12630b57cec5SDimitry Andric     OS << ", // " << Idx.getName() << '\n';
12640b57cec5SDimitry Andric   }
12650b57cec5SDimitry Andric   OS << " };\n\n";
12660b57cec5SDimitry Andric 
12670b57cec5SDimitry Andric   OS << "\n";
12680b57cec5SDimitry Andric 
12690b57cec5SDimitry Andric   // Now that all of the structs have been emitted, emit the instances.
12700b57cec5SDimitry Andric   if (!RegisterClasses.empty()) {
12710b57cec5SDimitry Andric     OS << "\nstatic const TargetRegisterInfo::RegClassInfo RegClassInfos[]"
12720b57cec5SDimitry Andric        << " = {\n";
12730b57cec5SDimitry Andric     for (unsigned M = 0; M < NumModes; ++M) {
12740b57cec5SDimitry Andric       unsigned EV = 0;
12750b57cec5SDimitry Andric       OS << "  // Mode = " << M << " (";
12760b57cec5SDimitry Andric       if (M == 0)
12770b57cec5SDimitry Andric         OS << "Default";
12780b57cec5SDimitry Andric       else
12790b57cec5SDimitry Andric         OS << CGH.getMode(M).Name;
12800b57cec5SDimitry Andric       OS << ")\n";
12810b57cec5SDimitry Andric       for (const auto &RC : RegisterClasses) {
1282e8d8bef9SDimitry Andric         assert(RC.EnumValue == EV && "Unexpected order of register classes");
1283e8d8bef9SDimitry Andric         ++EV;
12840b57cec5SDimitry Andric         (void)EV;
12850b57cec5SDimitry Andric         const RegSizeInfo &RI = RC.RSI.get(M);
12860b57cec5SDimitry Andric         OS << "  { " << RI.RegSize << ", " << RI.SpillSize << ", "
12870b57cec5SDimitry Andric            << RI.SpillAlignment;
12880b57cec5SDimitry Andric         std::vector<MVT::SimpleValueType> VTs;
12890b57cec5SDimitry Andric         for (const ValueTypeByHwMode &VVT : RC.VTs)
129006c3fb27SDimitry Andric           if (VVT.hasDefault() || VVT.hasMode(M))
12910b57cec5SDimitry Andric             VTs.push_back(VVT.get(M).SimpleTy);
12925f757f3fSDimitry Andric         OS << ", /*VTLists+*/" << VTSeqs.get(VTs) << " },    // "
12930b57cec5SDimitry Andric            << RC.getName() << '\n';
12940b57cec5SDimitry Andric       }
12950b57cec5SDimitry Andric     }
12960b57cec5SDimitry Andric     OS << "};\n";
12970b57cec5SDimitry Andric 
12980b57cec5SDimitry Andric     OS << "\nstatic const TargetRegisterClass *const "
12990b57cec5SDimitry Andric        << "NullRegClasses[] = { nullptr };\n\n";
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric     // Emit register class bit mask tables. The first bit mask emitted for a
13020b57cec5SDimitry Andric     // register class, RC, is the set of sub-classes, including RC itself.
13030b57cec5SDimitry Andric     //
13040b57cec5SDimitry Andric     // If RC has super-registers, also create a list of subreg indices and bit
13050b57cec5SDimitry Andric     // masks, (Idx, Mask). The bit mask has a bit for every superreg regclass,
13060b57cec5SDimitry Andric     // SuperRC, that satisfies:
13070b57cec5SDimitry Andric     //
13080b57cec5SDimitry Andric     //   For all SuperReg in SuperRC: SuperReg:Idx in RC
13090b57cec5SDimitry Andric     //
13100b57cec5SDimitry Andric     // The 0-terminated list of subreg indices starts at:
13110b57cec5SDimitry Andric     //
13120b57cec5SDimitry Andric     //   RC->getSuperRegIndices() = SuperRegIdxSeqs + ...
13130b57cec5SDimitry Andric     //
13140b57cec5SDimitry Andric     // The corresponding bitmasks follow the sub-class mask in memory. Each
13150b57cec5SDimitry Andric     // mask has RCMaskWords uint32_t entries.
13160b57cec5SDimitry Andric     //
13170b57cec5SDimitry Andric     // Every bit mask present in the list has at least one bit set.
13180b57cec5SDimitry Andric 
13190b57cec5SDimitry Andric     // Compress the sub-reg index lists.
13200b57cec5SDimitry Andric     typedef std::vector<const CodeGenSubRegIndex *> IdxList;
13210b57cec5SDimitry Andric     SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());
13228bcb0991SDimitry Andric     SequenceToOffsetTable<IdxList, deref<std::less<>>> SuperRegIdxSeqs;
13230b57cec5SDimitry Andric     BitVector MaskBV(RegisterClasses.size());
13240b57cec5SDimitry Andric 
13250b57cec5SDimitry Andric     for (const auto &RC : RegisterClasses) {
13260b57cec5SDimitry Andric       OS << "static const uint32_t " << RC.getName()
13270b57cec5SDimitry Andric          << "SubClassMask[] = {\n  ";
13280b57cec5SDimitry Andric       printBitVectorAsHex(OS, RC.getSubClasses(), 32);
13290b57cec5SDimitry Andric 
13300b57cec5SDimitry Andric       // Emit super-reg class masks for any relevant SubRegIndices that can
13310b57cec5SDimitry Andric       // project into RC.
13320b57cec5SDimitry Andric       IdxList &SRIList = SuperRegIdxLists[RC.EnumValue];
13330b57cec5SDimitry Andric       for (auto &Idx : SubRegIndices) {
13340b57cec5SDimitry Andric         MaskBV.reset();
13350b57cec5SDimitry Andric         RC.getSuperRegClasses(&Idx, MaskBV);
13360b57cec5SDimitry Andric         if (MaskBV.none())
13370b57cec5SDimitry Andric           continue;
13380b57cec5SDimitry Andric         SRIList.push_back(&Idx);
13390b57cec5SDimitry Andric         OS << "\n  ";
13400b57cec5SDimitry Andric         printBitVectorAsHex(OS, MaskBV, 32);
13410b57cec5SDimitry Andric         OS << "// " << Idx.getName();
13420b57cec5SDimitry Andric       }
13430b57cec5SDimitry Andric       SuperRegIdxSeqs.add(SRIList);
13440b57cec5SDimitry Andric       OS << "\n};\n\n";
13450b57cec5SDimitry Andric     }
13460b57cec5SDimitry Andric 
13470b57cec5SDimitry Andric     OS << "static const uint16_t SuperRegIdxSeqs[] = {\n";
13480b57cec5SDimitry Andric     SuperRegIdxSeqs.layout();
13490b57cec5SDimitry Andric     SuperRegIdxSeqs.emit(OS, printSubRegIndex);
13500b57cec5SDimitry Andric     OS << "};\n\n";
13510b57cec5SDimitry Andric 
13520b57cec5SDimitry Andric     // Emit NULL terminated super-class lists.
13530b57cec5SDimitry Andric     for (const auto &RC : RegisterClasses) {
13540b57cec5SDimitry Andric       ArrayRef<CodeGenRegisterClass *> Supers = RC.getSuperClasses();
13550b57cec5SDimitry Andric 
13560b57cec5SDimitry Andric       // Skip classes without supers.  We can reuse NullRegClasses.
13570b57cec5SDimitry Andric       if (Supers.empty())
13580b57cec5SDimitry Andric         continue;
13590b57cec5SDimitry Andric 
1360*0fca6ea1SDimitry Andric       OS << "static const TargetRegisterClass *const " << RC.getName()
1361*0fca6ea1SDimitry Andric          << "Superclasses[] = {\n";
13620b57cec5SDimitry Andric       for (const auto *Super : Supers)
13630b57cec5SDimitry Andric         OS << "  &" << Super->getQualifiedName() << "RegClass,\n";
13640b57cec5SDimitry Andric       OS << "  nullptr\n};\n\n";
13650b57cec5SDimitry Andric     }
13660b57cec5SDimitry Andric 
13670b57cec5SDimitry Andric     // Emit methods.
13680b57cec5SDimitry Andric     for (const auto &RC : RegisterClasses) {
13690b57cec5SDimitry Andric       if (!RC.AltOrderSelect.empty()) {
13700b57cec5SDimitry Andric         OS << "\nstatic inline unsigned " << RC.getName()
1371*0fca6ea1SDimitry Andric            << "AltOrderSelect(const MachineFunction &MF) {" << RC.AltOrderSelect
1372*0fca6ea1SDimitry Andric            << "}\n\n"
13730b57cec5SDimitry Andric            << "static ArrayRef<MCPhysReg> " << RC.getName()
13740b57cec5SDimitry Andric            << "GetRawAllocationOrder(const MachineFunction &MF) {\n";
13750b57cec5SDimitry Andric         for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi) {
13760b57cec5SDimitry Andric           ArrayRef<Record *> Elems = RC.getOrder(oi);
13770b57cec5SDimitry Andric           if (!Elems.empty()) {
13780b57cec5SDimitry Andric             OS << "  static const MCPhysReg AltOrder" << oi << "[] = {";
13790b57cec5SDimitry Andric             for (unsigned elem = 0; elem != Elems.size(); ++elem)
13800b57cec5SDimitry Andric               OS << (elem ? ", " : " ") << getQualifiedName(Elems[elem]);
13810b57cec5SDimitry Andric             OS << " };\n";
13820b57cec5SDimitry Andric           }
13830b57cec5SDimitry Andric         }
13840b57cec5SDimitry Andric         OS << "  const MCRegisterClass &MCR = " << Target.getName()
13850b57cec5SDimitry Andric            << "MCRegisterClasses[" << RC.getQualifiedName() + "RegClassID];\n"
13860b57cec5SDimitry Andric            << "  const ArrayRef<MCPhysReg> Order[] = {\n"
1387bdd1243dSDimitry Andric            << "    ArrayRef(MCR.begin(), MCR.getNumRegs()";
13880b57cec5SDimitry Andric         for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi)
13890b57cec5SDimitry Andric           if (RC.getOrder(oi).empty())
13900b57cec5SDimitry Andric             OS << "),\n    ArrayRef<MCPhysReg>(";
13910b57cec5SDimitry Andric           else
1392bdd1243dSDimitry Andric             OS << "),\n    ArrayRef(AltOrder" << oi;
13930b57cec5SDimitry Andric         OS << ")\n  };\n  const unsigned Select = " << RC.getName()
13940b57cec5SDimitry Andric            << "AltOrderSelect(MF);\n  assert(Select < " << RC.getNumOrders()
13950b57cec5SDimitry Andric            << ");\n  return Order[Select];\n}\n";
13960b57cec5SDimitry Andric       }
13970b57cec5SDimitry Andric     }
13980b57cec5SDimitry Andric 
13990b57cec5SDimitry Andric     // Now emit the actual value-initialized register class instances.
14000b57cec5SDimitry Andric     OS << "\nnamespace " << RegisterClasses.front().Namespace
14010b57cec5SDimitry Andric        << " {   // Register class instances\n";
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric     for (const auto &RC : RegisterClasses) {
14040b57cec5SDimitry Andric       OS << "  extern const TargetRegisterClass " << RC.getName()
14050b57cec5SDimitry Andric          << "RegClass = {\n    " << '&' << Target.getName()
14060b57cec5SDimitry Andric          << "MCRegisterClasses[" << RC.getName() << "RegClassID],\n    "
14070b57cec5SDimitry Andric          << RC.getName() << "SubClassMask,\n    SuperRegIdxSeqs + "
14080b57cec5SDimitry Andric          << SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]) << ",\n    ";
14090b57cec5SDimitry Andric       printMask(OS, RC.LaneMask);
14100b57cec5SDimitry Andric       OS << ",\n    " << (unsigned)RC.AllocationPriority << ",\n    "
1411bdd1243dSDimitry Andric          << (RC.GlobalPriority ? "true" : "false") << ",\n    "
1412349cc55cSDimitry Andric          << format("0x%02x", RC.TSFlags) << ", /* TSFlags */\n    "
14130b57cec5SDimitry Andric          << (RC.HasDisjunctSubRegs ? "true" : "false")
14140b57cec5SDimitry Andric          << ", /* HasDisjunctSubRegs */\n    "
14150b57cec5SDimitry Andric          << (RC.CoveredBySubRegs ? "true" : "false")
14160b57cec5SDimitry Andric          << ", /* CoveredBySubRegs */\n    ";
14170b57cec5SDimitry Andric       if (RC.getSuperClasses().empty())
14180b57cec5SDimitry Andric         OS << "NullRegClasses,\n    ";
14190b57cec5SDimitry Andric       else
14200b57cec5SDimitry Andric         OS << RC.getName() << "Superclasses,\n    ";
14210b57cec5SDimitry Andric       if (RC.AltOrderSelect.empty())
14220b57cec5SDimitry Andric         OS << "nullptr\n";
14230b57cec5SDimitry Andric       else
14240b57cec5SDimitry Andric         OS << RC.getName() << "GetRawAllocationOrder\n";
14250b57cec5SDimitry Andric       OS << "  };\n\n";
14260b57cec5SDimitry Andric     }
14270b57cec5SDimitry Andric 
14280b57cec5SDimitry Andric     OS << "} // end namespace " << RegisterClasses.front().Namespace << "\n";
14290b57cec5SDimitry Andric   }
14300b57cec5SDimitry Andric 
14310b57cec5SDimitry Andric   OS << "\nnamespace {\n";
14320b57cec5SDimitry Andric   OS << "  const TargetRegisterClass *const RegisterClasses[] = {\n";
14330b57cec5SDimitry Andric   for (const auto &RC : RegisterClasses)
14340b57cec5SDimitry Andric     OS << "    &" << RC.getQualifiedName() << "RegClass,\n";
14350b57cec5SDimitry Andric   OS << "  };\n";
14360b57cec5SDimitry Andric   OS << "} // end anonymous namespace\n";
14370b57cec5SDimitry Andric 
14380b57cec5SDimitry Andric   // Emit extra information about registers.
14395ffd83dbSDimitry Andric   const std::string &TargetName = std::string(Target.getName());
14400b57cec5SDimitry Andric   const auto &Regs = RegBank.getRegisters();
1441fe6060f1SDimitry Andric   unsigned NumRegCosts = 1;
1442fe6060f1SDimitry Andric   for (const auto &Reg : Regs)
1443fe6060f1SDimitry Andric     NumRegCosts = std::max((size_t)NumRegCosts, Reg.CostPerUse.size());
14440b57cec5SDimitry Andric 
1445fe6060f1SDimitry Andric   std::vector<unsigned> AllRegCostPerUse;
1446fe6060f1SDimitry Andric   llvm::BitVector InAllocClass(Regs.size() + 1, false);
1447fe6060f1SDimitry Andric   AllRegCostPerUse.insert(AllRegCostPerUse.end(), NumRegCosts, 0);
1448fe6060f1SDimitry Andric 
1449fe6060f1SDimitry Andric   // Populate the vector RegCosts with the CostPerUse list of the registers
1450fe6060f1SDimitry Andric   // in the order they are read. Have at most NumRegCosts entries for
1451fe6060f1SDimitry Andric   // each register. Fill with zero for values which are not explicitly given.
1452fe6060f1SDimitry Andric   for (const auto &Reg : Regs) {
1453fe6060f1SDimitry Andric     auto Costs = Reg.CostPerUse;
1454fe6060f1SDimitry Andric     AllRegCostPerUse.insert(AllRegCostPerUse.end(), Costs.begin(), Costs.end());
1455fe6060f1SDimitry Andric     if (NumRegCosts > Costs.size())
1456fe6060f1SDimitry Andric       AllRegCostPerUse.insert(AllRegCostPerUse.end(),
1457fe6060f1SDimitry Andric                               NumRegCosts - Costs.size(), 0);
1458fe6060f1SDimitry Andric 
1459fe6060f1SDimitry Andric     if (AllocatableRegs.count(Reg.TheDef))
1460fe6060f1SDimitry Andric       InAllocClass.set(Reg.EnumValue);
1461fe6060f1SDimitry Andric   }
1462fe6060f1SDimitry Andric 
1463fe6060f1SDimitry Andric   // Emit the cost values as a 1D-array after grouping them by their indices,
1464fe6060f1SDimitry Andric   // i.e. the costs for all registers corresponds to index 0, 1, 2, etc.
1465fe6060f1SDimitry Andric   // Size of the emitted array should be NumRegCosts * (Regs.size() + 1).
1466fe6060f1SDimitry Andric   OS << "\nstatic const uint8_t "
1467fe6060f1SDimitry Andric      << "CostPerUseTable[] = { \n";
1468fe6060f1SDimitry Andric   for (unsigned int I = 0; I < NumRegCosts; ++I) {
1469fe6060f1SDimitry Andric     for (unsigned J = I, E = AllRegCostPerUse.size(); J < E; J += NumRegCosts)
1470fe6060f1SDimitry Andric       OS << AllRegCostPerUse[J] << ", ";
1471fe6060f1SDimitry Andric   }
1472fe6060f1SDimitry Andric   OS << "};\n\n";
1473fe6060f1SDimitry Andric 
1474fe6060f1SDimitry Andric   OS << "\nstatic const bool "
1475fe6060f1SDimitry Andric      << "InAllocatableClassTable[] = { \n";
1476fe6060f1SDimitry Andric   for (unsigned I = 0, E = InAllocClass.size(); I < E; ++I) {
1477fe6060f1SDimitry Andric     OS << (InAllocClass[I] ? "true" : "false") << ", ";
1478fe6060f1SDimitry Andric   }
1479fe6060f1SDimitry Andric   OS << "};\n\n";
1480fe6060f1SDimitry Andric 
1481fe6060f1SDimitry Andric   OS << "\nstatic const TargetRegisterInfoDesc " << TargetName
1482fe6060f1SDimitry Andric      << "RegInfoDesc = { // Extra Descriptors\n";
1483fe6060f1SDimitry Andric   OS << "CostPerUseTable, " << NumRegCosts << ", "
1484fe6060f1SDimitry Andric      << "InAllocatableClassTable";
1485fe6060f1SDimitry Andric   OS << "};\n\n"; // End of register descriptors...
14860b57cec5SDimitry Andric 
14870b57cec5SDimitry Andric   std::string ClassName = Target.getName().str() + "GenRegisterInfo";
14880b57cec5SDimitry Andric 
14890b57cec5SDimitry Andric   auto SubRegIndicesSize =
14900b57cec5SDimitry Andric       std::distance(SubRegIndices.begin(), SubRegIndices.end());
14910b57cec5SDimitry Andric 
14920b57cec5SDimitry Andric   if (!SubRegIndices.empty()) {
14930b57cec5SDimitry Andric     emitComposeSubRegIndices(OS, RegBank, ClassName);
14940b57cec5SDimitry Andric     emitComposeSubRegIndexLaneMask(OS, RegBank, ClassName);
14950b57cec5SDimitry Andric   }
14960b57cec5SDimitry Andric 
14970b57cec5SDimitry Andric   if (!SubRegIndices.empty()) {
1498bdd1243dSDimitry Andric     // Emit getSubClassWithSubReg.
14990b57cec5SDimitry Andric     OS << "const TargetRegisterClass *" << ClassName
15000b57cec5SDimitry Andric        << "::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx)"
15010b57cec5SDimitry Andric        << " const {\n";
15020b57cec5SDimitry Andric     // Use the smallest type that can hold a regclass ID with room for a
15030b57cec5SDimitry Andric     // sentinel.
1504bdd1243dSDimitry Andric     if (RegisterClasses.size() <= UINT8_MAX)
15050b57cec5SDimitry Andric       OS << "  static const uint8_t Table[";
1506bdd1243dSDimitry Andric     else if (RegisterClasses.size() <= UINT16_MAX)
15070b57cec5SDimitry Andric       OS << "  static const uint16_t Table[";
15080b57cec5SDimitry Andric     else
15090b57cec5SDimitry Andric       PrintFatalError("Too many register classes.");
15100b57cec5SDimitry Andric     OS << RegisterClasses.size() << "][" << SubRegIndicesSize << "] = {\n";
15110b57cec5SDimitry Andric     for (const auto &RC : RegisterClasses) {
15120b57cec5SDimitry Andric       OS << "    {\t// " << RC.getName() << "\n";
15130b57cec5SDimitry Andric       for (auto &Idx : SubRegIndices) {
15140b57cec5SDimitry Andric         if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(&Idx))
15150b57cec5SDimitry Andric           OS << "      " << SRC->EnumValue + 1 << ",\t// " << Idx.getName()
15160b57cec5SDimitry Andric              << " -> " << SRC->getName() << "\n";
15170b57cec5SDimitry Andric         else
15180b57cec5SDimitry Andric           OS << "      0,\t// " << Idx.getName() << "\n";
15190b57cec5SDimitry Andric       }
15200b57cec5SDimitry Andric       OS << "    },\n";
15210b57cec5SDimitry Andric     }
15220b57cec5SDimitry Andric     OS << "  };\n  assert(RC && \"Missing regclass\");\n"
15230b57cec5SDimitry Andric        << "  if (!Idx) return RC;\n  --Idx;\n"
15240b57cec5SDimitry Andric        << "  assert(Idx < " << SubRegIndicesSize << " && \"Bad subreg\");\n"
15250b57cec5SDimitry Andric        << "  unsigned TV = Table[RC->getID()][Idx];\n"
15260b57cec5SDimitry Andric        << "  return TV ? getRegClass(TV - 1) : nullptr;\n}\n\n";
1527bdd1243dSDimitry Andric 
1528bdd1243dSDimitry Andric     // Emit getSubRegisterClass
1529bdd1243dSDimitry Andric     OS << "const TargetRegisterClass *" << ClassName
1530bdd1243dSDimitry Andric        << "::getSubRegisterClass(const TargetRegisterClass *RC, unsigned Idx)"
1531bdd1243dSDimitry Andric        << " const {\n";
1532bdd1243dSDimitry Andric 
1533bdd1243dSDimitry Andric     // Use the smallest type that can hold a regclass ID with room for a
1534bdd1243dSDimitry Andric     // sentinel.
1535bdd1243dSDimitry Andric     if (RegisterClasses.size() <= UINT8_MAX)
1536bdd1243dSDimitry Andric       OS << "  static const uint8_t Table[";
1537bdd1243dSDimitry Andric     else if (RegisterClasses.size() <= UINT16_MAX)
1538bdd1243dSDimitry Andric       OS << "  static const uint16_t Table[";
1539bdd1243dSDimitry Andric     else
1540bdd1243dSDimitry Andric       PrintFatalError("Too many register classes.");
1541bdd1243dSDimitry Andric 
1542bdd1243dSDimitry Andric     OS << RegisterClasses.size() << "][" << SubRegIndicesSize << "] = {\n";
1543bdd1243dSDimitry Andric 
1544bdd1243dSDimitry Andric     for (const auto &RC : RegisterClasses) {
1545bdd1243dSDimitry Andric       OS << "    {\t// " << RC.getName() << '\n';
1546bdd1243dSDimitry Andric       for (auto &Idx : SubRegIndices) {
1547bdd1243dSDimitry Andric         std::optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>>
1548bdd1243dSDimitry Andric             MatchingSubClass = RC.getMatchingSubClassWithSubRegs(RegBank, &Idx);
1549bdd1243dSDimitry Andric 
1550bdd1243dSDimitry Andric         unsigned EnumValue = 0;
1551bdd1243dSDimitry Andric         if (MatchingSubClass) {
1552bdd1243dSDimitry Andric           CodeGenRegisterClass *SubRegClass = MatchingSubClass->second;
1553bdd1243dSDimitry Andric           EnumValue = SubRegClass->EnumValue + 1;
1554bdd1243dSDimitry Andric         }
1555bdd1243dSDimitry Andric 
1556*0fca6ea1SDimitry Andric         OS << "      " << EnumValue << ",\t// " << RC.getName() << ':'
1557*0fca6ea1SDimitry Andric            << Idx.getName();
1558bdd1243dSDimitry Andric 
1559bdd1243dSDimitry Andric         if (MatchingSubClass) {
1560bdd1243dSDimitry Andric           CodeGenRegisterClass *SubRegClass = MatchingSubClass->second;
1561bdd1243dSDimitry Andric           OS << " -> " << SubRegClass->getName();
1562bdd1243dSDimitry Andric         }
1563bdd1243dSDimitry Andric 
1564bdd1243dSDimitry Andric         OS << '\n';
1565bdd1243dSDimitry Andric       }
1566bdd1243dSDimitry Andric 
1567bdd1243dSDimitry Andric       OS << "    },\n";
1568bdd1243dSDimitry Andric     }
1569bdd1243dSDimitry Andric     OS << "  };\n  assert(RC && \"Missing regclass\");\n"
1570bdd1243dSDimitry Andric        << "  if (!Idx) return RC;\n  --Idx;\n"
1571bdd1243dSDimitry Andric        << "  assert(Idx < " << SubRegIndicesSize << " && \"Bad subreg\");\n"
1572bdd1243dSDimitry Andric        << "  unsigned TV = Table[RC->getID()][Idx];\n"
1573bdd1243dSDimitry Andric        << "  return TV ? getRegClass(TV - 1) : nullptr;\n}\n\n";
15740b57cec5SDimitry Andric   }
15750b57cec5SDimitry Andric 
15760b57cec5SDimitry Andric   EmitRegUnitPressure(OS, RegBank, ClassName);
15770b57cec5SDimitry Andric 
1578bdd1243dSDimitry Andric   // Emit register base class mapper
1579bdd1243dSDimitry Andric   if (!RegisterClasses.empty()) {
1580bdd1243dSDimitry Andric     // Collect base classes
1581bdd1243dSDimitry Andric     SmallVector<const CodeGenRegisterClass *> BaseClasses;
1582bdd1243dSDimitry Andric     for (const auto &RC : RegisterClasses) {
1583bdd1243dSDimitry Andric       if (RC.getBaseClassOrder())
1584bdd1243dSDimitry Andric         BaseClasses.push_back(&RC);
1585bdd1243dSDimitry Andric     }
1586bdd1243dSDimitry Andric     if (!BaseClasses.empty()) {
15875f757f3fSDimitry Andric       assert(BaseClasses.size() < UINT16_MAX &&
15885f757f3fSDimitry Andric              "Too many base register classes");
1589bdd1243dSDimitry Andric 
1590bdd1243dSDimitry Andric       // Apply order
1591bdd1243dSDimitry Andric       struct BaseClassOrdering {
1592*0fca6ea1SDimitry Andric         bool operator()(const CodeGenRegisterClass *LHS,
1593*0fca6ea1SDimitry Andric                         const CodeGenRegisterClass *RHS) const {
1594*0fca6ea1SDimitry Andric           return std::pair(*LHS->getBaseClassOrder(), LHS->EnumValue) <
1595*0fca6ea1SDimitry Andric                  std::pair(*RHS->getBaseClassOrder(), RHS->EnumValue);
1596bdd1243dSDimitry Andric         }
1597bdd1243dSDimitry Andric       };
1598bdd1243dSDimitry Andric       llvm::stable_sort(BaseClasses, BaseClassOrdering());
1599bdd1243dSDimitry Andric 
1600bdd1243dSDimitry Andric       OS << "\n// Register to base register class mapping\n\n";
1601bdd1243dSDimitry Andric       OS << "\n";
1602bdd1243dSDimitry Andric       OS << "const TargetRegisterClass *" << ClassName
1603bdd1243dSDimitry Andric          << "::getPhysRegBaseClass(MCRegister Reg)"
1604bdd1243dSDimitry Andric          << " const {\n";
16055f757f3fSDimitry Andric       OS << "  static const uint16_t InvalidRegClassID = UINT16_MAX;\n\n";
16065f757f3fSDimitry Andric       OS << "  static const uint16_t Mapping[" << Regs.size() + 1 << "] = {\n";
16075f757f3fSDimitry Andric       OS << "    InvalidRegClassID,  // NoRegister\n";
16085f757f3fSDimitry Andric       for (const CodeGenRegister &Reg : Regs) {
16095f757f3fSDimitry Andric         const CodeGenRegisterClass *BaseRC = nullptr;
16105f757f3fSDimitry Andric         for (const CodeGenRegisterClass *RC : BaseClasses) {
16115f757f3fSDimitry Andric           if (is_contained(RC->getMembers(), &Reg)) {
16125f757f3fSDimitry Andric             BaseRC = RC;
16135f757f3fSDimitry Andric             break;
16145f757f3fSDimitry Andric           }
16155f757f3fSDimitry Andric         }
16165f757f3fSDimitry Andric 
16175f757f3fSDimitry Andric         OS << "    "
16185f757f3fSDimitry Andric            << (BaseRC ? BaseRC->getQualifiedIdName() : "InvalidRegClassID")
16195f757f3fSDimitry Andric            << ",  // " << Reg.getName() << "\n";
16205f757f3fSDimitry Andric       }
16215f757f3fSDimitry Andric       OS << "  };\n\n"
16225f757f3fSDimitry Andric             "  assert(Reg < ArrayRef(Mapping).size());\n"
16235f757f3fSDimitry Andric             "  unsigned RCID = Mapping[Reg];\n"
16245f757f3fSDimitry Andric             "  if (RCID == InvalidRegClassID)\n"
16255f757f3fSDimitry Andric             "    return nullptr;\n"
16265f757f3fSDimitry Andric             "  return RegisterClasses[RCID];\n"
16275f757f3fSDimitry Andric             "}\n";
1628bdd1243dSDimitry Andric     }
1629bdd1243dSDimitry Andric   }
1630bdd1243dSDimitry Andric 
16310b57cec5SDimitry Andric   // Emit the constructor of the class...
16320b57cec5SDimitry Andric   OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
163306c3fb27SDimitry Andric   OS << "extern const int16_t " << TargetName << "RegDiffLists[];\n";
16340b57cec5SDimitry Andric   OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[];\n";
16350b57cec5SDimitry Andric   OS << "extern const char " << TargetName << "RegStrings[];\n";
16360b57cec5SDimitry Andric   OS << "extern const char " << TargetName << "RegClassStrings[];\n";
16370b57cec5SDimitry Andric   OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2];\n";
16380b57cec5SDimitry Andric   OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n";
16390b57cec5SDimitry Andric   OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n";
16400b57cec5SDimitry Andric 
16410b57cec5SDimitry Andric   EmitRegMappingTables(OS, Regs, true);
16420b57cec5SDimitry Andric 
1643fe6060f1SDimitry Andric   OS << ClassName << "::\n"
1644fe6060f1SDimitry Andric      << ClassName
16450b57cec5SDimitry Andric      << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour,\n"
16460b57cec5SDimitry Andric         "      unsigned PC, unsigned HwMode)\n"
1647fe6060f1SDimitry Andric      << "  : TargetRegisterInfo(&" << TargetName << "RegInfoDesc"
16480b57cec5SDimitry Andric      << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() << ",\n"
1649*0fca6ea1SDimitry Andric      << "             SubRegIndexNameTable, SubRegIdxRangeTable, "
1650*0fca6ea1SDimitry Andric         "SubRegIndexLaneMaskTable,\n"
16510b57cec5SDimitry Andric      << "             ";
16520b57cec5SDimitry Andric   printMask(OS, RegBank.CoveringLanes);
16535f757f3fSDimitry Andric   OS << ", RegClassInfos, VTLists, HwMode) {\n"
16540b57cec5SDimitry Andric      << "  InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size() + 1
16550b57cec5SDimitry Andric      << ", RA, PC,\n                     " << TargetName
16560b57cec5SDimitry Andric      << "MCRegisterClasses, " << RegisterClasses.size() << ",\n"
16570b57cec5SDimitry Andric      << "                     " << TargetName << "RegUnitRoots,\n"
16580b57cec5SDimitry Andric      << "                     " << RegBank.getNumNativeRegUnits() << ",\n"
16590b57cec5SDimitry Andric      << "                     " << TargetName << "RegDiffLists,\n"
16600b57cec5SDimitry Andric      << "                     " << TargetName << "LaneMaskLists,\n"
16610b57cec5SDimitry Andric      << "                     " << TargetName << "RegStrings,\n"
16620b57cec5SDimitry Andric      << "                     " << TargetName << "RegClassStrings,\n"
16630b57cec5SDimitry Andric      << "                     " << TargetName << "SubRegIdxLists,\n"
16640b57cec5SDimitry Andric      << "                     " << SubRegIndicesSize + 1 << ",\n"
16650b57cec5SDimitry Andric      << "                     " << TargetName << "RegEncodingTable);\n\n";
16660b57cec5SDimitry Andric 
16670b57cec5SDimitry Andric   EmitRegMapping(OS, Regs, true);
16680b57cec5SDimitry Andric 
16690b57cec5SDimitry Andric   OS << "}\n\n";
16700b57cec5SDimitry Andric 
16710b57cec5SDimitry Andric   // Emit CalleeSavedRegs information.
16720b57cec5SDimitry Andric   std::vector<Record *> CSRSets =
16730b57cec5SDimitry Andric       Records.getAllDerivedDefinitions("CalleeSavedRegs");
16740b57cec5SDimitry Andric   for (unsigned i = 0, e = CSRSets.size(); i != e; ++i) {
16750b57cec5SDimitry Andric     Record *CSRSet = CSRSets[i];
16760b57cec5SDimitry Andric     const SetTheory::RecVec *Regs = RegBank.getSets().expand(CSRSet);
16770b57cec5SDimitry Andric     assert(Regs && "Cannot expand CalleeSavedRegs instance");
16780b57cec5SDimitry Andric 
16790b57cec5SDimitry Andric     // Emit the *_SaveList list of callee-saved registers.
1680*0fca6ea1SDimitry Andric     OS << "static const MCPhysReg " << CSRSet->getName() << "_SaveList[] = { ";
16810b57cec5SDimitry Andric     for (unsigned r = 0, re = Regs->size(); r != re; ++r)
16820b57cec5SDimitry Andric       OS << getQualifiedName((*Regs)[r]) << ", ";
16830b57cec5SDimitry Andric     OS << "0 };\n";
16840b57cec5SDimitry Andric 
16850b57cec5SDimitry Andric     // Emit the *_RegMask bit mask of call-preserved registers.
16860b57cec5SDimitry Andric     BitVector Covered = RegBank.computeCoveredRegisters(*Regs);
16870b57cec5SDimitry Andric 
16880b57cec5SDimitry Andric     // Check for an optional OtherPreserved set.
16890b57cec5SDimitry Andric     // Add those registers to RegMask, but not to SaveList.
16900b57cec5SDimitry Andric     if (DagInit *OPDag =
16910b57cec5SDimitry Andric             dyn_cast<DagInit>(CSRSet->getValueInit("OtherPreserved"))) {
16920b57cec5SDimitry Andric       SetTheory::RecSet OPSet;
16930b57cec5SDimitry Andric       RegBank.getSets().evaluate(OPDag, OPSet, CSRSet->getLoc());
16940b57cec5SDimitry Andric       Covered |= RegBank.computeCoveredRegisters(
16950b57cec5SDimitry Andric           ArrayRef<Record *>(OPSet.begin(), OPSet.end()));
16960b57cec5SDimitry Andric     }
16970b57cec5SDimitry Andric 
1698bdd1243dSDimitry Andric     // Add all constant physical registers to the preserved mask:
1699bdd1243dSDimitry Andric     SetTheory::RecSet ConstantSet;
1700bdd1243dSDimitry Andric     for (auto &Reg : RegBank.getRegisters()) {
1701bdd1243dSDimitry Andric       if (Reg.Constant)
1702bdd1243dSDimitry Andric         ConstantSet.insert(Reg.TheDef);
1703bdd1243dSDimitry Andric     }
1704bdd1243dSDimitry Andric     Covered |= RegBank.computeCoveredRegisters(
1705bdd1243dSDimitry Andric         ArrayRef<Record *>(ConstantSet.begin(), ConstantSet.end()));
1706bdd1243dSDimitry Andric 
1707*0fca6ea1SDimitry Andric     OS << "static const uint32_t " << CSRSet->getName() << "_RegMask[] = { ";
17080b57cec5SDimitry Andric     printBitVectorAsHex(OS, Covered, 32);
17090b57cec5SDimitry Andric     OS << "};\n";
17100b57cec5SDimitry Andric   }
17110b57cec5SDimitry Andric   OS << "\n\n";
17120b57cec5SDimitry Andric 
17130b57cec5SDimitry Andric   OS << "ArrayRef<const uint32_t *> " << ClassName
17140b57cec5SDimitry Andric      << "::getRegMasks() const {\n";
17150b57cec5SDimitry Andric   if (!CSRSets.empty()) {
17160b57cec5SDimitry Andric     OS << "  static const uint32_t *const Masks[] = {\n";
17170b57cec5SDimitry Andric     for (Record *CSRSet : CSRSets)
17180b57cec5SDimitry Andric       OS << "    " << CSRSet->getName() << "_RegMask,\n";
17190b57cec5SDimitry Andric     OS << "  };\n";
1720bdd1243dSDimitry Andric     OS << "  return ArrayRef(Masks);\n";
17210b57cec5SDimitry Andric   } else {
1722bdd1243dSDimitry Andric     OS << "  return std::nullopt;\n";
17230b57cec5SDimitry Andric   }
17240b57cec5SDimitry Andric   OS << "}\n\n";
17250b57cec5SDimitry Andric 
172681ad6265SDimitry Andric   const std::list<CodeGenRegisterCategory> &RegCategories =
172781ad6265SDimitry Andric       RegBank.getRegCategories();
172881ad6265SDimitry Andric   OS << "bool " << ClassName << "::\n"
172981ad6265SDimitry Andric      << "isGeneralPurposeRegister(const MachineFunction &MF, "
173081ad6265SDimitry Andric      << "MCRegister PhysReg) const {\n"
173181ad6265SDimitry Andric      << "  return\n";
173281ad6265SDimitry Andric   for (const CodeGenRegisterCategory &Category : RegCategories)
173381ad6265SDimitry Andric     if (Category.getName() == "GeneralPurposeRegisters") {
173481ad6265SDimitry Andric       for (const CodeGenRegisterClass *RC : Category.getClasses())
173581ad6265SDimitry Andric         OS << "      " << RC->getQualifiedName()
173681ad6265SDimitry Andric            << "RegClass.contains(PhysReg) ||\n";
173781ad6265SDimitry Andric       break;
173881ad6265SDimitry Andric     }
173981ad6265SDimitry Andric   OS << "      false;\n";
174081ad6265SDimitry Andric   OS << "}\n\n";
174181ad6265SDimitry Andric 
174281ad6265SDimitry Andric   OS << "bool " << ClassName << "::\n"
174381ad6265SDimitry Andric      << "isFixedRegister(const MachineFunction &MF, "
174481ad6265SDimitry Andric      << "MCRegister PhysReg) const {\n"
174581ad6265SDimitry Andric      << "  return\n";
174681ad6265SDimitry Andric   for (const CodeGenRegisterCategory &Category : RegCategories)
174781ad6265SDimitry Andric     if (Category.getName() == "FixedRegisters") {
174881ad6265SDimitry Andric       for (const CodeGenRegisterClass *RC : Category.getClasses())
174981ad6265SDimitry Andric         OS << "      " << RC->getQualifiedName()
175081ad6265SDimitry Andric            << "RegClass.contains(PhysReg) ||\n";
175181ad6265SDimitry Andric       break;
175281ad6265SDimitry Andric     }
175381ad6265SDimitry Andric   OS << "      false;\n";
175481ad6265SDimitry Andric   OS << "}\n\n";
175581ad6265SDimitry Andric 
175681ad6265SDimitry Andric   OS << "bool " << ClassName << "::\n"
175781ad6265SDimitry Andric      << "isArgumentRegister(const MachineFunction &MF, "
175881ad6265SDimitry Andric      << "MCRegister PhysReg) const {\n"
175981ad6265SDimitry Andric      << "  return\n";
176081ad6265SDimitry Andric   for (const CodeGenRegisterCategory &Category : RegCategories)
176181ad6265SDimitry Andric     if (Category.getName() == "ArgumentRegisters") {
176281ad6265SDimitry Andric       for (const CodeGenRegisterClass *RC : Category.getClasses())
176381ad6265SDimitry Andric         OS << "      " << RC->getQualifiedName()
176481ad6265SDimitry Andric            << "RegClass.contains(PhysReg) ||\n";
176581ad6265SDimitry Andric       break;
176681ad6265SDimitry Andric     }
176781ad6265SDimitry Andric   OS << "      false;\n";
176881ad6265SDimitry Andric   OS << "}\n\n";
176981ad6265SDimitry Andric 
1770bdd1243dSDimitry Andric   OS << "bool " << ClassName << "::\n"
1771bdd1243dSDimitry Andric      << "isConstantPhysReg(MCRegister PhysReg) const {\n"
1772bdd1243dSDimitry Andric      << "  return\n";
1773bdd1243dSDimitry Andric   for (const auto &Reg : Regs)
1774bdd1243dSDimitry Andric     if (Reg.Constant)
1775bdd1243dSDimitry Andric       OS << "      PhysReg == " << getQualifiedName(Reg.TheDef) << " ||\n";
1776bdd1243dSDimitry Andric   OS << "      false;\n";
1777bdd1243dSDimitry Andric   OS << "}\n\n";
1778bdd1243dSDimitry Andric 
17790b57cec5SDimitry Andric   OS << "ArrayRef<const char *> " << ClassName
17800b57cec5SDimitry Andric      << "::getRegMaskNames() const {\n";
17810b57cec5SDimitry Andric   if (!CSRSets.empty()) {
178281ad6265SDimitry Andric     OS << "  static const char *Names[] = {\n";
17830b57cec5SDimitry Andric     for (Record *CSRSet : CSRSets)
17840b57cec5SDimitry Andric       OS << "    " << '"' << CSRSet->getName() << '"' << ",\n";
17850b57cec5SDimitry Andric     OS << "  };\n";
1786bdd1243dSDimitry Andric     OS << "  return ArrayRef(Names);\n";
17870b57cec5SDimitry Andric   } else {
1788bdd1243dSDimitry Andric     OS << "  return std::nullopt;\n";
17890b57cec5SDimitry Andric   }
17900b57cec5SDimitry Andric   OS << "}\n\n";
17910b57cec5SDimitry Andric 
1792*0fca6ea1SDimitry Andric   OS << "const " << TargetName << "FrameLowering *\n"
1793*0fca6ea1SDimitry Andric      << TargetName
17940b57cec5SDimitry Andric      << "GenRegisterInfo::getFrameLowering(const MachineFunction &MF) {\n"
17950b57cec5SDimitry Andric      << "  return static_cast<const " << TargetName << "FrameLowering *>(\n"
17960b57cec5SDimitry Andric      << "      MF.getSubtarget().getFrameLowering());\n"
17970b57cec5SDimitry Andric      << "}\n\n";
17980b57cec5SDimitry Andric 
17990b57cec5SDimitry Andric   OS << "} // end namespace llvm\n\n";
18000b57cec5SDimitry Andric   OS << "#endif // GET_REGINFO_TARGET_DESC\n\n";
18010b57cec5SDimitry Andric }
18020b57cec5SDimitry Andric 
18030b57cec5SDimitry Andric void RegisterInfoEmitter::run(raw_ostream &OS) {
18040b57cec5SDimitry Andric   CodeGenRegBank &RegBank = Target.getRegBank();
1805e8d8bef9SDimitry Andric   Records.startTimer("Print enums");
18060b57cec5SDimitry Andric   runEnums(OS, Target, RegBank);
1807e8d8bef9SDimitry Andric 
1808e8d8bef9SDimitry Andric   Records.startTimer("Print MC registers");
18090b57cec5SDimitry Andric   runMCDesc(OS, Target, RegBank);
1810e8d8bef9SDimitry Andric 
1811e8d8bef9SDimitry Andric   Records.startTimer("Print header fragment");
18120b57cec5SDimitry Andric   runTargetHeader(OS, Target, RegBank);
1813e8d8bef9SDimitry Andric 
1814e8d8bef9SDimitry Andric   Records.startTimer("Print target registers");
18150b57cec5SDimitry Andric   runTargetDesc(OS, Target, RegBank);
18160b57cec5SDimitry Andric 
18170b57cec5SDimitry Andric   if (RegisterInfoDebug)
18180b57cec5SDimitry Andric     debugDump(errs());
18190b57cec5SDimitry Andric }
18200b57cec5SDimitry Andric 
18210b57cec5SDimitry Andric void RegisterInfoEmitter::debugDump(raw_ostream &OS) {
18220b57cec5SDimitry Andric   CodeGenRegBank &RegBank = Target.getRegBank();
18230b57cec5SDimitry Andric   const CodeGenHwModes &CGH = Target.getHwModes();
18240b57cec5SDimitry Andric   unsigned NumModes = CGH.getNumModeIds();
18250b57cec5SDimitry Andric   auto getModeName = [CGH](unsigned M) -> StringRef {
18260b57cec5SDimitry Andric     if (M == 0)
18270b57cec5SDimitry Andric       return "Default";
18280b57cec5SDimitry Andric     return CGH.getMode(M).Name;
18290b57cec5SDimitry Andric   };
18300b57cec5SDimitry Andric 
18310b57cec5SDimitry Andric   for (const CodeGenRegisterClass &RC : RegBank.getRegClasses()) {
18320b57cec5SDimitry Andric     OS << "RegisterClass " << RC.getName() << ":\n";
18330b57cec5SDimitry Andric     OS << "\tSpillSize: {";
18340b57cec5SDimitry Andric     for (unsigned M = 0; M != NumModes; ++M)
18350b57cec5SDimitry Andric       OS << ' ' << getModeName(M) << ':' << RC.RSI.get(M).SpillSize;
18360b57cec5SDimitry Andric     OS << " }\n\tSpillAlignment: {";
18370b57cec5SDimitry Andric     for (unsigned M = 0; M != NumModes; ++M)
18380b57cec5SDimitry Andric       OS << ' ' << getModeName(M) << ':' << RC.RSI.get(M).SpillAlignment;
18390b57cec5SDimitry Andric     OS << " }\n\tNumRegs: " << RC.getMembers().size() << '\n';
18400b57cec5SDimitry Andric     OS << "\tLaneMask: " << PrintLaneMask(RC.LaneMask) << '\n';
18410b57cec5SDimitry Andric     OS << "\tHasDisjunctSubRegs: " << RC.HasDisjunctSubRegs << '\n';
18420b57cec5SDimitry Andric     OS << "\tCoveredBySubRegs: " << RC.CoveredBySubRegs << '\n';
184381ad6265SDimitry Andric     OS << "\tAllocatable: " << RC.Allocatable << '\n';
184481ad6265SDimitry Andric     OS << "\tAllocationPriority: " << unsigned(RC.AllocationPriority) << '\n';
1845*0fca6ea1SDimitry Andric     OS << "\tBaseClassOrder: " << RC.getBaseClassOrder() << '\n';
18460b57cec5SDimitry Andric     OS << "\tRegs:";
18470b57cec5SDimitry Andric     for (const CodeGenRegister *R : RC.getMembers()) {
18480b57cec5SDimitry Andric       OS << " " << R->getName();
18490b57cec5SDimitry Andric     }
18500b57cec5SDimitry Andric     OS << '\n';
18510b57cec5SDimitry Andric     OS << "\tSubClasses:";
18520b57cec5SDimitry Andric     const BitVector &SubClasses = RC.getSubClasses();
18530b57cec5SDimitry Andric     for (const CodeGenRegisterClass &SRC : RegBank.getRegClasses()) {
18540b57cec5SDimitry Andric       if (!SubClasses.test(SRC.EnumValue))
18550b57cec5SDimitry Andric         continue;
18560b57cec5SDimitry Andric       OS << " " << SRC.getName();
18570b57cec5SDimitry Andric     }
18580b57cec5SDimitry Andric     OS << '\n';
18590b57cec5SDimitry Andric     OS << "\tSuperClasses:";
18600b57cec5SDimitry Andric     for (const CodeGenRegisterClass *SRC : RC.getSuperClasses()) {
18610b57cec5SDimitry Andric       OS << " " << SRC->getName();
18620b57cec5SDimitry Andric     }
18630b57cec5SDimitry Andric     OS << '\n';
18640b57cec5SDimitry Andric   }
18650b57cec5SDimitry Andric 
18660b57cec5SDimitry Andric   for (const CodeGenSubRegIndex &SRI : RegBank.getSubRegIndices()) {
18670b57cec5SDimitry Andric     OS << "SubRegIndex " << SRI.getName() << ":\n";
18680b57cec5SDimitry Andric     OS << "\tLaneMask: " << PrintLaneMask(SRI.LaneMask) << '\n';
18690b57cec5SDimitry Andric     OS << "\tAllSuperRegsCovered: " << SRI.AllSuperRegsCovered << '\n';
1870*0fca6ea1SDimitry Andric     OS << "\tOffset: {";
1871*0fca6ea1SDimitry Andric     for (unsigned M = 0; M != NumModes; ++M)
1872*0fca6ea1SDimitry Andric       OS << ' ' << getModeName(M) << ':' << SRI.Range.get(M).Offset;
1873*0fca6ea1SDimitry Andric     OS << " }\n\tSize: {";
1874*0fca6ea1SDimitry Andric     for (unsigned M = 0; M != NumModes; ++M)
1875*0fca6ea1SDimitry Andric       OS << ' ' << getModeName(M) << ':' << SRI.Range.get(M).Size;
1876*0fca6ea1SDimitry Andric     OS << " }\n";
18770b57cec5SDimitry Andric   }
18780b57cec5SDimitry Andric 
18790b57cec5SDimitry Andric   for (const CodeGenRegister &R : RegBank.getRegisters()) {
18800b57cec5SDimitry Andric     OS << "Register " << R.getName() << ":\n";
1881fe6060f1SDimitry Andric     OS << "\tCostPerUse: ";
1882fe6060f1SDimitry Andric     for (const auto &Cost : R.CostPerUse)
1883fe6060f1SDimitry Andric       OS << Cost << " ";
1884fe6060f1SDimitry Andric     OS << '\n';
18850b57cec5SDimitry Andric     OS << "\tCoveredBySubregs: " << R.CoveredBySubRegs << '\n';
18860b57cec5SDimitry Andric     OS << "\tHasDisjunctSubRegs: " << R.HasDisjunctSubRegs << '\n';
1887*0fca6ea1SDimitry Andric     for (std::pair<CodeGenSubRegIndex *, CodeGenRegister *> P :
1888*0fca6ea1SDimitry Andric          R.getSubRegs()) {
1889*0fca6ea1SDimitry Andric       OS << "\tSubReg " << P.first->getName() << " = " << P.second->getName()
1890*0fca6ea1SDimitry Andric          << '\n';
18910b57cec5SDimitry Andric     }
18920b57cec5SDimitry Andric   }
18930b57cec5SDimitry Andric }
18940b57cec5SDimitry Andric 
189506c3fb27SDimitry Andric static TableGen::Emitter::OptClass<RegisterInfoEmitter>
189606c3fb27SDimitry Andric     X("gen-register-info", "Generate registers and register classes info");
1897