diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp index 9dc69e203b0da..45183af0b7984 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -1238,6 +1238,42 @@ static void emitAccSpillRestoreInfo(MachineBasicBlock &MBB, bool IsPrimed, #endif } +static void spillRegPairs(MachineBasicBlock &MBB, + MachineBasicBlock::iterator II, DebugLoc DL, + const TargetInstrInfo &TII, Register SrcReg, + unsigned FrameIndex, bool IsLittleEndian, + bool IsKilled, bool TwoPairs) { + unsigned Offset = 0; + // The register arithmetic in this function does not support virtual + // registers. + assert(!SrcReg.isVirtual() && + "Spilling register pairs does not support virtual registers."); + + if (TwoPairs) + Offset = IsLittleEndian ? 48 : 0; + else + Offset = IsLittleEndian ? 16 : 0; + Register Reg = (SrcReg > PPC::VSRp15) ? PPC::V0 + (SrcReg - PPC::VSRp16) * 2 + : PPC::VSL0 + (SrcReg - PPC::VSRp0) * 2; + addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXV)) + .addReg(Reg, getKillRegState(IsKilled)), + FrameIndex, Offset); + Offset += IsLittleEndian ? -16 : 16; + addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXV)) + .addReg(Reg + 1, getKillRegState(IsKilled)), + FrameIndex, Offset); + if (TwoPairs) { + Offset += IsLittleEndian ? -16 : 16; + addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXV)) + .addReg(Reg + 2, getKillRegState(IsKilled)), + FrameIndex, Offset); + Offset += IsLittleEndian ? -16 : 16; + addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXV)) + .addReg(Reg + 3, getKillRegState(IsKilled)), + FrameIndex, Offset); + } +} + /// 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. @@ -1254,21 +1290,8 @@ void PPCRegisterInfo::lowerOctWordSpilling(MachineBasicBlock::iterator II, Register SrcReg = MI.getOperand(0).getReg(); 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); - + spillRegPairs(MBB, II, DL, TII, SrcReg, FrameIndex, IsLittleEndian, IsKilled, + /* TwoPairs */ false); // Discard the original instruction. MBB.erase(II); } @@ -1302,6 +1325,8 @@ void PPCRegisterInfo::lowerACCSpilling(MachineBasicBlock::iterator II, bool IsKilled = MI.getOperand(0).isKill(); bool IsPrimed = PPC::ACCRCRegClass.contains(SrcReg); + Register Reg = + PPC::VSRp0 + (SrcReg - (IsPrimed ? PPC::ACC0 : PPC::UACC0)) * 2; bool IsLittleEndian = Subtarget.isLittleEndian(); emitAccSpillRestoreInfo(MBB, IsPrimed, false); @@ -1312,34 +1337,16 @@ void PPCRegisterInfo::lowerACCSpilling(MachineBasicBlock::iterator II, // adjust the offset of the store that is within the 64-byte stack slot. 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); - } else { - addFrameReference( - BuildMI(MBB, II, DL, TII.get(PPC::STXVP)) - .addReg(TargetRegisterInfo::getSubReg(SrcReg, PPC::sub_pair0), - getKillRegState(IsKilled)), - FrameIndex, IsLittleEndian ? 32 : 0); - addFrameReference( - BuildMI(MBB, II, DL, TII.get(PPC::STXVP)) - .addReg(TargetRegisterInfo::getSubReg(SrcReg, PPC::sub_pair1), - getKillRegState(IsKilled)), - FrameIndex, IsLittleEndian ? 0 : 32); + if (DisableAutoPairedVecSt) + spillRegPairs(MBB, II, DL, TII, Reg, FrameIndex, IsLittleEndian, IsKilled, + /* TwoPairs */ true); + else { + addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXVP)) + .addReg(Reg, getKillRegState(IsKilled)), + FrameIndex, IsLittleEndian ? 32 : 0); + addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXVP)) + .addReg(Reg + 1, getKillRegState(IsKilled)), + FrameIndex, IsLittleEndian ? 0 : 32); } if (IsPrimed && !IsKilled) BuildMI(MBB, II, DL, TII.get(PPC::XXMTACC), SrcReg).addReg(SrcReg);