1*9880d681SAndroid Build Coastguard Worker //===- RegisterInfoEmitter.cpp - Generate a Register File Desc. -*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This tablegen backend is responsible for emitting a description of a target
11*9880d681SAndroid Build Coastguard Worker // register file for a code generator. It uses instances of the Register,
12*9880d681SAndroid Build Coastguard Worker // RegisterAliases, and RegisterClass classes to gather this information.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker #include "CodeGenRegisters.h"
17*9880d681SAndroid Build Coastguard Worker #include "CodeGenTarget.h"
18*9880d681SAndroid Build Coastguard Worker #include "SequenceToOffsetTable.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/ArrayRef.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/BitVector.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SetVector.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SparseBitVector.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Twine.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineValueType.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Casting.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/TableGen/Error.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/TableGen/Record.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/TableGen/SetTheory.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/TableGen/TableGenBackend.h"
34*9880d681SAndroid Build Coastguard Worker #include <algorithm>
35*9880d681SAndroid Build Coastguard Worker #include <cassert>
36*9880d681SAndroid Build Coastguard Worker #include <cstddef>
37*9880d681SAndroid Build Coastguard Worker #include <cstdint>
38*9880d681SAndroid Build Coastguard Worker #include <deque>
39*9880d681SAndroid Build Coastguard Worker #include <iterator>
40*9880d681SAndroid Build Coastguard Worker #include <set>
41*9880d681SAndroid Build Coastguard Worker #include <string>
42*9880d681SAndroid Build Coastguard Worker #include <vector>
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker using namespace llvm;
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker namespace {
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker class RegisterInfoEmitter {
49*9880d681SAndroid Build Coastguard Worker RecordKeeper &Records;
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker public:
RegisterInfoEmitter(RecordKeeper & R)52*9880d681SAndroid Build Coastguard Worker RegisterInfoEmitter(RecordKeeper &R) : Records(R) {}
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker // runEnums - Print out enum values for all of the registers.
55*9880d681SAndroid Build Coastguard Worker void runEnums(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank);
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker // runMCDesc - Print out MC register descriptions.
58*9880d681SAndroid Build Coastguard Worker void runMCDesc(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank);
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker // runTargetHeader - Emit a header fragment for the register info emitter.
61*9880d681SAndroid Build Coastguard Worker void runTargetHeader(raw_ostream &o, CodeGenTarget &Target,
62*9880d681SAndroid Build Coastguard Worker CodeGenRegBank &Bank);
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker // runTargetDesc - Output the target register and register file descriptions.
65*9880d681SAndroid Build Coastguard Worker void runTargetDesc(raw_ostream &o, CodeGenTarget &Target,
66*9880d681SAndroid Build Coastguard Worker CodeGenRegBank &Bank);
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker // run - Output the register file description.
69*9880d681SAndroid Build Coastguard Worker void run(raw_ostream &o);
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker private:
72*9880d681SAndroid Build Coastguard Worker void EmitRegMapping(raw_ostream &o, const std::deque<CodeGenRegister> &Regs,
73*9880d681SAndroid Build Coastguard Worker bool isCtor);
74*9880d681SAndroid Build Coastguard Worker void EmitRegMappingTables(raw_ostream &o,
75*9880d681SAndroid Build Coastguard Worker const std::deque<CodeGenRegister> &Regs,
76*9880d681SAndroid Build Coastguard Worker bool isCtor);
77*9880d681SAndroid Build Coastguard Worker void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
78*9880d681SAndroid Build Coastguard Worker const std::string &ClassName);
79*9880d681SAndroid Build Coastguard Worker void emitComposeSubRegIndices(raw_ostream &OS, CodeGenRegBank &RegBank,
80*9880d681SAndroid Build Coastguard Worker const std::string &ClassName);
81*9880d681SAndroid Build Coastguard Worker void emitComposeSubRegIndexLaneMask(raw_ostream &OS, CodeGenRegBank &RegBank,
82*9880d681SAndroid Build Coastguard Worker const std::string &ClassName);
83*9880d681SAndroid Build Coastguard Worker };
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Worker // runEnums - Print out enum values for all of the registers.
runEnums(raw_ostream & OS,CodeGenTarget & Target,CodeGenRegBank & Bank)88*9880d681SAndroid Build Coastguard Worker void RegisterInfoEmitter::runEnums(raw_ostream &OS,
89*9880d681SAndroid Build Coastguard Worker CodeGenTarget &Target, CodeGenRegBank &Bank) {
90*9880d681SAndroid Build Coastguard Worker const auto &Registers = Bank.getRegisters();
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker // Register enums are stored as uint16_t in the tables. Make sure we'll fit.
93*9880d681SAndroid Build Coastguard Worker assert(Registers.size() <= 0xffff && "Too many regs to fit in tables");
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker std::string Namespace =
96*9880d681SAndroid Build Coastguard Worker Registers.front().TheDef->getValueAsString("Namespace");
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker emitSourceFileHeader("Target Register Enum Values", OS);
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Worker OS << "\n#ifdef GET_REGINFO_ENUM\n";
101*9880d681SAndroid Build Coastguard Worker OS << "#undef GET_REGINFO_ENUM\n\n";
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker OS << "namespace llvm {\n\n";
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker OS << "class MCRegisterClass;\n"
106*9880d681SAndroid Build Coastguard Worker << "extern const MCRegisterClass " << Namespace
107*9880d681SAndroid Build Coastguard Worker << "MCRegisterClasses[];\n\n";
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker if (!Namespace.empty())
110*9880d681SAndroid Build Coastguard Worker OS << "namespace " << Namespace << " {\n";
111*9880d681SAndroid Build Coastguard Worker OS << "enum {\n NoRegister,\n";
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker for (const auto &Reg : Registers)
114*9880d681SAndroid Build Coastguard Worker OS << " " << Reg.getName() << " = " << Reg.EnumValue << ",\n";
115*9880d681SAndroid Build Coastguard Worker assert(Registers.size() == Registers.back().EnumValue &&
116*9880d681SAndroid Build Coastguard Worker "Register enum value mismatch!");
117*9880d681SAndroid Build Coastguard Worker OS << " NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n";
118*9880d681SAndroid Build Coastguard Worker OS << "};\n";
119*9880d681SAndroid Build Coastguard Worker if (!Namespace.empty())
120*9880d681SAndroid Build Coastguard Worker OS << "} // end namespace " << Namespace << "\n";
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker const auto &RegisterClasses = Bank.getRegClasses();
123*9880d681SAndroid Build Coastguard Worker if (!RegisterClasses.empty()) {
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker // RegisterClass enums are stored as uint16_t in the tables.
126*9880d681SAndroid Build Coastguard Worker assert(RegisterClasses.size() <= 0xffff &&
127*9880d681SAndroid Build Coastguard Worker "Too many register classes to fit in tables");
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker OS << "\n// Register classes\n\n";
130*9880d681SAndroid Build Coastguard Worker if (!Namespace.empty())
131*9880d681SAndroid Build Coastguard Worker OS << "namespace " << Namespace << " {\n";
132*9880d681SAndroid Build Coastguard Worker OS << "enum {\n";
133*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegisterClasses)
134*9880d681SAndroid Build Coastguard Worker OS << " " << RC.getName() << "RegClassID"
135*9880d681SAndroid Build Coastguard Worker << " = " << RC.EnumValue << ",\n";
136*9880d681SAndroid Build Coastguard Worker OS << "\n };\n";
137*9880d681SAndroid Build Coastguard Worker if (!Namespace.empty())
138*9880d681SAndroid Build Coastguard Worker OS << "} // end namespace " << Namespace << "\n\n";
139*9880d681SAndroid Build Coastguard Worker }
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker const std::vector<Record*> &RegAltNameIndices = Target.getRegAltNameIndices();
142*9880d681SAndroid Build Coastguard Worker // If the only definition is the default NoRegAltName, we don't need to
143*9880d681SAndroid Build Coastguard Worker // emit anything.
144*9880d681SAndroid Build Coastguard Worker if (RegAltNameIndices.size() > 1) {
145*9880d681SAndroid Build Coastguard Worker OS << "\n// Register alternate name indices\n\n";
146*9880d681SAndroid Build Coastguard Worker if (!Namespace.empty())
147*9880d681SAndroid Build Coastguard Worker OS << "namespace " << Namespace << " {\n";
148*9880d681SAndroid Build Coastguard Worker OS << "enum {\n";
149*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i)
150*9880d681SAndroid Build Coastguard Worker OS << " " << RegAltNameIndices[i]->getName() << ",\t// " << i << "\n";
151*9880d681SAndroid Build Coastguard Worker OS << " NUM_TARGET_REG_ALT_NAMES = " << RegAltNameIndices.size() << "\n";
152*9880d681SAndroid Build Coastguard Worker OS << "};\n";
153*9880d681SAndroid Build Coastguard Worker if (!Namespace.empty())
154*9880d681SAndroid Build Coastguard Worker OS << "} // end namespace " << Namespace << "\n\n";
155*9880d681SAndroid Build Coastguard Worker }
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker auto &SubRegIndices = Bank.getSubRegIndices();
158*9880d681SAndroid Build Coastguard Worker if (!SubRegIndices.empty()) {
159*9880d681SAndroid Build Coastguard Worker OS << "\n// Subregister indices\n\n";
160*9880d681SAndroid Build Coastguard Worker std::string Namespace = SubRegIndices.front().getNamespace();
161*9880d681SAndroid Build Coastguard Worker if (!Namespace.empty())
162*9880d681SAndroid Build Coastguard Worker OS << "namespace " << Namespace << " {\n";
163*9880d681SAndroid Build Coastguard Worker OS << "enum {\n NoSubRegister,\n";
164*9880d681SAndroid Build Coastguard Worker unsigned i = 0;
165*9880d681SAndroid Build Coastguard Worker for (const auto &Idx : SubRegIndices)
166*9880d681SAndroid Build Coastguard Worker OS << " " << Idx.getName() << ",\t// " << ++i << "\n";
167*9880d681SAndroid Build Coastguard Worker OS << " NUM_TARGET_SUBREGS\n};\n";
168*9880d681SAndroid Build Coastguard Worker if (!Namespace.empty())
169*9880d681SAndroid Build Coastguard Worker OS << "} // end namespace " << Namespace << "\n\n";
170*9880d681SAndroid Build Coastguard Worker }
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker OS << "} // end namespace llvm\n\n";
173*9880d681SAndroid Build Coastguard Worker OS << "#endif // GET_REGINFO_ENUM\n\n";
174*9880d681SAndroid Build Coastguard Worker }
175*9880d681SAndroid Build Coastguard Worker
printInt(raw_ostream & OS,int Val)176*9880d681SAndroid Build Coastguard Worker static void printInt(raw_ostream &OS, int Val) {
177*9880d681SAndroid Build Coastguard Worker OS << Val;
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker
getMinimalTypeForRange(uint64_t Range)180*9880d681SAndroid Build Coastguard Worker static const char *getMinimalTypeForRange(uint64_t Range) {
181*9880d681SAndroid Build Coastguard Worker assert(Range < 0xFFFFFFFFULL && "Enum too large");
182*9880d681SAndroid Build Coastguard Worker if (Range > 0xFFFF)
183*9880d681SAndroid Build Coastguard Worker return "uint32_t";
184*9880d681SAndroid Build Coastguard Worker if (Range > 0xFF)
185*9880d681SAndroid Build Coastguard Worker return "uint16_t";
186*9880d681SAndroid Build Coastguard Worker return "uint8_t";
187*9880d681SAndroid Build Coastguard Worker }
188*9880d681SAndroid Build Coastguard Worker
189*9880d681SAndroid Build Coastguard Worker void RegisterInfoEmitter::
EmitRegUnitPressure(raw_ostream & OS,const CodeGenRegBank & RegBank,const std::string & ClassName)190*9880d681SAndroid Build Coastguard Worker EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
191*9880d681SAndroid Build Coastguard Worker const std::string &ClassName) {
192*9880d681SAndroid Build Coastguard Worker unsigned NumRCs = RegBank.getRegClasses().size();
193*9880d681SAndroid Build Coastguard Worker unsigned NumSets = RegBank.getNumRegPressureSets();
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Worker OS << "/// Get the weight in units of pressure for this register class.\n"
196*9880d681SAndroid Build Coastguard Worker << "const RegClassWeight &" << ClassName << "::\n"
197*9880d681SAndroid Build Coastguard Worker << "getRegClassWeight(const TargetRegisterClass *RC) const {\n"
198*9880d681SAndroid Build Coastguard Worker << " static const RegClassWeight RCWeightTable[] = {\n";
199*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegBank.getRegClasses()) {
200*9880d681SAndroid Build Coastguard Worker const CodeGenRegister::Vec &Regs = RC.getMembers();
201*9880d681SAndroid Build Coastguard Worker if (Regs.empty())
202*9880d681SAndroid Build Coastguard Worker OS << " {0, 0";
203*9880d681SAndroid Build Coastguard Worker else {
204*9880d681SAndroid Build Coastguard Worker std::vector<unsigned> RegUnits;
205*9880d681SAndroid Build Coastguard Worker RC.buildRegUnitSet(RegUnits);
206*9880d681SAndroid Build Coastguard Worker OS << " {" << (*Regs.begin())->getWeight(RegBank)
207*9880d681SAndroid Build Coastguard Worker << ", " << RegBank.getRegUnitSetWeight(RegUnits);
208*9880d681SAndroid Build Coastguard Worker }
209*9880d681SAndroid Build Coastguard Worker OS << "}, \t// " << RC.getName() << "\n";
210*9880d681SAndroid Build Coastguard Worker }
211*9880d681SAndroid Build Coastguard Worker OS << " };\n"
212*9880d681SAndroid Build Coastguard Worker << " return RCWeightTable[RC->getID()];\n"
213*9880d681SAndroid Build Coastguard Worker << "}\n\n";
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Worker // Reasonable targets (not ARMv7) have unit weight for all units, so don't
216*9880d681SAndroid Build Coastguard Worker // bother generating a table.
217*9880d681SAndroid Build Coastguard Worker bool RegUnitsHaveUnitWeight = true;
218*9880d681SAndroid Build Coastguard Worker for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
219*9880d681SAndroid Build Coastguard Worker UnitIdx < UnitEnd; ++UnitIdx) {
220*9880d681SAndroid Build Coastguard Worker if (RegBank.getRegUnit(UnitIdx).Weight > 1)
221*9880d681SAndroid Build Coastguard Worker RegUnitsHaveUnitWeight = false;
222*9880d681SAndroid Build Coastguard Worker }
223*9880d681SAndroid Build Coastguard Worker OS << "/// Get the weight in units of pressure for this register unit.\n"
224*9880d681SAndroid Build Coastguard Worker << "unsigned " << ClassName << "::\n"
225*9880d681SAndroid Build Coastguard Worker << "getRegUnitWeight(unsigned RegUnit) const {\n"
226*9880d681SAndroid Build Coastguard Worker << " assert(RegUnit < " << RegBank.getNumNativeRegUnits()
227*9880d681SAndroid Build Coastguard Worker << " && \"invalid register unit\");\n";
228*9880d681SAndroid Build Coastguard Worker if (!RegUnitsHaveUnitWeight) {
229*9880d681SAndroid Build Coastguard Worker OS << " static const uint8_t RUWeightTable[] = {\n ";
230*9880d681SAndroid Build Coastguard Worker for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
231*9880d681SAndroid Build Coastguard Worker UnitIdx < UnitEnd; ++UnitIdx) {
232*9880d681SAndroid Build Coastguard Worker const RegUnit &RU = RegBank.getRegUnit(UnitIdx);
233*9880d681SAndroid Build Coastguard Worker assert(RU.Weight < 256 && "RegUnit too heavy");
234*9880d681SAndroid Build Coastguard Worker OS << RU.Weight << ", ";
235*9880d681SAndroid Build Coastguard Worker }
236*9880d681SAndroid Build Coastguard Worker OS << "};\n"
237*9880d681SAndroid Build Coastguard Worker << " return RUWeightTable[RegUnit];\n";
238*9880d681SAndroid Build Coastguard Worker }
239*9880d681SAndroid Build Coastguard Worker else {
240*9880d681SAndroid Build Coastguard Worker OS << " // All register units have unit weight.\n"
241*9880d681SAndroid Build Coastguard Worker << " return 1;\n";
242*9880d681SAndroid Build Coastguard Worker }
243*9880d681SAndroid Build Coastguard Worker OS << "}\n\n";
244*9880d681SAndroid Build Coastguard Worker
245*9880d681SAndroid Build Coastguard Worker OS << "\n"
246*9880d681SAndroid Build Coastguard Worker << "// Get the number of dimensions of register pressure.\n"
247*9880d681SAndroid Build Coastguard Worker << "unsigned " << ClassName << "::getNumRegPressureSets() const {\n"
248*9880d681SAndroid Build Coastguard Worker << " return " << NumSets << ";\n}\n\n";
249*9880d681SAndroid Build Coastguard Worker
250*9880d681SAndroid Build Coastguard Worker OS << "// Get the name of this register unit pressure set.\n"
251*9880d681SAndroid Build Coastguard Worker << "const char *" << ClassName << "::\n"
252*9880d681SAndroid Build Coastguard Worker << "getRegPressureSetName(unsigned Idx) const {\n"
253*9880d681SAndroid Build Coastguard Worker << " static const char *const PressureNameTable[] = {\n";
254*9880d681SAndroid Build Coastguard Worker unsigned MaxRegUnitWeight = 0;
255*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < NumSets; ++i ) {
256*9880d681SAndroid Build Coastguard Worker const RegUnitSet &RegUnits = RegBank.getRegSetAt(i);
257*9880d681SAndroid Build Coastguard Worker MaxRegUnitWeight = std::max(MaxRegUnitWeight, RegUnits.Weight);
258*9880d681SAndroid Build Coastguard Worker OS << " \"" << RegUnits.Name << "\",\n";
259*9880d681SAndroid Build Coastguard Worker }
260*9880d681SAndroid Build Coastguard Worker OS << " };\n"
261*9880d681SAndroid Build Coastguard Worker << " return PressureNameTable[Idx];\n"
262*9880d681SAndroid Build Coastguard Worker << "}\n\n";
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Worker OS << "// Get the register unit pressure limit for this dimension.\n"
265*9880d681SAndroid Build Coastguard Worker << "// This limit must be adjusted dynamically for reserved registers.\n"
266*9880d681SAndroid Build Coastguard Worker << "unsigned " << ClassName << "::\n"
267*9880d681SAndroid Build Coastguard Worker << "getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const {\n"
268*9880d681SAndroid Build Coastguard Worker << " static const " << getMinimalTypeForRange(MaxRegUnitWeight)
269*9880d681SAndroid Build Coastguard Worker << " PressureLimitTable[] = {\n";
270*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < NumSets; ++i ) {
271*9880d681SAndroid Build Coastguard Worker const RegUnitSet &RegUnits = RegBank.getRegSetAt(i);
272*9880d681SAndroid Build Coastguard Worker OS << " " << RegUnits.Weight << ", \t// " << i << ": "
273*9880d681SAndroid Build Coastguard Worker << RegUnits.Name << "\n";
274*9880d681SAndroid Build Coastguard Worker }
275*9880d681SAndroid Build Coastguard Worker OS << " };\n"
276*9880d681SAndroid Build Coastguard Worker << " return PressureLimitTable[Idx];\n"
277*9880d681SAndroid Build Coastguard Worker << "}\n\n";
278*9880d681SAndroid Build Coastguard Worker
279*9880d681SAndroid Build Coastguard Worker SequenceToOffsetTable<std::vector<int>> PSetsSeqs;
280*9880d681SAndroid Build Coastguard Worker
281*9880d681SAndroid Build Coastguard Worker // This table may be larger than NumRCs if some register units needed a list
282*9880d681SAndroid Build Coastguard Worker // of unit sets that did not correspond to a register class.
283*9880d681SAndroid Build Coastguard Worker unsigned NumRCUnitSets = RegBank.getNumRegClassPressureSetLists();
284*9880d681SAndroid Build Coastguard Worker std::vector<std::vector<int>> PSets(NumRCUnitSets);
285*9880d681SAndroid Build Coastguard Worker
286*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = NumRCUnitSets; i != e; ++i) {
287*9880d681SAndroid Build Coastguard Worker ArrayRef<unsigned> PSetIDs = RegBank.getRCPressureSetIDs(i);
288*9880d681SAndroid Build Coastguard Worker PSets[i].reserve(PSetIDs.size());
289*9880d681SAndroid Build Coastguard Worker for (ArrayRef<unsigned>::iterator PSetI = PSetIDs.begin(),
290*9880d681SAndroid Build Coastguard Worker PSetE = PSetIDs.end(); PSetI != PSetE; ++PSetI) {
291*9880d681SAndroid Build Coastguard Worker PSets[i].push_back(RegBank.getRegPressureSet(*PSetI).Order);
292*9880d681SAndroid Build Coastguard Worker }
293*9880d681SAndroid Build Coastguard Worker std::sort(PSets[i].begin(), PSets[i].end());
294*9880d681SAndroid Build Coastguard Worker PSetsSeqs.add(PSets[i]);
295*9880d681SAndroid Build Coastguard Worker }
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker PSetsSeqs.layout();
298*9880d681SAndroid Build Coastguard Worker
299*9880d681SAndroid Build Coastguard Worker OS << "/// Table of pressure sets per register class or unit.\n"
300*9880d681SAndroid Build Coastguard Worker << "static const int RCSetsTable[] = {\n";
301*9880d681SAndroid Build Coastguard Worker PSetsSeqs.emit(OS, printInt, "-1");
302*9880d681SAndroid Build Coastguard Worker OS << "};\n\n";
303*9880d681SAndroid Build Coastguard Worker
304*9880d681SAndroid Build Coastguard Worker OS << "/// Get the dimensions of register pressure impacted by this "
305*9880d681SAndroid Build Coastguard Worker << "register class.\n"
306*9880d681SAndroid Build Coastguard Worker << "/// Returns a -1 terminated array of pressure set IDs\n"
307*9880d681SAndroid Build Coastguard Worker << "const int* " << ClassName << "::\n"
308*9880d681SAndroid Build Coastguard Worker << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n";
309*9880d681SAndroid Build Coastguard Worker OS << " static const " << getMinimalTypeForRange(PSetsSeqs.size()-1)
310*9880d681SAndroid Build Coastguard Worker << " RCSetStartTable[] = {\n ";
311*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = NumRCs; i != e; ++i) {
312*9880d681SAndroid Build Coastguard Worker OS << PSetsSeqs.get(PSets[i]) << ",";
313*9880d681SAndroid Build Coastguard Worker }
314*9880d681SAndroid Build Coastguard Worker OS << "};\n"
315*9880d681SAndroid Build Coastguard Worker << " return &RCSetsTable[RCSetStartTable[RC->getID()]];\n"
316*9880d681SAndroid Build Coastguard Worker << "}\n\n";
317*9880d681SAndroid Build Coastguard Worker
318*9880d681SAndroid Build Coastguard Worker OS << "/// Get the dimensions of register pressure impacted by this "
319*9880d681SAndroid Build Coastguard Worker << "register unit.\n"
320*9880d681SAndroid Build Coastguard Worker << "/// Returns a -1 terminated array of pressure set IDs\n"
321*9880d681SAndroid Build Coastguard Worker << "const int* " << ClassName << "::\n"
322*9880d681SAndroid Build Coastguard Worker << "getRegUnitPressureSets(unsigned RegUnit) const {\n"
323*9880d681SAndroid Build Coastguard Worker << " assert(RegUnit < " << RegBank.getNumNativeRegUnits()
324*9880d681SAndroid Build Coastguard Worker << " && \"invalid register unit\");\n";
325*9880d681SAndroid Build Coastguard Worker OS << " static const " << getMinimalTypeForRange(PSetsSeqs.size()-1)
326*9880d681SAndroid Build Coastguard Worker << " RUSetStartTable[] = {\n ";
327*9880d681SAndroid Build Coastguard Worker for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
328*9880d681SAndroid Build Coastguard Worker UnitIdx < UnitEnd; ++UnitIdx) {
329*9880d681SAndroid Build Coastguard Worker OS << PSetsSeqs.get(PSets[RegBank.getRegUnit(UnitIdx).RegClassUnitSetsIdx])
330*9880d681SAndroid Build Coastguard Worker << ",";
331*9880d681SAndroid Build Coastguard Worker }
332*9880d681SAndroid Build Coastguard Worker OS << "};\n"
333*9880d681SAndroid Build Coastguard Worker << " return &RCSetsTable[RUSetStartTable[RegUnit]];\n"
334*9880d681SAndroid Build Coastguard Worker << "}\n\n";
335*9880d681SAndroid Build Coastguard Worker }
336*9880d681SAndroid Build Coastguard Worker
EmitRegMappingTables(raw_ostream & OS,const std::deque<CodeGenRegister> & Regs,bool isCtor)337*9880d681SAndroid Build Coastguard Worker void RegisterInfoEmitter::EmitRegMappingTables(
338*9880d681SAndroid Build Coastguard Worker raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) {
339*9880d681SAndroid Build Coastguard Worker // Collect all information about dwarf register numbers
340*9880d681SAndroid Build Coastguard Worker typedef std::map<Record*, std::vector<int64_t>, LessRecordRegister> DwarfRegNumsMapTy;
341*9880d681SAndroid Build Coastguard Worker DwarfRegNumsMapTy DwarfRegNums;
342*9880d681SAndroid Build Coastguard Worker
343*9880d681SAndroid Build Coastguard Worker // First, just pull all provided information to the map
344*9880d681SAndroid Build Coastguard Worker unsigned maxLength = 0;
345*9880d681SAndroid Build Coastguard Worker for (auto &RE : Regs) {
346*9880d681SAndroid Build Coastguard Worker Record *Reg = RE.TheDef;
347*9880d681SAndroid Build Coastguard Worker std::vector<int64_t> RegNums = Reg->getValueAsListOfInts("DwarfNumbers");
348*9880d681SAndroid Build Coastguard Worker maxLength = std::max((size_t)maxLength, RegNums.size());
349*9880d681SAndroid Build Coastguard Worker if (DwarfRegNums.count(Reg))
350*9880d681SAndroid Build Coastguard Worker PrintWarning(Reg->getLoc(), Twine("DWARF numbers for register ") +
351*9880d681SAndroid Build Coastguard Worker getQualifiedName(Reg) + "specified multiple times");
352*9880d681SAndroid Build Coastguard Worker DwarfRegNums[Reg] = RegNums;
353*9880d681SAndroid Build Coastguard Worker }
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Worker if (!maxLength)
356*9880d681SAndroid Build Coastguard Worker return;
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Worker // Now we know maximal length of number list. Append -1's, where needed
359*9880d681SAndroid Build Coastguard Worker for (DwarfRegNumsMapTy::iterator
360*9880d681SAndroid Build Coastguard Worker I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I)
361*9880d681SAndroid Build Coastguard Worker for (unsigned i = I->second.size(), e = maxLength; i != e; ++i)
362*9880d681SAndroid Build Coastguard Worker I->second.push_back(-1);
363*9880d681SAndroid Build Coastguard Worker
364*9880d681SAndroid Build Coastguard Worker std::string Namespace = Regs.front().TheDef->getValueAsString("Namespace");
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker OS << "// " << Namespace << " Dwarf<->LLVM register mappings.\n";
367*9880d681SAndroid Build Coastguard Worker
368*9880d681SAndroid Build Coastguard Worker // Emit reverse information about the dwarf register numbers.
369*9880d681SAndroid Build Coastguard Worker for (unsigned j = 0; j < 2; ++j) {
370*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = maxLength; i != e; ++i) {
371*9880d681SAndroid Build Coastguard Worker OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;
372*9880d681SAndroid Build Coastguard Worker OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");
373*9880d681SAndroid Build Coastguard Worker OS << i << "Dwarf2L[]";
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker if (!isCtor) {
376*9880d681SAndroid Build Coastguard Worker OS << " = {\n";
377*9880d681SAndroid Build Coastguard Worker
378*9880d681SAndroid Build Coastguard Worker // Store the mapping sorted by the LLVM reg num so lookup can be done
379*9880d681SAndroid Build Coastguard Worker // with a binary search.
380*9880d681SAndroid Build Coastguard Worker std::map<uint64_t, Record*> Dwarf2LMap;
381*9880d681SAndroid Build Coastguard Worker for (DwarfRegNumsMapTy::iterator
382*9880d681SAndroid Build Coastguard Worker I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
383*9880d681SAndroid Build Coastguard Worker int DwarfRegNo = I->second[i];
384*9880d681SAndroid Build Coastguard Worker if (DwarfRegNo < 0)
385*9880d681SAndroid Build Coastguard Worker continue;
386*9880d681SAndroid Build Coastguard Worker Dwarf2LMap[DwarfRegNo] = I->first;
387*9880d681SAndroid Build Coastguard Worker }
388*9880d681SAndroid Build Coastguard Worker
389*9880d681SAndroid Build Coastguard Worker for (std::map<uint64_t, Record*>::iterator
390*9880d681SAndroid Build Coastguard Worker I = Dwarf2LMap.begin(), E = Dwarf2LMap.end(); I != E; ++I)
391*9880d681SAndroid Build Coastguard Worker OS << " { " << I->first << "U, " << getQualifiedName(I->second)
392*9880d681SAndroid Build Coastguard Worker << " },\n";
393*9880d681SAndroid Build Coastguard Worker
394*9880d681SAndroid Build Coastguard Worker OS << "};\n";
395*9880d681SAndroid Build Coastguard Worker } else {
396*9880d681SAndroid Build Coastguard Worker OS << ";\n";
397*9880d681SAndroid Build Coastguard Worker }
398*9880d681SAndroid Build Coastguard Worker
399*9880d681SAndroid Build Coastguard Worker // We have to store the size in a const global, it's used in multiple
400*9880d681SAndroid Build Coastguard Worker // places.
401*9880d681SAndroid Build Coastguard Worker OS << "extern const unsigned " << Namespace
402*9880d681SAndroid Build Coastguard Worker << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "Dwarf2LSize";
403*9880d681SAndroid Build Coastguard Worker if (!isCtor)
404*9880d681SAndroid Build Coastguard Worker OS << " = array_lengthof(" << Namespace
405*9880d681SAndroid Build Coastguard Worker << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
406*9880d681SAndroid Build Coastguard Worker << "Dwarf2L);\n\n";
407*9880d681SAndroid Build Coastguard Worker else
408*9880d681SAndroid Build Coastguard Worker OS << ";\n\n";
409*9880d681SAndroid Build Coastguard Worker }
410*9880d681SAndroid Build Coastguard Worker }
411*9880d681SAndroid Build Coastguard Worker
412*9880d681SAndroid Build Coastguard Worker for (auto &RE : Regs) {
413*9880d681SAndroid Build Coastguard Worker Record *Reg = RE.TheDef;
414*9880d681SAndroid Build Coastguard Worker const RecordVal *V = Reg->getValue("DwarfAlias");
415*9880d681SAndroid Build Coastguard Worker if (!V || !V->getValue())
416*9880d681SAndroid Build Coastguard Worker continue;
417*9880d681SAndroid Build Coastguard Worker
418*9880d681SAndroid Build Coastguard Worker DefInit *DI = cast<DefInit>(V->getValue());
419*9880d681SAndroid Build Coastguard Worker Record *Alias = DI->getDef();
420*9880d681SAndroid Build Coastguard Worker DwarfRegNums[Reg] = DwarfRegNums[Alias];
421*9880d681SAndroid Build Coastguard Worker }
422*9880d681SAndroid Build Coastguard Worker
423*9880d681SAndroid Build Coastguard Worker // Emit information about the dwarf register numbers.
424*9880d681SAndroid Build Coastguard Worker for (unsigned j = 0; j < 2; ++j) {
425*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = maxLength; i != e; ++i) {
426*9880d681SAndroid Build Coastguard Worker OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;
427*9880d681SAndroid Build Coastguard Worker OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");
428*9880d681SAndroid Build Coastguard Worker OS << i << "L2Dwarf[]";
429*9880d681SAndroid Build Coastguard Worker if (!isCtor) {
430*9880d681SAndroid Build Coastguard Worker OS << " = {\n";
431*9880d681SAndroid Build Coastguard Worker // Store the mapping sorted by the Dwarf reg num so lookup can be done
432*9880d681SAndroid Build Coastguard Worker // with a binary search.
433*9880d681SAndroid Build Coastguard Worker for (DwarfRegNumsMapTy::iterator
434*9880d681SAndroid Build Coastguard Worker I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
435*9880d681SAndroid Build Coastguard Worker int RegNo = I->second[i];
436*9880d681SAndroid Build Coastguard Worker if (RegNo == -1) // -1 is the default value, don't emit a mapping.
437*9880d681SAndroid Build Coastguard Worker continue;
438*9880d681SAndroid Build Coastguard Worker
439*9880d681SAndroid Build Coastguard Worker OS << " { " << getQualifiedName(I->first) << ", " << RegNo
440*9880d681SAndroid Build Coastguard Worker << "U },\n";
441*9880d681SAndroid Build Coastguard Worker }
442*9880d681SAndroid Build Coastguard Worker OS << "};\n";
443*9880d681SAndroid Build Coastguard Worker } else {
444*9880d681SAndroid Build Coastguard Worker OS << ";\n";
445*9880d681SAndroid Build Coastguard Worker }
446*9880d681SAndroid Build Coastguard Worker
447*9880d681SAndroid Build Coastguard Worker // We have to store the size in a const global, it's used in multiple
448*9880d681SAndroid Build Coastguard Worker // places.
449*9880d681SAndroid Build Coastguard Worker OS << "extern const unsigned " << Namespace
450*9880d681SAndroid Build Coastguard Worker << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "L2DwarfSize";
451*9880d681SAndroid Build Coastguard Worker if (!isCtor)
452*9880d681SAndroid Build Coastguard Worker OS << " = array_lengthof(" << Namespace
453*9880d681SAndroid Build Coastguard Worker << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "L2Dwarf);\n\n";
454*9880d681SAndroid Build Coastguard Worker else
455*9880d681SAndroid Build Coastguard Worker OS << ";\n\n";
456*9880d681SAndroid Build Coastguard Worker }
457*9880d681SAndroid Build Coastguard Worker }
458*9880d681SAndroid Build Coastguard Worker }
459*9880d681SAndroid Build Coastguard Worker
EmitRegMapping(raw_ostream & OS,const std::deque<CodeGenRegister> & Regs,bool isCtor)460*9880d681SAndroid Build Coastguard Worker void RegisterInfoEmitter::EmitRegMapping(
461*9880d681SAndroid Build Coastguard Worker raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) {
462*9880d681SAndroid Build Coastguard Worker // Emit the initializer so the tables from EmitRegMappingTables get wired up
463*9880d681SAndroid Build Coastguard Worker // to the MCRegisterInfo object.
464*9880d681SAndroid Build Coastguard Worker unsigned maxLength = 0;
465*9880d681SAndroid Build Coastguard Worker for (auto &RE : Regs) {
466*9880d681SAndroid Build Coastguard Worker Record *Reg = RE.TheDef;
467*9880d681SAndroid Build Coastguard Worker maxLength = std::max((size_t)maxLength,
468*9880d681SAndroid Build Coastguard Worker Reg->getValueAsListOfInts("DwarfNumbers").size());
469*9880d681SAndroid Build Coastguard Worker }
470*9880d681SAndroid Build Coastguard Worker
471*9880d681SAndroid Build Coastguard Worker if (!maxLength)
472*9880d681SAndroid Build Coastguard Worker return;
473*9880d681SAndroid Build Coastguard Worker
474*9880d681SAndroid Build Coastguard Worker std::string Namespace = Regs.front().TheDef->getValueAsString("Namespace");
475*9880d681SAndroid Build Coastguard Worker
476*9880d681SAndroid Build Coastguard Worker // Emit reverse information about the dwarf register numbers.
477*9880d681SAndroid Build Coastguard Worker for (unsigned j = 0; j < 2; ++j) {
478*9880d681SAndroid Build Coastguard Worker OS << " switch (";
479*9880d681SAndroid Build Coastguard Worker if (j == 0)
480*9880d681SAndroid Build Coastguard Worker OS << "DwarfFlavour";
481*9880d681SAndroid Build Coastguard Worker else
482*9880d681SAndroid Build Coastguard Worker OS << "EHFlavour";
483*9880d681SAndroid Build Coastguard Worker OS << ") {\n"
484*9880d681SAndroid Build Coastguard Worker << " default:\n"
485*9880d681SAndroid Build Coastguard Worker << " llvm_unreachable(\"Unknown DWARF flavour\");\n";
486*9880d681SAndroid Build Coastguard Worker
487*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = maxLength; i != e; ++i) {
488*9880d681SAndroid Build Coastguard Worker OS << " case " << i << ":\n";
489*9880d681SAndroid Build Coastguard Worker OS << " ";
490*9880d681SAndroid Build Coastguard Worker if (!isCtor)
491*9880d681SAndroid Build Coastguard Worker OS << "RI->";
492*9880d681SAndroid Build Coastguard Worker std::string Tmp;
493*9880d681SAndroid Build Coastguard Worker raw_string_ostream(Tmp) << Namespace
494*9880d681SAndroid Build Coastguard Worker << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
495*9880d681SAndroid Build Coastguard Worker << "Dwarf2L";
496*9880d681SAndroid Build Coastguard Worker OS << "mapDwarfRegsToLLVMRegs(" << Tmp << ", " << Tmp << "Size, ";
497*9880d681SAndroid Build Coastguard Worker if (j == 0)
498*9880d681SAndroid Build Coastguard Worker OS << "false";
499*9880d681SAndroid Build Coastguard Worker else
500*9880d681SAndroid Build Coastguard Worker OS << "true";
501*9880d681SAndroid Build Coastguard Worker OS << ");\n";
502*9880d681SAndroid Build Coastguard Worker OS << " break;\n";
503*9880d681SAndroid Build Coastguard Worker }
504*9880d681SAndroid Build Coastguard Worker OS << " }\n";
505*9880d681SAndroid Build Coastguard Worker }
506*9880d681SAndroid Build Coastguard Worker
507*9880d681SAndroid Build Coastguard Worker // Emit information about the dwarf register numbers.
508*9880d681SAndroid Build Coastguard Worker for (unsigned j = 0; j < 2; ++j) {
509*9880d681SAndroid Build Coastguard Worker OS << " switch (";
510*9880d681SAndroid Build Coastguard Worker if (j == 0)
511*9880d681SAndroid Build Coastguard Worker OS << "DwarfFlavour";
512*9880d681SAndroid Build Coastguard Worker else
513*9880d681SAndroid Build Coastguard Worker OS << "EHFlavour";
514*9880d681SAndroid Build Coastguard Worker OS << ") {\n"
515*9880d681SAndroid Build Coastguard Worker << " default:\n"
516*9880d681SAndroid Build Coastguard Worker << " llvm_unreachable(\"Unknown DWARF flavour\");\n";
517*9880d681SAndroid Build Coastguard Worker
518*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = maxLength; i != e; ++i) {
519*9880d681SAndroid Build Coastguard Worker OS << " case " << i << ":\n";
520*9880d681SAndroid Build Coastguard Worker OS << " ";
521*9880d681SAndroid Build Coastguard Worker if (!isCtor)
522*9880d681SAndroid Build Coastguard Worker OS << "RI->";
523*9880d681SAndroid Build Coastguard Worker std::string Tmp;
524*9880d681SAndroid Build Coastguard Worker raw_string_ostream(Tmp) << Namespace
525*9880d681SAndroid Build Coastguard Worker << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
526*9880d681SAndroid Build Coastguard Worker << "L2Dwarf";
527*9880d681SAndroid Build Coastguard Worker OS << "mapLLVMRegsToDwarfRegs(" << Tmp << ", " << Tmp << "Size, ";
528*9880d681SAndroid Build Coastguard Worker if (j == 0)
529*9880d681SAndroid Build Coastguard Worker OS << "false";
530*9880d681SAndroid Build Coastguard Worker else
531*9880d681SAndroid Build Coastguard Worker OS << "true";
532*9880d681SAndroid Build Coastguard Worker OS << ");\n";
533*9880d681SAndroid Build Coastguard Worker OS << " break;\n";
534*9880d681SAndroid Build Coastguard Worker }
535*9880d681SAndroid Build Coastguard Worker OS << " }\n";
536*9880d681SAndroid Build Coastguard Worker }
537*9880d681SAndroid Build Coastguard Worker }
538*9880d681SAndroid Build Coastguard Worker
539*9880d681SAndroid Build Coastguard Worker // Print a BitVector as a sequence of hex numbers using a little-endian mapping.
540*9880d681SAndroid Build Coastguard Worker // Width is the number of bits per hex number.
printBitVectorAsHex(raw_ostream & OS,const BitVector & Bits,unsigned Width)541*9880d681SAndroid Build Coastguard Worker static void printBitVectorAsHex(raw_ostream &OS,
542*9880d681SAndroid Build Coastguard Worker const BitVector &Bits,
543*9880d681SAndroid Build Coastguard Worker unsigned Width) {
544*9880d681SAndroid Build Coastguard Worker assert(Width <= 32 && "Width too large");
545*9880d681SAndroid Build Coastguard Worker unsigned Digits = (Width + 3) / 4;
546*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Bits.size(); i < e; i += Width) {
547*9880d681SAndroid Build Coastguard Worker unsigned Value = 0;
548*9880d681SAndroid Build Coastguard Worker for (unsigned j = 0; j != Width && i + j != e; ++j)
549*9880d681SAndroid Build Coastguard Worker Value |= Bits.test(i + j) << j;
550*9880d681SAndroid Build Coastguard Worker OS << format("0x%0*x, ", Digits, Value);
551*9880d681SAndroid Build Coastguard Worker }
552*9880d681SAndroid Build Coastguard Worker }
553*9880d681SAndroid Build Coastguard Worker
554*9880d681SAndroid Build Coastguard Worker // Helper to emit a set of bits into a constant byte array.
555*9880d681SAndroid Build Coastguard Worker class BitVectorEmitter {
556*9880d681SAndroid Build Coastguard Worker BitVector Values;
557*9880d681SAndroid Build Coastguard Worker public:
add(unsigned v)558*9880d681SAndroid Build Coastguard Worker void add(unsigned v) {
559*9880d681SAndroid Build Coastguard Worker if (v >= Values.size())
560*9880d681SAndroid Build Coastguard Worker Values.resize(((v/8)+1)*8); // Round up to the next byte.
561*9880d681SAndroid Build Coastguard Worker Values[v] = true;
562*9880d681SAndroid Build Coastguard Worker }
563*9880d681SAndroid Build Coastguard Worker
print(raw_ostream & OS)564*9880d681SAndroid Build Coastguard Worker void print(raw_ostream &OS) {
565*9880d681SAndroid Build Coastguard Worker printBitVectorAsHex(OS, Values, 8);
566*9880d681SAndroid Build Coastguard Worker }
567*9880d681SAndroid Build Coastguard Worker };
568*9880d681SAndroid Build Coastguard Worker
printSimpleValueType(raw_ostream & OS,MVT::SimpleValueType VT)569*9880d681SAndroid Build Coastguard Worker static void printSimpleValueType(raw_ostream &OS, MVT::SimpleValueType VT) {
570*9880d681SAndroid Build Coastguard Worker OS << getEnumName(VT);
571*9880d681SAndroid Build Coastguard Worker }
572*9880d681SAndroid Build Coastguard Worker
printSubRegIndex(raw_ostream & OS,const CodeGenSubRegIndex * Idx)573*9880d681SAndroid Build Coastguard Worker static void printSubRegIndex(raw_ostream &OS, const CodeGenSubRegIndex *Idx) {
574*9880d681SAndroid Build Coastguard Worker OS << Idx->EnumValue;
575*9880d681SAndroid Build Coastguard Worker }
576*9880d681SAndroid Build Coastguard Worker
577*9880d681SAndroid Build Coastguard Worker // Differentially encoded register and regunit lists allow for better
578*9880d681SAndroid Build Coastguard Worker // compression on regular register banks. The sequence is computed from the
579*9880d681SAndroid Build Coastguard Worker // differential list as:
580*9880d681SAndroid Build Coastguard Worker //
581*9880d681SAndroid Build Coastguard Worker // out[0] = InitVal;
582*9880d681SAndroid Build Coastguard Worker // out[n+1] = out[n] + diff[n]; // n = 0, 1, ...
583*9880d681SAndroid Build Coastguard Worker //
584*9880d681SAndroid Build Coastguard Worker // The initial value depends on the specific list. The list is terminated by a
585*9880d681SAndroid Build Coastguard Worker // 0 differential which means we can't encode repeated elements.
586*9880d681SAndroid Build Coastguard Worker
587*9880d681SAndroid Build Coastguard Worker typedef SmallVector<uint16_t, 4> DiffVec;
588*9880d681SAndroid Build Coastguard Worker typedef SmallVector<unsigned, 4> MaskVec;
589*9880d681SAndroid Build Coastguard Worker
590*9880d681SAndroid Build Coastguard Worker // Differentially encode a sequence of numbers into V. The starting value and
591*9880d681SAndroid Build Coastguard Worker // terminating 0 are not added to V, so it will have the same size as List.
592*9880d681SAndroid Build Coastguard Worker static
diffEncode(DiffVec & V,unsigned InitVal,SparseBitVector<> List)593*9880d681SAndroid Build Coastguard Worker DiffVec &diffEncode(DiffVec &V, unsigned InitVal, SparseBitVector<> List) {
594*9880d681SAndroid Build Coastguard Worker assert(V.empty() && "Clear DiffVec before diffEncode.");
595*9880d681SAndroid Build Coastguard Worker uint16_t Val = uint16_t(InitVal);
596*9880d681SAndroid Build Coastguard Worker
597*9880d681SAndroid Build Coastguard Worker for (uint16_t Cur : List) {
598*9880d681SAndroid Build Coastguard Worker V.push_back(Cur - Val);
599*9880d681SAndroid Build Coastguard Worker Val = Cur;
600*9880d681SAndroid Build Coastguard Worker }
601*9880d681SAndroid Build Coastguard Worker return V;
602*9880d681SAndroid Build Coastguard Worker }
603*9880d681SAndroid Build Coastguard Worker
604*9880d681SAndroid Build Coastguard Worker template<typename Iter>
605*9880d681SAndroid Build Coastguard Worker static
diffEncode(DiffVec & V,unsigned InitVal,Iter Begin,Iter End)606*9880d681SAndroid Build Coastguard Worker DiffVec &diffEncode(DiffVec &V, unsigned InitVal, Iter Begin, Iter End) {
607*9880d681SAndroid Build Coastguard Worker assert(V.empty() && "Clear DiffVec before diffEncode.");
608*9880d681SAndroid Build Coastguard Worker uint16_t Val = uint16_t(InitVal);
609*9880d681SAndroid Build Coastguard Worker for (Iter I = Begin; I != End; ++I) {
610*9880d681SAndroid Build Coastguard Worker uint16_t Cur = (*I)->EnumValue;
611*9880d681SAndroid Build Coastguard Worker V.push_back(Cur - Val);
612*9880d681SAndroid Build Coastguard Worker Val = Cur;
613*9880d681SAndroid Build Coastguard Worker }
614*9880d681SAndroid Build Coastguard Worker return V;
615*9880d681SAndroid Build Coastguard Worker }
616*9880d681SAndroid Build Coastguard Worker
printDiff16(raw_ostream & OS,uint16_t Val)617*9880d681SAndroid Build Coastguard Worker static void printDiff16(raw_ostream &OS, uint16_t Val) {
618*9880d681SAndroid Build Coastguard Worker OS << Val;
619*9880d681SAndroid Build Coastguard Worker }
620*9880d681SAndroid Build Coastguard Worker
printMask(raw_ostream & OS,unsigned Val)621*9880d681SAndroid Build Coastguard Worker static void printMask(raw_ostream &OS, unsigned Val) {
622*9880d681SAndroid Build Coastguard Worker OS << format("0x%08X", Val);
623*9880d681SAndroid Build Coastguard Worker }
624*9880d681SAndroid Build Coastguard Worker
625*9880d681SAndroid Build Coastguard Worker // Try to combine Idx's compose map into Vec if it is compatible.
626*9880d681SAndroid Build Coastguard Worker // Return false if it's not possible.
combine(const CodeGenSubRegIndex * Idx,SmallVectorImpl<CodeGenSubRegIndex * > & Vec)627*9880d681SAndroid Build Coastguard Worker static bool combine(const CodeGenSubRegIndex *Idx,
628*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<CodeGenSubRegIndex*> &Vec) {
629*9880d681SAndroid Build Coastguard Worker const CodeGenSubRegIndex::CompMap &Map = Idx->getComposites();
630*9880d681SAndroid Build Coastguard Worker for (const auto &I : Map) {
631*9880d681SAndroid Build Coastguard Worker CodeGenSubRegIndex *&Entry = Vec[I.first->EnumValue - 1];
632*9880d681SAndroid Build Coastguard Worker if (Entry && Entry != I.second)
633*9880d681SAndroid Build Coastguard Worker return false;
634*9880d681SAndroid Build Coastguard Worker }
635*9880d681SAndroid Build Coastguard Worker
636*9880d681SAndroid Build Coastguard Worker // All entries are compatible. Make it so.
637*9880d681SAndroid Build Coastguard Worker for (const auto &I : Map) {
638*9880d681SAndroid Build Coastguard Worker auto *&Entry = Vec[I.first->EnumValue - 1];
639*9880d681SAndroid Build Coastguard Worker assert((!Entry || Entry == I.second) &&
640*9880d681SAndroid Build Coastguard Worker "Expected EnumValue to be unique");
641*9880d681SAndroid Build Coastguard Worker Entry = I.second;
642*9880d681SAndroid Build Coastguard Worker }
643*9880d681SAndroid Build Coastguard Worker return true;
644*9880d681SAndroid Build Coastguard Worker }
645*9880d681SAndroid Build Coastguard Worker
646*9880d681SAndroid Build Coastguard Worker void
emitComposeSubRegIndices(raw_ostream & OS,CodeGenRegBank & RegBank,const std::string & ClName)647*9880d681SAndroid Build Coastguard Worker RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS,
648*9880d681SAndroid Build Coastguard Worker CodeGenRegBank &RegBank,
649*9880d681SAndroid Build Coastguard Worker const std::string &ClName) {
650*9880d681SAndroid Build Coastguard Worker const auto &SubRegIndices = RegBank.getSubRegIndices();
651*9880d681SAndroid Build Coastguard Worker OS << "unsigned " << ClName
652*9880d681SAndroid Build Coastguard Worker << "::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {\n";
653*9880d681SAndroid Build Coastguard Worker
654*9880d681SAndroid Build Coastguard Worker // Many sub-register indexes are composition-compatible, meaning that
655*9880d681SAndroid Build Coastguard Worker //
656*9880d681SAndroid Build Coastguard Worker // compose(IdxA, IdxB) == compose(IdxA', IdxB)
657*9880d681SAndroid Build Coastguard Worker //
658*9880d681SAndroid Build Coastguard Worker // for many IdxA, IdxA' pairs. Not all sub-register indexes can be composed.
659*9880d681SAndroid Build Coastguard Worker // The illegal entries can be use as wildcards to compress the table further.
660*9880d681SAndroid Build Coastguard Worker
661*9880d681SAndroid Build Coastguard Worker // Map each Sub-register index to a compatible table row.
662*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 4> RowMap;
663*9880d681SAndroid Build Coastguard Worker SmallVector<SmallVector<CodeGenSubRegIndex*, 4>, 4> Rows;
664*9880d681SAndroid Build Coastguard Worker
665*9880d681SAndroid Build Coastguard Worker auto SubRegIndicesSize =
666*9880d681SAndroid Build Coastguard Worker std::distance(SubRegIndices.begin(), SubRegIndices.end());
667*9880d681SAndroid Build Coastguard Worker for (const auto &Idx : SubRegIndices) {
668*9880d681SAndroid Build Coastguard Worker unsigned Found = ~0u;
669*9880d681SAndroid Build Coastguard Worker for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
670*9880d681SAndroid Build Coastguard Worker if (combine(&Idx, Rows[r])) {
671*9880d681SAndroid Build Coastguard Worker Found = r;
672*9880d681SAndroid Build Coastguard Worker break;
673*9880d681SAndroid Build Coastguard Worker }
674*9880d681SAndroid Build Coastguard Worker }
675*9880d681SAndroid Build Coastguard Worker if (Found == ~0u) {
676*9880d681SAndroid Build Coastguard Worker Found = Rows.size();
677*9880d681SAndroid Build Coastguard Worker Rows.resize(Found + 1);
678*9880d681SAndroid Build Coastguard Worker Rows.back().resize(SubRegIndicesSize);
679*9880d681SAndroid Build Coastguard Worker combine(&Idx, Rows.back());
680*9880d681SAndroid Build Coastguard Worker }
681*9880d681SAndroid Build Coastguard Worker RowMap.push_back(Found);
682*9880d681SAndroid Build Coastguard Worker }
683*9880d681SAndroid Build Coastguard Worker
684*9880d681SAndroid Build Coastguard Worker // Output the row map if there is multiple rows.
685*9880d681SAndroid Build Coastguard Worker if (Rows.size() > 1) {
686*9880d681SAndroid Build Coastguard Worker OS << " static const " << getMinimalTypeForRange(Rows.size()) << " RowMap["
687*9880d681SAndroid Build Coastguard Worker << SubRegIndicesSize << "] = {\n ";
688*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = SubRegIndicesSize; i != e; ++i)
689*9880d681SAndroid Build Coastguard Worker OS << RowMap[i] << ", ";
690*9880d681SAndroid Build Coastguard Worker OS << "\n };\n";
691*9880d681SAndroid Build Coastguard Worker }
692*9880d681SAndroid Build Coastguard Worker
693*9880d681SAndroid Build Coastguard Worker // Output the rows.
694*9880d681SAndroid Build Coastguard Worker OS << " static const " << getMinimalTypeForRange(SubRegIndicesSize + 1)
695*9880d681SAndroid Build Coastguard Worker << " Rows[" << Rows.size() << "][" << SubRegIndicesSize << "] = {\n";
696*9880d681SAndroid Build Coastguard Worker for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
697*9880d681SAndroid Build Coastguard Worker OS << " { ";
698*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = SubRegIndicesSize; i != e; ++i)
699*9880d681SAndroid Build Coastguard Worker if (Rows[r][i])
700*9880d681SAndroid Build Coastguard Worker OS << Rows[r][i]->EnumValue << ", ";
701*9880d681SAndroid Build Coastguard Worker else
702*9880d681SAndroid Build Coastguard Worker OS << "0, ";
703*9880d681SAndroid Build Coastguard Worker OS << "},\n";
704*9880d681SAndroid Build Coastguard Worker }
705*9880d681SAndroid Build Coastguard Worker OS << " };\n\n";
706*9880d681SAndroid Build Coastguard Worker
707*9880d681SAndroid Build Coastguard Worker OS << " --IdxA; assert(IdxA < " << SubRegIndicesSize << ");\n"
708*9880d681SAndroid Build Coastguard Worker << " --IdxB; assert(IdxB < " << SubRegIndicesSize << ");\n";
709*9880d681SAndroid Build Coastguard Worker if (Rows.size() > 1)
710*9880d681SAndroid Build Coastguard Worker OS << " return Rows[RowMap[IdxA]][IdxB];\n";
711*9880d681SAndroid Build Coastguard Worker else
712*9880d681SAndroid Build Coastguard Worker OS << " return Rows[0][IdxB];\n";
713*9880d681SAndroid Build Coastguard Worker OS << "}\n\n";
714*9880d681SAndroid Build Coastguard Worker }
715*9880d681SAndroid Build Coastguard Worker
716*9880d681SAndroid Build Coastguard Worker void
emitComposeSubRegIndexLaneMask(raw_ostream & OS,CodeGenRegBank & RegBank,const std::string & ClName)717*9880d681SAndroid Build Coastguard Worker RegisterInfoEmitter::emitComposeSubRegIndexLaneMask(raw_ostream &OS,
718*9880d681SAndroid Build Coastguard Worker CodeGenRegBank &RegBank,
719*9880d681SAndroid Build Coastguard Worker const std::string &ClName) {
720*9880d681SAndroid Build Coastguard Worker // See the comments in computeSubRegLaneMasks() for our goal here.
721*9880d681SAndroid Build Coastguard Worker const auto &SubRegIndices = RegBank.getSubRegIndices();
722*9880d681SAndroid Build Coastguard Worker
723*9880d681SAndroid Build Coastguard Worker // Create a list of Mask+Rotate operations, with equivalent entries merged.
724*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 4> SubReg2SequenceIndexMap;
725*9880d681SAndroid Build Coastguard Worker SmallVector<SmallVector<MaskRolPair, 1>, 4> Sequences;
726*9880d681SAndroid Build Coastguard Worker for (const auto &Idx : SubRegIndices) {
727*9880d681SAndroid Build Coastguard Worker const SmallVector<MaskRolPair, 1> &IdxSequence
728*9880d681SAndroid Build Coastguard Worker = Idx.CompositionLaneMaskTransform;
729*9880d681SAndroid Build Coastguard Worker
730*9880d681SAndroid Build Coastguard Worker unsigned Found = ~0u;
731*9880d681SAndroid Build Coastguard Worker unsigned SIdx = 0;
732*9880d681SAndroid Build Coastguard Worker unsigned NextSIdx;
733*9880d681SAndroid Build Coastguard Worker for (size_t s = 0, se = Sequences.size(); s != se; ++s, SIdx = NextSIdx) {
734*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
735*9880d681SAndroid Build Coastguard Worker NextSIdx = SIdx + Sequence.size() + 1;
736*9880d681SAndroid Build Coastguard Worker if (Sequence == IdxSequence) {
737*9880d681SAndroid Build Coastguard Worker Found = SIdx;
738*9880d681SAndroid Build Coastguard Worker break;
739*9880d681SAndroid Build Coastguard Worker }
740*9880d681SAndroid Build Coastguard Worker }
741*9880d681SAndroid Build Coastguard Worker if (Found == ~0u) {
742*9880d681SAndroid Build Coastguard Worker Sequences.push_back(IdxSequence);
743*9880d681SAndroid Build Coastguard Worker Found = SIdx;
744*9880d681SAndroid Build Coastguard Worker }
745*9880d681SAndroid Build Coastguard Worker SubReg2SequenceIndexMap.push_back(Found);
746*9880d681SAndroid Build Coastguard Worker }
747*9880d681SAndroid Build Coastguard Worker
748*9880d681SAndroid Build Coastguard Worker OS << " struct MaskRolOp {\n"
749*9880d681SAndroid Build Coastguard Worker " unsigned Mask;\n"
750*9880d681SAndroid Build Coastguard Worker " uint8_t RotateLeft;\n"
751*9880d681SAndroid Build Coastguard Worker " };\n"
752*9880d681SAndroid Build Coastguard Worker " static const MaskRolOp LaneMaskComposeSequences[] = {\n";
753*9880d681SAndroid Build Coastguard Worker unsigned Idx = 0;
754*9880d681SAndroid Build Coastguard Worker for (size_t s = 0, se = Sequences.size(); s != se; ++s) {
755*9880d681SAndroid Build Coastguard Worker OS << " ";
756*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
757*9880d681SAndroid Build Coastguard Worker for (size_t p = 0, pe = Sequence.size(); p != pe; ++p) {
758*9880d681SAndroid Build Coastguard Worker const MaskRolPair &P = Sequence[p];
759*9880d681SAndroid Build Coastguard Worker OS << format("{ 0x%08X, %2u }, ", P.Mask, P.RotateLeft);
760*9880d681SAndroid Build Coastguard Worker }
761*9880d681SAndroid Build Coastguard Worker OS << "{ 0, 0 }";
762*9880d681SAndroid Build Coastguard Worker if (s+1 != se)
763*9880d681SAndroid Build Coastguard Worker OS << ", ";
764*9880d681SAndroid Build Coastguard Worker OS << " // Sequence " << Idx << "\n";
765*9880d681SAndroid Build Coastguard Worker Idx += Sequence.size() + 1;
766*9880d681SAndroid Build Coastguard Worker }
767*9880d681SAndroid Build Coastguard Worker OS << " };\n"
768*9880d681SAndroid Build Coastguard Worker " static const MaskRolOp *const CompositeSequences[] = {\n";
769*9880d681SAndroid Build Coastguard Worker for (size_t i = 0, e = SubRegIndices.size(); i != e; ++i) {
770*9880d681SAndroid Build Coastguard Worker OS << " ";
771*9880d681SAndroid Build Coastguard Worker unsigned Idx = SubReg2SequenceIndexMap[i];
772*9880d681SAndroid Build Coastguard Worker OS << format("&LaneMaskComposeSequences[%u]", Idx);
773*9880d681SAndroid Build Coastguard Worker if (i+1 != e)
774*9880d681SAndroid Build Coastguard Worker OS << ",";
775*9880d681SAndroid Build Coastguard Worker OS << " // to " << SubRegIndices[i].getName() << "\n";
776*9880d681SAndroid Build Coastguard Worker }
777*9880d681SAndroid Build Coastguard Worker OS << " };\n\n";
778*9880d681SAndroid Build Coastguard Worker
779*9880d681SAndroid Build Coastguard Worker OS << "LaneBitmask " << ClName
780*9880d681SAndroid Build Coastguard Worker << "::composeSubRegIndexLaneMaskImpl(unsigned IdxA, LaneBitmask LaneMask)"
781*9880d681SAndroid Build Coastguard Worker " const {\n"
782*9880d681SAndroid Build Coastguard Worker " --IdxA; assert(IdxA < " << SubRegIndices.size()
783*9880d681SAndroid Build Coastguard Worker << " && \"Subregister index out of bounds\");\n"
784*9880d681SAndroid Build Coastguard Worker " LaneBitmask Result = 0;\n"
785*9880d681SAndroid Build Coastguard Worker " for (const MaskRolOp *Ops = CompositeSequences[IdxA]; Ops->Mask != 0; ++Ops)"
786*9880d681SAndroid Build Coastguard Worker " {\n"
787*9880d681SAndroid Build Coastguard Worker " LaneBitmask Masked = LaneMask & Ops->Mask;\n"
788*9880d681SAndroid Build Coastguard Worker " Result |= (Masked << Ops->RotateLeft) & 0xFFFFFFFF;\n"
789*9880d681SAndroid Build Coastguard Worker " Result |= (Masked >> ((32 - Ops->RotateLeft) & 0x1F));\n"
790*9880d681SAndroid Build Coastguard Worker " }\n"
791*9880d681SAndroid Build Coastguard Worker " return Result;\n"
792*9880d681SAndroid Build Coastguard Worker "}\n\n";
793*9880d681SAndroid Build Coastguard Worker
794*9880d681SAndroid Build Coastguard Worker OS << "LaneBitmask " << ClName
795*9880d681SAndroid Build Coastguard Worker << "::reverseComposeSubRegIndexLaneMaskImpl(unsigned IdxA, "
796*9880d681SAndroid Build Coastguard Worker " LaneBitmask LaneMask) const {\n"
797*9880d681SAndroid Build Coastguard Worker " LaneMask &= getSubRegIndexLaneMask(IdxA);\n"
798*9880d681SAndroid Build Coastguard Worker " --IdxA; assert(IdxA < " << SubRegIndices.size()
799*9880d681SAndroid Build Coastguard Worker << " && \"Subregister index out of bounds\");\n"
800*9880d681SAndroid Build Coastguard Worker " LaneBitmask Result = 0;\n"
801*9880d681SAndroid Build Coastguard Worker " for (const MaskRolOp *Ops = CompositeSequences[IdxA]; Ops->Mask != 0; ++Ops)"
802*9880d681SAndroid Build Coastguard Worker " {\n"
803*9880d681SAndroid Build Coastguard Worker " LaneBitmask Rotated = (LaneMask >> Ops->RotateLeft) |\n"
804*9880d681SAndroid Build Coastguard Worker " ((LaneMask << ((32 - Ops->RotateLeft) & 0x1F)) & 0xFFFFFFFF);\n"
805*9880d681SAndroid Build Coastguard Worker " Result |= Rotated & Ops->Mask;\n"
806*9880d681SAndroid Build Coastguard Worker " }\n"
807*9880d681SAndroid Build Coastguard Worker " return Result;\n"
808*9880d681SAndroid Build Coastguard Worker "}\n\n";
809*9880d681SAndroid Build Coastguard Worker }
810*9880d681SAndroid Build Coastguard Worker
811*9880d681SAndroid Build Coastguard Worker //
812*9880d681SAndroid Build Coastguard Worker // runMCDesc - Print out MC register descriptions.
813*9880d681SAndroid Build Coastguard Worker //
814*9880d681SAndroid Build Coastguard Worker void
runMCDesc(raw_ostream & OS,CodeGenTarget & Target,CodeGenRegBank & RegBank)815*9880d681SAndroid Build Coastguard Worker RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
816*9880d681SAndroid Build Coastguard Worker CodeGenRegBank &RegBank) {
817*9880d681SAndroid Build Coastguard Worker emitSourceFileHeader("MC Register Information", OS);
818*9880d681SAndroid Build Coastguard Worker
819*9880d681SAndroid Build Coastguard Worker OS << "\n#ifdef GET_REGINFO_MC_DESC\n";
820*9880d681SAndroid Build Coastguard Worker OS << "#undef GET_REGINFO_MC_DESC\n\n";
821*9880d681SAndroid Build Coastguard Worker
822*9880d681SAndroid Build Coastguard Worker const auto &Regs = RegBank.getRegisters();
823*9880d681SAndroid Build Coastguard Worker
824*9880d681SAndroid Build Coastguard Worker auto &SubRegIndices = RegBank.getSubRegIndices();
825*9880d681SAndroid Build Coastguard Worker // The lists of sub-registers and super-registers go in the same array. That
826*9880d681SAndroid Build Coastguard Worker // allows us to share suffixes.
827*9880d681SAndroid Build Coastguard Worker typedef std::vector<const CodeGenRegister*> RegVec;
828*9880d681SAndroid Build Coastguard Worker
829*9880d681SAndroid Build Coastguard Worker // Differentially encoded lists.
830*9880d681SAndroid Build Coastguard Worker SequenceToOffsetTable<DiffVec> DiffSeqs;
831*9880d681SAndroid Build Coastguard Worker SmallVector<DiffVec, 4> SubRegLists(Regs.size());
832*9880d681SAndroid Build Coastguard Worker SmallVector<DiffVec, 4> SuperRegLists(Regs.size());
833*9880d681SAndroid Build Coastguard Worker SmallVector<DiffVec, 4> RegUnitLists(Regs.size());
834*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 4> RegUnitInitScale(Regs.size());
835*9880d681SAndroid Build Coastguard Worker
836*9880d681SAndroid Build Coastguard Worker // List of lane masks accompanying register unit sequences.
837*9880d681SAndroid Build Coastguard Worker SequenceToOffsetTable<MaskVec> LaneMaskSeqs;
838*9880d681SAndroid Build Coastguard Worker SmallVector<MaskVec, 4> RegUnitLaneMasks(Regs.size());
839*9880d681SAndroid Build Coastguard Worker
840*9880d681SAndroid Build Coastguard Worker // Keep track of sub-register names as well. These are not differentially
841*9880d681SAndroid Build Coastguard Worker // encoded.
842*9880d681SAndroid Build Coastguard Worker typedef SmallVector<const CodeGenSubRegIndex*, 4> SubRegIdxVec;
843*9880d681SAndroid Build Coastguard Worker SequenceToOffsetTable<SubRegIdxVec, deref<llvm::less>> SubRegIdxSeqs;
844*9880d681SAndroid Build Coastguard Worker SmallVector<SubRegIdxVec, 4> SubRegIdxLists(Regs.size());
845*9880d681SAndroid Build Coastguard Worker
846*9880d681SAndroid Build Coastguard Worker SequenceToOffsetTable<std::string> RegStrings;
847*9880d681SAndroid Build Coastguard Worker
848*9880d681SAndroid Build Coastguard Worker // Precompute register lists for the SequenceToOffsetTable.
849*9880d681SAndroid Build Coastguard Worker unsigned i = 0;
850*9880d681SAndroid Build Coastguard Worker for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I, ++i) {
851*9880d681SAndroid Build Coastguard Worker const auto &Reg = *I;
852*9880d681SAndroid Build Coastguard Worker RegStrings.add(Reg.getName());
853*9880d681SAndroid Build Coastguard Worker
854*9880d681SAndroid Build Coastguard Worker // Compute the ordered sub-register list.
855*9880d681SAndroid Build Coastguard Worker SetVector<const CodeGenRegister*> SR;
856*9880d681SAndroid Build Coastguard Worker Reg.addSubRegsPreOrder(SR, RegBank);
857*9880d681SAndroid Build Coastguard Worker diffEncode(SubRegLists[i], Reg.EnumValue, SR.begin(), SR.end());
858*9880d681SAndroid Build Coastguard Worker DiffSeqs.add(SubRegLists[i]);
859*9880d681SAndroid Build Coastguard Worker
860*9880d681SAndroid Build Coastguard Worker // Compute the corresponding sub-register indexes.
861*9880d681SAndroid Build Coastguard Worker SubRegIdxVec &SRIs = SubRegIdxLists[i];
862*9880d681SAndroid Build Coastguard Worker for (unsigned j = 0, je = SR.size(); j != je; ++j)
863*9880d681SAndroid Build Coastguard Worker SRIs.push_back(Reg.getSubRegIndex(SR[j]));
864*9880d681SAndroid Build Coastguard Worker SubRegIdxSeqs.add(SRIs);
865*9880d681SAndroid Build Coastguard Worker
866*9880d681SAndroid Build Coastguard Worker // Super-registers are already computed.
867*9880d681SAndroid Build Coastguard Worker const RegVec &SuperRegList = Reg.getSuperRegs();
868*9880d681SAndroid Build Coastguard Worker diffEncode(SuperRegLists[i], Reg.EnumValue, SuperRegList.begin(),
869*9880d681SAndroid Build Coastguard Worker SuperRegList.end());
870*9880d681SAndroid Build Coastguard Worker DiffSeqs.add(SuperRegLists[i]);
871*9880d681SAndroid Build Coastguard Worker
872*9880d681SAndroid Build Coastguard Worker // Differentially encode the register unit list, seeded by register number.
873*9880d681SAndroid Build Coastguard Worker // First compute a scale factor that allows more diff-lists to be reused:
874*9880d681SAndroid Build Coastguard Worker //
875*9880d681SAndroid Build Coastguard Worker // D0 -> (S0, S1)
876*9880d681SAndroid Build Coastguard Worker // D1 -> (S2, S3)
877*9880d681SAndroid Build Coastguard Worker //
878*9880d681SAndroid Build Coastguard Worker // A scale factor of 2 allows D0 and D1 to share a diff-list. The initial
879*9880d681SAndroid Build Coastguard Worker // value for the differential decoder is the register number multiplied by
880*9880d681SAndroid Build Coastguard Worker // the scale.
881*9880d681SAndroid Build Coastguard Worker //
882*9880d681SAndroid Build Coastguard Worker // Check the neighboring registers for arithmetic progressions.
883*9880d681SAndroid Build Coastguard Worker unsigned ScaleA = ~0u, ScaleB = ~0u;
884*9880d681SAndroid Build Coastguard Worker SparseBitVector<> RUs = Reg.getNativeRegUnits();
885*9880d681SAndroid Build Coastguard Worker if (I != Regs.begin() &&
886*9880d681SAndroid Build Coastguard Worker std::prev(I)->getNativeRegUnits().count() == RUs.count())
887*9880d681SAndroid Build Coastguard Worker ScaleB = *RUs.begin() - *std::prev(I)->getNativeRegUnits().begin();
888*9880d681SAndroid Build Coastguard Worker if (std::next(I) != Regs.end() &&
889*9880d681SAndroid Build Coastguard Worker std::next(I)->getNativeRegUnits().count() == RUs.count())
890*9880d681SAndroid Build Coastguard Worker ScaleA = *std::next(I)->getNativeRegUnits().begin() - *RUs.begin();
891*9880d681SAndroid Build Coastguard Worker unsigned Scale = std::min(ScaleB, ScaleA);
892*9880d681SAndroid Build Coastguard Worker // Default the scale to 0 if it can't be encoded in 4 bits.
893*9880d681SAndroid Build Coastguard Worker if (Scale >= 16)
894*9880d681SAndroid Build Coastguard Worker Scale = 0;
895*9880d681SAndroid Build Coastguard Worker RegUnitInitScale[i] = Scale;
896*9880d681SAndroid Build Coastguard Worker DiffSeqs.add(diffEncode(RegUnitLists[i], Scale * Reg.EnumValue, RUs));
897*9880d681SAndroid Build Coastguard Worker
898*9880d681SAndroid Build Coastguard Worker const auto &RUMasks = Reg.getRegUnitLaneMasks();
899*9880d681SAndroid Build Coastguard Worker MaskVec &LaneMaskVec = RegUnitLaneMasks[i];
900*9880d681SAndroid Build Coastguard Worker assert(LaneMaskVec.empty());
901*9880d681SAndroid Build Coastguard Worker LaneMaskVec.insert(LaneMaskVec.begin(), RUMasks.begin(), RUMasks.end());
902*9880d681SAndroid Build Coastguard Worker // Terminator mask should not be used inside of the list.
903*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
904*9880d681SAndroid Build Coastguard Worker for (unsigned M : LaneMaskVec) {
905*9880d681SAndroid Build Coastguard Worker assert(M != ~0u && "terminator mask should not be part of the list");
906*9880d681SAndroid Build Coastguard Worker }
907*9880d681SAndroid Build Coastguard Worker #endif
908*9880d681SAndroid Build Coastguard Worker LaneMaskSeqs.add(LaneMaskVec);
909*9880d681SAndroid Build Coastguard Worker }
910*9880d681SAndroid Build Coastguard Worker
911*9880d681SAndroid Build Coastguard Worker // Compute the final layout of the sequence table.
912*9880d681SAndroid Build Coastguard Worker DiffSeqs.layout();
913*9880d681SAndroid Build Coastguard Worker LaneMaskSeqs.layout();
914*9880d681SAndroid Build Coastguard Worker SubRegIdxSeqs.layout();
915*9880d681SAndroid Build Coastguard Worker
916*9880d681SAndroid Build Coastguard Worker OS << "namespace llvm {\n\n";
917*9880d681SAndroid Build Coastguard Worker
918*9880d681SAndroid Build Coastguard Worker const std::string &TargetName = Target.getName();
919*9880d681SAndroid Build Coastguard Worker
920*9880d681SAndroid Build Coastguard Worker // Emit the shared table of differential lists.
921*9880d681SAndroid Build Coastguard Worker OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[] = {\n";
922*9880d681SAndroid Build Coastguard Worker DiffSeqs.emit(OS, printDiff16);
923*9880d681SAndroid Build Coastguard Worker OS << "};\n\n";
924*9880d681SAndroid Build Coastguard Worker
925*9880d681SAndroid Build Coastguard Worker // Emit the shared table of regunit lane mask sequences.
926*9880d681SAndroid Build Coastguard Worker OS << "extern const unsigned " << TargetName << "LaneMaskLists[] = {\n";
927*9880d681SAndroid Build Coastguard Worker LaneMaskSeqs.emit(OS, printMask, "~0u");
928*9880d681SAndroid Build Coastguard Worker OS << "};\n\n";
929*9880d681SAndroid Build Coastguard Worker
930*9880d681SAndroid Build Coastguard Worker // Emit the table of sub-register indexes.
931*9880d681SAndroid Build Coastguard Worker OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n";
932*9880d681SAndroid Build Coastguard Worker SubRegIdxSeqs.emit(OS, printSubRegIndex);
933*9880d681SAndroid Build Coastguard Worker OS << "};\n\n";
934*9880d681SAndroid Build Coastguard Worker
935*9880d681SAndroid Build Coastguard Worker // Emit the table of sub-register index sizes.
936*9880d681SAndroid Build Coastguard Worker OS << "extern const MCRegisterInfo::SubRegCoveredBits "
937*9880d681SAndroid Build Coastguard Worker << TargetName << "SubRegIdxRanges[] = {\n";
938*9880d681SAndroid Build Coastguard Worker OS << " { " << (uint16_t)-1 << ", " << (uint16_t)-1 << " },\n";
939*9880d681SAndroid Build Coastguard Worker for (const auto &Idx : SubRegIndices) {
940*9880d681SAndroid Build Coastguard Worker OS << " { " << Idx.Offset << ", " << Idx.Size << " },\t// "
941*9880d681SAndroid Build Coastguard Worker << Idx.getName() << "\n";
942*9880d681SAndroid Build Coastguard Worker }
943*9880d681SAndroid Build Coastguard Worker OS << "};\n\n";
944*9880d681SAndroid Build Coastguard Worker
945*9880d681SAndroid Build Coastguard Worker // Emit the string table.
946*9880d681SAndroid Build Coastguard Worker RegStrings.layout();
947*9880d681SAndroid Build Coastguard Worker OS << "extern const char " << TargetName << "RegStrings[] = {\n";
948*9880d681SAndroid Build Coastguard Worker RegStrings.emit(OS, printChar);
949*9880d681SAndroid Build Coastguard Worker OS << "};\n\n";
950*9880d681SAndroid Build Coastguard Worker
951*9880d681SAndroid Build Coastguard Worker OS << "extern const MCRegisterDesc " << TargetName
952*9880d681SAndroid Build Coastguard Worker << "RegDesc[] = { // Descriptors\n";
953*9880d681SAndroid Build Coastguard Worker OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0, 0 },\n";
954*9880d681SAndroid Build Coastguard Worker
955*9880d681SAndroid Build Coastguard Worker // Emit the register descriptors now.
956*9880d681SAndroid Build Coastguard Worker i = 0;
957*9880d681SAndroid Build Coastguard Worker for (const auto &Reg : Regs) {
958*9880d681SAndroid Build Coastguard Worker OS << " { " << RegStrings.get(Reg.getName()) << ", "
959*9880d681SAndroid Build Coastguard Worker << DiffSeqs.get(SubRegLists[i]) << ", " << DiffSeqs.get(SuperRegLists[i])
960*9880d681SAndroid Build Coastguard Worker << ", " << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", "
961*9880d681SAndroid Build Coastguard Worker << (DiffSeqs.get(RegUnitLists[i]) * 16 + RegUnitInitScale[i]) << ", "
962*9880d681SAndroid Build Coastguard Worker << LaneMaskSeqs.get(RegUnitLaneMasks[i]) << " },\n";
963*9880d681SAndroid Build Coastguard Worker ++i;
964*9880d681SAndroid Build Coastguard Worker }
965*9880d681SAndroid Build Coastguard Worker OS << "};\n\n"; // End of register descriptors...
966*9880d681SAndroid Build Coastguard Worker
967*9880d681SAndroid Build Coastguard Worker // Emit the table of register unit roots. Each regunit has one or two root
968*9880d681SAndroid Build Coastguard Worker // registers.
969*9880d681SAndroid Build Coastguard Worker OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2] = {\n";
970*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = RegBank.getNumNativeRegUnits(); i != e; ++i) {
971*9880d681SAndroid Build Coastguard Worker ArrayRef<const CodeGenRegister*> Roots = RegBank.getRegUnit(i).getRoots();
972*9880d681SAndroid Build Coastguard Worker assert(!Roots.empty() && "All regunits must have a root register.");
973*9880d681SAndroid Build Coastguard Worker assert(Roots.size() <= 2 && "More than two roots not supported yet.");
974*9880d681SAndroid Build Coastguard Worker OS << " { " << getQualifiedName(Roots.front()->TheDef);
975*9880d681SAndroid Build Coastguard Worker for (unsigned r = 1; r != Roots.size(); ++r)
976*9880d681SAndroid Build Coastguard Worker OS << ", " << getQualifiedName(Roots[r]->TheDef);
977*9880d681SAndroid Build Coastguard Worker OS << " },\n";
978*9880d681SAndroid Build Coastguard Worker }
979*9880d681SAndroid Build Coastguard Worker OS << "};\n\n";
980*9880d681SAndroid Build Coastguard Worker
981*9880d681SAndroid Build Coastguard Worker const auto &RegisterClasses = RegBank.getRegClasses();
982*9880d681SAndroid Build Coastguard Worker
983*9880d681SAndroid Build Coastguard Worker // Loop over all of the register classes... emitting each one.
984*9880d681SAndroid Build Coastguard Worker OS << "namespace { // Register classes...\n";
985*9880d681SAndroid Build Coastguard Worker
986*9880d681SAndroid Build Coastguard Worker SequenceToOffsetTable<std::string> RegClassStrings;
987*9880d681SAndroid Build Coastguard Worker
988*9880d681SAndroid Build Coastguard Worker // Emit the register enum value arrays for each RegisterClass
989*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegisterClasses) {
990*9880d681SAndroid Build Coastguard Worker ArrayRef<Record*> Order = RC.getOrder();
991*9880d681SAndroid Build Coastguard Worker
992*9880d681SAndroid Build Coastguard Worker // Give the register class a legal C name if it's anonymous.
993*9880d681SAndroid Build Coastguard Worker const std::string &Name = RC.getName();
994*9880d681SAndroid Build Coastguard Worker
995*9880d681SAndroid Build Coastguard Worker RegClassStrings.add(Name);
996*9880d681SAndroid Build Coastguard Worker
997*9880d681SAndroid Build Coastguard Worker // Emit the register list now.
998*9880d681SAndroid Build Coastguard Worker OS << " // " << Name << " Register Class...\n"
999*9880d681SAndroid Build Coastguard Worker << " const MCPhysReg " << Name
1000*9880d681SAndroid Build Coastguard Worker << "[] = {\n ";
1001*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Order.size(); i != e; ++i) {
1002*9880d681SAndroid Build Coastguard Worker Record *Reg = Order[i];
1003*9880d681SAndroid Build Coastguard Worker OS << getQualifiedName(Reg) << ", ";
1004*9880d681SAndroid Build Coastguard Worker }
1005*9880d681SAndroid Build Coastguard Worker OS << "\n };\n\n";
1006*9880d681SAndroid Build Coastguard Worker
1007*9880d681SAndroid Build Coastguard Worker OS << " // " << Name << " Bit set.\n"
1008*9880d681SAndroid Build Coastguard Worker << " const uint8_t " << Name
1009*9880d681SAndroid Build Coastguard Worker << "Bits[] = {\n ";
1010*9880d681SAndroid Build Coastguard Worker BitVectorEmitter BVE;
1011*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Order.size(); i != e; ++i) {
1012*9880d681SAndroid Build Coastguard Worker Record *Reg = Order[i];
1013*9880d681SAndroid Build Coastguard Worker BVE.add(Target.getRegBank().getReg(Reg)->EnumValue);
1014*9880d681SAndroid Build Coastguard Worker }
1015*9880d681SAndroid Build Coastguard Worker BVE.print(OS);
1016*9880d681SAndroid Build Coastguard Worker OS << "\n };\n\n";
1017*9880d681SAndroid Build Coastguard Worker
1018*9880d681SAndroid Build Coastguard Worker }
1019*9880d681SAndroid Build Coastguard Worker OS << "} // end anonymous namespace\n\n";
1020*9880d681SAndroid Build Coastguard Worker
1021*9880d681SAndroid Build Coastguard Worker RegClassStrings.layout();
1022*9880d681SAndroid Build Coastguard Worker OS << "extern const char " << TargetName << "RegClassStrings[] = {\n";
1023*9880d681SAndroid Build Coastguard Worker RegClassStrings.emit(OS, printChar);
1024*9880d681SAndroid Build Coastguard Worker OS << "};\n\n";
1025*9880d681SAndroid Build Coastguard Worker
1026*9880d681SAndroid Build Coastguard Worker OS << "extern const MCRegisterClass " << TargetName
1027*9880d681SAndroid Build Coastguard Worker << "MCRegisterClasses[] = {\n";
1028*9880d681SAndroid Build Coastguard Worker
1029*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegisterClasses) {
1030*9880d681SAndroid Build Coastguard Worker // Asserts to make sure values will fit in table assuming types from
1031*9880d681SAndroid Build Coastguard Worker // MCRegisterInfo.h
1032*9880d681SAndroid Build Coastguard Worker assert((RC.SpillSize/8) <= 0xffff && "SpillSize too large.");
1033*9880d681SAndroid Build Coastguard Worker assert((RC.SpillAlignment/8) <= 0xffff && "SpillAlignment too large.");
1034*9880d681SAndroid Build Coastguard Worker assert(RC.CopyCost >= -128 && RC.CopyCost <= 127 && "Copy cost too large.");
1035*9880d681SAndroid Build Coastguard Worker
1036*9880d681SAndroid Build Coastguard Worker OS << " { " << RC.getName() << ", " << RC.getName() << "Bits, "
1037*9880d681SAndroid Build Coastguard Worker << RegClassStrings.get(RC.getName()) << ", "
1038*9880d681SAndroid Build Coastguard Worker << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), "
1039*9880d681SAndroid Build Coastguard Worker << RC.getQualifiedName() + "RegClassID" << ", "
1040*9880d681SAndroid Build Coastguard Worker << RC.SpillSize/8 << ", "
1041*9880d681SAndroid Build Coastguard Worker << RC.SpillAlignment/8 << ", "
1042*9880d681SAndroid Build Coastguard Worker << RC.CopyCost << ", "
1043*9880d681SAndroid Build Coastguard Worker << ( RC.Allocatable ? "true" : "false" ) << " },\n";
1044*9880d681SAndroid Build Coastguard Worker }
1045*9880d681SAndroid Build Coastguard Worker
1046*9880d681SAndroid Build Coastguard Worker OS << "};\n\n";
1047*9880d681SAndroid Build Coastguard Worker
1048*9880d681SAndroid Build Coastguard Worker EmitRegMappingTables(OS, Regs, false);
1049*9880d681SAndroid Build Coastguard Worker
1050*9880d681SAndroid Build Coastguard Worker // Emit Reg encoding table
1051*9880d681SAndroid Build Coastguard Worker OS << "extern const uint16_t " << TargetName;
1052*9880d681SAndroid Build Coastguard Worker OS << "RegEncodingTable[] = {\n";
1053*9880d681SAndroid Build Coastguard Worker // Add entry for NoRegister
1054*9880d681SAndroid Build Coastguard Worker OS << " 0,\n";
1055*9880d681SAndroid Build Coastguard Worker for (const auto &RE : Regs) {
1056*9880d681SAndroid Build Coastguard Worker Record *Reg = RE.TheDef;
1057*9880d681SAndroid Build Coastguard Worker BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
1058*9880d681SAndroid Build Coastguard Worker uint64_t Value = 0;
1059*9880d681SAndroid Build Coastguard Worker for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
1060*9880d681SAndroid Build Coastguard Worker if (BitInit *B = dyn_cast<BitInit>(BI->getBit(b)))
1061*9880d681SAndroid Build Coastguard Worker Value |= (uint64_t)B->getValue() << b;
1062*9880d681SAndroid Build Coastguard Worker }
1063*9880d681SAndroid Build Coastguard Worker OS << " " << Value << ",\n";
1064*9880d681SAndroid Build Coastguard Worker }
1065*9880d681SAndroid Build Coastguard Worker OS << "};\n"; // End of HW encoding table
1066*9880d681SAndroid Build Coastguard Worker
1067*9880d681SAndroid Build Coastguard Worker // MCRegisterInfo initialization routine.
1068*9880d681SAndroid Build Coastguard Worker OS << "static inline void Init" << TargetName
1069*9880d681SAndroid Build Coastguard Worker << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
1070*9880d681SAndroid Build Coastguard Worker << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0, unsigned PC = 0) "
1071*9880d681SAndroid Build Coastguard Worker "{\n"
1072*9880d681SAndroid Build Coastguard Worker << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
1073*9880d681SAndroid Build Coastguard Worker << Regs.size() + 1 << ", RA, PC, " << TargetName << "MCRegisterClasses, "
1074*9880d681SAndroid Build Coastguard Worker << RegisterClasses.size() << ", " << TargetName << "RegUnitRoots, "
1075*9880d681SAndroid Build Coastguard Worker << RegBank.getNumNativeRegUnits() << ", " << TargetName << "RegDiffLists, "
1076*9880d681SAndroid Build Coastguard Worker << TargetName << "LaneMaskLists, " << TargetName << "RegStrings, "
1077*9880d681SAndroid Build Coastguard Worker << TargetName << "RegClassStrings, " << TargetName << "SubRegIdxLists, "
1078*9880d681SAndroid Build Coastguard Worker << (std::distance(SubRegIndices.begin(), SubRegIndices.end()) + 1) << ",\n"
1079*9880d681SAndroid Build Coastguard Worker << TargetName << "SubRegIdxRanges, " << TargetName
1080*9880d681SAndroid Build Coastguard Worker << "RegEncodingTable);\n\n";
1081*9880d681SAndroid Build Coastguard Worker
1082*9880d681SAndroid Build Coastguard Worker EmitRegMapping(OS, Regs, false);
1083*9880d681SAndroid Build Coastguard Worker
1084*9880d681SAndroid Build Coastguard Worker OS << "}\n\n";
1085*9880d681SAndroid Build Coastguard Worker
1086*9880d681SAndroid Build Coastguard Worker OS << "} // end namespace llvm\n\n";
1087*9880d681SAndroid Build Coastguard Worker OS << "#endif // GET_REGINFO_MC_DESC\n\n";
1088*9880d681SAndroid Build Coastguard Worker }
1089*9880d681SAndroid Build Coastguard Worker
1090*9880d681SAndroid Build Coastguard Worker void
runTargetHeader(raw_ostream & OS,CodeGenTarget & Target,CodeGenRegBank & RegBank)1091*9880d681SAndroid Build Coastguard Worker RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
1092*9880d681SAndroid Build Coastguard Worker CodeGenRegBank &RegBank) {
1093*9880d681SAndroid Build Coastguard Worker emitSourceFileHeader("Register Information Header Fragment", OS);
1094*9880d681SAndroid Build Coastguard Worker
1095*9880d681SAndroid Build Coastguard Worker OS << "\n#ifdef GET_REGINFO_HEADER\n";
1096*9880d681SAndroid Build Coastguard Worker OS << "#undef GET_REGINFO_HEADER\n\n";
1097*9880d681SAndroid Build Coastguard Worker
1098*9880d681SAndroid Build Coastguard Worker const std::string &TargetName = Target.getName();
1099*9880d681SAndroid Build Coastguard Worker std::string ClassName = TargetName + "GenRegisterInfo";
1100*9880d681SAndroid Build Coastguard Worker
1101*9880d681SAndroid Build Coastguard Worker OS << "#include \"llvm/Target/TargetRegisterInfo.h\"\n\n";
1102*9880d681SAndroid Build Coastguard Worker
1103*9880d681SAndroid Build Coastguard Worker OS << "namespace llvm {\n\n";
1104*9880d681SAndroid Build Coastguard Worker
1105*9880d681SAndroid Build Coastguard Worker OS << "class " << TargetName << "FrameLowering;\n\n";
1106*9880d681SAndroid Build Coastguard Worker
1107*9880d681SAndroid Build Coastguard Worker OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
1108*9880d681SAndroid Build Coastguard Worker << " explicit " << ClassName
1109*9880d681SAndroid Build Coastguard Worker << "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n";
1110*9880d681SAndroid Build Coastguard Worker if (!RegBank.getSubRegIndices().empty()) {
1111*9880d681SAndroid Build Coastguard Worker OS << " unsigned composeSubRegIndicesImpl"
1112*9880d681SAndroid Build Coastguard Worker << "(unsigned, unsigned) const override;\n"
1113*9880d681SAndroid Build Coastguard Worker << " LaneBitmask composeSubRegIndexLaneMaskImpl"
1114*9880d681SAndroid Build Coastguard Worker << "(unsigned, LaneBitmask) const override;\n"
1115*9880d681SAndroid Build Coastguard Worker << " LaneBitmask reverseComposeSubRegIndexLaneMaskImpl"
1116*9880d681SAndroid Build Coastguard Worker << "(unsigned, LaneBitmask) const override;\n"
1117*9880d681SAndroid Build Coastguard Worker << " const TargetRegisterClass *getSubClassWithSubReg"
1118*9880d681SAndroid Build Coastguard Worker << "(const TargetRegisterClass*, unsigned) const override;\n";
1119*9880d681SAndroid Build Coastguard Worker }
1120*9880d681SAndroid Build Coastguard Worker OS << " const RegClassWeight &getRegClassWeight("
1121*9880d681SAndroid Build Coastguard Worker << "const TargetRegisterClass *RC) const override;\n"
1122*9880d681SAndroid Build Coastguard Worker << " unsigned getRegUnitWeight(unsigned RegUnit) const override;\n"
1123*9880d681SAndroid Build Coastguard Worker << " unsigned getNumRegPressureSets() const override;\n"
1124*9880d681SAndroid Build Coastguard Worker << " const char *getRegPressureSetName(unsigned Idx) const override;\n"
1125*9880d681SAndroid Build Coastguard Worker << " unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned "
1126*9880d681SAndroid Build Coastguard Worker "Idx) const override;\n"
1127*9880d681SAndroid Build Coastguard Worker << " const int *getRegClassPressureSets("
1128*9880d681SAndroid Build Coastguard Worker << "const TargetRegisterClass *RC) const override;\n"
1129*9880d681SAndroid Build Coastguard Worker << " const int *getRegUnitPressureSets("
1130*9880d681SAndroid Build Coastguard Worker << "unsigned RegUnit) const override;\n"
1131*9880d681SAndroid Build Coastguard Worker << " ArrayRef<const char *> getRegMaskNames() const override;\n"
1132*9880d681SAndroid Build Coastguard Worker << " ArrayRef<const uint32_t *> getRegMasks() const override;\n"
1133*9880d681SAndroid Build Coastguard Worker << " /// Devirtualized TargetFrameLowering.\n"
1134*9880d681SAndroid Build Coastguard Worker << " static const " << TargetName << "FrameLowering *getFrameLowering(\n"
1135*9880d681SAndroid Build Coastguard Worker << " const MachineFunction &MF);\n"
1136*9880d681SAndroid Build Coastguard Worker << "};\n\n";
1137*9880d681SAndroid Build Coastguard Worker
1138*9880d681SAndroid Build Coastguard Worker const auto &RegisterClasses = RegBank.getRegClasses();
1139*9880d681SAndroid Build Coastguard Worker
1140*9880d681SAndroid Build Coastguard Worker if (!RegisterClasses.empty()) {
1141*9880d681SAndroid Build Coastguard Worker OS << "namespace " << RegisterClasses.front().Namespace
1142*9880d681SAndroid Build Coastguard Worker << " { // Register classes\n";
1143*9880d681SAndroid Build Coastguard Worker
1144*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegisterClasses) {
1145*9880d681SAndroid Build Coastguard Worker const std::string &Name = RC.getName();
1146*9880d681SAndroid Build Coastguard Worker
1147*9880d681SAndroid Build Coastguard Worker // Output the extern for the instance.
1148*9880d681SAndroid Build Coastguard Worker OS << " extern const TargetRegisterClass " << Name << "RegClass;\n";
1149*9880d681SAndroid Build Coastguard Worker }
1150*9880d681SAndroid Build Coastguard Worker OS << "} // end namespace " << RegisterClasses.front().Namespace << "\n\n";
1151*9880d681SAndroid Build Coastguard Worker }
1152*9880d681SAndroid Build Coastguard Worker OS << "} // end namespace llvm\n\n";
1153*9880d681SAndroid Build Coastguard Worker OS << "#endif // GET_REGINFO_HEADER\n\n";
1154*9880d681SAndroid Build Coastguard Worker }
1155*9880d681SAndroid Build Coastguard Worker
1156*9880d681SAndroid Build Coastguard Worker //
1157*9880d681SAndroid Build Coastguard Worker // runTargetDesc - Output the target register and register file descriptions.
1158*9880d681SAndroid Build Coastguard Worker //
1159*9880d681SAndroid Build Coastguard Worker void
runTargetDesc(raw_ostream & OS,CodeGenTarget & Target,CodeGenRegBank & RegBank)1160*9880d681SAndroid Build Coastguard Worker RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
1161*9880d681SAndroid Build Coastguard Worker CodeGenRegBank &RegBank){
1162*9880d681SAndroid Build Coastguard Worker emitSourceFileHeader("Target Register and Register Classes Information", OS);
1163*9880d681SAndroid Build Coastguard Worker
1164*9880d681SAndroid Build Coastguard Worker OS << "\n#ifdef GET_REGINFO_TARGET_DESC\n";
1165*9880d681SAndroid Build Coastguard Worker OS << "#undef GET_REGINFO_TARGET_DESC\n\n";
1166*9880d681SAndroid Build Coastguard Worker
1167*9880d681SAndroid Build Coastguard Worker OS << "namespace llvm {\n\n";
1168*9880d681SAndroid Build Coastguard Worker
1169*9880d681SAndroid Build Coastguard Worker // Get access to MCRegisterClass data.
1170*9880d681SAndroid Build Coastguard Worker OS << "extern const MCRegisterClass " << Target.getName()
1171*9880d681SAndroid Build Coastguard Worker << "MCRegisterClasses[];\n";
1172*9880d681SAndroid Build Coastguard Worker
1173*9880d681SAndroid Build Coastguard Worker // Start out by emitting each of the register classes.
1174*9880d681SAndroid Build Coastguard Worker const auto &RegisterClasses = RegBank.getRegClasses();
1175*9880d681SAndroid Build Coastguard Worker const auto &SubRegIndices = RegBank.getSubRegIndices();
1176*9880d681SAndroid Build Coastguard Worker
1177*9880d681SAndroid Build Coastguard Worker // Collect all registers belonging to any allocatable class.
1178*9880d681SAndroid Build Coastguard Worker std::set<Record*> AllocatableRegs;
1179*9880d681SAndroid Build Coastguard Worker
1180*9880d681SAndroid Build Coastguard Worker // Collect allocatable registers.
1181*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegisterClasses) {
1182*9880d681SAndroid Build Coastguard Worker ArrayRef<Record*> Order = RC.getOrder();
1183*9880d681SAndroid Build Coastguard Worker
1184*9880d681SAndroid Build Coastguard Worker if (RC.Allocatable)
1185*9880d681SAndroid Build Coastguard Worker AllocatableRegs.insert(Order.begin(), Order.end());
1186*9880d681SAndroid Build Coastguard Worker }
1187*9880d681SAndroid Build Coastguard Worker
1188*9880d681SAndroid Build Coastguard Worker // Build a shared array of value types.
1189*9880d681SAndroid Build Coastguard Worker SequenceToOffsetTable<SmallVector<MVT::SimpleValueType, 4> > VTSeqs;
1190*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegisterClasses)
1191*9880d681SAndroid Build Coastguard Worker VTSeqs.add(RC.VTs);
1192*9880d681SAndroid Build Coastguard Worker VTSeqs.layout();
1193*9880d681SAndroid Build Coastguard Worker OS << "\nstatic const MVT::SimpleValueType VTLists[] = {\n";
1194*9880d681SAndroid Build Coastguard Worker VTSeqs.emit(OS, printSimpleValueType, "MVT::Other");
1195*9880d681SAndroid Build Coastguard Worker OS << "};\n";
1196*9880d681SAndroid Build Coastguard Worker
1197*9880d681SAndroid Build Coastguard Worker // Emit SubRegIndex names, skipping 0.
1198*9880d681SAndroid Build Coastguard Worker OS << "\nstatic const char *const SubRegIndexNameTable[] = { \"";
1199*9880d681SAndroid Build Coastguard Worker
1200*9880d681SAndroid Build Coastguard Worker for (const auto &Idx : SubRegIndices) {
1201*9880d681SAndroid Build Coastguard Worker OS << Idx.getName();
1202*9880d681SAndroid Build Coastguard Worker OS << "\", \"";
1203*9880d681SAndroid Build Coastguard Worker }
1204*9880d681SAndroid Build Coastguard Worker OS << "\" };\n\n";
1205*9880d681SAndroid Build Coastguard Worker
1206*9880d681SAndroid Build Coastguard Worker // Emit SubRegIndex lane masks, including 0.
1207*9880d681SAndroid Build Coastguard Worker OS << "\nstatic const unsigned SubRegIndexLaneMaskTable[] = {\n ~0u,\n";
1208*9880d681SAndroid Build Coastguard Worker for (const auto &Idx : SubRegIndices) {
1209*9880d681SAndroid Build Coastguard Worker OS << format(" 0x%08x, // ", Idx.LaneMask) << Idx.getName() << '\n';
1210*9880d681SAndroid Build Coastguard Worker }
1211*9880d681SAndroid Build Coastguard Worker OS << " };\n\n";
1212*9880d681SAndroid Build Coastguard Worker
1213*9880d681SAndroid Build Coastguard Worker OS << "\n";
1214*9880d681SAndroid Build Coastguard Worker
1215*9880d681SAndroid Build Coastguard Worker // Now that all of the structs have been emitted, emit the instances.
1216*9880d681SAndroid Build Coastguard Worker if (!RegisterClasses.empty()) {
1217*9880d681SAndroid Build Coastguard Worker OS << "\nstatic const TargetRegisterClass *const "
1218*9880d681SAndroid Build Coastguard Worker << "NullRegClasses[] = { nullptr };\n\n";
1219*9880d681SAndroid Build Coastguard Worker
1220*9880d681SAndroid Build Coastguard Worker // Emit register class bit mask tables. The first bit mask emitted for a
1221*9880d681SAndroid Build Coastguard Worker // register class, RC, is the set of sub-classes, including RC itself.
1222*9880d681SAndroid Build Coastguard Worker //
1223*9880d681SAndroid Build Coastguard Worker // If RC has super-registers, also create a list of subreg indices and bit
1224*9880d681SAndroid Build Coastguard Worker // masks, (Idx, Mask). The bit mask has a bit for every superreg regclass,
1225*9880d681SAndroid Build Coastguard Worker // SuperRC, that satisfies:
1226*9880d681SAndroid Build Coastguard Worker //
1227*9880d681SAndroid Build Coastguard Worker // For all SuperReg in SuperRC: SuperReg:Idx in RC
1228*9880d681SAndroid Build Coastguard Worker //
1229*9880d681SAndroid Build Coastguard Worker // The 0-terminated list of subreg indices starts at:
1230*9880d681SAndroid Build Coastguard Worker //
1231*9880d681SAndroid Build Coastguard Worker // RC->getSuperRegIndices() = SuperRegIdxSeqs + ...
1232*9880d681SAndroid Build Coastguard Worker //
1233*9880d681SAndroid Build Coastguard Worker // The corresponding bitmasks follow the sub-class mask in memory. Each
1234*9880d681SAndroid Build Coastguard Worker // mask has RCMaskWords uint32_t entries.
1235*9880d681SAndroid Build Coastguard Worker //
1236*9880d681SAndroid Build Coastguard Worker // Every bit mask present in the list has at least one bit set.
1237*9880d681SAndroid Build Coastguard Worker
1238*9880d681SAndroid Build Coastguard Worker // Compress the sub-reg index lists.
1239*9880d681SAndroid Build Coastguard Worker typedef std::vector<const CodeGenSubRegIndex*> IdxList;
1240*9880d681SAndroid Build Coastguard Worker SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());
1241*9880d681SAndroid Build Coastguard Worker SequenceToOffsetTable<IdxList, deref<llvm::less>> SuperRegIdxSeqs;
1242*9880d681SAndroid Build Coastguard Worker BitVector MaskBV(RegisterClasses.size());
1243*9880d681SAndroid Build Coastguard Worker
1244*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegisterClasses) {
1245*9880d681SAndroid Build Coastguard Worker OS << "static const uint32_t " << RC.getName() << "SubClassMask[] = {\n ";
1246*9880d681SAndroid Build Coastguard Worker printBitVectorAsHex(OS, RC.getSubClasses(), 32);
1247*9880d681SAndroid Build Coastguard Worker
1248*9880d681SAndroid Build Coastguard Worker // Emit super-reg class masks for any relevant SubRegIndices that can
1249*9880d681SAndroid Build Coastguard Worker // project into RC.
1250*9880d681SAndroid Build Coastguard Worker IdxList &SRIList = SuperRegIdxLists[RC.EnumValue];
1251*9880d681SAndroid Build Coastguard Worker for (auto &Idx : SubRegIndices) {
1252*9880d681SAndroid Build Coastguard Worker MaskBV.reset();
1253*9880d681SAndroid Build Coastguard Worker RC.getSuperRegClasses(&Idx, MaskBV);
1254*9880d681SAndroid Build Coastguard Worker if (MaskBV.none())
1255*9880d681SAndroid Build Coastguard Worker continue;
1256*9880d681SAndroid Build Coastguard Worker SRIList.push_back(&Idx);
1257*9880d681SAndroid Build Coastguard Worker OS << "\n ";
1258*9880d681SAndroid Build Coastguard Worker printBitVectorAsHex(OS, MaskBV, 32);
1259*9880d681SAndroid Build Coastguard Worker OS << "// " << Idx.getName();
1260*9880d681SAndroid Build Coastguard Worker }
1261*9880d681SAndroid Build Coastguard Worker SuperRegIdxSeqs.add(SRIList);
1262*9880d681SAndroid Build Coastguard Worker OS << "\n};\n\n";
1263*9880d681SAndroid Build Coastguard Worker }
1264*9880d681SAndroid Build Coastguard Worker
1265*9880d681SAndroid Build Coastguard Worker OS << "static const uint16_t SuperRegIdxSeqs[] = {\n";
1266*9880d681SAndroid Build Coastguard Worker SuperRegIdxSeqs.layout();
1267*9880d681SAndroid Build Coastguard Worker SuperRegIdxSeqs.emit(OS, printSubRegIndex);
1268*9880d681SAndroid Build Coastguard Worker OS << "};\n\n";
1269*9880d681SAndroid Build Coastguard Worker
1270*9880d681SAndroid Build Coastguard Worker // Emit NULL terminated super-class lists.
1271*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegisterClasses) {
1272*9880d681SAndroid Build Coastguard Worker ArrayRef<CodeGenRegisterClass*> Supers = RC.getSuperClasses();
1273*9880d681SAndroid Build Coastguard Worker
1274*9880d681SAndroid Build Coastguard Worker // Skip classes without supers. We can reuse NullRegClasses.
1275*9880d681SAndroid Build Coastguard Worker if (Supers.empty())
1276*9880d681SAndroid Build Coastguard Worker continue;
1277*9880d681SAndroid Build Coastguard Worker
1278*9880d681SAndroid Build Coastguard Worker OS << "static const TargetRegisterClass *const "
1279*9880d681SAndroid Build Coastguard Worker << RC.getName() << "Superclasses[] = {\n";
1280*9880d681SAndroid Build Coastguard Worker for (const auto *Super : Supers)
1281*9880d681SAndroid Build Coastguard Worker OS << " &" << Super->getQualifiedName() << "RegClass,\n";
1282*9880d681SAndroid Build Coastguard Worker OS << " nullptr\n};\n\n";
1283*9880d681SAndroid Build Coastguard Worker }
1284*9880d681SAndroid Build Coastguard Worker
1285*9880d681SAndroid Build Coastguard Worker // Emit methods.
1286*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegisterClasses) {
1287*9880d681SAndroid Build Coastguard Worker if (!RC.AltOrderSelect.empty()) {
1288*9880d681SAndroid Build Coastguard Worker OS << "\nstatic inline unsigned " << RC.getName()
1289*9880d681SAndroid Build Coastguard Worker << "AltOrderSelect(const MachineFunction &MF) {"
1290*9880d681SAndroid Build Coastguard Worker << RC.AltOrderSelect << "}\n\n"
1291*9880d681SAndroid Build Coastguard Worker << "static ArrayRef<MCPhysReg> " << RC.getName()
1292*9880d681SAndroid Build Coastguard Worker << "GetRawAllocationOrder(const MachineFunction &MF) {\n";
1293*9880d681SAndroid Build Coastguard Worker for (unsigned oi = 1 , oe = RC.getNumOrders(); oi != oe; ++oi) {
1294*9880d681SAndroid Build Coastguard Worker ArrayRef<Record*> Elems = RC.getOrder(oi);
1295*9880d681SAndroid Build Coastguard Worker if (!Elems.empty()) {
1296*9880d681SAndroid Build Coastguard Worker OS << " static const MCPhysReg AltOrder" << oi << "[] = {";
1297*9880d681SAndroid Build Coastguard Worker for (unsigned elem = 0; elem != Elems.size(); ++elem)
1298*9880d681SAndroid Build Coastguard Worker OS << (elem ? ", " : " ") << getQualifiedName(Elems[elem]);
1299*9880d681SAndroid Build Coastguard Worker OS << " };\n";
1300*9880d681SAndroid Build Coastguard Worker }
1301*9880d681SAndroid Build Coastguard Worker }
1302*9880d681SAndroid Build Coastguard Worker OS << " const MCRegisterClass &MCR = " << Target.getName()
1303*9880d681SAndroid Build Coastguard Worker << "MCRegisterClasses[" << RC.getQualifiedName() + "RegClassID];\n"
1304*9880d681SAndroid Build Coastguard Worker << " const ArrayRef<MCPhysReg> Order[] = {\n"
1305*9880d681SAndroid Build Coastguard Worker << " makeArrayRef(MCR.begin(), MCR.getNumRegs()";
1306*9880d681SAndroid Build Coastguard Worker for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi)
1307*9880d681SAndroid Build Coastguard Worker if (RC.getOrder(oi).empty())
1308*9880d681SAndroid Build Coastguard Worker OS << "),\n ArrayRef<MCPhysReg>(";
1309*9880d681SAndroid Build Coastguard Worker else
1310*9880d681SAndroid Build Coastguard Worker OS << "),\n makeArrayRef(AltOrder" << oi;
1311*9880d681SAndroid Build Coastguard Worker OS << ")\n };\n const unsigned Select = " << RC.getName()
1312*9880d681SAndroid Build Coastguard Worker << "AltOrderSelect(MF);\n assert(Select < " << RC.getNumOrders()
1313*9880d681SAndroid Build Coastguard Worker << ");\n return Order[Select];\n}\n";
1314*9880d681SAndroid Build Coastguard Worker }
1315*9880d681SAndroid Build Coastguard Worker }
1316*9880d681SAndroid Build Coastguard Worker
1317*9880d681SAndroid Build Coastguard Worker // Now emit the actual value-initialized register class instances.
1318*9880d681SAndroid Build Coastguard Worker OS << "\nnamespace " << RegisterClasses.front().Namespace
1319*9880d681SAndroid Build Coastguard Worker << " { // Register class instances\n";
1320*9880d681SAndroid Build Coastguard Worker
1321*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegisterClasses) {
1322*9880d681SAndroid Build Coastguard Worker OS << " extern const TargetRegisterClass " << RC.getName()
1323*9880d681SAndroid Build Coastguard Worker << "RegClass = {\n " << '&' << Target.getName()
1324*9880d681SAndroid Build Coastguard Worker << "MCRegisterClasses[" << RC.getName() << "RegClassID],\n "
1325*9880d681SAndroid Build Coastguard Worker << "VTLists + " << VTSeqs.get(RC.VTs) << ",\n " << RC.getName()
1326*9880d681SAndroid Build Coastguard Worker << "SubClassMask,\n SuperRegIdxSeqs + "
1327*9880d681SAndroid Build Coastguard Worker << SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]) << ",\n "
1328*9880d681SAndroid Build Coastguard Worker << format("0x%08x,\n ", RC.LaneMask)
1329*9880d681SAndroid Build Coastguard Worker << (unsigned)RC.AllocationPriority << ",\n "
1330*9880d681SAndroid Build Coastguard Worker << (RC.HasDisjunctSubRegs?"true":"false")
1331*9880d681SAndroid Build Coastguard Worker << ", /* HasDisjunctSubRegs */\n "
1332*9880d681SAndroid Build Coastguard Worker << (RC.CoveredBySubRegs?"true":"false")
1333*9880d681SAndroid Build Coastguard Worker << ", /* CoveredBySubRegs */\n ";
1334*9880d681SAndroid Build Coastguard Worker if (RC.getSuperClasses().empty())
1335*9880d681SAndroid Build Coastguard Worker OS << "NullRegClasses,\n ";
1336*9880d681SAndroid Build Coastguard Worker else
1337*9880d681SAndroid Build Coastguard Worker OS << RC.getName() << "Superclasses,\n ";
1338*9880d681SAndroid Build Coastguard Worker if (RC.AltOrderSelect.empty())
1339*9880d681SAndroid Build Coastguard Worker OS << "nullptr\n";
1340*9880d681SAndroid Build Coastguard Worker else
1341*9880d681SAndroid Build Coastguard Worker OS << RC.getName() << "GetRawAllocationOrder\n";
1342*9880d681SAndroid Build Coastguard Worker OS << " };\n\n";
1343*9880d681SAndroid Build Coastguard Worker }
1344*9880d681SAndroid Build Coastguard Worker
1345*9880d681SAndroid Build Coastguard Worker OS << "} // end namespace " << RegisterClasses.front().Namespace << "\n";
1346*9880d681SAndroid Build Coastguard Worker }
1347*9880d681SAndroid Build Coastguard Worker
1348*9880d681SAndroid Build Coastguard Worker OS << "\nnamespace {\n";
1349*9880d681SAndroid Build Coastguard Worker OS << " const TargetRegisterClass* const RegisterClasses[] = {\n";
1350*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegisterClasses)
1351*9880d681SAndroid Build Coastguard Worker OS << " &" << RC.getQualifiedName() << "RegClass,\n";
1352*9880d681SAndroid Build Coastguard Worker OS << " };\n";
1353*9880d681SAndroid Build Coastguard Worker OS << "} // end anonymous namespace\n";
1354*9880d681SAndroid Build Coastguard Worker
1355*9880d681SAndroid Build Coastguard Worker // Emit extra information about registers.
1356*9880d681SAndroid Build Coastguard Worker const std::string &TargetName = Target.getName();
1357*9880d681SAndroid Build Coastguard Worker OS << "\nstatic const TargetRegisterInfoDesc "
1358*9880d681SAndroid Build Coastguard Worker << TargetName << "RegInfoDesc[] = { // Extra Descriptors\n";
1359*9880d681SAndroid Build Coastguard Worker OS << " { 0, false },\n";
1360*9880d681SAndroid Build Coastguard Worker
1361*9880d681SAndroid Build Coastguard Worker const auto &Regs = RegBank.getRegisters();
1362*9880d681SAndroid Build Coastguard Worker for (const auto &Reg : Regs) {
1363*9880d681SAndroid Build Coastguard Worker OS << " { ";
1364*9880d681SAndroid Build Coastguard Worker OS << Reg.CostPerUse << ", "
1365*9880d681SAndroid Build Coastguard Worker << ( AllocatableRegs.count(Reg.TheDef) != 0 ? "true" : "false" )
1366*9880d681SAndroid Build Coastguard Worker << " },\n";
1367*9880d681SAndroid Build Coastguard Worker }
1368*9880d681SAndroid Build Coastguard Worker OS << "};\n"; // End of register descriptors...
1369*9880d681SAndroid Build Coastguard Worker
1370*9880d681SAndroid Build Coastguard Worker
1371*9880d681SAndroid Build Coastguard Worker std::string ClassName = Target.getName() + "GenRegisterInfo";
1372*9880d681SAndroid Build Coastguard Worker
1373*9880d681SAndroid Build Coastguard Worker auto SubRegIndicesSize =
1374*9880d681SAndroid Build Coastguard Worker std::distance(SubRegIndices.begin(), SubRegIndices.end());
1375*9880d681SAndroid Build Coastguard Worker
1376*9880d681SAndroid Build Coastguard Worker if (!SubRegIndices.empty()) {
1377*9880d681SAndroid Build Coastguard Worker emitComposeSubRegIndices(OS, RegBank, ClassName);
1378*9880d681SAndroid Build Coastguard Worker emitComposeSubRegIndexLaneMask(OS, RegBank, ClassName);
1379*9880d681SAndroid Build Coastguard Worker }
1380*9880d681SAndroid Build Coastguard Worker
1381*9880d681SAndroid Build Coastguard Worker // Emit getSubClassWithSubReg.
1382*9880d681SAndroid Build Coastguard Worker if (!SubRegIndices.empty()) {
1383*9880d681SAndroid Build Coastguard Worker OS << "const TargetRegisterClass *" << ClassName
1384*9880d681SAndroid Build Coastguard Worker << "::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx)"
1385*9880d681SAndroid Build Coastguard Worker << " const {\n";
1386*9880d681SAndroid Build Coastguard Worker // Use the smallest type that can hold a regclass ID with room for a
1387*9880d681SAndroid Build Coastguard Worker // sentinel.
1388*9880d681SAndroid Build Coastguard Worker if (RegisterClasses.size() < UINT8_MAX)
1389*9880d681SAndroid Build Coastguard Worker OS << " static const uint8_t Table[";
1390*9880d681SAndroid Build Coastguard Worker else if (RegisterClasses.size() < UINT16_MAX)
1391*9880d681SAndroid Build Coastguard Worker OS << " static const uint16_t Table[";
1392*9880d681SAndroid Build Coastguard Worker else
1393*9880d681SAndroid Build Coastguard Worker PrintFatalError("Too many register classes.");
1394*9880d681SAndroid Build Coastguard Worker OS << RegisterClasses.size() << "][" << SubRegIndicesSize << "] = {\n";
1395*9880d681SAndroid Build Coastguard Worker for (const auto &RC : RegisterClasses) {
1396*9880d681SAndroid Build Coastguard Worker OS << " {\t// " << RC.getName() << "\n";
1397*9880d681SAndroid Build Coastguard Worker for (auto &Idx : SubRegIndices) {
1398*9880d681SAndroid Build Coastguard Worker if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(&Idx))
1399*9880d681SAndroid Build Coastguard Worker OS << " " << SRC->EnumValue + 1 << ",\t// " << Idx.getName()
1400*9880d681SAndroid Build Coastguard Worker << " -> " << SRC->getName() << "\n";
1401*9880d681SAndroid Build Coastguard Worker else
1402*9880d681SAndroid Build Coastguard Worker OS << " 0,\t// " << Idx.getName() << "\n";
1403*9880d681SAndroid Build Coastguard Worker }
1404*9880d681SAndroid Build Coastguard Worker OS << " },\n";
1405*9880d681SAndroid Build Coastguard Worker }
1406*9880d681SAndroid Build Coastguard Worker OS << " };\n assert(RC && \"Missing regclass\");\n"
1407*9880d681SAndroid Build Coastguard Worker << " if (!Idx) return RC;\n --Idx;\n"
1408*9880d681SAndroid Build Coastguard Worker << " assert(Idx < " << SubRegIndicesSize << " && \"Bad subreg\");\n"
1409*9880d681SAndroid Build Coastguard Worker << " unsigned TV = Table[RC->getID()][Idx];\n"
1410*9880d681SAndroid Build Coastguard Worker << " return TV ? getRegClass(TV - 1) : nullptr;\n}\n\n";
1411*9880d681SAndroid Build Coastguard Worker }
1412*9880d681SAndroid Build Coastguard Worker
1413*9880d681SAndroid Build Coastguard Worker EmitRegUnitPressure(OS, RegBank, ClassName);
1414*9880d681SAndroid Build Coastguard Worker
1415*9880d681SAndroid Build Coastguard Worker // Emit the constructor of the class...
1416*9880d681SAndroid Build Coastguard Worker OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
1417*9880d681SAndroid Build Coastguard Worker OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[];\n";
1418*9880d681SAndroid Build Coastguard Worker OS << "extern const unsigned " << TargetName << "LaneMaskLists[];\n";
1419*9880d681SAndroid Build Coastguard Worker OS << "extern const char " << TargetName << "RegStrings[];\n";
1420*9880d681SAndroid Build Coastguard Worker OS << "extern const char " << TargetName << "RegClassStrings[];\n";
1421*9880d681SAndroid Build Coastguard Worker OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2];\n";
1422*9880d681SAndroid Build Coastguard Worker OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n";
1423*9880d681SAndroid Build Coastguard Worker OS << "extern const MCRegisterInfo::SubRegCoveredBits "
1424*9880d681SAndroid Build Coastguard Worker << TargetName << "SubRegIdxRanges[];\n";
1425*9880d681SAndroid Build Coastguard Worker OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n";
1426*9880d681SAndroid Build Coastguard Worker
1427*9880d681SAndroid Build Coastguard Worker EmitRegMappingTables(OS, Regs, true);
1428*9880d681SAndroid Build Coastguard Worker
1429*9880d681SAndroid Build Coastguard Worker OS << ClassName << "::\n" << ClassName
1430*9880d681SAndroid Build Coastguard Worker << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour, unsigned PC)\n"
1431*9880d681SAndroid Build Coastguard Worker << " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
1432*9880d681SAndroid Build Coastguard Worker << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
1433*9880d681SAndroid Build Coastguard Worker << " SubRegIndexNameTable, SubRegIndexLaneMaskTable, 0x";
1434*9880d681SAndroid Build Coastguard Worker OS.write_hex(RegBank.CoveringLanes);
1435*9880d681SAndroid Build Coastguard Worker OS << ") {\n"
1436*9880d681SAndroid Build Coastguard Worker << " InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size() + 1
1437*9880d681SAndroid Build Coastguard Worker << ", RA, PC,\n " << TargetName
1438*9880d681SAndroid Build Coastguard Worker << "MCRegisterClasses, " << RegisterClasses.size() << ",\n"
1439*9880d681SAndroid Build Coastguard Worker << " " << TargetName << "RegUnitRoots,\n"
1440*9880d681SAndroid Build Coastguard Worker << " " << RegBank.getNumNativeRegUnits() << ",\n"
1441*9880d681SAndroid Build Coastguard Worker << " " << TargetName << "RegDiffLists,\n"
1442*9880d681SAndroid Build Coastguard Worker << " " << TargetName << "LaneMaskLists,\n"
1443*9880d681SAndroid Build Coastguard Worker << " " << TargetName << "RegStrings,\n"
1444*9880d681SAndroid Build Coastguard Worker << " " << TargetName << "RegClassStrings,\n"
1445*9880d681SAndroid Build Coastguard Worker << " " << TargetName << "SubRegIdxLists,\n"
1446*9880d681SAndroid Build Coastguard Worker << " " << SubRegIndicesSize + 1 << ",\n"
1447*9880d681SAndroid Build Coastguard Worker << " " << TargetName << "SubRegIdxRanges,\n"
1448*9880d681SAndroid Build Coastguard Worker << " " << TargetName << "RegEncodingTable);\n\n";
1449*9880d681SAndroid Build Coastguard Worker
1450*9880d681SAndroid Build Coastguard Worker EmitRegMapping(OS, Regs, true);
1451*9880d681SAndroid Build Coastguard Worker
1452*9880d681SAndroid Build Coastguard Worker OS << "}\n\n";
1453*9880d681SAndroid Build Coastguard Worker
1454*9880d681SAndroid Build Coastguard Worker // Emit CalleeSavedRegs information.
1455*9880d681SAndroid Build Coastguard Worker std::vector<Record*> CSRSets =
1456*9880d681SAndroid Build Coastguard Worker Records.getAllDerivedDefinitions("CalleeSavedRegs");
1457*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = CSRSets.size(); i != e; ++i) {
1458*9880d681SAndroid Build Coastguard Worker Record *CSRSet = CSRSets[i];
1459*9880d681SAndroid Build Coastguard Worker const SetTheory::RecVec *Regs = RegBank.getSets().expand(CSRSet);
1460*9880d681SAndroid Build Coastguard Worker assert(Regs && "Cannot expand CalleeSavedRegs instance");
1461*9880d681SAndroid Build Coastguard Worker
1462*9880d681SAndroid Build Coastguard Worker // Emit the *_SaveList list of callee-saved registers.
1463*9880d681SAndroid Build Coastguard Worker OS << "static const MCPhysReg " << CSRSet->getName()
1464*9880d681SAndroid Build Coastguard Worker << "_SaveList[] = { ";
1465*9880d681SAndroid Build Coastguard Worker for (unsigned r = 0, re = Regs->size(); r != re; ++r)
1466*9880d681SAndroid Build Coastguard Worker OS << getQualifiedName((*Regs)[r]) << ", ";
1467*9880d681SAndroid Build Coastguard Worker OS << "0 };\n";
1468*9880d681SAndroid Build Coastguard Worker
1469*9880d681SAndroid Build Coastguard Worker // Emit the *_RegMask bit mask of call-preserved registers.
1470*9880d681SAndroid Build Coastguard Worker BitVector Covered = RegBank.computeCoveredRegisters(*Regs);
1471*9880d681SAndroid Build Coastguard Worker
1472*9880d681SAndroid Build Coastguard Worker // Check for an optional OtherPreserved set.
1473*9880d681SAndroid Build Coastguard Worker // Add those registers to RegMask, but not to SaveList.
1474*9880d681SAndroid Build Coastguard Worker if (DagInit *OPDag =
1475*9880d681SAndroid Build Coastguard Worker dyn_cast<DagInit>(CSRSet->getValueInit("OtherPreserved"))) {
1476*9880d681SAndroid Build Coastguard Worker SetTheory::RecSet OPSet;
1477*9880d681SAndroid Build Coastguard Worker RegBank.getSets().evaluate(OPDag, OPSet, CSRSet->getLoc());
1478*9880d681SAndroid Build Coastguard Worker Covered |= RegBank.computeCoveredRegisters(
1479*9880d681SAndroid Build Coastguard Worker ArrayRef<Record*>(OPSet.begin(), OPSet.end()));
1480*9880d681SAndroid Build Coastguard Worker }
1481*9880d681SAndroid Build Coastguard Worker
1482*9880d681SAndroid Build Coastguard Worker OS << "static const uint32_t " << CSRSet->getName()
1483*9880d681SAndroid Build Coastguard Worker << "_RegMask[] = { ";
1484*9880d681SAndroid Build Coastguard Worker printBitVectorAsHex(OS, Covered, 32);
1485*9880d681SAndroid Build Coastguard Worker OS << "};\n";
1486*9880d681SAndroid Build Coastguard Worker }
1487*9880d681SAndroid Build Coastguard Worker OS << "\n\n";
1488*9880d681SAndroid Build Coastguard Worker
1489*9880d681SAndroid Build Coastguard Worker OS << "ArrayRef<const uint32_t *> " << ClassName
1490*9880d681SAndroid Build Coastguard Worker << "::getRegMasks() const {\n";
1491*9880d681SAndroid Build Coastguard Worker if (!CSRSets.empty()) {
1492*9880d681SAndroid Build Coastguard Worker OS << " static const uint32_t *const Masks[] = {\n";
1493*9880d681SAndroid Build Coastguard Worker for (Record *CSRSet : CSRSets)
1494*9880d681SAndroid Build Coastguard Worker OS << " " << CSRSet->getName() << "_RegMask,\n";
1495*9880d681SAndroid Build Coastguard Worker OS << " };\n";
1496*9880d681SAndroid Build Coastguard Worker OS << " return makeArrayRef(Masks);\n";
1497*9880d681SAndroid Build Coastguard Worker } else {
1498*9880d681SAndroid Build Coastguard Worker OS << " return None;\n";
1499*9880d681SAndroid Build Coastguard Worker }
1500*9880d681SAndroid Build Coastguard Worker OS << "}\n\n";
1501*9880d681SAndroid Build Coastguard Worker
1502*9880d681SAndroid Build Coastguard Worker OS << "ArrayRef<const char *> " << ClassName
1503*9880d681SAndroid Build Coastguard Worker << "::getRegMaskNames() const {\n";
1504*9880d681SAndroid Build Coastguard Worker if (!CSRSets.empty()) {
1505*9880d681SAndroid Build Coastguard Worker OS << " static const char *const Names[] = {\n";
1506*9880d681SAndroid Build Coastguard Worker for (Record *CSRSet : CSRSets)
1507*9880d681SAndroid Build Coastguard Worker OS << " " << '"' << CSRSet->getName() << '"' << ",\n";
1508*9880d681SAndroid Build Coastguard Worker OS << " };\n";
1509*9880d681SAndroid Build Coastguard Worker OS << " return makeArrayRef(Names);\n";
1510*9880d681SAndroid Build Coastguard Worker } else {
1511*9880d681SAndroid Build Coastguard Worker OS << " return None;\n";
1512*9880d681SAndroid Build Coastguard Worker }
1513*9880d681SAndroid Build Coastguard Worker OS << "}\n\n";
1514*9880d681SAndroid Build Coastguard Worker
1515*9880d681SAndroid Build Coastguard Worker OS << "const " << TargetName << "FrameLowering *\n" << TargetName
1516*9880d681SAndroid Build Coastguard Worker << "GenRegisterInfo::getFrameLowering(const MachineFunction &MF) {\n"
1517*9880d681SAndroid Build Coastguard Worker << " return static_cast<const " << TargetName << "FrameLowering *>(\n"
1518*9880d681SAndroid Build Coastguard Worker << " MF.getSubtarget().getFrameLowering());\n"
1519*9880d681SAndroid Build Coastguard Worker << "}\n\n";
1520*9880d681SAndroid Build Coastguard Worker
1521*9880d681SAndroid Build Coastguard Worker OS << "} // end namespace llvm\n\n";
1522*9880d681SAndroid Build Coastguard Worker OS << "#endif // GET_REGINFO_TARGET_DESC\n\n";
1523*9880d681SAndroid Build Coastguard Worker }
1524*9880d681SAndroid Build Coastguard Worker
run(raw_ostream & OS)1525*9880d681SAndroid Build Coastguard Worker void RegisterInfoEmitter::run(raw_ostream &OS) {
1526*9880d681SAndroid Build Coastguard Worker CodeGenTarget Target(Records);
1527*9880d681SAndroid Build Coastguard Worker CodeGenRegBank &RegBank = Target.getRegBank();
1528*9880d681SAndroid Build Coastguard Worker RegBank.computeDerivedInfo();
1529*9880d681SAndroid Build Coastguard Worker
1530*9880d681SAndroid Build Coastguard Worker runEnums(OS, Target, RegBank);
1531*9880d681SAndroid Build Coastguard Worker runMCDesc(OS, Target, RegBank);
1532*9880d681SAndroid Build Coastguard Worker runTargetHeader(OS, Target, RegBank);
1533*9880d681SAndroid Build Coastguard Worker runTargetDesc(OS, Target, RegBank);
1534*9880d681SAndroid Build Coastguard Worker }
1535*9880d681SAndroid Build Coastguard Worker
1536*9880d681SAndroid Build Coastguard Worker namespace llvm {
1537*9880d681SAndroid Build Coastguard Worker
EmitRegisterInfo(RecordKeeper & RK,raw_ostream & OS)1538*9880d681SAndroid Build Coastguard Worker void EmitRegisterInfo(RecordKeeper &RK, raw_ostream &OS) {
1539*9880d681SAndroid Build Coastguard Worker RegisterInfoEmitter(RK).run(OS);
1540*9880d681SAndroid Build Coastguard Worker }
1541*9880d681SAndroid Build Coastguard Worker
1542*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
1543