Add the SubRegIndex TableGen class.

This is the beginning of purely symbolic subregister indices, but we need a bit
of jiggling before the explicit numeric indices can be completely removed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104492 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index a0bccfc..878ed09 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -1057,6 +1057,11 @@
     const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
     return EEVT::TypeSet(T.getRegisterVTs(R));
   }
+
+  if (R->isSubClassOf("SubRegIndex")) {
+    assert(ResNo == 0 && "SubRegisterIndices only produce one result!");
+    return EEVT::TypeSet();
+  }
   
   if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) {
     assert(ResNo == 0 && "This node only has one result!");
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index 9d469a9..eb528eb 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -224,6 +224,7 @@
   if (// Handle register references.  Nothing to do here, they always match.
       LeafRec->isSubClassOf("RegisterClass") || 
       LeafRec->isSubClassOf("PointerLikeRegClass") ||
+      LeafRec->isSubClassOf("SubRegIndex") ||
       // Place holder for SRCVALUE nodes. Nothing to do here.
       LeafRec->getName() == "srcvalue")
     return;
@@ -597,6 +598,14 @@
       ResultOps.push_back(NextRecordedOperandNo++);
       return;
     }
+
+    // Handle a subregister index. This is used for INSERT_SUBREG etc.
+    if (DI->getDef()->isSubClassOf("SubRegIndex")) {
+      std::string Value = getQualifiedName(DI->getDef());
+      AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
+      ResultOps.push_back(NextRecordedOperandNo++);
+      return;
+    }
   }
   
   errs() << "unhandled leaf node: \n";
diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp
index ce9d97b..9ec9e08 100644
--- a/utils/TableGen/FastISelEmitter.cpp
+++ b/utils/TableGen/FastISelEmitter.cpp
@@ -31,7 +31,7 @@
 struct InstructionMemo {
   std::string Name;
   const CodeGenRegisterClass *RC;
-  unsigned char SubRegNo;
+  std::string SubRegNo;
   std::vector<std::string>* PhysRegs;
 };
 
@@ -278,7 +278,7 @@
     // For now, ignore instructions where the first operand is not an
     // output register.
     const CodeGenRegisterClass *DstRC = 0;
-    unsigned SubRegNo = ~0;
+    std::string SubRegNo;
     if (Op->getName() != "EXTRACT_SUBREG") {
       Record *Op0Rec = II.OperandList[0].Rec;
       if (!Op0Rec->isSubClassOf("RegisterClass"))
@@ -287,8 +287,11 @@
       if (!DstRC)
         continue;
     } else {
-      SubRegNo = static_cast<IntInit*>(
-                 Dst->getChild(1)->getLeafValue())->getValue();
+      DefInit *SR = dynamic_cast<DefInit*>(Dst->getChild(1)->getLeafValue());
+      if (SR)
+        SubRegNo = getQualifiedName(SR->getDef());
+      else
+        SubRegNo = Dst->getChild(1)->getLeafValue()->getAsString();
     }
 
     // Inspect the pattern.
@@ -437,7 +440,7 @@
               }
               
               OS << "  return FastEmitInst_";
-              if (Memo.SubRegNo == (unsigned char)~0) {
+              if (Memo.SubRegNo.empty()) {
                 Operands.PrintManglingSuffix(OS, *Memo.PhysRegs);
                 OS << "(" << InstNS << Memo.Name << ", ";
                 OS << InstNS << Memo.RC->getName() << "RegisterClass";
@@ -448,7 +451,7 @@
               } else {
                 OS << "extractsubreg(" << getName(RetVT);
                 OS << ", Op0, Op0IsKill, ";
-                OS << (unsigned)Memo.SubRegNo;
+                OS << Memo.SubRegNo;
                 OS << ");\n";
               }
               
@@ -532,7 +535,7 @@
             
             OS << "  return FastEmitInst_";
             
-            if (Memo.SubRegNo == (unsigned char)~0) {
+            if (Memo.SubRegNo.empty()) {
               Operands.PrintManglingSuffix(OS, *Memo.PhysRegs);
               OS << "(" << InstNS << Memo.Name << ", ";
               OS << InstNS << Memo.RC->getName() << "RegisterClass";
@@ -542,7 +545,7 @@
               OS << ");\n";
             } else {
               OS << "extractsubreg(RetVT, Op0, Op0IsKill, ";
-              OS << (unsigned)Memo.SubRegNo;
+              OS << Memo.SubRegNo;
               OS << ");\n";
             }
             
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index fcf4123..a5fabea 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -35,14 +35,31 @@
 
   if (!Namespace.empty())
     OS << "namespace " << Namespace << " {\n";
-  OS << "  enum {\n    NoRegister,\n";
+  OS << "enum {\n  NoRegister,\n";
 
   for (unsigned i = 0, e = Registers.size(); i != e; ++i)
-    OS << "    " << Registers[i].getName() << ", \t// " << i+1 << "\n";
-  OS << "    NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n";
-  OS << "  };\n";
+    OS << "  " << Registers[i].getName() << ", \t// " << i+1 << "\n";
+  OS << "  NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n";
+  OS << "};\n";
   if (!Namespace.empty())
     OS << "}\n";
+
+  const std::vector<Record*> SubRegIndices =
+    Records.getAllDerivedDefinitions("SubRegIndex");
+  if (!SubRegIndices.empty()) {
+    OS << "\n// Subregister indices\n";
+    Namespace = SubRegIndices[0]->getValueAsString("Namespace");
+    if (!Namespace.empty())
+      OS << "namespace " << Namespace << " {\n";
+    OS << "enum {\n  NoSubRegister,\n";
+    for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
+      OS << "  " << SubRegIndices[i]->getName() << " = "
+         << SubRegIndices[i]->getValueAsInt("NumberHack") << ",\n";
+    OS << "  NUM_TARGET_SUBREGS = " << SubRegIndices.size()+1 << "\n";
+    OS << "};\n";
+    if (!Namespace.empty())
+      OS << "}\n";
+  }
   OS << "} // End llvm namespace \n";
 }