diff options
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp index 260c5f3..8adef37 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -1146,6 +1146,59 @@ void PPCRegisterInfo::lowerACCRestore(MachineBasicBlock::iterator II, MBB.erase(II); } +/// lowerQuadwordSpilling - Generate code to spill paired general register. +void PPCRegisterInfo::lowerQuadwordSpilling(MachineBasicBlock::iterator II, + unsigned FrameIndex) const { + MachineInstr &MI = *II; + MachineBasicBlock &MBB = *MI.getParent(); + MachineFunction &MF = *MBB.getParent(); + const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>(); + const TargetInstrInfo &TII = *Subtarget.getInstrInfo(); + DebugLoc DL = MI.getDebugLoc(); + + Register SrcReg = MI.getOperand(0).getReg(); + bool IsKilled = MI.getOperand(0).isKill(); + + Register Reg = PPC::X0 + (SrcReg - PPC::G8p0) * 2; + bool IsLittleEndian = Subtarget.isLittleEndian(); + + addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STD)) + .addReg(Reg, getKillRegState(IsKilled)), + FrameIndex, IsLittleEndian ? 8 : 0); + addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STD)) + .addReg(Reg + 1, getKillRegState(IsKilled)), + FrameIndex, IsLittleEndian ? 0 : 8); + + // Discard the pseudo instruction. + MBB.erase(II); +} + +/// lowerQuadwordRestore - Generate code to restore paired general register. +void PPCRegisterInfo::lowerQuadwordRestore(MachineBasicBlock::iterator II, + unsigned FrameIndex) const { + MachineInstr &MI = *II; + MachineBasicBlock &MBB = *MI.getParent(); + MachineFunction &MF = *MBB.getParent(); + const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>(); + const TargetInstrInfo &TII = *Subtarget.getInstrInfo(); + DebugLoc DL = MI.getDebugLoc(); + + Register DestReg = MI.getOperand(0).getReg(); + assert(MI.definesRegister(DestReg) && + "RESTORE_QUADWORD does not define its destination"); + + Register Reg = PPC::X0 + (DestReg - PPC::G8p0) * 2; + bool IsLittleEndian = Subtarget.isLittleEndian(); + + addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::LD), Reg), FrameIndex, + IsLittleEndian ? 8 : 0); + addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::LD), Reg + 1), FrameIndex, + IsLittleEndian ? 0 : 8); + + // Discard the pseudo instruction. + MBB.erase(II); +} + bool PPCRegisterInfo::hasReservedSpillSlot(const MachineFunction &MF, Register Reg, int &FrameIdx) const { // For the nonvolatile condition registers (CR2, CR3, CR4) return true to @@ -1182,12 +1235,14 @@ static unsigned offsetMinAlignForOpcode(unsigned OpC) { case PPC::LXSSP: case PPC::STXSD: case PPC::STXSSP: + case PPC::STQ: return 4; case PPC::EVLDD: case PPC::EVSTDD: return 8; case PPC::LXV: case PPC::STXV: + case PPC::LQ: return 16; } } @@ -1283,6 +1338,12 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, } else if (OpC == PPC::RESTORE_ACC || OpC == PPC::RESTORE_UACC) { lowerACCRestore(II, FrameIndex); return; + } else if (OpC == PPC::SPILL_QUADWORD) { + lowerQuadwordSpilling(II, FrameIndex); + return; + } else if (OpC == PPC::RESTORE_QUADWORD) { + lowerQuadwordRestore(II, FrameIndex); + return; } // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP). |