]> granicus.if.org Git - llvm/commitdiff
[ARM, Asm] Add diagnostics for general-purpose register operands
authorOliver Stannard <oliver.stannard@arm.com>
Tue, 10 Oct 2017 12:31:53 +0000 (12:31 +0000)
committerOliver Stannard <oliver.stannard@arm.com>
Tue, 10 Oct 2017 12:31:53 +0000 (12:31 +0000)
This adds diagnostic strings for the ARM general-purpose register
classes, which will be used when these classes are expected by the
assembler, but the provided operand is not valid.

One of these, rGPR, requires C++ code to select the correct error
message, as that class contains different registers in pre-v8 and v8
targets. The rest can all have their diagnostic strings stored in the
tablegen description of them.

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

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

16 files changed:
lib/Target/ARM/ARMRegisterInfo.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/basic-thumb2-instructions-v8.s
test/MC/ARM/diagnostics.s
test/MC/ARM/ldrd-strd-gnu-thumb-bad-regs.s
test/MC/ARM/lsl-zero-errors.s
test/MC/ARM/negative-immediates-fail.s
test/MC/ARM/negative-immediates-thumb1-fail.s
test/MC/ARM/register-token-source-loc.s
test/MC/ARM/thumb-branch-errors.s
test/MC/ARM/thumb-diagnostics.s
test/MC/ARM/thumb-mov.s
test/MC/ARM/thumb2-diagnostics.s
test/MC/ARM/thumb2-strd.s
test/MC/ARM/thumbv8m.s
test/MC/ARM/vmrs_vmsr.s

index 137539134dfbf4e1cb42fba2428c822e659d474e..6e06cbb227e3c9f79c6da1cd8e5a6b1d548ec4f2 100644 (file)
@@ -213,6 +213,7 @@ def GPR : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12),
   let AltOrderSelect = [{
       return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();
   }];
+  let DiagnosticString = "operand must be a register in range [r0, r15]";
 }
 
 // GPRs without the PC.  Some ARM instructions do not allow the PC in
@@ -223,6 +224,7 @@ def GPRnopc : RegisterClass<"ARM", [i32], 32, (sub GPR, PC)> {
   let AltOrderSelect = [{
       return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();
   }];
+  let DiagnosticString = "operand must be a register in range [r0, r14]";
 }
 
 // GPRs without the PC but with APSR. Some instructions allow accessing the
@@ -233,6 +235,7 @@ def GPRwithAPSR : RegisterClass<"ARM", [i32], 32, (add (sub GPR, PC), APSR_NZCV)
   let AltOrderSelect = [{
       return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();
   }];
+  let DiagnosticString = "operand must be a register in range [r0, r14] or apsr_nzcv";
 }
 
 // GPRsp - Only the SP is legal. Used by Thumb1 instructions that want the
@@ -240,7 +243,9 @@ def GPRwithAPSR : RegisterClass<"ARM", [i32], 32, (add (sub GPR, PC), APSR_NZCV)
 // FIXME: It would be better to not use this at all and refactor the
 // instructions to not have SP an an explicit argument. That makes
 // frame index resolution a bit trickier, though.
-def GPRsp : RegisterClass<"ARM", [i32], 32, (add SP)>;
+def GPRsp : RegisterClass<"ARM", [i32], 32, (add SP)> {
+  let DiagnosticString = "operand must be a register sp";
+}
 
 // restricted GPR register class. Many Thumb2 instructions allow the full
 // register range for operands, but have undefined behaviours when PC
@@ -251,18 +256,23 @@ def rGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, SP, PC)> {
   let AltOrderSelect = [{
       return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();
   }];
+  let DiagnosticType = "rGPR";
 }
 
 // Thumb registers are R0-R7 normally. Some instructions can still use
 // the general GPR register class above (MOV, e.g.)
-def tGPR : RegisterClass<"ARM", [i32], 32, (trunc GPR, 8)>;
+def tGPR : RegisterClass<"ARM", [i32], 32, (trunc GPR, 8)> {
+  let DiagnosticString = "operand must be a register in range [r0, r7]";
+}
 
 // Thumb registers R0-R7 and the PC. Some instructions like TBB or THH allow
 // the PC to be used as a destination operand as well.
 def tGPRwithpc : RegisterClass<"ARM", [i32], 32, (add tGPR, PC)>;
 
 // The high registers in thumb mode, R8-R15.
-def hGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, tGPR)>;
+def hGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, tGPR)> {
+  let DiagnosticString = "operand must be a register in range [r8, r15]";
+}
 
 // For tail calls, we can't use callee-saved registers, as they are restored
 // to the saved value before the tail call, which would clobber a call address.
