mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-11 00:39:36 +00:00
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
This commit is contained in:
parent
a4f62f85a2
commit
dd2836776f
@ -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.
|
||||
//
|
||||
|
@ -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
|
||||
|
97
test/MC/ARM/vfp-aliases-diagnostics.s
Normal file
97
test/MC/ARM/vfp-aliases-diagnostics.s
Normal file
@ -0,0 +1,97 @@
|
||||
@ RUN: not llvm-mc -triple armv7-eabi -filetype asm -o /dev/null %s 2>&1 \
|
||||
@ RUN: | FileCheck %s
|
||||
|
||||
.syntax unified
|
||||
.fpu vfp
|
||||
|
||||
.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}
|
||||
|
||||
fstmfdx 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: fstmeax sp!, {s0}
|
||||
@ CHECK: ^
|
||||
@ CHECK: error: VFP/Neon double precision register expected
|
||||
@ CHECK: fldmfdx sp!, {s0}
|
||||
@ CHECK: ^
|
||||
|
||||
@ CHECK: error: VFP/Neon double precision register expected
|
||||
@ CHECK: fstmfdx sp!, {s0}
|
||||
@ CHECK: ^
|
||||
@ CHECK: error: VFP/Neon double precision register expected
|
||||
@ CHECK: fldmeax sp!, {s0}
|
||||
@ CHECK: ^
|
||||
|
53
test/MC/ARM/vfp-aliases.s
Normal file
53
test/MC/ARM/vfp-aliases.s
Normal file
@ -0,0 +1,53 @@
|
||||
@ RUN: llvm-mc -triple armv7-eabi -filetype asm -o - %s | FileCheck %s
|
||||
|
||||
.syntax unified
|
||||
.fpu vfp
|
||||
|
||||
.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}
|
||||
|
||||
fstmfdx 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}
|
||||
@ CHECK: fldmdbx sp!, {d0}
|
||||
|
Loading…
x
Reference in New Issue
Block a user