summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp33
-rw-r--r--test/MC/ARM/vfp-aliases-diagnostics.s17
-rw-r--r--test/MC/ARM/vfp-aliases.s9
3 files changed, 52 insertions, 7 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 6e0038c9b0..33274bfd0f 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -5107,18 +5107,37 @@ static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
}
static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features,
unsigned VariantID);
+
+static bool RequiresVFPRegListValidation(StringRef Inst,
+ bool &AcceptSinglePrecisionOnly,
+ bool &AcceptDoublePrecisionOnly) {
+ if (Inst.size() < 7)
+ return false;
+
+ if (Inst.startswith("fldm") || Inst.startswith("fstm")) {
+ StringRef AddressingMode = Inst.substr(4, 2);
+ if (AddressingMode == "ia" || AddressingMode == "db" ||
+ AddressingMode == "ea" || AddressingMode == "fd") {
+ AcceptSinglePrecisionOnly = Inst[6] == 's';
+ AcceptDoublePrecisionOnly = Inst[6] == 'd' || Inst[6] == 'x';
+ return true;
+ }
+ }
+
+ return false;
+}
+
/// Parse an arm instruction mnemonic followed by its operands.
bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
// FIXME: Can this be done via tablegen in some fashion?
- bool RequireVFPRegisterList;
- bool AcceptDoublePrecisionOnly;
+ bool RequireVFPRegisterListCheck;
bool AcceptSinglePrecisionOnly;
- RequireVFPRegisterList = Name.startswith("fldm") || Name.startswith("fstm");
- AcceptDoublePrecisionOnly =
- RequireVFPRegisterList && (Name.back() == 'd' || Name.back() == 'x');
- AcceptSinglePrecisionOnly = RequireVFPRegisterList && Name.back() == 's';
+ bool AcceptDoublePrecisionOnly;
+ RequireVFPRegisterListCheck =
+ RequiresVFPRegListValidation(Name, AcceptSinglePrecisionOnly,
+ AcceptDoublePrecisionOnly);
// Apply mnemonic aliases before doing anything else, as the destination
// mnemonic may include suffices and we want to handle them normally.
@@ -5288,7 +5307,7 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
Parser.Lex(); // Consume the EndOfStatement
- if (RequireVFPRegisterList) {
+ if (RequireVFPRegisterListCheck) {
ARMOperand *Op = static_cast<ARMOperand*>(Operands.back());
if (AcceptSinglePrecisionOnly && !Op->isSPRRegList())
return Error(Op->getStartLoc(),
diff --git a/test/MC/ARM/vfp-aliases-diagnostics.s b/test/MC/ARM/vfp-aliases-diagnostics.s
index 911c23b235..d1ab18e998 100644
--- a/test/MC/ARM/vfp-aliases-diagnostics.s
+++ b/test/MC/ARM/vfp-aliases-diagnostics.s
@@ -95,3 +95,20 @@ aliases:
@ CHECK: fldmeax sp!, {s0}
@ CHECK: ^
+ fstmiaxcs r0, {s0}
+ fstmiaxhs r0, {s0}
+ fstmiaxls r0, {s0}
+ fstmiaxvs r0, {s0}
+@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK: fstmiaxcs r0, {s0}
+@ CHECK: ^
+@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK: fstmiaxhs r0, {s0}
+@ CHECK: ^
+@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK: fstmiaxls r0, {s0}
+@ CHECK: ^
+@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK: fstmiaxvs r0, {s0}
+@ CHECK: ^
+
diff --git a/test/MC/ARM/vfp-aliases.s b/test/MC/ARM/vfp-aliases.s
index 1ed6e53b80..4074feabbf 100644
--- a/test/MC/ARM/vfp-aliases.s
+++ b/test/MC/ARM/vfp-aliases.s
@@ -51,3 +51,12 @@ aliases:
@ CHECK: fstmdbx sp!, {d0}
@ CHECK: fldmdbx sp!, {d0}
+ fstmiaxcs r0, {d0}
+ fstmiaxhs r0, {d0}
+ fstmiaxls r0, {d0}
+ fstmiaxvs r0, {d0}
+@ CHECK: fstmiaxhs r0, {d0}
+@ CHECK: fstmiaxhs r0, {d0}
+@ CHECK: fstmiaxls r0, {d0}
+@ CHECK: fstmiaxvs r0, {d0}
+