131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- PPCFrameLowering.cpp - PPC Frame Information ----------------------===// 233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The LLVM Compiler Infrastructure 433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// This file is distributed under the University of Illinois Open Source 633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// License. See LICENSE.TXT for details. 733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 1016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov// This file contains the PPC implementation of TargetFrameLowering class. 1133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 1233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 1333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 1416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "PPCFrameLowering.h" 1533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "PPCInstrInfo.h" 1633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "PPCMachineFunctionInfo.h" 1733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Function.h" 1833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 1933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 2033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 2133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineModuleInfo.h" 2233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h" 2394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov#include "llvm/CodeGen/RegisterScavenging.h" 2433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Target/TargetOptions.h" 2533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 2633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovusing namespace llvm; 2733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 2833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// FIXME This disables some code that aligns the stack to a boundary bigger than 2933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// the default (16 bytes on Darwin) when there is a stack local of greater 3033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// alignment. This does not currently work, because the delta between old and 3133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// new stack pointers is added to offsets that reference incoming parameters 3233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// after the prolog is generated, and the code that does that doesn't handle a 3333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// variable delta. You don't want to do that anyway; a better approach is to 3433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// reserve another register that retains to the incoming stack pointer, and 3533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// reference parameters relative to that. 3633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#define ALIGN_STACK 0 3733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// VRRegNo - Map from a numbered VR register to its enum value. 4033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// 41b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t VRRegNo[] = { 4233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPC::V0 , PPC::V1 , PPC::V2 , PPC::V3 , PPC::V4 , PPC::V5 , PPC::V6 , PPC::V7 , 4333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPC::V8 , PPC::V9 , PPC::V10, PPC::V11, PPC::V12, PPC::V13, PPC::V14, PPC::V15, 4433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPC::V16, PPC::V17, PPC::V18, PPC::V19, PPC::V20, PPC::V21, PPC::V22, PPC::V23, 4533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPC::V24, PPC::V25, PPC::V26, PPC::V27, PPC::V28, PPC::V29, PPC::V30, PPC::V31 4633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov}; 4733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 4833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// RemoveVRSaveCode - We have found that this function does not need any code 4933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// to manipulate the VRSAVE register, even though it uses vector registers. 5033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// This can happen when the only registers used are known to be live in or out 5133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// of the function. Remove all of the VRSAVE related code from the function. 5233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic void RemoveVRSaveCode(MachineInstr *MI) { 5333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock *Entry = MI->getParent(); 5433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFunction *MF = Entry->getParent(); 5533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 5633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // We know that the MTVRSAVE instruction immediately follows MI. Remove it. 5733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MI; 5833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ++MBBI; 5933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MBBI != Entry->end() && MBBI->getOpcode() == PPC::MTVRSAVE); 6033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI->eraseFromParent(); 6133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 6233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool RemovedAllMTVRSAVEs = true; 6333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // See if we can find and remove the MTVRSAVE instruction from all of the 6433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // epilog blocks. 6533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I) { 6633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If last instruction is a return instruction, add an epilogue 675a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (!I->empty() && I->back().isReturn()) { 6833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool FoundIt = false; 6933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MBBI = I->end(); MBBI != I->begin(); ) { 7033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov --MBBI; 7133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI->getOpcode() == PPC::MTVRSAVE) { 7233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI->eraseFromParent(); // remove it. 7333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FoundIt = true; 7433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; 7533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 7633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 7733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RemovedAllMTVRSAVEs &= FoundIt; 7833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 7933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 8033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 8133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we found and removed all MTVRSAVE instructions, remove the read of 8233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // VRSAVE as well. 8333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RemovedAllMTVRSAVEs) { 8433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = MI; 8533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MBBI != Entry->begin() && "UPDATE_VRSAVE is first instr in block?"); 8633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov --MBBI; 8733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MBBI->getOpcode() == PPC::MFVRSAVE && "VRSAVE instrs wandered?"); 8833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI->eraseFromParent(); 8933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 9033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 9133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Finally, nuke the UPDATE_VRSAVE. 9233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->eraseFromParent(); 9333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 9433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 9533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// HandleVRSaveUpdate - MI is the UPDATE_VRSAVE instruction introduced by the 9633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// instruction selector. Based on the vector registers that have been used, 9733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// transform this into the appropriate ORI instruction. 9833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic void HandleVRSaveUpdate(MachineInstr *MI, const TargetInstrInfo &TII) { 9933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFunction *MF = MI->getParent()->getParent(); 10033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 10133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 10233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned UsedRegMask = 0; 10333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned i = 0; i != 32; ++i) 10433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MF->getRegInfo().isPhysRegUsed(VRRegNo[i])) 10533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov UsedRegMask |= 1 << (31-i); 10633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 10733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Live in and live out values already must be in the mask, so don't bother 10833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // marking them. 10933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MachineRegisterInfo::livein_iterator 11033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I = MF->getRegInfo().livein_begin(), 11133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov E = MF->getRegInfo().livein_end(); I != E; ++I) { 112966aeb5788c242cfaca35c56c0ddc0ff778d4376Evan Cheng unsigned RegNo = getPPCRegisterNumbering(I->first); 11333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (VRRegNo[RegNo] == I->first) // If this really is a vector reg. 11433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov UsedRegMask &= ~(1 << (31-RegNo)); // Doesn't need to be marked. 11533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 11633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MachineRegisterInfo::liveout_iterator 11733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I = MF->getRegInfo().liveout_begin(), 11833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov E = MF->getRegInfo().liveout_end(); I != E; ++I) { 119966aeb5788c242cfaca35c56c0ddc0ff778d4376Evan Cheng unsigned RegNo = getPPCRegisterNumbering(*I); 12033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (VRRegNo[RegNo] == *I) // If this really is a vector reg. 12133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov UsedRegMask &= ~(1 << (31-RegNo)); // Doesn't need to be marked. 12233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 12333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 12433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If no registers are used, turn this into a copy. 12533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (UsedRegMask == 0) { 12633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Remove all VRSAVE code. 12733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RemoveVRSaveCode(MI); 12833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return; 12933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 13033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 13133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned SrcReg = MI->getOperand(1).getReg(); 13233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned DstReg = MI->getOperand(0).getReg(); 13333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 13433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((UsedRegMask & 0xFFFF) == UsedRegMask) { 13533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (DstReg != SrcReg) 13633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORI), DstReg) 13733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(SrcReg) 13833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask); 13933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 14033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORI), DstReg) 14133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(SrcReg, RegState::Kill) 14233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask); 14333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((UsedRegMask & 0xFFFF0000) == UsedRegMask) { 14433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (DstReg != SrcReg) 14533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg) 14633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(SrcReg) 14733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask >> 16); 14833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 14933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg) 15033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(SrcReg, RegState::Kill) 15133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask >> 16); 15233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 15333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (DstReg != SrcReg) 15433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg) 15533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(SrcReg) 15633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask >> 16); 15733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 15833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg) 15933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(SrcReg, RegState::Kill) 16033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask >> 16); 16133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 16233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORI), DstReg) 16333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(DstReg, RegState::Kill) 16433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask & 0xFFFF); 16533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 16633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 16733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Remove the old UPDATE_VRSAVE instruction. 16833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->eraseFromParent(); 16933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 17033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 17133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// determineFrameLayout - Determine the size of the frame and maximum call 17233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// frame size. 17316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid PPCFrameLowering::determineFrameLayout(MachineFunction &MF) const { 17433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 17533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 17633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes to allocate from the FrameInfo 17733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FrameSize = MFI->getStackSize(); 17833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 17933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the alignments provided by the target, and the maximum alignment 18033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // (if any) of the fixed frame objects. 18133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned MaxAlign = MFI->getMaxAlignment(); 18216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned TargetAlign = getStackAlignment(); 18333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned AlignMask = TargetAlign - 1; // 18433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 18533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we are a leaf function, and use up to 224 bytes of stack space, 18633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // don't have a frame pointer, calls, or dynamic alloca then we do not need 18733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // to adjust the stack pointer (we fit in the Red Zone). 18833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool DisableRedZone = MF.getFunction()->hasFnAttr(Attribute::NoRedZone); 18933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // FIXME SVR4 The 32-bit SVR4 ABI has no red zone. 19033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!DisableRedZone && 19133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize <= 224 && // Fits in red zone. 19233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !MFI->hasVarSizedObjects() && // No dynamic alloca. 19333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !MFI->adjustsStack() && // No calls. 19433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (!ALIGN_STACK || MaxAlign <= TargetAlign)) { // No special alignment. 19533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // No need for frame 19633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->setStackSize(0); 19733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return; 19833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 19933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 20033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the maximum call frame size of all the calls. 20133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned maxCallFrameSize = MFI->getMaxCallFrameSize(); 20233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 20333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Maximum call frame needs to be at least big enough for linkage and 8 args. 20433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned minCallFrameSize = getMinCallFrameSize(Subtarget.isPPC64(), 20533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Subtarget.isDarwinABI()); 20633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize); 20733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 20833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we have dynamic alloca then maxCallFrameSize needs to be aligned so 20933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // that allocations will be aligned. 21033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MFI->hasVarSizedObjects()) 21133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask; 21233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 21333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Update maximum call frame size. 21433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->setMaxCallFrameSize(maxCallFrameSize); 21533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 21633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Include call frame size in total. 21733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize += maxCallFrameSize; 21833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 21933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Make sure the frame is aligned. 22033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize = (FrameSize + AlignMask) & ~AlignMask; 22133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 22233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Update frame info. 22333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->setStackSize(FrameSize); 22433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 22533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 226d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// hasFP - Return true if the specified function actually has a dedicated frame 227d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// pointer register. 22816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool PPCFrameLowering::hasFP(const MachineFunction &MF) const { 229d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 230c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov // FIXME: This is pretty much broken by design: hasFP() might be called really 231c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov // early, before the stack layout was calculated and thus hasFP() might return 232c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov // true or false here depending on the time of call. 233c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov return (MFI->getStackSize()) && needsFP(MF); 234c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov} 235c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov 236c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov// needsFP - Return true if the specified function should have a dedicated frame 237c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov// pointer register. This is true if the function has variable sized allocas or 238c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov// if frame pointer elimination is disabled. 23916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool PPCFrameLowering::needsFP(const MachineFunction &MF) const { 240c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 241d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 242d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov // Naked functions have no stack frame pushed, so we don't have a frame 243d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov // pointer. 244d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (MF.getFunction()->hasFnAttr(Attribute::Naked)) 245d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return false; 246d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 2478a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky return MF.getTarget().Options.DisableFramePointerElim(MF) || 2488a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky MFI->hasVarSizedObjects() || 2498a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky (MF.getTarget().Options.GuaranteedTailCallOpt && 2508a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky MF.getInfo<PPCFunctionInfo>()->hasFastCall()); 251d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 252d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 253d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 25416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid PPCFrameLowering::emitPrologue(MachineFunction &MF) const { 25533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 25633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 25733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 25833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const PPCInstrInfo &TII = 25933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo()); 26033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineModuleInfo &MMI = MF.getMMI(); 26233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl; 26333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool needsFrameMoves = MMI.hasDebugInfo() || 264fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola MF.getFunction()->needsUnwindTableEntry(); 26533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Prepare for frame info. 26733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *FrameLabel = 0; 26833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Scan the prolog, looking for an UPDATE_VRSAVE instruction. If we find it, 27033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // process it. 27133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) { 27233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) { 27333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov HandleVRSaveUpdate(MBBI, TII); 27433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; 27533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 27633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 27733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 27833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Move MBBI back to the beginning of the function. 27933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = MBB.begin(); 28033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 28133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Work out frame sizes. 282c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov // FIXME: determineFrameLayout() may change the frame size. This should be 283c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov // moved upper, to some hook. 28433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov determineFrameLayout(MF); 28533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FrameSize = MFI->getStackSize(); 28633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 28733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int NegFrameSize = -FrameSize; 28833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 28933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get processor type. 29033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isPPC64 = Subtarget.isPPC64(); 29133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get operating system 29233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isDarwinABI = Subtarget.isDarwinABI(); 29333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Check if the link register (LR) must be saved. 29433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 29533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool MustSaveLR = FI->mustSaveLR(); 29633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Do we have a frame pointer for this function? 297c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov bool HasFP = hasFP(MF); 29833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 29916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI); 30033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 30133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPOffset = 0; 30233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 30333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Subtarget.isSVR4ABI()) { 30433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *FFI = MF.getFrameInfo(); 30533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPIndex = FI->getFramePointerSaveIndex(); 30633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(FPIndex && "No Frame Pointer Save Slot!"); 30733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FPOffset = FFI->getObjectOffset(FPIndex); 30833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 30916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov FPOffset = PPCFrameLowering::getFramePointerSaveOffset(isPPC64, isDarwinABI); 31033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 31133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 31233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 31333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isPPC64) { 31433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 31533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR8), PPC::X0); 31633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 31733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) 31833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STD)) 31933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X31) 32033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FPOffset/4) 32133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1); 32233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 32333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 32433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STD)) 32533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0) 32633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(LROffset / 4) 32733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1); 32833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 32933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 33033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR), PPC::R0); 33133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 33233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) 333b8f2f29467b86a11e777e2ce071caf15ae6fcf75Hal Finkel // FIXME: On PPC32 SVR4, FPOffset is negative and access to negative 334b8f2f29467b86a11e777e2ce071caf15ae6fcf75Hal Finkel // offsets of R1 is not allowed. 33533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) 33633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R31) 33733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FPOffset) 33833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1); 33933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 34033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 34133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) 34233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0) 34333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(LROffset) 34433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1); 34533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 34633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 34733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip if a leaf routine. 34833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!FrameSize) return; 34933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get stack alignments. 35116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned TargetAlign = getStackAlignment(); 35233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned MaxAlign = MFI->getMaxAlignment(); 35333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer: r1 += NegFrameSize. 35533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is a preferred stack alignment, align R1 now 35633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!isPPC64) { 35733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // PPC32. 35833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ALIGN_STACK && MaxAlign > TargetAlign) { 35933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) && 36033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov "Invalid alignment!"); 36133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(isInt<16>(NegFrameSize) && "Unhandled stack size and alignment!"); 36233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 36333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::RLWINM), PPC::R0) 36433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 36533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(0) 36633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(32 - Log2_32(MaxAlign)) 36733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(31); 36833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC) ,PPC::R0) 36933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0, RegState::Kill) 37033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize); 371ac81cc3282750d724f824547bc519caec0a01bceHal Finkel BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX), PPC::R1) 3722e95afa04cd1c89de7e4abaeead66cd8e51ec929Hal Finkel .addReg(PPC::R1, RegState::Kill) 373ac81cc3282750d724f824547bc519caec0a01bceHal Finkel .addReg(PPC::R1) 37433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0); 37533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (isInt<16>(NegFrameSize)) { 37633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STWU), PPC::R1) 37733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 37833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize) 37933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1); 38033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 38133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0) 38233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize >> 16); 38333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0) 38433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0, RegState::Kill) 38533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize & 0xFFFF); 386ac81cc3282750d724f824547bc519caec0a01bceHal Finkel BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX), PPC::R1) 3872e95afa04cd1c89de7e4abaeead66cd8e51ec929Hal Finkel .addReg(PPC::R1, RegState::Kill) 388ac81cc3282750d724f824547bc519caec0a01bceHal Finkel .addReg(PPC::R1) 38933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0); 39033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 39133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { // PPC64. 39233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ALIGN_STACK && MaxAlign > TargetAlign) { 39333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) && 39433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov "Invalid alignment!"); 39533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(isInt<16>(NegFrameSize) && "Unhandled stack size and alignment!"); 39633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 39733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::RLDICL), PPC::X0) 39833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 39933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(0) 40033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(64 - Log2_32(MaxAlign)); 40133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC8), PPC::X0) 40233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0) 40333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize); 404ac81cc3282750d724f824547bc519caec0a01bceHal Finkel BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX), PPC::X1) 4052e95afa04cd1c89de7e4abaeead66cd8e51ec929Hal Finkel .addReg(PPC::X1, RegState::Kill) 406ac81cc3282750d724f824547bc519caec0a01bceHal Finkel .addReg(PPC::X1) 40733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0); 40833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (isInt<16>(NegFrameSize)) { 40933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STDU), PPC::X1) 41033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 41133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize / 4) 41233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1); 41333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 41433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0) 41533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize >> 16); 41633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0) 41733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0, RegState::Kill) 41833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize & 0xFFFF); 419ac81cc3282750d724f824547bc519caec0a01bceHal Finkel BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX), PPC::X1) 4202e95afa04cd1c89de7e4abaeead66cd8e51ec929Hal Finkel .addReg(PPC::X1, RegState::Kill) 421ac81cc3282750d724f824547bc519caec0a01bceHal Finkel .addReg(PPC::X1) 42233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0); 42333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 42433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 42533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 42633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 42733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 42833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add the "machine moves" for the instructions we generated above, but in 42933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // reverse order. 43033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 43133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark effective beginning of when frame pointer becomes valid. 43233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameLabel = MMI.getContext().CreateTempSymbol(); 43333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::PROLOG_LABEL)).addSym(FrameLabel); 43433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 43533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Show update of SP. 43633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NegFrameSize) { 43733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(MachineLocation::VirtualFP); 43833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(MachineLocation::VirtualFP, NegFrameSize); 43933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); 44033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 44133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SP(isPPC64 ? PPC::X31 : PPC::R31); 44233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, SP, SP)); 44333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 44433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 44533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 44633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPDst(MachineLocation::VirtualFP, FPOffset); 44733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPSrc(isPPC64 ? PPC::X31 : PPC::R31); 44833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc)); 44933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 45033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 45133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) { 45233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation LRDst(MachineLocation::VirtualFP, LROffset); 45333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation LRSrc(isPPC64 ? PPC::LR8 : PPC::LR); 45433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, LRDst, LRSrc)); 45533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 45633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 45733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 45833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *ReadyLabel = 0; 45933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 46033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is a frame pointer, copy R1 into R31 46133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 46233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!isPPC64) { 46333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), PPC::R31) 46433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 46533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1); 46633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 46733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), PPC::X31) 46833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 46933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1); 47033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 47133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 47233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 47333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ReadyLabel = MMI.getContext().CreateTempSymbol(); 47433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 47533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark effective beginning of when frame pointer is ready. 47633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::PROLOG_LABEL)).addSym(ReadyLabel); 47733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 47833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPDst(HasFP ? (isPPC64 ? PPC::X31 : PPC::R31) : 47933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (isPPC64 ? PPC::X1 : PPC::R1)); 48033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPSrc(MachineLocation::VirtualFP); 48133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(ReadyLabel, FPDst, FPSrc)); 48233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 48333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 48433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 48533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 48633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *Label = HasFP ? ReadyLabel : FrameLabel; 48733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 48833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add callee saved registers to move list. 48933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 49033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 49133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); 49233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Reg = CSI[I].getReg(); 49333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue; 4946e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola 4956e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola // This is a bit of a hack: CR2LT, CR2GT, CR2EQ and CR2UN are just 4966e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola // subregisters of CR2. We just need to emit a move of CR2. 497c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper if (PPC::CRBITRCRegClass.contains(Reg)) 4986e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola continue; 4996e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola 50033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation CSDst(MachineLocation::VirtualFP, Offset); 50133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation CSSrc(Reg); 50233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, CSDst, CSSrc)); 50333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 50433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 50533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 50633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 50716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid PPCFrameLowering::emitEpilogue(MachineFunction &MF, 50833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB) const { 5094f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 5104f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen assert(MBBI != MBB.end() && "Returning block has no terminator"); 51133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const PPCInstrInfo &TII = 51233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo()); 51333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 51433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned RetOpcode = MBBI->getOpcode(); 51533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl; 51633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 517d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov assert((RetOpcode == PPC::BLR || 518d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNri || 519d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNdi || 520d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNai || 521d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNri8 || 522d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNdi8 || 523d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNai8) && 52433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov "Can only insert epilog into returning blocks"); 52533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 52633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get alignment info so we know how to restore r1 52733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 52816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned TargetAlign = getStackAlignment(); 52933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned MaxAlign = MFI->getMaxAlignment(); 53033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 53133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes allocated from the FrameInfo. 53233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FrameSize = MFI->getStackSize(); 53333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 53433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get processor type. 53533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isPPC64 = Subtarget.isPPC64(); 53633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get operating system 53733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isDarwinABI = Subtarget.isDarwinABI(); 53833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Check if the link register (LR) has been saved. 53933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 54033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool MustSaveLR = FI->mustSaveLR(); 54133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Do we have a frame pointer for this function? 542c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov bool HasFP = hasFP(MF); 54333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 54416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI); 54533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 54633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPOffset = 0; 54733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 54833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Subtarget.isSVR4ABI()) { 54933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *FFI = MF.getFrameInfo(); 55033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPIndex = FI->getFramePointerSaveIndex(); 55133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(FPIndex && "No Frame Pointer Save Slot!"); 55233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FPOffset = FFI->getObjectOffset(FPIndex); 55333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 55416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov FPOffset = PPCFrameLowering::getFramePointerSaveOffset(isPPC64, isDarwinABI); 55533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 55633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 55733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 55833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool UsesTCRet = RetOpcode == PPC::TCRETURNri || 55933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNdi || 56033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNai || 56133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNri8 || 56233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNdi8 || 56333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNai8; 56433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 56533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (UsesTCRet) { 56633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int MaxTCRetDelta = FI->getTailCallSPDelta(); 56733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &StackAdjust = MBBI->getOperand(1); 56833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(StackAdjust.isImm() && "Expecting immediate value."); 56933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer. 57033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackAdj = StackAdjust.getImm(); 57133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Delta = StackAdj - MaxTCRetDelta; 57233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert((Delta >= 0) && "Delta must be positive"); 57333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MaxTCRetDelta>0) 57433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize += (StackAdj +Delta); 57533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 57633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize += StackAdj; 57733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 57833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 57933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (FrameSize) { 58033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // The loaded (or persistent) stack pointer value is offset by the 'stwu' 58133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // on entry to the function. Add this offset back now. 58233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!isPPC64) { 58333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If this function contained a fastcc call and GuaranteedTailCallOpt is 58433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // enabled (=> hasFastCall()==true) the fastcc call might contain a tail 58533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // call which invalidates the stack pointer value in SP(0). So we use the 58633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // value of R31 in this case. 58733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (FI->hasFastCall() && isInt<16>(FrameSize)) { 588d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov assert(hasFP(MF) && "Expecting a valid the frame pointer."); 58933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1) 59033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R31).addImm(FrameSize); 59133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if(FI->hasFastCall()) { 59233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0) 59333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FrameSize >> 16); 59433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0) 59533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0, RegState::Kill) 59633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FrameSize & 0xFFFF); 59733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD4)) 59833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 59933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R31) 60033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0); 60133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (isInt<16>(FrameSize) && 60233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (!ALIGN_STACK || TargetAlign >= MaxAlign) && 60333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !MFI->hasVarSizedObjects()) { 60433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1) 60533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1).addImm(FrameSize); 60633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 60733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ),PPC::R1) 60833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(0).addReg(PPC::R1); 60933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 61033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 61133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (FI->hasFastCall() && isInt<16>(FrameSize)) { 612d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov assert(hasFP(MF) && "Expecting a valid the frame pointer."); 61333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1) 61433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X31).addImm(FrameSize); 61533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if(FI->hasFastCall()) { 61633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0) 61733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FrameSize >> 16); 61833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0) 61933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0, RegState::Kill) 62033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FrameSize & 0xFFFF); 62133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD8)) 62233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 62333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X31) 62433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0); 62533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (isInt<16>(FrameSize) && TargetAlign >= MaxAlign && 62633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !MFI->hasVarSizedObjects()) { 62733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1) 62833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1).addImm(FrameSize); 62933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 63033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X1) 63133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(0).addReg(PPC::X1); 63233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 63333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 63433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 63533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 63633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isPPC64) { 63733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 63833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X0) 63933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(LROffset/4).addReg(PPC::X1); 64033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 64133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) 64233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X31) 64333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FPOffset/4).addReg(PPC::X1); 64433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 64533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 64633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR8)).addReg(PPC::X0); 64733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 64833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 64933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R0) 65033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(LROffset).addReg(PPC::R1); 65133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 65233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) 65333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R31) 65433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FPOffset).addReg(PPC::R1); 65533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 65633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 65733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR)).addReg(PPC::R0); 65833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 65933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 66033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Callee pop calling convention. Pop parameter/linkage area. Used for tail 66133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // call optimization 6628a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (MF.getTarget().Options.GuaranteedTailCallOpt && RetOpcode == PPC::BLR && 66333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MF.getFunction()->getCallingConv() == CallingConv::Fast) { 66433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 66533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned CallerAllocatedAmt = FI->getMinReservedArea(); 66633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackReg = isPPC64 ? PPC::X1 : PPC::R1; 66733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FPReg = isPPC64 ? PPC::X31 : PPC::R31; 66833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned TmpReg = isPPC64 ? PPC::X0 : PPC::R0; 66933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned ADDIInstr = isPPC64 ? PPC::ADDI8 : PPC::ADDI; 67033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned ADDInstr = isPPC64 ? PPC::ADD8 : PPC::ADD4; 67133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned LISInstr = isPPC64 ? PPC::LIS8 : PPC::LIS; 67233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned ORIInstr = isPPC64 ? PPC::ORI8 : PPC::ORI; 67333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 67433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (CallerAllocatedAmt && isInt<16>(CallerAllocatedAmt)) { 67533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(ADDIInstr), StackReg) 67633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(StackReg).addImm(CallerAllocatedAmt); 67733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 67833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(LISInstr), TmpReg) 67933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(CallerAllocatedAmt >> 16); 68033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(ORIInstr), TmpReg) 68133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(TmpReg, RegState::Kill) 68233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(CallerAllocatedAmt & 0xFFFF); 68333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(ADDInstr)) 68433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(StackReg) 68533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(FPReg) 68633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(TmpReg); 68733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 68833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNdi) { 6894f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 69033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 69133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)). 69233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); 69333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNri) { 6944f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 69533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MBBI->getOperand(0).isReg() && "Expecting register operand."); 69633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR)); 69733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNai) { 6984f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 69933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 70033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm()); 70133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNdi8) { 7024f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 70333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 70433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)). 70533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); 70633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNri8) { 7074f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 70833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MBBI->getOperand(0).isReg() && "Expecting register operand."); 70933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR8)); 71033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNai8) { 7114f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 71233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 71333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm()); 71433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 71533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 716d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov 71794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikovstatic bool spillsCR(const MachineFunction &MF) { 71894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); 71994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov return FuncInfo->isCRSpilled(); 72094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 72194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 72294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov/// MustSaveLR - Return true if this function requires that we save the LR 72394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov/// register onto the stack in the prolog and restore it in the epilog of the 72494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov/// function. 72594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikovstatic bool MustSaveLR(const MachineFunction &MF, unsigned LR) { 72694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>(); 72794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 72894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // We need a save/restore of LR if there is any def of LR (which is 72994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // defined by calls, including the PIC setup sequence), or if there is 73094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // some use of the LR stack slot (e.g. for builtin_return_address). 73194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // (LR comes in 32 and 64 bit versions.) 73294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR); 73394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired(); 73494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 73594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 73694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikovvoid 73716c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovPPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 73894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov RegScavenger *RS) const { 73994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); 74094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 74194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Save and clear the LR state. 74294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 74394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned LR = RegInfo->getRARegister(); 74494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FI->setMustSaveLR(MustSaveLR(MF, LR)); 74594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MF.getRegInfo().setPhysRegUnused(LR); 74694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 74794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Save R31 if necessary 74894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FPSI = FI->getFramePointerSaveIndex(); 74994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool isPPC64 = Subtarget.isPPC64(); 75094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool isDarwinABI = Subtarget.isDarwinABI(); 75194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 75294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 75394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // If the frame pointer save index hasn't been defined yet. 754c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov if (!FPSI && needsFP(MF)) { 75594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Find out what the fix offset of the frame pointer save area. 75694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FPOffset = getFramePointerSaveOffset(isPPC64, isDarwinABI); 75794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Allocate the frame index for frame pointer save area. 75816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov FPSI = MFI->CreateFixedObject(isPPC64? 8 : 4, FPOffset, true); 75994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Save the result. 76094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FI->setFramePointerSaveIndex(FPSI); 76194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 76294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 76394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Reserve stack space to move the linkage area to in case of a tail call. 76494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int TCSPDelta = 0; 7658a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (MF.getTarget().Options.GuaranteedTailCallOpt && 7668a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky (TCSPDelta = FI->getTailCallSPDelta()) < 0) { 76716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov MFI->CreateFixedObject(-1 * TCSPDelta, TCSPDelta, true); 76894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 76994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 77094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Reserve a slot closest to SP or frame pointer if we have a dynalloc or 77194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // a large stack, which will require scavenging a register to materialize a 77294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // large offset. 77394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // FIXME: this doesn't actually check stack size, so is a bit pessimistic 77494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // FIXME: doesn't detect whether or not we need to spill vXX, which requires 77594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // r0 for now. 77694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 7773fd0018af1b692cabfa5a002bf41f1e756aa9ddeHal Finkel if (RegInfo->requiresRegisterScavenging(MF)) 778c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov if (needsFP(MF) || spillsCR(MF)) { 77994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const TargetRegisterClass *GPRC = &PPC::GPRCRegClass; 78094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const TargetRegisterClass *G8RC = &PPC::G8RCRegClass; 78194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const TargetRegisterClass *RC = isPPC64 ? G8RC : GPRC; 78294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 78394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov RC->getAlignment(), 78494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov false)); 78594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 78694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 78794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 78816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF) 78994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const { 79094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Early exit if not using the SVR4 ABI. 79194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (!Subtarget.isSVR4ABI()) 79294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov return; 79394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 79494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Get callee saved register information. 79594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineFrameInfo *FFI = MF.getFrameInfo(); 79694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); 79794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 79894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Early exit if no callee saved registers are modified! 799c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov if (CSI.empty() && !needsFP(MF)) { 80094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov return; 80194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 80294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 80394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinGPR = PPC::R31; 80494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinG8R = PPC::X31; 80594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinFPR = PPC::F31; 80694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinVR = PPC::V31; 80794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 80894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasGPSaveArea = false; 80994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasG8SaveArea = false; 81094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasFPSaveArea = false; 81194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasCRSaveArea = false; 81294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasVRSAVESaveArea = false; 81394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasVRSaveArea = false; 81494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 81594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov SmallVector<CalleeSavedInfo, 18> GPRegs; 81694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov SmallVector<CalleeSavedInfo, 18> G8Regs; 81794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov SmallVector<CalleeSavedInfo, 18> FPRegs; 81894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov SmallVector<CalleeSavedInfo, 18> VRegs; 81994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 82094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 82194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 822c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper if (PPC::GPRCRegClass.contains(Reg)) { 82394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasGPSaveArea = true; 82494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 82594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov GPRegs.push_back(CSI[i]); 82694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 82794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Reg < MinGPR) { 82894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MinGPR = Reg; 82994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 830c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::G8RCRegClass.contains(Reg)) { 83194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasG8SaveArea = true; 83294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 83394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov G8Regs.push_back(CSI[i]); 83494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 83594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Reg < MinG8R) { 83694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MinG8R = Reg; 83794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 838c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::F8RCRegClass.contains(Reg)) { 83994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasFPSaveArea = true; 84094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 84194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FPRegs.push_back(CSI[i]); 84294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 84394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Reg < MinFPR) { 84494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MinFPR = Reg; 84594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 84694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov// FIXME SVR4: Disable CR save area for now. 847c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::CRBITRCRegClass.contains(Reg) || 848c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper PPC::CRRCRegClass.contains(Reg)) { 84994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov// HasCRSaveArea = true; 850c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::VRSAVERCRegClass.contains(Reg)) { 85194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasVRSAVESaveArea = true; 852c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::VRRCRegClass.contains(Reg)) { 85394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasVRSaveArea = true; 85494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 85594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov VRegs.push_back(CSI[i]); 85694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 85794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Reg < MinVR) { 85894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MinVR = Reg; 85994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 86094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } else { 86194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov llvm_unreachable("Unknown RegisterClass!"); 86294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 86394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 86494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 86594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>(); 86694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 86794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int64_t LowerBound = 0; 86894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 86994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Take into account stack space reserved for tail calls. 87094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int TCSPDelta = 0; 8718a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (MF.getTarget().Options.GuaranteedTailCallOpt && 8728a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky (TCSPDelta = PFI->getTailCallSPDelta()) < 0) { 87394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound = TCSPDelta; 87494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 87594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 87694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // The Floating-point register save area is right below the back chain word 87794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // of the previous stack frame. 87894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasFPSaveArea) { 87994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) { 88094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = FPRegs[i].getFrameIdx(); 88194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 88294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 88394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 88494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 885966aeb5788c242cfaca35c56c0ddc0ff778d4376Evan Cheng LowerBound -= (31 - getPPCRegisterNumbering(MinFPR) + 1) * 8; 88694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 88794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 88894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Check whether the frame pointer register is allocated. If so, make sure it 88994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // is spilled to the correct offset. 890c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov if (needsFP(MF)) { 89194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasGPSaveArea = true; 89294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 89394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = PFI->getFramePointerSaveIndex(); 89494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov assert(FI && "No Frame Pointer Save Slot!"); 89594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 89694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 89794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 89894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 89994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // General register save area starts right below the Floating-point 90094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // register save area. 90194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasGPSaveArea || HasG8SaveArea) { 90294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Move general register save area spill slots down, taking into account 90394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // the size of the Floating-point register save area. 90494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) { 90594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = GPRegs[i].getFrameIdx(); 90694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 90794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 90894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 90994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 91094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Move general register save area spill slots down, taking into account 91194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // the size of the Floating-point register save area. 91294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) { 91394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = G8Regs[i].getFrameIdx(); 91494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 91594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 91694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 91794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 91894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinReg = 919966aeb5788c242cfaca35c56c0ddc0ff778d4376Evan Cheng std::min<unsigned>(getPPCRegisterNumbering(MinGPR), 920966aeb5788c242cfaca35c56c0ddc0ff778d4376Evan Cheng getPPCRegisterNumbering(MinG8R)); 92194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 92294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Subtarget.isPPC64()) { 92394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= (31 - MinReg + 1) * 8; 92494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } else { 92594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= (31 - MinReg + 1) * 4; 92694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 92794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 92894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 92994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // The CR save area is below the general register save area. 93094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasCRSaveArea) { 93194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // FIXME SVR4: Is it actually possible to have multiple elements in CSI 93294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // which have the CR/CRBIT register class? 93394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Adjust the frame index of the CR spill slot. 93494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 93594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 93694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 937c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper if (PPC::CRBITRCRegClass.contains(Reg) || 938c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper PPC::CRRCRegClass.contains(Reg)) { 93994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = CSI[i].getFrameIdx(); 94094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 94194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 94294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 94394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 94494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 94594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= 4; // The CR save area is always 4 bytes long. 94694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 94794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 94894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasVRSAVESaveArea) { 94994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // FIXME SVR4: Is it actually possible to have multiple elements in CSI 95094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // which have the VRSAVE register class? 95194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Adjust the frame index of the VRSAVE spill slot. 95294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 95394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 95494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 955c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper if (PPC::VRSAVERCRegClass.contains(Reg)) { 95694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = CSI[i].getFrameIdx(); 95794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 95894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 95994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 96094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 96194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 96294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= 4; // The VRSAVE save area is always 4 bytes long. 96394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 96494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 96594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasVRSaveArea) { 96694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Insert alignment padding, we need 16-byte alignment. 96794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound = (LowerBound - 15) & ~(15); 96894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 96994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = VRegs.size(); i != e; ++i) { 97094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = VRegs[i].getFrameIdx(); 97194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 97294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 97394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 97494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 97594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 976