@@ -584,7 +584,6 @@ bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {
584
584
if (IsToCCR)
585
585
MIB->setDesc (get (M68k::MOV16cd));
586
586
else
587
- // FIXME M68010 or later is required
588
587
MIB->setDesc (get (M68k::MOV16dc));
589
588
590
589
return true ;
@@ -718,20 +717,13 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
718
717
else if (M68k::DR8RegClass.contains (DstReg, SrcReg))
719
718
Opc = M68k::MOV8dd;
720
719
721
- if (Opc) {
722
- BuildMI (MBB, MI, DL, get (Opc), DstReg)
723
- .addReg (SrcReg, getKillRegState (KillSrc));
724
- return ;
725
- }
726
-
727
720
// Now deal with asymmetrically sized copies. The cases that follow are upcast
728
721
// moves.
729
722
//
730
723
// NOTE
731
724
// These moves are not aware of type nature of these values and thus
732
725
// 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)) {
726
+ else if (M68k::DR8RegClass.contains (SrcReg)) {
735
727
if (M68k::XR16RegClass.contains (DstReg))
736
728
Opc = M68k::MOVXd16d8;
737
729
else if (M68k::XR32RegClass.contains (DstReg))
@@ -740,18 +732,7 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
740
732
M68k::XR32RegClass.contains (DstReg))
741
733
Opc = M68k::MOVXd32d16;
742
734
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) {
735
+ else if (SrcReg == M68k::CCR) {
755
736
if (M68k::DR8RegClass.contains (DstReg)) {
756
737
Opc = M68k::MOV8dc;
757
738
} else if (M68k::DR16RegClass.contains (DstReg)) {
@@ -762,7 +743,7 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
762
743
LLVM_DEBUG (dbgs () << " Cannot copy CCR to " << RI.getName (DstReg) << ' \n ' );
763
744
llvm_unreachable (" Invalid register for MOVE from CCR" );
764
745
}
765
- } else if (ToCCR ) {
746
+ } else if (DstReg == M68k::CCR ) {
766
747
if (M68k::DR8RegClass.contains (SrcReg)) {
767
748
Opc = M68k::MOV8cd;
768
749
} else if (M68k::DR16RegClass.contains (SrcReg)) {
@@ -773,18 +754,67 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
773
754
LLVM_DEBUG (dbgs () << " Cannot copy " << RI.getName (SrcReg) << " to CCR\n " );
774
755
llvm_unreachable (" Invalid register for MOVE to CCR" );
775
756
}
776
- } else if (FromSR || ToSR )
757
+ } else if (SrcReg == M68k::SR || DstReg == M68k::SR )
777
758
llvm_unreachable (" Cannot emit SR copy instruction" );
778
759
779
- if (Opc) {
760
+ if (!Opc) {
761
+ LLVM_DEBUG (dbgs () << " Cannot copy " << RI.getName (SrcReg) << " to "
762
+ << RI.getName (DstReg) << ' \n ' );
763
+ llvm_unreachable (" Cannot emit physreg copy instruction" );
764
+ }
765
+
766
+ // Create the final MOVE instruction without yet inserting
767
+ MachineFunction &MF = *MBB.getParent ();
768
+ // MachineInstrBuilder MoveMIB = BuildMI(MF, DL, get(Opc), DstReg)
769
+ // .addReg(SrcReg, getKillRegState(KillSrc));
770
+
771
+ // Get the live registers right before the COPY instruction. If CCR is
772
+ // live, the MOVE is going to kill it, so we will need to preserve it.
773
+ MachineRegisterInfo &MRI = MF.getRegInfo ();
774
+ LivePhysRegs UsedRegs (RI);
775
+ UsedRegs.addLiveOuts (MBB);
776
+ auto InstUpToI = MBB.end ();
777
+ while (InstUpToI != MI)
778
+ // The pre-decrement is on purpose here.
779
+ // We want to have the liveness right before I.
780
+ UsedRegs.stepBackward (*--InstUpToI);
781
+
782
+ if (UsedRegs.available (MRI, M68k::CCR)) {
780
783
BuildMI (MBB, MI, DL, get (Opc), DstReg)
781
- .addReg (SrcReg, getKillRegState (KillSrc));
784
+ .addReg (SrcReg, getKillRegState (KillSrc));
782
785
return ;
783
786
}
784
787
785
- LLVM_DEBUG (dbgs () << " Cannot copy " << RI.getName (SrcReg) << " to "
786
- << RI.getName (DstReg) << ' \n ' );
787
- llvm_unreachable (" Cannot emit physreg copy instruction" );
788
+ // CCR is live, so we must restore it after the copy. Prepare push/pop ops.
789
+ // 68000 must use MOVE from SR, 68010+ must use MOVE from CCR. In either
790
+ // case, MOVE to CCR masks out the upper byte.
791
+ const M68kSubtarget &STI = MF.getSubtarget <M68kSubtarget>();
792
+
793
+ // Look for an available data register for the CCR, or push to stack if
794
+ // there are none
795
+ BitVector Allocatable = RI.getAllocatableSet (
796
+ MF, RI.getRegClass (M68k::DR16RegClassID));
797
+ for (Register Reg : Allocatable.set_bits ()) {
798
+ if (!RI.regsOverlap (DstReg, Reg) &&
799
+ (UsedRegs.available (MRI, Reg) || !UsedRegs.contains (Reg))) {
800
+ unsigned CCRPushOp = STI.isM68000 () ? M68k::MOV16ds : M68k::MOV16dc;
801
+ unsigned CCRPopOp = M68k::MOV16cd;
802
+ BuildMI (MBB, MI, DL, get (CCRPushOp), Reg);
803
+ BuildMI (MBB, MI, DL, get (Opc), DstReg)
804
+ .addReg (SrcReg, getKillRegState (KillSrc));
805
+ BuildMI (MBB, MI, DL, get (CCRPopOp)).addReg (Reg);
806
+ return ;
807
+ }
808
+ }
809
+
810
+ unsigned CCRPushOp = STI.isM68000 () ? M68k::MOV16es : M68k::MOV16ec;
811
+ unsigned CCRPopOp = M68k::MOV16co;
812
+
813
+ BuildMI (MBB, MI, DL, get (CCRPushOp)).addReg (RI.getStackRegister ());
814
+ BuildMI (MBB, MI, DL, get (Opc), DstReg)
815
+ .addReg (SrcReg, getKillRegState (KillSrc));
816
+ BuildMI (MBB, MI, DL, get (CCRPopOp)).addReg (RI.getStackRegister ());
817
+ return ;
788
818
}
789
819
790
820
namespace {
0 commit comments