@@ -742,7 +742,50 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
742
742
743
743
template <>
744
744
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 ;
746
789
}
747
790
748
791
template <>
0 commit comments