From d6ca9879bab19410cbfc8c41d4c4b7a8f3668699 Mon Sep 17 00:00:00 2001 From: Oliver Stannard Date: Tue, 21 Nov 2017 15:06:01 +0000 Subject: [PATCH] [ARM] Add diagnostics for SPR/DPR lists Differential revision: https://reviews.llvm.org/D39195 llvm-svn: 318766 --- llvm/lib/Target/ARM/ARMInstrInfo.td | 10 ++++-- llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 3 ++ llvm/test/MC/ARM/vldm-vstm-diags.s | 44 ++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 llvm/test/MC/ARM/vldm-vstm-diags.s diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 37a8594..4e13af5 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -526,7 +526,10 @@ def reglist : Operand { 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 @@ def dpr_reglist : Operand { 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; diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index caa46bc..1d59cd1 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -10137,6 +10137,9 @@ ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) { 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: diff --git a/llvm/test/MC/ARM/vldm-vstm-diags.s b/llvm/test/MC/ARM/vldm-vstm-diags.s new file mode 100644 index 0000000..854d5c5 --- /dev/null +++ b/llvm/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} -- 2.7.4