From 7409d94d2d65e50693a5d9eb81ca14fb6141d748 Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Thu, 13 Aug 2015 21:09:13 +0000 Subject: [PATCH] [AArch64] Provide "too few operands" diags on short-form NEON also. We used to just say "invalid type suffix for instruction", which is misleading. This is because we fallback to the long-form matcher if the short-form matcher failed, losing the error information on the way. Save it, so that we can provide a little better diagnostics when the long-form matcher thinks a suffix is the cause of the error. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244955 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../AArch64/AsmParser/AArch64AsmParser.cpp | 10 ++++ test/MC/AArch64/arm64-diags.s | 54 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 44ed4dee029..9292f660735 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -3929,6 +3929,8 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, // If that fails, try against the alternate table containing long-form NEON: // "fadd v0.2s, v1.2s, v2.2s" + // But first, save the ErrorInfo: we can use it in case this try also fails. + uint64_t ShortFormNEONErrorInfo = ErrorInfo; if (MatchResult != Match_Success) MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0); @@ -3966,6 +3968,14 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return showMatchError(IDLoc, MatchResult); case Match_InvalidOperand: { SMLoc ErrorLoc = IDLoc; + + // If the long-form match failed on the mnemonic suffix token operand, + // the short-form match failure is probably more relevant: use it instead. + if (ErrorInfo == 1 && + ((AArch64Operand &)*Operands[1]).isToken() && + ((AArch64Operand &)*Operands[1]).isTokenSuffix()) + ErrorInfo = ShortFormNEONErrorInfo; + if (ErrorInfo != ~0ULL) { if (ErrorInfo >= Operands.size()) return Error(IDLoc, "too few operands for instruction"); diff --git a/test/MC/AArch64/arm64-diags.s b/test/MC/AArch64/arm64-diags.s index f8138bde3a4..8fdba9f2f62 100644 --- a/test/MC/AArch64/arm64-diags.s +++ b/test/MC/AArch64/arm64-diags.s @@ -426,3 +426,57 @@ tlbi vale2 ; CHECK-ERRORS: error: specified tlbi op requires a register tlbi vale3 ; CHECK-ERRORS: error: specified tlbi op requires a register + + +; Check that we give the proper "too few operands" diagnostic even when +; using short-form NEON. + + add.16b v0, v1, v2, v3 + add.8b v0, v1 + sub.8h v0, v1 + fadd.4s v0 + fmul.2s + +; CHECK-ERRORS: error: invalid operand for instruction +; CHECK-ERRORS: add.16b v0, v1, v2, v3 +; CHECK-ERRORS: ^ +; CHECK-ERRORS: error: too few operands for instruction +; CHECK-ERRORS: add.8b v0, v1 +; CHECK-ERRORS: ^ +; CHECK-ERRORS: error: too few operands for instruction +; CHECK-ERRORS: sub.8h v0, v1 +; CHECK-ERRORS: ^ +; CHECK-ERRORS: error: too few operands for instruction +; CHECK-ERRORS: fadd.4s v0 +; CHECK-ERRORS: ^ +; CHECK-ERRORS: error: too few operands for instruction +; CHECK-ERRORS: fmul.2s +; CHECK-ERRORS: ^ + +; Also for 2-operand instructions. + + frsqrte.4s v0, v1, v2 + frsqrte.2s v0 + frecpe.2d + +; CHECK-ERRORS: error: invalid operand for instruction +; CHECK-ERRORS: frsqrte.4s v0, v1, v2 +; CHECK-ERRORS ^ +; CHECK-ERRORS: error: too few operands for instruction +; CHECK-ERRORS: frsqrte.2s v0 +; CHECK-ERRORS: ^ +; CHECK-ERRORS: error: too few operands for instruction +; CHECK-ERRORS: frecpe.2d +; CHECK-ERRORS: ^ + +; And check that we do the same for non-NEON instructions. + + b.ne + b.eq 0, 0 + +; CHECK-ERRORS: error: too few operands for instruction +; CHECK-ERRORS: b.ne +; CHECK-ERRORS: ^ +; CHECK-ERRORS: error: invalid operand for instruction +; CHECK-ERRORS: b.eq 0, 0 +; CHECK-ERRORS: ^ -- 2.34.1