]> granicus.if.org Git - llvm/commitdiff
[Asm, ARM] Add fallback diag for multiple invalid operands
authorOliver Stannard <oliver.stannard@arm.com>
Mon, 4 Dec 2017 12:02:32 +0000 (12:02 +0000)
committerOliver Stannard <oliver.stannard@arm.com>
Mon, 4 Dec 2017 12:02:32 +0000 (12:02 +0000)
This adds a "invalid operands for instruction" diagnostic for
instructions where there is an instruction encoding with the correct
mnemonic and which is available for this target, but where multiple
operands do not match those which were provided. This makes it clear
that there is some combination of operands that is valid for the current
target, which the default diagnostic of "invalid instruction" does not.

Since this is a very general error, we only emit it if we don't have a
more specific error.

Differential revision: https://reviews.llvm.org/D36747

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319649 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
include/llvm/MC/MCParser/MCTargetAsmParser.h
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/diagnostics.s
test/MC/ARM/invalid-fp-armv8.s
test/MC/ARM/invalid-neon-v8.s
test/MC/ARM/ldrd-strd-gnu-arm-bad-regs.s
test/MC/ARM/ldrd-strd-gnu-bad-inst.s
test/MC/ARM/ldrd-strd-gnu-sp.s
test/MC/ARM/ldrd-strd-gnu-thumb-bad-regs.s
test/MC/ARM/thumb-mov.s
test/MC/ARM/thumb2-diagnostics.s
test/MC/ARM/vfp4.s
utils/TableGen/AsmMatcherEmitter.cpp

index 9f8550c3887c8ef395c59bb2d5e1771274c76ef6..870345b8b05d91f500c5c8f5c852c2c6270de5da 100644 (file)
@@ -143,6 +143,7 @@ public:
   enum NearMissKind {
     NoNearMiss,
     NearMissOperand,
+    NearMissMultipleOperands,
     NearMissFeature,
     NearMissPredicate,
     NearMissTooFewOperands,
@@ -189,6 +190,13 @@ public:
     return Result;
   }
 
+  static NearMissInfo getMissedMultipleOperands(unsigned Opcode) {
+    NearMissInfo Result;
+    Result.Kind = NearMissMultipleOperands;
+    Result.MissedOperand.Opcode = Opcode;
+    return Result;
+  }
+
   // The instruction encoding is not valid because it expects more operands
   // than were parsed. OperandClass is the class of the expected operand that
   // was not provided. Opcode is the instruction encoding.
@@ -208,34 +216,41 @@ public:
   // Feature flags required by the instruction, that the current target does
   // not have.
   uint64_t getFeatures() const {
-    assert(Kind == NearMissFeature);
+    assert(Kind == NearMissFeature &&
+           "near-miss does not have an associated target feature");
     return Features;
   }
   // Error code returned by the target predicate when validating this
   // instruction encoding.
   unsigned getPredicateError() const {
-    assert(Kind == NearMissPredicate);
+    assert(Kind == NearMissPredicate &&
+           "near-miss does not have an associated predicate error");
     return PredicateError;
   }
   // MatchClassKind of the operand that we expected to see.
   unsigned getOperandClass() const {
-    assert(Kind == NearMissOperand || Kind == NearMissTooFewOperands);
+    assert((Kind == NearMissOperand || Kind == NearMissTooFewOperands) &&
+           "near-miss does not have an associated operand class");
     return MissedOperand.Class;
   }
   // Opcode of the encoding we were trying to match.
   unsigned getOpcode() const {
-    assert(Kind == NearMissOperand || Kind == NearMissTooFewOperands);
+    assert((Kind == NearMissOperand || Kind == NearMissTooFewOperands ||
+            Kind == NearMissMultipleOperands) &&
+           "near-miss does not have an associated opcode");
     return MissedOperand.Opcode;
   }
   // Error code returned when validating the operand.
   unsigned getOperandError() const {
-    assert(Kind == NearMissOperand);
+    assert(Kind == NearMissOperand &&
+           "near-miss does not have an associated operand error");
     return MissedOperand.Error;
   }
   // Index of the actual operand we were trying to match in the list of parsed
   // operands.
   unsigned getOperandIndex() const {
-    assert(Kind == NearMissOperand);
+    assert(Kind == NearMissOperand &&
+           "near-miss does not have an associated operand index");
     return MissedOperand.Index;
   }
 
