[PATCH] D30960: generate decoding tables for registers

Mike Stump via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 14 17:05:39 PDT 2017


MikeStump created this revision.

Most ports have one or more create by hand decoding tables for their registers.  It is nice if tblgen creates this table for us, as it does have visibility into all the registers and their numbers.


Repository:
  rL LLVM

https://reviews.llvm.org/D30960

Files:
  utils/TableGen/RegisterInfoEmitter.cpp


Index: utils/TableGen/RegisterInfoEmitter.cpp
===================================================================
--- utils/TableGen/RegisterInfoEmitter.cpp
+++ utils/TableGen/RegisterInfoEmitter.cpp
@@ -1060,6 +1060,63 @@
   }
   OS << "};\n";       // End of HW encoding table
 
+  // Emit Reg decoding tables
+  OS << "\n#ifdef GET_REGINFO_REGISTER_DECODER\n";
+  OS << "#undef GET_REGINFO_REGISTER_DECODER\n\n";
+  for (const auto &RC : RegisterClasses) {
+    ArrayRef<Record*> Order = RC.getOrder();
+    unsigned HWEncodingWidth;
+    int e = Order.size();
+    for (HWEncodingWidth = 1;
+	 (1L<<HWEncodingWidth) < e;
+	 ++HWEncodingWidth) ;
+    uint64_t mask = (1 << HWEncodingWidth) - 1;
+    const std::string &Name = RC.getName();
+    OS << "extern const uint16_t " << TargetName;
+    OS << "RegDecodingTable_" << Name << "[] = {\n";
+    uint64_t max = 0;
+    for (int i = 0, e = Order.size(); i != e; ++i) {
+      auto Reg = Order[i];
+      BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
+      uint64_t Value = 0;
+      for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
+	if (BitInit *B = dyn_cast<BitInit>(BI->getBit(b)))
+	  Value |= (uint64_t)B->getValue() << b;
+      }
+      Value &= mask;
+      if (Value >= max)
+	max = Value;
+    }
+    std::map<uint64_t, std::string> RegNo2Name;
+    for (int i = Order.size()-1; i>=0; --i) {
+      auto Reg = Order[i];
+      BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
+      uint64_t Value = 0;
+      for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
+	if (BitInit *B = dyn_cast<BitInit>(BI->getBit(b)))
+	  Value |= (uint64_t)B->getValue() << b;
+      }
+      Value &= mask;
+      RegNo2Name[Value] = getQualifiedName(Reg);
+    }
+    uint64_t last = -1;
+    for (const auto i : RegNo2Name) {
+      while (++last < i.first)
+	OS << "  /* [" <<  last << "] = */ 0,\n";
+      OS << "  /* [" <<  i.first << "] = */ " << i.second <<",\n";
+    }
+    OS << "};\n";       // End of HW decoding tables
+  }
+  // Emit the main register decoding table
+  OS << "const uint16_t *" << TargetName;
+  OS << "RegDecodingTable[] = {\n";
+  for (const auto &RC : RegisterClasses) {
+    const std::string &Name = RC.getName();
+    OS << "  " << TargetName << "RegDecodingTable_" << Name << ",\n";
+  }
+  OS << "};\n";       // End of the main register decoding table
+  OS << "\n#endif // GET_REGINFO_REGISTER_DECODER\n\n";
+
   // MCRegisterInfo initialization routine.
   OS << "static inline void Init" << TargetName
      << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30960.91795.patch
Type: text/x-patch
Size: 2587 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170315/d787df40/attachment.bin>


More information about the llvm-commits mailing list