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
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
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
// 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
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.
SmallString<128> Message;
};
+ const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
+
void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
SmallVectorImpl<NearMissMessage> &NearMissesOut,
SMLoc IDLoc, OperandVector &Operands);
#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.
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
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()))
@ 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
@ 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: ^
@ 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]
// 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]
.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
# 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:
# 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:
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
@ 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
@ 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
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
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
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
.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
// 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
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