index 26fda5f22b4f28fae09af7eca055f60899ed051a..ddef2c99a0c3af161c82385e63125695466eaec5 100644 (file)
@@ -10134,6 +10134,7 @@ ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
   std::multimap<unsigned, unsigned> OperandMissesSeen;
   SmallSet<uint64_t, 4> FeatureMissesSeen;
   bool ReportedTooFewOperands = false;
+  bool HaveMultipleBadOperands = false;
 
   // Process the near-misses in reverse order, so that we see more general ones
   // first, and so can avoid emitting more specific ones.
@@ -10253,6 +10254,12 @@ ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
       NearMissesOut.emplace_back(Message);
       break;
     }
+    case NearMissInfo::NearMissMultipleOperands: {
+      // Just record the fact that we have seen this, we will use it as a
+      // fall-back if we don't find a better operand error to report.
+      HaveMultipleBadOperands = true;
+      break;
+    }
     case NearMissInfo::NearMissTooFewOperands: {
       if (!ReportedTooFewOperands) {
         SMLoc EndLoc = ((ARMOperand &)*Operands.back()).getEndLoc();
@@ -10268,6 +10275,16 @@ ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
       break;
     }
   }
+
+  // If there is an encoding that missed on multiple operands (but matched the
+  // target features and early predicate), but we haven't been able to emit a
+  // more specific error for any operands, emit a generic error. This lets the
+  // user know that the mnemonic exists, and that some combination of operands
+  // would work for the current target.
+  if (HaveMultipleBadOperands && NearMissesOut.empty()) {
+    NearMissesOut.emplace_back(NearMissMessage{
+        IDLoc, StringRef("invalid operands for instruction")});
+  }
 }
 
 void ARMAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
index 42e8b6a6128765279c3c39a9e2b070f0cdf91336..51616af818e5b50faf4445580d486a7680b004a5 100644 (file)
@@ -1,4 +1,4 @@
-@ RUN: not llvm-mc -triple=armv7-apple-darwin < %s 2> %t
+ RUN: not llvm-mc -triple=armv7-apple-darwin < %s 2> %t
 @ RUN: FileCheck --check-prefix=CHECK-ERRORS --check-prefix=CHECK-ERRORS-V7 < %t %s
 @ RUN: not llvm-mc -triple=armv8 < %s 2> %t
 @ RUN: FileCheck --check-prefix=CHECK-ERRORS --check-prefix=CHECK-ERRORS-V8 < %t %s
 @ CHECK-ERRORS: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,7]
-@ CHECK-ERRORS-V8: invalid instruction
+@ CHECK-ERRORS-V8: error: invalid operands for instruction
 @ CHECK-ERRORS-V8: too many operands for instruction
 @ CHECK-ERRORS: operand must be an immediate in the range [0,15]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,15]
 @ CHECK-ERRORS: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,7]
-@ CHECK-ERRORS-V8: invalid instruction
+@ CHECK-ERRORS-V8: error: invalid operands for instruction
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V8: too many operands for instruction
 @ CHECK-ERRORS: operand must be an immediate in the range [0,15]
index dca0e448d1140fc0a475ea3fe2f53f55bef5e3cf..8cb2ab34289cdd68597864ab2209e75f53e78da9 100644 (file)
 @ V8: error: invalid instruction
 
 vseleq.f32 s0, d2, d1
-@ V8: error: invalid instruction
+@ V8: error: invalid operands for instruction
 vselgt.f64 s3, s2, s1
 @ V8: error: invalid operand for instruction
 vselgt.f32 s0, q3, q1
-@ V8: error: invalid instruction
+@ V8: error: invalid operands for instruction
 vselgt.f64 q0, s3, q1
-@ V8: error: invalid instruction
+@ V8: error: invalid operands for instruction
 
 vmaxnm.f32 s0, d2, d1
-@ V8: error: invalid instruction
+@ V8: error: invalid operands for instruction
 vminnm.f64 s3, s2, s1
 @ V8: error: invalid operand for instruction
 vmaxnm.f32 s0, q3, q1
-@ V8: error: invalid instruction
+@ V8: error: invalid operands for instruction
 vmaxnm.f64 q0, s3, q1
