@@ -583,9 +583,11 @@ bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {
583583 // Replace the pseudo instruction with the real one
584584 if (IsToCCR)
585585 MIB->setDesc (get (M68k::MOV16cd));
586- else
587- // FIXME M68010 or later is required
586+ else if (MIB-> getParent ()-> getParent ()-> getSubtarget <M68kSubtarget>()
587+ . atLeastM68010 ())
588588 MIB->setDesc (get (M68k::MOV16dc));
589+ else
590+ MIB->setDesc (get (M68k::MOV16ds));
589591
590592 return true ;
591593}
@@ -709,6 +711,8 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
709711 Register SrcReg, bool KillSrc,
710712 bool RenamableDest, bool RenamableSrc) const {
711713 unsigned Opc = 0 ;
714+ MachineFunction &MF = *MBB.getParent ();
715+ const M68kSubtarget &STI = MF.getSubtarget <M68kSubtarget>();
712716
713717 // First deal with the normal symmetric copies.
714718 if (M68k::XR32RegClass.contains (DstReg, SrcReg))
@@ -718,20 +722,13 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
718722 else if (M68k::DR8RegClass.contains (DstReg, SrcReg))
719723 Opc = M68k::MOV8dd;
720724
721- if (Opc) {
722- BuildMI (MBB, MI, DL, get (Opc), DstReg)
723- .addReg (SrcReg, getKillRegState (KillSrc));
724- return ;
725- }
726-
727725 // Now deal with asymmetrically sized copies. The cases that follow are upcast
728726 // moves.
729727 //
730728 // NOTE
731729 // These moves are not aware of type nature of these values and thus
732730 // won't do any SExt or ZExt and upper bits will basically contain garbage.
733- MachineInstrBuilder MIB (*MBB.getParent (), MI);
734- if (M68k::DR8RegClass.contains (SrcReg)) {
731+ else if (M68k::DR8RegClass.contains (SrcReg)) {
735732 if (M68k::XR16RegClass.contains (DstReg))
736733 Opc = M68k::MOVXd16d8;
737734 else if (M68k::XR32RegClass.contains (DstReg))
@@ -740,29 +737,18 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
740737 M68k::XR32RegClass.contains (DstReg))
741738 Opc = M68k::MOVXd32d16;
742739
743- if (Opc) {
744- BuildMI (MBB, MI, DL, get (Opc), DstReg)
745- .addReg (SrcReg, getKillRegState (KillSrc));
746- return ;
747- }
748-
749- bool FromCCR = SrcReg == M68k::CCR;
750- bool FromSR = SrcReg == M68k::SR;
751- bool ToCCR = DstReg == M68k::CCR;
752- bool ToSR = DstReg == M68k::SR;
753-
754- if (FromCCR) {
740+ else if (SrcReg == M68k::CCR) {
755741 if (M68k::DR8RegClass.contains (DstReg)) {
756742 Opc = M68k::MOV8dc;
757743 } else if (M68k::DR16RegClass.contains (DstReg)) {
758- Opc = M68k::MOV16dc;
744+ Opc = STI. isM68000 () ? M68k::MOV16ds : M68k::MOV16dc;
759745 } else if (M68k::DR32RegClass.contains (DstReg)) {
760- Opc = M68k::MOV16dc;
746+ Opc = STI. isM68000 () ? M68k::MOV16ds : M68k::MOV16dc;
761747 } else {
762748 LLVM_DEBUG (dbgs () << " Cannot copy CCR to " << RI.getName (DstReg) << ' \n ' );
763749 llvm_unreachable (" Invalid register for MOVE from CCR" );
764750 }
765- } else if (ToCCR ) {
751+ } else if (DstReg == M68k::CCR ) {
766752 if (M68k::DR8RegClass.contains (SrcReg)) {
767753 Opc = M68k::MOV8cd;
768754 } else if (M68k::DR16RegClass.contains (SrcReg)) {
@@ -773,18 +759,69 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
773759 LLVM_DEBUG (dbgs () << " Cannot copy " << RI.getName (SrcReg) << " to CCR\n " );
774760 llvm_unreachable (" Invalid register for MOVE to CCR" );
775761 }
776- } else if (FromSR || ToSR )
762+ } else if (SrcReg == M68k::SR || DstReg == M68k::SR )
777763 llvm_unreachable (" Cannot emit SR copy instruction" );
778764
779- if (Opc) {
765+ if (!Opc) {
766+ LLVM_DEBUG (dbgs () << " Cannot copy " << RI.getName (SrcReg) << " to "
767+ << RI.getName (DstReg) << ' \n ' );
768+ llvm_unreachable (" Cannot emit physreg copy instruction" );
769+ }
770+
771+ unsigned CCRSrcReg = STI.isM68000 () ? M68k::SR : M68k::CCR;
772+
773+ // Get the live registers right before the COPY instruction. If CCR is
774+ // live, the MOVE is going to kill it, so we will need to preserve it.
775+ LiveRegUnits UsedRegs (RI);
776+ UsedRegs.addLiveOuts (MBB);
777+ auto InstUpToI = MBB.end ();
778+ while (InstUpToI != MI) {
779+ UsedRegs.stepBackward (*--InstUpToI);
780+ }
781+
782+ if (SrcReg == M68k::CCR) {
783+ BuildMI (MBB, MI, DL, get (Opc), DstReg).addReg (CCRSrcReg);
784+ return ;
785+ }
786+ if (DstReg == M68k::CCR) {
787+ BuildMI (MBB, MI, DL, get (Opc), M68k::CCR)
788+ .addReg (SrcReg, getKillRegState (KillSrc));
789+ return ;
790+ }
791+ if (UsedRegs.available (M68k::CCR)) {
780792 BuildMI (MBB, MI, DL, get (Opc), DstReg)
781- .addReg (SrcReg, getKillRegState (KillSrc));
793+ .addReg (SrcReg, getKillRegState (KillSrc));
782794 return ;
783795 }
784796
785- LLVM_DEBUG (dbgs () << " Cannot copy " << RI.getName (SrcReg) << " to "
786- << RI.getName (DstReg) << ' \n ' );
787- llvm_unreachable (" Cannot emit physreg copy instruction" );
797+ // CCR is live, so we must restore it after the copy. Prepare push/pop ops.
798+ // 68000 must use MOVE from SR, 68010+ must use MOVE from CCR. In either
799+ // case, MOVE to CCR masks out the upper byte.
800+
801+ // Look for an available data register for the CCR, or push to stack if
802+ // there are none
803+ BitVector Allocatable = RI.getAllocatableSet (
804+ MF, RI.getRegClass (M68k::DR16RegClassID));
805+ for (Register Reg : Allocatable.set_bits ()) {
806+ if (!RI.regsOverlap (DstReg, Reg) && (UsedRegs.available (Reg))) {
807+ unsigned CCRPushOp = STI.isM68000 () ? M68k::MOV16ds : M68k::MOV16dc;
808+ unsigned CCRPopOp = M68k::MOV16cd;
809+ BuildMI (MBB, MI, DL, get (CCRPushOp), Reg).addReg (CCRSrcReg);
810+ BuildMI (MBB, MI, DL, get (Opc), DstReg)
811+ .addReg (SrcReg, getKillRegState (KillSrc));
812+ BuildMI (MBB, MI, DL, get (CCRPopOp), M68k::CCR).addReg (Reg);
813+ return ;
814+ }
815+ }
816+
817+ unsigned CCRPushOp = STI.isM68000 () ? M68k::MOV16es : M68k::MOV16ec;
818+ unsigned CCRPopOp = M68k::MOV16co;
819+
820+ BuildMI (MBB, MI, DL, get (CCRPushOp)).addReg (RI.getStackRegister ()).addReg (CCRSrcReg);
821+ BuildMI (MBB, MI, DL, get (Opc), DstReg)
822+ .addReg (SrcReg, getKillRegState (KillSrc));
823+ BuildMI (MBB, MI, DL, get (CCRPopOp), M68k::CCR).addReg (RI.getStackRegister ());
824+ return ;
788825}
789826
790827namespace {
0 commit comments