[PowerPC] Preparatory refactoring for making prologue and epilogue

safe on PPC32 SVR4 ABI

[Patch and following text by Mark Minich; committing on his behalf.]

There are FIXME's in PowerPC/PPCFrameLowering.cpp, method
PPCFrameLowering::emitPrologue() related to "negative offsets of R1"
on PPC32 SVR4. They're true, but the real issue is that on PPC32 SVR4
(and any ABI without a Red Zone), no spills may be made until after
the stackframe is claimed, which also includes the LR spill which is
at a positive offset. The same problem exists in emitEpilogue(),
though there's no FIXME for it. I intend to fix this issue, making
LLVM-compiled code finally safe for use on SVR4/EABI/e500 32-bit
platforms (including in particular, OS-free embedded systems & kernel
code, where interrupts may share the same stack as user code).

In preparation for making these changes, to make the diffs for the
functional changes less cluttered, I am providing the non-functional
refactorings in two stages:

Stage 1 does some minor fluffy refactorings to pull multiple method
calls up into a single bool, creating named bools for repeated uses of
obscure logic, moving some code up earlier because either stage 2 or
my final version will require it earlier, and rewording/adding some
comments. My stage 1 changes can be characterized as primarily fluffy
cleanup, the purpose of which may be unclear until the stage 2 or
final changes are made.

My stage 2 refactorings combine the separate PPC32 & PPC64 logic,
which is currently performed by largely duplicate code, into a single
flow, with the differences handled by a group of constants initialized
early in the methods.

This submission is for my stage 1 changes. There should be no
functional changes whatsoever; this is a pure refactoring.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188573 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Schmidt 2013-08-16 20:05:04 +00:00
parent b0f7929885
commit 9bb6c81683

View File

