Index: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td @@ -526,7 +526,10 @@ def GPRPairOp : RegisterOperand; -def DPRRegListAsmOperand : AsmOperandClass { let Name = "DPRRegList"; } +def DPRRegListAsmOperand : AsmOperandClass { + let Name = "DPRRegList"; + let DiagnosticType = "DPR_RegList"; +} def dpr_reglist : Operand { let EncoderMethod = "getRegisterListOpValue"; let ParserMatchClass = DPRRegListAsmOperand; @@ -534,7 +537,10 @@ let DecoderMethod = "DecodeDPRRegListOperand"; } -def SPRRegListAsmOperand : AsmOperandClass { let Name = "SPRRegList"; } +def SPRRegListAsmOperand : AsmOperandClass { + let Name = "SPRRegList"; + let DiagnosticString = "operand must be a list of registers in range [s0, s31]"; +} def spr_reglist : Operand { let EncoderMethod = "getRegisterListOpValue"; let ParserMatchClass = SPRRegListAsmOperand; 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 @@ -10137,6 +10137,9 @@ case Match_DPR: return hasD16() ? "operand must be a register in range [d0, d15]" : "operand must be a register in range [d0, d31]"; + case Match_DPR_RegList: + return hasD16() ? "operand must be a list of registers in range [d0, d15]" + : "operand must be a list of registers in range [d0, d31]"; // For all other diags, use the static string from tablegen. default: Index: llvm/trunk/test/MC/ARM/vldm-vstm-diags.s =================================================================== --- llvm/trunk/test/MC/ARM/vldm-vstm-diags.s +++ llvm/trunk/test/MC/ARM/vldm-vstm-diags.s @@ -0,0 +1,44 @@ +@ RUN: not llvm-mc -triple armv7-eabi -filetype asm -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-D32 +@ RUN: not llvm-mc -triple armv7-eabi -filetype asm -o /dev/null -mattr=+d16 %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-D16 + + // First operand must be a GPR + vldm s0, {s1, s2} +// CHECK: error: operand must be a register in range [r0, r15] +// CHECK-NEXT: vldm s0, {s1, s2} + + vstm s0, {s1, s2} +// CHECK: error: operand must be a register in range [r0, r15] +// CHECK-NEXT: vstm s0, {s1, s2} + + + // Second operand must be a list of SPRs or DPRs + vldm r0, {r1, r2} +// CHECK: error: invalid instruction, any one of the following would fix this: +// CHECK-NEXT: vldm r0, {r1, r2} +// CHECK: note: operand must be a list of registers in range [s0, s31] +// CHECK-D32: note: operand must be a list of registers in range [d0, d31] +// CHECK-D16: note: operand must be a list of registers in range [d0, d15] + vldm r0, #42 +// CHECK: error: invalid instruction, any one of the following would fix this: +// CHECK-NEXT: vldm r0, #42 +// CHECK: note: operand must be a list of registers in range [s0, s31] +// CHECK-D32: note: operand must be a list of registers in range [d0, d31] +// CHECK-D16: note: operand must be a list of registers in range [d0, d15] + vldm r0, {s1, d2} +// CHECK: error: invalid register in register list +// CHECK-NEXT: vldm r0, {s1, d2} + vstm r0, {r1, r2} +// CHECK: error: invalid instruction, any one of the following would fix this: +// CHECK-NEXT: vstm r0, {r1, r2} +// CHECK: note: operand must be a list of registers in range [s0, s31] +// CHECK-D32: note: operand must be a list of registers in range [d0, d31] +// CHECK-D16: note: operand must be a list of registers in range [d0, d15] + vstm r0, #42 +// CHECK: error: invalid instruction, any one of the following would fix this: +// CHECK-NEXT: vstm r0, #42 +// CHECK: note: operand must be a list of registers in range [s0, s31] +// CHECK-D32: note: operand must be a list of registers in range [d0, d31] +// CHECK-D16: note: operand must be a list of registers in range [d0, d15] + vstm r0, {s1, d2} +// CHECK: error: invalid register in register list +// CHECK-NEXT: vstm r0, {s1, d2}