index 49b412f4b73ad1a706c06842628d2da5b73c4baf..facdf98aa4f5bdb9dc9d89c11a895159565b5634 100644 (file)
@@ -623,6 +623,8 @@ public:
     SmallString<128> Message;
   };
 
+  const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
+
   void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
                         SmallVectorImpl<NearMissMessage> &NearMissesOut,
                         SMLoc IDLoc, OperandVector &Operands);
@@ -10094,6 +10096,23 @@ extern "C" void LLVMInitializeARMAsmParser() {
 #define GET_MATCHER_IMPLEMENTATION
 #include "ARMGenAsmMatcher.inc"
 
+// Some diagnostics need to vary with subtarget features, so they are handled
+// here. For example, the DPR class has either 16 or 32 registers, depending
+// on the FPU available.
+const char *
+ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) {
+  switch (MatchError) {
+  // rGPR contains sp starting with ARMv8.
+  case Match_rGPR:
+    return hasV8Ops() ? "operand must be a register in range [r0, r14]"
+                      : "operand must be a register in range [r0, r12] or r14";
+
+  // For all other diags, use the static string from tablegen.
+  default:
+    return getMatchKindDiag(MatchError);
+  }
+}
+
 // Process the list of near-misses, throwing away ones we don't want to report
 // to the user, and converting the rest to a source location and string that
 // should be reported.
@@ -10124,7 +10143,7 @@ ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
       SMLoc OperandLoc =
           ((ARMOperand &)*Operands[I.getOperandIndex()]).getStartLoc();
       const char *OperandDiag =
-          getMatchKindDiag((ARMMatchResultTy)I.getOperandError());
+          getCustomOperandDiag((ARMMatchResultTy)I.getOperandError());
 
       // If we have already emitted a message for a superclass, don't also report
       // the sub-class. We consider all operand classes that we don't have a
@@ -10382,7 +10401,7 @@ unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
   case MCK_rGPR:
     if (hasV8Ops() && Op.isReg() && Op.getReg() == ARM::SP)
       return Match_Success;
-    break;
+    return Match_rGPR;
   case MCK_GPRPair:
     if (Op.isReg() &&
         MRI->getRegClass(ARM::GPRRegClassID).contains(Op.getReg()))
index ca38e7e1da529499ec8fe331b1afde157c14c449..d384a6c28356a57d74229396840c09a70dba6d2c 100644 (file)
 @ CHECK-V8: and.w r6, r3, sp, asr #16     @ encoding: [0x03,0xea,0x2d,0x46]
 @ CHECK-V8: and   sp, r0, #0              @ encoding: [0x00,0xf0,0x00,0x0d]
 @ CHECK-V7: error: invalid instruction, any one of the following would fix this:
-@ CHECk-V7: note: instruction variant requires ARMv8 or later
-@ CHECk-V7: note: invalid operand for instruction
+@ CHECK-V7-NEXT: sbc.w r6, r3, sp, asr #16
+@ CHECK-V7: note: instruction variant requires ARMv8 or later
+@ CHECK-V7: note: operand must be a register in range [r0, r12] or r14
 @ CHECK-V7: error: invalid instruction, any one of the following would fix this:
-@ CHECk-V7: note: instruction variant requires ARMv8 or later
-@ CHECk-V7: note: invalid operand for instruction
-@ CHECK-V7: error: invalid operand for instruction
+@ CHECK-V7-NEXT: and.w r6, r3, sp, asr #16
+@ CHECK-V7: note: invalid operand for instruction
+@ CHECK-V7: note: instruction variant requires ARMv8 or later
+@ CHECK-V7: note: operand must be a register in range [r0, r12] or r14
+@ CHECK-V7: error: invalid instruction, any one of the following would fix this:
+@ CHECK-V7-NEXT: and sp, r0, #0
+@ CHECK-V7: note: operand must be a register in range [r0, r12] or r14
+@ CHECK-V7: note: invalid operand for instruction
 
 @ DCPS{1,2,3} (in ARMv8 only)
         dcps1
index ca080cc947b458b686681cef504df697f89cc12d..223dbab87356e83cc7a4a4e229abcc3c389c6ec0 100644 (file)
         @ Invalid 's' bit usage for MOVW
         movs r6, #0xffff
         movwseq r9, #0xffff
-@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
+@ CHECK-ERRORS-NEXT: movs r6, #0xffff
+@ CHECK-ERRORS: note: invalid operand for instruction
+@ CHECK-ERRORS: note: operand must be a register in range [r0, r15]
 @ CHECK-ERRORS: error: instruction 'movw' can not set flags, but 's' suffix specified
