Add support for alternative register names, useful for instructions whose operands are logically equivalent to existing registers, but happen to be printed specially.  For example, an instruciton that prints d0[0] instead of s0.
Patch by Jim Grosbach.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133940 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index a05867b..1fb92ee 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -871,6 +871,31 @@
   if (SubOpIdx != -1)
     Rec = dynamic_cast<DefInit*>(OI.MIOperandInfo->getArg(SubOpIdx))->getDef();
 
+  if (Rec->isSubClassOf("RegisterOperand")) {
+    // RegisterOperand may have an associated ParserMatchClass. If it does,
+    // use it, else just fall back to the underlying register class.
+    const RecordVal *R = Rec->getValue("ParserMatchClass");
+    if (R == 0 || R->getValue() == 0)
+      throw "Record `" + Rec->getName() +
+        "' does not have a ParserMatchClass!\n";
+
+    if (DefInit *DI= dynamic_cast<DefInit*>(R->getValue())) {
+      Record *MatchClass = DI->getDef();
+      if (ClassInfo *CI = AsmOperandClasses[MatchClass])
+        return CI;
+    }
+
+    // No custom match class. Just use the register class.
+    Record *ClassRec = Rec->getValueAsDef("RegClass");
+    if (!ClassRec)
+      throw TGError(Rec->getLoc(), "RegisterOperand `" + Rec->getName() +
+                    "' has no associated register class!\n");
+    if (ClassInfo *CI = RegisterClassClasses[ClassRec])
+      return CI;
+    throw TGError(Rec->getLoc(), "register class has no class info!");
+  }
+
+
   if (Rec->isSubClassOf("RegisterClass")) {
     if (ClassInfo *CI = RegisterClassClasses[Rec])
       return CI;
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index 066e03d..53df7dd 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -18,6 +18,7 @@
 #include "CodeGenTarget.h"
 #include "Record.h"
 #include "StringToOffsetTable.h"
+#include "llvm/ADT/Twine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/MathExtras.h"
 #include <algorithm>
@@ -458,6 +459,58 @@
   O << "}\n";
 }
 
+static void
+emitRegisterNameString(raw_ostream &O, StringRef AltName,
+  const std::vector<CodeGenRegister*> &Registers) {
+  StringToOffsetTable StringTable;
+  O << "  static const unsigned RegAsmOffset" << AltName << "[] = {\n    ";
+  for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
+    const CodeGenRegister &Reg = *Registers[i];
+
+    StringRef AsmName;
+    // "NoRegAltName" is special. We don't need to do a lookup for that,
+    // as it's just a reference to the default register name.
+    if (AltName == "" || AltName == "NoRegAltName") {
+      AsmName = Reg.TheDef->getValueAsString("AsmName");
+      if (AsmName.empty())
+        AsmName = Reg.getName();
+    } else {
+      // Make sure the register has an alternate name for this index.
+      std::vector<Record*> AltNameList =
+        Reg.TheDef->getValueAsListOfDefs("RegAltNameIndices");
+      unsigned Idx = 0, e;
+      for (e = AltNameList.size();
+           Idx < e && (AltNameList[Idx]->getName() != AltName);
+           ++Idx)
+        ;
+      // If the register has an alternate name for this index, use it.
+      // Otherwise, leave it empty as an error flag.
+      if (Idx < e) {
+        std::vector<std::string> AltNames =
+          Reg.TheDef->getValueAsListOfStrings("AltNames");
+        if (AltNames.size() <= Idx)
+          throw TGError(Reg.TheDef->getLoc(),
+                        (Twine("Register definition missing alt name for '") +
+                        AltName + "'.").str());
+        AsmName = AltNames[Idx];
+      }
+    }
+
+    O << StringTable.GetOrAddStringOffset(AsmName);
+    if (((i + 1) % 14) == 0)
+      O << ",\n    ";
+    else
+      O << ", ";
+
+  }
+  O << "0\n"
+    << "  };\n"
+    << "\n";
+
+  O << "  const char *AsmStrs" << AltName << " =\n";
+  StringTable.EmitString(O);
+  O << ";\n";
+}
 
 void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
   CodeGenTarget Target(Records);
