Skip to content

Commit 383e429

Browse files
committed
[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
1 parent 66e570c commit 383e429

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
@@ -742,7 +742,50 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
742742

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

748791
template <>

0 commit comments

Comments
 (0)