diff options
| author | Chris Lattner <sabre@nondot.org> | 2010-09-06 21:54:15 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2010-09-06 21:54:15 +0000 |
| commit | 628fbecf4fbec551a0a7f2360c8bae0ac1881e72 (patch) | |
| tree | d23d2ae3a8bc076b5423b72b79d0e2e55e3ae6a5 | |
| parent | c0658cbd16e32ce7f092747d1f5d9b4760f0412d (diff) | |
| download | llvm-628fbecf4fbec551a0a7f2360c8bae0ac1881e72.zip llvm-628fbecf4fbec551a0a7f2360c8bae0ac1881e72.tar.gz llvm-628fbecf4fbec551a0a7f2360c8bae0ac1881e72.tar.bz2 | |
Now that we know if we had a total fail on the instruction mnemonic,
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"
llvm-svn: 113176
| -rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 34 | ||||
| -rw-r--r-- | llvm/utils/TableGen/AsmMatcherEmitter.cpp | 13 |
2 files changed, 36 insertions, 11 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 52ca15ba..20ed232 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -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; } diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp index a2222df..4d8a795 100644 --- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp +++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp @@ -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"; |