+@ CHECK-ERRORS-NEXT: movwseq r9, #0xffff
 
         @ Out of range immediate for MOVT
         movt r9, 0x10000
 @ CHECK-ERRORS: error: 'ror' rotate amount must be 8, 16, or 24
 @ CHECK-ERRORS:         sxtah r9, r3, r3, ror #-8
 @ CHECK-ERRORS:                                ^
-@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS: error: operand must be a register in range [r0, r14]
 @ CHECK-ERRORS:         sxtb16ge r2, r3, lsr #24
 @ CHECK-ERRORS:                          ^
 
         sbfx sp, pc, #4, #5
         ubfx pc, r0, #0, #31
         ubfx r14, pc, #1, #2
-@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS: error: operand must be a register in range [r0, r14]
 @ CHECK-ERRORS:         sbfx pc, r2, #1, #3
 @ CHECK-ERRORS:              ^
-@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS: error: operand must be a register in range [r0, r14]
 @ CHECK-ERRORS:         sbfx sp, pc, #4, #5
 @ CHECK-ERRORS:                  ^
-@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS: error: operand must be a register in range [r0, r14]
 @ CHECK-ERRORS:         ubfx pc, r0, #0, #31
 @ CHECK-ERRORS:              ^
-@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS: error: operand must be a register in range [r0, r14]
 @ CHECK-ERRORS:         ubfx r14, pc, #1, #2
 @ CHECK-ERRORS:                   ^
 
index 9d81a27f0ca5a427240101ab84cb72bf7c755c5d..3785815f41ce63d98beb6c0f24f799a9f8d5b0c4 100644 (file)
@@ -1,10 +1,14 @@
 @ RUN: not llvm-mc -triple=armv7-linux-gnueabi %s 2>&1 | FileCheck %s
+
+@ FIXME: These errors are inaccurate because the error is being reported on the
+@ implicit r13 operand added after r12.
+
 .text
 .thumb
