@@ -561,6 +561,60 @@ void Z80InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
561561 }
562562 return ;
563563 }
564+ // Specialized byte copy.
565+ if (DstReg == Z80::F) {
566+ // Copies to F.
567+ bool NeedEX = false ;
568+ switch (SrcReg) {
569+ case Z80::H: SrcReg = Z80::D; NeedEX = true ; break ;
570+ case Z80::L: SrcReg = Z80::E; NeedEX = true ; break ;
571+ }
572+ Register TempReg = Is24Bit ? Z80::UHL : Z80::HL;
573+ if (NeedEX)
574+ BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::EX24DE : Z80::EX16DE))
575+ .addReg (Is24Bit ? Z80::UDE : Z80::DE, RegState::ImplicitDefine)
576+ .addReg (TempReg, RegState::ImplicitDefine);
577+ applySPAdjust (
578+ *BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::PUSH24r : Z80::PUSH16r))
579+ .addReg (TempReg, RegState::Undef));
580+ copyPhysReg (MBB, MI, DL, Z80::L, SrcReg, KillSrc);
581+ BuildMI (MBB, MI, DL, get (TargetOpcode::COPY), Z80::H)
582+ .addReg (Z80::A, RegState::Undef); // Preserve A
583+ BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::EX24SP : Z80::EX16SP), TempReg)
584+ .addReg (TempReg, RegState::Undef);
585+ applySPAdjust (
586+ *BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::POP24AF : Z80::POP16AF)));
587+ if (NeedEX)
588+ BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::EX24DE : Z80::EX16DE))
589+ .addReg (Is24Bit ? Z80::UDE : Z80::DE, RegState::ImplicitDefine)
590+ .addReg (TempReg, RegState::ImplicitDefine);
591+ return ;
592+ }
593+ if (SrcReg == Z80::F) {
594+ // Copies from F.
595+ bool NeedEX = false ;
596+ switch (DstReg) {
597+ case Z80::H: DstReg = Z80::D; NeedEX = true ; break ;
598+ case Z80::L: DstReg = Z80::E; NeedEX = true ; break ;
599+ }
600+ Register TempReg = Is24Bit ? Z80::UHL : Z80::HL;
601+ if (NeedEX)
602+ BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::EX24DE : Z80::EX16DE))
603+ .addReg (Is24Bit ? Z80::UDE : Z80::DE, RegState::ImplicitDefine)
604+ .addReg (TempReg, RegState::ImplicitDefine);
605+ applySPAdjust (
606+ *BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::PUSH24AF : Z80::PUSH16AF)));
607+ BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::EX24SP : Z80::EX16SP), TempReg)
608+ .addReg (TempReg, RegState::Undef);
609+ copyPhysReg (MBB, MI, DL, DstReg, Z80::L, KillSrc);
610+ applySPAdjust (*BuildMI (MBB, MI, DL,
611+ get (Is24Bit ? Z80::POP24r : Z80::POP16r), TempReg));
612+ if (NeedEX)
613+ BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::EX24DE : Z80::EX16DE))
614+ .addReg (Is24Bit ? Z80::UDE : Z80::DE, RegState::ImplicitDefine)
615+ .addReg (TempReg, RegState::ImplicitDefine);
616+ return ;
617+ }
564618 // Specialized word copy.
565619 if (DstReg == Z80::SPS || DstReg == Z80::SPL) {
566620 // Copies to SP.
@@ -731,6 +785,24 @@ void Z80InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
731785 Register SrcReg, bool IsKill, int FI,
732786 const TargetRegisterClass *TRC,
733787 const TargetRegisterInfo *TRI) const {
788+ const DebugLoc &DL = MBB.findDebugLoc (MI);
789+ bool Is24Bit = Subtarget.is24Bit ();
790+
791+ // Special cases
792+ switch (SrcReg) {
793+ case Z80::F: {
794+ Register TempReg = Is24Bit ? Z80::UHL : Z80::HL;
795+ applySPAdjust (
796+ *BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::PUSH24AF : Z80::PUSH16AF)));
797+ BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::EX24SP : Z80::EX16SP), TempReg)
798+ .addReg (TempReg, RegState::Undef);
799+ storeRegToStackSlot (MBB, MI, Z80::L, true , FI, &Z80::R8RegClass, TRI);
800+ applySPAdjust (*BuildMI (MBB, MI, DL,
801+ get (Is24Bit ? Z80::POP24r : Z80::POP16r), TempReg));
802+ return ;
803+ }
804+ }
805+
734806 unsigned Opc;
735807 switch (TRI->getSpillSize (*TRC)) {
736808 default :
@@ -742,19 +814,40 @@ void Z80InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
742814 Opc = Subtarget.has16BitEZ80Ops () ? Z80::LD16or : Z80::LD88or;
743815 break ;
744816 case 3 :
745- assert (Subtarget. is24Bit () && " Only 24-bit should have 3 byte stack slots" );
817+ assert (Is24Bit && " Only 24-bit should have 3 byte stack slots" );
746818 Opc = Z80::LD24or;
747819 break ;
748820 }
749- BuildMI (MBB, MI, MBB. findDebugLoc (MI) , get (Opc)). addFrameIndex (FI). addImm ( 0 )
750- .addReg (SrcReg, getKillRegState (IsKill));
821+ BuildMI (MBB, MI, DL , get (Opc))
822+ . addFrameIndex (FI). addImm ( 0 ) .addReg (SrcReg, getKillRegState (IsKill));
751823}
752824
753825void Z80InstrInfo::loadRegFromStackSlot (MachineBasicBlock &MBB,
754826 MachineBasicBlock::iterator MI,
755827 Register DstReg, int FI,
756828 const TargetRegisterClass *TRC,
757829 const TargetRegisterInfo *TRI) const {
830+ const DebugLoc &DL = MBB.findDebugLoc (MI);
831+ bool Is24Bit = Subtarget.is24Bit ();
832+
833+ // Special cases
834+ switch (DstReg) {
835+ case Z80::F: {
836+ Register TempReg = Is24Bit ? Z80::UHL : Z80::HL;
837+ applySPAdjust (
838+ *BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::PUSH24r : Z80::PUSH16r))
839+ .addReg (TempReg, RegState::Undef));
840+ loadRegFromStackSlot (MBB, MI, Z80::L, FI, &Z80::R8RegClass, TRI);
841+ BuildMI (MBB, MI, DL, get (TargetOpcode::COPY), Z80::H)
842+ .addReg (Z80::A, RegState::Undef); // Preserve A
843+ BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::EX24SP : Z80::EX16SP), TempReg)
844+ .addReg (TempReg, RegState::Undef);
845+ applySPAdjust (
846+ *BuildMI (MBB, MI, DL, get (Is24Bit ? Z80::POP24AF : Z80::POP16AF)));
847+ return ;
848+ }
849+ }
850+
758851 unsigned Opc;
759852 switch (TRI->getSpillSize (*TRC)) {
760853 default :
@@ -763,17 +856,19 @@ void Z80InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
763856 Opc = Z80::LD8ro;
764857 break ;
765858 case 2 :
766- Opc = Subtarget.has16BitEZ80Ops () ? Z80::LD16ro : Z80::LD88ro;
767- if (Subtarget.is24Bit ())
768- Opc = Z80::LD24ro;
769- break ;
859+ if (!Is24Bit) {
860+ Opc = Subtarget.has16BitEZ80Ops () ? Z80::LD16ro : Z80::LD88ro;
861+ break ;
862+ }
863+ TRC = &Z80::R24RegClass;
864+ DstReg = TRI->getMatchingSuperReg (DstReg, Z80::sub_short, TRC);
865+ LLVM_FALLTHROUGH;
770866 case 3 :
771- assert (Subtarget. is24Bit () && " Only 24-bit should have 3 byte stack slots" );
867+ assert (Is24Bit && " Only 24-bit should have 3 byte stack slots" );
772868 Opc = Z80::LD24ro;
773869 break ;
774870 }
775- BuildMI (MBB, MI, MBB.findDebugLoc (MI), get (Opc), DstReg).addFrameIndex (FI)
776- .addImm (0 );
871+ BuildMI (MBB, MI, DL, get (Opc), DstReg).addFrameIndex (FI).addImm (0 );
777872}
778873
779874// / Return true and the FrameIndex if the specified
@@ -1739,22 +1834,30 @@ MachineInstr *Z80InstrInfo::foldMemoryOperandImpl(
17391834 case 0 :
17401835 switch (MI.getOpcode ()) {
17411836 default : return nullptr ;
1742- case TargetOpcode:: COPY: Opc = IsOff ? Z80:: LD8or : Z80:: LD8pr; break ;
1837+ case TargetOpcode::COPY:
1838+ if (!Z80::R8RegClass.contains (MI.getOperand (1 ).getReg ()))
1839+ return nullptr ;
1840+ Opc = IsOff ? Z80::LD8or : Z80::LD8pr;
1841+ break ;
17431842 }
17441843 break ;
17451844 case 1 :
17461845 switch (MI.getOpcode ()) {
17471846 default : return nullptr ;
1748- case Z80::BIT8bg: Opc = IsOff ? Z80::BIT8bo : Z80::BIT8bp; break ;
1749- case Z80::ADD8ar: Opc = IsOff ? Z80::ADD8ao : Z80::ADD8ap; break ;
1750- case Z80::ADC8ar: Opc = IsOff ? Z80::ADC8ao : Z80::ADC8ap; break ;
1751- case Z80::SUB8ar: Opc = IsOff ? Z80::SUB8ao : Z80::SUB8ap; break ;
1752- case Z80::SBC8ar: Opc = IsOff ? Z80::SBC8ao : Z80::SBC8ap; break ;
1753- case Z80::AND8ar: Opc = IsOff ? Z80::AND8ao : Z80::AND8ap; break ;
1754- case Z80::XOR8ar: Opc = IsOff ? Z80::XOR8ao : Z80::XOR8ap; break ;
1755- case Z80:: OR8ar: Opc = IsOff ? Z80:: OR8ao : Z80:: OR8ap; break ;
1756- case Z80::TST8ar: Opc = IsOff ? Z80::TST8ao : Z80::TST8ap; break ;
1757- case TargetOpcode:: COPY: Opc = IsOff ? Z80:: LD8ro : Z80:: LD8rp; break ;
1847+ case Z80::BIT8bg: Opc = IsOff ? Z80::BIT8bo : Z80::BIT8bp; break ;
1848+ case Z80::ADD8ar: Opc = IsOff ? Z80::ADD8ao : Z80::ADD8ap; break ;
1849+ case Z80::ADC8ar: Opc = IsOff ? Z80::ADC8ao : Z80::ADC8ap; break ;
1850+ case Z80::SUB8ar: Opc = IsOff ? Z80::SUB8ao : Z80::SUB8ap; break ;
1851+ case Z80::SBC8ar: Opc = IsOff ? Z80::SBC8ao : Z80::SBC8ap; break ;
1852+ case Z80::AND8ar: Opc = IsOff ? Z80::AND8ao : Z80::AND8ap; break ;
1853+ case Z80::XOR8ar: Opc = IsOff ? Z80::XOR8ao : Z80::XOR8ap; break ;
1854+ case Z80:: OR8ar: Opc = IsOff ? Z80:: OR8ao : Z80:: OR8ap; break ;
1855+ case Z80::TST8ar: Opc = IsOff ? Z80::TST8ao : Z80::TST8ap; break ;
1856+ case TargetOpcode::COPY:
1857+ if (!Z80::R8RegClass.contains (MI.getOperand (0 ).getReg ()))
1858+ return nullptr ;
1859+ Opc = IsOff ? Z80::LD8ro : Z80::LD8rp;
1860+ break ;
17581861 }
17591862 break ;
17601863 }
0 commit comments