Change VLDMQ and VSTMQ to be pseudo instructions. They are expanded after

register allocation to VLDMD and VSTMD respectively.  This avoids using the
dregpair operand modifier.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114047 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bob Wilson 2010-09-16 00:31:02 +00:00
parent cb86def1c2
commit 9d4ebc0eb8
3 changed files with 69 additions and 14 deletions

View File

@ -640,6 +640,56 @@ bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
MI.eraseFromParent();
}
case ARM::VLDMQ: {
MachineInstrBuilder MIB =
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::VLDMD));
unsigned OpIdx = 0;
// Grab the Q register destination.
bool DstIsDead = MI.getOperand(OpIdx).isDead();
unsigned DstReg = MI.getOperand(OpIdx++).getReg();
// Copy the addrmode4 operands.
MIB.addOperand(MI.getOperand(OpIdx++));
MIB.addOperand(MI.getOperand(OpIdx++));
// Copy the predicate operands.
MIB.addOperand(MI.getOperand(OpIdx++));
MIB.addOperand(MI.getOperand(OpIdx++));
// Add the destination operands (D subregs).
unsigned D0 = TRI->getSubReg(DstReg, ARM::dsub_0);
unsigned D1 = TRI->getSubReg(DstReg, ARM::dsub_1);
MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead))
.addReg(D1, RegState::Define | getDeadRegState(DstIsDead));
// Add an implicit def for the super-register.
MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead));
TransferImpOps(MI, MIB, MIB);
MI.eraseFromParent();
break;
}
case ARM::VSTMQ: {
MachineInstrBuilder MIB =
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::VSTMD));
unsigned OpIdx = 0;
// Grab the Q register source.
bool SrcIsKill = MI.getOperand(OpIdx).isKill();
unsigned SrcReg = MI.getOperand(OpIdx++).getReg();
// Copy the addrmode4 operands.
MIB.addOperand(MI.getOperand(OpIdx++));
MIB.addOperand(MI.getOperand(OpIdx++));
// Copy the predicate operands.
MIB.addOperand(MI.getOperand(OpIdx++));
MIB.addOperand(MI.getOperand(OpIdx++));
// Add the source operands (D subregs).
unsigned D0 = TRI->getSubReg(SrcReg, ARM::dsub_0);
unsigned D1 = TRI->getSubReg(SrcReg, ARM::dsub_1);
MIB.addReg(D0).addReg(D1);
if (SrcIsKill)
// Add an implicit kill for the Q register.
(*MIB).addRegisterKilled(SrcReg, TRI, true);
TransferImpOps(MI, MIB, MIB);
MI.eraseFromParent();
break;
}
case ARM::VLD1q8Pseudo:
case ARM::VLD1q16Pseudo:
case ARM::VLD1q32Pseudo:

View File

@ -1331,6 +1331,17 @@ class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
let Inst{11-8} = 0b1010;
}
// VFP Load / store multiple pseudo instructions.
class PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr,
list<dag> pattern>
: InstARM<AddrMode4, Size4Bytes, IndexModeNone, Pseudo, VFPNeonDomain,
cstr, itin> {
let OutOperandList = oops;
let InOperandList = !con(iops, (ins pred:$p));
let Pattern = pattern;
list<Predicate> Predicates = [HasVFP2];
}
// Load / store multiple
class AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
string asm, string cstr, list<dag> pattern>

View File

@ -129,23 +129,17 @@ def nModImm : Operand<i32> {
// NEON load / store instructions
//===----------------------------------------------------------------------===//
// Use vldmia to load a Q register as a D register pair.
// This is equivalent to VLDMD except that it has a Q register operand
// instead of a pair of D registers.
// Use VLDM to load a Q register as a D register pair.
// This is a pseudo instruction that is expanded to VLDMD after reg alloc.
def VLDMQ
: AXDI4<(outs QPR:$dst), (ins addrmode4:$addr, pred:$p),
IndexModeNone, IIC_fpLoadm,
"vldm${addr:submode}${p}\t$addr, ${dst:dregpair}", "",
[(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]>;
: PseudoVFPLdStM<(outs QPR:$dst), (ins addrmode4:$addr), IIC_fpLoadm, "",
[(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]>;
// Use vstmia to store a Q register as a D register pair.
// This is equivalent to VSTMD except that it has a Q register operand
// instead of a pair of D registers.
// Use VSTM to store a Q register as a D register pair.
// This is a pseudo instruction that is expanded to VSTMD after reg alloc.
def VSTMQ
: AXDI4<(outs), (ins QPR:$src, addrmode4:$addr, pred:$p),
IndexModeNone, IIC_fpStorem,
"vstm${addr:submode}${p}\t$addr, ${src:dregpair}", "",
[(store (v2f64 QPR:$src), addrmode4:$addr)]>;
: PseudoVFPLdStM<(outs), (ins QPR:$src, addrmode4:$addr), IIC_fpStorem, "",
[(store (v2f64 QPR:$src), addrmode4:$addr)]>;
let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {