forked from OSchip/llvm-project
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
This commit is contained in:
parent
c0658cbd16
commit
628fbecf4f
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Reference in New Issue