From 1c450c3d7ec01d9daaf9f2651da93b01e7790ffd Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Tue, 15 Jun 2021 01:55:37 +0000 Subject: [PowerPC] Export 16 byte load-store instructions Export `lq`, `stq`, `lqarx` and `stqcx.` in preparation for implementing 16-byte lock free atomic operations on AIX. Add a new register class `g8prc` for these instructions, since these instructions require even-odd register pair. Reviewed By: nemanjai, jsji, #powerpc Differential Revision: https://reviews.llvm.org/D103010 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp | 61 +++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp') 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(); + 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(); + 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). -- cgit v1.1