-@ V8: error: invalid instruction
+@ V8: error: invalid operands for instruction
 vmaxnmgt.f64 q0, s3, q1
 @ CHECK: error: instruction 'vmaxnm' is not predicable, but condition code specified
 
 vcvta.s32.f64 d3, s2
-@ V8: error: invalid instruction
+@ V8: error: invalid operands for instruction
 vcvtp.s32.f32 d3, s2
 @ V8: error: operand must be a register in range [s0, s31]
 vcvtn.u32.f64 d3, s2
-@ V8: error: invalid instruction
+@ V8: error: invalid operands for instruction
 vcvtm.u32.f32 d3, s2
 @ V8: error: operand must be a register in range [s0, s31]
 vcvtnge.u32.f64 d3, s2
 @ V8: error: instruction 'vcvtn' is not predicable, but condition code specified
 
 vcvtbgt.f64.f16 q0, d3
-@ V8: error: invalid instruction
+@ V8: error: invalid operands for instruction
 vcvttlt.f64.f16 s0, s3
 @ V8: error: invalid instruction, any one of the following would fix this:
 @ V8: note: operand must be a register in range [d0, d31]
@@ -79,12 +79,12 @@ vcvtthi.f16.f64 q0, d3
 @ V8: error: operand must be a register in range [s0, s31]
 
 vrintrlo.f32.f32 d3, q0
-@ V8: error: invalid instruction
+@ V8: error: invalid operands for instruction
 vrintxcs.f32.f32 d3, d0
-@ V8: error: invalid instruction
+@ V8: error: invalid operands for instruction
 
 vrinta.f64.f64 s3, q0
-@ V8: error: invalid instruction
+@ V8: error: invalid operands for instruction
 vrintn.f32.f32 d3, d0
 @ V8: error: instruction requires: NEON
 vrintp.f32 q3, q0
index cae1fb331cf50fb92030d0dd016be5b64c40d1a2..47cdab12ea7c4777ed4a95db203d19d33bc7baf5 100644 (file)
@@ -1,9 +1,9 @@
 @ RUN: not llvm-mc -triple armv8 -mattr=-fp-armv8 -show-encoding < %s 2>&1 | FileCheck %s
 
 vmaxnm.f32 s4, d5, q1
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 vmaxnm.f64.f64 s4, d5, q1
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 vmaxnmge.f64.f64 s4, d5, q1
 @ CHECK: error: instruction 'vmaxnm' is not predicable, but condition code specified
 
@@ -12,12 +12,12 @@ vcvta.s32.f32 s1, s2
 vcvtp.u32.f32 s1, d2
 @ CHECK: error: operand must be a register in range [d0, d31]
 vcvtp.f32.u32 d1, q2
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 vcvtplo.f32.u32 s1, s2
 @ CHECK: error: instruction 'vcvtp' is not predicable, but condition code specified
 
 vrinta.f64.f64 s3, d12
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 vrintn.f32 d3, q12
 @ CHECK: error: invalid instruction, any one of the following would fix this:
 @ CHECK: note: operand must be a register in range [d0, d31]
@@ -50,7 +50,7 @@ sha1heq.32  q0, q1
 @ CHECK: error: instruction 'sha1h' is not predicable, but condition code specified
 
 sha1c.32  s0, d1, q2
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 sha1m.32  q0, s1, q2
 @ CHECK: error: operand must be a register in range [q0, q15]
 sha1p.32  s0, q1, q2
@@ -62,12 +62,12 @@ sha256h.32  q0, s1, q2
 sha256h2.32  q0, q1, s2
 @ CHECK: error: operand must be a register in range [q0, q15]
 sha256su1.32  s0, d1, q2
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 sha256su1lt.32  q0, d1, q2
 @ CHECK: error: instruction 'sha256su1' is not predicable, but condition code specified
 
 vmull.p64 q0, s1, s3
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 vmull.p64 s1, d2, d3
 @ CHECK: error: operand must be a register in range [q0, q15]
 vmullge.p64 q0, d16, d17
