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