[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