[llvm] r314898 - [AVR] Implement LPMWRdZ pseudo-instruction's expansion.

Dylan McKay via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 4 03:37:22 PDT 2017


Author: dylanmckay
Date: Wed Oct  4 03:37:22 2017
New Revision: 314898

URL: http://llvm.org/viewvc/llvm-project?rev=314898&view=rev
Log:
[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/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp

Modified: llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp?rev=314898&r1=314897&r2=314898&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp (original)
+++ llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp Wed Oct  4 03:37:22 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 <>




More information about the llvm-commits mailing list