With the fix in r162954/162955 every cvt function returns true. Thus, have
[oota-llvm.git] / utils / TableGen / AsmMatcherEmitter.cpp
index abfb9ae9b1642f253929c997617d76f9a5383121..8debc8e32ab99ee5060a8bd88991a61e093b7972 100644 (file)
@@ -488,6 +488,15 @@ struct MatchableInfo {
         return false;
     }
 
+    // Give matches that require more features higher precedence. This is useful
+    // because we cannot define AssemblerPredicates with the negation of
+    // processor features. For example, ARM v6 "nop" may be either a HINT or
+    // MOV. With v6, we want to match HINT. The assembler has no way to
+    // predicate MOV under "NoV6", but HINT will always match first because it
+    // requires V6 while MOV does not.
+    if (RequiredFeatures.size() != RHS.RequiredFeatures.size())
+      return RequiredFeatures.size() > RHS.RequiredFeatures.size();
+
     return false;
   }
 
@@ -666,7 +675,7 @@ void MatchableInfo::dump() {
 }
 
 static std::pair<StringRef, StringRef>
-parseTwoOperandConstraint(StringRef S, SMLoc Loc) {
+parseTwoOperandConstraint(StringRef S, ArrayRef<SMLoc> Loc) {
   // Split via the '='.
   std::pair<StringRef, StringRef> Ops = S.split('=');
   if (Ops.second == "")
@@ -1669,12 +1678,12 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
   std::string ConvertFnBody;
   raw_string_ostream CvtOS(ConvertFnBody);
   // Start the unified conversion function.
-  CvtOS << "bool " << Target.getName() << ClassName << "::\n"
+  CvtOS << "void " << Target.getName() << ClassName << "::\n"
         << "ConvertToMCInst(unsigned Kind, MCInst &Inst, "
         << "unsigned Opcode,\n"
-        << "                      const SmallVectorImpl<MCParsedAsmOperand*"
+        << "                const SmallVectorImpl<MCParsedAsmOperand*"
         << "> &Operands) {\n"
-        << "  if (Kind >= CVT_NUM_SIGNATURES) return false;\n"
+        << "  assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
         << "  uint8_t *Converter = ConversionTable[Kind];\n"
         << "  Inst.setOpcode(Opcode);\n"
         << "  for (uint8_t *p = Converter; *p; p+= 2) {\n"
@@ -1688,6 +1697,26 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
         << "      Inst.addOperand(Inst.getOperand(*(p + 1)));\n"
         << "      break;\n";
 
+  std::string OperandFnBody;
+  raw_string_ostream OpOS(OperandFnBody);
+  // Start the operand number lookup function.
+  OpOS << "void " << Target.getName() << ClassName << "::\n"
+       << "GetMCInstOperandNum(unsigned Kind, MCInst &Inst,\n"
+       << "                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands,"
+       << "\n                    unsigned OperandNum, unsigned &MCOperandNum) {\n"
+       << "  assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
+       << "  MCOperandNum = 0;\n"
+       << "  uint8_t *Converter = ConversionTable[Kind];\n"
+       << "  for (uint8_t *p = Converter; *p; p+= 2) {\n"
+       << "    if (*(p + 1) > OperandNum) continue;\n"
+       << "    switch (*p) {\n"
+       << "    default: llvm_unreachable(\"invalid conversion entry!\");\n"
+       << "    case CVT_Reg:\n"
+       << "      ++MCOperandNum;\n"
+       << "      break;\n"
+       << "    case CVT_Tied:\n"
+       << "      //Inst.getOperand(*(p + 1)));\n"
+       << "      break;\n";
 
   // Pre-populate the operand conversion kinds with the standard always
   // available entries.
@@ -1722,9 +1751,10 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
 
       // Add the handler to the conversion driver function.
       CvtOS << "    case CVT_" << AsmMatchConverter << ":\n"
-            << "      return " << AsmMatchConverter
-            << "(Inst, Opcode, Operands);\n";
+            << "      " << AsmMatchConverter << "(Inst, Opcode, Operands);\n"
+            << "      break;\n";
 
+      // FIXME: Handle the operand number lookup for custom match functions.
       continue;
     }
 
@@ -1778,9 +1808,13 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
               << Op.Class->RenderMethod << "(Inst, " << OpInfo.MINumOperands
               << ");\n"
               << "      break;\n";
+
+        // Add a handler for the operand number lookup.
+        OpOS << "    case " << Name << ":\n"
+             << "      MCOperandNum += " << OpInfo.MINumOperands << ";\n"
+             << "      break;\n";
         break;
       }
