mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-01 07:11:45 +00:00
[AVR] Implement LPMWRdZ pseudo-instruction's expansion.
FIXME: implementation is mostly copy-pasted from LDWRdPtr, so we should refactor a bit and unify the two Patch by Gerdo Erdi. llvm-svn: 314898
This commit is contained in:
parent
569e524df6
commit
680a47c4f6
@ -743,7 +743,50 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
|
||||
|
||||
template <>
|
||||
bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &MBB, BlockIt MBBI) {
|
||||
llvm_unreachable("wide LPM is unimplemented");
|
||||
MachineInstr &MI = *MBBI;
|
||||
unsigned OpLo, OpHi, DstLoReg, DstHiReg;
|
||||
unsigned DstReg = MI.getOperand(0).getReg();
|
||||
unsigned TmpReg = 0; // 0 for no temporary register
|
||||
unsigned SrcReg = MI.getOperand(1).getReg();
|
||||
bool SrcIsKill = MI.getOperand(1).isKill();
|
||||
OpLo = AVR::LPMRdZPi;
|
||||
OpHi = AVR::LPMRdZ;
|
||||
TRI->splitReg(DstReg, DstLoReg, DstHiReg);
|
||||
|
||||
// Use a temporary register if src and dst registers are the same.
|
||||
if (DstReg == SrcReg)
|
||||
TmpReg = scavengeGPR8(MI);
|
||||
|
||||
unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
|
||||
unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
|
||||
|
||||
// Load low byte.
|
||||
auto MIBLO = buildMI(MBB, MBBI, OpLo)
|
||||
.addReg(CurDstLoReg, RegState::Define)
|
||||
.addReg(SrcReg);
|
||||
|
||||
// Push low byte onto stack if necessary.
|
||||
if (TmpReg)
|
||||
buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
|
||||
|
||||
// Load high byte.
|
||||
auto MIBHI = buildMI(MBB, MBBI, OpHi)
|
||||
.addReg(CurDstHiReg, RegState::Define)
|
||||
.addReg(SrcReg, getKillRegState(SrcIsKill));
|
||||
|
||||
if (TmpReg) {
|
||||
// Move the high byte into the final destination.
|
||||
buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
|
||||
|
||||
// Move the low byte from the scratch space into the final destination.
|
||||
buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
|
||||
}
|
||||
|
||||
MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
|
||||
MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
|
||||
|
||||
MI.eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
|
Loading…
x
Reference in New Issue
Block a user