@@ -583,9 +583,11 @@ bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {
583
583
// Replace the pseudo instruction with the real one
584
584
if (IsToCCR)
585
585
MIB->setDesc (get (M68k::MOV16cd));
586
- else
587
- // FIXME M68010 or later is required
586
+ else if (MIB-> getParent ()-> getParent ()-> getSubtarget <M68kSubtarget>()
587
+ . atLeastM68010 ())
588
588
MIB->setDesc (get (M68k::MOV16dc));
589
+ else
590
+ MIB->setDesc (get (M68k::MOV16ds));
589
591
590
592
return true ;
591
593
}
@@ -709,6 +711,8 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
709
711
Register SrcReg, bool KillSrc,
710
712
bool RenamableDest, bool RenamableSrc) const {
711
713
unsigned Opc = 0 ;
714
+ MachineFunction &MF = *MBB.getParent ();
715
+ const M68kSubtarget &STI = MF.getSubtarget <M68kSubtarget>();
712
716
713
717
// First deal with the normal symmetric copies.
714
718
if (M68k::XR32RegClass.contains (DstReg, SrcReg))
@@ -718,20 +722,13 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
718
722
else if (M68k::DR8RegClass.contains (DstReg, SrcReg))
719
723
Opc = M68k::MOV8dd;
720
724
721
- if (Opc) {
722
- BuildMI (MBB, MI, DL, get (Opc), DstReg)
723
- .addReg (SrcReg, getKillRegState (KillSrc));
724
- return ;
725
- }
726
-
727
725
// Now deal with asymmetrically sized copies. The cases that follow are upcast
728
726
// moves.
729
727
//
730
728
// NOTE
731
729
// These moves are not aware of type nature of these values and thus
732
730
// 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)) {
735
732
if (M68k::XR16RegClass.contains (DstReg))
736
733
Opc = M68k::MOVXd16d8;
737
734
else if (M68k::XR32RegClass.contains (DstReg))
@@ -740,29 +737,18 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
740
737
M68k::XR32RegClass.contains (DstReg))
741
738
Opc = M68k::MOVXd32d16;
742
739
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) {
755
741
if (M68k::DR8RegClass.contains (DstReg)) {
756
742
Opc = M68k::MOV8dc;
757
743
} else if (M68k::DR16RegClass.contains (DstReg)) {
758
- Opc = M68k::MOV16dc;
744
+ Opc = STI. isM68000 () ? M68k::MOV16ds : M68k::MOV16dc;
759
745
} else if (M68k::DR32RegClass.contains (DstReg)) {
760
- Opc = M68k::MOV16dc;
746
+ Opc = STI. isM68000 () ? M68k::MOV16ds : M68k::MOV16dc;
761
747
} else {
762
748
LLVM_DEBUG (dbgs () << " Cannot copy CCR to " << RI.getName (DstReg) << ' \n ' );
763
749
llvm_unreachable (" Invalid register for MOVE from CCR" );
764
750
}
765
- } else if (ToCCR ) {
751
+ } else if (DstReg == M68k::CCR ) {
766
752
if (M68k::DR8RegClass.contains (SrcReg)) {
767
753
Opc = M68k::MOV8cd;
768
754
} else if (M68k::DR16RegClass.contains (SrcReg)) {
@@ -773,18 +759,67 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
773
759
LLVM_DEBUG (dbgs () << " Cannot copy " << RI.getName (SrcReg) << " to CCR\n " );
774
760
llvm_unreachable (" Invalid register for MOVE to CCR" );
775
761
}
776
- } else if (FromSR || ToSR )
762
+ } else if (SrcReg == M68k::SR || DstReg == M68k::SR )
777
763
llvm_unreachable (" Cannot emit SR copy instruction" );
778
764
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
+ // 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
+ LiveRegUnits UsedRegs (RI);
774
+ UsedRegs.addLiveOuts (MBB);
775
+ auto InstUpToI = MBB.end ();
776
+ while (InstUpToI != MI) {
777
+ UsedRegs.stepBackward (*--InstUpToI);
778
+ }
779
+
780
+ if (SrcReg == M68k::CCR) {
781
+ BuildMI (MBB, MI, DL, get (Opc), DstReg);
782
+ return ;
783
+ }
784
+ if (DstReg == M68k::CCR) {
785
+ BuildMI (MBB, MI, DL, get (Opc))
786
+ .addReg (SrcReg, getKillRegState (KillSrc));
787
+ return ;
788
+ }
789
+ if (UsedRegs.available (M68k::CCR)) {
780
790
BuildMI (MBB, MI, DL, get (Opc), DstReg)
781
- .addReg (SrcReg, getKillRegState (KillSrc));
791
+ .addReg (SrcReg, getKillRegState (KillSrc));
782
792
return ;
783
793
}
784
794
785
- LLVM_DEBUG (dbgs () << " Cannot copy " << RI.getName (SrcReg) << " to "
786
- << RI.getName (DstReg) << ' \n ' );
787
- llvm_unreachable (" Cannot emit physreg copy instruction" );
795
+ // CCR is live, so we must restore it after the copy. Prepare push/pop ops.
796
+ // 68000 must use MOVE from SR, 68010+ must use MOVE from CCR. In either
797
+ // case, MOVE to CCR masks out the upper byte.
798
+
799
+ // Look for an available data register for the CCR, or push to stack if
800
+ // there are none
801
+ BitVector Allocatable = RI.getAllocatableSet (
802
+ MF, RI.getRegClass (M68k::DR16RegClassID));
803
+ for (Register Reg : Allocatable.set_bits ()) {
804
+ if (!RI.regsOverlap (DstReg, Reg) && (UsedRegs.available (Reg))) {
805
+ unsigned CCRPushOp = STI.isM68000 () ? M68k::MOV16ds : M68k::MOV16dc;
806
+ unsigned CCRPopOp = M68k::MOV16cd;
807
+ BuildMI (MBB, MI, DL, get (CCRPushOp), Reg);
808
+ BuildMI (MBB, MI, DL, get (Opc), DstReg)
809
+ .addReg (SrcReg, getKillRegState (KillSrc));
810
+ BuildMI (MBB, MI, DL, get (CCRPopOp)).addReg (Reg);
811
+ return ;
812
+ }
813
+ }
814
+
815
+ unsigned CCRPushOp = STI.isM68000 () ? M68k::MOV16es : M68k::MOV16ec;
816
+ unsigned CCRPopOp = M68k::MOV16co;
817
+
818
+ BuildMI (MBB, MI, DL, get (CCRPushOp)).addReg (RI.getStackRegister ());
819
+ BuildMI (MBB, MI, DL, get (Opc), DstReg)
820
+ .addReg (SrcReg, getKillRegState (KillSrc));
821
+ BuildMI (MBB, MI, DL, get (CCRPopOp)).addReg (RI.getStackRegister ());
822
+ return ;
788
823
}
789
824
790
825
namespace {
0 commit comments