[llvm-commits] PATCH: Tablegen - Add HWEncoding field to Register class and generate getHWEncoding() function
Tom Stellard
thomas.stellard at amd.com
Fri May 4 13:55:11 PDT 2012
Hi,
The attached patch causes tablegen with the -gen-register-info flag to
generate a getHWEncoding function that returns the encoding for the given
register. This is useful for targets like R600 that have hundreds of
registers, which makes it very tedious to write a function like this by
hand.
Please Review.
Thanks,
Tom Stellard
-------------- next part --------------
diff --git include/llvm/Target/Target.td include/llvm/Target/Target.td
index bd959d0..1f2bd47 100644
--- include/llvm/Target/Target.td
+++ include/llvm/Target/Target.td
@@ -96,6 +96,9 @@ class Register<string n, list<string> altNames = []> {
// x86 register AX is covered by its sub-registers AL and AH, but EAX is not
// covered by its sub-register AX.
bit CoveredBySubRegs = 0;
+
+ // HWEncoding - The target specific hardware encoding for this register.
+ bits<16> HWEncoding = 0;
}
// RegisterWithSubRegs - This can be used to define instances of Register which
diff --git utils/TableGen/RegisterInfoEmitter.cpp utils/TableGen/RegisterInfoEmitter.cpp
index 5b4a876..92c3fa8 100644
--- utils/TableGen/RegisterInfoEmitter.cpp
+++ utils/TableGen/RegisterInfoEmitter.cpp
@@ -412,6 +412,40 @@ RegisterInfoEmitter::EmitRegMapping(raw_ostream &OS,
}
}
+void
+RegisterInfoEmitter::EmitRegHWEncoding(raw_ostream &OS,
+ const std::vector<CodeGenRegister*> &Regs,
+ const std::string &ClassName) const {
+
+ std::map<uint64_t, std::vector<std::string> > CaseMap;
+
+ for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+ Record *Reg = Regs[i]->TheDef;
+ BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
+ uint64_t Value = 0;
+ for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
+ if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(b)))
+ Value |= (uint64_t)B->getValue() << b;
+ }
+ CaseMap[Value].push_back(getQualifiedName(Reg));
+ }
+ OS << "uint64_t " << ClassName << "::getHWEncoding(" << "unsigned reg) const";
+ OS << "\n{\n switch(reg) {\n";
+ OS << "default: llvm_unreachable(\"Unknown Register\");\n";
+ std::map<uint64_t, std::vector<std::string> >::iterator CI, CE;
+ for (CI = CaseMap.begin(), CE = CaseMap.end(); CI != CE; ++CI) {
+ uint64_t HWEncoding = (*CI).first;
+ std::vector<std::string> RegNames = (*CI).second;
+ for (std::vector<std::string>::iterator RI = RegNames.begin(),
+ RE = RegNames.end(); RI != RE; ++RI) {
+ OS << " case " << *RI << ":\n";
+ }
+ OS << " return " << HWEncoding << ";\n";
+ }
+
+ OS << " }\n}\n";
+}
+
// Print a BitVector as a sequence of hex numbers using a little-endian mapping.
// Width is the number of bits per hex number.
static void printBitVectorAsHex(raw_ostream &OS,
@@ -689,6 +723,7 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
<< " unsigned getRegPressureSetLimit(unsigned Idx) const;\n"
<< " const int *getRegClassPressureSets("
<< "const TargetRegisterClass *RC) const;\n"
+ << " uint64_t getHWEncoding(unsigned reg) const;\n"
<< "};\n\n";
ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();
@@ -994,6 +1029,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
}
EmitRegUnitPressure(OS, RegBank, ClassName);
+ EmitRegHWEncoding(OS, Regs, ClassName);
// Emit the constructor of the class...
OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
diff --git utils/TableGen/RegisterInfoEmitter.h utils/TableGen/RegisterInfoEmitter.h
index ee9903c..b8dfab2 100644
--- utils/TableGen/RegisterInfoEmitter.h
+++ utils/TableGen/RegisterInfoEmitter.h
@@ -57,6 +57,9 @@ private:
void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
const std::string &ClassName);
+ void EmitRegHWEncoding(raw_ostream &OS,
+ const std::vector<CodeGenRegister*> &Regs,
+ const std::string &ClassName) const;
};
} // End llvm namespace
More information about the llvm-commits
mailing list