//
// 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 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];
+
+ // Give the register class a legal C name if it's anonymous.
+ std::string Name = RC.TheDef->getName();
+
+ OS << " // " << Name
+ << " Sub-register Classess...\n"
+ << " static const TargetRegisterClass* const "
+ << Name << "SubRegClasses [] = {\n ";
+
+ bool Empty = true;
+
+ 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";
+ 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;
+ }
+ }
+ if (rc2 == e2)
+ throw "Register Class member '" +
+ RC.SubRegClasses[subrc]->getName() +
+ "' is not a valid RegisterClass!";
+ }
+
+ OS << (!Empty ? ", " : "") << "NULL";
+ 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() + "VTs" << ", "
<< 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";
OS << " };\n";
// Emit register sub-registers / super-registers, aliases...
+ std::map<Record*, std::set<Record*> > RegisterImmSubRegs;
std::map<Record*, std::set<Record*> > RegisterSubRegs;
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) {
cerr << "Warning: register " << getQualifiedName(SubReg)
<< " specified as a sub-register of " << getQualifiedName(R)
<< " multiple times!\n";
+ RegisterImmSubRegs[R].insert(SubReg);
addSubSuperReg(R, SubReg, RegisterSubRegs, RegisterSuperRegs,
RegisterAliases, *this);
}
OS << "0 };\n";
}
+ if (!RegisterImmSubRegs.empty())
+ OS << "\n\n // Register Immediate Sub-registers Sets...\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*> >::iterator
+ I = RegisterImmSubRegs.begin(), E = RegisterImmSubRegs.end();
+ I != E; ++I) {
+ OS << " const unsigned " << I->first->getName() << "_ImmSubRegsSet[] = { ";
+ for (std::set<Record*>::iterator ASI = I->second.begin(),
+ E = I->second.end(); ASI != E; ++ASI)
+ OS << getQualifiedName(*ASI) << ", ";
+ OS << "0 };\n";
+ }
+
if (!RegisterSuperRegs.empty())
OS << "\n\n // Register Super-registers Sets...\n";
}
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.
OS << Reg.getName() << "_SubRegsSet,\t";
else
OS << "Empty_SubRegsSet,\t";
+ if (RegisterImmSubRegs.count(Reg.TheDef))
+ OS << Reg.getName() << "_ImmSubRegsSet,\t";
+ else
+ OS << "Empty_SubRegsSet,\t";
if (RegisterSuperRegs.count(Reg.TheDef))
OS << Reg.getName() << "_SuperRegsSet },\n";
else
OS << " }; break;\n";
}
OS << " };\n";
+ OS << " return 0;\n";
OS << "}\n\n";
// Emit the constructor of the class...
<< ", 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";
}