PPCFrameLowering.cpp revision 99cb622041a0839c7dfcf0263c5102a305a0fdb5
131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- PPCFrameLowering.cpp - PPC Frame Information ----------------------===// 233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The LLVM Compiler Infrastructure 433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// This file is distributed under the University of Illinois Open Source 633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// License. See LICENSE.TXT for details. 733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 1016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov// This file contains the PPC implementation of TargetFrameLowering class. 1133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 1233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 1333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 1416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "PPCFrameLowering.h" 159d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky#include "PPCInstrBuilder.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "PPCInstrInfo.h" 1733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "PPCMachineFunctionInfo.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" 240b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 2533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Target/TargetOptions.h" 2633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 2733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovusing namespace llvm; 2833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 2933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// FIXME This disables some code that aligns the stack to a boundary bigger than 3033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// the default (16 bytes on Darwin) when there is a stack local of greater 3133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// alignment. This does not currently work, because the delta between old and 3233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// new stack pointers is added to offsets that reference incoming parameters 3333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// after the prolog is generated, and the code that does that doesn't handle a 3433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// variable delta. You don't want to do that anyway; a better approach is to 3533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// reserve another register that retains to the incoming stack pointer, and 3633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// reference parameters relative to that. 3733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#define ALIGN_STACK 0 3833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 4033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// VRRegNo - Map from a numbered VR register to its enum value. 4133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// 42b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t VRRegNo[] = { 4333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPC::V0 , PPC::V1 , PPC::V2 , PPC::V3 , PPC::V4 , PPC::V5 , PPC::V6 , PPC::V7 , 4433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPC::V8 , PPC::V9 , PPC::V10, PPC::V11, PPC::V12, PPC::V13, PPC::V14, PPC::V15, 4533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPC::V16, PPC::V17, PPC::V18, PPC::V19, PPC::V20, PPC::V21, PPC::V22, PPC::V23, 4633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPC::V24, PPC::V25, PPC::V26, PPC::V27, PPC::V28, PPC::V29, PPC::V30, PPC::V31 4733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov}; 4833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 4933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// RemoveVRSaveCode - We have found that this function does not need any code 5033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// to manipulate the VRSAVE register, even though it uses vector registers. 5133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// This can happen when the only registers used are known to be live in or out 5233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// of the function. Remove all of the VRSAVE related code from the function. 53a5d0ab555384baa293b06686bec5a01fb9638ca3Bill Schmidt/// FIXME: The removal of the code results in a compile failure at -O0 when the 54a5d0ab555384baa293b06686bec5a01fb9638ca3Bill Schmidt/// function contains a function call, as the GPR containing original VRSAVE 55a5d0ab555384baa293b06686bec5a01fb9638ca3Bill Schmidt/// contents is spilled and reloaded around the call. Without the prolog code, 56a5d0ab555384baa293b06686bec5a01fb9638ca3Bill Schmidt/// the spill instruction refers to an undefined register. This code needs 57a5d0ab555384baa293b06686bec5a01fb9638ca3Bill Schmidt/// to account for all uses of that GPR. 5833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic void RemoveVRSaveCode(MachineInstr *MI) { 5933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock *Entry = MI->getParent(); 6033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFunction *MF = Entry->getParent(); 6133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 6233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // We know that the MTVRSAVE instruction immediately follows MI. Remove it. 6333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MI; 6433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ++MBBI; 6533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MBBI != Entry->end() && MBBI->getOpcode() == PPC::MTVRSAVE); 6633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI->eraseFromParent(); 6733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 6833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool RemovedAllMTVRSAVEs = true; 6933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // See if we can find and remove the MTVRSAVE instruction from all of the 7033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // epilog blocks. 7133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I) { 7233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If last instruction is a return instruction, add an epilogue 735a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (!I->empty() && I->back().isReturn()) { 7433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool FoundIt = false; 7533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MBBI = I->end(); MBBI != I->begin(); ) { 7633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov --MBBI; 7733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI->getOpcode() == PPC::MTVRSAVE) { 7833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI->eraseFromParent(); // remove it. 7933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FoundIt = true; 8033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; 8133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 8233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 8333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RemovedAllMTVRSAVEs &= FoundIt; 8433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 8533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 8633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 8733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we found and removed all MTVRSAVE instructions, remove the read of 8833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // VRSAVE as well. 8933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RemovedAllMTVRSAVEs) { 9033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = MI; 9133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MBBI != Entry->begin() && "UPDATE_VRSAVE is first instr in block?"); 9233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov --MBBI; 9333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MBBI->getOpcode() == PPC::MFVRSAVE && "VRSAVE instrs wandered?"); 9433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI->eraseFromParent(); 9533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 9633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 9733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Finally, nuke the UPDATE_VRSAVE. 9833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->eraseFromParent(); 9933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 10033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 10133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// HandleVRSaveUpdate - MI is the UPDATE_VRSAVE instruction introduced by the 10233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// instruction selector. Based on the vector registers that have been used, 10333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// transform this into the appropriate ORI instruction. 10433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic void HandleVRSaveUpdate(MachineInstr *MI, const TargetInstrInfo &TII) { 10533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFunction *MF = MI->getParent()->getParent(); 106aa6047d23d8ed55abd8545f5cbe82cd13cbd756aHal Finkel const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); 10733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 10833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 10933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned UsedRegMask = 0; 11033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned i = 0; i != 32; ++i) 11133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MF->getRegInfo().isPhysRegUsed(VRRegNo[i])) 11233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov UsedRegMask |= 1 << (31-i); 11333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 11433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Live in and live out values already must be in the mask, so don't bother 11533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // marking them. 11633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MachineRegisterInfo::livein_iterator 11733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I = MF->getRegInfo().livein_begin(), 11833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov E = MF->getRegInfo().livein_end(); I != E; ++I) { 119aa6047d23d8ed55abd8545f5cbe82cd13cbd756aHal Finkel unsigned RegNo = TRI->getEncodingValue(I->first); 12033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (VRRegNo[RegNo] == I->first) // If this really is a vector reg. 12133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov UsedRegMask &= ~(1 << (31-RegNo)); // Doesn't need to be marked. 12233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 1230a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen 1240a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen // Live out registers appear as use operands on return instructions. 1250a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen for (MachineFunction::const_iterator BI = MF->begin(), BE = MF->end(); 1260a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen UsedRegMask != 0 && BI != BE; ++BI) { 1270a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen const MachineBasicBlock &MBB = *BI; 1280a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen if (MBB.empty() || !MBB.back().isReturn()) 1290a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen continue; 1300a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen const MachineInstr &Ret = MBB.back(); 1310a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen for (unsigned I = 0, E = Ret.getNumOperands(); I != E; ++I) { 1320a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen const MachineOperand &MO = Ret.getOperand(I); 1330a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen if (!MO.isReg() || !PPC::VRRCRegClass.contains(MO.getReg())) 1340a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen continue; 135aa6047d23d8ed55abd8545f5cbe82cd13cbd756aHal Finkel unsigned RegNo = TRI->getEncodingValue(MO.getReg()); 1360a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen UsedRegMask &= ~(1 << (31-RegNo)); 1370a9d1d31e9b3239b1dc38a67d31810c4bb405d0aJakob Stoklund Olesen } 13833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 13933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 14033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If no registers are used, turn this into a copy. 14133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (UsedRegMask == 0) { 14233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Remove all VRSAVE code. 14333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RemoveVRSaveCode(MI); 14433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return; 14533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 14633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 14733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned SrcReg = MI->getOperand(1).getReg(); 14833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned DstReg = MI->getOperand(0).getReg(); 14933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 15033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((UsedRegMask & 0xFFFF) == UsedRegMask) { 15133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (DstReg != SrcReg) 15233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORI), DstReg) 15333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(SrcReg) 15433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask); 15533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 15633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORI), DstReg) 15733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(SrcReg, RegState::Kill) 15833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask); 15933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((UsedRegMask & 0xFFFF0000) == UsedRegMask) { 16033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (DstReg != SrcReg) 16133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg) 16233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(SrcReg) 16333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask >> 16); 16433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 16533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg) 16633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(SrcReg, RegState::Kill) 16733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask >> 16); 16833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 16933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (DstReg != SrcReg) 17033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg) 17133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(SrcReg) 17233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask >> 16); 17333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 17433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg) 17533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(SrcReg, RegState::Kill) 17633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask >> 16); 17733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 17833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORI), DstReg) 17933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(DstReg, RegState::Kill) 18033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(UsedRegMask & 0xFFFF); 18133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 18233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 18333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Remove the old UPDATE_VRSAVE instruction. 18433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->eraseFromParent(); 18533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 18633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 1879d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divackystatic bool spillsCR(const MachineFunction &MF) { 1889d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); 1899d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky return FuncInfo->isCRSpilled(); 1909d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky} 1919d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 1923f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkelstatic bool spillsVRSAVE(const MachineFunction &MF) { 1933f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); 1943f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel return FuncInfo->isVRSAVESpilled(); 1953f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel} 1963f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel 1970cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkelstatic bool hasSpills(const MachineFunction &MF) { 1980cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); 1990cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel return FuncInfo->hasSpills(); 2000cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel} 2010cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel 202324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkelstatic bool hasNonRISpills(const MachineFunction &MF) { 203324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); 204324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel return FuncInfo->hasNonRISpills(); 205324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel} 206324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel 20733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// determineFrameLayout - Determine the size of the frame and maximum call 20833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// frame size. 2090cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkelunsigned PPCFrameLowering::determineFrameLayout(MachineFunction &MF, 2100cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel bool UpdateMF, 2110cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel bool UseEstimate) const { 21233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 21333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 21433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes to allocate from the FrameInfo 2150cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel unsigned FrameSize = 2160cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel UseEstimate ? MFI->estimateStackSize(MF) : MFI->getStackSize(); 21733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 21833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the alignments provided by the target, and the maximum alignment 21933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // (if any) of the fixed frame objects. 22033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned MaxAlign = MFI->getMaxAlignment(); 22116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned TargetAlign = getStackAlignment(); 22233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned AlignMask = TargetAlign - 1; // 22333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 22433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we are a leaf function, and use up to 224 bytes of stack space, 22533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // don't have a frame pointer, calls, or dynamic alloca then we do not need 226fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel // to adjust the stack pointer (we fit in the Red Zone). 22765396823305326bcb379e88a95ded318e1da875cBill Schmidt // The 32-bit SVR4 ABI has no Red Zone. However, it can still generate 22865396823305326bcb379e88a95ded318e1da875cBill Schmidt // stackless code if all local vars are reg-allocated. 229831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling bool DisableRedZone = MF.getFunction()->getAttributes(). 230831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling hasAttribute(AttributeSet::FunctionIndex, Attribute::NoRedZone); 23133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!DisableRedZone && 23265396823305326bcb379e88a95ded318e1da875cBill Schmidt (Subtarget.isPPC64() || // 32-bit SVR4, no stack- 23365396823305326bcb379e88a95ded318e1da875cBill Schmidt !Subtarget.isSVR4ABI() || // allocated locals. 23465396823305326bcb379e88a95ded318e1da875cBill Schmidt FrameSize == 0) && 23533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize <= 224 && // Fits in red zone. 23633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !MFI->hasVarSizedObjects() && // No dynamic alloca. 23733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !MFI->adjustsStack() && // No calls. 23833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (!ALIGN_STACK || MaxAlign <= TargetAlign)) { // No special alignment. 23933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // No need for frame 2400cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel if (UpdateMF) 2410cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel MFI->setStackSize(0); 2420cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel return 0; 24333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 24433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 24533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the maximum call frame size of all the calls. 24633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned maxCallFrameSize = MFI->getMaxCallFrameSize(); 24733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 24833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Maximum call frame needs to be at least big enough for linkage and 8 args. 24933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned minCallFrameSize = getMinCallFrameSize(Subtarget.isPPC64(), 25033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Subtarget.isDarwinABI()); 25133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize); 25233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 25333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we have dynamic alloca then maxCallFrameSize needs to be aligned so 25433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // that allocations will be aligned. 25533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MFI->hasVarSizedObjects()) 25633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask; 25733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 25833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Update maximum call frame size. 2590cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel if (UpdateMF) 2600cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel MFI->setMaxCallFrameSize(maxCallFrameSize); 26133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Include call frame size in total. 26333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize += maxCallFrameSize; 26433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Make sure the frame is aligned. 26633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize = (FrameSize + AlignMask) & ~AlignMask; 26733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Update frame info. 2690cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel if (UpdateMF) 2700cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel MFI->setStackSize(FrameSize); 2710cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel 2720cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel return FrameSize; 27333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 27433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 275d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// hasFP - Return true if the specified function actually has a dedicated frame 276d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// pointer register. 27716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool PPCFrameLowering::hasFP(const MachineFunction &MF) const { 278d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 279c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov // FIXME: This is pretty much broken by design: hasFP() might be called really 280c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov // early, before the stack layout was calculated and thus hasFP() might return 281c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov // true or false here depending on the time of call. 282c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov return (MFI->getStackSize()) && needsFP(MF); 283c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov} 284c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov 285c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov// needsFP - Return true if the specified function should have a dedicated frame 286c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov// pointer register. This is true if the function has variable sized allocas or 287c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov// if frame pointer elimination is disabled. 28816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool PPCFrameLowering::needsFP(const MachineFunction &MF) const { 289c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 290d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 291d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov // Naked functions have no stack frame pushed, so we don't have a frame 292d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov // pointer. 293831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (MF.getFunction()->getAttributes().hasAttribute(AttributeSet::FunctionIndex, 294831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling Attribute::Naked)) 295d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return false; 296d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 2978a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky return MF.getTarget().Options.DisableFramePointerElim(MF) || 2988a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky MFI->hasVarSizedObjects() || 2998a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky (MF.getTarget().Options.GuaranteedTailCallOpt && 3008a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky MF.getInfo<PPCFunctionInfo>()->hasFastCall()); 301d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 302d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 303e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkelvoid PPCFrameLowering::replaceFPWithRealFP(MachineFunction &MF) const { 304e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel bool is31 = needsFP(MF); 305e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel unsigned FPReg = is31 ? PPC::R31 : PPC::R1; 306e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel unsigned FP8Reg = is31 ? PPC::X31 : PPC::X1; 307e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel 308e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); 309e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel BI != BE; ++BI) 310e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel for (MachineBasicBlock::iterator MBBI = BI->end(); MBBI != BI->begin(); ) { 311e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel --MBBI; 312e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel for (unsigned I = 0, E = MBBI->getNumOperands(); I != E; ++I) { 313e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel MachineOperand &MO = MBBI->getOperand(I); 314e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel if (!MO.isReg()) 315e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel continue; 316e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel 317e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel switch (MO.getReg()) { 318e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel case PPC::FP: 319e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel MO.setReg(FPReg); 320e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel break; 321e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel case PPC::FP8: 322e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel MO.setReg(FP8Reg); 323e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel break; 324e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel } 325e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel } 326e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel } 327e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel} 328d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 32916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid PPCFrameLowering::emitPrologue(MachineFunction &MF) const { 33033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 33133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 33233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 33333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const PPCInstrInfo &TII = 33433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo()); 33533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 33633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineModuleInfo &MMI = MF.getMMI(); 33799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); 33833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl; 33933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool needsFrameMoves = MMI.hasDebugInfo() || 340fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola MF.getFunction()->needsUnwindTableEntry(); 34133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 34233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Prepare for frame info. 34333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *FrameLabel = 0; 34433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 34533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Scan the prolog, looking for an UPDATE_VRSAVE instruction. If we find it, 34633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // process it. 347a5d0ab555384baa293b06686bec5a01fb9638ca3Bill Schmidt if (!Subtarget.isSVR4ABI()) 348a5d0ab555384baa293b06686bec5a01fb9638ca3Bill Schmidt for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) { 349a5d0ab555384baa293b06686bec5a01fb9638ca3Bill Schmidt if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) { 350a5d0ab555384baa293b06686bec5a01fb9638ca3Bill Schmidt HandleVRSaveUpdate(MBBI, TII); 351a5d0ab555384baa293b06686bec5a01fb9638ca3Bill Schmidt break; 352a5d0ab555384baa293b06686bec5a01fb9638ca3Bill Schmidt } 35333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 35433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Move MBBI back to the beginning of the function. 35633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = MBB.begin(); 35733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Work out frame sizes. 3590cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel unsigned FrameSize = determineFrameLayout(MF); 36033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int NegFrameSize = -FrameSize; 36133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 362e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel if (MFI->isFrameAddressTaken()) 363e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel replaceFPWithRealFP(MF); 364e9cc0a09ae38c87b1b26a44f5e32222ede4f84e6Hal Finkel 36533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get processor type. 36633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isPPC64 = Subtarget.isPPC64(); 36733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get operating system 36833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isDarwinABI = Subtarget.isDarwinABI(); 36933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Check if the link register (LR) must be saved. 37033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 37133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool MustSaveLR = FI->mustSaveLR(); 372fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel const SmallVector<unsigned, 3> &MustSaveCRs = FI->getMustSaveCRs(); 37333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Do we have a frame pointer for this function? 374c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov bool HasFP = hasFP(MF); 37533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 37616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI); 37733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 37833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPOffset = 0; 37933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 38033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Subtarget.isSVR4ABI()) { 38133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *FFI = MF.getFrameInfo(); 38233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPIndex = FI->getFramePointerSaveIndex(); 38333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(FPIndex && "No Frame Pointer Save Slot!"); 38433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FPOffset = FFI->getObjectOffset(FPIndex); 38533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 38616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov FPOffset = PPCFrameLowering::getFramePointerSaveOffset(isPPC64, isDarwinABI); 38733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 38833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 38933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 39033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isPPC64) { 39133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 39233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR8), PPC::X0); 39333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 394fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel if (!MustSaveCRs.empty()) { 395fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel MachineInstrBuilder MIB = 396fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel BuildMI(MBB, MBBI, dl, TII.get(PPC::MFCR8), PPC::X12); 397fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i) 398fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel MIB.addReg(MustSaveCRs[i], RegState::ImplicitKill); 399fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel } 400fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel 40133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) 40233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STD)) 40333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X31) 404347a5079e18278803bc05b197d325b8580e95610Ulrich Weigand .addImm(FPOffset) 40533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1); 40633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 40733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 40833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STD)) 40933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0) 410347a5079e18278803bc05b197d325b8580e95610Ulrich Weigand .addImm(LROffset) 41133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1); 412fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel 413fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel if (!MustSaveCRs.empty()) 414fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel BuildMI(MBB, MBBI, dl, TII.get(PPC::STW8)) 415fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel .addReg(PPC::X12, getKillRegState(true)) 416fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel .addImm(8) 417fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel .addReg(PPC::X1); 41833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 41933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 42033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR), PPC::R0); 42133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 42233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) 423b8f2f29467b86a11e777e2ce071caf15ae6fcf75Hal Finkel // FIXME: On PPC32 SVR4, FPOffset is negative and access to negative 424b8f2f29467b86a11e777e2ce071caf15ae6fcf75Hal Finkel // offsets of R1 is not allowed. 42533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) 42633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R31) 42733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FPOffset) 42833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1); 42933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 430fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel assert(MustSaveCRs.empty() && 431fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel "Prologue CR saving supported only in 64-bit mode"); 432fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel 43333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 43433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STW)) 43533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0) 43633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(LROffset) 43733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1); 43833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 43933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 44033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip if a leaf routine. 44133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!FrameSize) return; 44233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 44333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get stack alignments. 44416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned TargetAlign = getStackAlignment(); 44533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned MaxAlign = MFI->getMaxAlignment(); 44633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 44733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer: r1 += NegFrameSize. 44833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is a preferred stack alignment, align R1 now 44933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!isPPC64) { 45033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // PPC32. 45133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ALIGN_STACK && MaxAlign > TargetAlign) { 45233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) && 45333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov "Invalid alignment!"); 45433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(isInt<16>(NegFrameSize) && "Unhandled stack size and alignment!"); 45533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 45633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::RLWINM), PPC::R0) 45733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 45833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(0) 45933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(32 - Log2_32(MaxAlign)) 46033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(31); 46133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC) ,PPC::R0) 46233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0, RegState::Kill) 46333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize); 464ac81cc3282750d724f824547bc519caec0a01bceHal Finkel BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX), PPC::R1) 4652e95afa04cd1c89de7e4abaeead66cd8e51ec929Hal Finkel .addReg(PPC::R1, RegState::Kill) 466ac81cc3282750d724f824547bc519caec0a01bceHal Finkel .addReg(PPC::R1) 46733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0); 46833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (isInt<16>(NegFrameSize)) { 46933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STWU), PPC::R1) 47033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 47133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize) 47233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1); 47333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 47433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0) 47533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize >> 16); 47633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0) 47733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0, RegState::Kill) 47833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize & 0xFFFF); 479ac81cc3282750d724f824547bc519caec0a01bceHal Finkel BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX), PPC::R1) 4802e95afa04cd1c89de7e4abaeead66cd8e51ec929Hal Finkel .addReg(PPC::R1, RegState::Kill) 481ac81cc3282750d724f824547bc519caec0a01bceHal Finkel .addReg(PPC::R1) 48233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0); 48333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 48433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { // PPC64. 48533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ALIGN_STACK && MaxAlign > TargetAlign) { 48633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) && 48733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov "Invalid alignment!"); 48833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(isInt<16>(NegFrameSize) && "Unhandled stack size and alignment!"); 48933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 49033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::RLDICL), PPC::X0) 49133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 49233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(0) 49333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(64 - Log2_32(MaxAlign)); 49433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC8), PPC::X0) 49533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0) 49633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize); 497ac81cc3282750d724f824547bc519caec0a01bceHal Finkel BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX), PPC::X1) 4982e95afa04cd1c89de7e4abaeead66cd8e51ec929Hal Finkel .addReg(PPC::X1, RegState::Kill) 499ac81cc3282750d724f824547bc519caec0a01bceHal Finkel .addReg(PPC::X1) 50033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0); 50133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (isInt<16>(NegFrameSize)) { 50233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::STDU), PPC::X1) 50333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 504347a5079e18278803bc05b197d325b8580e95610Ulrich Weigand .addImm(NegFrameSize) 50533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1); 50633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 50733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0) 50833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize >> 16); 50933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0) 51033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0, RegState::Kill) 51133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(NegFrameSize & 0xFFFF); 512ac81cc3282750d724f824547bc519caec0a01bceHal Finkel BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX), PPC::X1) 5132e95afa04cd1c89de7e4abaeead66cd8e51ec929Hal Finkel .addReg(PPC::X1, RegState::Kill) 514ac81cc3282750d724f824547bc519caec0a01bceHal Finkel .addReg(PPC::X1) 51533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0); 51633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 51733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 51833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 51933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add the "machine moves" for the instructions we generated above, but in 52033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // reverse order. 52133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 52233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark effective beginning of when frame pointer becomes valid. 52333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameLabel = MMI.getContext().CreateTempSymbol(); 52433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::PROLOG_LABEL)).addSym(FrameLabel); 52533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 52633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Show update of SP. 527ec7f4231cb7c26d5f52375617a9a73a1e79f3857Rafael Espindola assert(NegFrameSize); 5286b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MMI.addFrameInst( 5296b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MCCFIInstruction::createDefCfaOffset(FrameLabel, NegFrameSize)); 53033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 53133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 5326b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola unsigned Reg = isPPC64 ? PPC::X31 : PPC::R31; 53399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Reg = MRI->getDwarfRegNum(Reg, true); 5346b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MMI.addFrameInst( 5356b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MCCFIInstruction::createOffset(FrameLabel, Reg, FPOffset)); 53633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 53733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 53833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) { 5396b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola unsigned Reg = isPPC64 ? PPC::LR8 : PPC::LR; 54099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Reg = MRI->getDwarfRegNum(Reg, true); 5416b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MMI.addFrameInst( 5426b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MCCFIInstruction::createOffset(FrameLabel, Reg, LROffset)); 54333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 54433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 54533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 54633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *ReadyLabel = 0; 54733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 54833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is a frame pointer, copy R1 into R31 54933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 55033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!isPPC64) { 55133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), PPC::R31) 55233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 55333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1); 55433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 55533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), PPC::X31) 55633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 55733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1); 55833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 55933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 56033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 56133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ReadyLabel = MMI.getContext().CreateTempSymbol(); 56233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 56333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark effective beginning of when frame pointer is ready. 56433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::PROLOG_LABEL)).addSym(ReadyLabel); 56533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 5666b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola unsigned Reg = HasFP ? (isPPC64 ? PPC::X31 : PPC::R31) 5676b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola : (isPPC64 ? PPC::X1 : PPC::R1); 56899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Reg = MRI->getDwarfRegNum(Reg, true); 5696b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(ReadyLabel, Reg)); 57033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 57133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 57233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 57333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 57433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *Label = HasFP ? ReadyLabel : FrameLabel; 57533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 57633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add callee saved registers to move list. 57733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 57833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 57933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Reg = CSI[I].getReg(); 58033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue; 5816e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola 5826e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola // This is a bit of a hack: CR2LT, CR2GT, CR2EQ and CR2UN are just 5836e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola // subregisters of CR2. We just need to emit a move of CR2. 584c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper if (PPC::CRBITRCRegClass.contains(Reg)) 5856e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola continue; 5866e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola 5879d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // For SVR4, don't emit a move for the CR spill slot if we haven't 5889d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // spilled CRs. 5899d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (Subtarget.isSVR4ABI() 5909d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky && (PPC::CR2 <= Reg && Reg <= PPC::CR4) 591fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel && MustSaveCRs.empty()) 5929d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky continue; 5939d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 5949d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // For 64-bit SVR4 when we have spilled CRs, the spill location 5959d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // is SP+8, not a frame-relative slot. 5969d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (Subtarget.isSVR4ABI() 5979d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky && Subtarget.isPPC64() 5989d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky && (PPC::CR2 <= Reg && Reg <= PPC::CR4)) { 5996b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MMI.addFrameInst(MCCFIInstruction::createOffset( 60099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Label, MRI->getDwarfRegNum(PPC::CR2, true), 8)); 6019d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky continue; 6029d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } 6039d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 6049d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); 6056b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MMI.addFrameInst(MCCFIInstruction::createOffset( 60699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Label, MRI->getDwarfRegNum(Reg, true), Offset)); 60733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 60833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 60933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 61033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 61116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid PPCFrameLowering::emitEpilogue(MachineFunction &MF, 61233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB) const { 6134f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 6144f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen assert(MBBI != MBB.end() && "Returning block has no terminator"); 61533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const PPCInstrInfo &TII = 61633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo()); 61733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 61833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned RetOpcode = MBBI->getOpcode(); 61933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl; 62033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 621d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov assert((RetOpcode == PPC::BLR || 622d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNri || 623d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNdi || 624d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNai || 625d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNri8 || 626d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNdi8 || 627d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RetOpcode == PPC::TCRETURNai8) && 62833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov "Can only insert epilog into returning blocks"); 62933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 63033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get alignment info so we know how to restore r1 63133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 63216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned TargetAlign = getStackAlignment(); 63333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned MaxAlign = MFI->getMaxAlignment(); 63433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 63533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes allocated from the FrameInfo. 63633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FrameSize = MFI->getStackSize(); 63733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 63833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get processor type. 63933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isPPC64 = Subtarget.isPPC64(); 64033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get operating system 64133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isDarwinABI = Subtarget.isDarwinABI(); 64233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Check if the link register (LR) has been saved. 64333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 64433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool MustSaveLR = FI->mustSaveLR(); 645fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel const SmallVector<unsigned, 3> &MustSaveCRs = FI->getMustSaveCRs(); 64633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Do we have a frame pointer for this function? 647c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov bool HasFP = hasFP(MF); 64833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 64916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI); 65033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 65133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPOffset = 0; 65233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 65333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Subtarget.isSVR4ABI()) { 65433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *FFI = MF.getFrameInfo(); 65533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int FPIndex = FI->getFramePointerSaveIndex(); 65633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(FPIndex && "No Frame Pointer Save Slot!"); 65733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FPOffset = FFI->getObjectOffset(FPIndex); 65833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 65916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov FPOffset = PPCFrameLowering::getFramePointerSaveOffset(isPPC64, isDarwinABI); 66033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 66133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 66233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 66333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool UsesTCRet = RetOpcode == PPC::TCRETURNri || 66433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNdi || 66533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNai || 66633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNri8 || 66733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNdi8 || 66833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == PPC::TCRETURNai8; 66933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 67033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (UsesTCRet) { 67133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int MaxTCRetDelta = FI->getTailCallSPDelta(); 67233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &StackAdjust = MBBI->getOperand(1); 67333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(StackAdjust.isImm() && "Expecting immediate value."); 67433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer. 67533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackAdj = StackAdjust.getImm(); 67633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Delta = StackAdj - MaxTCRetDelta; 67733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert((Delta >= 0) && "Delta must be positive"); 67833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MaxTCRetDelta>0) 67933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize += (StackAdj +Delta); 68033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 68133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize += StackAdj; 68233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 68333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 68433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (FrameSize) { 68533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // The loaded (or persistent) stack pointer value is offset by the 'stwu' 68633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // on entry to the function. Add this offset back now. 68733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!isPPC64) { 68833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If this function contained a fastcc call and GuaranteedTailCallOpt is 68933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // enabled (=> hasFastCall()==true) the fastcc call might contain a tail 69033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // call which invalidates the stack pointer value in SP(0). So we use the 69133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // value of R31 in this case. 69233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (FI->hasFastCall() && isInt<16>(FrameSize)) { 693d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov assert(hasFP(MF) && "Expecting a valid the frame pointer."); 69433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1) 69533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R31).addImm(FrameSize); 69633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if(FI->hasFastCall()) { 69733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0) 69833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FrameSize >> 16); 69933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0) 70033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0, RegState::Kill) 70133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FrameSize & 0xFFFF); 70233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD4)) 70333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1) 70433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R31) 70533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R0); 70633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (isInt<16>(FrameSize) && 70733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (!ALIGN_STACK || TargetAlign >= MaxAlign) && 70833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !MFI->hasVarSizedObjects()) { 70933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1) 71033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::R1).addImm(FrameSize); 71133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 71233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ),PPC::R1) 71333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(0).addReg(PPC::R1); 71433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 71533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 71633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (FI->hasFastCall() && isInt<16>(FrameSize)) { 717d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov assert(hasFP(MF) && "Expecting a valid the frame pointer."); 71833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1) 71933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X31).addImm(FrameSize); 72033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if(FI->hasFastCall()) { 72133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0) 72233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FrameSize >> 16); 72333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0) 72433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0, RegState::Kill) 72533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FrameSize & 0xFFFF); 72633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD8)) 72733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1) 72833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X31) 72933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X0); 73033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (isInt<16>(FrameSize) && TargetAlign >= MaxAlign && 73133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !MFI->hasVarSizedObjects()) { 73233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1) 73333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(PPC::X1).addImm(FrameSize); 73433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 73533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X1) 73633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(0).addReg(PPC::X1); 73733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 73833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 73933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 74033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 74133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isPPC64) { 74233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 74333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X0) 744347a5079e18278803bc05b197d325b8580e95610Ulrich Weigand .addImm(LROffset).addReg(PPC::X1); 74533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 746fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel if (!MustSaveCRs.empty()) 747fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ8), PPC::X12) 748fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel .addImm(8).addReg(PPC::X1); 749fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel 75033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) 75133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X31) 752347a5079e18278803bc05b197d325b8580e95610Ulrich Weigand .addImm(FPOffset).addReg(PPC::X1); 75333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 754fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel if (!MustSaveCRs.empty()) 755fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i) 756fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel BuildMI(MBB, MBBI, dl, TII.get(PPC::MTCRF8), MustSaveCRs[i]) 757fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel .addReg(PPC::X12, getKillRegState(i == e-1)); 758fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel 75933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 76033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR8)).addReg(PPC::X0); 76133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 76233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 76333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R0) 76433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(LROffset).addReg(PPC::R1); 76533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 766fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel assert(MustSaveCRs.empty() && 767fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel "Epilogue CR restoring supported only in 64-bit mode"); 768fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel 76933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) 77033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R31) 77133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(FPOffset).addReg(PPC::R1); 77233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 77333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MustSaveLR) 77433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR)).addReg(PPC::R0); 77533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 77633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 77733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Callee pop calling convention. Pop parameter/linkage area. Used for tail 77833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // call optimization 7798a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (MF.getTarget().Options.GuaranteedTailCallOpt && RetOpcode == PPC::BLR && 78033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MF.getFunction()->getCallingConv() == CallingConv::Fast) { 78133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 78233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned CallerAllocatedAmt = FI->getMinReservedArea(); 78333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackReg = isPPC64 ? PPC::X1 : PPC::R1; 78433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FPReg = isPPC64 ? PPC::X31 : PPC::R31; 78533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned TmpReg = isPPC64 ? PPC::X0 : PPC::R0; 78633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned ADDIInstr = isPPC64 ? PPC::ADDI8 : PPC::ADDI; 78733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned ADDInstr = isPPC64 ? PPC::ADD8 : PPC::ADD4; 78833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned LISInstr = isPPC64 ? PPC::LIS8 : PPC::LIS; 78933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned ORIInstr = isPPC64 ? PPC::ORI8 : PPC::ORI; 79033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 79133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (CallerAllocatedAmt && isInt<16>(CallerAllocatedAmt)) { 79233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(ADDIInstr), StackReg) 79333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(StackReg).addImm(CallerAllocatedAmt); 79433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 79533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(LISInstr), TmpReg) 79633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(CallerAllocatedAmt >> 16); 79733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(ORIInstr), TmpReg) 79833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(TmpReg, RegState::Kill) 79933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(CallerAllocatedAmt & 0xFFFF); 80033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(ADDInstr)) 80133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(StackReg) 80233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(FPReg) 80333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(TmpReg); 80433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 80533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNdi) { 8064f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 80733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 80833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)). 80933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); 81033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNri) { 8114f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 81233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MBBI->getOperand(0).isReg() && "Expecting register operand."); 81333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR)); 81433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNai) { 8154f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 81633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 81733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm()); 81833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNdi8) { 8194f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 82033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 82133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)). 82233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); 82333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNri8) { 8244f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 82533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MBBI->getOperand(0).isReg() && "Expecting register operand."); 82633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR8)); 82733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == PPC::TCRETURNai8) { 8284f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 82933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 83033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm()); 83133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 83233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 833d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov 83494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov/// MustSaveLR - Return true if this function requires that we save the LR 83594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov/// register onto the stack in the prolog and restore it in the epilog of the 83694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov/// function. 83794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikovstatic bool MustSaveLR(const MachineFunction &MF, unsigned LR) { 83894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>(); 83994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 84094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // We need a save/restore of LR if there is any def of LR (which is 84194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // defined by calls, including the PIC setup sequence), or if there is 84294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // some use of the LR stack slot (e.g. for builtin_return_address). 84394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // (LR comes in 32 and 64 bit versions.) 84494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR); 84594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired(); 84694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 84794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 84894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikovvoid 84916c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovPPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 8500cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel RegScavenger *) const { 85194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); 85294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 85394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Save and clear the LR state. 85494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); 85594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned LR = RegInfo->getRARegister(); 85694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FI->setMustSaveLR(MustSaveLR(MF, LR)); 8574edd84da1b3f7fd73e96a13b6b7e183ad04ac7c4Bill Schmidt MachineRegisterInfo &MRI = MF.getRegInfo(); 8584edd84da1b3f7fd73e96a13b6b7e183ad04ac7c4Bill Schmidt MRI.setPhysRegUnused(LR); 85994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 86094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Save R31 if necessary 86194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FPSI = FI->getFramePointerSaveIndex(); 86294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool isPPC64 = Subtarget.isPPC64(); 86394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool isDarwinABI = Subtarget.isDarwinABI(); 86494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 86594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 86694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // If the frame pointer save index hasn't been defined yet. 867c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov if (!FPSI && needsFP(MF)) { 86894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Find out what the fix offset of the frame pointer save area. 86994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FPOffset = getFramePointerSaveOffset(isPPC64, isDarwinABI); 87094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Allocate the frame index for frame pointer save area. 87116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov FPSI = MFI->CreateFixedObject(isPPC64? 8 : 4, FPOffset, true); 87294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Save the result. 87394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FI->setFramePointerSaveIndex(FPSI); 87494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 87594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 87694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Reserve stack space to move the linkage area to in case of a tail call. 87794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int TCSPDelta = 0; 8788a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (MF.getTarget().Options.GuaranteedTailCallOpt && 8798a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky (TCSPDelta = FI->getTailCallSPDelta()) < 0) { 88016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov MFI->CreateFixedObject(-1 * TCSPDelta, TCSPDelta, true); 88194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 88294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 8834edd84da1b3f7fd73e96a13b6b7e183ad04ac7c4Bill Schmidt // For 32-bit SVR4, allocate the nonvolatile CR spill slot iff the 8844edd84da1b3f7fd73e96a13b6b7e183ad04ac7c4Bill Schmidt // function uses CR 2, 3, or 4. 8854edd84da1b3f7fd73e96a13b6b7e183ad04ac7c4Bill Schmidt if (!isPPC64 && !isDarwinABI && 8864edd84da1b3f7fd73e96a13b6b7e183ad04ac7c4Bill Schmidt (MRI.isPhysRegUsed(PPC::CR2) || 8874edd84da1b3f7fd73e96a13b6b7e183ad04ac7c4Bill Schmidt MRI.isPhysRegUsed(PPC::CR3) || 8884edd84da1b3f7fd73e96a13b6b7e183ad04ac7c4Bill Schmidt MRI.isPhysRegUsed(PPC::CR4))) { 8894edd84da1b3f7fd73e96a13b6b7e183ad04ac7c4Bill Schmidt int FrameIdx = MFI->CreateFixedObject((uint64_t)4, (int64_t)-4, true); 8904edd84da1b3f7fd73e96a13b6b7e183ad04ac7c4Bill Schmidt FI->setCRSpillFrameIndex(FrameIdx); 8914edd84da1b3f7fd73e96a13b6b7e183ad04ac7c4Bill Schmidt } 89294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 89394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 8943080d23fde4981835d8a7faf46c152441fadb11fHal Finkelvoid PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF, 8950cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel RegScavenger *RS) const { 89694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Early exit if not using the SVR4 ABI. 8970cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel if (!Subtarget.isSVR4ABI()) { 8980cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel addScavengingSpillSlot(MF, RS); 89994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov return; 9000cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel } 90194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 90294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Get callee saved register information. 90394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineFrameInfo *FFI = MF.getFrameInfo(); 90494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); 90594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 90694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Early exit if no callee saved registers are modified! 907c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov if (CSI.empty() && !needsFP(MF)) { 9080cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel addScavengingSpillSlot(MF, RS); 90994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov return; 91094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 91194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 91294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinGPR = PPC::R31; 91394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinG8R = PPC::X31; 91494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinFPR = PPC::F31; 91594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinVR = PPC::V31; 91694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 91794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasGPSaveArea = false; 91894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasG8SaveArea = false; 91994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasFPSaveArea = false; 92094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasVRSAVESaveArea = false; 92194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov bool HasVRSaveArea = false; 92294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 92394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov SmallVector<CalleeSavedInfo, 18> GPRegs; 92494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov SmallVector<CalleeSavedInfo, 18> G8Regs; 92594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov SmallVector<CalleeSavedInfo, 18> FPRegs; 92694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov SmallVector<CalleeSavedInfo, 18> VRegs; 92794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 92894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 92994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 930c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper if (PPC::GPRCRegClass.contains(Reg)) { 93194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasGPSaveArea = true; 93294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 93394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov GPRegs.push_back(CSI[i]); 93494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 93594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Reg < MinGPR) { 93694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MinGPR = Reg; 93794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 938c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::G8RCRegClass.contains(Reg)) { 93994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasG8SaveArea = true; 94094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 94194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov G8Regs.push_back(CSI[i]); 94294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 94394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Reg < MinG8R) { 94494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MinG8R = Reg; 94594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 946c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::F8RCRegClass.contains(Reg)) { 94794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasFPSaveArea = true; 94894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 94994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FPRegs.push_back(CSI[i]); 95094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 95194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Reg < MinFPR) { 95294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MinFPR = Reg; 95394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 954c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::CRBITRCRegClass.contains(Reg) || 955c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper PPC::CRRCRegClass.contains(Reg)) { 9569d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky ; // do nothing, as we already know whether CRs are spilled 957c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::VRSAVERCRegClass.contains(Reg)) { 95894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasVRSAVESaveArea = true; 959c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper } else if (PPC::VRRCRegClass.contains(Reg)) { 96094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasVRSaveArea = true; 96194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 96294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov VRegs.push_back(CSI[i]); 96394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 96494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Reg < MinVR) { 96594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MinVR = Reg; 96694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 96794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } else { 96894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov llvm_unreachable("Unknown RegisterClass!"); 96994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 97094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 97194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 97294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>(); 973aa6047d23d8ed55abd8545f5cbe82cd13cbd756aHal Finkel const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo(); 97494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 97594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int64_t LowerBound = 0; 97694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 97794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Take into account stack space reserved for tail calls. 97894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int TCSPDelta = 0; 9798a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (MF.getTarget().Options.GuaranteedTailCallOpt && 9808a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky (TCSPDelta = PFI->getTailCallSPDelta()) < 0) { 98194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound = TCSPDelta; 98294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 98394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 98494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // The Floating-point register save area is right below the back chain word 98594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // of the previous stack frame. 98694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasFPSaveArea) { 98794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) { 98894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = FPRegs[i].getFrameIdx(); 98994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 99094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 99194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 99294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 993aa6047d23d8ed55abd8545f5cbe82cd13cbd756aHal Finkel LowerBound -= (31 - TRI->getEncodingValue(MinFPR) + 1) * 8; 99494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 99594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 99694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Check whether the frame pointer register is allocated. If so, make sure it 99794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // is spilled to the correct offset. 998c8bd78c16ba0489835f2eb6101d9bdb96301cfe7Anton Korobeynikov if (needsFP(MF)) { 99994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov HasGPSaveArea = true; 100094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 100194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = PFI->getFramePointerSaveIndex(); 100294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov assert(FI && "No Frame Pointer Save Slot!"); 100394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 100494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 100594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 100694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 100794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // General register save area starts right below the Floating-point 100894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // register save area. 100994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasGPSaveArea || HasG8SaveArea) { 101094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Move general register save area spill slots down, taking into account 101194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // the size of the Floating-point register save area. 101294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) { 101394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = GPRegs[i].getFrameIdx(); 101494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 101594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 101694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 101794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 101894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Move general register save area spill slots down, taking into account 101994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // the size of the Floating-point register save area. 102094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) { 102194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = G8Regs[i].getFrameIdx(); 102294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 102394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 102494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 102594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 102694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned MinReg = 1027aa6047d23d8ed55abd8545f5cbe82cd13cbd756aHal Finkel std::min<unsigned>(TRI->getEncodingValue(MinGPR), 1028aa6047d23d8ed55abd8545f5cbe82cd13cbd756aHal Finkel TRI->getEncodingValue(MinG8R)); 102994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 103094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (Subtarget.isPPC64()) { 103194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= (31 - MinReg + 1) * 8; 103294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } else { 103394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= (31 - MinReg + 1) * 4; 103494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 103594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 103694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 10379d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // For 32-bit only, the CR save area is below the general register 10389d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // save area. For 64-bit SVR4, the CR save area is addressed relative 10399d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // to the stack pointer and hence does not need an adjustment here. 10409d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // Only CR2 (the first nonvolatile spilled) has an associated frame 10419d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // index so that we have a single uniform save area. 10429d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (spillsCR(MF) && !(Subtarget.isPPC64() && Subtarget.isSVR4ABI())) { 104394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Adjust the frame index of the CR spill slot. 104494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 104594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 104694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 10479d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if ((Subtarget.isSVR4ABI() && Reg == PPC::CR2) 10489d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // Leave Darwin logic as-is. 10499d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky || (!Subtarget.isSVR4ABI() && 10509d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky (PPC::CRBITRCRegClass.contains(Reg) || 10519d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky PPC::CRRCRegClass.contains(Reg)))) { 105294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = CSI[i].getFrameIdx(); 105394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 105494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 105594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 105694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 105794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 105894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= 4; // The CR save area is always 4 bytes long. 105994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 106094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 106194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasVRSAVESaveArea) { 106294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // FIXME SVR4: Is it actually possible to have multiple elements in CSI 106394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // which have the VRSAVE register class? 106494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Adjust the frame index of the VRSAVE spill slot. 106594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 106694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 106794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 1068c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper if (PPC::VRSAVERCRegClass.contains(Reg)) { 106994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = CSI[i].getFrameIdx(); 107094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 107194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 107294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 107394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 107494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 107594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound -= 4; // The VRSAVE save area is always 4 bytes long. 107694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 107794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 107894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (HasVRSaveArea) { 107994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Insert alignment padding, we need 16-byte alignment. 108094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov LowerBound = (LowerBound - 15) & ~(15); 108194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 108294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov for (unsigned i = 0, e = VRegs.size(); i != e; ++i) { 108394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FI = VRegs[i].getFrameIdx(); 108494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 108594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); 108694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 108794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 10880cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel 10890cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel addScavengingSpillSlot(MF, RS); 10900cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel} 10910cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel 10920cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkelvoid 10930cfb42adb5072fb19a01dba3ea58a33fd5927947Hal FinkelPPCFrameLowering::addScavengingSpillSlot(MachineFunction &MF, 10940cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel RegScavenger *RS) const { 10950cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel // Reserve a slot closest to SP or frame pointer if we have a dynalloc or 10960cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel // a large stack, which will require scavenging a register to materialize a 10970cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel // large offset. 10980cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel 10990cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel // We need to have a scavenger spill slot for spills if the frame size is 11000cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel // large. In case there is no free register for large-offset addressing, 11010cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel // this slot is used for the necessary emergency spill. Also, we need the 11020cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel // slot for dynamic stack allocations. 11030cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel 11040cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel // The scavenger might be invoked if the frame offset does not fit into 11050cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel // the 16-bit immediate. We don't know the complete frame size here 11060cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel // because we've not yet computed callee-saved register spills or the 11070cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel // needed alignment padding. 11080cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel unsigned StackSize = determineFrameLayout(MF, false, true); 11090cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel MachineFrameInfo *MFI = MF.getFrameInfo(); 11103f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel if (MFI->hasVarSizedObjects() || spillsCR(MF) || spillsVRSAVE(MF) || 11113f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel hasNonRISpills(MF) || (hasSpills(MF) && !isInt<16>(StackSize))) { 11120cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel const TargetRegisterClass *GPRC = &PPC::GPRCRegClass; 11130cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel const TargetRegisterClass *G8RC = &PPC::G8RCRegClass; 11140cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel const TargetRegisterClass *RC = Subtarget.isPPC64() ? G8RC : GPRC; 1115dc3beb90178fc316f63790812b22201884eaa017Hal Finkel RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 11160cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel RC->getAlignment(), 11170cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel false)); 111801f99d29c3010f2891e5edb78182216214017063Hal Finkel 111901f99d29c3010f2891e5edb78182216214017063Hal Finkel // These kinds of spills might need two registers. 112001f99d29c3010f2891e5edb78182216214017063Hal Finkel if (spillsCR(MF) || spillsVRSAVE(MF)) 112101f99d29c3010f2891e5edb78182216214017063Hal Finkel RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 112201f99d29c3010f2891e5edb78182216214017063Hal Finkel RC->getAlignment(), 112301f99d29c3010f2891e5edb78182216214017063Hal Finkel false)); 112401f99d29c3010f2891e5edb78182216214017063Hal Finkel 11250cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel } 112694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 11279d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 11289d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divackybool 11299d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman DivackyPPCFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 11309d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MachineBasicBlock::iterator MI, 11319d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky const std::vector<CalleeSavedInfo> &CSI, 11329d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky const TargetRegisterInfo *TRI) const { 11339d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 11349d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // Currently, this function only handles SVR4 32- and 64-bit ABIs. 11359d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // Return false otherwise to maintain pre-existing behavior. 11369d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (!Subtarget.isSVR4ABI()) 11379d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky return false; 11389d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 11399d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MachineFunction *MF = MBB.getParent(); 11409d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky const PPCInstrInfo &TII = 11419d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky *static_cast<const PPCInstrInfo*>(MF->getTarget().getInstrInfo()); 11429d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky DebugLoc DL; 11439d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky bool CRSpilled = false; 114463496f66c5b528a48f8da7714ee3f635f8aadd18Hal Finkel MachineInstrBuilder CRMIB; 11459d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 11469d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 11479d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky unsigned Reg = CSI[i].getReg(); 11489d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // CR2 through CR4 are the nonvolatile CR fields. 11499d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky bool IsCRField = PPC::CR2 <= Reg && Reg <= PPC::CR4; 11509d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 11519d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // Add the callee-saved register as live-in; it's killed at the spill. 11529d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MBB.addLiveIn(Reg); 11539d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 115463496f66c5b528a48f8da7714ee3f635f8aadd18Hal Finkel if (CRSpilled && IsCRField) { 115563496f66c5b528a48f8da7714ee3f635f8aadd18Hal Finkel CRMIB.addReg(Reg, RegState::ImplicitKill); 115663496f66c5b528a48f8da7714ee3f635f8aadd18Hal Finkel continue; 115763496f66c5b528a48f8da7714ee3f635f8aadd18Hal Finkel } 115863496f66c5b528a48f8da7714ee3f635f8aadd18Hal Finkel 11599d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // Insert the spill to the stack frame. 11609d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (IsCRField) { 1161fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>(); 11629d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (Subtarget.isPPC64()) { 1163fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel // The actual spill will happen at the start of the prologue. 1164fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel FuncInfo->addMustSaveCR(Reg); 11659d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } else { 1166fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel CRSpilled = true; 1167ded53bf4dd499f213334400fa870d0c7896d1d0dBill Schmidt FuncInfo->setSpillsCR(); 1168fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel 11699d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // 32-bit: FP-relative. Note that we made sure CR2-CR4 all have 11709d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // the same frame index in PPCRegisterInfo::hasReservedSpillSlot. 117163496f66c5b528a48f8da7714ee3f635f8aadd18Hal Finkel CRMIB = BuildMI(*MF, DL, TII.get(PPC::MFCR), PPC::R12) 117263496f66c5b528a48f8da7714ee3f635f8aadd18Hal Finkel .addReg(Reg, RegState::ImplicitKill); 117363496f66c5b528a48f8da7714ee3f635f8aadd18Hal Finkel 117463496f66c5b528a48f8da7714ee3f635f8aadd18Hal Finkel MBB.insert(MI, CRMIB); 11759d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MBB.insert(MI, addFrameReference(BuildMI(*MF, DL, TII.get(PPC::STW)) 11769d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky .addReg(PPC::R12, 11779d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky getKillRegState(true)), 11789d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky CSI[i].getFrameIdx())); 11799d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } 11809d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } else { 11819d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 11829d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky TII.storeRegToStackSlot(MBB, MI, Reg, true, 11839d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky CSI[i].getFrameIdx(), RC, TRI); 11849d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } 11859d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } 11869d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky return true; 11879d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky} 11889d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 11899d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divackystatic void 1190b99c995825a49f0da5af40ee1b61269deb8994b5Hal FinkelrestoreCRs(bool isPPC64, bool is31, 1191b99c995825a49f0da5af40ee1b61269deb8994b5Hal Finkel bool CR2Spilled, bool CR3Spilled, bool CR4Spilled, 11929d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 11939d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky const std::vector<CalleeSavedInfo> &CSI, unsigned CSIIndex) { 11949d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 11959d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MachineFunction *MF = MBB.getParent(); 11969d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky const PPCInstrInfo &TII = 11979d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky *static_cast<const PPCInstrInfo*>(MF->getTarget().getInstrInfo()); 11989d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky DebugLoc DL; 11999d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky unsigned RestoreOp, MoveReg; 12009d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 1201fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel if (isPPC64) 1202fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel // This is handled during epilogue generation. 1203fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel return; 1204fb6fe0aea2d1adde6d5e86f43797b5795ff2dc36Hal Finkel else { 12059d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // 32-bit: FP-relative 12069d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MBB.insert(MI, addFrameReference(BuildMI(*MF, DL, TII.get(PPC::LWZ), 12079d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky PPC::R12), 12089d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky CSI[CSIIndex].getFrameIdx())); 12099d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky RestoreOp = PPC::MTCRF; 12109d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MoveReg = PPC::R12; 12119d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } 12129d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 12139d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (CR2Spilled) 12149d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR2) 1215d957f957eee12cf26a7160e6015f0a7c2629904fHal Finkel .addReg(MoveReg, getKillRegState(!CR3Spilled && !CR4Spilled))); 12169d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 12179d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (CR3Spilled) 12189d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR3) 1219d957f957eee12cf26a7160e6015f0a7c2629904fHal Finkel .addReg(MoveReg, getKillRegState(!CR4Spilled))); 12209d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 12219d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (CR4Spilled) 12229d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR4) 1223d957f957eee12cf26a7160e6015f0a7c2629904fHal Finkel .addReg(MoveReg, getKillRegState(true))); 12249d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky} 12259d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 1226700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Benderskyvoid PPCFrameLowering:: 1227700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli BenderskyeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 1228700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineBasicBlock::iterator I) const { 1229700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky const PPCInstrInfo &TII = 1230700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo()); 1231700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (MF.getTarget().Options.GuaranteedTailCallOpt && 1232700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky I->getOpcode() == PPC::ADJCALLSTACKUP) { 1233700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // Add (actually subtract) back the amount the callee popped on return. 1234700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (int CalleeAmt = I->getOperand(1).getImm()) { 1235700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky bool is64Bit = Subtarget.isPPC64(); 1236700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky CalleeAmt *= -1; 1237700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned StackReg = is64Bit ? PPC::X1 : PPC::R1; 1238700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned TmpReg = is64Bit ? PPC::X0 : PPC::R0; 1239700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned ADDIInstr = is64Bit ? PPC::ADDI8 : PPC::ADDI; 1240700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned ADDInstr = is64Bit ? PPC::ADD8 : PPC::ADD4; 1241700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned LISInstr = is64Bit ? PPC::LIS8 : PPC::LIS; 1242700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned ORIInstr = is64Bit ? PPC::ORI8 : PPC::ORI; 1243700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineInstr *MI = I; 1244700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky DebugLoc dl = MI->getDebugLoc(); 1245700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1246700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (isInt<16>(CalleeAmt)) { 1247700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky BuildMI(MBB, I, dl, TII.get(ADDIInstr), StackReg) 1248700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addReg(StackReg, RegState::Kill) 1249700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addImm(CalleeAmt); 1250700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } else { 1251700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineBasicBlock::iterator MBBI = I; 1252700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky BuildMI(MBB, MBBI, dl, TII.get(LISInstr), TmpReg) 1253700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addImm(CalleeAmt >> 16); 1254700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky BuildMI(MBB, MBBI, dl, TII.get(ORIInstr), TmpReg) 1255700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addReg(TmpReg, RegState::Kill) 1256700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addImm(CalleeAmt & 0xFFFF); 1257700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky BuildMI(MBB, MBBI, dl, TII.get(ADDInstr), StackReg) 1258700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addReg(StackReg, RegState::Kill) 1259700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addReg(TmpReg); 1260700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1261700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1262700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1263700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions. 1264700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MBB.erase(I); 1265700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky} 1266700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 12679d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divackybool 12689d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman DivackyPPCFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 12699d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MachineBasicBlock::iterator MI, 12709d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky const std::vector<CalleeSavedInfo> &CSI, 12719d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky const TargetRegisterInfo *TRI) const { 12729d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 12739d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // Currently, this function only handles SVR4 32- and 64-bit ABIs. 12749d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // Return false otherwise to maintain pre-existing behavior. 12759d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (!Subtarget.isSVR4ABI()) 12769d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky return false; 12779d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 12789d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MachineFunction *MF = MBB.getParent(); 12799d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky const PPCInstrInfo &TII = 12809d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky *static_cast<const PPCInstrInfo*>(MF->getTarget().getInstrInfo()); 12819d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky bool CR2Spilled = false; 12829d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky bool CR3Spilled = false; 12839d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky bool CR4Spilled = false; 12849d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky unsigned CSIIndex = 0; 12859d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 12869d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // Initialize insertion-point logic; we will be restoring in reverse 12879d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // order of spill. 12889d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MachineBasicBlock::iterator I = MI, BeforeI = I; 12899d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky bool AtStart = I == MBB.begin(); 12909d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 12919d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (!AtStart) 12929d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky --BeforeI; 12939d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 12949d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 12959d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky unsigned Reg = CSI[i].getReg(); 12969d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 12979d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (Reg == PPC::CR2) { 12989d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky CR2Spilled = true; 12999d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // The spill slot is associated only with CR2, which is the 13009d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // first nonvolatile spilled. Save it here. 13019d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky CSIIndex = i; 13029d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky continue; 13039d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } else if (Reg == PPC::CR3) { 13049d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky CR3Spilled = true; 13059d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky continue; 13069d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } else if (Reg == PPC::CR4) { 13079d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky CR4Spilled = true; 13089d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky continue; 13099d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } else { 13109d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // When we first encounter a non-CR register after seeing at 13119d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // least one CR register, restore all spilled CRs together. 13129d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if ((CR2Spilled || CR3Spilled || CR4Spilled) 13139d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky && !(PPC::CR2 <= Reg && Reg <= PPC::CR4)) { 1314b99c995825a49f0da5af40ee1b61269deb8994b5Hal Finkel bool is31 = needsFP(*MF); 1315b99c995825a49f0da5af40ee1b61269deb8994b5Hal Finkel restoreCRs(Subtarget.isPPC64(), is31, 1316b99c995825a49f0da5af40ee1b61269deb8994b5Hal Finkel CR2Spilled, CR3Spilled, CR4Spilled, 13179d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MBB, I, CSI, CSIIndex); 13189d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky CR2Spilled = CR3Spilled = CR4Spilled = false; 13199d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } 13209d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 13219d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // Default behavior for non-CR saves. 13229d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 13239d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky TII.loadRegFromStackSlot(MBB, I, Reg, CSI[i].getFrameIdx(), 13249d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky RC, TRI); 13259d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky assert(I != MBB.begin() && 13269d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky "loadRegFromStackSlot didn't insert any code!"); 13279d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } 13289d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 13299d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // Insert in reverse order. 13309d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky if (AtStart) 13319d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky I = MBB.begin(); 13329d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky else { 13339d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky I = BeforeI; 13349d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky ++I; 13359d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } 13369d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky } 13379d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 13389d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky // If we haven't yet spilled the CRs, do so now. 1339b99c995825a49f0da5af40ee1b61269deb8994b5Hal Finkel if (CR2Spilled || CR3Spilled || CR4Spilled) { 1340b99c995825a49f0da5af40ee1b61269deb8994b5Hal Finkel bool is31 = needsFP(*MF); 1341b99c995825a49f0da5af40ee1b61269deb8994b5Hal Finkel restoreCRs(Subtarget.isPPC64(), is31, CR2Spilled, CR3Spilled, CR4Spilled, 13429d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky MBB, I, CSI, CSIIndex); 1343b99c995825a49f0da5af40ee1b61269deb8994b5Hal Finkel } 13449d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 13459d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky return true; 13469d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky} 13479d760ae5c6bc1d1482e2824efcf9cb11db1cc16fRoman Divacky 1348