Index: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td @@ -213,6 +213,7 @@ let AltOrderSelect = [{ return 1 + MF.getSubtarget().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 @@ let AltOrderSelect = [{ return 1 + MF.getSubtarget().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 @@ let AltOrderSelect = [{ return 1 + MF.getSubtarget().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 @@ // 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 @@ let AltOrderSelect = [{ return 1 + MF.getSubtarget().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: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -623,6 +623,8 @@ SmallString<128> Message; }; + const char *getCustomOperandDiag(ARMMatchResultTy MatchError); + void FilterNearMisses(SmallVectorImpl &NearMissesIn, SmallVectorImpl &NearMissesOut, SMLoc IDLoc, OperandVector &Operands); @@ -10094,6 +10096,23 @@ #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 @@ 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 @@ 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: llvm/trunk/test/MC/ARM/basic-thumb2-instructions-v8.s =================================================================== --- llvm/trunk/test/MC/ARM/basic-thumb2-instructions-v8.s +++ llvm/trunk/test/MC/ARM/basic-thumb2-instructions-v8.s @@ -32,12 +32,18 @@ @ 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: llvm/trunk/test/MC/ARM/diagnostics.s =================================================================== --- llvm/trunk/test/MC/ARM/diagnostics.s +++ llvm/trunk/test/MC/ARM/diagnostics.s @@ -182,8 +182,12 @@ @ 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 @@ -359,7 +363,7 @@ @ 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: ^ @@ -379,16 +383,16 @@ 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: llvm/trunk/test/MC/ARM/ldrd-strd-gnu-thumb-bad-regs.s =================================================================== --- llvm/trunk/test/MC/ARM/ldrd-strd-gnu-thumb-bad-regs.s +++ llvm/trunk/test/MC/ARM/ldrd-strd-gnu-thumb-bad-regs.s @@ -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: llvm/trunk/test/MC/ARM/lsl-zero-errors.s =================================================================== --- llvm/trunk/test/MC/ARM/lsl-zero-errors.s +++ llvm/trunk/test/MC/ARM/lsl-zero-errors.s @@ -15,26 +15,26 @@ // 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 @@ -55,24 +55,35 @@ // 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] @@ -118,17 +129,25 @@ // 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: llvm/trunk/test/MC/ARM/negative-immediates-fail.s =================================================================== --- llvm/trunk/test/MC/ARM/negative-immediates-fail.s +++ llvm/trunk/test/MC/ARM/negative-immediates-fail.s @@ -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: llvm/trunk/test/MC/ARM/negative-immediates-thumb1-fail.s =================================================================== --- llvm/trunk/test/MC/ARM/negative-immediates-thumb1-fail.s +++ llvm/trunk/test/MC/ARM/negative-immediates-thumb1-fail.s @@ -7,6 +7,7 @@ # 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 @@ # 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: llvm/trunk/test/MC/ARM/register-token-source-loc.s =================================================================== --- llvm/trunk/test/MC/ARM/register-token-source-loc.s +++ llvm/trunk/test/MC/ARM/register-token-source-loc.s @@ -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: llvm/trunk/test/MC/ARM/thumb-branch-errors.s =================================================================== --- llvm/trunk/test/MC/ARM/thumb-branch-errors.s +++ llvm/trunk/test/MC/ARM/thumb-branch-errors.s @@ -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: llvm/trunk/test/MC/ARM/thumb-diagnostics.s =================================================================== --- llvm/trunk/test/MC/ARM/thumb-diagnostics.s +++ llvm/trunk/test/MC/ARM/thumb-diagnostics.s @@ -27,11 +27,20 @@ @ 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 @@ -237,17 +246,17 @@ @ 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: llvm/trunk/test/MC/ARM/thumb-mov.s =================================================================== --- llvm/trunk/test/MC/ARM/thumb-mov.s +++ llvm/trunk/test/MC/ARM/thumb-mov.s @@ -13,9 +13,11 @@ 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 @@ -24,9 +26,11 @@ 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 @@ -35,9 +39,11 @@ 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: llvm/trunk/test/MC/ARM/thumb2-diagnostics.s =================================================================== --- llvm/trunk/test/MC/ARM/thumb2-diagnostics.s +++ llvm/trunk/test/MC/ARM/thumb2-diagnostics.s @@ -91,8 +91,7 @@ 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 @@ 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: llvm/trunk/test/MC/ARM/thumb2-strd.s =================================================================== --- llvm/trunk/test/MC/ARM/thumb2-strd.s +++ llvm/trunk/test/MC/ARM/thumb2-strd.s @@ -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: llvm/trunk/test/MC/ARM/thumbv8m.s =================================================================== --- llvm/trunk/test/MC/ARM/thumbv8m.s +++ llvm/trunk/test/MC/ARM/thumbv8m.s @@ -238,42 +238,42 @@ // 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: llvm/trunk/test/MC/ARM/vmrs_vmsr.s =================================================================== --- llvm/trunk/test/MC/ARM/vmrs_vmsr.s +++ llvm/trunk/test/MC/ARM/vmrs_vmsr.s @@ -123,53 +123,53 @@ 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