summaryrefslogtreecommitdiff
path: root/utils/TableGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-08-21 04:05:00 +0000
committerChris Lattner <sabre@nondot.org>2004-08-21 04:05:00 +0000
commit056afeface2ac98664ed8fa4799b46178a4a6fe3 (patch)
treeb20825736e75aae16c585715fa1f6feab2fe5233 /utils/TableGen
parent7a680c60646fb3b06085f1fe6a7a1917c35010c6 (diff)
downloadllvm-056afeface2ac98664ed8fa4799b46178a4a6fe3.tar.gz
llvm-056afeface2ac98664ed8fa4799b46178a4a6fe3.tar.bz2
llvm-056afeface2ac98664ed8fa4799b46178a4a6fe3.tar.xz
Start parsing register classes into a more structured form
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15961 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/CodeGenRegisters.h8
-rw-r--r--utils/TableGen/CodeGenTarget.cpp32
-rw-r--r--utils/TableGen/CodeGenTarget.h10
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp30
4 files changed, 61 insertions, 19 deletions
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index ba89190325..bbec4ea670 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -16,6 +16,7 @@
#define CODEGEN_REGISTERS_H
#include <string>
+#include <vector>
namespace llvm {
class Record;
@@ -31,7 +32,14 @@ namespace llvm {
struct CodeGenRegisterClass {
+ Record *TheDef;
+ std::vector<Record*> Elements;
+ unsigned SpillSize;
+ unsigned SpillAlignment;
+
+ const std::string &getName() const;
+ CodeGenRegisterClass(Record *R);
};
}
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index c495519e58..e0d585c618 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -121,6 +121,38 @@ const std::string &CodeGenRegister::getName() const {
return TheDef->getName();
}
+void CodeGenTarget::ReadRegisterClasses() const {
+ std::vector<Record*> RegClasses =
+ Records.getAllDerivedDefinitions("RegisterClass");
+ if (RegClasses.empty())
+ throw std::string("No 'RegisterClass' subclasses defined!");
+
+ RegisterClasses.reserve(RegClasses.size());
+ RegisterClasses.assign(RegClasses.begin(), RegClasses.end());
+}
+
+CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
+ SpillSize = R->getValueAsInt("Size");
+ SpillAlignment = R->getValueAsInt("Alignment");
+
+ ListInit *RegList = R->getValueAsListInit("MemberList");
+ for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
+ 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("Register"))
+ throw "Register Class member '" + Reg->getName() +
+ "' does not derive from the Register class!";
+ Elements.push_back(Reg);
+ }
+}
+
+const std::string &CodeGenRegisterClass::getName() const {
+ return TheDef->getName();
+}
+
+
void CodeGenTarget::ReadInstructions() const {
std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h
index 2d65b7be8e..9b338d88c9 100644
--- a/utils/TableGen/CodeGenTarget.h
+++ b/utils/TableGen/CodeGenTarget.h
@@ -46,8 +46,10 @@ class CodeGenTarget {
mutable std::map<std::string, CodeGenInstruction> Instructions;
mutable std::vector<CodeGenRegister> Registers;
- void ReadInstructions() const;
+ mutable std::vector<CodeGenRegisterClass> RegisterClasses;
void ReadRegisters() const;
+ void ReadRegisterClasses() const;
+ void ReadInstructions() const;
public:
CodeGenTarget();
@@ -73,6 +75,12 @@ public:
return Registers;
}
+ const std::vector<CodeGenRegisterClass> getRegisterClasses() {
+ if (RegisterClasses.empty()) ReadRegisterClasses();
+ return RegisterClasses;
+ }
+
+
/// getInstructions - Return all of the instructions defined for this target.
///
const std::map<std::string, CodeGenInstruction> &getInstructions() const {
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 4ed1a0fe8c..6763af3f65 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -85,8 +85,8 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
// a set of registers which belong to a register class, this is to ensure that
// each register is only in a single register class.
//
- std::vector<Record*> RegisterClasses =
- Records.getAllDerivedDefinitions("RegisterClass");
+ const std::vector<CodeGenRegisterClass> &RegisterClasses =
+ Target.getRegisterClasses();
std::set<Record*> RegistersFound;
std::vector<std::string> RegClassNames;
@@ -95,9 +95,9 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
OS << "namespace { // Register classes...\n";
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
- Record *RC = RegisterClasses[rc];
+ const CodeGenRegisterClass &RC = RegisterClasses[rc];
- std::string Name = RC->getName();
+ std::string Name = RC.getName();
if (Name.size() > 9 && Name[9] == '.') {
static unsigned AnonCounter = 0;
Name = "AnonRegClass_"+utostr(AnonCounter++);
@@ -108,14 +108,8 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
// 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) {
- 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("Register"))
- throw "Register Class member '" + Reg->getName() +
- " does not derive from the Register class!";
+ for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) {
+ Record *Reg = RC.Elements[i];
if (RegistersFound.count(Reg))
throw "Register '" + Reg->getName() +
"' included in multiple register classes!";
@@ -126,15 +120,15 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
OS << " struct " << Name << "Class : public TargetRegisterClass {\n"
<< " " << Name << "Class() : TargetRegisterClass("
- << RC->getValueAsInt("Size")/8 << ", " << RC->getValueAsInt("Alignment")
- << ", " << Name << ", " << Name << " + " << RegList->getSize()
- << ") {}\n";
+ << RC.SpillSize/8 << ", " << RC.SpillAlignment << ", " << Name << ", "
+ << Name << " + " << RC.Elements.size() << ") {}\n";
- if (CodeInit *CI = dynamic_cast<CodeInit*>(RC->getValueInit("Methods")))
+ if (CodeInit *CI =
+ dynamic_cast<CodeInit*>(RC.TheDef->getValueInit("Methods")))
OS << CI->getValue();
else
throw "Expected 'code' fragment for 'Methods' value in register class '"+
- RC->getName() + "'!";
+ RC.getName() + "'!";
OS << " } " << Name << "Instance;\n\n";
}
@@ -215,7 +209,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
OS << "namespace " << Target.getName() << " { // Register classes\n";
for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
- const std::string &Name = RegisterClasses[i]->getName();
+ const std::string &Name = RegisterClasses[i].getName();
if (Name.size() < 9 || Name[9] != '.') // Ignore anonymous classes
OS << " TargetRegisterClass *" << Name << "RegisterClass = &"
<< Name << "Instance;\n";