add support for emitting register classes
authorChris Lattner <sabre@nondot.org>
Fri, 1 Aug 2003 06:27:59 +0000 (06:27 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 1 Aug 2003 06:27:59 +0000 (06:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7473 91177308-0d34-0410-b5e6-96231b3b80d8

support/tools/TableGen/Record.cpp
support/tools/TableGen/Record.h
support/tools/TableGen/RegisterInfoEmitter.cpp
utils/TableGen/Record.cpp
utils/TableGen/Record.h
utils/TableGen/RegisterInfoEmitter.cpp

index 8649b5fe4cc270d8776f72a514525d2b52d4ca8d..7f81a382bb59b308a531654b9e2b4130bb37c6e3 100644 (file)
@@ -460,6 +460,18 @@ std::ostream &operator<<(std::ostream &OS, const Record &R) {
   return OS << "}\n";
 }
 
+/// getValueInit - Return the initializer for a value with the specified name,
+/// or throw an exception if the field does not exist.
+///
+Init *Record::getValueInit(const std::string &FieldName) const {
+  const RecordVal *R = getValue(FieldName);
+  if (R == 0 || R->getValue() == 0)
+    throw "Record '" + R->getName() + "' does not have a field named '" +
+      FieldName + "!\n";
+  return R->getValue();
+}
+
+
 /// getValueAsString - This method looks up the specified field and returns its
 /// value as a string, throwing an exception if the field does not exist or if
 /// the value is not a string.
index 0eaf16ff0e2b79fec93794815387b3540653ed56..1729b02866853f94af4ec5aa6c01fed84ff957a5 100644 (file)
@@ -335,6 +335,8 @@ class CodeInit : public Init {
 public:
   CodeInit(const std::string &V) : Value(V) {}
 
+  const std::string getValue() const { return Value; }
+
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
@@ -601,6 +603,11 @@ public:
   // High-level methods useful to tablegen back-ends
   //
 
+  /// getValueInit - Return the initializer for a value with the specified name,
+  /// or throw an exception if the field does not exist.
+  ///
+  Init *getValueInit(const std::string &FieldName) const;
+
   /// getValueAsString - This method looks up the specified field and returns
   /// its value as a string, throwing an exception if the field does not exist
   /// or if the value is not a string.
index 66e7b1250f57c75e00670d00ccc219207b1810dd..af04f791d56e3178684f24d25b9d9ca923beaa04 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "RegisterInfoEmitter.h"
 #include "Record.h"
+#include "Support/StringExtras.h"
 #include <set>
 
 static void EmitSourceHeader(const std::string &Desc, std::ostream &o) {
@@ -59,6 +60,12 @@ void RegisterInfoEmitter::runHeader(std::ostream &OS) {
      << "};\n\n";
 }
 
+static std::string getQualifiedRecordName(Record *R) {
+  std::string Namespace = R->getValueAsString("Namespace");
+  if (Namespace.empty()) return R->getName();
+  return Namespace + "::" + R->getName();
+}
+
 // RegisterInfoEmitter::run - Main register file description emitter.
 //
 void RegisterInfoEmitter::run(std::ostream &OS) {
@@ -71,6 +78,9 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
   std::vector<Record*> RegisterClasses =
     Records.getAllDerivedDefinitions("RegisterClass");
 
+  std::vector<Record*> Registers = Records.getAllDerivedDefinitions("Register");
+  Record *RegisterClass = Records.getClass("Register");
+
   std::set<Record*> RegistersFound;
 
   // Loop over all of the register classes... emitting each one.
@@ -79,7 +89,40 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
   for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
     Record *RC = RegisterClasses[rc];
     std::string Name = RC->getName();
-    //if (Name[
+    if (Name[9] == '.') {
+      static unsigned AnonCounter = 0;
+      Name = "AnonRegClass_"+utostr(AnonCounter++);
+    }
+
+    // Emit the register list now...
+    OS << "  // " << Name << " Register Class...\n  const unsigned " << Name
+       << "[] = {\n    ";
+    ListInit *RegList = RC->getValueAsListInit("MemberList");
+    for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
+      Record *Reg = RegList->getElement(i);
+      if (!Reg->isSubClassOf(RegisterClass))
+        throw "Register Class member '" + Reg->getName() +
+              " does not derive from the Register class!";
+      if (RegistersFound.count(Reg))
+        throw "Register '" + Reg->getName() +
+              "' included in multiple register classes!";
+      OS << getQualifiedRecordName(Reg) << ", ";
+    }
+    OS << "\n  };\n\n";
+
+    OS << "  struct " << Name << "Class : public TargetRegisterClass {\n"
+       << "    " << Name << "Class() : TargetRegisterClass("
+       << RC->getValueAsInt("Size")/8 << ", " << RC->getValueAsInt("Alignment")
+       << ", " << Name << ", " << Name << " + " << RegList->getSize()
+       << ") {}\n";
+    
+    if (CodeInit *CI = dynamic_cast<CodeInit*>(RC->getValueInit("Methods")))
+      OS << CI->getValue();
+    else
+      throw "Expected 'code' fragment for 'Methods' value in register class '"+
+            RC->getName() + "'!";
+
+    OS << "  } " << Name << "Instance;\n\n";
 
   }
 
index 8649b5fe4cc270d8776f72a514525d2b52d4ca8d..7f81a382bb59b308a531654b9e2b4130bb37c6e3 100644 (file)
@@ -460,6 +460,18 @@ std::ostream &operator<<(std::ostream &OS, const Record &R) {
   return OS << "}\n";
 }
 
+/// getValueInit - Return the initializer for a value with the specified name,
+/// or throw an exception if the field does not exist.
+///
+Init *Record::getValueInit(const std::string &FieldName) const {
+  const RecordVal *R = getValue(FieldName);
+  if (R == 0 || R->getValue() == 0)
+    throw "Record '" + R->getName() + "' does not have a field named '" +
+      FieldName + "!\n";
+  return R->getValue();
+}
+
+
 /// getValueAsString - This method looks up the specified field and returns its
 /// value as a string, throwing an exception if the field does not exist or if
 /// the value is not a string.
index 0eaf16ff0e2b79fec93794815387b3540653ed56..1729b02866853f94af4ec5aa6c01fed84ff957a5 100644 (file)
@@ -335,6 +335,8 @@ class CodeInit : public Init {
 public:
   CodeInit(const std::string &V) : Value(V) {}
 
+  const std::string getValue() const { return Value; }
+
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
@@ -601,6 +603,11 @@ public:
   // High-level methods useful to tablegen back-ends
   //
 
+  /// getValueInit - Return the initializer for a value with the specified name,
+  /// or throw an exception if the field does not exist.
+  ///
+  Init *getValueInit(const std::string &FieldName) const;
+
   /// getValueAsString - This method looks up the specified field and returns
   /// its value as a string, throwing an exception if the field does not exist
   /// or if the value is not a string.
index 66e7b1250f57c75e00670d00ccc219207b1810dd..af04f791d56e3178684f24d25b9d9ca923beaa04 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "RegisterInfoEmitter.h"
 #include "Record.h"
+#include "Support/StringExtras.h"
 #include <set>
 
 static void EmitSourceHeader(const std::string &Desc, std::ostream &o) {
@@ -59,6 +60,12 @@ void RegisterInfoEmitter::runHeader(std::ostream &OS) {
      << "};\n\n";
 }
 
+static std::string getQualifiedRecordName(Record *R) {
+  std::string Namespace = R->getValueAsString("Namespace");
+  if (Namespace.empty()) return R->getName();
+  return Namespace + "::" + R->getName();
+}
+
 // RegisterInfoEmitter::run - Main register file description emitter.
 //
 void RegisterInfoEmitter::run(std::ostream &OS) {
@@ -71,6 +78,9 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
   std::vector<Record*> RegisterClasses =
     Records.getAllDerivedDefinitions("RegisterClass");
 
+  std::vector<Record*> Registers = Records.getAllDerivedDefinitions("Register");
+  Record *RegisterClass = Records.getClass("Register");
+
   std::set<Record*> RegistersFound;
 
   // Loop over all of the register classes... emitting each one.
@@ -79,7 +89,40 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
   for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
     Record *RC = RegisterClasses[rc];
     std::string Name = RC->getName();
-    //if (Name[
+    if (Name[9] == '.') {
+      static unsigned AnonCounter = 0;
+      Name = "AnonRegClass_"+utostr(AnonCounter++);
+    }
+
+    // Emit the register list now...
+    OS << "  // " << Name << " Register Class...\n  const unsigned " << Name
+       << "[] = {\n    ";
+    ListInit *RegList = RC->getValueAsListInit("MemberList");
+    for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
+      Record *Reg = RegList->getElement(i);
+      if (!Reg->isSubClassOf(RegisterClass))
+        throw "Register Class member '" + Reg->getName() +
+              " does not derive from the Register class!";
+      if (RegistersFound.count(Reg))
+        throw "Register '" + Reg->getName() +
+              "' included in multiple register classes!";
+      OS << getQualifiedRecordName(Reg) << ", ";
+    }
+    OS << "\n  };\n\n";
+
+    OS << "  struct " << Name << "Class : public TargetRegisterClass {\n"
+       << "    " << Name << "Class() : TargetRegisterClass("
+       << RC->getValueAsInt("Size")/8 << ", " << RC->getValueAsInt("Alignment")
+       << ", " << Name << ", " << Name << " + " << RegList->getSize()
+       << ") {}\n";
+    
+    if (CodeInit *CI = dynamic_cast<CodeInit*>(RC->getValueInit("Methods")))
+      OS << CI->getValue();
+    else
+      throw "Expected 'code' fragment for 'Methods' value in register class '"+
+            RC->getName() + "'!";
+
+    OS << "  } " << Name << "Instance;\n\n";
 
   }