PPCFrameLowering.cpp revision fc2bb8c4448fa884d79e437cc2d2627a7d7740a8
116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov//=====- PPCFrameLowering.cpp - PPC Frame Information -----------*- C++ -*-===// 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/// 4133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic const unsigned short 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 6733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!I->empty() && I->back().getDesc().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) { 11233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned RegNo = PPCRegisterInfo::getRegisterNumbering(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) { 11933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned RegNo = PPCRegisterInfo::getRegisterNumbering(*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 247d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects() || 248d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov (GuaranteedTailCallOpt && MF.getInfo<PPCFunctionInfo>()->hasFastCall()); 249d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 250d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 251d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 25216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid PPCFrameLowering::emitPrologue(MachineFunction &MF) const { 25333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 25433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 25533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 25633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const PPCInstrInfo &TII = 25733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo()); 25833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 25933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineModuleInfo &MMI = MF.getMMI(); 26033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl; 26133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool needsFrameMoves = MMI.hasDebugInfo() || 262fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola MF.getFunction()->needsUnwindTableEntry(); 26333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Prepare for frame info. 26533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *FrameLabel = 0; 26633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Scan the prolog, looking for an UPDATE_VRSAVE instruction. If we find it, 26833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // process it. 26933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) { 27033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) { 27133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov HandleVRSaveUpdate(MBBI, TII); 27233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; 27333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 27433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 27533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 27633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Move MBBI back to the beginning of the function. 27733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = MBB.begin(); 27833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 27933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Work out frame sizes. 280c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov // FIXME: determineFrameLayout() may change the frame size. This should be 281c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov // moved upper, to some hook. 28233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov determineFrameLayout(MF); 28333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FrameSize = MFI->getStackSize(); 28433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 28533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int NegFrameSize = -FrameSize; 28633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 28733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get processor type. 28833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isPPC64 = Subtarget.isPPC64(); 28933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get operating system 29033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isDarwinABI = Subtarget.isDarwinABI(); 29133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Check if the link register (LR) must be saved. 29233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 29333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool MustSaveLR = FI->mustSaveLR(); 29433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Do we have a frame pointer for this function? 295c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov bool HasFP = hasFP(MF); 29633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 29716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI); 29833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 29933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPOffset = 0; 30033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 30133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Subtarget.isSVR4ABI()) { 30233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *FFI = MF.getFrameInfo(); 30333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPIndex = FI->getFramePointerSaveIndex(); 30433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(FPIndex && "No Frame Pointer Save Slot!"); 30533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FPOffset = FFI->getObjectOffset(FPIndex); 30633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 30716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov FPOffset = PPCFrameLowering::getFramePointerSaveOffset(isPPC64, isDarwinABI); 30833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 30933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 31033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 31133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isPPC64) { 31233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 31333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR8), PPC::X0); 31433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 31533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) 31633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STD)) 31733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X31) 31833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FPOffset/4) 31933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1); 32033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 32133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 32233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STD)) 32333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0) 32433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(LROffset / 4) 32533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1); 32633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 32733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 32833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR), PPC::R0); 32933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 33033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) 33133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) 33233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R31) 33333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FPOffset) 33433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1); 33533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 33633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 33733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) 33833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0) 33933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(LROffset) 34033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1); 34133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 34233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 34333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip if a leaf routine. 34433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!FrameSize) return; 34533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 34633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get stack alignments. 34716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned TargetAlign = getStackAlignment(); 34833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned MaxAlign = MFI->getMaxAlignment(); 34933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer: r1 += NegFrameSize. 35133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is a preferred stack alignment, align R1 now 35233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!isPPC64) { 35333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // PPC32. 35433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ALIGN_STACK && MaxAlign > TargetAlign) { 35533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) && 35633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov "Invalid alignment!"); 35733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(isInt<16>(NegFrameSize) && "Unhandled stack size and alignment!"); 35833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::RLWINM), PPC::R0) 36033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 36133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(0) 36233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(32 - Log2_32(MaxAlign)) 36333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(31); 36433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC) ,PPC::R0) 36533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0, RegState::Kill) 36633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize); 36733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX)) 36833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 36933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 37033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0); 37133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (isInt<16>(NegFrameSize)) { 37233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STWU), PPC::R1) 37333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 37433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize) 37533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1); 37633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 37733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0) 37833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize >> 16); 37933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0) 38033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0, RegState::Kill) 38133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize & 0xFFFF); 38233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX)) 38333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 38433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 38533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0); 38633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 38733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { // PPC64. 38833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ALIGN_STACK && MaxAlign > TargetAlign) { 38933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) && 39033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov "Invalid alignment!"); 39133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(isInt<16>(NegFrameSize) && "Unhandled stack size and alignment!"); 39233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 39333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::RLDICL), PPC::X0) 39433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 39533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(0) 39633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(64 - Log2_32(MaxAlign)); 39733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC8), PPC::X0) 39833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0) 39933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize); 40033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX)) 40133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 40233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 40333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0); 40433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (isInt<16>(NegFrameSize)) { 40533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STDU), PPC::X1) 40633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 40733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize / 4) 40833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1); 40933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 41033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0) 41133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize >> 16); 41233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0) 41333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0, RegState::Kill) 41433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize & 0xFFFF); 41533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX)) 41633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 41733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 41833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0); 41933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 42033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 42133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 42233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 42333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 42433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add the "machine moves" for the instructions we generated above, but in 42533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // reverse order. 42633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 42733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark effective beginning of when frame pointer becomes valid. 42833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameLabel = MMI.getContext().CreateTempSymbol(); 42933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::PROLOG_LABEL)).addSym(FrameLabel); 43033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 43133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Show update of SP. 43233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NegFrameSize) { 43333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(MachineLocation::VirtualFP); 43433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(MachineLocation::VirtualFP, NegFrameSize); 43533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); 43633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 43733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SP(isPPC64 ? PPC::X31 : PPC::R31); 43833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, SP, SP)); 43933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 44033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 44133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 44233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPDst(MachineLocation::VirtualFP, FPOffset); 44333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPSrc(isPPC64 ? PPC::X31 : PPC::R31); 44433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc)); 44533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 44633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 44733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) { 44833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation LRDst(MachineLocation::VirtualFP, LROffset); 44933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation LRSrc(isPPC64 ? PPC::LR8 : PPC::LR); 45033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, LRDst, LRSrc)); 45133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 45233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 45333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 45433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *ReadyLabel = 0; 45533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 45633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is a frame pointer, copy R1 into R31 45733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 45833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!isPPC64) { 45933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), PPC::R31) 46033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 46133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1); 46233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 46333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), PPC::X31) 46433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 46533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1); 46633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 46733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 46833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 46933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ReadyLabel = MMI.getContext().CreateTempSymbol(); 47033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 47133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark effective beginning of when frame pointer is ready. 47233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::PROLOG_LABEL)).addSym(ReadyLabel); 47333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 47433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPDst(HasFP ? (isPPC64 ? PPC::X31 : PPC::R31) : 47533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (isPPC64 ? PPC::X1 : PPC::R1)); 47633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPSrc(MachineLocation::VirtualFP); 47733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(ReadyLabel, FPDst, FPSrc)); 47833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 47933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 48033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 48133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 48233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *Label = HasFP ? ReadyLabel : FrameLabel; 48333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 48433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add callee saved registers to move list. 48533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 48633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 48733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); 48833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Reg = CSI[I].getReg(); 48933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue; 49033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation CSDst(MachineLocation::VirtualFP, Offset); 49133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation CSSrc(Reg); 49233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, CSDst, CSSrc)); 49333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 49433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 49533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 49633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 49716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid PPCFrameLowering::emitEpilogue(MachineFunction &MF, 49833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB) const { 4994f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 5004f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen assert(MBBI != MBB.end() && "Returning block has no terminator"); 50133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const PPCInstrInfo &TII = 50233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo()); 50333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 50433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned RetOpcode = MBBI->getOpcode(); 50533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl; 50633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 507d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov assert((RetOpcode == PPC::BLR || 508d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNri || 509d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNdi || 510d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNai || 511d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNri8 || 512d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNdi8 || 513d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNai8) && 51433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov "Can only insert epilog into returning blocks"); 51533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 51633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get alignment info so we know how to restore r1 51733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 51816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned TargetAlign = getStackAlignment(); 51933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned MaxAlign = MFI->getMaxAlignment(); 52033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 52133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes allocated from the FrameInfo. 52233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FrameSize = MFI->getStackSize(); 52333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 52433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get processor type. 52533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isPPC64 = Subtarget.isPPC64(); 52633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get operating system 52733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isDarwinABI = Subtarget.isDarwinABI(); 52833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Check if the link register (LR) has been saved. 52933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 53033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool MustSaveLR = FI->mustSaveLR(); 53133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Do we have a frame pointer for this function? 532c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov bool HasFP = hasFP(MF); 53333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 53416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI); 53533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 53633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPOffset = 0; 53733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 53833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Subtarget.isSVR4ABI()) { 53933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *FFI = MF.getFrameInfo(); 54033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPIndex = FI->getFramePointerSaveIndex(); 54133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(FPIndex && "No Frame Pointer Save Slot!"); 54233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FPOffset = FFI->getObjectOffset(FPIndex); 54333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 54416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov FPOffset = PPCFrameLowering::getFramePointerSaveOffset(isPPC64, isDarwinABI); 54533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 54633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 54733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 54833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool UsesTCRet = RetOpcode == PPC::TCRETURNri || 54933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNdi || 55033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNai || 55133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNri8 || 55233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNdi8 || 55333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNai8; 55433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 55533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (UsesTCRet) { 55633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int MaxTCRetDelta = FI->getTailCallSPDelta(); 55733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &StackAdjust = MBBI->getOperand(1); 55833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(StackAdjust.isImm() && "Expecting immediate value."); 55933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer. 56033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackAdj = StackAdjust.getImm(); 56133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Delta = StackAdj - MaxTCRetDelta; 56233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert((Delta >= 0) && "Delta must be positive"); 56333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MaxTCRetDelta>0) 56433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize += (StackAdj +Delta); 56533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 56633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize += StackAdj; 56733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 56833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 56933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (FrameSize) { 57033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // The loaded (or persistent) stack pointer value is offset by the 'stwu' 57133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // on entry to the function. Add this offset back now. 57233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!isPPC64) { 57333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If this function contained a fastcc call and GuaranteedTailCallOpt is 57433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // enabled (=> hasFastCall()==true) the fastcc call might contain a tail 57533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // call which invalidates the stack pointer value in SP(0). So we use the 57633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // value of R31 in this case. 57733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (FI->hasFastCall() && isInt<16>(FrameSize)) { 578d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov assert(hasFP(MF) && "Expecting a valid the frame pointer."); 57933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1) 58033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R31).addImm(FrameSize); 58133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if(FI->hasFastCall()) { 58233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0) 58333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FrameSize >> 16); 58433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0) 58533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0, RegState::Kill) 58633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FrameSize & 0xFFFF); 58733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD4)) 58833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 58933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R31) 59033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0); 59133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (isInt<16>(FrameSize) && 59233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (!ALIGN_STACK || TargetAlign >= MaxAlign) && 59333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !MFI->hasVarSizedObjects()) { 59433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1) 59533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1).addImm(FrameSize); 59633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 59733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ),PPC::R1) 59833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(0).addReg(PPC::R1); 59933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 60033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 60133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (FI->hasFastCall() && isInt<16>(FrameSize)) { 602d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov assert(hasFP(MF) && "Expecting a valid the frame pointer."); 60333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1) 60433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X31).addImm(FrameSize); 60533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if(FI->hasFastCall()) { 60633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0) 60733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FrameSize >> 16); 60833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0) 60933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0, RegState::Kill) 61033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FrameSize & 0xFFFF); 61133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD8)) 61233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 61333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X31) 61433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0); 61533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (isInt<16>(FrameSize) && TargetAlign >= MaxAlign && 61633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !MFI->hasVarSizedObjects()) { 61733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1) 61833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1).addImm(FrameSize); 61933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 62033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X1) 62133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(0).addReg(PPC::X1); 62233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 62333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 62433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 62533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 62633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isPPC64) { 62733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 62833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X0) 62933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(LROffset/4).addReg(PPC::X1); 63033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 63133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) 63233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X31) 63333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FPOffset/4).addReg(PPC::X1); 63433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 63533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 63633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR8)).addReg(PPC::X0); 63733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 63833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 63933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R0) 64033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(LROffset).addReg(PPC::R1); 64133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 64233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) 64333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R31) 64433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FPOffset).addReg(PPC::R1); 64533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 64633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 64733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR)).addReg(PPC::R0); 64833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 64933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 65033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Callee pop calling convention. Pop parameter/linkage area. Used for tail 65133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // call optimization 65233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (GuaranteedTailCallOpt && RetOpcode == PPC::BLR && 65333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MF.getFunction()->getCallingConv() == CallingConv::Fast) { 65433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 65533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned CallerAllocatedAmt = FI->getMinReservedArea(); 65633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackReg = isPPC64 ? PPC::X1 : PPC::R1; 65733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FPReg = isPPC64 ? PPC::X31 : PPC::R31; 65833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned TmpReg = isPPC64 ? PPC::X0 : PPC::R0; 65933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned ADDIInstr = isPPC64 ? PPC::ADDI8 : PPC::ADDI; 66033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned ADDInstr = isPPC64 ? PPC::ADD8 : PPC::ADD4; 66133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned LISInstr = isPPC64 ? PPC::LIS8 : PPC::LIS; 66233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned ORIInstr = isPPC64 ? PPC::ORI8 : PPC::ORI; 66333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 66433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (CallerAllocatedAmt && isInt<16>(CallerAllocatedAmt)) { 66533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(ADDIInstr), StackReg) 66633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(StackReg).addImm(CallerAllocatedAmt); 66733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 66833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(LISInstr), TmpReg) 66933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(CallerAllocatedAmt >> 16); 67033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(ORIInstr), TmpReg) 67133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(TmpReg, RegState::Kill) 67233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(CallerAllocatedAmt & 0xFFFF); 67333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(ADDInstr)) 67433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(StackReg) 67533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(FPReg) 67633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(TmpReg); 67733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 67833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNdi) { 6794f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 68033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 68133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)). 68233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); 68333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNri) { 6844f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 68533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MBBI->getOperand(0).isReg() && "Expecting register operand."); 68633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR)); 68733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNai) { 6884f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 68933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 69033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm()); 69133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNdi8) { 6924f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 69333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 69433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)). 69533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); 69633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNri8) { 6974f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 69833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MBBI->getOperand(0).isReg() && "Expecting register operand."); 69933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR8)); 70033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNai8) { 7014f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 70233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 70333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm()); 70433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 70533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 706d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov 70716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid PPCFrameLowering::getInitialFrameState(std::vector<MachineMove> &Moves) const { 708d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov // Initial state of the frame pointer is R1. 709d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov MachineLocation Dst(MachineLocation::VirtualFP); 710d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov MachineLocation Src(PPC::R1, 0); 711d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov Moves.push_back(MachineMove(0, Dst, Src)); 712d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov} 71394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 71494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikovstatic bool spillsCR(const MachineFunction &MF) { 71594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); 71694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov return FuncInfo->isCRSpilled(); 71794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 71894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 71994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov/// MustSaveLR - Return true if this function requires that we save the LR 72094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov/// register onto the stack in the prolog and restore it in the epilog of the 72194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov/// function. 72294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikovstatic bool MustSaveLR(const MachineFunction &MF, unsigned LR) { 72394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>(); 72494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 72594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // We need a save/restore of LR if there is any def of LR (which is 72694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // defined by calls, including the PIC setup sequence), or if there is 72794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // some use of the LR stack slot (e.g. for builtin_return_address). 72894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // (LR comes in 32 and 64 bit versions.) 72994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR); 73094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired(); 73194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 73294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 73394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikovvoid 73416c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovPPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 73594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov RegScavenger *RS) const { 73694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); 73794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 73894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Save and clear the LR state. 73994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 74094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned LR = RegInfo->getRARegister(); 74194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FI->setMustSaveLR(MustSaveLR(MF, LR)); 74294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MF.getRegInfo().setPhysRegUnused(LR); 74394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 74494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Save R31 if necessary 74594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FPSI = FI->getFramePointerSaveIndex(); 74694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool isPPC64 = Subtarget.isPPC64(); 74794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool isDarwinABI = Subtarget.isDarwinABI(); 74894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 74994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 75094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // If the frame pointer save index hasn't been defined yet. 751c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov if (!FPSI && needsFP(MF)) { 75294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Find out what the fix offset of the frame pointer save area. 75394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FPOffset = getFramePointerSaveOffset(isPPC64, isDarwinABI); 75494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Allocate the frame index for frame pointer save area. 75516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov FPSI = MFI->CreateFixedObject(isPPC64? 8 : 4, FPOffset, true); 75694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Save the result. 75794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FI->setFramePointerSaveIndex(FPSI); 75894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 75994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 76094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Reserve stack space to move the linkage area to in case of a tail call. 76194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int TCSPDelta = 0; 76294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (GuaranteedTailCallOpt && (TCSPDelta = FI->getTailCallSPDelta()) < 0) { 76316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov MFI->CreateFixedObject(-1 * TCSPDelta, TCSPDelta, true); 76494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 76594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 76694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Reserve a slot closest to SP or frame pointer if we have a dynalloc or 76794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // a large stack, which will require scavenging a register to materialize a 76894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // large offset. 76994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // FIXME: this doesn't actually check stack size, so is a bit pessimistic 77094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // FIXME: doesn't detect whether or not we need to spill vXX, which requires 77194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // r0 for now. 77294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 77394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (RegInfo->requiresRegisterScavenging(MF)) // FIXME (64-bit): Enable. 774c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov if (needsFP(MF) || spillsCR(MF)) { 77594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const TargetRegisterClass *GPRC = &PPC::GPRCRegClass; 77694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const TargetRegisterClass *G8RC = &PPC::G8RCRegClass; 77794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const TargetRegisterClass *RC = isPPC64 ? G8RC : GPRC; 77894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 77994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov RC->getAlignment(), 78094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov false)); 78194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 78294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 78394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 78416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF) 78594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const { 78694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Early exit if not using the SVR4 ABI. 78794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (!Subtarget.isSVR4ABI()) 78894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov return; 78994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 79094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Get callee saved register information. 79194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineFrameInfo *FFI = MF.getFrameInfo(); 79294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); 79394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 79494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Early exit if no callee saved registers are modified! 795c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov if (CSI.empty() && !needsFP(MF)) { 79694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov return; 79794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 79894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 79994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinGPR = PPC::R31; 80094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinG8R = PPC::X31; 80194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinFPR = PPC::F31; 80294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinVR = PPC::V31; 80394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 80494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasGPSaveArea = false; 80594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasG8SaveArea = false; 80694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasFPSaveArea = false; 80794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasCRSaveArea = false; 80894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasVRSAVESaveArea = false; 80994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasVRSaveArea = false; 81094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 81194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov SmallVector<CalleeSavedInfo, 18> GPRegs; 81294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov SmallVector<CalleeSavedInfo, 18> G8Regs; 81394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov SmallVector<CalleeSavedInfo, 18> FPRegs; 81494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov SmallVector<CalleeSavedInfo, 18> VRegs; 81594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 81694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 81794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 81894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (PPC::GPRCRegisterClass->contains(Reg)) { 81994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasGPSaveArea = true; 82094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 82194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov GPRegs.push_back(CSI[i]); 82294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 82394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Reg < MinGPR) { 82494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MinGPR = Reg; 82594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 82694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } else if (PPC::G8RCRegisterClass->contains(Reg)) { 82794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasG8SaveArea = true; 82894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 82994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov G8Regs.push_back(CSI[i]); 83094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 83194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Reg < MinG8R) { 83294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MinG8R = Reg; 83394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 83494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } else if (PPC::F8RCRegisterClass->contains(Reg)) { 83594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasFPSaveArea = true; 83694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 83794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FPRegs.push_back(CSI[i]); 83894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 83994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Reg < MinFPR) { 84094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MinFPR = Reg; 84194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 84294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov// FIXME SVR4: Disable CR save area for now. 84394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } else if (PPC::CRBITRCRegisterClass->contains(Reg) 84494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov || PPC::CRRCRegisterClass->contains(Reg)) { 84594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov// HasCRSaveArea = true; 84694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } else if (PPC::VRSAVERCRegisterClass->contains(Reg)) { 84794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasVRSAVESaveArea = true; 84894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } else if (PPC::VRRCRegisterClass->contains(Reg)) { 84994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasVRSaveArea = true; 85094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 85194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov VRegs.push_back(CSI[i]); 85294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 85394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Reg < MinVR) { 85494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MinVR = Reg; 85594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 85694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } else { 85794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov llvm_unreachable("Unknown RegisterClass!"); 85894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 85994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 86094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 86194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>(); 86294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 86394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int64_t LowerBound = 0; 86494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 86594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Take into account stack space reserved for tail calls. 86694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int TCSPDelta = 0; 86794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (GuaranteedTailCallOpt && (TCSPDelta = PFI->getTailCallSPDelta()) < 0) { 86894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound = TCSPDelta; 86994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 87094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 87194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // The Floating-point register save area is right below the back chain word 87294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // of the previous stack frame. 87394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasFPSaveArea) { 87494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) { 87594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = FPRegs[i].getFrameIdx(); 87694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 87794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 87894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 87994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 88094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= (31 - PPCRegisterInfo::getRegisterNumbering(MinFPR) + 1) * 8; 88194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 88294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 88394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Check whether the frame pointer register is allocated. If so, make sure it 88494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // is spilled to the correct offset. 885c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov if (needsFP(MF)) { 88694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasGPSaveArea = true; 88794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 88894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = PFI->getFramePointerSaveIndex(); 88994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov assert(FI && "No Frame Pointer Save Slot!"); 89094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 89194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 89294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 89394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 89494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // General register save area starts right below the Floating-point 89594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // register save area. 89694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasGPSaveArea || HasG8SaveArea) { 89794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Move general register save area spill slots down, taking into account 89894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // the size of the Floating-point register save area. 89994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) { 90094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = GPRegs[i].getFrameIdx(); 90194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 90294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 90394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 90494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 90594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Move general register save area spill slots down, taking into account 90694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // the size of the Floating-point register save area. 90794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) { 90894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = G8Regs[i].getFrameIdx(); 90994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 91094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 91194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 91294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 91394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinReg = 91494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov std::min<unsigned>(PPCRegisterInfo::getRegisterNumbering(MinGPR), 91594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov PPCRegisterInfo::getRegisterNumbering(MinG8R)); 91694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 91794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Subtarget.isPPC64()) { 91894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= (31 - MinReg + 1) * 8; 91994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } else { 92094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= (31 - MinReg + 1) * 4; 92194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 92294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 92394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 92494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // The CR save area is below the general register save area. 92594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasCRSaveArea) { 92694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // FIXME SVR4: Is it actually possible to have multiple elements in CSI 92794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // which have the CR/CRBIT register class? 92894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Adjust the frame index of the CR spill slot. 92994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 93094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 93194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 93294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (PPC::CRBITRCRegisterClass->contains(Reg) || 93394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov PPC::CRRCRegisterClass->contains(Reg)) { 93494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = CSI[i].getFrameIdx(); 93594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 93694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 93794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 93894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 93994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 94094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= 4; // The CR save area is always 4 bytes long. 94194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 94294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 94394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasVRSAVESaveArea) { 94494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // FIXME SVR4: Is it actually possible to have multiple elements in CSI 94594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // which have the VRSAVE register class? 94694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Adjust the frame index of the VRSAVE spill slot. 94794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 94894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 94994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 95094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (PPC::VRSAVERCRegisterClass->contains(Reg)) { 95194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = CSI[i].getFrameIdx(); 95294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 95394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 95494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 95594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 95694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 95794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= 4; // The VRSAVE save area is always 4 bytes long. 95894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 95994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 96094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasVRSaveArea) { 96194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Insert alignment padding, we need 16-byte alignment. 96294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound = (LowerBound - 15) & ~(15); 96394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 96494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = VRegs.size(); i != e; ++i) { 96594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = VRegs[i].getFrameIdx(); 96694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 96794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 96894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 96994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 97094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 971