1235633Sdim//===-- PPCFrameLowering.h - Define frame lowering for PowerPC --*- C++ -*-===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// 11218885Sdim//===----------------------------------------------------------------------===// 12218885Sdim 13218885Sdim#ifndef POWERPC_FRAMEINFO_H 14218885Sdim#define POWERPC_FRAMEINFO_H 15218885Sdim 16218885Sdim#include "PPC.h" 17218885Sdim#include "PPCSubtarget.h" 18252723Sdim#include "llvm/ADT/STLExtras.h" 19218885Sdim#include "llvm/Target/TargetFrameLowering.h" 20218885Sdim#include "llvm/Target/TargetMachine.h" 21218885Sdim 22218885Sdimnamespace llvm { 23218885Sdim class PPCSubtarget; 24218885Sdim 25218885Sdimclass PPCFrameLowering: public TargetFrameLowering { 26218885Sdim const PPCSubtarget &Subtarget; 27218885Sdim 28218885Sdimpublic: 29218885Sdim PPCFrameLowering(const PPCSubtarget &sti) 30252723Sdim : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 31252723Sdim (sti.hasQPX() || sti.isBGQ()) ? 32 : 16, 0), 32218885Sdim Subtarget(sti) { 33218885Sdim } 34218885Sdim 35252723Sdim unsigned determineFrameLayout(MachineFunction &MF, 36252723Sdim bool UpdateMF = true, 37252723Sdim bool UseEstimate = false) const; 38218885Sdim 39218885Sdim /// emitProlog/emitEpilog - These methods insert prolog and epilog code into 40218885Sdim /// the function. 41218885Sdim void emitPrologue(MachineFunction &MF) const; 42218885Sdim void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; 43218885Sdim 44218885Sdim bool hasFP(const MachineFunction &MF) const; 45218885Sdim bool needsFP(const MachineFunction &MF) const; 46252723Sdim void replaceFPWithRealFP(MachineFunction &MF) const; 47218885Sdim 48218885Sdim void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 49218885Sdim RegScavenger *RS = NULL) const; 50252723Sdim void processFunctionBeforeFrameFinalized(MachineFunction &MF, 51252723Sdim RegScavenger *RS = NULL) const; 52252723Sdim void addScavengingSpillSlot(MachineFunction &MF, RegScavenger *RS) const; 53218885Sdim 54245431Sdim bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 55245431Sdim MachineBasicBlock::iterator MI, 56245431Sdim const std::vector<CalleeSavedInfo> &CSI, 57245431Sdim const TargetRegisterInfo *TRI) const; 58245431Sdim 59252723Sdim void eliminateCallFramePseudoInstr(MachineFunction &MF, 60252723Sdim MachineBasicBlock &MBB, 61252723Sdim MachineBasicBlock::iterator I) const; 62252723Sdim 63245431Sdim bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 64245431Sdim MachineBasicBlock::iterator MI, 65245431Sdim const std::vector<CalleeSavedInfo> &CSI, 66245431Sdim const TargetRegisterInfo *TRI) const; 67245431Sdim 68218885Sdim /// targetHandlesStackFrameRounding - Returns true if the target is 69218885Sdim /// responsible for rounding up the stack frame (probably at emitPrologue 70218885Sdim /// time). 71218885Sdim bool targetHandlesStackFrameRounding() const { return true; } 72218885Sdim 73218885Sdim /// getReturnSaveOffset - Return the previous frame offset to save the 74218885Sdim /// return address. 75218885Sdim static unsigned getReturnSaveOffset(bool isPPC64, bool isDarwinABI) { 76218885Sdim if (isDarwinABI) 77218885Sdim return isPPC64 ? 16 : 8; 78218885Sdim // SVR4 ABI: 79218885Sdim return isPPC64 ? 16 : 4; 80218885Sdim } 81218885Sdim 82218885Sdim /// getFramePointerSaveOffset - Return the previous frame offset to save the 83218885Sdim /// frame pointer. 84218885Sdim static unsigned getFramePointerSaveOffset(bool isPPC64, bool isDarwinABI) { 85218885Sdim // For the Darwin ABI: 86218885Sdim // We cannot use the TOC save slot (offset +20) in the PowerPC linkage area 87218885Sdim // for saving the frame pointer (if needed.) While the published ABI has 88218885Sdim // not used this slot since at least MacOSX 10.2, there is older code 89218885Sdim // around that does use it, and that needs to continue to work. 90218885Sdim if (isDarwinABI) 91218885Sdim return isPPC64 ? -8U : -4U; 92218885Sdim 93218885Sdim // SVR4 ABI: First slot in the general register save area. 94218885Sdim return isPPC64 ? -8U : -4U; 95218885Sdim } 96218885Sdim 97263509Sdim /// getBasePointerSaveOffset - Return the previous frame offset to save the 98263509Sdim /// base pointer. 99263509Sdim static unsigned getBasePointerSaveOffset(bool isPPC64, bool isDarwinABI) { 100263509Sdim if (isDarwinABI) 101263509Sdim return isPPC64 ? -16U : -8U; 102263509Sdim 103263509Sdim // SVR4 ABI: First slot in the general register save area. 104263509Sdim return isPPC64 ? -16U : -8U; 105263509Sdim } 106263509Sdim 107218885Sdim /// getLinkageSize - Return the size of the PowerPC ABI linkage area. 108218885Sdim /// 109218885Sdim static unsigned getLinkageSize(bool isPPC64, bool isDarwinABI) { 110218885Sdim if (isDarwinABI || isPPC64) 111218885Sdim return 6 * (isPPC64 ? 8 : 4); 112218885Sdim 113218885Sdim // SVR4 ABI: 114218885Sdim return 8; 115218885Sdim } 116218885Sdim 117218885Sdim /// getMinCallArgumentsSize - Return the size of the minium PowerPC ABI 118218885Sdim /// argument area. 119218885Sdim static unsigned getMinCallArgumentsSize(bool isPPC64, bool isDarwinABI) { 120218885Sdim // For the Darwin ABI / 64-bit SVR4 ABI: 121218885Sdim // The prolog code of the callee may store up to 8 GPR argument registers to 122218885Sdim // the stack, allowing va_start to index over them in memory if its varargs. 123218885Sdim // Because we cannot tell if this is needed on the caller side, we have to 124218885Sdim // conservatively assume that it is needed. As such, make sure we have at 125218885Sdim // least enough stack space for the caller to store the 8 GPRs. 126218885Sdim if (isDarwinABI || isPPC64) 127218885Sdim return 8 * (isPPC64 ? 8 : 4); 128218885Sdim 129218885Sdim // 32-bit SVR4 ABI: 130218885Sdim // There is no default stack allocated for the 8 first GPR arguments. 131218885Sdim return 0; 132218885Sdim } 133218885Sdim 134218885Sdim /// getMinCallFrameSize - Return the minimum size a call frame can be using 135218885Sdim /// the PowerPC ABI. 136218885Sdim static unsigned getMinCallFrameSize(bool isPPC64, bool isDarwinABI) { 137218885Sdim // The call frame needs to be at least big enough for linkage and 8 args. 138218885Sdim return getLinkageSize(isPPC64, isDarwinABI) + 139218885Sdim getMinCallArgumentsSize(isPPC64, isDarwinABI); 140218885Sdim } 141218885Sdim 142218885Sdim // With the SVR4 ABI, callee-saved registers have fixed offsets on the stack. 143218885Sdim const SpillSlot * 144218885Sdim getCalleeSavedSpillSlots(unsigned &NumEntries) const { 145218885Sdim if (Subtarget.isDarwinABI()) { 146218885Sdim NumEntries = 1; 147218885Sdim if (Subtarget.isPPC64()) { 148218885Sdim static const SpillSlot darwin64Offsets = {PPC::X31, -8}; 149218885Sdim return &darwin64Offsets; 150218885Sdim } else { 151218885Sdim static const SpillSlot darwinOffsets = {PPC::R31, -4}; 152218885Sdim return &darwinOffsets; 153218885Sdim } 154218885Sdim } 155218885Sdim 156218885Sdim // Early exit if not using the SVR4 ABI. 157218885Sdim if (!Subtarget.isSVR4ABI()) { 158218885Sdim NumEntries = 0; 159218885Sdim return 0; 160218885Sdim } 161218885Sdim 162252723Sdim // Note that the offsets here overlap, but this is fixed up in 163252723Sdim // processFunctionBeforeFrameFinalized. 164252723Sdim 165218885Sdim static const SpillSlot Offsets[] = { 166218885Sdim // Floating-point register save area offsets. 167218885Sdim {PPC::F31, -8}, 168218885Sdim {PPC::F30, -16}, 169218885Sdim {PPC::F29, -24}, 170218885Sdim {PPC::F28, -32}, 171218885Sdim {PPC::F27, -40}, 172218885Sdim {PPC::F26, -48}, 173218885Sdim {PPC::F25, -56}, 174218885Sdim {PPC::F24, -64}, 175218885Sdim {PPC::F23, -72}, 176218885Sdim {PPC::F22, -80}, 177218885Sdim {PPC::F21, -88}, 178218885Sdim {PPC::F20, -96}, 179218885Sdim {PPC::F19, -104}, 180218885Sdim {PPC::F18, -112}, 181218885Sdim {PPC::F17, -120}, 182218885Sdim {PPC::F16, -128}, 183218885Sdim {PPC::F15, -136}, 184218885Sdim {PPC::F14, -144}, 185218885Sdim 186218885Sdim // General register save area offsets. 187218885Sdim {PPC::R31, -4}, 188218885Sdim {PPC::R30, -8}, 189218885Sdim {PPC::R29, -12}, 190218885Sdim {PPC::R28, -16}, 191218885Sdim {PPC::R27, -20}, 192218885Sdim {PPC::R26, -24}, 193218885Sdim {PPC::R25, -28}, 194218885Sdim {PPC::R24, -32}, 195218885Sdim {PPC::R23, -36}, 196218885Sdim {PPC::R22, -40}, 197218885Sdim {PPC::R21, -44}, 198218885Sdim {PPC::R20, -48}, 199218885Sdim {PPC::R19, -52}, 200218885Sdim {PPC::R18, -56}, 201218885Sdim {PPC::R17, -60}, 202218885Sdim {PPC::R16, -64}, 203218885Sdim {PPC::R15, -68}, 204218885Sdim {PPC::R14, -72}, 205218885Sdim 206245431Sdim // CR save area offset. We map each of the nonvolatile CR fields 207245431Sdim // to the slot for CR2, which is the first of the nonvolatile CR 208245431Sdim // fields to be assigned, so that we only allocate one save slot. 209245431Sdim // See PPCRegisterInfo::hasReservedSpillSlot() for more information. 210245431Sdim {PPC::CR2, -4}, 211218885Sdim 212218885Sdim // VRSAVE save area offset. 213218885Sdim {PPC::VRSAVE, -4}, 214218885Sdim 215218885Sdim // Vector register save area 216218885Sdim {PPC::V31, -16}, 217218885Sdim {PPC::V30, -32}, 218218885Sdim {PPC::V29, -48}, 219218885Sdim {PPC::V28, -64}, 220218885Sdim {PPC::V27, -80}, 221218885Sdim {PPC::V26, -96}, 222218885Sdim {PPC::V25, -112}, 223218885Sdim {PPC::V24, -128}, 224218885Sdim {PPC::V23, -144}, 225218885Sdim {PPC::V22, -160}, 226218885Sdim {PPC::V21, -176}, 227218885Sdim {PPC::V20, -192} 228218885Sdim }; 229218885Sdim 230218885Sdim static const SpillSlot Offsets64[] = { 231218885Sdim // Floating-point register save area offsets. 232218885Sdim {PPC::F31, -8}, 233218885Sdim {PPC::F30, -16}, 234218885Sdim {PPC::F29, -24}, 235218885Sdim {PPC::F28, -32}, 236218885Sdim {PPC::F27, -40}, 237218885Sdim {PPC::F26, -48}, 238218885Sdim {PPC::F25, -56}, 239218885Sdim {PPC::F24, -64}, 240218885Sdim {PPC::F23, -72}, 241218885Sdim {PPC::F22, -80}, 242218885Sdim {PPC::F21, -88}, 243218885Sdim {PPC::F20, -96}, 244218885Sdim {PPC::F19, -104}, 245218885Sdim {PPC::F18, -112}, 246218885Sdim {PPC::F17, -120}, 247218885Sdim {PPC::F16, -128}, 248218885Sdim {PPC::F15, -136}, 249218885Sdim {PPC::F14, -144}, 250218885Sdim 251218885Sdim // General register save area offsets. 252218885Sdim {PPC::X31, -8}, 253218885Sdim {PPC::X30, -16}, 254218885Sdim {PPC::X29, -24}, 255218885Sdim {PPC::X28, -32}, 256218885Sdim {PPC::X27, -40}, 257218885Sdim {PPC::X26, -48}, 258218885Sdim {PPC::X25, -56}, 259218885Sdim {PPC::X24, -64}, 260218885Sdim {PPC::X23, -72}, 261218885Sdim {PPC::X22, -80}, 262218885Sdim {PPC::X21, -88}, 263218885Sdim {PPC::X20, -96}, 264218885Sdim {PPC::X19, -104}, 265218885Sdim {PPC::X18, -112}, 266218885Sdim {PPC::X17, -120}, 267218885Sdim {PPC::X16, -128}, 268218885Sdim {PPC::X15, -136}, 269218885Sdim {PPC::X14, -144}, 270218885Sdim 271218885Sdim // VRSAVE save area offset. 272218885Sdim {PPC::VRSAVE, -4}, 273218885Sdim 274218885Sdim // Vector register save area 275218885Sdim {PPC::V31, -16}, 276218885Sdim {PPC::V30, -32}, 277218885Sdim {PPC::V29, -48}, 278218885Sdim {PPC::V28, -64}, 279218885Sdim {PPC::V27, -80}, 280218885Sdim {PPC::V26, -96}, 281218885Sdim {PPC::V25, -112}, 282218885Sdim {PPC::V24, -128}, 283218885Sdim {PPC::V23, -144}, 284218885Sdim {PPC::V22, -160}, 285218885Sdim {PPC::V21, -176}, 286218885Sdim {PPC::V20, -192} 287218885Sdim }; 288218885Sdim 289218885Sdim if (Subtarget.isPPC64()) { 290218885Sdim NumEntries = array_lengthof(Offsets64); 291218885Sdim 292218885Sdim return Offsets64; 293218885Sdim } else { 294218885Sdim NumEntries = array_lengthof(Offsets); 295218885Sdim 296218885Sdim return Offsets; 297218885Sdim } 298218885Sdim } 299218885Sdim}; 300218885Sdim 301218885Sdim} // End llvm namespace 302218885Sdim 303218885Sdim#endif 304