-
       case MatchableInfo::ResOperand::TiedOperand: {
         // If this operand is tied to a previous one, just copy the MCInst
         // operand from the earlier one.We can only tie single MCOperand values.
@@ -1790,6 +1824,7 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
         Signature += "__Tie" + utostr(TiedOp);
         ConversionRow.push_back(CVT_Tied);
         ConversionRow.push_back(TiedOp);
+        // FIXME: Handle the operand number lookup for tied operands.
         break;
       }
       case MatchableInfo::ResOperand::ImmOperand: {
@@ -1812,6 +1847,9 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
               << "      Inst.addOperand(MCOperand::CreateImm(" << Val << "));\n"
               << "      break;\n";
 
+        OpOS << "    case " << Name << ":\n"
+             << "      ++MCOperandNum;\n"
+             << "      break;\n";
         break;
       }
       case MatchableInfo::ResOperand::RegOperand: {
@@ -1837,6 +1875,10 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
         CvtOS << "    case " << Name << ":\n"
               << "      Inst.addOperand(MCOperand::CreateReg(" << Reg << "));\n"
               << "      break;\n";
+
+        OpOS << "    case " << Name << ":\n"
+             << "      ++MCOperandNum;\n"
+             << "      break;\n";
       }
       }
     }
@@ -1857,7 +1899,10 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
   }
 
   // Finish up the converter driver function.
-  CvtOS << "    }\n  }\n  return true;\n}\n\n";
+  CvtOS << "    }\n  }\n  return;\n}\n\n";
+
+  // Finish up the operand number lookup function.
+  OpOS << "    }\n  }\n  return;\n}\n\n";
 
   OS << "namespace {\n";
 
@@ -1899,6 +1944,8 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
   // Spit out the conversion driver function.
   OS << CvtOS.str();
 
+  // Spit out the operand number lookup function.
+  OS << OpOS.str();
 }
 
 /// emitMatchClassEnumeration - Emit the enumeration for match class kinds.
@@ -2529,10 +2576,14 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   OS << "  // This should be included into the middle of the declaration of\n";
   OS << "  // your subclasses implementation of MCTargetAsmParser.\n";
   OS << "  unsigned ComputeAvailableFeatures(uint64_t FeatureBits) const;\n";
-  OS << "  bool ConvertToMCInst(unsigned Kind, MCInst &Inst, "
+  OS << "  void ConvertToMCInst(unsigned Kind, MCInst &Inst, "
      << "unsigned Opcode,\n"
      << "                       const SmallVectorImpl<MCParsedAsmOperand*> "
      << "&Operands);\n";
+  OS << "  void GetMCInstOperandNum(unsigned Kind, MCInst &Inst,\n"
+     << "                           const SmallVectorImpl<MCParsedAsmOperand*> "
+     << "&Operands,\n                           unsigned OperandNum, unsigned "
+     << "&MCOperandNum);\n";
   OS << "  bool MnemonicIsValid(StringRef Mnemonic);\n";
   OS << "  unsigned MatchInstructionImpl(\n";
   OS << "    const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
@@ -2719,6 +2770,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   OS << "                     MCInst &Inst, unsigned &ErrorInfo, ";
   OS << "unsigned VariantID) {\n";
 
+  OS << "  // Eliminate obvious mismatches.\n";
+  OS << "  if (Operands.size() > " << (MaxNumOperands+1) << ") {\n";
+  OS << "    ErrorInfo = " << (MaxNumOperands+1) << ";\n";
+  OS << "    return Match_InvalidOperand;\n";
+  OS << "  }\n\n";
+
   // Emit code to get the available features.
   OS << "  // Get the current feature set.\n";
   OS << "  unsigned AvailableFeatures = getAvailableFeatures();\n\n";
@@ -2735,12 +2792,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   }
 
   // Emit code to compute the class list for this operand vector.
-  OS << "  // Eliminate obvious mismatches.\n";
-  OS << "  if (Operands.size() > " << (MaxNumOperands+1) << ") {\n";
-  OS << "    ErrorInfo = " << (MaxNumOperands+1) << ";\n";
-  OS << "    return Match_InvalidOperand;\n";
-  OS << "  }\n\n";
-
   OS << "  // Some state to try to produce better error messages.\n";
   OS << "  bool HadMatchOtherThanFeatures = false;\n";
   OS << "  bool HadMatchOtherThanPredicate = false;\n";
@@ -2805,17 +2856,15 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   OS << "      HadMatchOtherThanFeatures = true;\n";
   OS << "      unsigned NewMissingFeatures = it->RequiredFeatures & "
         "~AvailableFeatures;\n";
-  OS << "      if (CountPopulation_32(NewMissingFeatures) <= "
-        "CountPopulation_32(MissingFeatures))\n";
+  OS << "      if (CountPopulation_32(NewMissingFeatures) <=\n"
+        "          CountPopulation_32(MissingFeatures))\n";
   OS << "        MissingFeatures = NewMissingFeatures;\n";
   OS << "      continue;\n";
   OS << "    }\n";
   OS << "\n";
   OS << "    // We have selected a definite instruction, convert the parsed\n"
      << "    // operands into the appropriate MCInst.\n";
-  OS << "    if (!ConvertToMCInst(it->ConvertFn, Inst,\n"
-     << "                         it->Opcode, Operands))\n";
-  OS << "      return Match_ConversionFail;\n";
+  OS << "    ConvertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
   OS << "\n";
 
   // Verify the instruction with the target-specific match predicate function.