Skip to content

Commit 06d0f6b

Browse files
gergoerdidylanmckay
authored andcommitted
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314898 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent f6d00a7 commit 06d0f6b

File tree

1 file changed

+44
-1
lines changed

1 file changed

+44
-1
lines changed

lib/Target/AVR/AVRExpandPseudoInsts.cpp

+44-1
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,50 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
743743

744744
template <>
745745
bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &MBB, BlockIt MBBI) {
746-
llvm_unreachable("wide LPM is unimplemented");
746+
MachineInstr &MI = *MBBI;
747+
unsigned OpLo, OpHi, DstLoReg, DstHiReg;
748+
unsigned DstReg = MI.getOperand(0).getReg();
749+
unsigned TmpReg = 0; // 0 for no temporary register
750+
unsigned SrcReg = MI.getOperand(1).getReg();
751+
bool SrcIsKill = MI.getOperand(1).isKill();
752+
OpLo = AVR::LPMRdZPi;
753+
OpHi = AVR::LPMRdZ;
754+
TRI->splitReg(DstReg, DstLoReg, DstHiReg);
755+
756+
// Use a temporary register if src and dst registers are the same.
757+
if (DstReg == SrcReg)
758+
TmpReg = scavengeGPR8(MI);
759+
760+
unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
761+
unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
762+
763+
// Load low byte.
764+
auto MIBLO = buildMI(MBB, MBBI, OpLo)
765+
.addReg(CurDstLoReg, RegState::Define)
766+
.addReg(SrcReg);
767+
768+
// Push low byte onto stack if necessary.
769+
if (TmpReg)
770+
buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
771+
772+
// Load high byte.
773+
auto MIBHI = buildMI(MBB, MBBI, OpHi)
774+
.addReg(CurDstHiReg, RegState::Define)
775+
.addReg(SrcReg, getKillRegState(SrcIsKill));
776+
777+
if (TmpReg) {
778+
// Move the high byte into the final destination.
779+
buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
780+
781+
// Move the low byte from the scratch space into the final destination.
782+
buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
783+
}
784+
785+
MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
786+
MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
787+
788+
MI.eraseFromParent();
789+
return true;
747790
}
748791

749792
template <>

0 commit comments

Comments
 (0)