mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-28 06:29:45 +00:00
Promote VMOVS to VMOVD when possible.
On Cortex-A8, we use the NEON v2f32 instructions for f32 arithmetic. For better latency, we also send D-register copies down the NEON pipeline by translating them to vorr instructions. This patch promotes even S-register copies to D-register copies when possible so they can also go down the NEON pipeline. Example: vldr.32 s0, LCPI0_0 loop: vorr d1, d0, d0 loop2: ... vadd.f32 d1, d1, d16 The vorr instruction looked like this after regalloc: %S2<def> = COPY %S0, %D1<imp-def> Copies involving odd S-registers, and copies that don't define the full D-register are left alone. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137182 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
de317f40f7
commit
c70c2cafe1
@ -629,9 +629,36 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
bool SPRSrc = ARM::SPRRegClass.contains(SrcReg);
|
||||
|
||||
unsigned Opc;
|
||||
if (SPRDest && SPRSrc)
|
||||
if (SPRDest && SPRSrc) {
|
||||
Opc = ARM::VMOVS;
|
||||
else if (GPRDest && SPRSrc)
|
||||
|
||||
// An even S-S copy may be feeding a NEON v2f32 instruction being used for
|
||||
// f32 operations. In that case, it is better to copy the full D-regs with
|
||||
// a VMOVD since that can be converted to a NEON-domain move by
|
||||
// NEONMoveFix.cpp. Check that MI is the original COPY instruction, and
|
||||
// that it really defines the whole D-register.
|
||||
if ((DestReg - ARM::S0) % 2 == 0 && (SrcReg - ARM::S0) % 2 == 0 &&
|
||||
I != MBB.end() && I->isCopy() &&
|
||||
I->getOperand(0).getReg() == DestReg &&
|
||||
I->getOperand(1).getReg() == SrcReg) {
|
||||
// I is pointing to the ortiginal COPY instruction.
|
||||
// Find the parent D-registers.
|
||||
const TargetRegisterInfo *TRI = &getRegisterInfo();
|
||||
unsigned SrcD = TRI->getMatchingSuperReg(SrcReg, ARM::ssub_0,
|
||||
&ARM::DPRRegClass);
|
||||
unsigned DestD = TRI->getMatchingSuperReg(DestReg, ARM::ssub_0,
|
||||
&ARM::DPRRegClass);
|
||||
// Be careful to not clobber an INSERT_SUBREG that reads and redefines a
|
||||
// D-register. There must be an <imp-def> of destD, and no <imp-use>.
|
||||
if (I->definesRegister(DestD, TRI) && !I->readsRegister(DestD, TRI)) {
|
||||
Opc = ARM::VMOVD;
|
||||
SrcReg = SrcD;
|
||||
DestReg = DestD;
|
||||
if (KillSrc)
|
||||
KillSrc = I->killsRegister(SrcReg, TRI);
|
||||
}
|
||||
}
|
||||
} else if (GPRDest && SPRSrc)
|
||||
Opc = ARM::VMOVRS;
|
||||
else if (SPRDest && GPRSrc)
|
||||
Opc = ARM::VMOVSR;
|
||||
|
Loading…
Reference in New Issue
Block a user