[AArch64] Provide "too few operands" diags on short-form NEON also.
authorAhmed Bougacha <ahmed.bougacha@gmail.com>
Thu, 13 Aug 2015 21:09:13 +0000 (21:09 +0000)
committerAhmed Bougacha <ahmed.bougacha@gmail.com>
Thu, 13 Aug 2015 21:09:13 +0000 (21:09 +0000)
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

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
test/MC/AArch64/arm64-diags.s

index 44ed4dee0298e58c688453c55dae87ac695455ca..9292f660735a5714dd32e9f471d33f4c3042b9c8 100644 (file)
@@ -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");
index f8138bde3a4feb6710c55435cd5f6fcb7914dffa..8fdba9f2f62413cc97a7805c224f0e7ebb2a00c6 100644 (file)
@@ -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:           ^