#include "PPCRegisterInfo.h"
#include "PPCFrameInfo.h"
#include "PPCSubtarget.h"
+#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
+#include "llvm/Function.h"
#include "llvm/Type.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
-#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include <cstdlib>
using namespace llvm;
+// FIXME This disables some code that aligns the stack to a boundary
+// bigger than the default (16 bytes on Darwin) when there is a stack local
+// of greater alignment. This does not currently work, because the delta
+// between old and new stack pointers is added to offsets that reference
+// incoming parameters after the prolog is generated, and the code that
+// does that doesn't handle a variable delta. You don't want to do that
+// anyway; a better approach is to reserve another register that retains
+// to the incoming stack pointer, and reference parameters relative to that.
+#define ALIGN_STACK 0
+
// FIXME (64-bit): Eventually enable by default.
-cl::opt<bool> EnablePPCRS("enable-ppc-regscavenger",
- cl::init(false),
- cl::desc("enable PPC register scavenger"),
- cl::Hidden);
+cl::opt<bool> EnablePPC32RS("enable-ppc32-regscavenger",
+ cl::init(false),
+ cl::desc("Enable PPC32 register scavenger"),
+ cl::Hidden);
+cl::opt<bool> EnablePPC64RS("enable-ppc64-regscavenger",
+ cl::init(false),
+ cl::desc("Enable PPC64 register scavenger"),
+ cl::Hidden);
+#define EnableRegisterScavenging \
+ ((EnablePPC32RS && !Subtarget.isPPC64()) || \
+ (EnablePPC64RS && Subtarget.isPPC64()))
// FIXME (64-bit): Should be inlined.
bool
PPCRegisterInfo::requiresRegisterScavenging(const MachineFunction &) const {
- return EnablePPCRS;
+ return EnableRegisterScavenging;
}
/// getRegisterNumbering - Given the enum value for some register, e.g.
ImmToIdxMap[PPC::ADDI8] = PPC::ADD8; ImmToIdxMap[PPC::STD_32] = PPC::STDX_32;
}
-void PPCRegisterInfo::reMaterialize(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I,
- unsigned DestReg,
- const MachineInstr *Orig) const {
- MachineInstr *MI = Orig->clone();
- MI->getOperand(0).setReg(DestReg);
- MBB.insert(I, MI);
+/// getPointerRegClass - Return the register class to use to hold pointers.
+/// This is used for addressing modes.
+const TargetRegisterClass *PPCRegisterInfo::getPointerRegClass() const {
+ if (Subtarget.isPPC64())
+ return &PPC::G8RCRegClass;
+ else
+ return &PPC::GPRCRegClass;
}
const unsigned*
//
static bool needsFP(const MachineFunction &MF) {
const MachineFrameInfo *MFI = MF.getFrameInfo();
- return NoFramePointerElim || MFI->hasVarSizedObjects();
+ return NoFramePointerElim || MFI->hasVarSizedObjects() ||
+ (PerformTailCallOpt && MF.getInfo<PPCFunctionInfo>()->hasFastCall());
}
static bool spillsCR(const MachineFunction &MF) {
Reserved.set(PPC::R1);
Reserved.set(PPC::LR);
Reserved.set(PPC::LR8);
+ Reserved.set(PPC::RM);
// In Linux, r2 is reserved for the OS.
if (!Subtarget.isDarwin())
Reserved.set(PPC::R13);
Reserved.set(PPC::R31);
- if (!EnablePPCRS)
+ if (!EnableRegisterScavenging)
Reserved.set(PPC::R0); // FIXME (64-bit): Remove
Reserved.set(PPC::X0);
/// MustSaveLR - Return true if this function requires that we save the LR
/// register onto the stack in the prolog and restore it in the epilog of the
/// function.
-static bool MustSaveLR(const MachineFunction &MF) {
+static bool MustSaveLR(const MachineFunction &MF, unsigned LR) {
const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>();
- // We need an save/restore of LR if there is any use/def of LR explicitly, or
- // if there is some use of the LR stack slot (e.g. for builtin_return_address.
- return MFI->usesLR() || MFI->isLRStoreRequired() ||
- // FIXME: Anything that has a call should clobber the LR register,
- // isn't this redundant??
- MF.getFrameInfo()->hasCalls();
+ // We need a save/restore of LR if there is any def of LR (which is
+ // defined by calls, including the PIC setup sequence), or if there is
+ // some use of the LR stack slot (e.g. for builtin_return_address).
+ // (LR comes in 32 and 64 bit versions.)
+ MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR);
+ return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired();
}
+
+
void PPCRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
+ if (PerformTailCallOpt && I->getOpcode() == PPC::ADJCALLSTACKUP) {
+ // Add (actually subtract) back the amount the callee popped on return.
+ if (int CalleeAmt = I->getOperand(1).getImm()) {
+ bool is64Bit = Subtarget.isPPC64();
+ CalleeAmt *= -1;
+ unsigned StackReg = is64Bit ? PPC::X1 : PPC::R1;
+ unsigned TmpReg = is64Bit ? PPC::X0 : PPC::R0;
+ unsigned ADDIInstr = is64Bit ? PPC::ADDI8 : PPC::ADDI;
+ unsigned ADDInstr = is64Bit ? PPC::ADD8 : PPC::ADD4;
+ unsigned LISInstr = is64Bit ? PPC::LIS8 : PPC::LIS;
+ unsigned ORIInstr = is64Bit ? PPC::ORI8 : PPC::ORI;
+
+ if (isInt16(CalleeAmt)) {
+ BuildMI(MBB, I, TII.get(ADDIInstr), StackReg).addReg(StackReg).
+ addImm(CalleeAmt);
+ } else {
+ MachineBasicBlock::iterator MBBI = I;
+ BuildMI(MBB, MBBI, TII.get(LISInstr), TmpReg)
+ .addImm(CalleeAmt >> 16);
+ BuildMI(MBB, MBBI, TII.get(ORIInstr), TmpReg)
+ .addReg(TmpReg, false, false, true)
+ .addImm(CalleeAmt & 0xFFFF);
+ BuildMI(MBB, MBBI, TII.get(ADDInstr))
+ .addReg(StackReg)
+ .addReg(StackReg)
+ .addReg(TmpReg);
+ }
+ }
+ }
// Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
MBB.erase(I);
}
// FIXME (64-bit): Use "findScratchRegister"
unsigned Reg;
- if (EnablePPCRS)
+ if (EnableRegisterScavenging)
Reg = findScratchRegister(II, RS, RC, SPAdj);
else
Reg = PPC::R0;
.addReg(PPC::R31)
.addImm(FrameSize);
} else if (LP64) {
- if (EnablePPCRS) // FIXME (64-bit): Use "true" version.
+ if (EnableRegisterScavenging) // FIXME (64-bit): Use "true" part.
BuildMI(MBB, II, TII.get(PPC::LD), Reg)
- .addImm(0)
- .addReg(PPC::X1);
+ .addImm(0)
+ .addReg(PPC::X1);
else
BuildMI(MBB, II, TII.get(PPC::LD), PPC::X0)
- .addImm(0)
- .addReg(PPC::X1);
+ .addImm(0)
+ .addReg(PPC::X1);
} else {
BuildMI(MBB, II, TII.get(PPC::LWZ), Reg)
.addImm(0)
// Grow the stack and update the stack pointer link, then determine the
// address of new allocated space.
if (LP64) {
- if (EnablePPCRS) // FIXME (64-bit): Use "true" version.
+ if (EnableRegisterScavenging) // FIXME (64-bit): Use "true" part.
BuildMI(MBB, II, TII.get(PPC::STDUX))
- .addReg(Reg, false, false, true)
- .addReg(PPC::X1)
- .addReg(MI.getOperand(1).getReg());
+ .addReg(Reg, false, false, true)
+ .addReg(PPC::X1)
+ .addReg(MI.getOperand(1).getReg());
else
BuildMI(MBB, II, TII.get(PPC::STDUX))
- .addReg(PPC::X0, false, false, true)
- .addReg(PPC::X1)
- .addReg(MI.getOperand(1).getReg());
+ .addReg(PPC::X0, false, false, true)
+ .addReg(PPC::X1)
+ .addReg(MI.getOperand(1).getReg());
if (!MI.getOperand(1).isKill())
BuildMI(MBB, II, TII.get(PPC::ADDI8), MI.getOperand(0).getReg())
- .addReg(PPC::X1)
- .addImm(maxCallFrameSize);
+ .addReg(PPC::X1)
+ .addImm(maxCallFrameSize);
else
// Implicitly kill the register.
BuildMI(MBB, II, TII.get(PPC::ADDI8), MI.getOperand(0).getReg())
- .addReg(PPC::X1)
- .addImm(maxCallFrameSize)
- .addReg(MI.getOperand(1).getReg(), false, true, true);
+ .addReg(PPC::X1)
+ .addImm(maxCallFrameSize)
+ .addReg(MI.getOperand(1).getReg(), false, true, true);
} else {
BuildMI(MBB, II, TII.get(PPC::STWUX))
.addReg(Reg, false, false, true)
if (!MI.getOperand(1).isKill())
BuildMI(MBB, II, TII.get(PPC::ADDI), MI.getOperand(0).getReg())
- .addReg(PPC::R1)
- .addImm(maxCallFrameSize);
+ .addReg(PPC::R1)
+ .addImm(maxCallFrameSize);
else
// Implicitly kill the register.
BuildMI(MBB, II, TII.get(PPC::ADDI), MI.getOperand(0).getReg())
- .addReg(PPC::R1)
- .addImm(maxCallFrameSize)
- .addReg(MI.getOperand(1).getReg(), false, true, true);
+ .addReg(PPC::R1)
+ .addImm(maxCallFrameSize)
+ .addReg(MI.getOperand(1).getReg(), false, true, true);
}
// Discard the DYNALLOC instruction.
// Find out which operand is the frame index.
unsigned FIOperandNo = 0;
- while (!MI.getOperand(FIOperandNo).isFrameIndex()) {
+ while (!MI.getOperand(FIOperandNo).isFI()) {
++FIOperandNo;
assert(FIOperandNo != MI.getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
}
// Special case for pseudo-op SPILL_CR.
- if (EnablePPCRS) // FIXME (64-bit): Enable by default
+ if (EnableRegisterScavenging) // FIXME (64-bit): Enable by default.
if (OpC == PPC::SPILL_CR) {
lowerCRSpilling(II, FrameIndex, SPAdj, RS);
return;
// FIXME (64-bit): Use "findScratchRegister".
unsigned SReg;
- if (EnablePPCRS)
+ if (EnableRegisterScavenging)
SReg = findScratchRegister(II, RS, &PPC::GPRCRegClass, SPAdj);
else
SReg = PPC::R0;
// If we are a leaf function, and use up to 224 bytes of stack space,
// don't have a frame pointer, calls, or dynamic alloca then we do not need
// to adjust the stack pointer (we fit in the Red Zone).
- if (FrameSize <= 224 && // Fits in red zone.
- !MFI->hasVarSizedObjects() && // No dynamic alloca.
- !MFI->hasCalls() && // No calls.
- MaxAlign <= TargetAlign) { // No special alignment.
+ if (!DisableRedZone &&
+ FrameSize <= 224 && // Fits in red zone.
+ !MFI->hasVarSizedObjects() && // No dynamic alloca.
+ !MFI->hasCalls() && // No calls.
+ (!ALIGN_STACK || MaxAlign <= TargetAlign)) { // No special alignment.
// No need for frame
MFI->setStackSize(0);
return;
// Save and clear the LR state.
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
unsigned LR = getRARegister();
- FI->setUsesLR(MF.getRegInfo().isPhysRegUsed(LR));
+ FI->setMustSaveLR(MustSaveLR(MF, LR));
MF.getRegInfo().setPhysRegUnused(LR);
// Save R31 if necessary
FI->setFramePointerSaveIndex(FPSI);
}
+ // Reserve stack space to move the linkage area to in case of a tail call.
+ int TCSPDelta = 0;
+ if (PerformTailCallOpt && (TCSPDelta=FI->getTailCallSPDelta()) < 0) {
+ int AddFPOffsetAmount = IsELF32_ABI ? -4 : 0;
+ MF.getFrameInfo()->CreateFixedObject( -1 * TCSPDelta,
+ AddFPOffsetAmount + TCSPDelta);
+ }
// Reserve a slot closest to SP or frame pointer if we have a dynalloc or
// a large stack, which will require scavenging a register to materialize a
// large offset.
// FIXME: doesn't detect whether or not we need to spill vXX, which requires
// r0 for now.
- if (EnablePPCRS) // FIXME (64-bit): Enable.
+ if (EnableRegisterScavenging) // FIXME (64-bit): Enable.
if (needsFP(MF) || spillsCR(MF)) {
const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;
const TargetRegisterClass *G8RC = &PPC::G8RCRegClass;
const TargetRegisterClass *RC = IsPPC64 ? G8RC : GPRC;
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
- RC->getAlignment()));
+ RC->getAlignment()));
}
}
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+ bool needsFrameMoves = (MMI && MMI->hasDebugInfo()) ||
+ !MF.getFunction()->doesNotThrow() ||
+ UnwindTablesMandatory;
// Prepare for frame info.
unsigned FrameLabelId = 0;
bool IsPPC64 = Subtarget.isPPC64();
// Get operating system
bool IsMachoABI = Subtarget.isMachoABI();
- // Check if the link register (LR) has been used.
- bool UsesLR = MustSaveLR(MF);
+ // Check if the link register (LR) must be saved.
+ PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
+ bool MustSaveLR = FI->mustSaveLR();
// Do we have a frame pointer for this function?
bool HasFP = hasFP(MF) && FrameSize;
int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, IsMachoABI);
if (IsPPC64) {
- if (UsesLR)
+ if (MustSaveLR)
BuildMI(MBB, MBBI, TII.get(PPC::MFLR8), PPC::X0);
if (HasFP)
.addImm(FPOffset/4)
.addReg(PPC::X1);
- if (UsesLR)
+ if (MustSaveLR)
BuildMI(MBB, MBBI, TII.get(PPC::STD))
.addReg(PPC::X0)
.addImm(LROffset / 4)
.addReg(PPC::X1);
} else {
- if (UsesLR)
+ if (MustSaveLR)
BuildMI(MBB, MBBI, TII.get(PPC::MFLR), PPC::R0);
if (HasFP)
.addImm(FPOffset)
.addReg(PPC::R1);
- if (UsesLR)
+ if (MustSaveLR)
BuildMI(MBB, MBBI, TII.get(PPC::STW))
.addReg(PPC::R0)
.addImm(LROffset)
unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
unsigned MaxAlign = MFI->getMaxAlignment();
- if (MMI && MMI->needsFrameInfo()) {
+ if (needsFrameMoves) {
// Mark effective beginning of when frame pointer becomes valid.
FrameLabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, TII.get(PPC::LABEL)).addImm(FrameLabelId).addImm(0);
+ BuildMI(MBB, MBBI, TII.get(PPC::DBG_LABEL)).addImm(FrameLabelId);
}
// Adjust stack pointer: r1 += NegFrameSize.
// If there is a preferred stack alignment, align R1 now
if (!IsPPC64) {
// PPC32.
- if (MaxAlign > TargetAlign) {
+ if (ALIGN_STACK && MaxAlign > TargetAlign) {
assert(isPowerOf2_32(MaxAlign)&&isInt16(MaxAlign)&&"Invalid alignment!");
assert(isInt16(NegFrameSize) && "Unhandled stack size and alignment!");
.addReg(PPC::R0);
}
} else { // PPC64.
- if (MaxAlign > TargetAlign) {
+ if (ALIGN_STACK && MaxAlign > TargetAlign) {
assert(isPowerOf2_32(MaxAlign)&&isInt16(MaxAlign)&&"Invalid alignment!");
assert(isInt16(NegFrameSize) && "Unhandled stack size and alignment!");
}
}
- if (MMI && MMI->needsFrameInfo()) {
+ if (needsFrameMoves) {
std::vector<MachineMove> &Moves = MMI->getFrameMoves();
if (NegFrameSize) {
for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx());
unsigned Reg = CSI[I].getReg();
- if (Reg == PPC::LR || Reg == PPC::LR8) continue;
+ if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue;
MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
MachineLocation CSSrc(Reg);
Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc));
// Mark effective beginning of when frame pointer is ready.
unsigned ReadyLabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, TII.get(PPC::LABEL)).addImm(ReadyLabelId).addImm(0);
+ BuildMI(MBB, MBBI, TII.get(PPC::DBG_LABEL)).addImm(ReadyLabelId);
MachineLocation FPDst(HasFP ? (IsPPC64 ? PPC::X31 : PPC::R31) :
(IsPPC64 ? PPC::X1 : PPC::R1));
void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = prior(MBB.end());
- assert(MBBI->getOpcode() == PPC::BLR &&
+ unsigned RetOpcode = MBBI->getOpcode();
+
+ assert( (RetOpcode == PPC::BLR ||
+ RetOpcode == PPC::TCRETURNri ||
+ RetOpcode == PPC::TCRETURNdi ||
+ RetOpcode == PPC::TCRETURNai ||
+ RetOpcode == PPC::TCRETURNri8 ||
+ RetOpcode == PPC::TCRETURNdi8 ||
+ RetOpcode == PPC::TCRETURNai8) &&
"Can only insert epilog into returning blocks");
// Get alignment info so we know how to restore r1
unsigned MaxAlign = MFI->getMaxAlignment();
// Get the number of bytes allocated from the FrameInfo.
- unsigned FrameSize = MFI->getStackSize();
+ int FrameSize = MFI->getStackSize();
// Get processor type.
bool IsPPC64 = Subtarget.isPPC64();
// Get operating system
bool IsMachoABI = Subtarget.isMachoABI();
- // Check if the link register (LR) has been used.
- bool UsesLR = MustSaveLR(MF);
+ // Check if the link register (LR) has been saved.
+ PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
+ bool MustSaveLR = FI->mustSaveLR();
// Do we have a frame pointer for this function?
bool HasFP = hasFP(MF) && FrameSize;
int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64, IsMachoABI);
int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, IsMachoABI);
+ bool UsesTCRet = RetOpcode == PPC::TCRETURNri ||
+ RetOpcode == PPC::TCRETURNdi ||
+ RetOpcode == PPC::TCRETURNai ||
+ RetOpcode == PPC::TCRETURNri8 ||
+ RetOpcode == PPC::TCRETURNdi8 ||
+ RetOpcode == PPC::TCRETURNai8;
+
+ if (UsesTCRet) {
+ int MaxTCRetDelta = FI->getTailCallSPDelta();
+ MachineOperand &StackAdjust = MBBI->getOperand(1);
+ assert(StackAdjust.isImm() && "Expecting immediate value.");
+ // Adjust stack pointer.
+ int StackAdj = StackAdjust.getImm();
+ int Delta = StackAdj - MaxTCRetDelta;
+ assert((Delta >= 0) && "Delta must be positive");
+ if (MaxTCRetDelta>0)
+ FrameSize += (StackAdj +Delta);
+ else
+ FrameSize += StackAdj;
+ }
+
if (FrameSize) {
// The loaded (or persistent) stack pointer value is offset by the 'stwu'
// on entry to the function. Add this offset back now.
- if (!Subtarget.isPPC64()) {
- if (isInt16(FrameSize) && TargetAlign >= MaxAlign &&
- !MFI->hasVarSizedObjects()) {
- BuildMI(MBB, MBBI, TII.get(PPC::ADDI), PPC::R1)
- .addReg(PPC::R1).addImm(FrameSize);
+ if (!IsPPC64) {
+ // If this function contained a fastcc call and PerformTailCallOpt is
+ // enabled (=> hasFastCall()==true) the fastcc call might contain a tail
+ // call which invalidates the stack pointer value in SP(0). So we use the
+ // value of R31 in this case.
+ if (FI->hasFastCall() && isInt16(FrameSize)) {
+ assert(hasFP(MF) && "Expecting a valid the frame pointer.");
+ BuildMI(MBB, MBBI, TII.get(PPC::ADDI), PPC::R1)
+ .addReg(PPC::R31).addImm(FrameSize);
+ } else if(FI->hasFastCall()) {
+ BuildMI(MBB, MBBI, TII.get(PPC::LIS), PPC::R0)
+ .addImm(FrameSize >> 16);
+ BuildMI(MBB, MBBI, TII.get(PPC::ORI), PPC::R0)
+ .addReg(PPC::R0, false, false, true)
+ .addImm(FrameSize & 0xFFFF);
+ BuildMI(MBB, MBBI, TII.get(PPC::ADD4))
+ .addReg(PPC::R1)
+ .addReg(PPC::R31)
+ .addReg(PPC::R0);
+ } else if (isInt16(FrameSize) &&
+ (!ALIGN_STACK || TargetAlign >= MaxAlign) &&
+ !MFI->hasVarSizedObjects()) {
+ BuildMI(MBB, MBBI, TII.get(PPC::ADDI), PPC::R1)
+ .addReg(PPC::R1).addImm(FrameSize);
} else {
BuildMI(MBB, MBBI, TII.get(PPC::LWZ),PPC::R1).addImm(0).addReg(PPC::R1);
}
} else {
- if (isInt16(FrameSize) && TargetAlign >= MaxAlign &&
+ if (FI->hasFastCall() && isInt16(FrameSize)) {
+ assert(hasFP(MF) && "Expecting a valid the frame pointer.");
+ BuildMI(MBB, MBBI, TII.get(PPC::ADDI8), PPC::X1)
+ .addReg(PPC::X31).addImm(FrameSize);
+ } else if(FI->hasFastCall()) {
+ BuildMI(MBB, MBBI, TII.get(PPC::LIS8), PPC::X0)
+ .addImm(FrameSize >> 16);
+ BuildMI(MBB, MBBI, TII.get(PPC::ORI8), PPC::X0)
+ .addReg(PPC::X0, false, false, true)
+ .addImm(FrameSize & 0xFFFF);
+ BuildMI(MBB, MBBI, TII.get(PPC::ADD8))
+ .addReg(PPC::X1)
+ .addReg(PPC::X31)
+ .addReg(PPC::X0);
+ } else if (isInt16(FrameSize) && TargetAlign >= MaxAlign &&
!MFI->hasVarSizedObjects()) {
BuildMI(MBB, MBBI, TII.get(PPC::ADDI8), PPC::X1)
.addReg(PPC::X1).addImm(FrameSize);
}
if (IsPPC64) {
- if (UsesLR)
+ if (MustSaveLR)
BuildMI(MBB, MBBI, TII.get(PPC::LD), PPC::X0)
.addImm(LROffset/4).addReg(PPC::X1);
BuildMI(MBB, MBBI, TII.get(PPC::LD), PPC::X31)
.addImm(FPOffset/4).addReg(PPC::X1);
- if (UsesLR)
+ if (MustSaveLR)
BuildMI(MBB, MBBI, TII.get(PPC::MTLR8)).addReg(PPC::X0);
} else {
- if (UsesLR)
+ if (MustSaveLR)
BuildMI(MBB, MBBI, TII.get(PPC::LWZ), PPC::R0)
.addImm(LROffset).addReg(PPC::R1);
BuildMI(MBB, MBBI, TII.get(PPC::LWZ), PPC::R31)
.addImm(FPOffset).addReg(PPC::R1);
- if (UsesLR)
+ if (MustSaveLR)
BuildMI(MBB, MBBI, TII.get(PPC::MTLR)).addReg(PPC::R0);
}
+
+ // Callee pop calling convention. Pop parameter/linkage area. Used for tail
+ // call optimization
+ if (PerformTailCallOpt && RetOpcode == PPC::BLR &&
+ MF.getFunction()->getCallingConv() == CallingConv::Fast) {
+ PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
+ unsigned CallerAllocatedAmt = FI->getMinReservedArea();
+ unsigned StackReg = IsPPC64 ? PPC::X1 : PPC::R1;
+ unsigned FPReg = IsPPC64 ? PPC::X31 : PPC::R31;
+ unsigned TmpReg = IsPPC64 ? PPC::X0 : PPC::R0;
+ unsigned ADDIInstr = IsPPC64 ? PPC::ADDI8 : PPC::ADDI;
+ unsigned ADDInstr = IsPPC64 ? PPC::ADD8 : PPC::ADD4;
+ unsigned LISInstr = IsPPC64 ? PPC::LIS8 : PPC::LIS;
+ unsigned ORIInstr = IsPPC64 ? PPC::ORI8 : PPC::ORI;
+
+ if (CallerAllocatedAmt && isInt16(CallerAllocatedAmt)) {
+ BuildMI(MBB, MBBI, TII.get(ADDIInstr), StackReg)
+ .addReg(StackReg).addImm(CallerAllocatedAmt);
+ } else {
+ BuildMI(MBB, MBBI, TII.get(LISInstr), TmpReg)
+ .addImm(CallerAllocatedAmt >> 16);
+ BuildMI(MBB, MBBI, TII.get(ORIInstr), TmpReg)
+ .addReg(TmpReg, false, false, true)
+ .addImm(CallerAllocatedAmt & 0xFFFF);
+ BuildMI(MBB, MBBI, TII.get(ADDInstr))
+ .addReg(StackReg)
+ .addReg(FPReg)
+ .addReg(TmpReg);
+ }
+ } else if (RetOpcode == PPC::TCRETURNdi) {
+ MBBI = prior(MBB.end());
+ MachineOperand &JumpTarget = MBBI->getOperand(0);
+ BuildMI(MBB, MBBI, TII.get(PPC::TAILB)).
+ addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
+ } else if (RetOpcode == PPC::TCRETURNri) {
+ MBBI = prior(MBB.end());
+ MachineOperand &JumpTarget = MBBI->getOperand(0);
+ assert(JumpTarget.isReg() && "Expecting register operand.");
+ BuildMI(MBB, MBBI, TII.get(PPC::TAILBCTR));
+ } else if (RetOpcode == PPC::TCRETURNai) {
+ MBBI = prior(MBB.end());
+ MachineOperand &JumpTarget = MBBI->getOperand(0);
+ BuildMI(MBB, MBBI, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm());
+ } else if (RetOpcode == PPC::TCRETURNdi8) {
+ MBBI = prior(MBB.end());
+ MachineOperand &JumpTarget = MBBI->getOperand(0);
+ BuildMI(MBB, MBBI, TII.get(PPC::TAILB8)).
+ addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
+ } else if (RetOpcode == PPC::TCRETURNri8) {
+ MBBI = prior(MBB.end());
+ MachineOperand &JumpTarget = MBBI->getOperand(0);
+ assert(JumpTarget.isReg() && "Expecting register operand.");
+ BuildMI(MBB, MBBI, TII.get(PPC::TAILBCTR8));
+ } else if (RetOpcode == PPC::TCRETURNai8) {
+ MBBI = prior(MBB.end());
+ MachineOperand &JumpTarget = MBBI->getOperand(0);
+ BuildMI(MBB, MBBI, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm());
+ }
}
unsigned PPCRegisterInfo::getRARegister() const {