aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
diff options
context:
space:
mode:
authorKai Luo <lkail@cn.ibm.com>2021-06-15 01:55:37 +0000
committerKai Luo <lkail@cn.ibm.com>2021-06-15 01:56:10 +0000
commit1c450c3d7ec01d9daaf9f2651da93b01e7790ffd (patch)
treebcf0ce27bb38de8a5eb5ec0467cf02ff5fb713a7 /llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
parentb8919fb0eac15d13c5f56d3d30ce378a588dd78c (diff)
downloadllvm-1c450c3d7ec01d9daaf9f2651da93b01e7790ffd.zip
llvm-1c450c3d7ec01d9daaf9f2651da93b01e7790ffd.tar.gz
llvm-1c450c3d7ec01d9daaf9f2651da93b01e7790ffd.tar.bz2
[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
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp')
-rw-r--r--llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp61
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).