Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -6297,6 +6297,9 @@ return false; } +static std::string MipsMnemonicSpellCheck(StringRef S, uint64_t FBS, + unsigned VariantID = 0); + bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) { MCAsmParser &Parser = getParser(); @@ -6307,7 +6310,9 @@ // Check if we have valid mnemonic if (!mnemonicIsValid(Name, 0)) { - return Error(NameLoc, "unknown instruction"); + uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); + std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS); + return Error(NameLoc, "unknown instruction" + Suggestion); } // First operand in MCInst is instruction mnemonic. Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this)); @@ -8002,6 +8007,7 @@ #define GET_REGISTER_MATCHER #define GET_MATCHER_IMPLEMENTATION +#define GET_MNEMONIC_SPELL_CHECKER #include "MipsGenAsmMatcher.inc" bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) { Index: test/MC/Mips/invalid-instructions-spellcheck.s =================================================================== --- /dev/null +++ test/MC/Mips/invalid-instructions-spellcheck.s @@ -0,0 +1,45 @@ +# RUN: not llvm-mc -triple mips-unknown-unknown \ +# RUN: -mattr=micromips -show-encoding < %s 2>&1 | FileCheck %s + +# This tests the mnemonic spell checker. + +# First check what happens when an instruction is omitted: + +$2, $1, $25 + +# CHECK: error: unexpected token at start of statement +# CHECK-NEXT: $2, $1, $25 +# CHECK-NEXT: ^ + +# We don't want to see a suggestion here; the edit distance is too large to +# give sensible suggestions: + +aaaaaaaaaaaaaaa $2, $1, $25 + +# CHECK: error: unknown instruction +# CHECK-NEXT: aaaaaaaaaaaaaaa $2, $1, $25 +# CHECK-NEXT: ^ + +# Check that we get one suggestion: 'addiuspi' is 1 edit away, i.e. an deletion. + +addiuspi -16 + +# CHECK: error: unknown instruction, did you mean: addiusp? +# CHECK-NEXT: addiuspi -16 +# CHECK-NEXT: ^ + +# Check edit distance 1 and 2, just insertions: + +addru $9, $6, 17767 + +# CHECK: error: unknown instruction, did you mean: add, addiu, addu, maddu? +# CHECK-NEXT: addru $9, $6, 17767 +# CHECK-NEXT: ^ + +# Check an instruction that is 2 edits away, and also has a lot of candidates: + +culE.d $fcc7, $f24, $f18 + +# CHECK: error: unknown instruction, did you mean: c.le.d, c.ule.d? +# CHECK-NEXT: culE.d $fcc7, $f24, $f18 +# CHECK-NEXT: ^