index bb30bde49afa76db621c9697bd55017f4b035e4a..b5ed9b7346ecf998a98bf0e9251eafda412a0dbc 100644 (file)
@@ -2,18 +2,18 @@
 
 .text
 .arm
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 @ CHECK:         ldrd    r12, [r0, #512]
         ldrd    r12, [r0, #512]
 
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 @ CHECK:         strd    r12, [r0, #512]
         strd    r12, [r0, #512]
 
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 @ CHECK:         ldrd    r1, [r0, #512]
         ldrd    r1, [r0, #512]
 
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 @ CHECK:         strd    r1, [r0, #512]
         strd    r1, [r0, #512]
index e080538eeac3149cfd64fdcdcf6b35a505e99260..d46dc514de8906ad4d63b955bc24e540a3b0db5f 100644 (file)
@@ -10,9 +10,9 @@
   strd r0
 @ CHECK: error: too few operands for instruction
   ldrd r0
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
   strd s0, [r0]
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
   ldrd s0, [r0]
   .arm
 @ CHECK: error: too few operands for instruction
@@ -23,7 +23,7 @@
   strd r0
 @ CHECK: error: too few operands for instruction
   ldrd r0
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
   strd s0, [r0]
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
   ldrd s0, [r0]
index 3d6db3bf422ef8eb529a50920911bc1d9d2dce35..bf5cd8bfe1b2ab7c2b468003d4156a16d0fd7747 100644 (file)
@@ -8,20 +8,20 @@
 
   .arm
 
-// V7: error: invalid instruction
+// V7: error: invalid operands for instruction
 // V8: ldrd    r12, sp, [r0, #32]      @ encoding: [0xd0,0xc2,0xc0,0xe1]
         ldrd    r12, [r0, #32]
 
-// V7: error: invalid instruction
+// V7: error: invalid operands for instruction
 // V8: strd    r12, sp, [r0, #32]      @ encoding: [0xf0,0xc2,0xc0,0xe1]
         strd    r12, [r0, #32]
 
   .thumb
 
-// V7: error: invalid instruction
+// V7: error: invalid operands for instruction
 // V8: ldrd    r12, sp, [r0, #32]      @ encoding: [0xd0,0xe9,0x08,0xcd]
         ldrd    r12, [r0, #32]
 
-// V7: error: invalid instruction
+// V7: error: invalid operands for instruction
 // V8: strd    r12, sp, [r0, #32]      @ encoding: [0xc0,0xe9,0x08,0xcd]
         strd    r12, [r0, #32]
index 93e2db1cb0cb1ccde6923047fa1992401d25c199..732061589a23265e6b12379841ba72e965cbd8f6 100644 (file)
@@ -2,10 +2,10 @@
 
 .text
 .thumb
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 @ CHECK:         ldrd    r12, [r0, #512]
         ldrd    r12, [r0, #512]
 
-@ CHECK: error: invalid instruction
+@ CHECK: error: invalid operands for instruction
 @ CHECK:         strd    r12, [r0, #512]
         strd    r12, [r0, #512]
index 5ceb0082dddc75472e1142bfd3ddf8e18a6a1d97..12d683695e089cf59e23a32819ae331937a1723b 100644 (file)
@@ -19,7 +19,7 @@
 // CHECK-NEXT: movs r0, pc
 // CHECK: note: invalid operand for instruction
 // CHECK-NEXT: movs r0, pc
-// CHECK: error: invalid instruction
+// CHECK: error: invalid operands for instruction
 // CHECK-NEXT: movs pc, pc
 
         // mov.w selects t2MOVr
@@ -32,7 +32,7 @@
 // CHECK-NEXT: mov.w r0, pc
 // CHECK: note: invalid operand for instruction
 // CHECK-NEXT: mov.w r0, pc
-// CHECK: error: invalid instruction
+// CHECK: error: invalid operands for instruction
 // CHECK-NEXT: mov.w pc, pc
 
         // movs.w selects t2MOVr
@@ -45,7 +45,7 @@
 // CHECK-NEXT: movs.w r0, pc
 // CHECK: note: invalid operand for instruction
 // CHECK-NEXT: movs.w r0, pc
-// CHECK: error: invalid instruction
+// CHECK: error: invalid operands for instruction
 // CHECK-NEXT: movs.w pc, pc
 
 
index b784d79fa435505887e642d5ec35c570d44ef09a..5ccbec441106e9927183c20ae8b768362246f3e4 100644 (file)
@@ -43,7 +43,7 @@
 @ CHECK-ERRORS: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,7]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,7]
-@ CHECK-ERRORS-V8: invalid instruction
+@ CHECK-ERRORS-V8: error: invalid operands for instruction
 @ CHECK-ERRORS-V8: too many operands for instruction
 @ CHECK-ERRORS: operand must be an immediate in the range [0,15]
 @ CHECK-ERRORS-V7: operand must be an immediate in the range [0,15]
@@ -91,8 +91,11 @@ foo2:
 
         and sp, r1, #80008000
         and pc, r1, #80008000
-@ CHECK-ERRORS: error: invalid instruction
-@ CHECK-ERRORS: error: invalid instruction
+@ CHECK-ERRORS-V7: error: invalid operands for instruction
+@ CHECK-ERRORS-V8: invalid instruction, any one of the following would fix this:
+@ CHECK-ERRORS-V8: note: invalid operand for instruction
+@ CHECK-ERRORS-V8: note: operand must be a register in range [r0, r14]
+@ CHECK-ERRORS: error: invalid operands for instruction
 
         ssat r0, #1, r0, asr #32
         usat r0, #1, r0, asr #32
@@ -129,7 +132,7 @@ foo2:
 @ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
 @ CHECK-ERRORS: note: instruction requires: arm-mode
 @ CHECK-ERRORS: note: invalid operand for instruction
-@ CHECK-ERRORS: error: invalid instruction
+@ CHECK-ERRORS: error: invalid operands for instruction
 @ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
 @ CHECK-ERRORS: note: invalid operand for instruction
 @ CHECK-ERRORS: note: instruction requires: arm-mode
index be36abe15d389b7e5a2d3e1a39d9702ab48a5f81..986d07a7d88ed41aaab570b020d696270a10a7cd 100644 (file)
@@ -6,7 +6,7 @@
 
 @ ARM: vfma.f64 d16, d18, d17 @ encoding: [0xa1,0x0b,0xe2,0xee]
 @ THUMB: vfma.f64 d16, d18, d17 @ encoding: [0xe2,0xee,0xa1,0x0b]
-@ THUMB_V7EM-ERRORS: error: invalid instruction
+@ THUMB_V7EM-ERRORS: error: invalid operands for instruction
 @ THUMB_V7EM-ERRORS-NEXT: vfma.f64 d16, d18, d17
 vfma.f64 d16, d18, d17
 
@@ -17,7 +17,7 @@ vfma.f32 s2, s4, s0
 
 @ ARM: vfma.f32 d16, d18, d17 @ encoding: [0xb1,0x0c,0x42,0xf2]
 @ THUMB: vfma.f32 d16, d18, d17 @ encoding: [0x42,0xef,0xb1,0x0c]
-@ THUMB_V7EM-ERRORS: error: invalid instruction
+@ THUMB_V7EM-ERRORS: error: invalid operands for instruction
 @ THUMB_V7EM-ERRORS-NEXT: vfma.f32 d16, d18, d17
 vfma.f32 d16, d18, d17
 
@@ -29,7 +29,7 @@ vfma.f32 q2, q4, q0
 
 @ ARM: vfnma.f64 d16, d18, d17 @ encoding: [0xe1,0x0b,0xd2,0xee]
 @ THUMB: vfnma.f64 d16, d18, d17 @ encoding: [0xd2,0xee,0xe1,0x0b]
-@ THUMB_V7EM-ERRORS: error: invalid instruction
+@ THUMB_V7EM-ERRORS: error: invalid operands for instruction
 @ THUMB_V7EM-ERRORS-NEXT: vfnma.f64 d16, d18, d17
 vfnma.f64 d16, d18, d17
 
@@ -40,7 +40,7 @@ vfnma.f32 s2, s4, s0
 
 @ ARM: vfms.f64 d16, d18, d17 @ encoding: [0xe1,0x0b,0xe2,0xee]
 @ THUMB: vfms.f64 d16, d18, d17 @ encoding: [0xe2,0xee,0xe1,0x0b]
-@ THUMB_V7EM-ERRORS: error: invalid instruction
+@ THUMB_V7EM-ERRORS: error: invalid operands for instruction
 @ THUMB_V7EM-ERRORS-NEXT: vfms.f64 d16, d18, d17
 vfms.f64 d16, d18, d17
 
@@ -51,7 +51,7 @@ vfms.f32 s2, s4, s0
 
 @ ARM: vfms.f32 d16, d18, d17 @ encoding: [0xb1,0x0c,0x62,0xf2]
 @ THUMB: vfms.f32 d16, d18, d17 @ encoding: [0x62,0xef,0xb1,0x0c]
-@ THUMB_V7EM-ERRORS: error: invalid instruction
+@ THUMB_V7EM-ERRORS: error: invalid operands for instruction
 @ THUMB_V7EM-ERRORS-NEXT: vfms.f32 d16, d18, d17
 vfms.f32 d16, d18, d17
 
@@ -63,7 +63,7 @@ vfms.f32 q2, q4, q0
 
 @ ARM: vfnms.f64 d16, d18, d17 @ encoding: [0xa1,0x0b,0xd2,0xee]
 @ THUMB: vfnms.f64 d16, d18, d17 @ encoding: [0xd2,0xee,0xa1,0x0b]
-@ THUMB_V7EM-ERRORS: error: invalid instruction
+@ THUMB_V7EM-ERRORS: error: invalid operands for instruction
 @ THUMB_V7EM-ERRORS-NEXT: vfnms.f64 d16, d18, d17
 vfnms.f64 d16, d18, d17
 
index 72fb53053fdd854495a52e8284e2c4dad5931242..7739e4462b41b26f8125df5560919ff1e816520a 100644 (file)
@@ -3275,7 +3275,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
     OS << "    NearMissInfo FeaturesNearMiss = NearMissInfo::getSuccess();\n";
     OS << "    NearMissInfo EarlyPredicateNearMiss = NearMissInfo::getSuccess();\n";
     OS << "    NearMissInfo LatePredicateNearMiss = NearMissInfo::getSuccess();\n";
-    OS << "    bool MultipleInvalidOperands = false;\n";
   }
 
   if (HasMnemonicFirst) {
@@ -3314,11 +3313,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
     OS << "            OperandNearMiss =\n";
     OS << "                NearMissInfo::getTooFewOperands(Formal, it->Opcode);\n";
     OS << "          } else if (OperandNearMiss.getKind() != NearMissInfo::NearMissTooFewOperands) {\n";
-    OS << "            // If more than one operand is invalid, give up on this match entry.\n";
+    OS << "            // An invalid operand plus a missing one at the end are reported the\n";
+    OS << "            // same way as multiple invalid operands.\n";
     OS << "            DEBUG_WITH_TYPE(\n";
     OS << "                \"asm-matcher\",\n";
     OS << "                dbgs() << \"second invalid operand, giving up on this opcode\\n\");\n";
-    OS << "            MultipleInvalidOperands = true;\n";
+    OS << "            OperandNearMiss = NearMissInfo::getMissedMultipleOperands(it->Opcode);\n";
     OS << "            break;\n";
     OS << "          }\n";
     OS << "        } else {\n";
@@ -3387,7 +3387,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
     OS << "        DEBUG_WITH_TYPE(\n";
     OS << "            \"asm-matcher\",\n";
     OS << "            dbgs() << \"second operand mismatch, skipping this opcode\\n\");\n";
-    OS << "        MultipleInvalidOperands = true;\n";
+    OS << "        OperandNearMiss = NearMissInfo::getMissedMultipleOperands(it->Opcode);\n";
     OS << "        break;\n";
     OS << "      }\n";
     OS << "    }\n\n";
@@ -3409,15 +3409,14 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
     OS << "    }\n\n";
   }
 
-  if (ReportMultipleNearMisses)
-    OS << "    if (MultipleInvalidOperands) {\n";
-  else
+  if (!ReportMultipleNearMisses) {
     OS << "    if (!OperandsValid) {\n";
-  OS << "      DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: multiple \"\n";
-  OS << "                                               \"operand mismatches, ignoring \"\n";
-  OS << "                                               \"this opcode\\n\");\n";
-  OS << "      continue;\n";
-  OS << "    }\n";
+    OS << "      DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: multiple \"\n";
+    OS << "                                               \"operand mismatches, ignoring \"\n";
+    OS << "                                               \"this opcode\\n\");\n";
+    OS << "      continue;\n";
+    OS << "    }\n";
+  }
 
   // Emit check that the required features are available.
   OS << "    if ((AvailableFeatures & it->RequiredFeatures) "