factor the operand list (and related fields/operations) out of
authorChris Lattner <sabre@nondot.org>
Mon, 1 Nov 2010 04:03:32 +0000 (04:03 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 1 Nov 2010 04:03:32 +0000 (04:03 +0000)
CodeGenInstruction into its own helper class.  No functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117893 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
utils/TableGen/ARMDecoderEmitter.cpp
utils/TableGen/AsmMatcherEmitter.cpp
utils/TableGen/AsmWriterInst.cpp
utils/TableGen/CodeEmitterGen.cpp
utils/TableGen/CodeGenDAGPatterns.cpp
utils/TableGen/CodeGenInstruction.cpp
utils/TableGen/CodeGenInstruction.h
utils/TableGen/DAGISelMatcherGen.cpp
utils/TableGen/EDEmitter.cpp
utils/TableGen/FastISelEmitter.cpp
utils/TableGen/InstrInfoEmitter.cpp
utils/TableGen/X86RecognizableInstr.cpp
utils/TableGen/X86RecognizableInstr.h

index 89b3b8354c996aa056973511999a3c45565a101c..533fca0db0ae9646c5b3617ff1b9fd8a4714e4b6 100644 (file)
@@ -1763,8 +1763,8 @@ bool ARMDecoderEmitter::ARMDEBackend::populateInstruction(
       errs() << '\n';
 
       // Dumps the list of operand info.
-      for (unsigned i = 0, e = CGI.OperandList.size(); i != e; ++i) {
-        CodeGenInstruction::OperandInfo Info = CGI.OperandList[i];
+      for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) {
+        const CGIOperandList::OperandInfo &Info = CGI.Operands[i];
         const std::string &OperandName = Info.Name;
         const Record &OperandDef = *Info.Rec;
 
index 3f4594c4e3e679ca052ca2ac62d51cf84923826a..254a719959fae433280b6f8d2f8b9251a29d7e9e 100644 (file)
@@ -386,7 +386,7 @@ struct InstructionInfo {
     ClassInfo *Class;
 
     /// The original operand this corresponds to, if any.
-    const CodeGenInstruction::OperandInfo *OperandInfo;
+    const CGIOperandList::OperandInfo *OperandInfo;
   };
 
   /// InstrName - The target name for this instruction.
@@ -536,7 +536,7 @@ private:
 
   /// getOperandClass - Lookup or create the class for the given operand.
   ClassInfo *getOperandClass(StringRef Token,
-                             const CodeGenInstruction::OperandInfo &OI);
+                             const CGIOperandList::OperandInfo &OI);
 
   /// BuildRegisterClasses - Build the ClassInfo* instances for register
   /// classes.
@@ -587,7 +587,7 @@ void InstructionInfo::dump() {
       continue;
     }
 
-    const CodeGenInstruction::OperandInfo &OI = *Op.OperandInfo;
+    const CGIOperandList::OperandInfo &OI = *Op.OperandInfo;
     errs() << OI.Name << " " << OI.Rec->getName()
            << " (" << OI.MIOperandNo << ", " << OI.MINumOperands << ")\n";
   }
@@ -665,7 +665,7 @@ ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
 
 ClassInfo *
 AsmMatcherInfo::getOperandClass(StringRef Token,
-                                const CodeGenInstruction::OperandInfo &OI) {
+                                const CGIOperandList::OperandInfo &OI) {
   if (OI.Rec->isSubClassOf("RegisterClass")) {
     ClassInfo *CI = RegisterClassClasses[OI.Rec];
 
@@ -945,7 +945,8 @@ void AsmMatcherInfo::BuildInfo() {
 
     Instructions.push_back(II.take());
   }
+  
+
   // Build info for the register classes.
   BuildRegisterClasses(SingletonRegisters);
 
@@ -998,7 +999,7 @@ void AsmMatcherInfo::BuildInfo() {
 
       // Map this token to an operand. FIXME: Move elsewhere.
       unsigned Idx;
-      if (!II->Instr->hasOperandNamed(OperandName, Idx))
+      if (!II->Instr->Operands.hasOperandNamed(OperandName, Idx))
         throw std::string("error: unable to find operand: '" +
                           OperandName.str() + "'");
 
@@ -1006,15 +1007,15 @@ void AsmMatcherInfo::BuildInfo() {
       // XCHG8rm). What we want is the untied operand, which we now have to
       // grovel for. Only worry about this for single entry operands, we have to
       // clean this up anyway.
-      const CodeGenInstruction::OperandInfo *OI = &II->Instr->OperandList[Idx];
+      const CGIOperandList::OperandInfo *OI = &II->Instr->Operands[Idx];
       if (OI->Constraints[0].isTied()) {
         unsigned TiedOp = OI->Constraints[0].getTiedOperand();
 
         // The tied operand index is an MIOperand index, find the operand that
         // contains it.
-        for (unsigned i = 0, e = II->Instr->OperandList.size(); i != e; ++i) {
-          if (II->Instr->OperandList[i].MIOperandNo == TiedOp) {
-            OI = &II->Instr->OperandList[i];
+        for (unsigned i = 0, e = II->Instr->Operands.size(); i != e; ++i) {
+          if (II->Instr->Operands[i].MIOperandNo == TiedOp) {
+            OI = &II->Instr->Operands[i];
             break;
           }
         }
@@ -1086,10 +1087,10 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
 
     // Find any tied operands.
     SmallVector<std::pair<unsigned, unsigned>, 4> TiedOperands;
-    for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) {
-      const CodeGenInstruction::OperandInfo &OpInfo = II.Instr->OperandList[i];
+    for (unsigned i = 0, e = II.Instr->Operands.size(); i != e; ++i) {
+      const CGIOperandList::OperandInfo &OpInfo = II.Instr->Operands[i];
       for (unsigned j = 0, e = OpInfo.Constraints.size(); j != e; ++j) {
-        const CodeGenInstruction::ConstraintInfo &CI = OpInfo.Constraints[j];
+        const CGIOperandList::ConstraintInfo &CI = OpInfo.Constraints[j];
         if (CI.isTied())
           TiedOperands.push_back(std::make_pair(OpInfo.MIOperandNo + j,
                                                 CI.getTiedOperand()));
@@ -1100,8 +1101,8 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
 
     // Compute the total number of operands.
     unsigned NumMIOperands = 0;
-    for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) {
-      const CodeGenInstruction::OperandInfo &OI = II.Instr->OperandList[i];
+    for (unsigned i = 0, e = II.Instr->Operands.size(); i != e; ++i) {
+      const CGIOperandList::OperandInfo &OI = II.Instr->Operands[i];
       NumMIOperands = std::max(NumMIOperands,
                                OI.MIOperandNo + OI.MINumOperands);
     }
index 7989406d6fa23fd16afefa47273941974205e0ec..fdf447f2aaf386509a965ea1d81be322a1fe9c4e 100644 (file)
@@ -198,8 +198,8 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
                                             Modifier));
       } else {
         // Otherwise, normal operand.
-        unsigned OpNo = CGI.getOperandNamed(VarName);
-        CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
+        unsigned OpNo = CGI.Operands.getOperandNamed(VarName);
+        CGIOperandList::OperandInfo OpInfo = CGI.Operands[OpNo];
         
         unsigned MIOp = OpInfo.MIOperandNo;
         Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, 
index b7b62d502b08138f838a8a9f1ac5fcb66316122d..631075263e4681ddd6fb568972a4a1ab3760fe2b 100644 (file)
@@ -158,21 +158,22 @@ void CodeEmitterGen::run(raw_ostream &o) {
               // operand number. Non-matching operands are assumed to be in
               // order.
               unsigned OpIdx;
-              if (CGI.hasOperandNamed(VarName, OpIdx)) {
+              if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) {
                 // Get the machine operand number for the indicated operand.
-                OpIdx = CGI.OperandList[OpIdx].MIOperandNo;
-                assert (!CGI.isFlatOperandNotEmitted(OpIdx) &&
+                OpIdx = CGI.Operands[OpIdx].MIOperandNo;
+                assert (!CGI.Operands.isFlatOperandNotEmitted(OpIdx) &&
                         "Explicitly used operand also marked as not emitted!");
               } else {
                 /// If this operand is not supposed to be emitted by the
                 /// generated emitter, skip it.
-                while (CGI.isFlatOperandNotEmitted(NumberedOp))
+                while (CGI.Operands.isFlatOperandNotEmitted(NumberedOp))
                   ++NumberedOp;
                 OpIdx = NumberedOp++;
               }
-              std::pair<unsigned, unsigned> SO = CGI.getSubOperandNumber(OpIdx);
+              std::pair<unsigned, unsigned> SO =
+                CGI.Operands.getSubOperandNumber(OpIdx);
               std::string &EncoderMethodName =
-                CGI.OperandList[SO.first].EncoderMethodName;
+                CGI.Operands[SO.first].EncoderMethodName;
 
               // If the source operand has a custom encoder, use it. This will
               // get the encoding for all of the suboperands.
index 6f54191498188b9bc62665f423a8af44c91ced9b..6c89453ce4cb8a240a61e8671fcd4b5d3a3ad2d5 100644 (file)
@@ -829,7 +829,7 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) {
     CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(Operator);
 
     // FIXME: Should allow access to all the results here.
-    unsigned NumDefsToAdd = InstInfo.NumDefs ? 1 : 0;
+    unsigned NumDefsToAdd = InstInfo.Operands.NumDefs ? 1 : 0;
     
     // Add on one implicit def if it has a resolvable type.
     if (InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()) !=MVT::Other)
@@ -1314,7 +1314,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
     // Apply the result types to the node, these come from the things in the
     // (outs) list of the instruction.
     // FIXME: Cap at one result so far.
-    unsigned NumResultsToAdd = InstInfo.NumDefs ? 1 : 0;
+    unsigned NumResultsToAdd = InstInfo.Operands.NumDefs ? 1 : 0;
     for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo) {
       Record *ResultNode = Inst.getResult(ResNo);
       
@@ -2258,7 +2258,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst,
     HasSideEffects = true;
   }
   
-  if (Inst.isVariadic)
+  if (Inst.Operands.isVariadic)
     IsVariadic = true;  // Can warn if we want.
 }
 
@@ -2283,18 +2283,18 @@ void CodeGenDAGPatterns::ParseInstructions() {
       
       CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]);
 
-      if (InstInfo.OperandList.size() != 0) {
-        if (InstInfo.NumDefs == 0) {
+      if (InstInfo.Operands.size() != 0) {
+        if (InstInfo.Operands.NumDefs == 0) {
           // These produce no results
-          for (unsigned j = 0, e = InstInfo.OperandList.size(); j < e; ++j)
-            Operands.push_back(InstInfo.OperandList[j].Rec);
+          for (unsigned j = 0, e = InstInfo.Operands.size(); j < e; ++j)
+            Operands.push_back(InstInfo.Operands[j].Rec);
         } else {
           // Assume the first operand is the result.
-          Results.push_back(InstInfo.OperandList[0].Rec);
+          Results.push_back(InstInfo.Operands[0].Rec);
       
           // The rest are inputs.
-          for (unsigned j = 1, e = InstInfo.OperandList.size(); j < e; ++j)
-            Operands.push_back(InstInfo.OperandList[j].Rec);
+          for (unsigned j = 1, e = InstInfo.Operands.size(); j < e; ++j)
+            Operands.push_back(InstInfo.Operands[j].Rec);
         }
       }
       
@@ -2351,10 +2351,10 @@ void CodeGenDAGPatterns::ParseInstructions() {
     std::vector<Record*> Results;
     TreePatternNode *Res0Node = 0;
     for (unsigned i = 0; i != NumResults; ++i) {
-      if (i == CGI.OperandList.size())
+      if (i == CGI.Operands.size())
         I->error("'" + InstResults.begin()->first +
                  "' set but does not appear in operand list!");
-      const std::string &OpName = CGI.OperandList[i].Name;
+      const std::string &OpName = CGI.Operands[i].Name;
       
       // Check that it exists in InstResults.
       TreePatternNode *RNode = InstResults[OpName];
@@ -2368,11 +2368,11 @@ void CodeGenDAGPatterns::ParseInstructions() {
         I->error("Operand $" + OpName + " should be a set destination: all "
                  "outputs must occur before inputs in operand list!");
       
-      if (CGI.OperandList[i].Rec != R)
+      if (CGI.Operands[i].Rec != R)
         I->error("Operand $" + OpName + " class mismatch!");
       
       // Remember the return type.
-      Results.push_back(CGI.OperandList[i].Rec);
+      Results.push_back(CGI.Operands[i].Rec);
       
       // Okay, this one checks out.
       InstResults.erase(OpName);
@@ -2384,8 +2384,8 @@ void CodeGenDAGPatterns::ParseInstructions() {
 
     std::vector<TreePatternNode*> ResultNodeOperands;
     std::vector<Record*> Operands;
-    for (unsigned i = NumResults, e = CGI.OperandList.size(); i != e; ++i) {
-      CodeGenInstruction::OperandInfo &Op = CGI.OperandList[i];
+    for (unsigned i = NumResults, e = CGI.Operands.size(); i != e; ++i) {
+      CGIOperandList::OperandInfo &Op = CGI.Operands[i];
       const std::string &OpName = Op.Name;
       if (OpName.empty())
         I->error("Operand #" + utostr(i) + " in operands list has no name!");
@@ -2569,7 +2569,7 @@ void CodeGenDAGPatterns::InferInstructionFlags() {
     InstInfo.mayStore = MayStore;
     InstInfo.mayLoad = MayLoad;
     InstInfo.hasSideEffects = HasSideEffects;
-    InstInfo.isVariadic = IsVariadic;
+    InstInfo.Operands.isVariadic = IsVariadic;
   }
 }
 
index 259e7c36a4c5ae87677e8687406868957b02d88d..5eceaeb015ccb8fd551bec0082dde0accbc22533 100644 (file)
 #include <set>
 using namespace llvm;
 
-static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) {
-  // EARLY_CLOBBER: @early $reg
-  std::string::size_type wpos = CStr.find_first_of(" \t");
-  std::string::size_type start = CStr.find_first_not_of(" \t");
-  std::string Tok = CStr.substr(start, wpos - start);
-  if (Tok == "@earlyclobber") {
-    std::string Name = CStr.substr(wpos+1);
-    wpos = Name.find_first_not_of(" \t");
-    if (wpos == std::string::npos)
-      throw "Illegal format for @earlyclobber constraint: '" + CStr + "'";
-    Name = Name.substr(wpos);
-    std::pair<unsigned,unsigned> Op =
-      I->ParseOperandName(Name, false);
-
-    // Build the string for the operand
-    if (!I->OperandList[Op.first].Constraints[Op.second].isNone())
-      throw "Operand '" + Name + "' cannot have multiple constraints!";
-    I->OperandList[Op.first].Constraints[Op.second] =
-      CodeGenInstruction::ConstraintInfo::getEarlyClobber();
-    return;
-  }
-
-  // Only other constraint is "TIED_TO" for now.
-  std::string::size_type pos = CStr.find_first_of('=');
-  assert(pos != std::string::npos && "Unrecognized constraint");
-  start = CStr.find_first_not_of(" \t");
-  std::string Name = CStr.substr(start, pos - start);
-
-  // TIED_TO: $src1 = $dst
-  wpos = Name.find_first_of(" \t");
-  if (wpos == std::string::npos)
-    throw "Illegal format for tied-to constraint: '" + CStr + "'";
-  std::string DestOpName = Name.substr(0, wpos);
-  std::pair<unsigned,unsigned> DestOp = I->ParseOperandName(DestOpName, false);
-
-  Name = CStr.substr(pos+1);
-  wpos = Name.find_first_not_of(" \t");
-  if (wpos == std::string::npos)
-    throw "Illegal format for tied-to constraint: '" + CStr + "'";
-
-  std::pair<unsigned,unsigned> SrcOp =
-  I->ParseOperandName(Name.substr(wpos), false);
-  if (SrcOp > DestOp)
-    throw "Illegal tied-to operand constraint '" + CStr + "'";
-
-
-  unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp);
-
-  if (!I->OperandList[DestOp.first].Constraints[DestOp.second].isNone())
-    throw "Operand '" + DestOpName + "' cannot have multiple constraints!";
-  I->OperandList[DestOp.first].Constraints[DestOp.second] =
-    CodeGenInstruction::ConstraintInfo::getTied(FlatOpNo);
-}
-
-static void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) {
-  // Make sure the constraints list for each operand is large enough to hold
-  // constraint info, even if none is present.
-  for (unsigned i = 0, e = I->OperandList.size(); i != e; ++i)
-    I->OperandList[i].Constraints.resize(I->OperandList[i].MINumOperands);
-
-  if (CStr.empty()) return;
-
-  const std::string delims(",");
-  std::string::size_type bidx, eidx;
-
-  bidx = CStr.find_first_not_of(delims);
-  while (bidx != std::string::npos) {
-    eidx = CStr.find_first_of(delims, bidx);
-    if (eidx == std::string::npos)
-      eidx = CStr.length();
-
-    ParseConstraint(CStr.substr(bidx, eidx - bidx), I);
-    bidx = CStr.find_first_not_of(delims, eidx);
-  }
-}
-
-CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R) {
-  Namespace = R->getValueAsString("Namespace");
-  AsmString = R->getValueAsString("AsmString");
+//===----------------------------------------------------------------------===//
+// CGIOperandList Implementation
+//===----------------------------------------------------------------------===//
 
-  isReturn     = R->getValueAsBit("isReturn");
-  isBranch     = R->getValueAsBit("isBranch");
-  isIndirectBranch = R->getValueAsBit("isIndirectBranch");
-  isCompare    = R->getValueAsBit("isCompare");
-  isBarrier    = R->getValueAsBit("isBarrier");
-  isCall       = R->getValueAsBit("isCall");
-  canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
-  mayLoad      = R->getValueAsBit("mayLoad");
-  mayStore     = R->getValueAsBit("mayStore");
-  isPredicable = R->getValueAsBit("isPredicable");
-  isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
-  isCommutable = R->getValueAsBit("isCommutable");
-  isTerminator = R->getValueAsBit("isTerminator");
-  isReMaterializable = R->getValueAsBit("isReMaterializable");
-  hasDelaySlot = R->getValueAsBit("hasDelaySlot");
-  usesCustomInserter = R->getValueAsBit("usesCustomInserter");
-  hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
-  isNotDuplicable = R->getValueAsBit("isNotDuplicable");
-  hasSideEffects = R->getValueAsBit("hasSideEffects");
-  neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
-  isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove");
-  hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq");
-  hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq");
+CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
+  isPredicable = false;
   hasOptionalDef = false;
   isVariadic = false;
-  ImplicitDefs = R->getValueAsListOfDefs("Defs");
-  ImplicitUses = R->getValueAsListOfDefs("Uses");
-
-  if (neverHasSideEffects + hasSideEffects > 1)
-    throw R->getName() + ": multiple conflicting side-effect flags set!";
-
+  
   DagInit *OutDI = R->getValueAsDag("OutOperandList");
-
+  
   if (DefInit *Init = dynamic_cast<DefInit*>(OutDI->getOperator())) {
     if (Init->getDef()->getName() != "outs")
       throw R->getName() + ": invalid def name for output list: use 'outs'";
   } else
     throw R->getName() + ": invalid output list: use 'outs'";
-    
+  
   NumDefs = OutDI->getNumArgs();
-    
+
   DagInit *InDI = R->getValueAsDag("InOperandList");
   if (DefInit *Init = dynamic_cast<DefInit*>(InDI->getOperator())) {
     if (Init->getDef()->getName() != "ins")
       throw R->getName() + ": invalid def name for input list: use 'ins'";
   } else
     throw R->getName() + ": invalid input list: use 'ins'";
-    
+  
   unsigned MIOperandNo = 0;
   std::set<std::string> OperandNames;
   for (unsigned i = 0, e = InDI->getNumArgs()+OutDI->getNumArgs(); i != e; ++i){
@@ -163,7 +61,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R) {
     DefInit *Arg = dynamic_cast<DefInit*>(ArgInit);
     if (!Arg)
       throw "Illegal operand for the '" + R->getName() + "' instruction!";
-
+    
     Record *Rec = Arg->getDef();
     std::string PrintMethod = "printOperand";
     std::string EncoderMethod;
@@ -175,19 +73,19 @@ CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R) {
       if (Rec->getValue("EncoderMethod"))
         EncoderMethod = Rec->getValueAsString("EncoderMethod");
       MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
-
+      
       // Verify that MIOpInfo has an 'ops' root value.
       if (!dynamic_cast<DefInit*>(MIOpInfo->getOperator()) ||
           dynamic_cast<DefInit*>(MIOpInfo->getOperator())
-               ->getDef()->getName() != "ops")
+          ->getDef()->getName() != "ops")
         throw "Bad value for MIOperandInfo in operand '" + Rec->getName() +
-              "'\n";
-
+        "'\n";
+      
       // If we have MIOpInfo, then we have #operands equal to number of entries
       // in MIOperandInfo.
       if (unsigned NumArgs = MIOpInfo->getNumArgs())
         NumOps = NumArgs;
-
+      
       if (Rec->isSubClassOf("PredicateOperand"))
         isPredicable = true;
       else if (Rec->isSubClassOf("OptionalDefOperand"))
@@ -198,57 +96,38 @@ CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R) {
     } else if (!Rec->isSubClassOf("RegisterClass") &&
                Rec->getName() != "ptr_rc" && Rec->getName() != "unknown")
       throw "Unknown operand class '" + Rec->getName() +
-            "' in '" + R->getName() + "' instruction!";
-
+      "' in '" + R->getName() + "' instruction!";
+    
     // Check that the operand has a name and that it's unique.
     if (ArgName.empty())
       throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
-        " has no name!";
+      " has no name!";
     if (!OperandNames.insert(ArgName).second)
       throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
-        " has the same name as a previous operand!";
-
+      " has the same name as a previous operand!";
+    
     OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod, EncoderMethod,
                                       MIOperandNo, NumOps, MIOpInfo));
     MIOperandNo += NumOps;
   }
-
-  // Parse Constraints.
-  ParseConstraints(R->getValueAsString("Constraints"), this);
-
-  // Parse the DisableEncoding field.
-  std::string DisableEncoding = R->getValueAsString("DisableEncoding");
-  while (1) {
-    std::string OpName;
-    tie(OpName, DisableEncoding) = getToken(DisableEncoding, " ,\t");
-    if (OpName.empty()) break;
-
-    // Figure out which operand this is.
-    std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false);
-
-    // Mark the operand as not-to-be encoded.
-    if (Op.second >= OperandList[Op.first].DoNotEncode.size())
-      OperandList[Op.first].DoNotEncode.resize(Op.second+1);
-    OperandList[Op.first].DoNotEncode[Op.second] = true;
-  }
 }
 
+
 /// getOperandNamed - Return the index of the operand with the specified
 /// non-empty name.  If the instruction does not have an operand with the
 /// specified name, throw an exception.
 ///
-unsigned CodeGenInstruction::getOperandNamed(StringRef Name) const {
+unsigned CGIOperandList::getOperandNamed(StringRef Name) const {
   unsigned OpIdx;
   if (hasOperandNamed(Name, OpIdx)) return OpIdx;
-  throw "Instruction '" + TheDef->getName() +
-        "' does not have an operand named '$" + Name.str() + "'!";
+  throw "'" + TheDef->getName() + "' does not have an operand named '$" + 
+    Name.str() + "'!";
 }
 
 /// hasOperandNamed - Query whether the instruction has an operand of the
 /// given name. If so, return true and set OpIdx to the index of the
 /// operand. Otherwise, return false.
-bool CodeGenInstruction::hasOperandNamed(StringRef Name,
-                                         unsigned &OpIdx) const {
+bool CGIOperandList::hasOperandNamed(StringRef Name, unsigned &OpIdx) const {
   assert(!Name.empty() && "Cannot search for operand with no name!");
   for (unsigned i = 0, e = OperandList.size(); i != e; ++i)
     if (OperandList[i].Name == Name) {
@@ -259,14 +138,13 @@ bool CodeGenInstruction::hasOperandNamed(StringRef Name,
 }
 
 std::pair<unsigned,unsigned>
-CodeGenInstruction::ParseOperandName(const std::string &Op,
-                                     bool AllowWholeOp) {
+CGIOperandList::ParseOperandName(const std::string &Op, bool AllowWholeOp) {
   if (Op.empty() || Op[0] != '$')
     throw TheDef->getName() + ": Illegal operand name: '" + Op + "'";
-
+  
   std::string OpName = Op.substr(1);
   std::string SubOpName;
-
+  
   // Check to see if this is $foo.bar.
   std::string::size_type DotIdx = OpName.find_first_of(".");
   if (DotIdx != std::string::npos) {
@@ -275,34 +153,169 @@ CodeGenInstruction::ParseOperandName(const std::string &Op,
       throw TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'";
     OpName = OpName.substr(0, DotIdx);
   }
-
+  
   unsigned OpIdx = getOperandNamed(OpName);
-
+  
   if (SubOpName.empty()) {  // If no suboperand name was specified:
     // If one was needed, throw.
     if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp &&
         SubOpName.empty())
       throw TheDef->getName() + ": Illegal to refer to"
-            " whole operand part of complex operand '" + Op + "'";
-
+      " whole operand part of complex operand '" + Op + "'";
+    
     // Otherwise, return the operand.
     return std::make_pair(OpIdx, 0U);
   }
-
+  
   // Find the suboperand number involved.
   DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo;
   if (MIOpInfo == 0)
     throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'";
-
+  
   // Find the operand with the right name.
   for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i)
     if (MIOpInfo->getArgName(i) == SubOpName)
       return std::make_pair(OpIdx, i);
-
+  
   // Otherwise, didn't find it!
   throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'";
 }
 
+static void ParseConstraint(const std::string &CStr, CGIOperandList &Ops) {
+  // EARLY_CLOBBER: @early $reg
+  std::string::size_type wpos = CStr.find_first_of(" \t");
+  std::string::size_type start = CStr.find_first_not_of(" \t");
+  std::string Tok = CStr.substr(start, wpos - start);
+  if (Tok == "@earlyclobber") {
+    std::string Name = CStr.substr(wpos+1);
+    wpos = Name.find_first_not_of(" \t");
+    if (wpos == std::string::npos)
+      throw "Illegal format for @earlyclobber constraint: '" + CStr + "'";
+    Name = Name.substr(wpos);
+    std::pair<unsigned,unsigned> Op = Ops.ParseOperandName(Name, false);
+    
+    // Build the string for the operand
+    if (!Ops[Op.first].Constraints[Op.second].isNone())
+      throw "Operand '" + Name + "' cannot have multiple constraints!";
+    Ops[Op.first].Constraints[Op.second] =
+    CGIOperandList::ConstraintInfo::getEarlyClobber();
+    return;
+  }
+  
+  // Only other constraint is "TIED_TO" for now.
+  std::string::size_type pos = CStr.find_first_of('=');
+  assert(pos != std::string::npos && "Unrecognized constraint");
+  start = CStr.find_first_not_of(" \t");
+  std::string Name = CStr.substr(start, pos - start);
+  
+  // TIED_TO: $src1 = $dst
+  wpos = Name.find_first_of(" \t");
+  if (wpos == std::string::npos)
+    throw "Illegal format for tied-to constraint: '" + CStr + "'";
+  std::string DestOpName = Name.substr(0, wpos);
+  std::pair<unsigned,unsigned> DestOp = Ops.ParseOperandName(DestOpName, false);
+  
+  Name = CStr.substr(pos+1);
+  wpos = Name.find_first_not_of(" \t");
+  if (wpos == std::string::npos)
+    throw "Illegal format for tied-to constraint: '" + CStr + "'";
+  
+  std::pair<unsigned,unsigned> SrcOp =
+  Ops.ParseOperandName(Name.substr(wpos), false);
+  if (SrcOp > DestOp)
+    throw "Illegal tied-to operand constraint '" + CStr + "'";
+  
+  
+  unsigned FlatOpNo = Ops.getFlattenedOperandNumber(SrcOp);
+  
+  if (!Ops[DestOp.first].Constraints[DestOp.second].isNone())
+    throw "Operand '" + DestOpName + "' cannot have multiple constraints!";
+  Ops[DestOp.first].Constraints[DestOp.second] =
+  CGIOperandList::ConstraintInfo::getTied(FlatOpNo);
+}
+
+static void ParseConstraints(const std::string &CStr, CGIOperandList &Ops) {
+  // Make sure the constraints list for each operand is large enough to hold
+  // constraint info, even if none is present.
+  for (unsigned i = 0, e = Ops.size(); i != e; ++i)
+    Ops[i].Constraints.resize(Ops[i].MINumOperands);
+  
+  if (CStr.empty()) return;
+  
+  const std::string delims(",");
+  std::string::size_type bidx, eidx;
+  
+  bidx = CStr.find_first_not_of(delims);
+  while (bidx != std::string::npos) {
+    eidx = CStr.find_first_of(delims, bidx);
+    if (eidx == std::string::npos)
+      eidx = CStr.length();
+    
+    ParseConstraint(CStr.substr(bidx, eidx - bidx), Ops);
+    bidx = CStr.find_first_not_of(delims, eidx);
+  }
+}
+
+void CGIOperandList::ProcessDisableEncoding(std::string DisableEncoding) {
+  while (1) {
+    std::string OpName;
+    tie(OpName, DisableEncoding) = getToken(DisableEncoding, " ,\t");
+    if (OpName.empty()) break;
+    
+    // Figure out which operand this is.
+    std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false);
+    
+    // Mark the operand as not-to-be encoded.
+    if (Op.second >= OperandList[Op.first].DoNotEncode.size())
+      OperandList[Op.first].DoNotEncode.resize(Op.second+1);
+    OperandList[Op.first].DoNotEncode[Op.second] = true;
+  }
+  
+}
+
+//===----------------------------------------------------------------------===//
+// CodeGenInstruction Implementation
+//===----------------------------------------------------------------------===//
+
+CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R), Operands(R) {
+  Namespace = R->getValueAsString("Namespace");
+  AsmString = R->getValueAsString("AsmString");
+
+  isReturn     = R->getValueAsBit("isReturn");
+  isBranch     = R->getValueAsBit("isBranch");
+  isIndirectBranch = R->getValueAsBit("isIndirectBranch");
+  isCompare    = R->getValueAsBit("isCompare");
+  isBarrier    = R->getValueAsBit("isBarrier");
+  isCall       = R->getValueAsBit("isCall");
+  canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
+  mayLoad      = R->getValueAsBit("mayLoad");
+  mayStore     = R->getValueAsBit("mayStore");
+  isPredicable = Operands.isPredicable || R->getValueAsBit("isPredicable");
+  isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
+  isCommutable = R->getValueAsBit("isCommutable");
+  isTerminator = R->getValueAsBit("isTerminator");
+  isReMaterializable = R->getValueAsBit("isReMaterializable");
+  hasDelaySlot = R->getValueAsBit("hasDelaySlot");
+  usesCustomInserter = R->getValueAsBit("usesCustomInserter");
+  hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
+  isNotDuplicable = R->getValueAsBit("isNotDuplicable");
+  hasSideEffects = R->getValueAsBit("hasSideEffects");
+  neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
+  isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove");
+  hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq");
+  hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq");
+  ImplicitDefs = R->getValueAsListOfDefs("Defs");
+  ImplicitUses = R->getValueAsListOfDefs("Uses");
+
+  if (neverHasSideEffects + hasSideEffects > 1)
+    throw R->getName() + ": multiple conflicting side-effect flags set!";
+
+  // Parse Constraints.
+  ParseConstraints(R->getValueAsString("Constraints"), Operands);
+
+  // Parse the DisableEncoding field.
+  Operands.ProcessDisableEncoding(R->getValueAsString("DisableEncoding"));
+}
 
 /// HasOneImplicitDefWithKnownVT - If the instruction has at least one
 /// implicit def and it has a known VT, return the VT, otherwise return
@@ -369,4 +382,3 @@ FlattenAsmStringVariants(StringRef Cur, unsigned Variant) {
   return Res;
 }
 
-
index 7f9d24925cc66e2f57a00e645f6213ec975917f7..93bec14ff5f696a24133a89c619fcbb898b7219e 100644 (file)
@@ -24,40 +24,33 @@ namespace llvm {
   class DagInit;
   class CodeGenTarget;
   class StringRef;
-
-  class CodeGenInstruction {
+  
+  class CGIOperandList {
   public:
-    Record *TheDef;            // The actual record defining this instruction.
-    std::string Namespace;     // The namespace the instruction is in.
-
-    /// AsmString - The format string used to emit a .s file for the
-    /// instruction.
-    std::string AsmString;
-
     class ConstraintInfo {
       enum { None, EarlyClobber, Tied } Kind;
       unsigned OtherTiedOperand;
     public:
       ConstraintInfo() : Kind(None) {}
-
+      
       static ConstraintInfo getEarlyClobber() {
         ConstraintInfo I;
         I.Kind = EarlyClobber;
         I.OtherTiedOperand = 0;
         return I;
       }
-
+      
       static ConstraintInfo getTied(unsigned Op) {
         ConstraintInfo I;
         I.Kind = Tied;
         I.OtherTiedOperand = Op;
         return I;
       }
-
+      
       bool isNone() const { return Kind == None; }
       bool isEarlyClobber() const { return Kind == EarlyClobber; }
       bool isTied() const { return Kind == Tied; }
-
+      
       unsigned getTiedOperand() const {
         assert(isTied());
         return OtherTiedOperand;
@@ -70,19 +63,19 @@ namespace llvm {
       /// Rec - The definition this operand is declared as.
       ///
       Record *Rec;
-
+      
       /// Name - If this operand was assigned a symbolic name, this is it,
       /// otherwise, it's empty.
       std::string Name;
-
+      
       /// PrinterMethodName - The method used to print operands of this type in
       /// the asmprinter.
       std::string PrinterMethodName;
-
+      
       /// EncoderMethodName - The method used to get the machine operand value
       /// for binary encoding. "getMachineOpValue" by default.
       std::string EncoderMethodName;
-
+      
       /// MIOperandNo - Currently (this is meant to be phased out), some logical
       /// operands correspond to multiple MachineInstr operands.  In the X86
       /// target for example, one address operand is represented as 4
@@ -91,66 +84,63 @@ namespace llvm {
       /// does, this contains the MI operand index of this operand.
       unsigned MIOperandNo;
       unsigned MINumOperands;   // The number of operands.
-
+      
       /// DoNotEncode - Bools are set to true in this vector for each operand in
       /// the DisableEncoding list.  These should not be emitted by the code
       /// emitter.
       std::vector<bool> DoNotEncode;
-
+      
       /// MIOperandInfo - Default MI operand type. Note an operand may be made
       /// up of multiple MI operands.
       DagInit *MIOperandInfo;
-
+      
       /// Constraint info for this operand.  This operand can have pieces, so we
       /// track constraint info for each.
       std::vector<ConstraintInfo> Constraints;
-
+      
       OperandInfo(Record *R, const std::string &N, const std::string &PMN,
                   const std::string &EMN, unsigned MION, unsigned MINO,
                   DagInit *MIOI)
-        : Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN),
-          MIOperandNo(MION), MINumOperands(MINO), MIOperandInfo(MIOI) {}
+      : Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN),
+      MIOperandNo(MION), MINumOperands(MINO), MIOperandInfo(MIOI) {}
     };
+    
+    CGIOperandList(Record *D);
+    
+    Record *TheDef;            // The actual record containing this OperandList.
 
     /// NumDefs - Number of def operands declared, this is the number of
     /// elements in the instruction's (outs) list.
     ///
     unsigned NumDefs;
-
+    
     /// OperandList - The list of declared operands, along with their declared
     /// type (which is a record).
     std::vector<OperandInfo> OperandList;
-
-    /// ImplicitDefs/ImplicitUses - These are lists of registers that are
-    /// implicitly defined and used by the instruction.
-    std::vector<Record*> ImplicitDefs, ImplicitUses;
-
-    // Various boolean values we track for the instruction.
-    bool isReturn;
-    bool isBranch;
-    bool isIndirectBranch;
-    bool isCompare;
-    bool isBarrier;
-    bool isCall;
-    bool canFoldAsLoad;
-    bool mayLoad, mayStore;
+    
+    // Information gleaned from the operand list.
     bool isPredicable;
-    bool isConvertibleToThreeAddress;
-    bool isCommutable;
-    bool isTerminator;
-    bool isReMaterializable;
-    bool hasDelaySlot;
-    bool usesCustomInserter;
-    bool isVariadic;
-    bool hasCtrlDep;
-    bool isNotDuplicable;
     bool hasOptionalDef;
-    bool hasSideEffects;
-    bool neverHasSideEffects;
-    bool isAsCheapAsAMove;
-    bool hasExtraSrcRegAllocReq;
-    bool hasExtraDefRegAllocReq;
-
+    bool isVariadic;
+    
+    // Provide transparent accessors to the operand list.
+    unsigned size() const { return OperandList.size(); }
+    const OperandInfo &operator[](unsigned i) const { return OperandList[i]; }
+    OperandInfo &operator[](unsigned i) { return OperandList[i]; }
+    OperandInfo &back() { return OperandList.back(); }
+    const OperandInfo &back() const { return OperandList.back(); }
+    
+    
+    /// getOperandNamed - Return the index of the operand with the specified
+    /// non-empty name.  If the instruction does not have an operand with the
+    /// specified name, throw an exception.
+    unsigned getOperandNamed(StringRef Name) const;
+    
+    /// hasOperandNamed - Query whether the instruction has an operand of the
+    /// given name. If so, return true and set OpIdx to the index of the
+    /// operand. Otherwise, return false.
+    bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const;
+      
     /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
     /// where $foo is a whole operand and $foo.bar refers to a suboperand.
     /// This throws an exception if the name is invalid.  If AllowWholeOp is
@@ -158,13 +148,13 @@ namespace llvm {
     /// not.
     std::pair<unsigned,unsigned> ParseOperandName(const std::string &Op,
                                                   bool AllowWholeOp = true);
-
+    
     /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a
     /// flat machineinstr operand #.
     unsigned getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op) const {
       return OperandList[Op.first].MIOperandNo + Op.second;
     }
-
+    
     /// getSubOperandNumber - Unflatten a operand number into an
     /// operand/suboperand pair.
     std::pair<unsigned,unsigned> getSubOperandNumber(unsigned Op) const {
@@ -174,8 +164,8 @@ namespace llvm {
           return std::make_pair(i, Op-OperandList[i].MIOperandNo);
       }
     }
-
-
+    
+    
     /// isFlatOperandNotEmitted - Return true if the specified flat operand #
     /// should not be emitted with the code emitter.
     bool isFlatOperandNotEmitted(unsigned FlatOpNo) const {
@@ -184,18 +174,54 @@ namespace llvm {
         return OperandList[Op.first].DoNotEncode[Op.second];
       return false;
     }
+    
+    void ProcessDisableEncoding(std::string Value);
+  };
+  
 
-    CodeGenInstruction(Record *R);
+  class CodeGenInstruction {
+  public:
+    Record *TheDef;            // The actual record defining this instruction.
+    std::string Namespace;     // The namespace the instruction is in.
 
-    /// getOperandNamed - Return the index of the operand with the specified
-    /// non-empty name.  If the instruction does not have an operand with the
-    /// specified name, throw an exception.
-    unsigned getOperandNamed(StringRef Name) const;
+    /// AsmString - The format string used to emit a .s file for the
+    /// instruction.
+    std::string AsmString;
 
-    /// hasOperandNamed - Query whether the instruction has an operand of the
-    /// given name. If so, return true and set OpIdx to the index of the
-    /// operand. Otherwise, return false.
-    bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const;
+    /// Operands - This is information about the (ins) and (outs) list specified
+    /// to the instruction.
+    CGIOperandList Operands;
+
+    /// ImplicitDefs/ImplicitUses - These are lists of registers that are
+    /// implicitly defined and used by the instruction.
+    std::vector<Record*> ImplicitDefs, ImplicitUses;
+
+    // Various boolean values we track for the instruction.
+    bool isReturn;
+    bool isBranch;
+    bool isIndirectBranch;
+    bool isCompare;
+    bool isBarrier;
+    bool isCall;
+    bool canFoldAsLoad;
+    bool mayLoad, mayStore;
+    bool isPredicable;
+    bool isConvertibleToThreeAddress;
+    bool isCommutable;
+    bool isTerminator;
+    bool isReMaterializable;
+    bool hasDelaySlot;
+    bool usesCustomInserter;
+    bool hasCtrlDep;
+    bool isNotDuplicable;
+    bool hasSideEffects;
+    bool neverHasSideEffects;
+    bool isAsCheapAsAMove;
+    bool hasExtraSrcRegAllocReq;
+    bool hasExtraDefRegAllocReq;
+
+
+    CodeGenInstruction(Record *R);
 
     /// HasOneImplicitDefWithKnownVT - If the instruction has at least one
     /// implicit def and it has a known VT, return the VT, otherwise return
@@ -209,6 +235,6 @@ namespace llvm {
     static std::string FlattenAsmStringVariants(StringRef AsmString,
                                                 unsigned Variant);
   };
-}
+  }
 
 #endif
index 57c0b1557889528c61ed1ccac17fc05b22a3263b..c1e3212e81c242e282d742e171ada20c5a8541aa 100644 (file)
@@ -678,11 +678,11 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
   // in the 'execute always' values.  Match up the node operands to the
   // instruction operands to do this.
   SmallVector<unsigned, 8> InstOps;
-  for (unsigned ChildNo = 0, InstOpNo = NumResults, e = II.OperandList.size();
+  for (unsigned ChildNo = 0, InstOpNo = NumResults, e = II.Operands.size();
        InstOpNo != e; ++InstOpNo) {
     
     // Determine what to emit for this operand.
-    Record *OperandNode = II.OperandList[InstOpNo].Rec;
+    Record *OperandNode = II.Operands[InstOpNo].Rec;
     if ((OperandNode->isSubClassOf("PredicateOperand") ||
          OperandNode->isSubClassOf("OptionalDefOperand")) &&
         !CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
index 8b1b890538ec53b1da803d1dc1e3d023456b128c..1d5e1e170ba1d810333dc0d915c1b223de6a902e 100644 (file)
@@ -346,11 +346,10 @@ static void X86PopulateOperands(
     return;
 
   unsigned int index;
-  unsigned int numOperands = inst.OperandList.size();
+  unsigned int numOperands = inst.Operands.size();
 
   for (index = 0; index < numOperands; ++index) {
-    const CodeGenInstruction::OperandInfo &operandInfo =
-      inst.OperandList[index];
+    const CGIOperandList::OperandInfo &operandInfo = inst.Operands[index];
     Record &rec = *operandInfo.Rec;
 
     if (X86TypeFromOpName(operandTypes[index], rec.getName())) {
@@ -376,7 +375,7 @@ static inline void decorate1(
   const char *opFlag) {
   unsigned opIndex;
 
-  opIndex = inst.getOperandNamed(std::string(opName));
+  opIndex = inst.Operands.getOperandNamed(std::string(opName));
 
   operandFlags[opIndex]->addEntry(opFlag);
 }
@@ -648,7 +647,7 @@ static void ARMPopulateOperands(
     return;
 
   unsigned int index;
-  unsigned int numOperands = inst.OperandList.size();
+  unsigned int numOperands = inst.Operands.size();
 
   if (numOperands > EDIS_MAX_OPERANDS) {
     errs() << "numOperands == " << numOperands << " > " <<
@@ -657,8 +656,7 @@ static void ARMPopulateOperands(
   }
 
   for (index = 0; index < numOperands; ++index) {
-    const CodeGenInstruction::OperandInfo &operandInfo =
-    inst.OperandList[index];
+    const CGIOperandList::OperandInfo &operandInfo = inst.Operands[index];
     Record &rec = *operandInfo.Rec;
 
     if (ARMFlagFromOpName(operandTypes[index], rec.getName())) {
@@ -709,7 +707,7 @@ static void ARMExtractSemantics(
     BRANCH("func");
 
     unsigned opIndex;
-    opIndex = inst.getOperandNamed("func");
+    opIndex = inst.Operands.getOperandNamed("func");
     if (operandTypes[opIndex]->is("kOperandTypeImmediate"))
       operandTypes[opIndex]->set("kOperandTypeARMBranchTarget");
   }
@@ -740,7 +738,7 @@ static void populateInstInfo(CompoundConstantEmitter &infoArray,
     infoStruct->addEntry(instType);
 
     LiteralConstantEmitter *numOperandsEmitter =
-      new LiteralConstantEmitter(inst.OperandList.size());
+      new LiteralConstantEmitter(inst.Operands.size());
     infoStruct->addEntry(numOperandsEmitter);
 
     CompoundConstantEmitter *operandTypeArray = new CompoundConstantEmitter;
index 6c16fcfaa8a27aa621a869b36dd402b554274b33..0039506f621a6c9b7aeec958a363a0a18e957a28 100644 (file)
@@ -263,7 +263,7 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) {
     if (!Op->isSubClassOf("Instruction"))
       continue;
     CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op);
-    if (II.OperandList.empty())
+    if (II.Operands.size() == 0)
       continue;
       
     // For now, ignore multi-instruction patterns.
@@ -285,7 +285,7 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) {
     const CodeGenRegisterClass *DstRC = 0;
     std::string SubRegNo;
     if (Op->getName() != "EXTRACT_SUBREG") {
-      Record *Op0Rec = II.OperandList[0].Rec;
+      Record *Op0Rec = II.Operands[0].Rec;
       if (!Op0Rec->isSubClassOf("RegisterClass"))
         continue;
       DstRC = &Target.getRegisterClass(Op0Rec);
index 4d3aa5e621c9c749347ed86d1d66fd6ce756019f..e04ab6c4ef96c36c244cef862d43a3e4d70defef 100644 (file)
@@ -60,23 +60,23 @@ std::vector<std::string>
 InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
   std::vector<std::string> Result;
   
-  for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) {
+  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.
-    std::vector<CodeGenInstruction::OperandInfo> OperandList;
+    std::vector<CGIOperandList::OperandInfo> OperandList;
 
     // This might be a multiple operand thing.  Targets like X86 have
     // registers in their multi-operand operands.  It may also be an anonymous
     // operand, which has a single operand, but no declared class for the
     // operand.
-    DagInit *MIOI = Inst.OperandList[i].MIOperandInfo;
+    DagInit *MIOI = Inst.Operands[i].MIOperandInfo;
     
     if (!MIOI || MIOI->getNumArgs() == 0) {
       // Single, anonymous, operand.
-      OperandList.push_back(Inst.OperandList[i]);
+      OperandList.push_back(Inst.Operands[i]);
     } else {
-      for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) {
-        OperandList.push_back(Inst.OperandList[i]);
+      for (unsigned j = 0, e = Inst.Operands[i].MINumOperands; j != e; ++j) {
+        OperandList.push_back(Inst.Operands[i]);
 
         Record *OpR = dynamic_cast<DefInit*>(MIOI->getArg(j))->getDef();
         OperandList.back().Rec = OpR;
@@ -104,19 +104,19 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
 
       // Predicate operands.  Check to see if the original unexpanded operand
       // was of type PredicateOperand.
-      if (Inst.OperandList[i].Rec->isSubClassOf("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.OperandList[i].Rec->isSubClassOf("OptionalDefOperand"))
+      if (Inst.Operands[i].Rec->isSubClassOf("OptionalDefOperand"))
         Res += "|(1<<TOI::OptionalDef)";
 
       // Fill in constraint info.
       Res += ", ";
       
-      const CodeGenInstruction::ConstraintInfo &Constraint =
-        Inst.OperandList[i].Constraints[j];
+      const CGIOperandList::ConstraintInfo &Constraint =
+        Inst.Operands[i].Constraints[j];
       if (Constraint.isNone())
         Res += "0";
       else if (Constraint.isEarlyClobber())
@@ -256,14 +256,14 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
                                   const OperandInfoMapTy &OpInfo,
                                   raw_ostream &OS) {
   int MinOperands = 0;
-  if (!Inst.OperandList.empty())
+  if (!Inst.Operands.size() == 0)
     // Each logical operand can be multiple MI operands.
-    MinOperands = Inst.OperandList.back().MIOperandNo +
-                  Inst.OperandList.back().MINumOperands;
+    MinOperands = Inst.Operands.back().MIOperandNo +
+                  Inst.Operands.back().MINumOperands;
 
   OS << "  { ";
   OS << Num << ",\t" << MinOperands << ",\t"
-     << Inst.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef)
+     << Inst.Operands.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef)
      << ",\t\"" << Inst.TheDef->getName() << "\", 0";
 
   // Emit all of the target indepedent flags...
@@ -283,9 +283,9 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
   if (Inst.isTerminator)       OS << "|(1<<TID::Terminator)";
   if (Inst.isReMaterializable) OS << "|(1<<TID::Rematerializable)";
   if (Inst.isNotDuplicable)    OS << "|(1<<TID::NotDuplicable)";
-  if (Inst.hasOptionalDef)     OS << "|(1<<TID::HasOptionalDef)";
+  if (Inst.Operands.hasOptionalDef) OS << "|(1<<TID::HasOptionalDef)";
   if (Inst.usesCustomInserter) OS << "|(1<<TID::UsesCustomInserter)";
-  if (Inst.isVariadic)         OS << "|(1<<TID::Variadic)";
+  if (Inst.Operands.isVariadic)OS << "|(1<<TID::Variadic)";
   if (Inst.hasSideEffects)     OS << "|(1<<TID::UnmodeledSideEffects)";
   if (Inst.isAsCheapAsAMove)   OS << "|(1<<TID::CheapAsAMove)";
   if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<TID::ExtraSrcRegAllocReq)";
index 1343fcf5ad2129bc93560b3e83dd430e12a9502e..e3cad1aaa89fc29da7b40e45e423eb2fd428bf02 100644 (file)
@@ -219,7 +219,7 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
   Name      = Rec->getName();
   AsmString = Rec->getValueAsString("AsmString");
   
-  Operands = &insn.OperandList;
+  Operands = &insn.Operands.OperandList;
   
   IsSSE            = HasOpSizePrefix && (Name.find("16") == Name.npos);
   HasFROperands    = false;
@@ -424,7 +424,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
   
   Spec->insnContext = insnContext();
     
-  const std::vector<CodeGenInstruction::OperandInfo> &OperandList = *Operands;
+  const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands;
   
   unsigned operandIndex;
   unsigned numOperands = OperandList.size();
@@ -440,7 +440,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
   
   for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
     if (OperandList[operandIndex].Constraints.size()) {
-      const CodeGenInstruction::ConstraintInfo &Constraint =
+      const CGIOperandList::ConstraintInfo &Constraint =
         OperandList[operandIndex].Constraints[0];
       if (Constraint.isTied()) {
         operandMapping[operandIndex] = Constraint.getTiedOperand();
index db4d96dda032bd59db08fc6c0f2f9dcc2c5fbb61..113b3bdb37c028525c56be877350626188a192ab 100644 (file)
@@ -76,7 +76,8 @@ private:
   /// The operands of the instruction, as listed in the CodeGenInstruction.
   /// They are not one-to-one with operands listed in the MCInst; for example,
   /// memory operands expand to 5 operands in the MCInst
-  const std::vector<CodeGenInstruction::OperandInfo>* Operands;
+  const std::vector<CGIOperandList::OperandInfo>* Operands;
+  
   /// The description of the instruction that is emitted into the instruction
   /// info table
   InstructionSpecifier* Spec;