@@ -5302,30 +5302,78 @@ void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
53025302
53035303 if (AArch64::FPR32RegClass.contains (DestReg) &&
53045304 AArch64::FPR32RegClass.contains (SrcReg)) {
5305- BuildMI (MBB, I, DL, get (AArch64::FMOVSr), DestReg)
5306- .addReg (SrcReg, getKillRegState (KillSrc));
5305+ if (Subtarget.hasZeroCycleRegMoveFPR64 () &&
5306+ !Subtarget.hasZeroCycleRegMoveFPR32 ()) {
5307+ const TargetRegisterInfo *TRI = &getRegisterInfo ();
5308+ MCRegister DestRegD = TRI->getMatchingSuperReg (DestReg, AArch64::ssub,
5309+ &AArch64::FPR64RegClass);
5310+ MCRegister SrcRegD = TRI->getMatchingSuperReg (SrcReg, AArch64::ssub,
5311+ &AArch64::FPR64RegClass);
5312+ // This instruction is reading and writing D registers. This may upset
5313+ // the register scavenger and machine verifier, so we need to indicate
5314+ // that we are reading an undefined value from SrcRegD, but a proper
5315+ // value from SrcReg.
5316+ BuildMI (MBB, I, DL, get (AArch64::FMOVDr), DestRegD)
5317+ .addReg (SrcRegD, RegState::Undef)
5318+ .addReg (SrcReg, RegState::Implicit | getKillRegState (KillSrc));
5319+ } else {
5320+ BuildMI (MBB, I, DL, get (AArch64::FMOVSr), DestReg)
5321+ .addReg (SrcReg, getKillRegState (KillSrc));
5322+ }
53075323 return ;
53085324 }
53095325
53105326 if (AArch64::FPR16RegClass.contains (DestReg) &&
53115327 AArch64::FPR16RegClass.contains (SrcReg)) {
5312- DestReg =
5313- RI.getMatchingSuperReg (DestReg, AArch64::hsub, &AArch64::FPR32RegClass);
5314- SrcReg =
5315- RI.getMatchingSuperReg (SrcReg, AArch64::hsub, &AArch64::FPR32RegClass);
5316- BuildMI (MBB, I, DL, get (AArch64::FMOVSr), DestReg)
5317- .addReg (SrcReg, getKillRegState (KillSrc));
5328+ if (Subtarget.hasZeroCycleRegMoveFPR64 () &&
5329+ !Subtarget.hasZeroCycleRegMoveFPR32 ()) {
5330+ const TargetRegisterInfo *TRI = &getRegisterInfo ();
5331+ MCRegister DestRegD = TRI->getMatchingSuperReg (DestReg, AArch64::hsub,
5332+ &AArch64::FPR64RegClass);
5333+ MCRegister SrcRegD = TRI->getMatchingSuperReg (SrcReg, AArch64::hsub,
5334+ &AArch64::FPR64RegClass);
5335+ // This instruction is reading and writing D registers. This may upset
5336+ // the register scavenger and machine verifier, so we need to indicate
5337+ // that we are reading an undefined value from SrcRegD, but a proper
5338+ // value from SrcReg.
5339+ BuildMI (MBB, I, DL, get (AArch64::FMOVDr), DestRegD)
5340+ .addReg (SrcRegD, RegState::Undef)
5341+ .addReg (SrcReg, RegState::Implicit | getKillRegState (KillSrc));
5342+ } else {
5343+ DestReg = RI.getMatchingSuperReg (DestReg, AArch64::hsub,
5344+ &AArch64::FPR32RegClass);
5345+ SrcReg = RI.getMatchingSuperReg (SrcReg, AArch64::hsub,
5346+ &AArch64::FPR32RegClass);
5347+ BuildMI (MBB, I, DL, get (AArch64::FMOVSr), DestReg)
5348+ .addReg (SrcReg, getKillRegState (KillSrc));
5349+ }
53185350 return ;
53195351 }
53205352
53215353 if (AArch64::FPR8RegClass.contains (DestReg) &&
53225354 AArch64::FPR8RegClass.contains (SrcReg)) {
5323- DestReg =
5324- RI.getMatchingSuperReg (DestReg, AArch64::bsub, &AArch64::FPR32RegClass);
5325- SrcReg =
5326- RI.getMatchingSuperReg (SrcReg, AArch64::bsub, &AArch64::FPR32RegClass);
5327- BuildMI (MBB, I, DL, get (AArch64::FMOVSr), DestReg)
5328- .addReg (SrcReg, getKillRegState (KillSrc));
5355+ if (Subtarget.hasZeroCycleRegMoveFPR64 () &&
5356+ !Subtarget.hasZeroCycleRegMoveFPR32 ()) {
5357+ const TargetRegisterInfo *TRI = &getRegisterInfo ();
5358+ MCRegister DestRegD = TRI->getMatchingSuperReg (DestReg, AArch64::bsub,
5359+ &AArch64::FPR64RegClass);
5360+ MCRegister SrcRegD = TRI->getMatchingSuperReg (SrcReg, AArch64::bsub,
5361+ &AArch64::FPR64RegClass);
5362+ // This instruction is reading and writing D registers. This may upset
5363+ // the register scavenger and machine verifier, so we need to indicate
5364+ // that we are reading an undefined value from SrcRegD, but a proper
5365+ // value from SrcReg.
5366+ BuildMI (MBB, I, DL, get (AArch64::FMOVDr), DestRegD)
5367+ .addReg (SrcRegD, RegState::Undef)
5368+ .addReg (SrcReg, RegState::Implicit | getKillRegState (KillSrc));
5369+ } else {
5370+ DestReg = RI.getMatchingSuperReg (DestReg, AArch64::bsub,
5371+ &AArch64::FPR32RegClass);
5372+ SrcReg = RI.getMatchingSuperReg (SrcReg, AArch64::bsub,
5373+ &AArch64::FPR32RegClass);
5374+ BuildMI (MBB, I, DL, get (AArch64::FMOVSr), DestReg)
5375+ .addReg (SrcReg, getKillRegState (KillSrc));
5376+ }
53295377 return ;
53305378 }
53315379
0 commit comments