aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp185
-rw-r--r--utils/TableGen/RegisterInfoEmitter.h3
-rw-r--r--utils/TableGen/TableGen.cpp20
3 files changed, 130 insertions, 78 deletions
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 991f34c1b9..997f1c0b73 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -79,7 +79,8 @@ void RegisterInfoEmitter::runHeader(raw_ostream &OS) {
OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
<< " explicit " << ClassName
- << "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n"
+ << "(const TargetRegisterDesc *D, const TargetRegisterInfoDesc *ID, "
+ << "int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n"
<< " virtual int getDwarfRegNumFull(unsigned RegNum, "
<< "unsigned Flavour) const;\n"
<< " virtual int getLLVMRegNumFull(unsigned DwarfRegNum, "
@@ -140,8 +141,6 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
CodeGenTarget Target(Records);
CodeGenRegBank &RegBank = Target.getRegBank();
RegBank.computeDerivedInfo();
- std::map<const CodeGenRegister*, CodeGenRegister::Set> Overlaps;
- RegBank.computeOverlaps(Overlaps);
EmitSourceFileHeader("Register Information Source Fragment", OS);
@@ -407,78 +406,22 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
<< "RegClass,\n";
OS << " };\n";
- typedef std::map<Record*, std::vector<int64_t>, LessRecord> DwarfRegNumsMapTy;
- DwarfRegNumsMapTy DwarfRegNums;
- const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();
-
- // Emit an overlap list for all registers.
- for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
- const CodeGenRegister *Reg = Regs[i];
- const CodeGenRegister::Set &O = Overlaps[Reg];
- // Move Reg to the front so TRI::getAliasSet can share the list.
- OS << " const unsigned " << Reg->getName() << "_Overlaps[] = { "
- << getQualifiedName(Reg->TheDef) << ", ";
- for (CodeGenRegister::Set::const_iterator I = O.begin(), E = O.end();
- I != E; ++I)
- if (*I != Reg)
- OS << getQualifiedName((*I)->TheDef) << ", ";
- OS << "0 };\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 (unsigned i = 0, e = Regs.size(); i != e; ++i) {
- const CodeGenRegister &Reg = *Regs[i];
- if (Reg.getSubRegs().empty())
- continue;
- // getSubRegs() orders by SubRegIndex. We want a topological order.
- SetVector<CodeGenRegister*> SR;
- Reg.addSubRegsPreOrder(SR);
- OS << " const unsigned " << Reg.getName() << "_SubRegsSet[] = { ";
- for (unsigned j = 0, je = SR.size(); j != je; ++j)
- OS << getQualifiedName(SR[j]->TheDef) << ", ";
- OS << "0 };\n";
- }
+ // Emit extra information about registers.
+ OS << "\n static const TargetRegisterInfoDesc "
+ << Target.getName() << "RegInfoDesc[] = "
+ << "{ // Extra Descriptors\n";
+ OS << " { 0, 0 },\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 (unsigned i = 0, e = Regs.size(); i != e; ++i) {
- const CodeGenRegister &Reg = *Regs[i];
- const CodeGenRegister::SuperRegList &SR = Reg.getSuperRegs();
- if (SR.empty())
- continue;
- OS << " const unsigned " << Reg.getName() << "_SuperRegsSet[] = { ";
- for (unsigned j = 0, je = SR.size(); j != je; ++j)
- OS << getQualifiedName(SR[j]->TheDef) << ", ";
- OS << "0 };\n";
- }
-
- OS<<"\n const TargetRegisterDesc RegisterDescriptors[] = { // Descriptors\n";
- OS << " { \"NOREG\",\t0,\t0,\t0,\t0,\t0 },\n";
-
- // Now that register alias and sub-registers sets have been emitted, emit the
- // register descriptors now.
+ const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();
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 (!Reg.getSubRegs().empty())
- OS << Reg.getName() << "_SubRegsSet,\t";
- else
- OS << "Empty_SubRegsSet,\t";
- if (!Reg.getSuperRegs().empty())
- OS << Reg.getName() << "_SuperRegsSet,\t";
- else
- OS << "Empty_SuperRegsSet,\t";
- OS << Reg.CostPerUse << ",\t"
+ OS << " { ";
+ OS << Reg.CostPerUse << ", "
<< int(AllocatableRegs.count(Reg.TheDef)) << " },\n";
}
OS << " };\n"; // End of register descriptors...
+
// Calculate the mapping of subregister+index pairs to physical registers.
// This will also create further anonymous indexes.
unsigned NamedIndices = RegBank.getNumNamedIndices();
@@ -575,14 +518,18 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
// Emit the constructor of the class...
OS << ClassName << "::" << ClassName
- << "(int CallFrameSetupOpcode, int CallFrameDestroyOpcode)\n"
- << " : TargetRegisterInfo(RegisterDescriptors, " << Regs.size()+1
+ << "(const TargetRegisterDesc *D, const TargetRegisterInfoDesc *ID, "
+ << "int CallFrameSetupOpcode, int CallFrameDestroyOpcode)\n"
+ << " : TargetRegisterInfo(ID"
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
<< " SubRegIndexTable,\n"
<< " CallFrameSetupOpcode, CallFrameDestroyOpcode) {\n"
+ << " InitMCRegisterInfo(D, " << Regs.size()+1 << ");\n"
<< "}\n\n";
// Collect all information about dwarf register numbers
+ typedef std::map<Record*, std::vector<int64_t>, LessRecord> DwarfRegNumsMapTy;
+ DwarfRegNumsMapTy DwarfRegNums;
// First, just pull all provided information to the map
unsigned maxLength = 0;
@@ -671,3 +618,101 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
OS << "} // End llvm namespace \n";
}
+
+void RegisterInfoEmitter::runDesc(raw_ostream &OS) {
+ CodeGenTarget Target(Records);
+ CodeGenRegBank &RegBank = Target.getRegBank();
+ RegBank.computeDerivedInfo();
+ std::map<const CodeGenRegister*, CodeGenRegister::Set> Overlaps;
+ RegBank.computeOverlaps(Overlaps);
+
+ OS << "namespace llvm {\n\n";
+
+ const std::string &TargetName = Target.getName();
+ std::string ClassName = TargetName + "GenMCRegisterInfo";
+ OS << "struct " << ClassName << " : public MCRegisterInfo {\n"
+ << " explicit " << ClassName << "(const TargetRegisterDesc *D);\n";
+ OS << "};\n";
+
+ OS << "\nnamespace {\n";
+
+ const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();
+
+ // Emit an overlap list for all registers.
+ for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+ const CodeGenRegister *Reg = Regs[i];
+ const CodeGenRegister::Set &O = Overlaps[Reg];
+ // Move Reg to the front so TRI::getAliasSet can share the list.
+ OS << " const unsigned " << Reg->getName() << "_Overlaps[] = { "
+ << getQualifiedName(Reg->TheDef) << ", ";
+ for (CodeGenRegister::Set::const_iterator I = O.begin(), E = O.end();
+ I != E; ++I)
+ if (*I != Reg)
+ OS << getQualifiedName((*I)->TheDef) << ", ";
+ OS << "0 };\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 (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+ const CodeGenRegister &Reg = *Regs[i];
+ if (Reg.getSubRegs().empty())
+ continue;
+ // getSubRegs() orders by SubRegIndex. We want a topological order.
+ SetVector<CodeGenRegister*> SR;
+ Reg.addSubRegsPreOrder(SR);
+ OS << " const unsigned " << Reg.getName() << "_SubRegsSet[] = { ";
+ for (unsigned j = 0, je = SR.size(); j != je; ++j)
+ OS << getQualifiedName(SR[j]->TheDef) << ", ";
+ OS << "0 };\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 (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+ const CodeGenRegister &Reg = *Regs[i];
+ const CodeGenRegister::SuperRegList &SR = Reg.getSuperRegs();
+ if (SR.empty())
+ continue;
+ OS << " const unsigned " << Reg.getName() << "_SuperRegsSet[] = { ";
+ for (unsigned j = 0, je = SR.size(); j != je; ++j)
+ OS << getQualifiedName(SR[j]->TheDef) << ", ";
+ OS << "0 };\n";
+ }
+
+ OS << "\n const TargetRegisterDesc " << TargetName
+ << "RegDesc[] = { // 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 (!Reg.getSubRegs().empty())
+ OS << Reg.getName() << "_SubRegsSet,\t";
+ else
+ OS << "Empty_SubRegsSet,\t";
+ if (!Reg.getSuperRegs().empty())
+ OS << Reg.getName() << "_SuperRegsSet";
+ else
+ OS << "Empty_SuperRegsSet";
+ OS << " },\n";
+ }
+ OS << " };\n"; // End of register descriptors...
+
+ OS << "}\n\n"; // End of anonymous namespace...
+
+ // MCRegisterInfo initialization routine.
+ OS << "void " << "Init" << TargetName
+ << "MCRegisterInfo(MCRegisterInfo *RI) {\n";
+ OS << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
+ << Regs.size()+1 << ");\n}\n\n";
+
+ OS << "} // End llvm namespace \n";
+}
diff --git a/utils/TableGen/RegisterInfoEmitter.h b/utils/TableGen/RegisterInfoEmitter.h
index 1456b4f1ec..6bf14b259a 100644
--- a/utils/TableGen/RegisterInfoEmitter.h
+++ b/utils/TableGen/RegisterInfoEmitter.h
@@ -33,6 +33,9 @@ public:
// runEnums - Print out enum values for all of the registers.
void runEnums(raw_ostream &o);
+
+ // runDesc - Print out register descriptions.
+ void runDesc(raw_ostream &o);
};
} // End llvm namespace
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index 39fe9934cd..b11ef6f698 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -54,7 +54,7 @@ using namespace llvm;
enum ActionType {
PrintRecords,
GenEmitter,
- GenRegisterEnums, GenRegister, GenRegisterHeader,
+ GenRegisterEnums, GenRegisterDesc, GenRegisterInfo, GenRegisterInfoHeader,
GenInstrEnums, GenInstrs, GenAsmWriter, GenAsmMatcher,
GenARMDecoder,
GenDisassembler,
@@ -95,10 +95,12 @@ namespace {
"Generate machine code emitter"),
clEnumValN(GenRegisterEnums, "gen-register-enums",
"Generate enum values for registers"),
- clEnumValN(GenRegister, "gen-register-desc",
- "Generate a register info description"),
- clEnumValN(GenRegisterHeader, "gen-register-desc-header",
- "Generate a register info description header"),
+ clEnumValN(GenRegisterDesc, "gen-register-desc",
+ "Generate register descriptions"),
+ clEnumValN(GenRegisterInfo, "gen-register-info",
+ "Generate registers & reg-classes info"),
+ clEnumValN(GenRegisterInfoHeader, "gen-register-info-header",
+ "Generate registers & reg-classes info header"),
clEnumValN(GenInstrEnums, "gen-instr-enums",
"Generate enum values for instructions"),
clEnumValN(GenInstrs, "gen-instr-desc",
@@ -261,14 +263,16 @@ int main(int argc, char **argv) {
case GenEmitter:
CodeEmitterGen(Records).run(Out.os());
break;
-
case GenRegisterEnums:
RegisterInfoEmitter(Records).runEnums(Out.os());
break;
- case GenRegister:
+ case GenRegisterDesc:
+ RegisterInfoEmitter(Records).runDesc(Out.os());
+ break;
+ case GenRegisterInfo:
RegisterInfoEmitter(Records).run(Out.os());
break;
- case GenRegisterHeader:
+ case GenRegisterInfoHeader:
RegisterInfoEmitter(Records).runHeader(Out.os());
break;
case GenInstrEnums: