Now that we know if we had a total fail on the instruction mnemonic,
authorChris Lattner <sabre@nondot.org>
Mon, 6 Sep 2010 21:54:15 +0000 (21:54 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 6 Sep 2010 21:54:15 +0000 (21:54 +0000)
give a more detailed error.  Before:

t.s:11:4: error: unrecognized instruction
   addl $1, $1
   ^
t.s:12:4: error: unrecognized instruction
   f2efqefa $1
   ^

After:

t.s:11:4: error: invalid operand for instruction
   addl $1, $1
   ^
t.s:12:4: error: invalid instruction mnemonic 'f2efqefa'
   f2efqefa $1
   ^

This fixes rdar://8017912 - llvm-mc says "unrecognized instruction" when it means "invalid operands"

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

lib/Target/X86/AsmParser/X86AsmParser.cpp
utils/TableGen/AsmMatcherEmitter.cpp

index 52ca15ba1a6c0d57dd3f5bcdb7d40108eb6d786f..20ed232eccd1afb5462e226f6d8ef3d74646d3bd 100644 (file)
@@ -862,6 +862,8 @@ X86ATTAsmParser::MatchInstruction(SMLoc IDLoc,
                                   MCInst &Inst) {
   assert(!Operands.empty() && "Unexpect empty operand list!");
 
+  bool WasOriginallyInvalidOperand = false;
+  
   // First, try a direct match.
   switch (MatchInstructionImpl(Operands, Inst)) {
   case Match_Success:
@@ -869,7 +871,10 @@ X86ATTAsmParser::MatchInstruction(SMLoc IDLoc,
   case Match_MissingFeature:
     Error(IDLoc, "instruction requires a CPU feature not currently enabled");
     return true;
-  default:
+  case Match_InvalidOperand:
+    WasOriginallyInvalidOperand = true;
+    break;
+  case Match_MnemonicFail:
     break;
   }
 
@@ -941,23 +946,38 @@ X86ATTAsmParser::MatchInstruction(SMLoc IDLoc,
     return true;
   }
   
-  unsigned NumMatchFailures =
-    (MatchB == Match_Fail) + (MatchW == Match_Fail) +
-    (MatchL == Match_Fail) + (MatchQ == Match_Fail);
+  // Okay, we know that none of the variants matched successfully.
   
+  // If all of the instructions reported an invalid mnemonic, then the original
+  // mnemonic was invalid.
+  if ((MatchB == Match_MnemonicFail) && (MatchW == Match_MnemonicFail) &&
+      (MatchL == Match_MnemonicFail) && (MatchQ == Match_MnemonicFail)) {
+    if (WasOriginallyInvalidOperand)
+      Error(IDLoc, "invalid operand for instruction");
+    else
+      Error(IDLoc, "invalid instruction mnemonic '" + Base + "'"); 
+    return true;
+  }
   
   // If one instruction matched with a missing feature, report this as a
   // missing feature.
   if ((MatchB == Match_MissingFeature) + (MatchW == Match_MissingFeature) +
-      (MatchL == Match_MissingFeature) + (MatchQ == Match_MissingFeature) == 1&&
-      NumMatchFailures == 3) {
+      (MatchL == Match_MissingFeature) + (MatchQ == Match_MissingFeature) == 1){
     Error(IDLoc, "instruction requires a CPU feature not currently enabled");
     return true;
   }
   
+  // If one instruction matched with an invalid operand, report this as an
+  // operand failure.
+  if ((MatchB == Match_InvalidOperand) + (MatchW == Match_InvalidOperand) +
+      (MatchL == Match_InvalidOperand) + (MatchQ == Match_InvalidOperand) == 1){
+    Error(IDLoc, "invalid operand for instruction");
+    return true;
+  }
+  
   // If all of these were an outright failure, report it in a useless way.
   // FIXME: We should give nicer diagnostics about the exact failure.
-  Error(IDLoc, "unrecognized instruction");
+  Error(IDLoc, "unknown use of instruction mnemonic without a size suffix");
   return true;
 }
 
index a2222df223384fa76295feed4ef293a5f94b4203..4d8a7957c61b5364bef9e8f30ce79a09c8c16d69 100644 (file)
@@ -1559,7 +1559,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   OS << "  unsigned ComputeAvailableFeatures(const " <<
            Target.getName() << "Subtarget *Subtarget) const;\n";
   OS << "  enum MatchResultTy {\n";
-  OS << "    Match_Success, Match_Fail, Match_MissingFeature\n";
+  OS << "    Match_Success, Match_MnemonicFail, Match_InvalidOperand,\n";
+  OS << "    Match_MissingFeature\n";
   OS << "  };\n";
   OS << "  MatchResultTy MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
      << " &Operands, MCInst &Inst);\n\n";
@@ -1687,7 +1688,7 @@ 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 << "    return Match_Fail;\n\n";
+  OS << "    return Match_InvalidOperand;\n\n";
 
   OS << "  // Compute the class list for this operand vector.\n";
   OS << "  MatchClassKind Classes[" << MaxNumOperands << "];\n";
@@ -1696,7 +1697,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
 
   OS << "    // Check for invalid operands before matching.\n";
   OS << "    if (Classes[i-1] == InvalidMatchClass)\n";
-  OS << "      return Match_Fail;\n";
+  OS << "      return Match_InvalidOperand;\n";
   OS << "  }\n\n";
 
   OS << "  // Mark unused classes.\n";
@@ -1716,6 +1717,10 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   OS << "    std::equal_range(MatchTable, MatchTable+"
      << Info.Instructions.size() << ", Mnemonic, LessOpcode());\n\n";
   
+  OS << "  // Return a more specific error code if no mnemonics match.\n";
+  OS << "  if (MnemonicRange.first == MnemonicRange.second)\n";
+  OS << "    return Match_MnemonicFail;\n\n";
+  
   OS << "  for (const MatchEntry *it = MnemonicRange.first, "
      << "*ie = MnemonicRange.second;\n";
   OS << "       it != ie; ++it) {\n";
@@ -1751,7 +1756,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
 
   OS << "  // Okay, we had no match.  Try to return a useful error code.\n";
   OS << "  if (HadMatchOtherThanFeatures) return Match_MissingFeature;\n";
-  OS << "  return Match_Fail;\n";
+  OS << "  return Match_InvalidOperand;\n";
   OS << "}\n\n";
   
   OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n";