summaryrefslogtreecommitdiff
path: root/lib/Target/ARM
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2013-12-29 17:58:35 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2013-12-29 17:58:35 +0000
commitdd2836776f435d4b6de8d780228d02da15c37e7f (patch)
treeb590a63a75333b7fe300e24b1f61547ae10a0608 /lib/Target/ARM
parenta4f62f85a2b5613fc4c0c04114843f03361a85ad (diff)
downloadllvm-dd2836776f435d4b6de8d780228d02da15c37e7f.tar.gz
llvm-dd2836776f435d4b6de8d780228d02da15c37e7f.tar.bz2
llvm-dd2836776f435d4b6de8d780228d02da15c37e7f.tar.xz
ARM: provide VFP aliases for pre-V6 mnemonics
In order to provide compatibility with the GNU assembler, provide aliases for pre-UAL mnemonics for floating point operations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198172 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r--lib/Target/ARM/ARMInstrVFP.td29
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp29
2 files changed, 57 insertions, 1 deletions
diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td
index 0912b473cb..a5494819d1 100644
--- a/lib/Target/ARM/ARMInstrVFP.td
+++ b/lib/Target/ARM/ARMInstrVFP.td
@@ -207,6 +207,27 @@ defm VSTM : vfp_ldst_mult<"vstm", 0, IIC_fpStore_m, IIC_fpStore_mu>;
def : MnemonicAlias<"vldm", "vldmia">;
def : MnemonicAlias<"vstm", "vstmia">;
+// 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)>,
Requires<[HasVFP2]>;
def : InstAlias<"vpush${p} $r", (VSTMSDB_UPD SP, pred:$p, spr_reglist:$r)>,
@@ -247,7 +268,7 @@ multiclass vfp_ldstx_mult<string asm, bit L_bit> {
AXXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
IndexModeUpd, !strconcat(asm, "dbx${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
let Inst{24-23} = 0b10; // Decrement Before
- let Inst{21} = 1;
+ let Inst{21} = 1; // Writeback
let Inst{20} = L_bit;
}
}
@@ -255,6 +276,12 @@ multiclass vfp_ldstx_mult<string asm, bit L_bit> {
defm FLDM : vfp_ldstx_mult<"fldm", 1>;
defm FSTM : vfp_ldstx_mult<"fstm", 0>;
+def : VFP2MnemonicAlias<"fldmeax", "fldmdbx">;
+def : VFP2MnemonicAlias<"fldmfdx", "fldmiax">;
+
+def : VFP2MnemonicAlias<"fstmeax", "fstmiax">;
+def : VFP2MnemonicAlias<"fstmfdx", "fstmdbx">;
+
//===----------------------------------------------------------------------===//
// FP Binary Operations.
//
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index d4122bcb4a..c0e5472346 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -5111,6 +5111,15 @@ static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features,
bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ // FIXME: Can this be done via tablegen in some fashion?
+ bool HasPrecisionRestrictions;
+ bool AcceptDoublePrecisionOnly;
+ bool AcceptSinglePrecisionOnly;
+ HasPrecisionRestrictions = Name.startswith("fldm") || Name.startswith("fstm");
+ AcceptDoublePrecisionOnly =
+ HasPrecisionRestrictions && (Name.back() == 'd' || Name.back() == 'x');
+ AcceptSinglePrecisionOnly = HasPrecisionRestrictions && Name.back() == 's';
+
// Apply mnemonic aliases before doing anything else, as the destination
// mnemonic may include suffices and we want to handle them normally.
// The generic tblgen'erated code does this later, at the start of
@@ -5279,6 +5288,26 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
Parser.Lex(); // Consume the EndOfStatement
+ if (HasPrecisionRestrictions) {
+ ARMOperand *Op = static_cast<ARMOperand*>(Operands.back());
+ assert(Op->isRegList());
+ const SmallVectorImpl<unsigned> &RegList = Op->getRegList();
+ for (SmallVectorImpl<unsigned>::const_iterator RLI = RegList.begin(),
+ RLE = RegList.end();
+ RLI != RLE; ++RLI) {
+ if (AcceptSinglePrecisionOnly &&
+ !ARMMCRegisterClasses[ARM::SPRRegClassID].contains(*RLI))
+ return Error(Op->getStartLoc(),
+ "VFP/Neon single precision register expected");
+ else if (AcceptDoublePrecisionOnly &&
+ !ARMMCRegisterClasses[ARM::DPRRegClassID].contains(*RLI))
+ return Error(Op->getStartLoc(),
+ "VFP/Neon double precision register expected");
+ else
+ llvm_unreachable("must have single or double precision restrictions");
+ }
+ }
+
// Some instructions, mostly Thumb, have forms for the same mnemonic that
// do and don't have a cc_out optional-def operand. With some spot-checks
// of the operand list, we can figure out which variant we're trying to