//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
OS << "struct " << ClassName << " : public MRegisterInfo {\n"
<< " " << ClassName
<< "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n"
- << " int getDwarfRegNum(unsigned RegNum) const;\n"
+ << " virtual int getDwarfRegNumFull(unsigned RegNum, "
+ << "unsigned Flavour) const;\n"
+ << " virtual int getDwarfRegNum(unsigned RegNum, bool isEH) const = 0;\n"
<< " unsigned getSubReg(unsigned RegNo, unsigned Index) const;\n"
<< "};\n\n";
static void addSuperReg(Record *R, Record *S,
std::map<Record*, std::set<Record*> > &SubRegs,
std::map<Record*, std::set<Record*> > &SuperRegs,
- std::map<Record*, std::set<Record*> > &Aliases,
- RegisterInfoEmitter &RIE) {
+ std::map<Record*, std::set<Record*> > &Aliases) {
if (R == S) {
cerr << "Error: recursive sub-register relationship between"
- << " register " << RIE.getQualifiedName(R)
+ << " register " << getQualifiedName(R)
<< " and its sub-registers?\n";
abort();
}
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, RIE);
+ addSuperReg(R, *I, SubRegs, SuperRegs, Aliases);
}
static void addSubSuperReg(Record *R, Record *S,
std::map<Record*, std::set<Record*> > &SubRegs,
std::map<Record*, std::set<Record*> > &SuperRegs,
- std::map<Record*, std::set<Record*> > &Aliases,
- RegisterInfoEmitter &RIE) {
+ std::map<Record*, std::set<Record*> > &Aliases) {
if (R == S) {
cerr << "Error: recursive sub-register relationship between"
- << " register " << RIE.getQualifiedName(R)
+ << " register " << getQualifiedName(R)
<< " and its sub-registers?\n";
abort();
}
if (!SubRegs[R].insert(S).second)
return;
- addSuperReg(S, R, SubRegs, SuperRegs, Aliases, RIE);
+ 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, RIE);
+ addSubSuperReg(R, *I, SubRegs, SuperRegs, Aliases);
}
// RegisterInfoEmitter::run - Main register file description emitter.
<< " static const MVT::ValueType " << Name
<< "[] = {\n ";
for (unsigned i = 0, e = RC.VTs.size(); i != e; ++i)
- OS << getName(RC.VTs[i]) << ", ";
+ OS << getEnumName(RC.VTs[i]) << ", ";
OS << "MVT::Other\n };\n\n";
}
OS << "} // end anonymous namespace\n\n";
<< RegisterClasses[i].getName() << "RegClass;\n";
std::map<unsigned, std::set<unsigned> > SuperClassMap;
+ std::map<unsigned, std::set<unsigned> > SuperRegClassMap;
OS << "\n";
-
// Emit the sub-register classes for each RegisterClass
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
const CodeGenRegisterClass &RC = RegisterClasses[rc];
bool Empty = true;
- for (unsigned subrc = 0, e2 = RC.SubRegClasses.size();
- subrc != e2; ++subrc) {
+ for (unsigned subrc = 0, subrcMax = RC.SubRegClasses.size();
+ subrc != subrcMax; ++subrc) {
unsigned rc2 = 0, e2 = RegisterClasses.size();
for (; rc2 != e2; ++rc2) {
const CodeGenRegisterClass &RC2 = RegisterClasses[rc2];
if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) {
- if (!Empty) OS << ", ";
- OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
+ if (!Empty)
+ OS << ", ";
+ OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
Empty = false;
+
+ std::map<unsigned, std::set<unsigned> >::iterator SCMI =
+ SuperRegClassMap.find(rc2);
+ if (SCMI == SuperRegClassMap.end()) {
+ SuperRegClassMap.insert(std::make_pair(rc2, std::set<unsigned>()));
+ SCMI = SuperRegClassMap.find(rc2);
+ }
+ SCMI->second.insert(rc);
break;
}
}
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 Classess...\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";
+ }
+
// Emit the sub-classes array for each RegisterClass
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
const CodeGenRegisterClass &RC = RegisterClasses[rc];
<< RC.getName() + "Subclasses" << ", "
<< RC.getName() + "Superclasses" << ", "
<< RC.getName() + "SubRegClasses" << ", "
+ << RC.getName() + "SuperRegClasses" << ", "
<< RC.SpillSize/8 << ", "
- << RC.SpillAlignment/8 << ", " << RC.getName() << ", "
- << RC.getName() << " + " << RC.Elements.size() << ") {}\n";
+ << RC.SpillAlignment/8 << ", "
+ << RC.CopyCost << ", "
+ << RC.getName() << ", " << RC.getName() << " + " << RC.Elements.size()
+ << ") {}\n";
}
OS << "}\n";
std::map<Record*, std::set<Record*> > RegisterSuperRegs;
std::map<Record*, std::set<Record*> > RegisterAliases;
std::map<Record*, std::vector<std::pair<int, Record*> > > SubRegVectors;
+ std::map<Record*, std::vector<int> > DwarfRegNums;
+
const std::vector<CodeGenRegister> &Regs = Target.getRegisters();
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
<< " multiple times!\n";
RegisterImmSubRegs[R].insert(SubReg);
addSubSuperReg(R, SubReg, RegisterSubRegs, RegisterSuperRegs,
- RegisterAliases, *this);
+ RegisterAliases);
}
}
}
OS<<"\n const TargetRegisterDesc RegisterDescriptors[] = { // Descriptors\n";
- OS << " { \"NOREG\",\t0,\t0,\t0 },\n";
+ OS << " { \"NOREG\",\t0,\t0,\t0,\t0 },\n";
// Now that register alias and sub-registers sets have been emitted, emit the
// register descriptors now.
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n "
<< " CallFrameSetupOpcode, CallFrameDestroyOpcode) {}\n\n";
- // Emit information about the dwarf register numbers.
- OS << "int " << ClassName << "::getDwarfRegNum(unsigned RegNum) const {\n";
- OS << " static const int DwarfRegNums[] = { -1, // NoRegister";
+ // Collect all information about dwarf register numbers
+
+ // First, just pull all provided information to the map
+ unsigned maxLength = 0;
for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
- if (!(i % 16)) OS << "\n ";
- const CodeGenRegister &Reg = Registers[i];
- int DwarfRegNum = Reg.TheDef->getValueAsInt("DwarfNumber");
- OS << DwarfRegNum;
- if ((i + 1) != e) OS << ", ";
+ Record *Reg = Registers[i].TheDef;
+ std::vector<int> RegNums = Reg->getValueAsListOfInts("DwarfNumbers");
+ maxLength = std::max((size_t)maxLength, RegNums.size());
+ if (DwarfRegNums.count(Reg))
+ cerr << "Warning: DWARF numbers for register " << getQualifiedName(Reg)
+ << "specified multiple times\n";
+ DwarfRegNums[Reg] = RegNums;
}
- OS << "\n };\n";
- OS << " assert(RegNum < (sizeof(DwarfRegNums)/sizeof(int)) &&\n";
- OS << " \"RegNum exceeds number of registers\");\n";
- OS << " return DwarfRegNums[RegNum];\n";
- OS << "}\n\n";
+
+ // Now we know maximal length of number list. Append -1's, where needed
+ for (std::map<Record*, std::vector<int> >::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";
+
+ for (std::map<Record*, std::vector<int> >::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";
}