[llvm-commits] [llvm] r133940 - in /llvm/trunk: include/llvm/Target/ utils/TableGen/

Owen Anderson resistor at mac.com
Mon Jun 27 14:06:21 PDT 2011


Author: resistor
Date: Mon Jun 27 16:06:21 2011
New Revision: 133940

URL: http://llvm.org/viewvc/llvm-project?rev=133940&view=rev
Log:
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.

Modified:
    llvm/trunk/include/llvm/Target/Target.td
    llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
    llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
    llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
    llvm/trunk/utils/TableGen/CodeGenTarget.cpp
    llvm/trunk/utils/TableGen/CodeGenTarget.h
    llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp
    llvm/trunk/utils/TableGen/FastISelEmitter.cpp
    llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp
    llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
    llvm/trunk/utils/TableGen/Record.cpp
    llvm/trunk/utils/TableGen/Record.h
    llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp

Modified: llvm/trunk/include/llvm/Target/Target.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/Target.td (original)
+++ llvm/trunk/include/llvm/Target/Target.td Mon Jun 27 16:06:21 2011
@@ -26,11 +26,19 @@
   string Namespace = "";
 }
 
+// RegAltNameIndex - The alternate name set to use for register operands of
+// this register class when printing.
+class RegAltNameIndex {
+  string Namespace = "";
+}
+def NoRegAltName : RegAltNameIndex;
+
 // Register - You should define one instance of this class for each register
 // in the target machine.  String n will become the "name" of the register.
-class Register<string n> {
+class Register<string n, list<string> altNames = []> {
   string Namespace = "";
   string AsmName = n;
+  list<string> AltNames = altNames;
 
   // Aliases - A list of registers that this register overlaps with.  A read or
   // modification of this register can potentially read or modify the aliased
@@ -48,6 +56,10 @@
   // SubRegs.
   list<SubRegIndex> SubRegIndices = [];
 
+  // RegAltNameIndices - The alternate name indices which are valid for this
+  // register.
+  list<RegAltNameIndex> RegAltNameIndices = [];
+
   // CompositeIndices - Specify subreg indices that don't correspond directly to
   // a register in SubRegs and are not inherited. The following formats are
   // supported:
@@ -92,7 +104,7 @@
 // registers by register allocators.
 //
 class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
-                    dag regList> {
+                    dag regList, RegAltNameIndex idx = NoRegAltName> {
   string Namespace = namespace;
 
   // RegType - Specify the list ValueType of the registers in this register
@@ -124,6 +136,11 @@
   //
   dag MemberList = regList;
 
+  // AltNameIndex - The alternate register name to use when printing operands
+  // of this register class. Every register in the register class must have
+  // a valid alternate name for the given index.
+  RegAltNameIndex altNameIndex = idx;
+
   // SubRegClasses - Specify the register class of subregisters as a list of
   // dags: (RegClass SubRegIndex, SubRegindex, ...)
   list<dag> SubRegClasses = [];
@@ -466,6 +483,24 @@
   AsmOperandClass ParserMatchClass = ImmAsmOperand;
 }
 
+class RegisterOperand<RegisterClass regclass, string pm = "printOperand"> {
+  // RegClass - The register class of the operand.
+  RegisterClass RegClass = regclass;
+  // PrintMethod - The target method to call to print register operands of
+  // this type. The method normally will just use an alt-name index to look
+  // up the name to print. Default to the generic printOperand().
+  string PrintMethod = pm;
+  // ParserMatchClass - The "match class" that operands of this type fit
+  // in. Match classes are used to define the order in which instructions are
+  // match, to ensure that which instructions gets matched is deterministic.
+  //
+  // The target specific parser must be able to classify an parsed operand into
+  // a unique class, which does not partially overlap with any other classes. It
+  // can match a subset of some other class, in which case the AsmOperandClass
+  // should declare the other operand as one of its super classes.
+  AsmOperandClass ParserMatchClass;
+}
+
 def i1imm  : Operand<i1>;
 def i8imm  : Operand<i8>;
 def i16imm : Operand<i16>;

Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Mon Jun 27 16:06:21 2011
@@ -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;

Modified: llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp Mon Jun 27 16:06:21 2011
@@ -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);
+
+  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 << "  return AsmStrs+RegAsmOffset[RegNo-1];\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);

Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Mon Jun 27 16:06:21 2011
@@ -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!");

Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp Mon Jun 27 16:06:21 2011
@@ -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;
 

Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Mon Jun 27 16:06:21 2011
@@ -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 {

Modified: llvm/trunk/utils/TableGen/CodeGenTarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.h?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenTarget.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenTarget.h Mon Jun 27 16:06:21 2011
@@ -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();
   }

Modified: llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp Mon Jun 27 16:06:21 2011
@@ -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;

Modified: llvm/trunk/utils/TableGen/FastISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FastISelEmitter.cpp?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/FastISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/FastISelEmitter.cpp Mon Jun 27 16:06:21 2011
@@ -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);

Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp Mon Jun 27 16:06:21 2011
@@ -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;
       }
 

Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Mon Jun 27 16:06:21 2011
@@ -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

Modified: llvm/trunk/utils/TableGen/Record.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.cpp?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/Record.cpp (original)
+++ llvm/trunk/utils/TableGen/Record.cpp Mon Jun 27 16:06:21 2011
@@ -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.

Modified: llvm/trunk/utils/TableGen/Record.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.h?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/Record.h (original)
+++ llvm/trunk/utils/TableGen/Record.h Mon Jun 27 16:06:21 2011
@@ -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.

Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=133940&r1=133939&r2=133940&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Mon Jun 27 16:06:21 2011
@@ -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





More information about the llvm-commits mailing list