mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-17 03:07:06 +00:00
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:
parent
cb86def1c2
commit
9d4ebc0eb8
@ -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:
|
||||
|
@ -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>
|
||||
|
@ -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 {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user