mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 17:29:19 +00:00
registers that alias Reg, including itself. This is almost the same as the existing getAliasSet() method, except for the inclusion of Reg. The name matches the reflexive TRI::regsOverlap(x, y) relation. It is very common to do stuff to a register and all its aliases: stuff(Reg) for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) stuff(*Alias); That can now be written as the simpler: for (const unsigned *Alias = TRI->getOverlaps(Reg); *Alias; ++Alias) stuff(*Alias); This change requires a bit more constant space for the alias lists because Reg is included and because the empty alias list cannot be shared any longer. If the getAliasSet method is eventually removed, this space can be reclaimed by sharing overlap lists. For instance, %rax and %eax have identical overlap sets. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121800 91177308-0d34-0410-b5e6-96231b3b80d8
1010 lines
38 KiB
C++
1010 lines
38 KiB
C++
//===- RegisterInfoEmitter.cpp - Generate a Register File Desc. -*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This tablegen backend is responsible for emitting a description of a target
|
|
// register file for a code generator. It uses instances of the Register,
|
|
// RegisterAliases, and RegisterClass classes to gather this information.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "RegisterInfoEmitter.h"
|
|
#include "CodeGenTarget.h"
|
|
#include "CodeGenRegisters.h"
|
|
#include "Record.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
#include <algorithm>
|
|
#include <set>
|
|
using namespace llvm;
|
|
|
|
// runEnums - Print out enum values for all of the registers.
|
|
void RegisterInfoEmitter::runEnums(raw_ostream &OS) {
|
|
CodeGenTarget Target(Records);
|
|
const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
|
|
|
|
std::string Namespace = Registers[0].TheDef->getValueAsString("Namespace");
|
|
|
|
EmitSourceFileHeader("Target Register Enum Values", OS);
|
|
OS << "namespace llvm {\n\n";
|
|
|
|
if (!Namespace.empty())
|
|
OS << "namespace " << Namespace << " {\n";
|
|
OS << "enum {\n NoRegister,\n";
|
|
|
|
for (unsigned i = 0, e = Registers.size(); i != e; ++i)
|
|
OS << " " << Registers[i].getName() << ", \t// " << i+1 << "\n";
|
|
OS << " NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n";
|
|
OS << "};\n";
|
|
if (!Namespace.empty())
|
|
OS << "}\n";
|
|
|
|
const std::vector<Record*> SubRegIndices = Target.getSubRegIndices();
|
|
if (!SubRegIndices.empty()) {
|
|
OS << "\n// Subregister indices\n";
|
|
Namespace = SubRegIndices[0]->getValueAsString("Namespace");
|
|
if (!Namespace.empty())
|
|
OS << "namespace " << Namespace << " {\n";
|
|
OS << "enum {\n NoSubRegister,\n";
|
|
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
|
|
OS << " " << SubRegIndices[i]->getName() << ",\t// " << i+1 << "\n";
|
|
OS << " NUM_TARGET_SUBREGS = " << SubRegIndices.size()+1 << "\n";
|
|
OS << "};\n";
|
|
if (!Namespace.empty())
|
|
OS << "}\n";
|
|
}
|
|
OS << "} // End llvm namespace \n";
|
|
}
|
|
|
|
void RegisterInfoEmitter::runHeader(raw_ostream &OS) {
|
|
EmitSourceFileHeader("Register Information Header Fragment", OS);
|
|
CodeGenTarget Target(Records);
|
|
const std::string &TargetName = Target.getName();
|
|
std::string ClassName = TargetName + "GenRegisterInfo";
|
|
|
|
OS << "#include \"llvm/Target/TargetRegisterInfo.h\"\n";
|
|
OS << "#include <string>\n\n";
|
|
|
|
OS << "namespace llvm {\n\n";
|
|
|
|
OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
|
|
<< " explicit " << ClassName
|
|
<< "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n"
|
|
<< " virtual int getDwarfRegNumFull(unsigned RegNum, "
|
|
<< "unsigned Flavour) const;\n"
|
|
<< " virtual int getDwarfRegNum(unsigned RegNum, bool isEH) const = 0;\n"
|
|
<< " virtual bool needsStackRealignment(const MachineFunction &) const\n"
|
|
<< " { return false; }\n"
|
|
<< " unsigned getSubReg(unsigned RegNo, unsigned Index) const;\n"
|
|
<< " unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;\n"
|
|
<< " unsigned composeSubRegIndices(unsigned, unsigned) const;\n"
|
|
<< "};\n\n";
|
|
|
|
const std::vector<CodeGenRegisterClass> &RegisterClasses =
|
|
Target.getRegisterClasses();
|
|
|
|
if (!RegisterClasses.empty()) {
|
|
OS << "namespace " << RegisterClasses[0].Namespace
|
|
<< " { // Register classes\n";
|
|
|
|
OS << " enum {\n";
|
|
for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
|
|
if (i) OS << ",\n";
|
|
OS << " " << RegisterClasses[i].getName() << "RegClassID";
|
|
OS << " = " << i;
|
|
}
|
|
OS << "\n };\n\n";
|
|
|
|
for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
|
|
const std::string &Name = RegisterClasses[i].getName();
|
|
|
|
// Output the register class definition.
|
|
OS << " struct " << Name << "Class : public TargetRegisterClass {\n"
|
|
<< " " << Name << "Class();\n"
|
|
<< RegisterClasses[i].MethodProtos << " };\n";
|
|
|
|
// Output the extern for the instance.
|
|
OS << " extern " << Name << "Class\t" << Name << "RegClass;\n";
|
|
// Output the extern for the pointer to the instance (should remove).
|
|
OS << " static TargetRegisterClass * const "<< Name <<"RegisterClass = &"
|
|
<< Name << "RegClass;\n";
|
|
}
|
|
OS << "} // end of namespace " << TargetName << "\n\n";
|
|
}
|
|
OS << "} // End llvm namespace \n";
|
|
}
|
|
|
|
static void addSuperReg(Record *R, Record *S,
|
|
std::map<Record*, std::set<Record*>, LessRecord> &SubRegs,
|
|
std::map<Record*, std::set<Record*>, LessRecord> &SuperRegs,
|
|
std::map<Record*, std::set<Record*>, LessRecord> &Aliases) {
|
|
if (R == S) {
|
|
errs() << "Error: recursive sub-register relationship between"
|
|
<< " register " << getQualifiedName(R)
|
|
<< " and its sub-registers?\n";
|
|
abort();
|
|
}
|
|
if (!SuperRegs[R].insert(S).second)
|
|
return;
|
|
SubRegs[S].insert(R);
|
|
Aliases[R].insert(S);
|
|
Aliases[S].insert(R);
|
|
if (SuperRegs.count(S))
|
|
for (std::set<Record*>::iterator I = SuperRegs[S].begin(),
|
|
E = SuperRegs[S].end(); I != E; ++I)
|
|
addSuperReg(R, *I, SubRegs, SuperRegs, Aliases);
|
|
}
|
|
|
|
static void addSubSuperReg(Record *R, Record *S,
|
|
std::map<Record*, std::set<Record*>, LessRecord> &SubRegs,
|
|
std::map<Record*, std::set<Record*>, LessRecord> &SuperRegs,
|
|
std::map<Record*, std::set<Record*>, LessRecord> &Aliases) {
|
|
if (R == S) {
|
|
errs() << "Error: recursive sub-register relationship between"
|
|
<< " register " << getQualifiedName(R)
|
|
<< " and its sub-registers?\n";
|
|
abort();
|
|
}
|
|
|
|
if (!SubRegs[R].insert(S).second)
|
|
return;
|
|
addSuperReg(S, R, SubRegs, SuperRegs, Aliases);
|
|
Aliases[R].insert(S);
|
|
Aliases[S].insert(R);
|
|
if (SubRegs.count(S))
|
|
for (std::set<Record*>::iterator I = SubRegs[S].begin(),
|
|
E = SubRegs[S].end(); I != E; ++I)
|
|
addSubSuperReg(R, *I, SubRegs, SuperRegs, Aliases);
|
|
}
|
|
|
|
struct RegisterMaps {
|
|
// Map SubRegIndex -> Register
|
|
typedef std::map<Record*, Record*, LessRecord> SubRegMap;
|
|
// Map Register -> SubRegMap
|
|
typedef std::map<Record*, SubRegMap> SubRegMaps;
|
|
|
|
SubRegMaps SubReg;
|
|
SubRegMap &inferSubRegIndices(Record *Reg);
|
|
|
|
// Composite SubRegIndex instances.
|
|
// Map (SubRegIndex,SubRegIndex) -> SubRegIndex
|
|
typedef DenseMap<std::pair<Record*,Record*>,Record*> CompositeMap;
|
|
CompositeMap Composite;
|
|
|
|
// Compute SubRegIndex compositions after inferSubRegIndices has run on all
|
|
// registers.
|
|
void computeComposites();
|
|
};
|
|
|
|
// Calculate all subregindices for Reg. Loopy subregs cause infinite recursion.
|
|
RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg) {
|
|
SubRegMap &SRM = SubReg[Reg];
|
|
if (!SRM.empty())
|
|
return SRM;
|
|
std::vector<Record*> SubRegs = Reg->getValueAsListOfDefs("SubRegs");
|
|
std::vector<Record*> Indices = Reg->getValueAsListOfDefs("SubRegIndices");
|
|
if (SubRegs.size() != Indices.size())
|
|
throw "Register " + Reg->getName() + " SubRegIndices doesn't match SubRegs";
|
|
|
|
// First insert the direct subregs and make sure they are fully indexed.
|
|
for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) {
|
|
if (!SRM.insert(std::make_pair(Indices[i], SubRegs[i])).second)
|
|
throw "SubRegIndex " + Indices[i]->getName()
|
|
+ " appears twice in Register " + Reg->getName();
|
|
inferSubRegIndices(SubRegs[i]);
|
|
}
|
|
|
|
// Keep track of inherited subregs and how they can be reached.
|
|
// Register -> (SubRegIndex, SubRegIndex)
|
|
typedef std::map<Record*, std::pair<Record*,Record*>, LessRecord> OrphanMap;
|
|
OrphanMap Orphans;
|
|
|
|
// Clone inherited subregs. Here the order is important - earlier subregs take
|
|
// precedence.
|
|
for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) {
|
|
SubRegMap &M = SubReg[SubRegs[i]];
|
|
for (SubRegMap::iterator si = M.begin(), se = M.end(); si != se; ++si)
|
|
if (!SRM.insert(*si).second)
|
|
Orphans[si->second] = std::make_pair(Indices[i], si->first);
|
|
}
|
|
|
|
// Finally process the composites.
|
|
ListInit *Comps = Reg->getValueAsListInit("CompositeIndices");
|
|
for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
|
|
DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i));
|
|
if (!Pat)
|
|
throw "Invalid dag '" + Comps->getElement(i)->getAsString()
|
|
+ "' in CompositeIndices";
|
|
DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator());
|
|
if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex"))
|
|
throw "Invalid SubClassIndex in " + Pat->getAsString();
|
|
|
|
// Resolve list of subreg indices into R2.
|
|
Record *R2 = Reg;
|
|
for (DagInit::const_arg_iterator di = Pat->arg_begin(),
|
|
de = Pat->arg_end(); di != de; ++di) {
|
|
DefInit *IdxInit = dynamic_cast<DefInit*>(*di);
|
|
if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex"))
|
|
throw "Invalid SubClassIndex in " + Pat->getAsString();
|
|
SubRegMap::const_iterator ni = SubReg[R2].find(IdxInit->getDef());
|
|
if (ni == SubReg[R2].end())
|
|
throw "Composite " + Pat->getAsString() + " refers to bad index in "
|
|
+ R2->getName();
|
|
R2 = ni->second;
|
|
}
|
|
|
|
// Insert composite index. Allow overriding inherited indices etc.
|
|
SRM[BaseIdxInit->getDef()] = R2;
|
|
|
|
// R2 is now directly addressable, no longer an orphan.
|
|
Orphans.erase(R2);
|
|
}
|
|
|
|
// Now, Orphans contains the inherited subregisters without a direct index.
|
|
if (!Orphans.empty()) {
|
|
errs() << "Error: Register " << getQualifiedName(Reg)
|
|
<< " inherited subregisters without an index:\n";
|
|
for (OrphanMap::iterator i = Orphans.begin(), e = Orphans.end(); i != e;
|
|
++i) {
|
|
errs() << " " << getQualifiedName(i->first)
|
|
<< " = " << i->second.first->getName()
|
|
<< ", " << i->second.second->getName() << "\n";
|
|
}
|
|
abort();
|
|
}
|
|
return SRM;
|
|
}
|
|
|
|
void RegisterMaps::computeComposites() {
|
|
for (SubRegMaps::const_iterator sri = SubReg.begin(), sre = SubReg.end();
|
|
sri != sre; ++sri) {
|
|
Record *Reg1 = sri->first;
|
|
const SubRegMap &SRM1 = sri->second;
|
|
for (SubRegMap::const_iterator i1 = SRM1.begin(), e1 = SRM1.end();
|
|
i1 != e1; ++i1) {
|
|
Record *Idx1 = i1->first;
|
|
Record *Reg2 = i1->second;
|
|
// Ignore identity compositions.
|
|
if (Reg1 == Reg2)
|
|
continue;
|
|
// If Reg2 has no subregs, Idx1 doesn't compose.
|
|
if (!SubReg.count(Reg2))
|
|
continue;
|
|
const SubRegMap &SRM2 = SubReg[Reg2];
|
|
// Try composing Idx1 with another SubRegIndex.
|
|
for (SubRegMap::const_iterator i2 = SRM2.begin(), e2 = SRM2.end();
|
|
i2 != e2; ++i2) {
|
|
std::pair<Record*,Record*> IdxPair(Idx1, i2->first);
|
|
Record *Reg3 = i2->second;
|
|
// OK Reg1:IdxPair == Reg3. Find the index with Reg:Idx == Reg3.
|
|
for (SubRegMap::const_iterator i1d = SRM1.begin(), e1d = SRM1.end();
|
|
i1d != e1d; ++i1d) {
|
|
// Ignore identity compositions.
|
|
if (Reg2 == Reg3)
|
|
continue;
|
|
if (i1d->second == Reg3) {
|
|
std::pair<CompositeMap::iterator,bool> Ins =
|
|
Composite.insert(std::make_pair(IdxPair, i1d->first));
|
|
// Conflicting composition?
|
|
if (!Ins.second && Ins.first->second != i1d->first) {
|
|
errs() << "Error: SubRegIndex " << getQualifiedName(Idx1)
|
|
<< " and " << getQualifiedName(IdxPair.second)
|
|
<< " compose ambiguously as "
|
|
<< getQualifiedName(Ins.first->second) << " or "
|
|
<< getQualifiedName(i1d->first) << "\n";
|
|
abort();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// We don't care about the difference between (Idx1, Idx2) -> Idx2 and invalid
|
|
// compositions, so remove any mappings of that form.
|
|
for (CompositeMap::iterator i = Composite.begin(), e = Composite.end();
|
|
i != e;) {
|
|
CompositeMap::iterator j = i;
|
|
++i;
|
|
if (j->first.second == j->second)
|
|
Composite.erase(j);
|
|
}
|
|
}
|
|
|
|
class RegisterSorter {
|
|
private:
|
|
std::map<Record*, std::set<Record*>, LessRecord> &RegisterSubRegs;
|
|
|
|
public:
|
|
RegisterSorter(std::map<Record*, std::set<Record*>, LessRecord> &RS)
|
|
: RegisterSubRegs(RS) {}
|
|
|
|
bool operator()(Record *RegA, Record *RegB) {
|
|
// B is sub-register of A.
|
|
return RegisterSubRegs.count(RegA) && RegisterSubRegs[RegA].count(RegB);
|
|
}
|
|
};
|
|
|
|
// RegisterInfoEmitter::run - Main register file description emitter.
|
|
//
|
|
void RegisterInfoEmitter::run(raw_ostream &OS) {
|
|
CodeGenTarget Target(Records);
|
|
EmitSourceFileHeader("Register Information Source Fragment", OS);
|
|
|
|
OS << "namespace llvm {\n\n";
|
|
|
|
// Start out by emitting each of the register classes... to do this, we build
|
|
// a set of registers which belong to a register class, this is to ensure that
|
|
// each register is only in a single register class.
|
|
//
|
|
const std::vector<CodeGenRegisterClass> &RegisterClasses =
|
|
Target.getRegisterClasses();
|
|
|
|
// Loop over all of the register classes... emitting each one.
|
|
OS << "namespace { // Register classes...\n";
|
|
|
|
// RegClassesBelongedTo - Keep track of which register classes each reg
|
|
// belongs to.
|
|
std::multimap<Record*, const CodeGenRegisterClass*> RegClassesBelongedTo;
|
|
|
|
// Emit the register enum value arrays for each RegisterClass
|
|
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
|
const CodeGenRegisterClass &RC = RegisterClasses[rc];
|
|
|
|
// Give the register class a legal C name if it's anonymous.
|
|
std::string Name = RC.TheDef->getName();
|
|
|
|
// Emit the register list now.
|
|
OS << " // " << Name << " Register Class...\n"
|
|
<< " static const unsigned " << Name
|
|
<< "[] = {\n ";
|
|
for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) {
|
|
Record *Reg = RC.Elements[i];
|
|
OS << getQualifiedName(Reg) << ", ";
|
|
|
|
// Keep track of which regclasses this register is in.
|
|
RegClassesBelongedTo.insert(std::make_pair(Reg, &RC));
|
|
}
|
|
OS << "\n };\n\n";
|
|
}
|
|
|
|
// Emit the ValueType arrays for each RegisterClass
|
|
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
|
const CodeGenRegisterClass &RC = RegisterClasses[rc];
|
|
|
|
// Give the register class a legal C name if it's anonymous.
|
|
std::string Name = RC.TheDef->getName() + "VTs";
|
|
|
|
// Emit the register list now.
|
|
OS << " // " << Name
|
|
<< " Register Class Value Types...\n"
|
|
<< " static const EVT " << Name
|
|
<< "[] = {\n ";
|
|
for (unsigned i = 0, e = RC.VTs.size(); i != e; ++i)
|
|
OS << getEnumName(RC.VTs[i]) << ", ";
|
|
OS << "MVT::Other\n };\n\n";
|
|
}
|
|
OS << "} // end anonymous namespace\n\n";
|
|
|
|
// Now that all of the structs have been emitted, emit the instances.
|
|
if (!RegisterClasses.empty()) {
|
|
OS << "namespace " << RegisterClasses[0].Namespace
|
|
<< " { // Register class instances\n";
|
|
for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i)
|
|
OS << " " << RegisterClasses[i].getName() << "Class\t"
|
|
<< RegisterClasses[i].getName() << "RegClass;\n";
|
|
|
|
std::map<unsigned, std::set<unsigned> > SuperClassMap;
|
|
std::map<unsigned, std::set<unsigned> > SuperRegClassMap;
|
|
OS << "\n";
|
|
|
|
unsigned NumSubRegIndices = Target.getSubRegIndices().size();
|
|
|
|
if (NumSubRegIndices) {
|
|
// Emit the sub-register classes for each RegisterClass
|
|
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
|
const CodeGenRegisterClass &RC = RegisterClasses[rc];
|
|
std::vector<Record*> SRC(NumSubRegIndices);
|
|
for (DenseMap<Record*,Record*>::const_iterator
|
|
i = RC.SubRegClasses.begin(),
|
|
e = RC.SubRegClasses.end(); i != e; ++i) {
|
|
// Build SRC array.
|
|
unsigned idx = Target.getSubRegIndexNo(i->first);
|
|
SRC.at(idx-1) = i->second;
|
|
|
|
// Find the register class number of i->second for SuperRegClassMap.
|
|
for (unsigned rc2 = 0, e2 = RegisterClasses.size(); rc2 != e2; ++rc2) {
|
|
const CodeGenRegisterClass &RC2 = RegisterClasses[rc2];
|
|
if (RC2.TheDef == i->second) {
|
|
SuperRegClassMap[rc2].insert(rc);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Give the register class a legal C name if it's anonymous.
|
|
std::string Name = RC.TheDef->getName();
|
|
|
|
OS << " // " << Name
|
|
<< " Sub-register Classes...\n"
|
|
<< " static const TargetRegisterClass* const "
|
|
<< Name << "SubRegClasses[] = {\n ";
|
|
|
|
for (unsigned idx = 0; idx != NumSubRegIndices; ++idx) {
|
|
if (idx)
|
|
OS << ", ";
|
|
if (SRC[idx])
|
|
OS << "&" << getQualifiedName(SRC[idx]) << "RegClass";
|
|
else
|
|
OS << "0";
|
|
}
|
|
OS << "\n };\n\n";
|
|
}
|
|
|
|
// Emit the super-register classes for each RegisterClass
|
|
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
|
const CodeGenRegisterClass &RC = RegisterClasses[rc];
|
|
|
|
// Give the register class a legal C name if it's anonymous.
|
|
std::string Name = RC.TheDef->getName();
|
|
|
|
OS << " // " << Name
|
|
<< " Super-register Classes...\n"
|
|
<< " static const TargetRegisterClass* const "
|
|
<< Name << "SuperRegClasses[] = {\n ";
|
|
|
|
bool Empty = true;
|
|
std::map<unsigned, std::set<unsigned> >::iterator I =
|
|
SuperRegClassMap.find(rc);
|
|
if (I != SuperRegClassMap.end()) {
|
|
for (std::set<unsigned>::iterator II = I->second.begin(),
|
|
EE = I->second.end(); II != EE; ++II) {
|
|
const CodeGenRegisterClass &RC2 = RegisterClasses[*II];
|
|
if (!Empty)
|
|
OS << ", ";
|
|
OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
|
|
Empty = false;
|
|
}
|
|
}
|
|
|
|
OS << (!Empty ? ", " : "") << "NULL";
|
|
OS << "\n };\n\n";
|
|
}
|
|
} else {
|
|
// No subregindices in this target
|
|
OS << " static const TargetRegisterClass* const "
|
|
<< "NullRegClasses[] = { NULL };\n\n";
|
|
}
|
|
|
|
// Emit the sub-classes array for each RegisterClass
|
|
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
|
const CodeGenRegisterClass &RC = RegisterClasses[rc];
|
|
|
|
// Give the register class a legal C name if it's anonymous.
|
|
std::string Name = RC.TheDef->getName();
|
|
|
|
OS << " // " << Name
|
|
<< " Register Class sub-classes...\n"
|
|
<< " static const TargetRegisterClass* const "
|
|
<< Name << "Subclasses[] = {\n ";
|
|
|
|
bool Empty = true;
|
|
for (unsigned rc2 = 0, e2 = RegisterClasses.size(); rc2 != e2; ++rc2) {
|
|
const CodeGenRegisterClass &RC2 = RegisterClasses[rc2];
|
|
|
|
// Sub-classes are used to determine if a virtual register can be used
|
|
// as an instruction operand, or if it must be copied first.
|
|
if (rc == rc2 || !RC.hasSubClass(&RC2)) continue;
|
|
|
|
if (!Empty) OS << ", ";
|
|
OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
|
|
Empty = false;
|
|
|
|
std::map<unsigned, std::set<unsigned> >::iterator SCMI =
|
|
SuperClassMap.find(rc2);
|
|
if (SCMI == SuperClassMap.end()) {
|
|
SuperClassMap.insert(std::make_pair(rc2, std::set<unsigned>()));
|
|
SCMI = SuperClassMap.find(rc2);
|
|
}
|
|
SCMI->second.insert(rc);
|
|
}
|
|
|
|
OS << (!Empty ? ", " : "") << "NULL";
|
|
OS << "\n };\n\n";
|
|
}
|
|
|
|
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
|
const CodeGenRegisterClass &RC = RegisterClasses[rc];
|
|
|
|
// Give the register class a legal C name if it's anonymous.
|
|
std::string Name = RC.TheDef->getName();
|
|
|
|
OS << " // " << Name
|
|
<< " Register Class super-classes...\n"
|
|
<< " static const TargetRegisterClass* const "
|
|
<< Name << "Superclasses[] = {\n ";
|
|
|
|
bool Empty = true;
|
|
std::map<unsigned, std::set<unsigned> >::iterator I =
|
|
SuperClassMap.find(rc);
|
|
if (I != SuperClassMap.end()) {
|
|
for (std::set<unsigned>::iterator II = I->second.begin(),
|
|
EE = I->second.end(); II != EE; ++II) {
|
|
const CodeGenRegisterClass &RC2 = RegisterClasses[*II];
|
|
if (!Empty) OS << ", ";
|
|
OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
|
|
Empty = false;
|
|
}
|
|
}
|
|
|
|
OS << (!Empty ? ", " : "") << "NULL";
|
|
OS << "\n };\n\n";
|
|
}
|
|
|
|
|
|
for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
|
|
const CodeGenRegisterClass &RC = RegisterClasses[i];
|
|
OS << RC.MethodBodies << "\n";
|
|
OS << RC.getName() << "Class::" << RC.getName()
|
|
<< "Class() : TargetRegisterClass("
|
|
<< RC.getName() + "RegClassID" << ", "
|
|
<< '\"' << RC.getName() << "\", "
|
|
<< RC.getName() + "VTs" << ", "
|
|
<< RC.getName() + "Subclasses" << ", "
|
|
<< RC.getName() + "Superclasses" << ", "
|
|
<< (NumSubRegIndices ? RC.getName() + "Sub" : std::string("Null"))
|
|
<< "RegClasses, "
|
|
<< (NumSubRegIndices ? RC.getName() + "Super" : std::string("Null"))
|
|
<< "RegClasses, "
|
|
<< RC.SpillSize/8 << ", "
|
|
<< RC.SpillAlignment/8 << ", "
|
|
<< RC.CopyCost << ", "
|
|
<< RC.getName() << ", " << RC.getName() << " + " << RC.Elements.size()
|
|
<< ") {}\n";
|
|
}
|
|
|
|
OS << "}\n";
|
|
}
|
|
|
|
OS << "\nnamespace {\n";
|
|
OS << " const TargetRegisterClass* const RegisterClasses[] = {\n";
|
|
for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i)
|
|
OS << " &" << getQualifiedName(RegisterClasses[i].TheDef)
|
|
<< "RegClass,\n";
|
|
OS << " };\n";
|
|
|
|
// Emit register sub-registers / super-registers, aliases...
|
|
std::map<Record*, std::set<Record*>, LessRecord> RegisterSubRegs;
|
|
std::map<Record*, std::set<Record*>, LessRecord> RegisterSuperRegs;
|
|
std::map<Record*, std::set<Record*>, LessRecord> RegisterAliases;
|
|
typedef std::map<Record*, std::vector<int64_t>, LessRecord> DwarfRegNumsMapTy;
|
|
DwarfRegNumsMapTy DwarfRegNums;
|
|
|
|
const std::vector<CodeGenRegister> &Regs = Target.getRegisters();
|
|
|
|
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
|
Record *R = Regs[i].TheDef;
|
|
std::vector<Record*> LI = Regs[i].TheDef->getValueAsListOfDefs("Aliases");
|
|
// Add information that R aliases all of the elements in the list... and
|
|
// that everything in the list aliases R.
|
|
for (unsigned j = 0, e = LI.size(); j != e; ++j) {
|
|
Record *Reg = LI[j];
|
|
if (RegisterAliases[R].count(Reg))
|
|
errs() << "Warning: register alias between " << getQualifiedName(R)
|
|
<< " and " << getQualifiedName(Reg)
|
|
<< " specified multiple times!\n";
|
|
RegisterAliases[R].insert(Reg);
|
|
|
|
if (RegisterAliases[Reg].count(R))
|
|
errs() << "Warning: register alias between " << getQualifiedName(R)
|
|
<< " and " << getQualifiedName(Reg)
|
|
<< " specified multiple times!\n";
|
|
RegisterAliases[Reg].insert(R);
|
|
}
|
|
}
|
|
|
|
// Process sub-register sets.
|
|
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
|
Record *R = Regs[i].TheDef;
|
|
std::vector<Record*> LI = Regs[i].TheDef->getValueAsListOfDefs("SubRegs");
|
|
// Process sub-register set and add aliases information.
|
|
for (unsigned j = 0, e = LI.size(); j != e; ++j) {
|
|
Record *SubReg = LI[j];
|
|
if (RegisterSubRegs[R].count(SubReg))
|
|
errs() << "Warning: register " << getQualifiedName(SubReg)
|
|
<< " specified as a sub-register of " << getQualifiedName(R)
|
|
<< " multiple times!\n";
|
|
addSubSuperReg(R, SubReg, RegisterSubRegs, RegisterSuperRegs,
|
|
RegisterAliases);
|
|
}
|
|
}
|
|
|
|
// Print the SubregHashTable, a simple quadratically probed
|
|
// hash table for determining if a register is a subregister
|
|
// of another register.
|
|
unsigned NumSubRegs = 0;
|
|
std::map<Record*, unsigned> RegNo;
|
|
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
|
RegNo[Regs[i].TheDef] = i;
|
|
NumSubRegs += RegisterSubRegs[Regs[i].TheDef].size();
|
|
}
|
|
|
|
unsigned SubregHashTableSize = 2 * NextPowerOf2(2 * NumSubRegs);
|
|
unsigned* SubregHashTable = new unsigned[2 * SubregHashTableSize];
|
|
std::fill(SubregHashTable, SubregHashTable + 2 * SubregHashTableSize, ~0U);
|
|
|
|
unsigned hashMisses = 0;
|
|
|
|
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
|
Record* R = Regs[i].TheDef;
|
|
for (std::set<Record*>::iterator I = RegisterSubRegs[R].begin(),
|
|
E = RegisterSubRegs[R].end(); I != E; ++I) {
|
|
Record* RJ = *I;
|
|
// We have to increase the indices of both registers by one when
|
|
// computing the hash because, in the generated code, there
|
|
// will be an extra empty slot at register 0.
|
|
size_t index = ((i+1) + (RegNo[RJ]+1) * 37) & (SubregHashTableSize-1);
|
|
unsigned ProbeAmt = 2;
|
|
while (SubregHashTable[index*2] != ~0U &&
|
|
SubregHashTable[index*2+1] != ~0U) {
|
|
index = (index + ProbeAmt) & (SubregHashTableSize-1);
|
|
ProbeAmt += 2;
|
|
|
|
hashMisses++;
|
|
}
|
|
|
|
SubregHashTable[index*2] = i;
|
|
SubregHashTable[index*2+1] = RegNo[RJ];
|
|
}
|
|
}
|
|
|
|
OS << "\n\n // Number of hash collisions: " << hashMisses << "\n";
|
|
|
|
if (SubregHashTableSize) {
|
|
std::string Namespace = Regs[0].TheDef->getValueAsString("Namespace");
|
|
|
|
OS << " const unsigned SubregHashTable[] = { ";
|
|
for (unsigned i = 0; i < SubregHashTableSize - 1; ++i) {
|
|
if (i != 0)
|
|
// Insert spaces for nice formatting.
|
|
OS << " ";
|
|
|
|
if (SubregHashTable[2*i] != ~0U) {
|
|
OS << getQualifiedName(Regs[SubregHashTable[2*i]].TheDef) << ", "
|
|
<< getQualifiedName(Regs[SubregHashTable[2*i+1]].TheDef) << ", \n";
|
|
} else {
|
|
OS << Namespace << "::NoRegister, " << Namespace << "::NoRegister, \n";
|
|
}
|
|
}
|
|
|
|
unsigned Idx = SubregHashTableSize*2-2;
|
|
if (SubregHashTable[Idx] != ~0U) {
|
|
OS << " "
|
|
<< getQualifiedName(Regs[SubregHashTable[Idx]].TheDef) << ", "
|
|
<< getQualifiedName(Regs[SubregHashTable[Idx+1]].TheDef) << " };\n";
|
|
} else {
|
|
OS << Namespace << "::NoRegister, " << Namespace << "::NoRegister };\n";
|
|
}
|
|
|
|
OS << " const unsigned SubregHashTableSize = "
|
|
<< SubregHashTableSize << ";\n";
|
|
} else {
|
|
OS << " const unsigned SubregHashTable[] = { ~0U, ~0U };\n"
|
|
<< " const unsigned SubregHashTableSize = 1;\n";
|
|
}
|
|
|
|
delete [] SubregHashTable;
|
|
|
|
|
|
// Print the AliasHashTable, a simple quadratically probed
|
|
// hash table for determining if a register aliases another register.
|
|
unsigned NumAliases = 0;
|
|
RegNo.clear();
|
|
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
|
RegNo[Regs[i].TheDef] = i;
|
|
NumAliases += RegisterAliases[Regs[i].TheDef].size();
|
|
}
|
|
|
|
unsigned AliasesHashTableSize = 2 * NextPowerOf2(2 * NumAliases);
|
|
unsigned* AliasesHashTable = new unsigned[2 * AliasesHashTableSize];
|
|
std::fill(AliasesHashTable, AliasesHashTable + 2 * AliasesHashTableSize, ~0U);
|
|
|
|
hashMisses = 0;
|
|
|
|
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
|
Record* R = Regs[i].TheDef;
|
|
for (std::set<Record*>::iterator I = RegisterAliases[R].begin(),
|
|
E = RegisterAliases[R].end(); I != E; ++I) {
|
|
Record* RJ = *I;
|
|
// We have to increase the indices of both registers by one when
|
|
// computing the hash because, in the generated code, there
|
|
// will be an extra empty slot at register 0.
|
|
size_t index = ((i+1) + (RegNo[RJ]+1) * 37) & (AliasesHashTableSize-1);
|
|
unsigned ProbeAmt = 2;
|
|
while (AliasesHashTable[index*2] != ~0U &&
|
|
AliasesHashTable[index*2+1] != ~0U) {
|
|
index = (index + ProbeAmt) & (AliasesHashTableSize-1);
|
|
ProbeAmt += 2;
|
|
|
|
hashMisses++;
|
|
}
|
|
|
|
AliasesHashTable[index*2] = i;
|
|
AliasesHashTable[index*2+1] = RegNo[RJ];
|
|
}
|
|
}
|
|
|
|
OS << "\n\n // Number of hash collisions: " << hashMisses << "\n";
|
|
|
|
if (AliasesHashTableSize) {
|
|
std::string Namespace = Regs[0].TheDef->getValueAsString("Namespace");
|
|
|
|
OS << " const unsigned AliasesHashTable[] = { ";
|
|
for (unsigned i = 0; i < AliasesHashTableSize - 1; ++i) {
|
|
if (i != 0)
|
|
// Insert spaces for nice formatting.
|
|
OS << " ";
|
|
|
|
if (AliasesHashTable[2*i] != ~0U) {
|
|
OS << getQualifiedName(Regs[AliasesHashTable[2*i]].TheDef) << ", "
|
|
<< getQualifiedName(Regs[AliasesHashTable[2*i+1]].TheDef) << ", \n";
|
|
} else {
|
|
OS << Namespace << "::NoRegister, " << Namespace << "::NoRegister, \n";
|
|
}
|
|
}
|
|
|
|
unsigned Idx = AliasesHashTableSize*2-2;
|
|
if (AliasesHashTable[Idx] != ~0U) {
|
|
OS << " "
|
|
<< getQualifiedName(Regs[AliasesHashTable[Idx]].TheDef) << ", "
|
|
<< getQualifiedName(Regs[AliasesHashTable[Idx+1]].TheDef) << " };\n";
|
|
} else {
|
|
OS << Namespace << "::NoRegister, " << Namespace << "::NoRegister };\n";
|
|
}
|
|
|
|
OS << " const unsigned AliasesHashTableSize = "
|
|
<< AliasesHashTableSize << ";\n";
|
|
} else {
|
|
OS << " const unsigned AliasesHashTable[] = { ~0U, ~0U };\n"
|
|
<< " const unsigned AliasesHashTableSize = 1;\n";
|
|
}
|
|
|
|
delete [] AliasesHashTable;
|
|
|
|
if (!RegisterAliases.empty())
|
|
OS << "\n\n // Register Overlap Lists...\n";
|
|
|
|
// Emit an overlap list for all registers.
|
|
for (std::map<Record*, std::set<Record*>, LessRecord >::iterator
|
|
I = RegisterAliases.begin(), E = RegisterAliases.end(); I != E; ++I) {
|
|
OS << " const unsigned " << I->first->getName() << "_Overlaps[] = { "
|
|
<< getQualifiedName(I->first) << ", ";
|
|
for (std::set<Record*>::iterator ASI = I->second.begin(),
|
|
E = I->second.end(); ASI != E; ++ASI)
|
|
OS << getQualifiedName(*ASI) << ", ";
|
|
OS << "0 };\n";
|
|
}
|
|
|
|
if (!RegisterSubRegs.empty())
|
|
OS << "\n\n // Register Sub-registers Sets...\n";
|
|
|
|
// Emit the empty sub-registers list
|
|
OS << " const unsigned Empty_SubRegsSet[] = { 0 };\n";
|
|
// Loop over all of the registers which have sub-registers, emitting the
|
|
// sub-registers list to memory.
|
|
for (std::map<Record*, std::set<Record*>, LessRecord>::iterator
|
|
I = RegisterSubRegs.begin(), E = RegisterSubRegs.end(); I != E; ++I) {
|
|
if (I->second.empty())
|
|
continue;
|
|
OS << " const unsigned " << I->first->getName() << "_SubRegsSet[] = { ";
|
|
std::vector<Record*> SubRegsVector;
|
|
for (std::set<Record*>::iterator ASI = I->second.begin(),
|
|
E = I->second.end(); ASI != E; ++ASI)
|
|
SubRegsVector.push_back(*ASI);
|
|
RegisterSorter RS(RegisterSubRegs);
|
|
std::stable_sort(SubRegsVector.begin(), SubRegsVector.end(), RS);
|
|
for (unsigned i = 0, e = SubRegsVector.size(); i != e; ++i)
|
|
OS << getQualifiedName(SubRegsVector[i]) << ", ";
|
|
OS << "0 };\n";
|
|
}
|
|
|
|
if (!RegisterSuperRegs.empty())
|
|
OS << "\n\n // Register Super-registers Sets...\n";
|
|
|
|
// Emit the empty super-registers list
|
|
OS << " const unsigned Empty_SuperRegsSet[] = { 0 };\n";
|
|
// Loop over all of the registers which have super-registers, emitting the
|
|
// super-registers list to memory.
|
|
for (std::map<Record*, std::set<Record*>, LessRecord >::iterator
|
|
I = RegisterSuperRegs.begin(), E = RegisterSuperRegs.end(); I != E; ++I) {
|
|
if (I->second.empty())
|
|
continue;
|
|
OS << " const unsigned " << I->first->getName() << "_SuperRegsSet[] = { ";
|
|
|
|
std::vector<Record*> SuperRegsVector;
|
|
for (std::set<Record*>::iterator ASI = I->second.begin(),
|
|
E = I->second.end(); ASI != E; ++ASI)
|
|
SuperRegsVector.push_back(*ASI);
|
|
RegisterSorter RS(RegisterSubRegs);
|
|
std::stable_sort(SuperRegsVector.begin(), SuperRegsVector.end(), RS);
|
|
for (unsigned i = 0, e = SuperRegsVector.size(); i != e; ++i)
|
|
OS << getQualifiedName(SuperRegsVector[i]) << ", ";
|
|
OS << "0 };\n";
|
|
}
|
|
|
|
OS<<"\n const TargetRegisterDesc RegisterDescriptors[] = { // Descriptors\n";
|
|
OS << " { \"NOREG\",\t0,\t0,\t0 },\n";
|
|
|
|
// Now that register alias and sub-registers sets have been emitted, emit the
|
|
// register descriptors now.
|
|
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
|
const CodeGenRegister &Reg = Regs[i];
|
|
OS << " { \"";
|
|
OS << Reg.getName() << "\",\t" << Reg.getName() << "_Overlaps,\t";
|
|
if (!RegisterSubRegs[Reg.TheDef].empty())
|
|
OS << Reg.getName() << "_SubRegsSet,\t";
|
|
else
|
|
OS << "Empty_SubRegsSet,\t";
|
|
if (!RegisterSuperRegs[Reg.TheDef].empty())
|
|
OS << Reg.getName() << "_SuperRegsSet },\n";
|
|
else
|
|
OS << "Empty_SuperRegsSet },\n";
|
|
}
|
|
OS << " };\n"; // End of register descriptors...
|
|
|
|
// Emit SubRegIndex names, skipping 0
|
|
const std::vector<Record*> SubRegIndices = Target.getSubRegIndices();
|
|
OS << "\n const char *const SubRegIndexTable[] = { \"";
|
|
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
|
|
OS << SubRegIndices[i]->getName();
|
|
if (i+1 != e)
|
|
OS << "\", \"";
|
|
}
|
|
OS << "\" };\n\n";
|
|
OS << "}\n\n"; // End of anonymous namespace...
|
|
|
|
std::string ClassName = Target.getName() + "GenRegisterInfo";
|
|
|
|
// Calculate the mapping of subregister+index pairs to physical registers.
|
|
RegisterMaps RegMaps;
|
|
|
|
// Emit the subregister + index mapping function based on the information
|
|
// calculated above.
|
|
OS << "unsigned " << ClassName
|
|
<< "::getSubReg(unsigned RegNo, unsigned Index) const {\n"
|
|
<< " switch (RegNo) {\n"
|
|
<< " default:\n return 0;\n";
|
|
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
|
RegisterMaps::SubRegMap &SRM = RegMaps.inferSubRegIndices(Regs[i].TheDef);
|
|
if (SRM.empty())
|
|
continue;
|
|
OS << " case " << getQualifiedName(Regs[i].TheDef) << ":\n";
|
|
OS << " switch (Index) {\n";
|
|
OS << " default: return 0;\n";
|
|
for (RegisterMaps::SubRegMap::const_iterator ii = SRM.begin(),
|
|
ie = SRM.end(); ii != ie; ++ii)
|
|
OS << " case " << getQualifiedName(ii->first)
|
|
<< ": return " << getQualifiedName(ii->second) << ";\n";
|
|
OS << " };\n" << " break;\n";
|
|
}
|
|
OS << " };\n";
|
|
OS << " return 0;\n";
|
|
OS << "}\n\n";
|
|
|
|
OS << "unsigned " << ClassName
|
|
<< "::getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const {\n"
|
|
<< " switch (RegNo) {\n"
|
|
<< " default:\n return 0;\n";
|
|
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
|
RegisterMaps::SubRegMap &SRM = RegMaps.SubReg[Regs[i].TheDef];
|
|
if (SRM.empty())
|
|
continue;
|
|
OS << " case " << getQualifiedName(Regs[i].TheDef) << ":\n";
|
|
for (RegisterMaps::SubRegMap::const_iterator ii = SRM.begin(),
|
|
ie = SRM.end(); ii != ie; ++ii)
|
|
OS << " if (SubRegNo == " << getQualifiedName(ii->second)
|
|
<< ") return " << getQualifiedName(ii->first) << ";\n";
|
|
OS << " return 0;\n";
|
|
}
|
|
OS << " };\n";
|
|
OS << " return 0;\n";
|
|
OS << "}\n\n";
|
|
|
|
// Emit composeSubRegIndices
|
|
RegMaps.computeComposites();
|
|
OS << "unsigned " << ClassName
|
|
<< "::composeSubRegIndices(unsigned IdxA, unsigned IdxB) const {\n"
|
|
<< " switch (IdxA) {\n"
|
|
<< " default:\n return IdxB;\n";
|
|
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
|
|
bool Open = false;
|
|
for (unsigned j = 0; j != e; ++j) {
|
|
if (Record *Comp = RegMaps.Composite.lookup(
|
|
std::make_pair(SubRegIndices[i], SubRegIndices[j]))) {
|
|
if (!Open) {
|
|
OS << " case " << getQualifiedName(SubRegIndices[i])
|
|
<< ": switch(IdxB) {\n default: return IdxB;\n";
|
|
Open = true;
|
|
}
|
|
OS << " case " << getQualifiedName(SubRegIndices[j])
|
|
<< ": return " << getQualifiedName(Comp) << ";\n";
|
|
}
|
|
}
|
|
if (Open)
|
|
OS << " }\n";
|
|
}
|
|
OS << " }\n}\n\n";
|
|
|
|
// Emit the constructor of the class...
|
|
OS << ClassName << "::" << ClassName
|
|
<< "(int CallFrameSetupOpcode, int CallFrameDestroyOpcode)\n"
|
|
<< " : TargetRegisterInfo(RegisterDescriptors, " << Regs.size()+1
|
|
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
|
|
<< " SubRegIndexTable,\n"
|
|
<< " CallFrameSetupOpcode, CallFrameDestroyOpcode,\n"
|
|
<< " SubregHashTable, SubregHashTableSize,\n"
|
|
<< " AliasesHashTable, AliasesHashTableSize) {\n"
|
|
<< "}\n\n";
|
|
|
|
// Collect all information about dwarf register numbers
|
|
|
|
// First, just pull all provided information to the map
|
|
unsigned maxLength = 0;
|
|
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
|
Record *Reg = Regs[i].TheDef;
|
|
std::vector<int64_t> RegNums = Reg->getValueAsListOfInts("DwarfNumbers");
|
|
maxLength = std::max((size_t)maxLength, RegNums.size());
|
|
if (DwarfRegNums.count(Reg))
|
|
errs() << "Warning: DWARF numbers for register " << getQualifiedName(Reg)
|
|
<< "specified multiple times\n";
|
|
DwarfRegNums[Reg] = RegNums;
|
|
}
|
|
|
|
// Now we know maximal length of number list. Append -1's, where needed
|
|
for (DwarfRegNumsMapTy::iterator
|
|
I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I)
|
|
for (unsigned i = I->second.size(), e = maxLength; i != e; ++i)
|
|
I->second.push_back(-1);
|
|
|
|
// Emit information about the dwarf register numbers.
|
|
OS << "int " << ClassName << "::getDwarfRegNumFull(unsigned RegNum, "
|
|
<< "unsigned Flavour) const {\n"
|
|
<< " switch (Flavour) {\n"
|
|
<< " default:\n"
|
|
<< " assert(0 && \"Unknown DWARF flavour\");\n"
|
|
<< " return -1;\n";
|
|
|
|
for (unsigned i = 0, e = maxLength; i != e; ++i) {
|
|
OS << " case " << i << ":\n"
|
|
<< " switch (RegNum) {\n"
|
|
<< " default:\n"
|
|
<< " assert(0 && \"Invalid RegNum\");\n"
|
|
<< " return -1;\n";
|
|
|
|
// Sort by name to get a stable order.
|
|
|
|
|
|
for (DwarfRegNumsMapTy::iterator
|
|
I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
|
|
int RegNo = I->second[i];
|
|
if (RegNo != -2)
|
|
OS << " case " << getQualifiedName(I->first) << ":\n"
|
|
<< " return " << RegNo << ";\n";
|
|
else
|
|
OS << " case " << getQualifiedName(I->first) << ":\n"
|
|
<< " assert(0 && \"Invalid register for this mode\");\n"
|
|
<< " return -1;\n";
|
|
}
|
|
OS << " };\n";
|
|
}
|
|
|
|
OS << " };\n}\n\n";
|
|
|
|
OS << "} // End llvm namespace \n";
|
|
}
|