-@ CHECK: error: invalid operand for instruction
+@ CHECK: error: operand must be a register in range [r0, r12] or r14
 @ CHECK:         ldrd    r12, [r0, #512]
         ldrd    r12, [r0, #512]
 
-@ CHECK: error: invalid operand for instruction
+@ CHECK: error: operand must be a register in range [r0, r12] or r14
 @ CHECK:         strd    r12, [r0, #512]
         strd    r12, [r0, #512]
index fe5846503c1a84875cd1d0f774d8dbd3cf331060..937b50f62da04a1004443757a1e3b4729c51dcae 100644 (file)
 
 // CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
 // CHECK-NONARM-NEXT: lsl pc, r0, #0
-// CHECK-NONARM: instruction requires: arm-mode
-// CHECK-NONARM: invalid operand for instruction
+// CHECK-NONARM: note: instruction requires: arm-mode
+// CHECK-NONARM: note: operand must be a register in range [r0, r14]
 
 // CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
 // CHECK-NONARM-NEXT: lsl r0, pc, #0
-// CHECK-NONARM: instruction requires: arm-mode
-// CHECK-NONARM: invalid operand for instruction
+// CHECK-NONARM: note: instruction requires: arm-mode
+// CHECK-NONARM: note: operand must be a register in range [r0, r14]
 
 // CHECK-NONARM: error: instruction requires: arm-mode
 // CHECK-NONARM-NEXT: lsl pc, pc, #0
 
 // CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
 // CHECK-NONARM-NEXT: lsls pc, r0, #0
-// CHECK-NONARM: instruction requires: arm-mode
-// CHECK-NONARM: invalid operand for instruction
+// CHECK-NONARM: note: instruction requires: arm-mode
+// CHECK-NONARM: note: operand must be a register in range [r0, r14]
 
 // CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
 // CHECK-NONARM-NEXT: lsls r0, pc, #0
-// CHECK-NONARM: instruction requires: arm-mode
-// CHECK-NONARM: invalid operand for instruction
+// CHECK-NONARM: note: instruction requires: arm-mode
+// CHECK-NONARM: note: operand must be a register in range [r0, r14]
 
 // CHECK-NONARM: error: instruction requires: arm-mode
 // CHECK-NONARM-NEXT: lsls pc, pc, #0
 
 // CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
 // CHECK-NONARM-NEXT: mov pc, r0, lsl #0
-// CHECK-NONARM: invalid operand for instruction
-// CHECK-NONARM: invalid operand for instruction
+// CHECK-NONARM: note: operand must be a register in range [r0, r15]
+// CHECK-THUMBV7: note: operand must be a register in range [r0, r12] or r14
+// CHECK-THUMBV8: note: operand must be a register in range [r0, r14]
+
 // CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
 // CHECK-NONARM-NEXT: mov r0, pc, lsl #0
-// CHECK-NONARM: invalid operand for instruction
-// CHECK-NONARM: invalid operand for instruction
-// CHECK-NONARM: operand must be an immediate in the range [256,65535]
+// CHECK-NONARM: note: operand must be a register in range [r0, r15]
+// CHECK-NONARM: note: invalid operand for instruction
+// CHECK-NONARM: note: invalid operand for instruction
+// CHECK-NONARM: note: operand must be an immediate in the range [256,65535]
+
 // CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
 // CHECK-NONARM-NEXT: mov pc, pc, lsl #0
-// CHECK-NONARM: invalid operand for instruction
-// CHECK-NONARM: invalid operand for instruction
-// CHECK-NONARM: error: invalid operand for instruction
+// CHECK-NONARM: note: operand must be a register in range [r0, r15]
+// CHECK-THUMBV7: note: operand must be a register in range [r0, r12] or r14
+// CHECK-THUMBV8: note: operand must be a register in range [r0, r14]
+
+// CHECK-THUMBV7: error: operand must be a register in range [r0, r12] or r14
+// CHECK-THUMBV8: error: operand must be a register in range [r0, r14]
 // CHECK-NONARM-NEXT: movs pc, r0, lsl #0
+
 // CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
 // CHECK-NONARM-NEXT: movs r0, pc, lsl #0
-// CHECK-NONARM: invalid operand for instruction
-// CHECK-NONARM: invalid operand for instruction
-// CHECK-NONARM: error: invalid operand for instruction
+// CHECK-NONARM: note: operand must be a register in range [r0, r14]
+// CHECK-NONARM: note: invalid operand for instruction
+// CHECK-NONARM: note: invalid operand for instruction
+
+// CHECK-THUMBV7: error: operand must be a register in range [r0, r12] or r14
+// CHECK-THUMBV8: error: operand must be a register in range [r0, r14]
 // CHECK-NONARM-NEXT: movs pc, pc, lsl #0
 
 // CHECK-ARM: mov pc, r0                @ encoding: [0x00,0xf0,0xa0,0xe1]
 
 // FIXME: We should consistently have the "requires ARMv8" error here
 // CHECK-THUMBV7: error: invalid instruction, any one of the following would fix this:
-// CHECK-THUMBV7: invalid operand for instruction
 // CHECK-THUMBV7-NEXT: mov sp, sp, lsl #0
+// CHECK-THUMBV7: note: operand must be a register in range [r0, r15]
+// CHECK-THUMBV7: note: operand must be a register in range [r0, r12] or r14
+
 // CHECK-THUMBV7: error: invalid instruction, any one of the following would fix this:
-// CHECK-THUMBV7: invalid operand for instruction
 // CHECK-THUMBV7-NEXT: movs sp, sp, lsl #0
+// CHECK-THUMBV7: note: operand must be a register in range [r0, r14]
+// CHECK-THUMBV7: note: operand must be a register in range [r0, r12] or r14
+
 // CHECK-THUMBV7: error: invalid instruction, any one of the following would fix this:
-// CHECK-THUMBV7: instruction variant requires ARMv8 or later
 // CHECK-THUMBV7-NEXT: movs r0, sp, lsl #0
+// CHECK-THUMBV7: note: operand must be a register in range [r0, r14]
+// CHECK-THUMBV7: note: invalid operand for instruction
+// CHECK-THUMBV7: note: instruction variant requires ARMv8 or later
+
 // CHECK-THUMBV7: error: invalid instruction, any one of the following would fix this:
-// CHECK-THUMBV7: invalid operand for instruction
 // CHECK-THUMBV7-NEXT: movs sp, r0, lsl #0
+// CHECK-THUMBV7: note: operand must be a register in range [r0, r14]
+// CHECK-THUMBV7: note: operand must be a register in range [r0, r12] or r14
 
 // CHECK-ARM: mov sp, sp                @ encoding: [0x0d,0xd0,0xa0,0xe1]
 // CHECK-ARM: movs sp, sp               @ encoding: [0x0d,0xd0,0xb0,0xe1]
index dc9b5eb2d1ef45392f61a5c16f76a2eb3742395a..9bc4c92b5ee6655859e6e816ab74b09cc6707585 100644 (file)
@@ -3,18 +3,27 @@
 .arm
 
 ADC r0, r1, #0xFFFFFEEE
-# CHECK: error: invalid operand for instruction
+# CHECK: error: invalid instruction, any one of the following would fix this:
+# CHECK: note: invalid operand for instruction
+# CHECK: note: operand must be a register in range [r0, r15]
 ADC r0, r1, #0xABFEABFF
-# CHECK: error: invalid operand for instruction
+# CHECK: error: invalid instruction, any one of the following would fix this:
+# CHECK: note: invalid operand for instruction
+# CHECK: note: operand must be a register in range [r0, r15]
 ADC r0, r1, #0xFFFFFE02
-# CHECK: error: invalid operand for instruction
+# CHECK: error: invalid instruction, any one of the following would fix this:
+# CHECK: note: invalid operand for instruction
+# CHECK: note: operand must be a register in range [r0, r15]
 
 ADD.W r0, r0, #0xFF01FF01
-# CHECK: invalid operand for instruction
+# CHECK: error: invalid instruction, any one of the following would fix this:
+# CHECK: note: invalid operand for instruction
+# CHECK: note: operand must be a register in range [r0, r15]
 
 ORR r0, r1, #0xFFFFFF00
 # CHECK: error: invalid instruction, any one of the following would fix this:
 # CHECK: note: invalid operand for instruction
+# CHECK: note: operand must be a register in range [r0, r15]
 # CHECK: note: instruction requires: thumb2
 ORN r0, r1, #0xFFFFFF00
 # CHECK: error: instruction requires: thumb2
index bc09bd3e790b5dfdc056f331982150919bef078b..70e01ff1f82c1be769a7ea312ced09afefe8ada9 100644 (file)
@@ -7,6 +7,7 @@ ADDs r1, r0, #0xFFFFFFF5
 # CHECK-DAG: note: instruction requires: thumb2
 # CHECK-DAG: note: invalid operand for instruction
 # CHECK-DAG: note: operand must be an immediate in the range [0,7]
+# CHECK-DAG: note: operand must be a register in range [r0, r7]
 
 ADDs r0, #0xFFFFFEFF
 # CHECK: error: invalid instruction, any one of the following would fix this:
@@ -17,6 +18,7 @@ SUBs r1, r0, #0xFFFFFFF5
 # CHECK: error: invalid instruction, any one of the following would fix this:
 # CHECK-DAG: note: invalid operand for instruction
 # CHECK-DAG: note: operand must be an immediate in the range [0,7]
+# CHECK-DAG: note: operand must be a register in range [r0, r7]
 
 SUBs r0, #0xFFFFFEFF
 # CHECK: error: invalid instruction, any one of the following would fix this:
index 3907dc1b61a7bc91c03926ba4313fa9195d04325..bfd6097adf0408786451960b8ac2a1ad490c7ed2 100644 (file)
@@ -6,7 +6,7 @@
   add sp, r0, #4
 // CHECK: error: invalid instruction, any one of the following would fix this:
 // CHECK: note: instruction requires: thumb2
-// CHECK: note: invalid operand for instruction
+// CHECK: note: operand must be a register sp
 // CHECK-NEXT: {{^  add sp, r0, #4}}
 // CHECK-NEXT: {{^          \^}}
 // CHECK: note: too many operands for instruction
index 82525c15a54acef42530b390f05830ce251beab6..df7b47c8f6b5db8e27277ed53112552211b9db5a 100644 (file)
@@ -18,5 +18,7 @@
 @ CHECK:         cbnz r2, #1
 @ CHECK: error: branch target out of range
 @ CHECK:         beq #1
-@ CHECK: error: invalid operand for instruction
-@ CHECK:         blx #2
+@ CHECK: invalid operand for instruction
+@ CHECK-NEXT:         blx #2
+@ CHECK: operand must be a register in range [r0, r15]
+@ CHECK-NEXT:         blx #2
index 91b8a2b276d8440994ce0c856f59eadc7ad4e31a..dd543b1ac80b13499ded383caa5c8024b09c36f4 100644 (file)
 @ CHECK-ERRORS:         add r2, r3
 @ CHECK-ERRORS:         ^
 @ CHECK-ERRORS: note: instruction variant requires Thumb2
-@ CHECK-ERRORS: note: invalid operand for instruction
+@ CHECK-ERRORS: note: operand must be a register sp
 @ CHECK-ERRORS-V5: error: instruction variant requires ARMv6 or later
 @ CHECK-ERRORS-V5:         mov r2, r3
 @ CHECK-ERRORS-V5:         ^
 
+@ Immediates where registers were expected
+        adds #0, r1, r2
+        adds r0, #1, r2
+@ CHECK-ERRORS: error: operand must be a register in range [r0, r7]
+@ CHECK-ERRORS:         adds #0, r1, r2
+@ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
+@ CHECK-ERRORS:         adds r0, #1, r2
+@ CHECK-ERRORS: note: operand must be a register in range [r0, r7]
+@ CHECK-ERRORS: note: too many operands for instruction
 
 @ Out of range immediates for ASR instruction.
         asrs r2, r3, #33
 @ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
 @ CHECK-ERRORS:         add sp, #-1
 @ CHECK-ERRORS:                 ^
-@ CHECK-ERRORS: note: invalid operand for instruction
+@ CHECK-ERRORS: note: operand must be a register in range [r0, r15]
 @ CHECK-ERRORS: note: instruction requires: thumb2
 @ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
 @ CHECK-ERRORS:         add sp, #3
 @ CHECK-ERRORS:                 ^
-@ CHECK-ERRORS: note: invalid operand for instruction
+@ CHECK-ERRORS: note: operand must be a register in range [r0, r15]
 @ CHECK-ERRORS: note: instruction requires: thumb2
 @ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
 @ CHECK-ERRORS:         add sp, sp, #512
 @ CHECK-ERRORS:                     ^
-@ CHECK-ERRORS: note: invalid operand for instruction
+@ CHECK-ERRORS: note: operand must be a register in range [r0, r15]
 @ CHECK-ERRORS: note: instruction requires: thumb2
 @ CHECK-ERRORS: error: instruction requires: thumb2
 @ CHECK-ERRORS:         add r2, sp, #1024
index 69784b02bf7f80b03c2d956d8be81045c5234078..5ceb0082dddc75472e1142bfd3ddf8e18a6a1d97 100644 (file)
         movs pc, r0
         movs r0, pc
         movs pc, pc
-// CHECK: error: invalid operand for instruction
+// CHECK: error: operand must be a register in range [r0, r14]
 // CHECK-NEXT: movs pc, r0
-// CHECK: error: invalid operand for instruction
+// CHECK: note: operand must be a register in range [r0, r14]
+// CHECK-NEXT: movs r0, pc
+// CHECK: note: invalid operand for instruction
 // CHECK-NEXT: movs r0, pc
 // CHECK: error: invalid instruction
 // CHECK-NEXT: movs pc, pc
         mov.w pc, r0
         mov.w r0, pc
         mov.w pc, pc
-// CHECK: error: invalid operand for instruction
+// CHECK: error: operand must be a register in range [r0, r14]
 // CHECK-NEXT: mov.w pc, r0
-// CHECK: error: invalid operand for instruction
+// CHECK: note: operand must be a register in range [r0, r14]
+// CHECK-NEXT: mov.w r0, pc
+// CHECK: note: invalid operand for instruction
 // CHECK-NEXT: mov.w r0, pc
 // CHECK: error: invalid instruction
 // CHECK-NEXT: mov.w pc, pc
         movs.w pc, r0
         movs.w r0, pc
         movs.w pc, pc
-// CHECK: error: invalid operand for instruction
+// CHECK: error: operand must be a register in range [r0, r14]
 // CHECK-NEXT: movs.w pc, r0
-// CHECK: error: invalid operand for instruction
+// CHECK: note: operand must be a register in range [r0, r14]
+// CHECK-NEXT: movs.w r0, pc
+// CHECK: note: invalid operand for instruction
 // CHECK-NEXT: movs.w r0, pc
 // CHECK: error: invalid instruction
 // CHECK-NEXT: movs.w pc, pc
index 67ce2423569ea3272e44cca402be4cd4033aba38..851afb816338c09516a8f45a0bdd824102253a6a 100644 (file)
@@ -91,8 +91,7 @@ foo2:
 
         and sp, r1, #80008000
         and pc, r1, #80008000
-@ CHECK-ERRORS-V7: error: invalid instruction
-@ CHECK-ERRORS-V8: error: invalid operand for instruction
+@ CHECK-ERRORS: error: invalid instruction
 @ CHECK-ERRORS: error: invalid instruction
 
         ssat r0, #1, r0, asr #32
@@ -105,10 +104,12 @@ foo2:
         and.w r2, r7, pc, lsr #16
 @ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
 @ CHECK-ERRORS: note: invalid operand for instruction
-@ CHECK-ERRORS: note: invalid operand for instruction
+@ CHECK-ERRORS-V7: note: operand must be a register in range [r0, r12] or r14
+@ CHECK-ERRORS-V8: note: operand must be a register in range [r0, r14]
 @ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
 @ CHECK-ERRORS: note: invalid operand for instruction
-@ CHECK-ERRORS: note: invalid operand for instruction
+@ CHECK-ERRORS-V7: note: operand must be a register in range [r0, r12] or r14
+@ CHECK-ERRORS-V8: note: operand must be a register in range [r0, r14]
 
 
         @ PC is not valid as base of load
index 3f8025d2cd70dea763eeac91264c1a131880e1a7..3036a04c0fcd3c0965084aeda4c65dc808407bb4 100644 (file)
@@ -2,9 +2,9 @@
 .text
 .thumb
 
-@ CHECK: error: invalid operand for instruction
-@ CHECK: error: invalid operand for instruction
-@ CHECK: error: invalid operand for instruction
+@ CHECK: error: operand must be a register in range [r0, r12] or r14
+@ CHECK: error: operand must be a register in range [r0, r12] or r14
+@ CHECK: error: operand must be a register in range [r0, r12] or r14
 strd r12, SP, [r0, #256]
 strd r12, SP, [r0, #256]!
 strd r12, SP, [r0], #256
index 354b75e71c4ce4a28759d7fc82336e59896af82a..5ff58cccb800fb151f64d81d295233b4ccd54b40 100644 (file)
@@ -238,42 +238,42 @@ bxns r0, r1
 // UNDEF: error: too many operands for instruction
 // UNDEF:     blxns r0, #0
 blxns r0, #0
-// UNDEF: error: invalid operand for instruction
+// UNDEF: error: operand must be a register in range [r0, r14]
 // UNDEF:     blxns label
 blxns label
 // UNDEF: error: too many operands for instruction
 // UNDEF:     tt r0, r1, r2
 tt r0, r1, r2
-// UNDEF: error: invalid operand for instruction
+// UNDEF: error: operand must be a register in range [r0, r14]
 // UNDEF:     tt r0, [r1]
 tt r0, [r1]
 // UNDEF: error: too many operands for instruction
 // UNDEF:     tt r0, r1, #4
 tt r0, r1, #4
-// UNDEF: error: invalid operand for instruction
+// UNDEF: error: operand must be a register in range [r0, r14]
 // UNDEF:     tt r0, #4
 tt r0, #4
 
 // Unpredictable operands
-// UNDEF: error: invalid operand for instruction
+// UNDEF: error: operand must be a register in range [r0, r14]
 // UNDEF:     blxns pc
 blxns pc
-// UNDEF: error: invalid operand for instruction
+// UNDEF: error: operand must be a register in range [r0, r12] or r14
 // UNDEF:     tt sp, r0
 tt sp, r0
-// UNDEF: error: invalid operand for instruction
+// UNDEF: error: operand must be a register in range [r0, r12] or r14
 // UNDEF:     tt pc, r0
 tt pc, r0
-// UNDEF: error: invalid operand for instruction
+// UNDEF: error: operand must be a register in range [r0, r14]
 // UNDEF:     tt r0, pc
 tt r0, pc
 
 // UNDEF-BASELINE: error: invalid instruction
-// UNDEF-MAINLINE: error: invalid operand for instruction
+// UNDEF-MAINLINE: error: operand must be a register in range [r0, r14]
 // UNDEF:     vlldm pc
 vlldm pc
 
 // UNDEF-BASELINE: error: invalid instruction
-// UNDEF-MAINLINE: error: invalid operand for instruction
+// UNDEF-MAINLINE: error: operand must be a register in range [r0, r14]
 // UNDEF:     vlstm pc
 vlstm pc
index 4bb046c797b83f5be2e69a9e3569f856b03eb965..edca917c72a32a0ef5110000f37a9e233d824763 100644 (file)
         vmsr  fpscr, sp
         vmsr  fpscr, pc
 
-// ERROR-V7A-ARM: invalid operand for instruction
+// ERROR-V7A-ARM: operand must be a register in range [r0, r14]
 // CHECK-V7A-ARM: vmsr  fpscr, r0             @ encoding: [0x10,0x0a,0xe1,0xee]
 // CHECK-V7A-ARM: vmsr  fpexc, r1             @ encoding: [0x10,0x1a,0xe8,0xee]
 // CHECK-V7A-ARM: vmsr  fpsid, r2             @ encoding: [0x10,0x2a,0xe0,0xee]
 // CHECK-V7A-ARM: vmsr  fpscr, r10            @ encoding: [0x10,0xaa,0xe1,0xee]
 // CHECK-V7A-ARM: vmsr  fpscr, sp             @ encoding: [0x10,0xda,0xe1,0xee]
-// ERROR-V7A-ARM: invalid operand for instruction
+// ERROR-V7A-ARM: operand must be a register in range [r0, r14]
 
-// ERROR-V7A-THUMB: invalid operand for instruction
+// ERROR-V7A-THUMB: operand must be a register in range [r0, r14]
 // CHECK-V7A-THUMB: vmsr  fpscr, r0             @ encoding: [0xe1,0xee,0x10,0x0a]
 // CHECK-V7A-THUMB: vmsr  fpexc, r1             @ encoding: [0xe8,0xee,0x10,0x1a]
 // CHECK-V7A-THUMB: vmsr  fpsid, r2             @ encoding: [0xe0,0xee,0x10,0x2a]
 // CHECK-V7A-THUMB: vmsr  fpscr, r10            @ encoding: [0xe1,0xee,0x10,0xaa]
 // ERROR-V7A-THUMB: invalid operand for instruction
-// ERROR-V7A-THUMB: invalid operand for instruction
+// ERROR-V7A-THUMB: operand must be a register in range [r0, r14]
 
-// ERROR-V7M: invalid operand for instruction
+// ERROR-V7M: operand must be a register in range [r0, r14]
 // CHECK-V7M: vmsr  fpscr, r0             @ encoding: [0xe1,0xee,0x10,0x0a]
 // CHECK-V7M: vmsr  fpexc, r1             @ encoding: [0xe8,0xee,0x10,0x1a]
 // CHECK-V7M: vmsr  fpsid, r2             @ encoding: [0xe0,0xee,0x10,0x2a]
 // CHECK-V7M: vmsr  fpscr, r10            @ encoding: [0xe1,0xee,0x10,0xaa]
 // ERROR-V7M: invalid operand for instruction
-// ERROR-V7M: invalid operand for instruction
+// ERROR-V7M: operand must be a register in range [r0, r14]
 
-// ERROR-V8A-ARM: invalid operand for instruction
+// ERROR-V8A-ARM: operand must be a register in range [r0, r14]
 // CHECK-V8A-ARM: vmsr  fpscr, r0             @ encoding: [0x10,0x0a,0xe1,0xee]
 // CHECK-V8A-ARM: vmsr  fpexc, r1             @ encoding: [0x10,0x1a,0xe8,0xee]
 // CHECK-V8A-ARM: vmsr  fpsid, r2             @ encoding: [0x10,0x2a,0xe0,0xee]
 // CHECK-V8A-ARM: vmsr  fpscr, r10            @ encoding: [0x10,0xaa,0xe1,0xee]
 // CHECK-V8A-ARM: vmsr  fpscr, sp             @ encoding: [0x10,0xda,0xe1,0xee]
-// ERROR-V8A-ARM: invalid operand for instruction
+// ERROR-V8A-ARM: operand must be a register in range [r0, r14]
 
-// ERROR-V8A-THUMB: invalid operand for instruction
+// ERROR-V8A-THUMB: operand must be a register in range [r0, r14]
 // CHECK-V8A-THUMB: vmsr  fpscr, r0             @ encoding: [0xe1,0xee,0x10,0x0a]
 // CHECK-V8A-THUMB: vmsr  fpexc, r1             @ encoding: [0xe8,0xee,0x10,0x1a]
 // CHECK-V8A-THUMB: vmsr  fpsid, r2             @ encoding: [0xe0,0xee,0x10,0x2a]
 // CHECK-V8A-THUMB: vmsr  fpscr, r10            @ encoding: [0xe1,0xee,0x10,0xaa]
 // CHECK-V8A-THUMB: vmsr  fpscr, sp             @ encoding: [0xe1,0xee,0x10,0xda]
-// ERROR-V8A-THUMB: invalid operand for instruction
+// ERROR-V8A-THUMB: operand must be a register in range [r0, r14]
 
-// ERROR-V8M: invalid operand for instruction
+// ERROR-V8M: operand must be a register in range [r0, r14]
 // CHECK-V8M: vmsr  fpscr, r0             @ encoding: [0xe1,0xee,0x10,0x0a]
 // CHECK-V8M: vmsr  fpexc, r1             @ encoding: [0xe8,0xee,0x10,0x1a]
 // CHECK-V8M: vmsr  fpsid, r2             @ encoding: [0xe0,0xee,0x10,0x2a]
 // CHECK-V8M: vmsr  fpscr, r10            @ encoding: [0xe1,0xee,0x10,0xaa]
 // ERROR-V8M: invalid operand for instruction
-// ERROR-V8M: invalid operand for instruction
+// ERROR-V8M: operand must be a register in range [r0, r14]
 
 // ERROR-NOVFP: invalid instruction
 // ERROR-NOVFP: instruction requires: VFP2