let mayStore = 1;
}
-
-// FLDM/FSTM - Load / Store multiple single / double precision registers for
-// pre-ARMv6 cores.
-// These instructions are deprecated!
-def : VFP2MnemonicAlias<"fldmias", "vldmia">;
-def : VFP2MnemonicAlias<"fldmdbs", "vldmdb">;
-def : VFP2MnemonicAlias<"fldmeas", "vldmdb">;
-def : VFP2MnemonicAlias<"fldmfds", "vldmia">;
-def : VFP2MnemonicAlias<"fldmiad", "vldmia">;
-def : VFP2MnemonicAlias<"fldmdbd", "vldmdb">;
-def : VFP2MnemonicAlias<"fldmead", "vldmdb">;
-def : VFP2MnemonicAlias<"fldmfdd", "vldmia">;
-
-def : VFP2MnemonicAlias<"fstmias", "vstmia">;
-def : VFP2MnemonicAlias<"fstmdbs", "vstmdb">;
-def : VFP2MnemonicAlias<"fstmeas", "vstmia">;
-def : VFP2MnemonicAlias<"fstmfds", "vstmdb">;
-def : VFP2MnemonicAlias<"fstmiad", "vstmia">;
-def : VFP2MnemonicAlias<"fstmdbd", "vstmdb">;
-def : VFP2MnemonicAlias<"fstmead", "vstmia">;
-def : VFP2MnemonicAlias<"fstmfdd", "vstmdb">;
-
def : InstAlias<"vpush${p} $r", (VSTMDDB_UPD SP, pred:$p, dpr_reglist:$r), 0>,
Requires<[HasVFP2]>;
def : InstAlias<"vpush${p} $r", (VSTMSDB_UPD SP, pred:$p, spr_reglist:$r), 0>,
// FLDMX, FSTMX - Load and store multiple unknown precision registers for
// pre-armv6 cores.
// These instruction are deprecated so we don't want them to get selected.
+// However, there is no UAL syntax for them, so we keep them around for
+// (dis)assembly only.
multiclass vfp_ldstx_mult<string asm, bit L_bit> {
// Unknown precision
def XIA :
static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t 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;
-}
-
// The GNU assembler has aliases of ldrd and strd with the second register
// omitted. We don't have a way to do that in tablegen, so fix it up here.
//
bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc, OperandVector &Operands) {
MCAsmParser &Parser = getParser();
- // FIXME: Can this be done via tablegen in some fashion?
- bool RequireVFPRegisterListCheck;
- bool AcceptSinglePrecisionOnly;
- 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.
if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
return true;
- if (RequireVFPRegisterListCheck) {
- ARMOperand &Op = static_cast<ARMOperand &>(*Operands.back());
- if (AcceptSinglePrecisionOnly && !Op.isSPRRegList())
- return Error(Op.getStartLoc(),
- "VFP/Neon single precision register expected");
- if (AcceptDoublePrecisionOnly && !Op.isDPRRegList())
- return Error(Op.getStartLoc(),
- "VFP/Neon double precision register expected");
- }
-
tryConvertingToTwoOperandForm(Mnemonic, CarrySetting, Operands);
// Some instructions, mostly Thumb, have forms for the same mnemonic that
mov r6, r5
vldr d21, [r7, #296]
add r9, r7, #216
-
-fstmfdd sp!, {d8, d9, d10, d11, d12, d13, d14, d15}
.type aliases,%function
aliases:
- fstmfdd sp!, {s0}
- fstmead sp!, {s0}
- fstmdbd sp!, {s0}
- fstmiad sp!, {s0}
- fstmfds sp!, {d0}
- fstmeas sp!, {d0}
- fstmdbs sp!, {d0}
- fstmias sp!, {d0}
-
- fldmias sp!, {d0}
- fldmdbs sp!, {d0}
- fldmeas sp!, {d0}
- fldmfds sp!, {d0}
- fldmiad sp!, {s0}
- fldmdbd sp!, {s0}
- fldmead sp!, {s0}
- fldmfdd sp!, {s0}
-
fstmeax sp!, {s0}
fldmfdx sp!, {s0}
fldmeax sp!, {s0}
@ CHECK-LABEL: aliases
-@ CHECK: error: VFP/Neon double precision register expected
-@ CHECK: fstmfdd sp!, {s0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
-@ CHECK: fstmead sp!, {s0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
-@ CHECK: fstmdbd sp!, {s0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
-@ CHECK: fstmiad sp!, {s0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon single precision register expected
-@ CHECK: fstmfds sp!, {d0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon single precision register expected
-@ CHECK: fstmeas sp!, {d0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon single precision register expected
-@ CHECK: fstmdbs sp!, {d0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon single precision register expected
-@ CHECK: fstmias sp!, {d0}
-@ CHECK: ^
-
-@ CHECK: error: VFP/Neon single precision register expected
-@ CHECK: fldmias sp!, {d0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon single precision register expected
-@ CHECK: fldmdbs sp!, {d0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon single precision register expected
-@ CHECK: fldmeas sp!, {d0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon single precision register expected
-@ CHECK: fldmfds sp!, {d0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
-@ CHECK: fldmiad sp!, {s0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
-@ CHECK: fldmdbd sp!, {s0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
-@ CHECK: fldmead sp!, {s0}
-@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
-@ CHECK: fldmfdd sp!, {s0}
-@ CHECK: ^
-
-@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK: error: operand must be a list of registers in range [d0, d31]
@ CHECK: fstmeax sp!, {s0}
@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK: error: operand must be a list of registers in range [d0, d31]
@ CHECK: fldmfdx sp!, {s0}
@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK: error: operand must be a list of registers in range [d0, d31]
@ CHECK: fstmfdx sp!, {s0}
@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK: error: operand must be a list of registers in range [d0, d31]
@ CHECK: fldmeax sp!, {s0}
@ CHECK: ^
fstmiaxhs r0, {s0}
fstmiaxls r0, {s0}
fstmiaxvs r0, {s0}
-@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK: error: operand must be a list of registers in range [d0, d31]
@ CHECK: fstmiaxcs r0, {s0}
@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK: error: operand must be a list of registers in range [d0, d31]
@ CHECK: fstmiaxhs r0, {s0}
@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK: error: operand must be a list of registers in range [d0, d31]
@ CHECK: fstmiaxls r0, {s0}
@ CHECK: ^
-@ CHECK: error: VFP/Neon double precision register expected
+@ CHECK: error: operand must be a list of registers in range [d0, d31]
@ CHECK: fstmiaxvs r0, {s0}
@ CHECK: ^
.type aliases,%function
aliases:
- fstmfdd sp!, {d0}
- fstmead sp!, {d0}
- fstmdbd sp!, {d0}
- fstmiad sp!, {d0}
- fstmfds sp!, {s0}
- fstmeas sp!, {s0}
- fstmdbs sp!, {s0}
- fstmias sp!, {s0}
-
- fldmias sp!, {s0}
- fldmdbs sp!, {s0}
- fldmeas sp!, {s0}
- fldmfds sp!, {s0}
- fldmiad sp!, {d0}
- fldmdbd sp!, {d0}
- fldmead sp!, {d0}
- fldmfdd sp!, {d0}
-
fstmeax sp!, {d0}
fldmfdx sp!, {d0}
fldmeax sp!, {d0}
@ CHECK-LABEL: aliases
-@ CHECK: vpush {d0}
-@ CHECK: vstmia sp!, {d0}
-@ CHECK: vpush {d0}
-@ CHECK: vstmia sp!, {d0}
-@ CHECK: vpush {s0}
-@ CHECK: vstmia sp!, {s0}
-@ CHECK: vpush {s0}
-@ CHECK: vstmia sp!, {s0}
-@ CHECK: vpop {s0}
-@ CHECK: vldmdb sp!, {s0}
-@ CHECK: vldmdb sp!, {s0}
-@ CHECK: vpop {s0}
-@ CHECK: vpop {d0}
-@ CHECK: vldmdb sp!, {d0}
-@ CHECK: vldmdb sp!, {d0}
-@ CHECK: vpop {d0}
@ CHECK: fstmiax sp!, {d0}
@ CHECK: fldmiax sp!, {d0}
@ CHECK: fstmdbx sp!, {d0}