diff options
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 33 | ||||
-rw-r--r-- | test/MC/ARM/vfp-aliases-diagnostics.s | 17 | ||||
-rw-r--r-- | test/MC/ARM/vfp-aliases.s | 9 |
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} + |