@@ -465,40 +518,48 @@
   std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
   const std::vector<CodeGenRegister*> &Registers =
     Target.getRegBank().getRegisters();
+  std::vector<Record*> AltNameIndices = Target.getRegAltNameIndices();
+  bool hasAltNames = AltNameIndices.size() > 1;
 
-  StringToOffsetTable StringTable;
   O <<
   "\n\n/// getRegisterName - This method is automatically generated by tblgen\n"
   "/// from the register set description.  This returns the assembler name\n"
   "/// for the specified register.\n"
-  "const char *" << Target.getName() << ClassName
-  << "::getRegisterName(unsigned RegNo) {\n"
-  << "  assert(RegNo && RegNo < " << (Registers.size()+1)
-  << " && \"Invalid register number!\");\n"
-  << "\n"
-  << "  static const unsigned RegAsmOffset[] = {";
-  for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
-    const CodeGenRegister &Reg = *Registers[i];
-
-    std::string AsmName = Reg.TheDef->getValueAsString("AsmName");
-    if (AsmName.empty())
-      AsmName = Reg.getName();
-
-
-    if ((i % 14) == 0)
-      O << "\n    ";
-
-    O << StringTable.GetOrAddStringOffset(AsmName) << ", ";
-  }
-  O << "0\n"
-    << "  };\n"
+  "const char *" << Target.getName() << ClassName << "::";
+  if (hasAltNames)
+    O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n";
+  else
+    O << "getRegisterName(unsigned RegNo) {\n";
+  O << "  assert(RegNo && RegNo < " << (Registers.size()+1)
+    << " && \"Invalid register number!\");\n"
     << "\n";
 
-  O << "  const char *AsmStrs =\n";
-  StringTable.EmitString(O);
-  O << ";\n";
+  if (hasAltNames) {
+    for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i)
+      emitRegisterNameString(O, AltNameIndices[i]->getName(), Registers);
+  } else
+    emitRegisterNameString(O, "", Registers);
 
-  O << "  return AsmStrs+RegAsmOffset[RegNo-1];\n"
+  if (hasAltNames) {
+    O << "  const unsigned *RegAsmOffset;\n"
+      << "  const char *AsmStrs;\n"
+      << "  switch(AltIdx) {\n"
+      << "  default: assert(0 && \"Invalid register alt name index!\");\n";
+    for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i) {
+      StringRef Namespace = AltNameIndices[1]->getValueAsString("Namespace");
+      StringRef AltName(AltNameIndices[i]->getName());
+      O << "  case " << Namespace << "::" << AltName
+        << ":\n"
+        << "    AsmStrs = AsmStrs" << AltName  << ";\n"
+        << "    RegAsmOffset = RegAsmOffset" << AltName << ";\n"
+        << "    break;\n";
+    }
+    O << "}\n";
+  }
+
+  O << "  assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n"
+    << "          \"Invalid alt name index for register!\");\n"
+    << "  return AsmStrs+RegAsmOffset[RegNo-1];\n"
     << "}\n";
 }
 
@@ -936,6 +997,9 @@
           const Record *Rec = RO.getRecord();
           StringRef ROName = RO.getName();
 
