diff options
Diffstat (limited to 'lib/Target/PowerPC/PPCFrameLowering.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCFrameLowering.cpp | 219 |
1 files changed, 178 insertions, 41 deletions
diff --git a/lib/Target/PowerPC/PPCFrameLowering.cpp b/lib/Target/PowerPC/PPCFrameLowering.cpp index dabe613..24d3a0b 100644 --- a/lib/Target/PowerPC/PPCFrameLowering.cpp +++ b/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -26,17 +26,6 @@ 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 - - /// VRRegNo - Map from a numbered VR register to its enum value. /// static const uint16_t VRRegNo[] = { @@ -217,9 +206,12 @@ unsigned PPCFrameLowering::determineFrameLayout(MachineFunction &MF, // Get the alignments provided by the target, and the maximum alignment // (if any) of the fixed frame objects. - unsigned MaxAlign = MFI->getMaxAlignment(); unsigned TargetAlign = getStackAlignment(); - unsigned AlignMask = TargetAlign - 1; // + unsigned MaxAlign = MFI->getMaxAlignment(); + unsigned AlignMask = std::max(MaxAlign, TargetAlign) - 1; + + const PPCRegisterInfo *RegInfo = + static_cast<const PPCRegisterInfo*>(MF.getTarget().getRegisterInfo()); // 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 @@ -235,7 +227,7 @@ unsigned PPCFrameLowering::determineFrameLayout(MachineFunction &MF, FrameSize <= 224 && // Fits in red zone. !MFI->hasVarSizedObjects() && // No dynamic alloca. !MFI->adjustsStack() && // No calls. - (!ALIGN_STACK || MaxAlign <= TargetAlign)) { // No special alignment. + !RegInfo->hasBasePointer(MF)) { // No special alignment. // No need for frame if (UpdateMF) MFI->setStackSize(0); @@ -305,6 +297,12 @@ void PPCFrameLowering::replaceFPWithRealFP(MachineFunction &MF) const { unsigned FPReg = is31 ? PPC::R31 : PPC::R1; unsigned FP8Reg = is31 ? PPC::X31 : PPC::X1; + const PPCRegisterInfo *RegInfo = + static_cast<const PPCRegisterInfo*>(MF.getTarget().getRegisterInfo()); + bool HasBP = RegInfo->hasBasePointer(MF); + unsigned BPReg = HasBP ? (unsigned) PPC::R30 : FPReg; + unsigned BP8Reg = HasBP ? (unsigned) PPC::X30 : FPReg; + for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); BI != BE; ++BI) for (MachineBasicBlock::iterator MBBI = BI->end(); MBBI != BI->begin(); ) { @@ -321,6 +319,13 @@ void PPCFrameLowering::replaceFPWithRealFP(MachineFunction &MF) const { case PPC::FP8: MO.setReg(FP8Reg); break; + case PPC::BP: + MO.setReg(BPReg); + break; + case PPC::BP8: + MO.setReg(BP8Reg); + break; + } } } @@ -332,9 +337,11 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { MachineFrameInfo *MFI = MF.getFrameInfo(); const PPCInstrInfo &TII = *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo()); + const PPCRegisterInfo *RegInfo = + static_cast<const PPCRegisterInfo*>(MF.getTarget().getRegisterInfo()); MachineModuleInfo &MMI = MF.getMMI(); - const MCRegisterInfo &MRI = MMI.getContext().getRegisterInfo(); + const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); DebugLoc dl; bool needsFrameMoves = MMI.hasDebugInfo() || MF.getFunction()->needsUnwindTableEntry(); @@ -358,6 +365,8 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { // Work out frame sizes. unsigned FrameSize = determineFrameLayout(MF); int NegFrameSize = -FrameSize; + if (!isInt<32>(NegFrameSize)) + llvm_unreachable("Unhandled stack size!"); if (MFI->isFrameAddressTaken()) replaceFPWithRealFP(MF); @@ -369,9 +378,10 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { // Check if the link register (LR) must be saved. PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); bool MustSaveLR = FI->mustSaveLR(); - const SmallVector<unsigned, 3> &MustSaveCRs = FI->getMustSaveCRs(); + const SmallVectorImpl<unsigned> &MustSaveCRs = FI->getMustSaveCRs(); // Do we have a frame pointer for this function? bool HasFP = hasFP(MF); + bool HasBP = RegInfo->hasBasePointer(MF); int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI); @@ -387,6 +397,19 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { } } + int BPOffset = 0; + if (HasBP) { + if (Subtarget.isSVR4ABI()) { + MachineFrameInfo *FFI = MF.getFrameInfo(); + int BPIndex = FI->getBasePointerSaveIndex(); + assert(BPIndex && "No Base Pointer Save Slot!"); + BPOffset = FFI->getObjectOffset(BPIndex); + } else { + BPOffset = + PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI); + } + } + if (isPPC64) { if (MustSaveLR) BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR8), PPC::X0); @@ -404,6 +427,12 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { .addImm(FPOffset) .addReg(PPC::X1); + if (HasBP) + BuildMI(MBB, MBBI, dl, TII.get(PPC::STD)) + .addReg(PPC::X30) + .addImm(BPOffset) + .addReg(PPC::X1); + if (MustSaveLR) BuildMI(MBB, MBBI, dl, TII.get(PPC::STD)) .addReg(PPC::X0) @@ -427,6 +456,14 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { .addImm(FPOffset) .addReg(PPC::R1); + if (HasBP) + // FIXME: On PPC32 SVR4, FPOffset is negative and access to negative + // offsets of R1 is not allowed. + BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) + .addReg(PPC::R30) + .addImm(BPOffset) + .addReg(PPC::R1); + assert(MustSaveCRs.empty() && "Prologue CR saving supported only in 64-bit mode"); @@ -441,26 +478,43 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { if (!FrameSize) return; // Get stack alignments. - unsigned TargetAlign = getStackAlignment(); unsigned MaxAlign = MFI->getMaxAlignment(); // Adjust stack pointer: r1 += NegFrameSize. // If there is a preferred stack alignment, align R1 now if (!isPPC64) { // PPC32. - if (ALIGN_STACK && MaxAlign > TargetAlign) { + + if (HasBP) { + // Save a copy of r1 as the base pointer. + BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), PPC::R30) + .addReg(PPC::R1) + .addReg(PPC::R1); + } + + if (HasBP && MaxAlign > 1) { assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) && "Invalid alignment!"); - assert(isInt<16>(NegFrameSize) && "Unhandled stack size and alignment!"); BuildMI(MBB, MBBI, dl, TII.get(PPC::RLWINM), PPC::R0) .addReg(PPC::R1) .addImm(0) .addImm(32 - Log2_32(MaxAlign)) .addImm(31); - BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC) ,PPC::R0) - .addReg(PPC::R0, RegState::Kill) - .addImm(NegFrameSize); + if (isInt<16>(NegFrameSize)) { + BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC), PPC::R0) + .addReg(PPC::R0, RegState::Kill) + .addImm(NegFrameSize); + } else { + BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R12) + .addImm(NegFrameSize >> 16); + BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R12) + .addReg(PPC::R12, RegState::Kill) + .addImm(NegFrameSize & 0xFFFF); + BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFC), PPC::R0) + .addReg(PPC::R0, RegState::Kill) + .addReg(PPC::R12, RegState::Kill); + } BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX), PPC::R1) .addReg(PPC::R1, RegState::Kill) .addReg(PPC::R1) @@ -482,18 +536,35 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { .addReg(PPC::R0); } } else { // PPC64. - if (ALIGN_STACK && MaxAlign > TargetAlign) { + if (HasBP) { + // Save a copy of r1 as the base pointer. + BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), PPC::X30) + .addReg(PPC::X1) + .addReg(PPC::X1); + } + + if (HasBP && MaxAlign > 1) { assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) && "Invalid alignment!"); - assert(isInt<16>(NegFrameSize) && "Unhandled stack size and alignment!"); BuildMI(MBB, MBBI, dl, TII.get(PPC::RLDICL), PPC::X0) .addReg(PPC::X1) .addImm(0) .addImm(64 - Log2_32(MaxAlign)); - BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC8), PPC::X0) - .addReg(PPC::X0) - .addImm(NegFrameSize); + if (isInt<16>(NegFrameSize)) { + BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC8), PPC::X0) + .addReg(PPC::X0, RegState::Kill) + .addImm(NegFrameSize); + } else { + BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X12) + .addImm(NegFrameSize >> 16); + BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X12) + .addReg(PPC::X12, RegState::Kill) + .addImm(NegFrameSize & 0xFFFF); + BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFC8), PPC::X0) + .addReg(PPC::X0, RegState::Kill) + .addReg(PPC::X12, RegState::Kill); + } BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX), PPC::X1) .addReg(PPC::X1, RegState::Kill) .addReg(PPC::X1) @@ -530,14 +601,21 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { if (HasFP) { unsigned Reg = isPPC64 ? PPC::X31 : PPC::R31; - Reg = MRI.getDwarfRegNum(Reg, true); + Reg = MRI->getDwarfRegNum(Reg, true); MMI.addFrameInst( MCCFIInstruction::createOffset(FrameLabel, Reg, FPOffset)); } + if (HasBP) { + unsigned Reg = isPPC64 ? PPC::X30 : PPC::R30; + Reg = MRI->getDwarfRegNum(Reg, true); + MMI.addFrameInst( + MCCFIInstruction::createOffset(FrameLabel, Reg, BPOffset)); + } + if (MustSaveLR) { unsigned Reg = isPPC64 ? PPC::LR8 : PPC::LR; - Reg = MRI.getDwarfRegNum(Reg, true); + Reg = MRI->getDwarfRegNum(Reg, true); MMI.addFrameInst( MCCFIInstruction::createOffset(FrameLabel, Reg, LROffset)); } @@ -565,7 +643,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { unsigned Reg = HasFP ? (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)); } } @@ -597,13 +675,13 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { && Subtarget.isPPC64() && (PPC::CR2 <= Reg && Reg <= PPC::CR4)) { MMI.addFrameInst(MCCFIInstruction::createOffset( - Label, MRI.getDwarfRegNum(PPC::CR2, true), 8)); + Label, MRI->getDwarfRegNum(PPC::CR2, true), 8)); continue; } int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); MMI.addFrameInst(MCCFIInstruction::createOffset( - Label, MRI.getDwarfRegNum(Reg, true), Offset)); + Label, MRI->getDwarfRegNum(Reg, true), Offset)); } } } @@ -614,6 +692,8 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF, assert(MBBI != MBB.end() && "Returning block has no terminator"); const PPCInstrInfo &TII = *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo()); + const PPCRegisterInfo *RegInfo = + static_cast<const PPCRegisterInfo*>(MF.getTarget().getRegisterInfo()); unsigned RetOpcode = MBBI->getOpcode(); DebugLoc dl; @@ -629,8 +709,6 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF, // Get alignment info so we know how to restore r1 const MachineFrameInfo *MFI = MF.getFrameInfo(); - unsigned TargetAlign = getStackAlignment(); - unsigned MaxAlign = MFI->getMaxAlignment(); // Get the number of bytes allocated from the FrameInfo. int FrameSize = MFI->getStackSize(); @@ -642,9 +720,10 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF, // Check if the link register (LR) has been saved. PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); bool MustSaveLR = FI->mustSaveLR(); - const SmallVector<unsigned, 3> &MustSaveCRs = FI->getMustSaveCRs(); + const SmallVectorImpl<unsigned> &MustSaveCRs = FI->getMustSaveCRs(); // Do we have a frame pointer for this function? bool HasFP = hasFP(MF); + bool HasBP = RegInfo->hasBasePointer(MF); int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI); @@ -660,6 +739,19 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF, } } + int BPOffset = 0; + if (HasBP) { + if (Subtarget.isSVR4ABI()) { + MachineFrameInfo *FFI = MF.getFrameInfo(); + int BPIndex = FI->getBasePointerSaveIndex(); + assert(BPIndex && "No Base Pointer Save Slot!"); + BPOffset = FFI->getObjectOffset(BPIndex); + } else { + BPOffset = + PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI); + } + } + bool UsesTCRet = RetOpcode == PPC::TCRETURNri || RetOpcode == PPC::TCRETURNdi || RetOpcode == PPC::TCRETURNai || @@ -704,7 +796,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF, .addReg(PPC::R31) .addReg(PPC::R0); } else if (isInt<16>(FrameSize) && - (!ALIGN_STACK || TargetAlign >= MaxAlign) && + !HasBP && !MFI->hasVarSizedObjects()) { BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1) .addReg(PPC::R1).addImm(FrameSize); @@ -727,7 +819,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF, .addReg(PPC::X1) .addReg(PPC::X31) .addReg(PPC::X0); - } else if (isInt<16>(FrameSize) && TargetAlign >= MaxAlign && + } else if (isInt<16>(FrameSize) && !HasBP && !MFI->hasVarSizedObjects()) { BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1) .addReg(PPC::X1).addImm(FrameSize); @@ -751,9 +843,13 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF, BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X31) .addImm(FPOffset).addReg(PPC::X1); + if (HasBP) + BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X30) + .addImm(BPOffset).addReg(PPC::X1); + if (!MustSaveCRs.empty()) for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i) - BuildMI(MBB, MBBI, dl, TII.get(PPC::MTCRF8), MustSaveCRs[i]) + BuildMI(MBB, MBBI, dl, TII.get(PPC::MTOCRF8), MustSaveCRs[i]) .addReg(PPC::X12, getKillRegState(i == e-1)); if (MustSaveLR) @@ -770,6 +866,10 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF, BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R31) .addImm(FPOffset).addReg(PPC::R1); + if (HasBP) + BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R30) + .addImm(FPOffset).addReg(PPC::R1); + if (MustSaveLR) BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR)).addReg(PPC::R0); } @@ -848,7 +948,8 @@ static bool MustSaveLR(const MachineFunction &MF, unsigned LR) { void PPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *) const { - const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); + const PPCRegisterInfo *RegInfo = + static_cast<const PPCRegisterInfo*>(MF.getTarget().getRegisterInfo()); // Save and clear the LR state. PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); @@ -873,6 +974,15 @@ PPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, FI->setFramePointerSaveIndex(FPSI); } + int BPSI = FI->getBasePointerSaveIndex(); + if (!BPSI && RegInfo->hasBasePointer(MF)) { + int BPOffset = getBasePointerSaveOffset(isPPC64, isDarwinABI); + // Allocate the frame index for the base pointer save area. + BPSI = MFI->CreateFixedObject(isPPC64? 8 : 4, BPOffset, true); + // Save the result. + FI->setBasePointerSaveIndex(BPSI); + } + // Reserve stack space to move the linkage area to in case of a tail call. int TCSPDelta = 0; if (MF.getTarget().Options.GuaranteedTailCallOpt && @@ -1004,6 +1114,17 @@ void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF, FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); } + const PPCRegisterInfo *RegInfo = + static_cast<const PPCRegisterInfo*>(MF.getTarget().getRegisterInfo()); + if (RegInfo->hasBasePointer(MF)) { + HasGPSaveArea = true; + + int FI = PFI->getBasePointerSaveIndex(); + assert(FI && "No Base Pointer Save Slot!"); + + FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); + } + // General register save area starts right below the Floating-point // register save area. if (HasGPSaveArea || HasG8SaveArea) { @@ -1116,8 +1237,12 @@ PPCFrameLowering::addScavengingSpillSlot(MachineFunction &MF, RC->getAlignment(), false)); + // Might we have over-aligned allocas? + bool HasAlVars = MFI->hasVarSizedObjects() && + MFI->getMaxAlignment() > getStackAlignment(); + // These kinds of spills might need two registers. - if (spillsCR(MF) || spillsVRSAVE(MF)) + if (spillsCR(MF) || spillsVRSAVE(MF) || HasAlVars) RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), RC->getAlignment(), false)); @@ -1145,6 +1270,12 @@ PPCFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, for (unsigned i = 0, e = CSI.size(); i != e; ++i) { unsigned Reg = CSI[i].getReg(); + // Only Darwin actually uses the VRSAVE register, but it can still appear + // here if, for example, @llvm.eh.unwind.init() is used. If we're not on + // Darwin, ignore it. + if (Reg == PPC::VRSAVE && !Subtarget.isDarwinABI()) + continue; + // CR2 through CR4 are the nonvolatile CR fields. bool IsCRField = PPC::CR2 <= Reg && Reg <= PPC::CR4; @@ -1206,7 +1337,7 @@ restoreCRs(bool isPPC64, bool is31, MBB.insert(MI, addFrameReference(BuildMI(*MF, DL, TII.get(PPC::LWZ), PPC::R12), CSI[CSIIndex].getFrameIdx())); - RestoreOp = PPC::MTCRF; + RestoreOp = PPC::MTOCRF; MoveReg = PPC::R12; } @@ -1294,6 +1425,12 @@ PPCFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, for (unsigned i = 0, e = CSI.size(); i != e; ++i) { unsigned Reg = CSI[i].getReg(); + // Only Darwin actually uses the VRSAVE register, but it can still appear + // here if, for example, @llvm.eh.unwind.init() is used. If we're not on + // Darwin, ignore it. + if (Reg == PPC::VRSAVE && !Subtarget.isDarwinABI()) + continue; + if (Reg == PPC::CR2) { CR2Spilled = true; // The spill slot is associated only with CR2, which is the |