Index: lib/Target/ARM/ARMRegisterInfo.td =================================================================== --- lib/Target/ARM/ARMRegisterInfo.td +++ lib/Target/ARM/ARMRegisterInfo.td @@ -294,11 +294,14 @@ let AltOrderSelect = [{ return 1 + MF.getSubtarget().useStride4VFPs(MF); }]; + let DiagnosticString = "operand must be a register in range [s0, s31]"; } // Subset of SPR which can be used as a source of NEON scalars for 16-bit // operations -def SPR_8 : RegisterClass<"ARM", [f32], 32, (sequence "S%u", 0, 15)>; +def SPR_8 : RegisterClass<"ARM", [f32], 32, (sequence "S%u", 0, 15)> { + let DiagnosticString = "operand must be a register in range [s0, s15]"; +} // Scalar double precision floating point / generic 64-bit vector register // class. @@ -313,17 +316,22 @@ let AltOrderSelect = [{ return 1 + MF.getSubtarget().useStride4VFPs(MF); }]; + let DiagnosticType = "DPR"; } // Subset of DPR that are accessible with VFP2 (and so that also have // 32-bit SPR subregs). def DPR_VFP2 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32, v4f16], 64, - (trunc DPR, 16)>; + (trunc DPR, 16)> { + let DiagnosticString = "operand must be a register in range [d0, d15]"; +} // Subset of DPR which can be used as a source of NEON scalars for 16-bit // operations def DPR_8 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32, v4f16], 64, - (trunc DPR, 8)>; + (trunc DPR, 8)> { + let DiagnosticString = "operand must be a register in range [d0, d7]"; +} // Generic 128-bit vector register class. def QPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16], 128, @@ -331,15 +339,20 @@ // Allocate non-VFP2 aliases Q8-Q15 first. let AltOrders = [(rotl QPR, 8)]; let AltOrderSelect = [{ return 1; }]; + let DiagnosticString = "operand must be a register in range [q0, q15]"; } // Subset of QPR that have 32-bit SPR subregs. def QPR_VFP2 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], - 128, (trunc QPR, 8)>; + 128, (trunc QPR, 8)> { + let DiagnosticString = "operand must be a register in range [q0, q7]"; +} // Subset of QPR that have DPR_8 and SPR_8 subregs. def QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], - 128, (trunc QPR, 4)>; + 128, (trunc QPR, 4)> { + let DiagnosticString = "operand must be a register in range [q0, q3]"; +} // Pseudo-registers representing odd-even pairs of D registers. The even-odd // pairs are already represented by the Q registers. Index: lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -10012,6 +10012,10 @@ 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"; + // DPR contains 16 registers for some FPUs, and 32 for others. + case Match_DPR: + return hasD16() ? "operand must be a register in range [d0, d15]" + : "operand must be a register in range [d0, d31]"; // For all other diags, use the static string from tablegen. default: Index: test/MC/ARM/d16.s =================================================================== --- test/MC/ARM/d16.s +++ test/MC/ARM/d16.s @@ -3,22 +3,24 @@ @ D32-NOT: error: -@ D16: invalid operand for instruction +@ D16: error: invalid instruction, any one of the following would fix this: @ D16-NEXT: vadd.f64 d1, d2, d16 +@ D16: note: operand must be a register in range [d0, d15] +@ D16: note: too many operands for instruction vadd.f64 d1, d2, d16 -@ D16: invalid operand for instruction +@ D16: error: operand must be a register in range [d0, d15] @ D16-NEXT: vadd.f64 d1, d17, d6 vadd.f64 d1, d17, d6 -@ D16: invalid operand for instruction +@ D16: error: operand must be a register in range [d0, d15] @ D16-NEXT: vadd.f64 d19, d7, d6 vadd.f64 d19, d7, d6 -@ D16: invalid operand for instruction +@ D16: error: operand must be a register in range [d0, d15] @ D16-NEXT: vcvt.f64.f32 d22, s4 vcvt.f64.f32 d22, s4 -@ D16: invalid operand for instruction +@ D16: error: operand must be a register in range [d0, d15] @ D16-NEXT: vcvt.f32.f64 s26, d30 vcvt.f32.f64 s26, d30 Index: test/MC/ARM/invalid-fp-armv8.s =================================================================== --- test/MC/ARM/invalid-fp-armv8.s +++ test/MC/ARM/invalid-fp-armv8.s @@ -57,22 +57,26 @@ vcvta.s32.f64 d3, s2 @ V8: error: invalid instruction vcvtp.s32.f32 d3, s2 -@ V8: error: invalid operand for instruction +@ V8: error: operand must be a register in range [s0, s31] vcvtn.u32.f64 d3, s2 @ V8: error: invalid instruction vcvtm.u32.f32 d3, s2 -@ V8: error: invalid operand for instruction +@ 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 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] @ V8: note: invalid operand for instruction vcvttvs.f16.f64 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] @ V8: note: invalid operand for instruction vcvtthi.f16.f64 q0, d3 -@ V8: error: invalid operand for instruction +@ V8: error: operand must be a register in range [s0, s31] vrintrlo.f32.f32 d3, q0 @ V8: error: invalid instruction Index: test/MC/ARM/invalid-neon-v8.s =================================================================== --- test/MC/ARM/invalid-neon-v8.s +++ test/MC/ARM/invalid-neon-v8.s @@ -10,7 +10,7 @@ vcvta.s32.f32 s1, s2 @ CHECK: error: instruction requires: FPARMv8 vcvtp.u32.f32 s1, d2 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [d0, d31] vcvtp.f32.u32 d1, q2 @ CHECK: error: invalid instruction vcvtplo.f32.u32 s1, s2 @@ -20,47 +20,47 @@ @ CHECK: error: invalid instruction vrintn.f32 d3, q12 @ CHECK: error: invalid instruction, any one of the following would fix this: -@ CHECK: note: invalid operand for instruction -@ CHECK: note: invalid operand for instruction +@ CHECK: note: operand must be a register in range [d0, d31] +@ CHECK: note: operand must be a register in range [q0, q15] vrintz.f32 d3, q12 @ CHECK: error: invalid instruction, any one of the following would fix this: -@ CHECK: note: invalid operand for instruction -@ CHECK: note: invalid operand for instruction +@ CHECK: note: operand must be a register in range [d0, d31] +@ CHECK: note: operand must be a register in range [q0, q15] vrintmge.f32.f32 d3, d4 @ CHECK: error: instruction 'vrintm' is not predicable, but condition code specified aesd.8 q0, s1 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] aese.8 s0, q1 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] aesimc.8 s0, q1 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] aesmc.8 q0, d1 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] aesdge.8 q0, q1 @ CHECK: error: instruction 'aesd' is not predicable, but condition code specified sha1h.32 d0, q1 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] sha1su1.32 q0, s1 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] sha256su0.32 s0, q1 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] sha1heq.32 q0, q1 @ CHECK: error: instruction 'sha1h' is not predicable, but condition code specified sha1c.32 s0, d1, q2 @ CHECK: error: invalid instruction sha1m.32 q0, s1, q2 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] sha1p.32 s0, q1, q2 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] sha1su0.32 d0, q1, q2 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] sha256h.32 q0, s1, q2 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] sha256h2.32 q0, q1, s2 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] sha256su1.32 s0, d1, q2 @ CHECK: error: invalid instruction sha256su1lt.32 q0, d1, q2 @@ -69,6 +69,6 @@ vmull.p64 q0, s1, s3 @ CHECK: error: invalid instruction vmull.p64 s1, d2, d3 -@ CHECK: error: invalid operand for instruction +@ CHECK: error: operand must be a register in range [q0, q15] vmullge.p64 q0, d16, d17 @ CHECK: error: instruction 'vmull' is not predicable, but condition code specified Index: test/MC/ARM/vmov-vmvn-illegal-cases.s =================================================================== --- test/MC/ARM/vmov-vmvn-illegal-cases.s +++ test/MC/ARM/vmov-vmvn-illegal-cases.s @@ -1,23 +1,39 @@ @ RUN: not llvm-mc -triple=armv7-linux-gnueabi %s 2>&1 | FileCheck %s .text -@ CHECK: error: invalid operand for instruction -@ CHECK: vmov.i32 d2, #0xffffffab -@ CHECK: error: invalid operand for instruction -@ CHECK: vmov.i32 q2, #0xffffffab -@ CHECK: error: invalid operand for instruction -@ CHECK: vmov.i16 q2, #0xffab -@ CHECK: error: invalid operand for instruction -@ CHECK: vmov.i16 q2, #0xffab +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK-NEXT: vmov.i32 d2, #0xffffffab +@ CHECK: note: operand must be a register in range [d0, d31] +@ CHECK: note: invalid operand for instruction +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK-NEXT: vmov.i32 q2, #0xffffffab +@ CHECK: note: operand must be a register in range [q0, q15] +@ CHECK: note: invalid operand for instruction +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK-NEXT: vmov.i16 q2, #0xffab +@ CHECK: note: operand must be a register in range [q0, q15] +@ CHECK: note: invalid operand for instruction +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK-NEXT: vmov.i16 q2, #0xffab +@ CHECK: note: operand must be a register in range [q0, q15] +@ CHECK: note: invalid operand for instruction -@ CHECK: error: invalid operand for instruction -@ CHECK: vmvn.i32 d2, #0xffffffab -@ CHECK: error: invalid operand for instruction -@ CHECK: vmvn.i32 q2, #0xffffffab -@ CHECK: error: invalid operand for instruction -@ CHECK: vmvn.i16 q2, #0xffab -@ CHECK: error: invalid operand for instruction -@ CHECK: vmvn.i16 q2, #0xffab +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK-NEXT: vmvn.i32 d2, #0xffffffab +@ CHECK: note: operand must be a register in range [d0, d31] +@ CHECK: note: invalid operand for instruction +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK-NEXT: vmvn.i32 q2, #0xffffffab +@ CHECK: note: operand must be a register in range [q0, q15] +@ CHECK: note: invalid operand for instruction +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK-NEXT: vmvn.i16 q2, #0xffab +@ CHECK: note: operand must be a register in range [q0, q15] +@ CHECK: note: invalid operand for instruction +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK-NEXT: vmvn.i16 q2, #0xffab +@ CHECK: note: operand must be a register in range [q0, q15] +@ CHECK: note: invalid operand for instruction vmov.i32 d2, #0xffffffab vmov.i32 q2, #0xffffffab Index: test/MC/ARM/vorr-vbic-illegal-cases.s =================================================================== --- test/MC/ARM/vorr-vbic-illegal-cases.s +++ test/MC/ARM/vorr-vbic-illegal-cases.s @@ -8,17 +8,29 @@ vorr.i16 q2, #0xabab vorr.i16 q2, #0xabab -@ CHECK: error: invalid operand for instruction +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK: operand must be a register in range [d0, d31] +@ CHECK: note: invalid operand for instruction @ CHECK: vorr.i32 d2, #0xffffffff -@ CHECK: error: invalid operand for instruction +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK: note: operand must be a register in range [q0, q15] +@ CHECK: note: invalid operand for instruction @ CHECK: vorr.i32 q2, #0xffffffff -@ CHECK: error: invalid operand for instruction +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK: operand must be a register in range [d0, d31] +@ CHECK: note: invalid operand for instruction @ CHECK: vorr.i32 d2, #0xabababab -@ CHECK: error: invalid operand for instruction +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK: note: operand must be a register in range [q0, q15] +@ CHECK: note: invalid operand for instruction @ CHECK: vorr.i32 q2, #0xabababab -@ CHECK: error: invalid operand for instruction +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK: note: operand must be a register in range [q0, q15] +@ CHECK: note: invalid operand for instruction @ CHECK: vorr.i16 q2, #0xabab -@ CHECK: error: invalid operand for instruction +@ CHECK: error: invalid instruction, any one of the following would fix this: +@ CHECK: note: operand must be a register in range [q0, q15] +@ CHECK: note: invalid operand for instruction @ CHECK: vorr.i16 q2, #0xabab vbic.i32 d2, #0xffffffff