@ -204,10 +204,9 @@ unsigned PPCFrameLowering::determineFrameLayout(MachineFunction &MF,
unsigned FrameSize = unsigned FrameSize =
UseEstimate ? MFI->estimateStackSize(MF) : MFI->getStackSize(); UseEstimate ? MFI->estimateStackSize(MF) : MFI->getStackSize();
// Get the alignments provided by the target, and the maximum alignment // Get stack alignments. The frame must be aligned to the greatest of these:
// (if any) of the fixed frame objects. unsigned TargetAlign = getStackAlignment(); // alignment required per the ABI
unsigned TargetAlign = getStackAlignment(); unsigned MaxAlign = MFI->getMaxAlignment(); // algmt required by data in frame
unsigned MaxAlign = MFI->getMaxAlignment();
unsigned AlignMask = std::max(MaxAlign, TargetAlign) - 1; unsigned AlignMask = std::max(MaxAlign, TargetAlign) - 1;
const PPCRegisterInfo *RegInfo = const PPCRegisterInfo *RegInfo =
@ -346,12 +345,20 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
bool needsFrameMoves = MMI.hasDebugInfo() || bool needsFrameMoves = MMI.hasDebugInfo() ||
MF.getFunction()->needsUnwindTableEntry(); MF.getFunction()->needsUnwindTableEntry();
// Get processor type.
bool isPPC64 = Subtarget.isPPC64();
// Get the ABI.
bool isDarwinABI = Subtarget.isDarwinABI();
bool isSVR4ABI = Subtarget.isSVR4ABI();
assert((isDarwinABI || isSVR4ABI) &&
"Currently only Darwin and SVR4 ABIs are supported for PowerPC.");
// Prepare for frame info. // Prepare for frame info.
MCSymbol *FrameLabel = 0; MCSymbol *FrameLabel = 0;
// Scan the prolog, looking for an UPDATE_VRSAVE instruction. If we find it, // Scan the prolog, looking for an UPDATE_VRSAVE instruction. If we find it,
// process it. // process it.
if (!Subtarget.isSVR4ABI()) if (!isSVR4ABI)
for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) { for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) {
if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) { if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) {
HandleVRSaveUpdate(MBBI, TII); HandleVRSaveUpdate(MBBI, TII);
@ -371,10 +378,6 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
if (MFI->isFrameAddressTaken()) if (MFI->isFrameAddressTaken())
replaceFPWithRealFP(MF); replaceFPWithRealFP(MF);
// Get processor type.
bool isPPC64 = Subtarget.isPPC64();
// Get operating system
bool isDarwinABI = Subtarget.isDarwinABI();
// Check if the link register (LR) must be saved. // Check if the link register (LR) must be saved.
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
bool MustSaveLR = FI->mustSaveLR(); bool MustSaveLR = FI->mustSaveLR();
@ -383,11 +386,18 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
bool HasFP = hasFP(MF); bool HasFP = hasFP(MF);
bool HasBP = RegInfo->hasBasePointer(MF); bool HasBP = RegInfo->hasBasePointer(MF);
// Regarding this assert: Even though LR is saved in the caller's frame (i.e.,
// LROffset is positive), that slot is callee-owned. Because PPC32 SVR4 has no
// Red Zone, an asynchronous event (a form of "callee") could claim a frame &
// overwrite it, so PPC32 SVR4 must claim at least a minimal frame to save LR.
assert((isPPC64 || !isSVR4ABI || !(!FrameSize && (MustSaveLR || HasFP))) &&
"FrameSize must be >0 to save/restore the FP or LR for 32-bit SVR4.");
int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI); int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI);
int FPOffset = 0; int FPOffset = 0;
if (HasFP) { if (HasFP) {
if (Subtarget.isSVR4ABI()) { if (isSVR4ABI) {
MachineFrameInfo *FFI = MF.getFrameInfo(); MachineFrameInfo *FFI = MF.getFrameInfo();
int FPIndex = FI->getFramePointerSaveIndex(); int FPIndex = FI->getFramePointerSaveIndex();
assert(FPIndex && "No Frame Pointer Save Slot!"); assert(FPIndex && "No Frame Pointer Save Slot!");
@ -399,7 +409,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
int BPOffset = 0; int BPOffset = 0;
if (HasBP) { if (HasBP) {
if (Subtarget.isSVR4ABI()) { if (isSVR4ABI) {
MachineFrameInfo *FFI = MF.getFrameInfo(); MachineFrameInfo *FFI = MF.getFrameInfo();
int BPIndex = FI->getBasePointerSaveIndex(); int BPIndex = FI->getBasePointerSaveIndex();
assert(BPIndex && "No Base Pointer Save Slot!"); assert(BPIndex && "No Base Pointer Save Slot!");
@ -410,6 +420,16 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
} }
} }
// Get stack alignments.
unsigned MaxAlign = MFI->getMaxAlignment();
if (HasBP && MaxAlign > 1)
assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) &&
"Invalid alignment!");
// Frames of 32KB & larger require special handling because they cannot be
// indexed into with a simple STDU/STWU/STD/STW immediate offset operand.
bool isLargeFrame = !isInt<16>(NegFrameSize);
if (isPPC64) { if (isPPC64) {
if (MustSaveLR) if (MustSaveLR)
BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR8), PPC::X0); BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR8), PPC::X0);
@ -444,21 +464,19 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
.addReg(PPC::X12, getKillRegState(true)) .addReg(PPC::X12, getKillRegState(true))
.addImm(8) .addImm(8)
.addReg(PPC::X1); .addReg(PPC::X1);
} else { } else { // PPC32...
if (MustSaveLR) if (MustSaveLR)
BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR), PPC::R0); BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR), PPC::R0);
if (HasFP) if (HasFP)
// FIXME: On PPC32 SVR4, FPOffset is negative and access to negative // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
// offsets of R1 is not allowed.
BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) BuildMI(MBB, MBBI, dl, TII.get(PPC::STW))
.addReg(PPC::R31) .addReg(PPC::R31)
.addImm(FPOffset) .addImm(FPOffset)
.addReg(PPC::R1); .addReg(PPC::R1);
if (HasBP) if (HasBP)
// FIXME: On PPC32 SVR4, FPOffset is negative and access to negative // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
// offsets of R1 is not allowed.
BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) BuildMI(MBB, MBBI, dl, TII.get(PPC::STW))
.addReg(PPC::R30) .addReg(PPC::R30)
.addImm(BPOffset) .addImm(BPOffset)
@ -468,23 +486,19 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
"Prologue CR saving supported only in 64-bit mode"); "Prologue CR saving supported only in 64-bit mode");
if (MustSaveLR) if (MustSaveLR)
// FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) BuildMI(MBB, MBBI, dl, TII.get(PPC::STW))
.addReg(PPC::R0) .addReg(PPC::R0)
.addImm(LROffset) .addImm(LROffset)
.addReg(PPC::R1); .addReg(PPC::R1);
} }
// Skip if a leaf routine. // Skip the rest if this is a leaf function & all spills fit in the Red Zone.
if (!FrameSize) return; if (!FrameSize) return;
// Get stack alignments.
unsigned MaxAlign = MFI->getMaxAlignment();
// Adjust stack pointer: r1 += NegFrameSize. // Adjust stack pointer: r1 += NegFrameSize.
// If there is a preferred stack alignment, align R1 now // If there is a preferred stack alignment, align R1 now
if (!isPPC64) { if (!isPPC64) { // PPC32...
// PPC32.
if (HasBP) { if (HasBP) {
// Save a copy of r1 as the base pointer. // Save a copy of r1 as the base pointer.
BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), PPC::R30) BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), PPC::R30)
@ -493,15 +507,12 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
} }
if (HasBP && MaxAlign > 1) { if (HasBP && MaxAlign > 1) {
assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) &&
"Invalid alignment!");
BuildMI(MBB, MBBI, dl, TII.get(PPC::RLWINM), PPC::R0) BuildMI(MBB, MBBI, dl, TII.get(PPC::RLWINM), PPC::R0)
.addReg(PPC::R1) .addReg(PPC::R1)
.addImm(0) .addImm(0)
.addImm(32 - Log2_32(MaxAlign)) .addImm(32 - Log2_32(MaxAlign))
.addImm(31); .addImm(31);
if (isInt<16>(NegFrameSize)) { if (!isLargeFrame) {
BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC), PPC::R0) BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC), PPC::R0)
.addReg(PPC::R0, RegState::Kill) .addReg(PPC::R0, RegState::Kill)
.addImm(NegFrameSize); .addImm(NegFrameSize);
@ -519,11 +530,13 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
.addReg(PPC::R1, RegState::Kill) .addReg(PPC::R1, RegState::Kill)
.addReg(PPC::R1) .addReg(PPC::R1)
.addReg(PPC::R0); .addReg(PPC::R0);
} else if (isInt<16>(NegFrameSize)) {
} else if (!isLargeFrame) {
BuildMI(MBB, MBBI, dl, TII.get(PPC::STWU), PPC::R1) BuildMI(MBB, MBBI, dl, TII.get(PPC::STWU), PPC::R1)
.addReg(PPC::R1) .addReg(PPC::R1)
.addImm(NegFrameSize) .addImm(NegFrameSize)
.addReg(PPC::R1); .addReg(PPC::R1);
} else { } else {
BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0) BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0)
.addImm(NegFrameSize >> 16); .addImm(NegFrameSize >> 16);
@ -535,7 +548,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
.addReg(PPC::R1) .addReg(PPC::R1)
.addReg(PPC::R0); .addReg(PPC::R0);
} }
} else { // PPC64. } else { // PPC64...
if (HasBP) { if (HasBP) {
// Save a copy of r1 as the base pointer. // Save a copy of r1 as the base pointer.
BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), PPC::X30) BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), PPC::X30)
@ -544,14 +557,11 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
} }
if (HasBP && MaxAlign > 1) { if (HasBP && MaxAlign > 1) {
assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) &&
"Invalid alignment!");
BuildMI(MBB, MBBI, dl, TII.get(PPC::RLDICL), PPC::X0) BuildMI(MBB, MBBI, dl, TII.get(PPC::RLDICL), PPC::X0)
.addReg(PPC::X1) .addReg(PPC::X1)
.addImm(0) .addImm(0)
.addImm(64 - Log2_32(MaxAlign)); .addImm(64 - Log2_32(MaxAlign));
if (isInt<16>(NegFrameSize)) { if (!isLargeFrame) {
BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC8), PPC::X0) BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC8), PPC::X0)
.addReg(PPC::X0, RegState::Kill) .addReg(PPC::X0, RegState::Kill)
.addImm(NegFrameSize); .addImm(NegFrameSize);
@ -569,11 +579,13 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
.addReg(PPC::X1, RegState::Kill) .addReg(PPC::X1, RegState::Kill)
.addReg(PPC::X1) .addReg(PPC::X1)
.addReg(PPC::X0); .addReg(PPC::X0);
} else if (isInt<16>(NegFrameSize)) {
} else if (!isLargeFrame) {
BuildMI(MBB, MBBI, dl, TII.get(PPC::STDU), PPC::X1) BuildMI(MBB, MBBI, dl, TII.get(PPC::STDU), PPC::X1)
.addReg(PPC::X1) .addReg(PPC::X1)
.addImm(NegFrameSize) .addImm(NegFrameSize)
.addReg(PPC::X1); .addReg(PPC::X1);
} else { } else {
BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0) BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0)
.addImm(NegFrameSize >> 16); .addImm(NegFrameSize >> 16);
@ -625,11 +637,11 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
// If there is a frame pointer, copy R1 into R31 // If there is a frame pointer, copy R1 into R31
if (HasFP) { if (HasFP) {
if (!isPPC64) { if (!isPPC64) { // PPC32...
BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), PPC::R31) BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), PPC::R31)
.addReg(PPC::R1) .addReg(PPC::R1)
.addReg(PPC::R1); .addReg(PPC::R1);
} else { } else { // PPC64...
BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), PPC::X31) BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), PPC::X31)
.addReg(PPC::X1) .addReg(PPC::X1)
.addReg(PPC::X1); .addReg(PPC::X1);
@ -641,8 +653,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
// Mark effective beginning of when frame pointer is ready. // Mark effective beginning of when frame pointer is ready.
BuildMI(MBB, MBBI, dl, TII.get(PPC::PROLOG_LABEL)).addSym(ReadyLabel); BuildMI(MBB, MBBI, dl, TII.get(PPC::PROLOG_LABEL)).addSym(ReadyLabel);
unsigned Reg = HasFP ? (isPPC64 ? PPC::X31 : PPC::R31) unsigned Reg = isPPC64 ? PPC::X31 : PPC::R31;
: (isPPC64 ? PPC::X1 : PPC::R1);
Reg = MRI->getDwarfRegNum(Reg, true); Reg = MRI->getDwarfRegNum(Reg, true);
MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(ReadyLabel, Reg)); MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(ReadyLabel, Reg));
} }
@ -664,19 +675,16 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
// For SVR4, don't emit a move for the CR spill slot if we haven't // For SVR4, don't emit a move for the CR spill slot if we haven't
// spilled CRs. // spilled CRs.
if (Subtarget.isSVR4ABI() if (isSVR4ABI && (PPC::CR2 <= Reg && Reg <= PPC::CR4)
&& (PPC::CR2 <= Reg && Reg <= PPC::CR4) && MustSaveCRs.empty())
&& MustSaveCRs.empty()) continue;
continue;
// For 64-bit SVR4 when we have spilled CRs, the spill location // For 64-bit SVR4 when we have spilled CRs, the spill location
// is SP+8, not a frame-relative slot. // is SP+8, not a frame-relative slot.
if (Subtarget.isSVR4ABI() if (isSVR4ABI && isPPC64 && (PPC::CR2 <= Reg && Reg <= PPC::CR4)) {
&& Subtarget.isPPC64()
&& (PPC::CR2 <= Reg && Reg <= PPC::CR4)) {
MMI.addFrameInst(MCCFIInstruction::createOffset( MMI.addFrameInst(MCCFIInstruction::createOffset(
Label, MRI->getDwarfRegNum(PPC::CR2, true), 8)); Label, MRI->getDwarfRegNum(PPC::CR2, true), 8));
continue; continue;
} }
int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx());
@ -707,7 +715,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
RetOpcode == PPC::TCRETURNai8) && RetOpcode == PPC::TCRETURNai8) &&
"Can only insert epilog into returning blocks"); "Can only insert epilog into returning blocks");
// Get alignment info so we know how to restore r1 // Get alignment info so we know how to restore the SP.
const MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineFrameInfo *MFI = MF.getFrameInfo();
// Get the number of bytes allocated from the FrameInfo. // Get the number of bytes allocated from the FrameInfo.
@ -715,8 +723,10 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
// Get processor type. // Get processor type.
bool isPPC64 = Subtarget.isPPC64(); bool isPPC64 = Subtarget.isPPC64();
// Get operating system // Get the ABI.
bool isDarwinABI = Subtarget.isDarwinABI(); bool isDarwinABI = Subtarget.isDarwinABI();
bool isSVR4ABI = Subtarget.isSVR4ABI();
// Check if the link register (LR) has been saved. // Check if the link register (LR) has been saved.
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
bool MustSaveLR = FI->mustSaveLR(); bool MustSaveLR = FI->mustSaveLR();
@ -729,7 +739,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
int FPOffset = 0; int FPOffset = 0;
if (HasFP) { if (HasFP) {
if (Subtarget.isSVR4ABI()) { if (isSVR4ABI) {
MachineFrameInfo *FFI = MF.getFrameInfo(); MachineFrameInfo *FFI = MF.getFrameInfo();
int FPIndex = FI->getFramePointerSaveIndex(); int FPIndex = FI->getFramePointerSaveIndex();
assert(FPIndex && "No Frame Pointer Save Slot!"); assert(FPIndex && "No Frame Pointer Save Slot!");
@ -741,7 +751,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
int BPOffset = 0; int BPOffset = 0;
if (HasBP) { if (HasBP) {
if (Subtarget.isSVR4ABI()) { if (isSVR4ABI) {
MachineFrameInfo *FFI = MF.getFrameInfo(); MachineFrameInfo *FFI = MF.getFrameInfo();
int BPIndex = FI->getBasePointerSaveIndex(); int BPIndex = FI->getBasePointerSaveIndex();
assert(BPIndex && "No Base Pointer Save Slot!"); assert(BPIndex && "No Base Pointer Save Slot!");
@ -773,30 +783,35 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
FrameSize += StackAdj; FrameSize += StackAdj;
} }
// Frames of 32KB & larger require special handling because they cannot be
// indexed into with a simple LD/LWZ immediate offset operand.
bool isLargeFrame = !isInt<16>(FrameSize);
if (FrameSize) { if (FrameSize) {
// The loaded (or persistent) stack pointer value is offset by the 'stwu' // In the prologue, the loaded (or persistent) stack pointer value is offset
// on entry to the function. Add this offset back now. // by the STDU/STDUX/STWU/STWUX instruction. Add this offset back now.
if (!isPPC64) { if (!isPPC64) {
// If this function contained a fastcc call and GuaranteedTailCallOpt is // If this function contained a fastcc call and GuaranteedTailCallOpt is
// enabled (=> hasFastCall()==true) the fastcc call might contain a tail // enabled (=> hasFastCall()==true) the fastcc call might contain a tail
// call which invalidates the stack pointer value in SP(0). So we use the // call which invalidates the stack pointer value in SP(0). So we use the
// value of R31 in this case. // value of R31 in this case.
if (FI->hasFastCall() && isInt<16>(FrameSize)) { if (FI->hasFastCall()) {
assert(hasFP(MF) && "Expecting a valid the frame pointer."); assert(HasFP && "Expecting a valid frame pointer.");
BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1) if (!isLargeFrame) {
.addReg(PPC::R31).addImm(FrameSize); BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1)
} else if(FI->hasFastCall()) { .addReg(PPC::R31).addImm(FrameSize);
BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0) } else {
.addImm(FrameSize >> 16); BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0)
BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0) .addImm(FrameSize >> 16);
.addReg(PPC::R0, RegState::Kill) BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0)
.addImm(FrameSize & 0xFFFF); .addReg(PPC::R0, RegState::Kill)
BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD4)) .addImm(FrameSize & 0xFFFF);
.addReg(PPC::R1) BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD4))
.addReg(PPC::R31) .addReg(PPC::R1)
.addReg(PPC::R0); .addReg(PPC::R31)
} else if (isInt<16>(FrameSize) && .addReg(PPC::R0);
!HasBP && }
} else if (!isLargeFrame && !HasBP &&
!MFI->hasVarSizedObjects()) { !MFI->hasVarSizedObjects()) {
BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1) BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1)
.addReg(PPC::R1).addImm(FrameSize); .addReg(PPC::R1).addImm(FrameSize);
@ -804,22 +819,24 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ),PPC::R1) BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ),PPC::R1)
.addImm(0).addReg(PPC::R1); .addImm(0).addReg(PPC::R1);
} }
} else { } else { // PPC64...
if (FI->hasFastCall() && isInt<16>(FrameSize)) { if (FI->hasFastCall()) {
assert(hasFP(MF) && "Expecting a valid the frame pointer."); if (!isLargeFrame) {
BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1) assert(HasFP && "Expecting a valid frame pointer.");
.addReg(PPC::X31).addImm(FrameSize); BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1)
} else if(FI->hasFastCall()) { .addReg(PPC::X31).addImm(FrameSize);
BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0) } else {
.addImm(FrameSize >> 16); BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0)
BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0) .addImm(FrameSize >> 16);
.addReg(PPC::X0, RegState::Kill) BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0)
.addImm(FrameSize & 0xFFFF); .addReg(PPC::X0, RegState::Kill)
BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD8)) .addImm(FrameSize & 0xFFFF);
.addReg(PPC::X1) BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD8))
.addReg(PPC::X31) .addReg(PPC::X1)
.addReg(PPC::X0); .addReg(PPC::X31)
} else if (isInt<16>(FrameSize) && !HasBP && .addReg(PPC::X0);
}
} else if (!isLargeFrame && !HasBP &&
!MFI->hasVarSizedObjects()) { !MFI->hasVarSizedObjects()) {
BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1) BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1)
.addReg(PPC::X1).addImm(FrameSize); .addReg(PPC::X1).addImm(FrameSize);
@ -854,7 +871,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
if (MustSaveLR) if (MustSaveLR)
BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR8)).addReg(PPC::X0); BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR8)).addReg(PPC::X0);
} else { } else { // PPC32...
if (MustSaveLR) if (MustSaveLR)
BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R0) BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R0)
.addImm(LROffset).addReg(PPC::R1); .addImm(LROffset).addReg(PPC::R1);