+
+          if (Rec->isSubClassOf("RegisterOperand"))
+            Rec = Rec->getValueAsDef("RegClass");
           if (Rec->isSubClassOf("RegisterClass")) {
             Cond = std::string("MI->getOperand(")+llvm::utostr(i)+").isReg()";
             IAP->addCond(Cond);
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 1930a96..0fe5d05 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -1242,6 +1242,16 @@
 ///
 static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo,
                                      bool NotRegisters, TreePattern &TP) {
+  // Check to see if this is a register operand.
+  if (R->isSubClassOf("RegisterOperand")) {
+    assert(ResNo == 0 && "Regoperand ref only has one result!");
+    if (NotRegisters)
+      return EEVT::TypeSet(); // Unknown.
+    Record *RegClass = R->getValueAsDef("RegClass");
+    const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
+    return EEVT::TypeSet(T.getRegisterClass(RegClass).getValueTypes());
+  }
+
   // Check to see if this is a register or a register class.
   if (R->isSubClassOf("RegisterClass")) {
     assert(ResNo == 0 && "Regclass ref only has one result!");
@@ -1524,6 +1534,11 @@
 
       if (ResultNode->isSubClassOf("PointerLikeRegClass")) {
         MadeChange |= UpdateNodeType(ResNo, MVT::iPTR, TP);
+      } else if (ResultNode->isSubClassOf("RegisterOperand")) {
+        Record *RegClass = ResultNode->getValueAsDef("RegClass");
+        const CodeGenRegisterClass &RC =
+          CDP.getTargetInfo().getRegisterClass(RegClass);
+        MadeChange |= UpdateNodeType(ResNo, RC.getValueTypes(), TP);
       } else if (ResultNode->getName() == "unknown") {
         // Nothing to do.
       } else {
@@ -1582,6 +1597,11 @@
         const CodeGenRegisterClass &RC =
           CDP.getTargetInfo().getRegisterClass(OperandNode);
         MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP);
+      } else if (OperandNode->isSubClassOf("RegisterOperand")) {
+        Record *RegClass = OperandNode->getValueAsDef("RegClass");
+        const CodeGenRegisterClass &RC =
+          CDP.getTargetInfo().getRegisterClass(RegClass);
+        MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP);
       } else if (OperandNode->isSubClassOf("Operand")) {
         VT = getValueType(OperandNode->getValueAsDef("Type"));
         MadeChange |= Child->UpdateNodeType(ChildResNo, VT, TP);
@@ -1928,7 +1948,8 @@
           //  def : Pat<(v1i64 (bitconvert(v2i32 DPR:$src))), (v1i64 DPR:$src)>;
           if (Nodes[i] == Trees[0] && Nodes[i]->isLeaf()) {
             DefInit *DI = dynamic_cast<DefInit*>(Nodes[i]->getLeafValue());
-            if (DI && DI->getDef()->isSubClassOf("RegisterClass"))
+            if (DI && (DI->getDef()->isSubClassOf("RegisterClass") ||
+                       DI->getDef()->isSubClassOf("RegisterOperand")))
               continue;
           }
 
@@ -2211,7 +2232,8 @@
   if (Pat->getName().empty()) {
     if (Pat->isLeaf()) {
       DefInit *DI = dynamic_cast<DefInit*>(Pat->getLeafValue());
-      if (DI && DI->getDef()->isSubClassOf("RegisterClass"))
+      if (DI && (DI->getDef()->isSubClassOf("RegisterClass") ||
+                 DI->getDef()->isSubClassOf("RegisterOperand")))
         I->error("Input " + DI->getDef()->getName() + " must be named!");
     }
     return false;
@@ -2318,6 +2340,7 @@
       I->error("set destination should be a register!");
 
     if (Val->getDef()->isSubClassOf("RegisterClass") ||
+        Val->getDef()->isSubClassOf("RegisterOperand") ||
         Val->getDef()->isSubClassOf("PointerLikeRegClass")) {
       if (Dest->getName().empty())
         I->error("set destination must have a name!");
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
index e9557d2..5fa91be 100644
--- a/utils/TableGen/CodeGenInstruction.cpp
+++ b/utils/TableGen/CodeGenInstruction.cpp
@@ -69,7 +69,9 @@
     std::string EncoderMethod;
     unsigned NumOps = 1;
     DagInit *MIOpInfo = 0;
-    if (Rec->isSubClassOf("Operand")) {
+    if (Rec->isSubClassOf("RegisterOperand")) {
+      PrintMethod = Rec->getValueAsString("PrintMethod");
+    } else if (Rec->isSubClassOf("Operand")) {
       PrintMethod = Rec->getValueAsString("PrintMethod");
       // If there is an explicit encoder method, use it.
       EncoderMethod = Rec->getValueAsString("EncoderMethod");
@@ -415,6 +417,9 @@
 
   // Handle explicit registers.
   if (ADI && ADI->getDef()->isSubClassOf("Register")) {
+    if (InstOpRec->isSubClassOf("RegisterOperand"))
+      InstOpRec = InstOpRec->getValueAsDef("RegClass");
+
     if (!InstOpRec->isSubClassOf("RegisterClass"))
       return false;
 
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index 5b0b315..929791c 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -164,6 +164,11 @@
   return *RegBank;
 }
 
+void CodeGenTarget::ReadRegAltNameIndices() const {
+  RegAltNameIndices = Records.getAllDerivedDefinitions("RegAltNameIndex");
+  std::sort(RegAltNameIndices.begin(), RegAltNameIndices.end(), LessRecord());
+}
+
 /// getRegisterByName - If there is a register with the specific AsmName,
 /// return it.
 const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const {
diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h
index 9bedb9c..143daed 100644
--- a/utils/TableGen/CodeGenTarget.h
+++ b/utils/TableGen/CodeGenTarget.h
@@ -66,7 +66,9 @@
 
   mutable DenseMap<const Record*, CodeGenInstruction*> Instructions;
   mutable CodeGenRegBank *RegBank;
+  mutable std::vector<Record*> RegAltNameIndices;
   mutable std::vector<MVT::SimpleValueType> LegalValueTypes;
+  void ReadRegAltNameIndices() const;
   void ReadInstructions() const;
   void ReadLegalValueTypes() const;
 
@@ -100,6 +102,11 @@
   /// return it.
   const CodeGenRegister *getRegisterByName(StringRef Name) const;
 
+  const std::vector<Record*> &getRegAltNameIndices() const {
+    if (RegAltNameIndices.empty()) ReadRegAltNameIndices();
+    return RegAltNameIndices;
+  }
+
   const std::vector<CodeGenRegisterClass> &getRegisterClasses() const {
     return getRegBank().getRegClasses();
   }
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index 54553a8..c5897c7 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -224,6 +224,7 @@
   Record *LeafRec = DI->getDef();
   if (// Handle register references.  Nothing to do here, they always match.
       LeafRec->isSubClassOf("RegisterClass") ||
+      LeafRec->isSubClassOf("RegisterOperand") ||
       LeafRec->isSubClassOf("PointerLikeRegClass") ||
       LeafRec->isSubClassOf("SubRegIndex") ||
       // Place holder for SRCVALUE nodes. Nothing to do here.
@@ -579,15 +580,16 @@
 
   // If this is an explicit register reference, handle it.
   if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
-    if (DI->getDef()->isSubClassOf("Register")) {
+    Record *Def = DI->getDef();
+    if (Def->isSubClassOf("Register")) {
       const CodeGenRegister *Reg =
-        CGP.getTargetInfo().getRegBank().getReg(DI->getDef());
+        CGP.getTargetInfo().getRegBank().getReg(Def);
       AddMatcher(new EmitRegisterMatcher(Reg, N->getType(0)));
       ResultOps.push_back(NextRecordedOperandNo++);
       return;
     }
 
-    if (DI->getDef()->getName() == "zero_reg") {
+    if (Def->getName() == "zero_reg") {
       AddMatcher(new EmitRegisterMatcher(0, N->getType(0)));
       ResultOps.push_back(NextRecordedOperandNo++);
       return;
@@ -595,16 +597,18 @@
 
     // Handle a reference to a register class. This is used
     // in COPY_TO_SUBREG instructions.
-    if (DI->getDef()->isSubClassOf("RegisterClass")) {
-      std::string Value = getQualifiedName(DI->getDef()) + "RegClassID";
+    if (Def->isSubClassOf("RegisterOperand"))
+      Def = Def->getValueAsDef("RegClass");
+    if (Def->isSubClassOf("RegisterClass")) {
+      std::string Value = getQualifiedName(Def) + "RegClassID";
       AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
       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());
+    if (Def->isSubClassOf("SubRegIndex")) {
+      std::string Value = getQualifiedName(Def);
       AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
       ResultOps.push_back(NextRecordedOperandNo++);
       return;
diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp
index f946ac7..f54e8df 100644
--- a/utils/TableGen/FastISelEmitter.cpp
+++ b/utils/TableGen/FastISelEmitter.cpp
@@ -248,6 +248,8 @@
       
       // For now, the only other thing we accept is register operands.
       const CodeGenRegisterClass *RC = 0;
+      if (OpLeafRec->isSubClassOf("RegisterOperand"))
+        OpLeafRec = OpLeafRec->getValueAsDef("RegClass");
       if (OpLeafRec->isSubClassOf("RegisterClass"))
         RC = &Target.getRegisterClass(OpLeafRec);
       else if (OpLeafRec->isSubClassOf("Register"))
@@ -454,6 +456,8 @@
     std::string SubRegNo;
     if (Op->getName() != "EXTRACT_SUBREG") {
       Record *Op0Rec = II.Operands[0].Rec;
+      if (Op0Rec->isSubClassOf("RegisterOperand"))
+        Op0Rec = Op0Rec->getValueAsDef("RegClass");
       if (!Op0Rec->isSubClassOf("RegisterClass"))
         continue;
       DstRC = &Target.getRegisterClass(Op0Rec);
diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp
index 9312fe8..ba6cd86 100644
--- a/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -1305,8 +1305,10 @@
       RecordRecTy *Type = dynamic_cast<RecordRecTy*>(TI->getType());
       Record *TypeRecord = Type->getRecord();
       bool isReg = false;
+      if (TypeRecord->isSubClassOf("RegisterOperand"))
+        TypeRecord = TypeRecord->getValueAsDef("RegClass");
       if (TypeRecord->isSubClassOf("RegisterClass")) {
-        Decoder = "Decode" + Type->getRecord()->getName() + "RegisterClass";
+        Decoder = "Decode" + TypeRecord->getName() + "RegisterClass";
         isReg = true;
       }
 
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
index fc544ee..6a96696 100644
--- a/utils/TableGen/InstrInfoEmitter.cpp
+++ b/utils/TableGen/InstrInfoEmitter.cpp
@@ -43,10 +43,10 @@
   std::vector<Record*> DefList =
   Records.getAllDerivedDefinitions("InstrItinClass");
   std::sort(DefList.begin(), DefList.end(), LessRecord());
-  
+
   for (unsigned i = 0, N = DefList.size(); i < N; i++)
     ItinClassMap[DefList[i]->getName()] = i;
-}  
+}
 
 unsigned InstrInfoEmitter::getItinClassNumber(const Record *InstRec) {
   return ItinClassMap[InstRec->getValueAsDef("Itinerary")->getName()];
@@ -59,7 +59,7 @@
 std::vector<std::string>
 InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
   std::vector<std::string> Result;
-  
+
   for (unsigned i = 0, e = Inst.Operands.size(); i != e; ++i) {
     // Handle aggregate operands and normal operands the same way by expanding
     // either case into a list of operands for this op.
@@ -70,7 +70,7 @@
     // operand, which has a single operand, but no declared class for the
     // operand.
     DagInit *MIOI = Inst.Operands[i].MIOperandInfo;
-    
+
     if (!MIOI || MIOI->getNumArgs() == 0) {
       // Single, anonymous, operand.
       OperandList.push_back(Inst.Operands[i]);
@@ -86,7 +86,9 @@
     for (unsigned j = 0, e = OperandList.size(); j != e; ++j) {
       Record *OpR = OperandList[j].Rec;
       std::string Res;
-      
+
+      if (OpR->isSubClassOf("RegisterOperand"))
+        OpR = OpR->getValueAsDef("RegClass");
       if (OpR->isSubClassOf("RegisterClass"))
         Res += getQualifiedName(OpR) + "RegClassID, ";
       else if (OpR->isSubClassOf("PointerLikeRegClass"))
@@ -94,10 +96,10 @@
       else
         // -1 means the operand does not have a fixed register class.
         Res += "-1, ";
-      
+
       // Fill in applicable flags.
       Res += "0";
-        
+
       // Ptr value whose register class is resolved via callback.
       if (OpR->isSubClassOf("PointerLikeRegClass"))
         Res += "|(1<<TOI::LookupPtrRegClass)";
@@ -106,7 +108,7 @@
       // was of type PredicateOperand.
       if (Inst.Operands[i].Rec->isSubClassOf("PredicateOperand"))
         Res += "|(1<<TOI::Predicate)";
-        
+
       // Optional def operands.  Check to see if the original unexpanded operand
       // was of type OptionalDefOperand.
       if (Inst.Operands[i].Rec->isSubClassOf("OptionalDefOperand"))
@@ -114,7 +116,7 @@
 
       // Fill in constraint info.
       Res += ", ";
-      
+
       const CGIOperandList::ConstraintInfo &Constraint =
         Inst.Operands[i].Constraints[j];
       if (Constraint.isNone())
@@ -126,7 +128,7 @@
         Res += "((" + utostr(Constraint.getTiedOperand()) +
                     " << 16) | (1 << TOI::TIED_TO))";
       }
-        
+
       Result.push_back(Res);
     }
   }
@@ -134,12 +136,12 @@
   return Result;
 }
 
-void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, 
+void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
                                        OperandInfoMapTy &OperandInfoIDs) {
   // ID #0 is for no operand info.
   unsigned OperandListNum = 0;
   OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum;
-  
+
   OS << "\n";
   const CodeGenTarget &Target = CDP.getTargetInfo();
   for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
@@ -147,7 +149,7 @@
     std::vector<std::string> OperandInfo = GetOperandInfo(**II);
     unsigned &N = OperandInfoIDs[OperandInfo];
     if (N != 0) continue;
-    
+
     N = ++OperandListNum;
     OS << "static const TargetOperandInfo OperandInfo" << N << "[] = { ";
     for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i)
@@ -205,7 +207,7 @@
   std::map<std::vector<Record*>, unsigned> EmittedBarriers;
   unsigned BarrierNumber = 0;
   std::map<Record*, unsigned> BarriersMap;
- 
+
   // Emit all of the instruction's implicit uses and defs.
   for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
          E = Target.inst_end(); II != E; ++II) {
@@ -231,10 +233,10 @@
   }
 
   OperandInfoMapTy OperandInfoIDs;
-  
+
   // Emit all of the operand info records.
   EmitOperandInfo(OS, OperandInfoIDs);
-  
+
   // Emit all of the TargetInstrDesc records in their ENUM ordering.
   //
   OS << "\nstatic const TargetInstrDesc " << TargetName
diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp
index 3c750da..730eca1 100644
--- a/utils/TableGen/Record.cpp
+++ b/utils/TableGen/Record.cpp
@@ -1443,6 +1443,25 @@
   return Ints;
 }
 
+/// getValueAsListOfStrings - This method looks up the specified field and
+/// returns its value as a vector of strings, throwing an exception if the
+/// field does not exist or if the value is not the right type.
+///
+std::vector<std::string>
+Record::getValueAsListOfStrings(StringRef FieldName) const {
+  ListInit *List = getValueAsListInit(FieldName);
+  std::vector<std::string> Strings;
+  for (unsigned i = 0; i < List->getSize(); i++) {
+    if (StringInit *II = dynamic_cast<StringInit*>(List->getElement(i))) {
+      Strings.push_back(II->getValue());
+    } else {
+      throw "Record `" + getName() + "', field `" + FieldName.str() +
+            "' does not have a list of strings initializer!";
+    }
+  }
+  return Strings;
+}
+
 /// getValueAsDef - This method looks up the specified field and returns its
 /// value as a Record, throwing an exception if the field does not exist or if
 /// the value is not the right type.
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index c8905cc..f24f5e6 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -1368,6 +1368,12 @@
   ///
   std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const;
 
+  /// getValueAsListOfStrings - This method looks up the specified field and
+  /// returns its value as a vector of strings, throwing an exception if the
+  /// field does not exist or if the value is not the right type.
+  ///
+  std::vector<std::string> getValueAsListOfStrings(StringRef FieldName) const;
+
   /// getValueAsDef - This method looks up the specified field and returns its
   /// value as a Record, throwing an exception if the field does not exist or if
   /// the value is not the right type.
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index ab081eb..f8ce3ac 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -112,6 +112,18 @@
     OS << "0 };\n";
   }
 
+  const std::vector<Record*> RegAltNameIndices = Target.getRegAltNameIndices();
+  // If the only definition is the default NoRegAltName, we don't need to
+  // emit anything.
+  if (RegAltNameIndices.size() > 1) {
+    OS << "\n// Register alternate name indices\n";
+    OS << "enum {\n";
+    for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i)
+      OS << "  " << RegAltNameIndices[i]->getName() << ",\t// " << i << "\n";
+    OS << "  NUM_TARGET_REG_ALT_NAMES = " << RegAltNameIndices.size() << "\n";
+    OS << "};\n";
+  }
+
   // Emit the empty sub-registers list
   OS << "  const unsigned Empty_SubRegsSet[] = { 0 };\n";
   // Loop over all of the registers which have sub-registers, emitting the