diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp index 9dc69e203b0da..ea34c1aba82e3 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -1238,6 +1238,30 @@ static void emitAccSpillRestoreInfo(MachineBasicBlock &MBB, bool IsPrimed, #endif } +void PPCRegisterInfo::spillRegPair(MachineBasicBlock &MBB, + MachineBasicBlock::iterator II, DebugLoc DL, + const TargetInstrInfo &TII, + unsigned FrameIndex, bool IsLittleEndian, + bool IsKilled, Register Reg, + int Offset) const { + + // This function does not support virtual registers. + assert(!Reg.isVirtual() && + "Spilling register pairs does not support virtual registers."); + + addFrameReference( + BuildMI(MBB, II, DL, TII.get(PPC::STXV)) + .addReg(TargetRegisterInfo::getSubReg(Reg, PPC::sub_vsx0), + getKillRegState(IsKilled)), + FrameIndex, Offset); + + addFrameReference( + BuildMI(MBB, II, DL, TII.get(PPC::STXV)) + .addReg(TargetRegisterInfo::getSubReg(Reg, PPC::sub_vsx1), + getKillRegState(IsKilled)), + FrameIndex, IsLittleEndian ? Offset - 16 : Offset + 16); +} + /// Remove any STXVP[X] instructions and split them out into a pair of /// STXV[X] instructions if --disable-auto-paired-vec-st is specified on /// the command line. @@ -1255,19 +1279,8 @@ void PPCRegisterInfo::lowerOctWordSpilling(MachineBasicBlock::iterator II, bool IsLittleEndian = Subtarget.isLittleEndian(); bool IsKilled = MI.getOperand(0).isKill(); - assert(PPC::VSRpRCRegClass.contains(SrcReg) && - "Expecting STXVP to be utilizing a VSRp register."); - - addFrameReference( - BuildMI(MBB, II, DL, TII.get(PPC::STXV)) - .addReg(TargetRegisterInfo::getSubReg(SrcReg, PPC::sub_vsx0), - getKillRegState(IsKilled)), - FrameIndex, IsLittleEndian ? 16 : 0); - addFrameReference( - BuildMI(MBB, II, DL, TII.get(PPC::STXV)) - .addReg(TargetRegisterInfo::getSubReg(SrcReg, PPC::sub_vsx1), - getKillRegState(IsKilled)), - FrameIndex, IsLittleEndian ? 0 : 16); + spillRegPair(MBB, II, DL, TII, FrameIndex, IsLittleEndian, IsKilled, SrcReg, + IsLittleEndian ? 16 : 0); // Discard the original instruction. MBB.erase(II); @@ -1313,22 +1326,12 @@ void PPCRegisterInfo::lowerACCSpilling(MachineBasicBlock::iterator II, if (IsPrimed) BuildMI(MBB, II, DL, TII.get(PPC::XXMFACC), SrcReg).addReg(SrcReg); if (DisableAutoPairedVecSt) { - auto spillPair = [&](Register Reg, int Offset) { - addFrameReference( - BuildMI(MBB, II, DL, TII.get(PPC::STXV)) - .addReg(TargetRegisterInfo::getSubReg(Reg, PPC::sub_vsx0), - getKillRegState(IsKilled)), - FrameIndex, Offset); - addFrameReference( - BuildMI(MBB, II, DL, TII.get(PPC::STXV)) - .addReg(TargetRegisterInfo::getSubReg(Reg, PPC::sub_vsx1), - getKillRegState(IsKilled)), - FrameIndex, IsLittleEndian ? Offset - 16 : Offset + 16); - }; - spillPair(TargetRegisterInfo::getSubReg(SrcReg, PPC::sub_pair0), - IsLittleEndian ? 48 : 0); - spillPair(TargetRegisterInfo::getSubReg(SrcReg, PPC::sub_pair1), - IsLittleEndian ? 16 : 32); + spillRegPair(MBB, II, DL, TII, FrameIndex, IsLittleEndian, IsKilled, + TargetRegisterInfo::getSubReg(SrcReg, PPC::sub_pair0), + IsLittleEndian ? 48 : 0); + spillRegPair(MBB, II, DL, TII, FrameIndex, IsLittleEndian, IsKilled, + TargetRegisterInfo::getSubReg(SrcReg, PPC::sub_pair1), + IsLittleEndian ? 16 : 32); } else { addFrameReference( BuildMI(MBB, II, DL, TII.get(PPC::STXVP)) diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.h b/llvm/lib/Target/PowerPC/PPCRegisterInfo.h index 4b66ece534112..849f856b5419e 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.h +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.h @@ -58,6 +58,11 @@ class PPCRegisterInfo : public PPCGenRegisterInfo { DenseMap ImmToIdxMap; const PPCTargetMachine &TM; + void spillRegPair(MachineBasicBlock &MBB, MachineBasicBlock::iterator II, + DebugLoc DL, const TargetInstrInfo &TII, + unsigned FrameIndex, bool IsLittleEndian, bool IsKilled, + Register Reg, int Offset) const; + public: PPCRegisterInfo(const PPCTargetMachine &TM);