summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td10
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp3
-rw-r--r--test/MC/ARM/vldm-vstm-diags.s44
3 files changed, 55 insertions, 2 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 37a8594e544..4e13af59630 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -526,7 +526,10 @@ def reglist : Operand<i32> {
def GPRPairOp : RegisterOperand<GPRPair, "printGPRPairOperand">;
-def DPRRegListAsmOperand : AsmOperandClass { let Name = "DPRRegList"; }
+def DPRRegListAsmOperand : AsmOperandClass {
+ let Name = "DPRRegList";
+ let DiagnosticType = "DPR_RegList";
+}
def dpr_reglist : Operand<i32> {
let EncoderMethod = "getRegisterListOpValue";
let ParserMatchClass = DPRRegListAsmOperand;
@@ -534,7 +537,10 @@ def dpr_reglist : Operand<i32> {
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<i32> {
let EncoderMethod = "getRegisterListOpValue";
let ParserMatchClass = SPRRegListAsmOperand;
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index caa46bcb98d..1d59cd1a745 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/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/test/MC/ARM/vldm-vstm-diags.s b/test/MC/ARM/vldm-vstm-diags.s
new file mode 100644
index 00000000000..854d5c55f2a
--- /dev/null
+++ b/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}