Author: dylanmckay Date: Sat Oct 14 15:31:06 2017 New Revision: 315836 URL: http://llvm.org/viewvc/llvm-project?rev=315836&view=rev Log: Merging r314898: ------------------------------------------------------------------------ r314898 | dylanmckay | 2017-10-04 23:37:22 +1300 (Wed, 04 Oct 2017) | 6 lines
[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. ------------------------------------------------------------------------ Modified: llvm/branches/release_50/lib/Target/AVR/AVRExpandPseudoInsts.cpp Modified: llvm/branches/release_50/lib/Target/AVR/AVRExpandPseudoInsts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/lib/Target/AVR/AVRExpandPseudoInsts.cpp?rev=315836&r1=315835&r2=315836&view=diff ============================================================================== --- llvm/branches/release_50/lib/Target/AVR/AVRExpandPseudoInsts.cpp (original) +++ llvm/branches/release_50/lib/Target/AVR/AVRExpandPseudoInsts.cpp Sat Oct 14 15:31:06 2017 @@ -743,7 +743,50 @@ bool AVRExpandPseudo::expand<AVR::LDDWRd 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 <> _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits