Add and use a new method
[oota-llvm.git] / support / tools / TableGen / RegisterInfoEmitter.cpp
index 043fb3b5bebd20ff33492ba5b4e49a2749cff60a..9ef5f020a28890428fc92372d4df6ef9a1b843d1 100644 (file)
@@ -7,17 +7,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "RegisterInfoEmitter.h"
+#include "CodeGenWrappers.h"
 #include "Record.h"
 #include "Support/StringExtras.h"
 #include <set>
 
-static void EmitSourceHeader(const std::string &Desc, std::ostream &o) {
-  o << "//===- TableGen'erated file -------------------------------------*-"
-       " C++ -*-===//\n//\n// " << Desc << "\n//\n// Automatically generate"
-       "d file, do not edit!\n//\n//===------------------------------------"
-       "----------------------------------===//\n\n";
-}
-
 // runEnums - Print out enum values for all of the registers.
 void RegisterInfoEmitter::runEnums(std::ostream &OS) {
   std::vector<Record*> Registers = Records.getAllDerivedDefinitions("Register");
@@ -27,7 +21,7 @@ void RegisterInfoEmitter::runEnums(std::ostream &OS) {
 
   std::string Namespace = Registers[0]->getValueAsString("Namespace");
 
-  EmitSourceHeader("Target Register Enum Values", OS);
+  EmitSourceFileHeader("Target Register Enum Values", OS);
 
   if (!Namespace.empty())
     OS << "namespace " << Namespace << " {\n";
@@ -41,24 +35,10 @@ void RegisterInfoEmitter::runEnums(std::ostream &OS) {
     OS << "}\n";
 }
 
-static Record *getTarget(RecordKeeper &RC) {
-  std::vector<Record*> Targets = RC.getAllDerivedDefinitions("Target");
-
-  if (Targets.size() != 1)
-    throw std::string("ERROR: Multiple subclasses of Target defined!");
-  return Targets[0];
-}
-
-static std::string getQualifiedName(Record *R) {
-  std::string Namespace = R->getValueAsString("Namespace");
-  if (Namespace.empty()) return R->getName();
-  return Namespace + "::" + R->getName();
-}
-
 void RegisterInfoEmitter::runHeader(std::ostream &OS) {
-  EmitSourceHeader("Register Information Header Fragment", OS);
-  
-  std::string ClassName = getTarget(Records)->getName() + "GenRegisterInfo";
+  EmitSourceFileHeader("Register Information Header Fragment", OS);
+  const std::string &TargetName = CodeGenTarget().getName();
+  std::string ClassName = TargetName + "GenRegisterInfo";
 
   OS << "#include \"llvm/Target/MRegisterInfo.h\"\n\n";
 
@@ -67,12 +47,23 @@ void RegisterInfoEmitter::runHeader(std::ostream &OS) {
      << "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n"
      << "  const unsigned* getCalleeSaveRegs() const;\n"
      << "};\n\n";
+
+  std::vector<Record*> RegisterClasses =
+    Records.getAllDerivedDefinitions("RegisterClass");
+
+  OS << "namespace " << TargetName << " { // Register classes\n";
+  for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
+    const std::string &Name = RegisterClasses[i]->getName();
+    if (Name.size() < 9 || Name[9] != '.')    // Ignore anonymous classes
+      OS << "  extern TargetRegisterClass *" << Name << "RegisterClass;\n";
+  }
+  OS << "} // end of namespace " << TargetName << "\n\n";
 }
 
 // RegisterInfoEmitter::run - Main register file description emitter.
 //
 void RegisterInfoEmitter::run(std::ostream &OS) {
-  EmitSourceHeader("Register Information Source Fragment", OS);
+  EmitSourceFileHeader("Register Information Source Fragment", OS);
 
   // 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
@@ -82,7 +73,6 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
     Records.getAllDerivedDefinitions("RegisterClass");
 
   std::vector<Record*> Registers = Records.getAllDerivedDefinitions("Register");
-  Record *RegisterClass = Records.getClass("Register");
 
   std::set<Record*> RegistersFound;
   std::vector<std::string> RegClassNames;
@@ -108,7 +98,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
       DefInit *RegDef = dynamic_cast<DefInit*>(RegList->getElement(i));
       if (!RegDef) throw "Register class member is not a record!";      
       Record *Reg = RegDef->getDef();
-      if (!Reg->isSubClassOf(RegisterClass))
+      if (!Reg->isSubClassOf("Register"))
         throw "Register Class member '" + Reg->getName() +
               " does not derive from the Register class!";
       if (RegistersFound.count(Reg))
@@ -203,8 +193,20 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
   OS << "  };\n";      // End of register descriptors...
   OS << "}\n\n";       // End of anonymous namespace...
 
-  Record *Target = getTarget(Records);
-  std::string ClassName = Target->getName() + "GenRegisterInfo";
+  CodeGenTarget Target;
+
+  OS << "namespace " << Target.getName() << " { // Register classes\n";
+  for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
+    const std::string &Name = RegisterClasses[i]->getName();
+    if (Name.size() < 9 || Name[9] != '.')    // Ignore anonymous classes
+      OS << "  TargetRegisterClass *" << Name << "RegisterClass = &"
+         << Name << "Instance;\n";
+  }
+  OS << "} // end of namespace " << Target.getName() << "\n\n";
+
+
+
+  std::string ClassName = Target.getName() + "GenRegisterInfo";
   
   // Emit the constructor of the class...
   OS << ClassName << "::" << ClassName
@@ -217,11 +219,8 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
   OS << "const unsigned* " << ClassName << "::getCalleeSaveRegs() const {\n"
      << "  static const unsigned CalleeSaveRegs[] = {\n    ";
 
-  ListInit *LI = Target->getValueAsListInit("CalleeSavedRegisters");
-  for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
-    if (DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(i)))
-      OS << getQualifiedName(DI->getDef()) << ", ";  
-    else
-      throw "Expected register definition in CalleeSavedRegisters list!";
+  const std::vector<Record*> &CSR = Target.getCalleeSavedRegisters();
+  for (unsigned i = 0, e = CSR.size(); i != e; ++i)
+    OS << getQualifiedName(CSR[i]) << ", ";  
   OS << " 0\n  };\n  return CalleeSaveRegs;\n}\n\n";
 }