119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//=====- PPCFrameLowering.cpp - PPC Frame Information -----------*- C++ -*-===// 219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// The LLVM Compiler Infrastructure 419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source 619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details. 719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file contains the PPC implementation of TargetFrameLowering class. 1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "PPCFrameLowering.h" 1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "PPCInstrInfo.h" 1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "PPCMachineFunctionInfo.h" 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Function.h" 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineFrameInfo.h" 1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineFunction.h" 2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineInstrBuilder.h" 2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineModuleInfo.h" 2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineRegisterInfo.h" 2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/RegisterScavenging.h" 2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetOptions.h" 2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm; 2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// FIXME This disables some code that aligns the stack to a boundary bigger than 2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// the default (16 bytes on Darwin) when there is a stack local of greater 3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// alignment. This does not currently work, because the delta between old and 3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// new stack pointers is added to offsets that reference incoming parameters 3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// after the prolog is generated, and the code that does that doesn't handle a 3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// variable delta. You don't want to do that anyway; a better approach is to 3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// reserve another register that retains to the incoming stack pointer, and 3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// reference parameters relative to that. 3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define ALIGN_STACK 0 3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// VRRegNo - Map from a numbered VR register to its enum value. 4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// 4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic const unsigned short VRRegNo[] = { 4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PPC::V0 , PPC::V1 , PPC::V2 , PPC::V3 , PPC::V4 , PPC::V5 , PPC::V6 , PPC::V7 , 4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PPC::V8 , PPC::V9 , PPC::V10, PPC::V11, PPC::V12, PPC::V13, PPC::V14, PPC::V15, 4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PPC::V16, PPC::V17, PPC::V18, PPC::V19, PPC::V20, PPC::V21, PPC::V22, PPC::V23, 4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PPC::V24, PPC::V25, PPC::V26, PPC::V27, PPC::V28, PPC::V29, PPC::V30, PPC::V31 4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}; 4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// RemoveVRSaveCode - We have found that this function does not need any code 4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// to manipulate the VRSAVE register, even though it uses vector registers. 5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// This can happen when the only registers used are known to be live in or out 5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// of the function. Remove all of the VRSAVE related code from the function. 5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void RemoveVRSaveCode(MachineInstr *MI) { 5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineBasicBlock *Entry = MI->getParent(); 5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineFunction *MF = Entry->getParent(); 5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // We know that the MTVRSAVE instruction immediately follows MI. Remove it. 5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineBasicBlock::iterator MBBI = MI; 5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ++MBBI; 5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(MBBI != Entry->end() && MBBI->getOpcode() == PPC::MTVRSAVE); 6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MBBI->eraseFromParent(); 6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool RemovedAllMTVRSAVEs = true; 6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // See if we can find and remove the MTVRSAVE instruction from all of the 6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // epilog blocks. 6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I) { 6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If last instruction is a return instruction, add an epilogue 6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!I->empty() && I->back().getDesc().isReturn()) { 6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool FoundIt = false; 6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (MBBI = I->end(); MBBI != I->begin(); ) { 7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman --MBBI; 7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MBBI->getOpcode() == PPC::MTVRSAVE) { 7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MBBI->eraseFromParent(); // remove it. 7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FoundIt = true; 7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RemovedAllMTVRSAVEs &= FoundIt; 7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If we found and removed all MTVRSAVE instructions, remove the read of 8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // VRSAVE as well. 8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RemovedAllMTVRSAVEs) { 8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MBBI = MI; 8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(MBBI != Entry->begin() && "UPDATE_VRSAVE is first instr in block?"); 8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman --MBBI; 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(MBBI->getOpcode() == PPC::MFVRSAVE && "VRSAVE instrs wandered?"); 8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MBBI->eraseFromParent(); 8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Finally, nuke the UPDATE_VRSAVE. 9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MI->eraseFromParent(); 9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// HandleVRSaveUpdate - MI is the UPDATE_VRSAVE instruction introduced by the 9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// instruction selector. Based on the vector registers that have been used, 9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// transform this into the appropriate ORI instruction. 9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void HandleVRSaveUpdate(MachineInstr *MI, const TargetInstrInfo &TII) { 9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineFunction *MF = MI->getParent()->getParent(); 10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = MI->getDebugLoc(); 10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned UsedRegMask = 0; 10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i != 32; ++i) 10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MF->getRegInfo().isPhysRegUsed(VRRegNo[i])) 10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman UsedRegMask |= 1 << (31-i); 10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Live in and live out values already must be in the mask, so don't bother 10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // marking them. 10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (MachineRegisterInfo::livein_iterator 11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I = MF->getRegInfo().livein_begin(), 11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman E = MF->getRegInfo().livein_end(); I != E; ++I) { 11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned RegNo = getPPCRegisterNumbering(I->first); 11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VRRegNo[RegNo] == I->first) // If this really is a vector reg. 11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman UsedRegMask &= ~(1 << (31-RegNo)); // Doesn't need to be marked. 11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (MachineRegisterInfo::liveout_iterator 11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I = MF->getRegInfo().liveout_begin(), 11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman E = MF->getRegInfo().liveout_end(); I != E; ++I) { 11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned RegNo = getPPCRegisterNumbering(*I); 12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VRRegNo[RegNo] == *I) // If this really is a vector reg. 12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman UsedRegMask &= ~(1 << (31-RegNo)); // Doesn't need to be marked. 12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If no registers are used, turn this into a copy. 12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (UsedRegMask == 0) { 12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Remove all VRSAVE code. 12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RemoveVRSaveCode(MI); 12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SrcReg = MI->getOperand(1).getReg(); 13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned DstReg = MI->getOperand(0).getReg(); 13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if ((UsedRegMask & 0xFFFF) == UsedRegMask) { 13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (DstReg != SrcReg) 13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORI), DstReg) 13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(SrcReg) 13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(UsedRegMask); 13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORI), DstReg) 14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(SrcReg, RegState::Kill) 14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(UsedRegMask); 14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if ((UsedRegMask & 0xFFFF0000) == UsedRegMask) { 14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (DstReg != SrcReg) 14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg) 14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(SrcReg) 14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(UsedRegMask >> 16); 14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg) 15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(SrcReg, RegState::Kill) 15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(UsedRegMask >> 16); 15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (DstReg != SrcReg) 15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg) 15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(SrcReg) 15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(UsedRegMask >> 16); 15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg) 15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(SrcReg, RegState::Kill) 16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(UsedRegMask >> 16); 16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORI), DstReg) 16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(DstReg, RegState::Kill) 16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(UsedRegMask & 0xFFFF); 16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Remove the old UPDATE_VRSAVE instruction. 16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MI->eraseFromParent(); 16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// determineFrameLayout - Determine the size of the frame and maximum call 17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// frame size. 17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid PPCFrameLowering::determineFrameLayout(MachineFunction &MF) const { 17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineFrameInfo *MFI = MF.getFrameInfo(); 17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get the number of bytes to allocate from the FrameInfo 17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned FrameSize = MFI->getStackSize(); 17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get the alignments provided by the target, and the maximum alignment 18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // (if any) of the fixed frame objects. 18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned MaxAlign = MFI->getMaxAlignment(); 18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned TargetAlign = getStackAlignment(); 18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned AlignMask = TargetAlign - 1; // 18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If we are a leaf function, and use up to 224 bytes of stack space, 18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // don't have a frame pointer, calls, or dynamic alloca then we do not need 18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // to adjust the stack pointer (we fit in the Red Zone). 18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool DisableRedZone = MF.getFunction()->hasFnAttr(Attribute::NoRedZone); 18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME SVR4 The 32-bit SVR4 ABI has no red zone. 19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!DisableRedZone && 19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FrameSize <= 224 && // Fits in red zone. 19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman !MFI->hasVarSizedObjects() && // No dynamic alloca. 19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman !MFI->adjustsStack() && // No calls. 19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (!ALIGN_STACK || MaxAlign <= TargetAlign)) { // No special alignment. 19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // No need for frame 19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MFI->setStackSize(0); 19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get the maximum call frame size of all the calls. 20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned maxCallFrameSize = MFI->getMaxCallFrameSize(); 20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Maximum call frame needs to be at least big enough for linkage and 8 args. 20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned minCallFrameSize = getMinCallFrameSize(Subtarget.isPPC64(), 20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Subtarget.isDarwinABI()); 20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize); 20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If we have dynamic alloca then maxCallFrameSize needs to be aligned so 20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // that allocations will be aligned. 21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MFI->hasVarSizedObjects()) 21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask; 21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Update maximum call frame size. 21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MFI->setMaxCallFrameSize(maxCallFrameSize); 21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Include call frame size in total. 21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FrameSize += maxCallFrameSize; 21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Make sure the frame is aligned. 22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FrameSize = (FrameSize + AlignMask) & ~AlignMask; 22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Update frame info. 22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MFI->setStackSize(FrameSize); 22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// hasFP - Return true if the specified function actually has a dedicated frame 22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// pointer register. 22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool PPCFrameLowering::hasFP(const MachineFunction &MF) const { 22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MachineFrameInfo *MFI = MF.getFrameInfo(); 23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: This is pretty much broken by design: hasFP() might be called really 23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // early, before the stack layout was calculated and thus hasFP() might return 23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // true or false here depending on the time of call. 23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return (MFI->getStackSize()) && needsFP(MF); 23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// needsFP - Return true if the specified function should have a dedicated frame 23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// pointer register. This is true if the function has variable sized allocas or 23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// if frame pointer elimination is disabled. 23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool PPCFrameLowering::needsFP(const MachineFunction &MF) const { 24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MachineFrameInfo *MFI = MF.getFrameInfo(); 24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Naked functions have no stack frame pushed, so we don't have a frame 24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // pointer. 24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MF.getFunction()->hasFnAttr(Attribute::Naked)) 24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return false; 24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects() || 24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (GuaranteedTailCallOpt && MF.getInfo<PPCFunctionInfo>()->hasFastCall()); 24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid PPCFrameLowering::emitPrologue(MachineFunction &MF) const { 25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineBasicBlock::iterator MBBI = MBB.begin(); 25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineFrameInfo *MFI = MF.getFrameInfo(); 25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const PPCInstrInfo &TII = 25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo()); 25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineModuleInfo &MMI = MF.getMMI(); 26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl; 26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool needsFrameMoves = MMI.hasDebugInfo() || 26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MF.getFunction()->needsUnwindTableEntry(); 26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Prepare for frame info. 26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbol *FrameLabel = 0; 26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Scan the prolog, looking for an UPDATE_VRSAVE instruction. If we find it, 26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // process it. 26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) { 27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) { 27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman HandleVRSaveUpdate(MBBI, TII); 27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Move MBBI back to the beginning of the function. 27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MBBI = MBB.begin(); 27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Work out frame sizes. 28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: determineFrameLayout() may change the frame size. This should be 28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // moved upper, to some hook. 28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman determineFrameLayout(MF); 28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned FrameSize = MFI->getStackSize(); 28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int NegFrameSize = -FrameSize; 28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get processor type. 28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isPPC64 = Subtarget.isPPC64(); 28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get operating system 29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isDarwinABI = Subtarget.isDarwinABI(); 29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Check if the link register (LR) must be saved. 29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool MustSaveLR = FI->mustSaveLR(); 29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Do we have a frame pointer for this function? 29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool HasFP = hasFP(MF); 29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI); 29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FPOffset = 0; 30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasFP) { 30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Subtarget.isSVR4ABI()) { 30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineFrameInfo *FFI = MF.getFrameInfo(); 30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FPIndex = FI->getFramePointerSaveIndex(); 30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(FPIndex && "No Frame Pointer Save Slot!"); 30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FPOffset = FFI->getObjectOffset(FPIndex); 30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FPOffset = PPCFrameLowering::getFramePointerSaveOffset(isPPC64, isDarwinABI); 30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (isPPC64) { 31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MustSaveLR) 31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR8), PPC::X0); 31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasFP) 31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::STD)) 31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X31) 31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(FPOffset/4) 31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1); 32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MustSaveLR) 32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::STD)) 32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X0) 32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(LROffset / 4) 32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1); 32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MustSaveLR) 32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR), PPC::R0); 32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasFP) 33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) 33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R31) 33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(FPOffset) 33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1); 33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MustSaveLR) 33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) 33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R0) 33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(LROffset) 34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1); 34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Skip if a leaf routine. 34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!FrameSize) return; 34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get stack alignments. 34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned TargetAlign = getStackAlignment(); 34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned MaxAlign = MFI->getMaxAlignment(); 34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Adjust stack pointer: r1 += NegFrameSize. 35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If there is a preferred stack alignment, align R1 now 35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!isPPC64) { 35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // PPC32. 35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ALIGN_STACK && MaxAlign > TargetAlign) { 35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) && 35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Invalid alignment!"); 35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(isInt<16>(NegFrameSize) && "Unhandled stack size and alignment!"); 35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::RLWINM), PPC::R0) 36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1) 36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(0) 36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(32 - Log2_32(MaxAlign)) 36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(31); 36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC) ,PPC::R0) 36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R0, RegState::Kill) 36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(NegFrameSize); 36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX)) 36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1) 36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1) 37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R0); 37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (isInt<16>(NegFrameSize)) { 37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::STWU), PPC::R1) 37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1) 37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(NegFrameSize) 37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1); 37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0) 37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(NegFrameSize >> 16); 37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0) 38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R0, RegState::Kill) 38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(NegFrameSize & 0xFFFF); 38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX)) 38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1) 38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1) 38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R0); 38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { // PPC64. 38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ALIGN_STACK && MaxAlign > TargetAlign) { 38919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) && 39019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Invalid alignment!"); 39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(isInt<16>(NegFrameSize) && "Unhandled stack size and alignment!"); 39219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::RLDICL), PPC::X0) 39419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1) 39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(0) 39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(64 - Log2_32(MaxAlign)); 39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC8), PPC::X0) 39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X0) 39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(NegFrameSize); 40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX)) 40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1) 40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1) 40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X0); 40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (isInt<16>(NegFrameSize)) { 40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::STDU), PPC::X1) 40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1) 40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(NegFrameSize / 4) 40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1); 40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0) 41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(NegFrameSize >> 16); 41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0) 41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X0, RegState::Kill) 41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(NegFrameSize & 0xFFFF); 41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX)) 41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1) 41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1) 41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X0); 41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Add the "machine moves" for the instructions we generated above, but in 42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // reverse order. 42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (needsFrameMoves) { 42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Mark effective beginning of when frame pointer becomes valid. 42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FrameLabel = MMI.getContext().CreateTempSymbol(); 42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::PROLOG_LABEL)).addSym(FrameLabel); 43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Show update of SP. 43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (NegFrameSize) { 43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineLocation SPDst(MachineLocation::VirtualFP); 43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineLocation SPSrc(MachineLocation::VirtualFP, NegFrameSize); 43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); 43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineLocation SP(isPPC64 ? PPC::X31 : PPC::R31); 43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Moves.push_back(MachineMove(FrameLabel, SP, SP)); 43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 44119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasFP) { 44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineLocation FPDst(MachineLocation::VirtualFP, FPOffset); 44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineLocation FPSrc(isPPC64 ? PPC::X31 : PPC::R31); 44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc)); 44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MustSaveLR) { 44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineLocation LRDst(MachineLocation::VirtualFP, LROffset); 44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineLocation LRSrc(isPPC64 ? PPC::LR8 : PPC::LR); 45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Moves.push_back(MachineMove(FrameLabel, LRDst, LRSrc)); 45119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbol *ReadyLabel = 0; 45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If there is a frame pointer, copy R1 into R31 45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasFP) { 45819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!isPPC64) { 45919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), PPC::R31) 46019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1) 46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1); 46219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 46319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), PPC::X31) 46419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1) 46519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1); 46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (needsFrameMoves) { 46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ReadyLabel = MMI.getContext().CreateTempSymbol(); 47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 47119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Mark effective beginning of when frame pointer is ready. 47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::PROLOG_LABEL)).addSym(ReadyLabel); 47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineLocation FPDst(HasFP ? (isPPC64 ? PPC::X31 : PPC::R31) : 47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (isPPC64 ? PPC::X1 : PPC::R1)); 47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineLocation FPSrc(MachineLocation::VirtualFP); 47719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Moves.push_back(MachineMove(ReadyLabel, FPDst, FPSrc)); 47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (needsFrameMoves) { 48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbol *Label = HasFP ? ReadyLabel : FrameLabel; 48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Add callee saved registers to move list. 48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); 48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Reg = CSI[I].getReg(); 48919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue; 49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // This is a bit of a hack: CR2LT, CR2GT, CR2EQ and CR2UN are just 49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // subregisters of CR2. We just need to emit a move of CR2. 49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (PPC::CRBITRCRegisterClass->contains(Reg)) 49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineLocation CSDst(MachineLocation::VirtualFP, Offset); 49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineLocation CSSrc(Reg); 49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Moves.push_back(MachineMove(Label, CSDst, CSSrc)); 49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid PPCFrameLowering::emitEpilogue(MachineFunction &MF, 50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineBasicBlock &MBB) const { 50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(MBBI != MBB.end() && "Returning block has no terminator"); 50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const PPCInstrInfo &TII = 50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo()); 50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned RetOpcode = MBBI->getOpcode(); 51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl; 51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert((RetOpcode == PPC::BLR || 51419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RetOpcode == PPC::TCRETURNri || 51519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RetOpcode == PPC::TCRETURNdi || 51619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RetOpcode == PPC::TCRETURNai || 51719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RetOpcode == PPC::TCRETURNri8 || 51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RetOpcode == PPC::TCRETURNdi8 || 51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RetOpcode == PPC::TCRETURNai8) && 52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Can only insert epilog into returning blocks"); 52119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get alignment info so we know how to restore r1 52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MachineFrameInfo *MFI = MF.getFrameInfo(); 52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned TargetAlign = getStackAlignment(); 52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned MaxAlign = MFI->getMaxAlignment(); 52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get the number of bytes allocated from the FrameInfo. 52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FrameSize = MFI->getStackSize(); 52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get processor type. 53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isPPC64 = Subtarget.isPPC64(); 53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get operating system 53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isDarwinABI = Subtarget.isDarwinABI(); 53419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Check if the link register (LR) has been saved. 53519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 53619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool MustSaveLR = FI->mustSaveLR(); 53719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Do we have a frame pointer for this function? 53819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool HasFP = hasFP(MF); 53919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 54019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI); 54119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FPOffset = 0; 54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasFP) { 54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Subtarget.isSVR4ABI()) { 54519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineFrameInfo *FFI = MF.getFrameInfo(); 54619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FPIndex = FI->getFramePointerSaveIndex(); 54719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(FPIndex && "No Frame Pointer Save Slot!"); 54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FPOffset = FFI->getObjectOffset(FPIndex); 54919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 55019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FPOffset = PPCFrameLowering::getFramePointerSaveOffset(isPPC64, isDarwinABI); 55119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 55219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool UsesTCRet = RetOpcode == PPC::TCRETURNri || 55519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RetOpcode == PPC::TCRETURNdi || 55619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RetOpcode == PPC::TCRETURNai || 55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RetOpcode == PPC::TCRETURNri8 || 55819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RetOpcode == PPC::TCRETURNdi8 || 55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RetOpcode == PPC::TCRETURNai8; 56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (UsesTCRet) { 56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int MaxTCRetDelta = FI->getTailCallSPDelta(); 56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineOperand &StackAdjust = MBBI->getOperand(1); 56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(StackAdjust.isImm() && "Expecting immediate value."); 56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Adjust stack pointer. 56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int StackAdj = StackAdjust.getImm(); 56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int Delta = StackAdj - MaxTCRetDelta; 56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert((Delta >= 0) && "Delta must be positive"); 56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MaxTCRetDelta>0) 57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FrameSize += (StackAdj +Delta); 57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FrameSize += StackAdj; 57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (FrameSize) { 57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The loaded (or persistent) stack pointer value is offset by the 'stwu' 57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // on entry to the function. Add this offset back now. 57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!isPPC64) { 57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If this function contained a fastcc call and GuaranteedTailCallOpt is 58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // enabled (=> hasFastCall()==true) the fastcc call might contain a tail 58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // call which invalidates the stack pointer value in SP(0). So we use the 58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // value of R31 in this case. 58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (FI->hasFastCall() && isInt<16>(FrameSize)) { 58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(hasFP(MF) && "Expecting a valid the frame pointer."); 58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1) 58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R31).addImm(FrameSize); 58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if(FI->hasFastCall()) { 58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0) 58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(FrameSize >> 16); 59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0) 59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R0, RegState::Kill) 59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(FrameSize & 0xFFFF); 59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD4)) 59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1) 59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R31) 59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R0); 59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (isInt<16>(FrameSize) && 59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (!ALIGN_STACK || TargetAlign >= MaxAlign) && 59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman !MFI->hasVarSizedObjects()) { 60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1) 60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::R1).addImm(FrameSize); 60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ),PPC::R1) 60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(0).addReg(PPC::R1); 60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (FI->hasFastCall() && isInt<16>(FrameSize)) { 60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(hasFP(MF) && "Expecting a valid the frame pointer."); 60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1) 61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X31).addImm(FrameSize); 61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if(FI->hasFastCall()) { 61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0) 61319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(FrameSize >> 16); 61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0) 61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X0, RegState::Kill) 61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(FrameSize & 0xFFFF); 61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD8)) 61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1) 61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X31) 62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X0); 62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (isInt<16>(FrameSize) && TargetAlign >= MaxAlign && 62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman !MFI->hasVarSizedObjects()) { 62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1) 62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(PPC::X1).addImm(FrameSize); 62519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 62619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X1) 62719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(0).addReg(PPC::X1); 62819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 62919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (isPPC64) { 63319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MustSaveLR) 63419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X0) 63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(LROffset/4).addReg(PPC::X1); 63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasFP) 63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X31) 63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(FPOffset/4).addReg(PPC::X1); 64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MustSaveLR) 64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR8)).addReg(PPC::X0); 64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MustSaveLR) 64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R0) 64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(LROffset).addReg(PPC::R1); 64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasFP) 64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R31) 65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(FPOffset).addReg(PPC::R1); 65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MustSaveLR) 65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR)).addReg(PPC::R0); 65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Callee pop calling convention. Pop parameter/linkage area. Used for tail 65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // call optimization 65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (GuaranteedTailCallOpt && RetOpcode == PPC::BLR && 65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MF.getFunction()->getCallingConv() == CallingConv::Fast) { 66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned CallerAllocatedAmt = FI->getMinReservedArea(); 66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned StackReg = isPPC64 ? PPC::X1 : PPC::R1; 66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned FPReg = isPPC64 ? PPC::X31 : PPC::R31; 66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned TmpReg = isPPC64 ? PPC::X0 : PPC::R0; 66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ADDIInstr = isPPC64 ? PPC::ADDI8 : PPC::ADDI; 66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ADDInstr = isPPC64 ? PPC::ADD8 : PPC::ADD4; 66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned LISInstr = isPPC64 ? PPC::LIS8 : PPC::LIS; 66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ORIInstr = isPPC64 ? PPC::ORI8 : PPC::ORI; 66919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (CallerAllocatedAmt && isInt<16>(CallerAllocatedAmt)) { 67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(ADDIInstr), StackReg) 67219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(StackReg).addImm(CallerAllocatedAmt); 67319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 67419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(LISInstr), TmpReg) 67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(CallerAllocatedAmt >> 16); 67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(ORIInstr), TmpReg) 67719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(TmpReg, RegState::Kill) 67819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addImm(CallerAllocatedAmt & 0xFFFF); 67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(ADDInstr)) 68019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(StackReg) 68119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(FPReg) 68219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .addReg(TmpReg); 68319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 68419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (RetOpcode == PPC::TCRETURNdi) { 68519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MBBI = MBB.getLastNonDebugInstr(); 68619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineOperand &JumpTarget = MBBI->getOperand(0); 68719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)). 68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); 68919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (RetOpcode == PPC::TCRETURNri) { 69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MBBI = MBB.getLastNonDebugInstr(); 69119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(MBBI->getOperand(0).isReg() && "Expecting register operand."); 69219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR)); 69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (RetOpcode == PPC::TCRETURNai) { 69419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MBBI = MBB.getLastNonDebugInstr(); 69519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineOperand &JumpTarget = MBBI->getOperand(0); 69619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm()); 69719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (RetOpcode == PPC::TCRETURNdi8) { 69819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MBBI = MBB.getLastNonDebugInstr(); 69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineOperand &JumpTarget = MBBI->getOperand(0); 70019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)). 70119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); 70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (RetOpcode == PPC::TCRETURNri8) { 70319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MBBI = MBB.getLastNonDebugInstr(); 70419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(MBBI->getOperand(0).isReg() && "Expecting register operand."); 70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR8)); 70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (RetOpcode == PPC::TCRETURNai8) { 70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MBBI = MBB.getLastNonDebugInstr(); 70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineOperand &JumpTarget = MBBI->getOperand(0); 70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm()); 71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool spillsCR(const MachineFunction &MF) { 71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); 71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return FuncInfo->isCRSpilled(); 71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 71719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// MustSaveLR - Return true if this function requires that we save the LR 71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// register onto the stack in the prolog and restore it in the epilog of the 72019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// function. 72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool MustSaveLR(const MachineFunction &MF, unsigned LR) { 72219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>(); 72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 72419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // We need a save/restore of LR if there is any def of LR (which is 72519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // defined by calls, including the PIC setup sequence), or if there is 72619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // some use of the LR stack slot (e.g. for builtin_return_address). 72719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // (LR comes in 32 and 64 bit versions.) 72819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR); 72919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired(); 73019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 73119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 73219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid 73319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanPPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 73419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RegScavenger *RS) const { 73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); 73619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 73719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Save and clear the LR state. 73819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 73919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned LR = RegInfo->getRARegister(); 74019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FI->setMustSaveLR(MustSaveLR(MF, LR)); 74119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MF.getRegInfo().setPhysRegUnused(LR); 74219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 74319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Save R31 if necessary 74419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FPSI = FI->getFramePointerSaveIndex(); 74519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isPPC64 = Subtarget.isPPC64(); 74619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isDarwinABI = Subtarget.isDarwinABI(); 74719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineFrameInfo *MFI = MF.getFrameInfo(); 74819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 74919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If the frame pointer save index hasn't been defined yet. 75019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!FPSI && needsFP(MF)) { 75119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Find out what the fix offset of the frame pointer save area. 75219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FPOffset = getFramePointerSaveOffset(isPPC64, isDarwinABI); 75319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Allocate the frame index for frame pointer save area. 75419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FPSI = MFI->CreateFixedObject(isPPC64? 8 : 4, FPOffset, true); 75519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Save the result. 75619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FI->setFramePointerSaveIndex(FPSI); 75719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 75819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 75919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Reserve stack space to move the linkage area to in case of a tail call. 76019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int TCSPDelta = 0; 76119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (GuaranteedTailCallOpt && (TCSPDelta = FI->getTailCallSPDelta()) < 0) { 76219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MFI->CreateFixedObject(-1 * TCSPDelta, TCSPDelta, true); 76319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 76419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 76519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Reserve a slot closest to SP or frame pointer if we have a dynalloc or 76619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // a large stack, which will require scavenging a register to materialize a 76719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // large offset. 76819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: this doesn't actually check stack size, so is a bit pessimistic 76919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: doesn't detect whether or not we need to spill vXX, which requires 77019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // r0 for now. 77119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 77219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RegInfo->requiresRegisterScavenging(MF)) // FIXME (64-bit): Enable. 77319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (needsFP(MF) || spillsCR(MF)) { 77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetRegisterClass *GPRC = &PPC::GPRCRegClass; 77519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetRegisterClass *G8RC = &PPC::G8RCRegClass; 77619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetRegisterClass *RC = isPPC64 ? G8RC : GPRC; 77719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 77819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RC->getAlignment(), 77919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false)); 78019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 78119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 78219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 78319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF) 78419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const { 78519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Early exit if not using the SVR4 ABI. 78619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!Subtarget.isSVR4ABI()) 78719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 78819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 78919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get callee saved register information. 79019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineFrameInfo *FFI = MF.getFrameInfo(); 79119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); 79219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 79319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Early exit if no callee saved registers are modified! 79419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (CSI.empty() && !needsFP(MF)) { 79519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 79619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 79719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 79819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned MinGPR = PPC::R31; 79919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned MinG8R = PPC::X31; 80019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned MinFPR = PPC::F31; 80119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned MinVR = PPC::V31; 80219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 80319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool HasGPSaveArea = false; 80419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool HasG8SaveArea = false; 80519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool HasFPSaveArea = false; 80619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool HasCRSaveArea = false; 80719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool HasVRSAVESaveArea = false; 80819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool HasVRSaveArea = false; 80919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 81019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<CalleeSavedInfo, 18> GPRegs; 81119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<CalleeSavedInfo, 18> G8Regs; 81219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<CalleeSavedInfo, 18> FPRegs; 81319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<CalleeSavedInfo, 18> VRegs; 81419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 81519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 81619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Reg = CSI[i].getReg(); 81719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (PPC::GPRCRegisterClass->contains(Reg)) { 81819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman HasGPSaveArea = true; 81919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 82019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman GPRegs.push_back(CSI[i]); 82119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 82219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Reg < MinGPR) { 82319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MinGPR = Reg; 82419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 82519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (PPC::G8RCRegisterClass->contains(Reg)) { 82619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman HasG8SaveArea = true; 82719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 82819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman G8Regs.push_back(CSI[i]); 82919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 83019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Reg < MinG8R) { 83119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MinG8R = Reg; 83219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 83319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (PPC::F8RCRegisterClass->contains(Reg)) { 83419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman HasFPSaveArea = true; 83519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 83619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FPRegs.push_back(CSI[i]); 83719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 83819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Reg < MinFPR) { 83919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MinFPR = Reg; 84019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 84119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// FIXME SVR4: Disable CR save area for now. 84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (PPC::CRBITRCRegisterClass->contains(Reg) 84319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman || PPC::CRRCRegisterClass->contains(Reg)) { 84419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// HasCRSaveArea = true; 84519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (PPC::VRSAVERCRegisterClass->contains(Reg)) { 84619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman HasVRSAVESaveArea = true; 84719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (PPC::VRRCRegisterClass->contains(Reg)) { 84819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman HasVRSaveArea = true; 84919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 85019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VRegs.push_back(CSI[i]); 85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 85219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Reg < MinVR) { 85319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MinVR = Reg; 85419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 85519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 85619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm_unreachable("Unknown RegisterClass!"); 85719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 85819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 85919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 86019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>(); 86119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 86219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t LowerBound = 0; 86319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 86419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Take into account stack space reserved for tail calls. 86519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int TCSPDelta = 0; 86619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (GuaranteedTailCallOpt && (TCSPDelta = PFI->getTailCallSPDelta()) < 0) { 86719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LowerBound = TCSPDelta; 86819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 86919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 87019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The Floating-point register save area is right below the back chain word 87119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // of the previous stack frame. 87219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasFPSaveArea) { 87319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) { 87419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FI = FPRegs[i].getFrameIdx(); 87519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 87619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 87719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 87819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 87919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LowerBound -= (31 - getPPCRegisterNumbering(MinFPR) + 1) * 8; 88019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 88119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 88219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Check whether the frame pointer register is allocated. If so, make sure it 88319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // is spilled to the correct offset. 88419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (needsFP(MF)) { 88519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman HasGPSaveArea = true; 88619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 88719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FI = PFI->getFramePointerSaveIndex(); 88819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(FI && "No Frame Pointer Save Slot!"); 88919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 89019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 89119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 89219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 89319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // General register save area starts right below the Floating-point 89419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // register save area. 89519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasGPSaveArea || HasG8SaveArea) { 89619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Move general register save area spill slots down, taking into account 89719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the size of the Floating-point register save area. 89819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) { 89919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FI = GPRegs[i].getFrameIdx(); 90019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 90119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 90219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 90319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 90419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Move general register save area spill slots down, taking into account 90519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the size of the Floating-point register save area. 90619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) { 90719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FI = G8Regs[i].getFrameIdx(); 90819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 90919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 91019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 91119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 91219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned MinReg = 91319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::min<unsigned>(getPPCRegisterNumbering(MinGPR), 91419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getPPCRegisterNumbering(MinG8R)); 91519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 91619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Subtarget.isPPC64()) { 91719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LowerBound -= (31 - MinReg + 1) * 8; 91819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 91919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LowerBound -= (31 - MinReg + 1) * 4; 92019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 92119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 92219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 92319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The CR save area is below the general register save area. 92419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasCRSaveArea) { 92519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME SVR4: Is it actually possible to have multiple elements in CSI 92619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // which have the CR/CRBIT register class? 92719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Adjust the frame index of the CR spill slot. 92819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 92919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Reg = CSI[i].getReg(); 93019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 93119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (PPC::CRBITRCRegisterClass->contains(Reg) || 93219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PPC::CRRCRegisterClass->contains(Reg)) { 93319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FI = CSI[i].getFrameIdx(); 93419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 93519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 93619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 93719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 93819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 93919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LowerBound -= 4; // The CR save area is always 4 bytes long. 94019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 94119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 94219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasVRSAVESaveArea) { 94319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME SVR4: Is it actually possible to have multiple elements in CSI 94419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // which have the VRSAVE register class? 94519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Adjust the frame index of the VRSAVE spill slot. 94619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 94719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Reg = CSI[i].getReg(); 94819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 94919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (PPC::VRSAVERCRegisterClass->contains(Reg)) { 95019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FI = CSI[i].getFrameIdx(); 95119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 95219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 95319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 95419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 95519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 95619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LowerBound -= 4; // The VRSAVE save area is always 4 bytes long. 95719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 95819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 95919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HasVRSaveArea) { 96019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Insert alignment padding, we need 16-byte alignment. 96119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LowerBound = (LowerBound - 15) & ~(15); 96219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 96319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = VRegs.size(); i != e; ++i) { 96419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FI = VRegs[i].getFrameIdx(); 96519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 96619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 96719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 96819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 96919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 970