PPCFrameLowering.cpp revision 223017
1218885Sdim//=====- PPCFrameLowering.cpp - PPC Frame Information -----------*- 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// This file contains the PPC implementation of TargetFrameLowering class.
11218885Sdim//
12218885Sdim//===----------------------------------------------------------------------===//
13218885Sdim
14218885Sdim#include "PPCFrameLowering.h"
15218885Sdim#include "PPCInstrInfo.h"
16218885Sdim#include "PPCMachineFunctionInfo.h"
17218885Sdim#include "llvm/Function.h"
18218885Sdim#include "llvm/CodeGen/MachineFrameInfo.h"
19218885Sdim#include "llvm/CodeGen/MachineFunction.h"
20218885Sdim#include "llvm/CodeGen/MachineInstrBuilder.h"
21218885Sdim#include "llvm/CodeGen/MachineModuleInfo.h"
22218885Sdim#include "llvm/CodeGen/MachineRegisterInfo.h"
23218885Sdim#include "llvm/CodeGen/RegisterScavenging.h"
24218885Sdim#include "llvm/Target/TargetOptions.h"
25218885Sdim
26218885Sdimusing namespace llvm;
27218885Sdim
28218885Sdim// FIXME This disables some code that aligns the stack to a boundary bigger than
29218885Sdim// the default (16 bytes on Darwin) when there is a stack local of greater
30218885Sdim// alignment.  This does not currently work, because the delta between old and
31218885Sdim// new stack pointers is added to offsets that reference incoming parameters
32218885Sdim// after the prolog is generated, and the code that does that doesn't handle a
33218885Sdim// variable delta.  You don't want to do that anyway; a better approach is to
34218885Sdim// reserve another register that retains to the incoming stack pointer, and
35218885Sdim// reference parameters relative to that.
36218885Sdim#define ALIGN_STACK 0
37218885Sdim
38218885Sdim
39218885Sdim/// VRRegNo - Map from a numbered VR register to its enum value.
40218885Sdim///
41218885Sdimstatic const unsigned short VRRegNo[] = {
42218885Sdim PPC::V0 , PPC::V1 , PPC::V2 , PPC::V3 , PPC::V4 , PPC::V5 , PPC::V6 , PPC::V7 ,
43218885Sdim PPC::V8 , PPC::V9 , PPC::V10, PPC::V11, PPC::V12, PPC::V13, PPC::V14, PPC::V15,
44218885Sdim PPC::V16, PPC::V17, PPC::V18, PPC::V19, PPC::V20, PPC::V21, PPC::V22, PPC::V23,
45218885Sdim PPC::V24, PPC::V25, PPC::V26, PPC::V27, PPC::V28, PPC::V29, PPC::V30, PPC::V31
46218885Sdim};
47218885Sdim
48218885Sdim/// RemoveVRSaveCode - We have found that this function does not need any code
49218885Sdim/// to manipulate the VRSAVE register, even though it uses vector registers.
50218885Sdim/// This can happen when the only registers used are known to be live in or out
51218885Sdim/// of the function.  Remove all of the VRSAVE related code from the function.
52218885Sdimstatic void RemoveVRSaveCode(MachineInstr *MI) {
53218885Sdim  MachineBasicBlock *Entry = MI->getParent();
54218885Sdim  MachineFunction *MF = Entry->getParent();
55218885Sdim
56218885Sdim  // We know that the MTVRSAVE instruction immediately follows MI.  Remove it.
57218885Sdim  MachineBasicBlock::iterator MBBI = MI;
58218885Sdim  ++MBBI;
59218885Sdim  assert(MBBI != Entry->end() && MBBI->getOpcode() == PPC::MTVRSAVE);
60218885Sdim  MBBI->eraseFromParent();
61218885Sdim
62218885Sdim  bool RemovedAllMTVRSAVEs = true;
63218885Sdim  // See if we can find and remove the MTVRSAVE instruction from all of the
64218885Sdim  // epilog blocks.
65218885Sdim  for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I) {
66218885Sdim    // If last instruction is a return instruction, add an epilogue
67218885Sdim    if (!I->empty() && I->back().getDesc().isReturn()) {
68218885Sdim      bool FoundIt = false;
69218885Sdim      for (MBBI = I->end(); MBBI != I->begin(); ) {
70218885Sdim        --MBBI;
71218885Sdim        if (MBBI->getOpcode() == PPC::MTVRSAVE) {
72218885Sdim          MBBI->eraseFromParent();  // remove it.
73218885Sdim          FoundIt = true;
74218885Sdim          break;
75218885Sdim        }
76218885Sdim      }
77218885Sdim      RemovedAllMTVRSAVEs &= FoundIt;
78218885Sdim    }
79218885Sdim  }
80218885Sdim
81218885Sdim  // If we found and removed all MTVRSAVE instructions, remove the read of
82218885Sdim  // VRSAVE as well.
83218885Sdim  if (RemovedAllMTVRSAVEs) {
84218885Sdim    MBBI = MI;
85218885Sdim    assert(MBBI != Entry->begin() && "UPDATE_VRSAVE is first instr in block?");
86218885Sdim    --MBBI;
87218885Sdim    assert(MBBI->getOpcode() == PPC::MFVRSAVE && "VRSAVE instrs wandered?");
88218885Sdim    MBBI->eraseFromParent();
89218885Sdim  }
90218885Sdim
91218885Sdim  // Finally, nuke the UPDATE_VRSAVE.
92218885Sdim  MI->eraseFromParent();
93218885Sdim}
94218885Sdim
95218885Sdim// HandleVRSaveUpdate - MI is the UPDATE_VRSAVE instruction introduced by the
96218885Sdim// instruction selector.  Based on the vector registers that have been used,
97218885Sdim// transform this into the appropriate ORI instruction.
98218885Sdimstatic void HandleVRSaveUpdate(MachineInstr *MI, const TargetInstrInfo &TII) {
99218885Sdim  MachineFunction *MF = MI->getParent()->getParent();
100218885Sdim  DebugLoc dl = MI->getDebugLoc();
101218885Sdim
102218885Sdim  unsigned UsedRegMask = 0;
103218885Sdim  for (unsigned i = 0; i != 32; ++i)
104218885Sdim    if (MF->getRegInfo().isPhysRegUsed(VRRegNo[i]))
105218885Sdim      UsedRegMask |= 1 << (31-i);
106218885Sdim
107218885Sdim  // Live in and live out values already must be in the mask, so don't bother
108218885Sdim  // marking them.
109218885Sdim  for (MachineRegisterInfo::livein_iterator
110218885Sdim       I = MF->getRegInfo().livein_begin(),
111218885Sdim       E = MF->getRegInfo().livein_end(); I != E; ++I) {
112218885Sdim    unsigned RegNo = PPCRegisterInfo::getRegisterNumbering(I->first);
113218885Sdim    if (VRRegNo[RegNo] == I->first)        // If this really is a vector reg.
114218885Sdim      UsedRegMask &= ~(1 << (31-RegNo));   // Doesn't need to be marked.
115218885Sdim  }
116218885Sdim  for (MachineRegisterInfo::liveout_iterator
117218885Sdim       I = MF->getRegInfo().liveout_begin(),
118218885Sdim       E = MF->getRegInfo().liveout_end(); I != E; ++I) {
119218885Sdim    unsigned RegNo = PPCRegisterInfo::getRegisterNumbering(*I);
120218885Sdim    if (VRRegNo[RegNo] == *I)              // If this really is a vector reg.
121218885Sdim      UsedRegMask &= ~(1 << (31-RegNo));   // Doesn't need to be marked.
122218885Sdim  }
123218885Sdim
124218885Sdim  // If no registers are used, turn this into a copy.
125218885Sdim  if (UsedRegMask == 0) {
126218885Sdim    // Remove all VRSAVE code.
127218885Sdim    RemoveVRSaveCode(MI);
128218885Sdim    return;
129218885Sdim  }
130218885Sdim
131218885Sdim  unsigned SrcReg = MI->getOperand(1).getReg();
132218885Sdim  unsigned DstReg = MI->getOperand(0).getReg();
133218885Sdim
134218885Sdim  if ((UsedRegMask & 0xFFFF) == UsedRegMask) {
135218885Sdim    if (DstReg != SrcReg)
136218885Sdim      BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORI), DstReg)
137218885Sdim        .addReg(SrcReg)
138218885Sdim        .addImm(UsedRegMask);
139218885Sdim    else
140218885Sdim      BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORI), DstReg)
141218885Sdim        .addReg(SrcReg, RegState::Kill)
142218885Sdim        .addImm(UsedRegMask);
143218885Sdim  } else if ((UsedRegMask & 0xFFFF0000) == UsedRegMask) {
144218885Sdim    if (DstReg != SrcReg)
145218885Sdim      BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg)
146218885Sdim        .addReg(SrcReg)
147218885Sdim        .addImm(UsedRegMask >> 16);
148218885Sdim    else
149218885Sdim      BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg)
150218885Sdim        .addReg(SrcReg, RegState::Kill)
151218885Sdim        .addImm(UsedRegMask >> 16);
152218885Sdim  } else {
153218885Sdim    if (DstReg != SrcReg)
154218885Sdim      BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg)
155218885Sdim        .addReg(SrcReg)
156218885Sdim        .addImm(UsedRegMask >> 16);
157218885Sdim    else
158218885Sdim      BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORIS), DstReg)
159218885Sdim        .addReg(SrcReg, RegState::Kill)
160218885Sdim        .addImm(UsedRegMask >> 16);
161218885Sdim
162218885Sdim    BuildMI(*MI->getParent(), MI, dl, TII.get(PPC::ORI), DstReg)
163218885Sdim      .addReg(DstReg, RegState::Kill)
164218885Sdim      .addImm(UsedRegMask & 0xFFFF);
165218885Sdim  }
166218885Sdim
167218885Sdim  // Remove the old UPDATE_VRSAVE instruction.
168218885Sdim  MI->eraseFromParent();
169218885Sdim}
170218885Sdim
171218885Sdim/// determineFrameLayout - Determine the size of the frame and maximum call
172218885Sdim/// frame size.
173218885Sdimvoid PPCFrameLowering::determineFrameLayout(MachineFunction &MF) const {
174218885Sdim  MachineFrameInfo *MFI = MF.getFrameInfo();
175218885Sdim
176218885Sdim  // Get the number of bytes to allocate from the FrameInfo
177218885Sdim  unsigned FrameSize = MFI->getStackSize();
178218885Sdim
179218885Sdim  // Get the alignments provided by the target, and the maximum alignment
180218885Sdim  // (if any) of the fixed frame objects.
181218885Sdim  unsigned MaxAlign = MFI->getMaxAlignment();
182218885Sdim  unsigned TargetAlign = getStackAlignment();
183218885Sdim  unsigned AlignMask = TargetAlign - 1;  //
184218885Sdim
185218885Sdim  // If we are a leaf function, and use up to 224 bytes of stack space,
186218885Sdim  // don't have a frame pointer, calls, or dynamic alloca then we do not need
187218885Sdim  // to adjust the stack pointer (we fit in the Red Zone).
188218885Sdim  bool DisableRedZone = MF.getFunction()->hasFnAttr(Attribute::NoRedZone);
189218885Sdim  // FIXME SVR4 The 32-bit SVR4 ABI has no red zone.
190218885Sdim  if (!DisableRedZone &&
191218885Sdim      FrameSize <= 224 &&                          // Fits in red zone.
192218885Sdim      !MFI->hasVarSizedObjects() &&                // No dynamic alloca.
193218885Sdim      !MFI->adjustsStack() &&                      // No calls.
194218885Sdim      (!ALIGN_STACK || MaxAlign <= TargetAlign)) { // No special alignment.
195218885Sdim    // No need for frame
196218885Sdim    MFI->setStackSize(0);
197218885Sdim    return;
198218885Sdim  }
199218885Sdim
200218885Sdim  // Get the maximum call frame size of all the calls.
201218885Sdim  unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
202218885Sdim
203218885Sdim  // Maximum call frame needs to be at least big enough for linkage and 8 args.
204218885Sdim  unsigned minCallFrameSize = getMinCallFrameSize(Subtarget.isPPC64(),
205218885Sdim                                                  Subtarget.isDarwinABI());
206218885Sdim  maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize);
207218885Sdim
208218885Sdim  // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
209218885Sdim  // that allocations will be aligned.
210218885Sdim  if (MFI->hasVarSizedObjects())
211218885Sdim    maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask;
212218885Sdim
213218885Sdim  // Update maximum call frame size.
214218885Sdim  MFI->setMaxCallFrameSize(maxCallFrameSize);
215218885Sdim
216218885Sdim  // Include call frame size in total.
217218885Sdim  FrameSize += maxCallFrameSize;
218218885Sdim
219218885Sdim  // Make sure the frame is aligned.
220218885Sdim  FrameSize = (FrameSize + AlignMask) & ~AlignMask;
221218885Sdim
222218885Sdim  // Update frame info.
223218885Sdim  MFI->setStackSize(FrameSize);
224218885Sdim}
225218885Sdim
226218885Sdim// hasFP - Return true if the specified function actually has a dedicated frame
227218885Sdim// pointer register.
228218885Sdimbool PPCFrameLowering::hasFP(const MachineFunction &MF) const {
229218885Sdim  const MachineFrameInfo *MFI = MF.getFrameInfo();
230218885Sdim  // FIXME: This is pretty much broken by design: hasFP() might be called really
231218885Sdim  // early, before the stack layout was calculated and thus hasFP() might return
232218885Sdim  // true or false here depending on the time of call.
233218885Sdim  return (MFI->getStackSize()) && needsFP(MF);
234218885Sdim}
235218885Sdim
236218885Sdim// needsFP - Return true if the specified function should have a dedicated frame
237218885Sdim// pointer register.  This is true if the function has variable sized allocas or
238218885Sdim// if frame pointer elimination is disabled.
239218885Sdimbool PPCFrameLowering::needsFP(const MachineFunction &MF) const {
240218885Sdim  const MachineFrameInfo *MFI = MF.getFrameInfo();
241218885Sdim
242218885Sdim  // Naked functions have no stack frame pushed, so we don't have a frame
243218885Sdim  // pointer.
244218885Sdim  if (MF.getFunction()->hasFnAttr(Attribute::Naked))
245218885Sdim    return false;
246218885Sdim
247218885Sdim  return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects() ||
248218885Sdim    (GuaranteedTailCallOpt && MF.getInfo<PPCFunctionInfo>()->hasFastCall());
249218885Sdim}
250218885Sdim
251218885Sdim
252218885Sdimvoid PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
253218885Sdim  MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
254218885Sdim  MachineBasicBlock::iterator MBBI = MBB.begin();
255218885Sdim  MachineFrameInfo *MFI = MF.getFrameInfo();
256218885Sdim  const PPCInstrInfo &TII =
257218885Sdim    *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo());
258218885Sdim
259218885Sdim  MachineModuleInfo &MMI = MF.getMMI();
260218885Sdim  DebugLoc dl;
261218885Sdim  bool needsFrameMoves = MMI.hasDebugInfo() ||
262223017Sdim    MF.getFunction()->needsUnwindTableEntry();
263218885Sdim
264218885Sdim  // Prepare for frame info.
265218885Sdim  MCSymbol *FrameLabel = 0;
266218885Sdim
267218885Sdim  // Scan the prolog, looking for an UPDATE_VRSAVE instruction.  If we find it,
268218885Sdim  // process it.
269218885Sdim  for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) {
270218885Sdim    if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) {
271218885Sdim      HandleVRSaveUpdate(MBBI, TII);
272218885Sdim      break;
273218885Sdim    }
274218885Sdim  }
275218885Sdim
276218885Sdim  // Move MBBI back to the beginning of the function.
277218885Sdim  MBBI = MBB.begin();
278218885Sdim
279218885Sdim  // Work out frame sizes.
280218885Sdim  // FIXME: determineFrameLayout() may change the frame size. This should be
281218885Sdim  // moved upper, to some hook.
282218885Sdim  determineFrameLayout(MF);
283218885Sdim  unsigned FrameSize = MFI->getStackSize();
284218885Sdim
285218885Sdim  int NegFrameSize = -FrameSize;
286218885Sdim
287218885Sdim  // Get processor type.
288218885Sdim  bool isPPC64 = Subtarget.isPPC64();
289218885Sdim  // Get operating system
290218885Sdim  bool isDarwinABI = Subtarget.isDarwinABI();
291218885Sdim  // Check if the link register (LR) must be saved.
292218885Sdim  PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
293218885Sdim  bool MustSaveLR = FI->mustSaveLR();
294218885Sdim  // Do we have a frame pointer for this function?
295218885Sdim  bool HasFP = hasFP(MF);
296218885Sdim
297218885Sdim  int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI);
298218885Sdim
299218885Sdim  int FPOffset = 0;
300218885Sdim  if (HasFP) {
301218885Sdim    if (Subtarget.isSVR4ABI()) {
302218885Sdim      MachineFrameInfo *FFI = MF.getFrameInfo();
303218885Sdim      int FPIndex = FI->getFramePointerSaveIndex();
304218885Sdim      assert(FPIndex && "No Frame Pointer Save Slot!");
305218885Sdim      FPOffset = FFI->getObjectOffset(FPIndex);
306218885Sdim    } else {
307218885Sdim      FPOffset = PPCFrameLowering::getFramePointerSaveOffset(isPPC64, isDarwinABI);
308218885Sdim    }
309218885Sdim  }
310218885Sdim
311218885Sdim  if (isPPC64) {
312218885Sdim    if (MustSaveLR)
313218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR8), PPC::X0);
314218885Sdim
315218885Sdim    if (HasFP)
316218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::STD))
317218885Sdim        .addReg(PPC::X31)
318218885Sdim        .addImm(FPOffset/4)
319218885Sdim        .addReg(PPC::X1);
320218885Sdim
321218885Sdim    if (MustSaveLR)
322218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::STD))
323218885Sdim        .addReg(PPC::X0)
324218885Sdim        .addImm(LROffset / 4)
325218885Sdim        .addReg(PPC::X1);
326218885Sdim  } else {
327218885Sdim    if (MustSaveLR)
328218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::MFLR), PPC::R0);
329218885Sdim
330218885Sdim    if (HasFP)
331218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::STW))
332218885Sdim        .addReg(PPC::R31)
333218885Sdim        .addImm(FPOffset)
334218885Sdim        .addReg(PPC::R1);
335218885Sdim
336218885Sdim    if (MustSaveLR)
337218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::STW))
338218885Sdim        .addReg(PPC::R0)
339218885Sdim        .addImm(LROffset)
340218885Sdim        .addReg(PPC::R1);
341218885Sdim  }
342218885Sdim
343218885Sdim  // Skip if a leaf routine.
344218885Sdim  if (!FrameSize) return;
345218885Sdim
346218885Sdim  // Get stack alignments.
347218885Sdim  unsigned TargetAlign = getStackAlignment();
348218885Sdim  unsigned MaxAlign = MFI->getMaxAlignment();
349218885Sdim
350218885Sdim  // Adjust stack pointer: r1 += NegFrameSize.
351218885Sdim  // If there is a preferred stack alignment, align R1 now
352218885Sdim  if (!isPPC64) {
353218885Sdim    // PPC32.
354218885Sdim    if (ALIGN_STACK && MaxAlign > TargetAlign) {
355218885Sdim      assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) &&
356218885Sdim             "Invalid alignment!");
357218885Sdim      assert(isInt<16>(NegFrameSize) && "Unhandled stack size and alignment!");
358218885Sdim
359218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::RLWINM), PPC::R0)
360218885Sdim        .addReg(PPC::R1)
361218885Sdim        .addImm(0)
362218885Sdim        .addImm(32 - Log2_32(MaxAlign))
363218885Sdim        .addImm(31);
364218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC) ,PPC::R0)
365218885Sdim        .addReg(PPC::R0, RegState::Kill)
366218885Sdim        .addImm(NegFrameSize);
367218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX))
368218885Sdim        .addReg(PPC::R1)
369218885Sdim        .addReg(PPC::R1)
370218885Sdim        .addReg(PPC::R0);
371218885Sdim    } else if (isInt<16>(NegFrameSize)) {
372218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::STWU), PPC::R1)
373218885Sdim        .addReg(PPC::R1)
374218885Sdim        .addImm(NegFrameSize)
375218885Sdim        .addReg(PPC::R1);
376218885Sdim    } else {
377218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0)
378218885Sdim        .addImm(NegFrameSize >> 16);
379218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0)
380218885Sdim        .addReg(PPC::R0, RegState::Kill)
381218885Sdim        .addImm(NegFrameSize & 0xFFFF);
382218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::STWUX))
383218885Sdim        .addReg(PPC::R1)
384218885Sdim        .addReg(PPC::R1)
385218885Sdim        .addReg(PPC::R0);
386218885Sdim    }
387218885Sdim  } else {    // PPC64.
388218885Sdim    if (ALIGN_STACK && MaxAlign > TargetAlign) {
389218885Sdim      assert(isPowerOf2_32(MaxAlign) && isInt<16>(MaxAlign) &&
390218885Sdim             "Invalid alignment!");
391218885Sdim      assert(isInt<16>(NegFrameSize) && "Unhandled stack size and alignment!");
392218885Sdim
393218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::RLDICL), PPC::X0)
394218885Sdim        .addReg(PPC::X1)
395218885Sdim        .addImm(0)
396218885Sdim        .addImm(64 - Log2_32(MaxAlign));
397218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBFIC8), PPC::X0)
398218885Sdim        .addReg(PPC::X0)
399218885Sdim        .addImm(NegFrameSize);
400218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX))
401218885Sdim        .addReg(PPC::X1)
402218885Sdim        .addReg(PPC::X1)
403218885Sdim        .addReg(PPC::X0);
404218885Sdim    } else if (isInt<16>(NegFrameSize)) {
405218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::STDU), PPC::X1)
406218885Sdim        .addReg(PPC::X1)
407218885Sdim        .addImm(NegFrameSize / 4)
408218885Sdim        .addReg(PPC::X1);
409218885Sdim    } else {
410218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0)
411218885Sdim        .addImm(NegFrameSize >> 16);
412218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0)
413218885Sdim        .addReg(PPC::X0, RegState::Kill)
414218885Sdim        .addImm(NegFrameSize & 0xFFFF);
415218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::STDUX))
416218885Sdim        .addReg(PPC::X1)
417218885Sdim        .addReg(PPC::X1)
418218885Sdim        .addReg(PPC::X0);
419218885Sdim    }
420218885Sdim  }
421218885Sdim
422218885Sdim  std::vector<MachineMove> &Moves = MMI.getFrameMoves();
423218885Sdim
424218885Sdim  // Add the "machine moves" for the instructions we generated above, but in
425218885Sdim  // reverse order.
426218885Sdim  if (needsFrameMoves) {
427218885Sdim    // Mark effective beginning of when frame pointer becomes valid.
428218885Sdim    FrameLabel = MMI.getContext().CreateTempSymbol();
429218885Sdim    BuildMI(MBB, MBBI, dl, TII.get(PPC::PROLOG_LABEL)).addSym(FrameLabel);
430218885Sdim
431218885Sdim    // Show update of SP.
432218885Sdim    if (NegFrameSize) {
433218885Sdim      MachineLocation SPDst(MachineLocation::VirtualFP);
434218885Sdim      MachineLocation SPSrc(MachineLocation::VirtualFP, NegFrameSize);
435218885Sdim      Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
436218885Sdim    } else {
437218885Sdim      MachineLocation SP(isPPC64 ? PPC::X31 : PPC::R31);
438218885Sdim      Moves.push_back(MachineMove(FrameLabel, SP, SP));
439218885Sdim    }
440218885Sdim
441218885Sdim    if (HasFP) {
442218885Sdim      MachineLocation FPDst(MachineLocation::VirtualFP, FPOffset);
443218885Sdim      MachineLocation FPSrc(isPPC64 ? PPC::X31 : PPC::R31);
444218885Sdim      Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc));
445218885Sdim    }
446218885Sdim
447218885Sdim    if (MustSaveLR) {
448218885Sdim      MachineLocation LRDst(MachineLocation::VirtualFP, LROffset);
449218885Sdim      MachineLocation LRSrc(isPPC64 ? PPC::LR8 : PPC::LR);
450218885Sdim      Moves.push_back(MachineMove(FrameLabel, LRDst, LRSrc));
451218885Sdim    }
452218885Sdim  }
453218885Sdim
454218885Sdim  MCSymbol *ReadyLabel = 0;
455218885Sdim
456218885Sdim  // If there is a frame pointer, copy R1 into R31
457218885Sdim  if (HasFP) {
458218885Sdim    if (!isPPC64) {
459218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), PPC::R31)
460218885Sdim        .addReg(PPC::R1)
461218885Sdim        .addReg(PPC::R1);
462218885Sdim    } else {
463218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), PPC::X31)
464218885Sdim        .addReg(PPC::X1)
465218885Sdim        .addReg(PPC::X1);
466218885Sdim    }
467218885Sdim
468218885Sdim    if (needsFrameMoves) {
469218885Sdim      ReadyLabel = MMI.getContext().CreateTempSymbol();
470218885Sdim
471218885Sdim      // Mark effective beginning of when frame pointer is ready.
472218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::PROLOG_LABEL)).addSym(ReadyLabel);
473218885Sdim
474218885Sdim      MachineLocation FPDst(HasFP ? (isPPC64 ? PPC::X31 : PPC::R31) :
475218885Sdim                                    (isPPC64 ? PPC::X1 : PPC::R1));
476218885Sdim      MachineLocation FPSrc(MachineLocation::VirtualFP);
477218885Sdim      Moves.push_back(MachineMove(ReadyLabel, FPDst, FPSrc));
478218885Sdim    }
479218885Sdim  }
480218885Sdim
481218885Sdim  if (needsFrameMoves) {
482218885Sdim    MCSymbol *Label = HasFP ? ReadyLabel : FrameLabel;
483218885Sdim
484218885Sdim    // Add callee saved registers to move list.
485218885Sdim    const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
486218885Sdim    for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
487218885Sdim      int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx());
488218885Sdim      unsigned Reg = CSI[I].getReg();
489218885Sdim      if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue;
490223017Sdim
491223017Sdim      // This is a bit of a hack: CR2LT, CR2GT, CR2EQ and CR2UN are just
492223017Sdim      // subregisters of CR2. We just need to emit a move of CR2.
493223017Sdim      if (Reg == PPC::CR2LT || Reg == PPC::CR2GT || Reg == PPC::CR2EQ)
494223017Sdim        continue;
495223017Sdim      if (Reg == PPC::CR2UN)
496223017Sdim        Reg = PPC::CR2;
497223017Sdim
498218885Sdim      MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
499218885Sdim      MachineLocation CSSrc(Reg);
500218885Sdim      Moves.push_back(MachineMove(Label, CSDst, CSSrc));
501218885Sdim    }
502218885Sdim  }
503218885Sdim}
504218885Sdim
505218885Sdimvoid PPCFrameLowering::emitEpilogue(MachineFunction &MF,
506218885Sdim                                MachineBasicBlock &MBB) const {
507218885Sdim  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
508218885Sdim  assert(MBBI != MBB.end() && "Returning block has no terminator");
509218885Sdim  const PPCInstrInfo &TII =
510218885Sdim    *static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo());
511218885Sdim
512218885Sdim  unsigned RetOpcode = MBBI->getOpcode();
513218885Sdim  DebugLoc dl;
514218885Sdim
515218885Sdim  assert((RetOpcode == PPC::BLR ||
516218885Sdim          RetOpcode == PPC::TCRETURNri ||
517218885Sdim          RetOpcode == PPC::TCRETURNdi ||
518218885Sdim          RetOpcode == PPC::TCRETURNai ||
519218885Sdim          RetOpcode == PPC::TCRETURNri8 ||
520218885Sdim          RetOpcode == PPC::TCRETURNdi8 ||
521218885Sdim          RetOpcode == PPC::TCRETURNai8) &&
522218885Sdim         "Can only insert epilog into returning blocks");
523218885Sdim
524218885Sdim  // Get alignment info so we know how to restore r1
525218885Sdim  const MachineFrameInfo *MFI = MF.getFrameInfo();
526218885Sdim  unsigned TargetAlign = getStackAlignment();
527218885Sdim  unsigned MaxAlign = MFI->getMaxAlignment();
528218885Sdim
529218885Sdim  // Get the number of bytes allocated from the FrameInfo.
530218885Sdim  int FrameSize = MFI->getStackSize();
531218885Sdim
532218885Sdim  // Get processor type.
533218885Sdim  bool isPPC64 = Subtarget.isPPC64();
534218885Sdim  // Get operating system
535218885Sdim  bool isDarwinABI = Subtarget.isDarwinABI();
536218885Sdim  // Check if the link register (LR) has been saved.
537218885Sdim  PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
538218885Sdim  bool MustSaveLR = FI->mustSaveLR();
539218885Sdim  // Do we have a frame pointer for this function?
540218885Sdim  bool HasFP = hasFP(MF);
541218885Sdim
542218885Sdim  int LROffset = PPCFrameLowering::getReturnSaveOffset(isPPC64, isDarwinABI);
543218885Sdim
544218885Sdim  int FPOffset = 0;
545218885Sdim  if (HasFP) {
546218885Sdim    if (Subtarget.isSVR4ABI()) {
547218885Sdim      MachineFrameInfo *FFI = MF.getFrameInfo();
548218885Sdim      int FPIndex = FI->getFramePointerSaveIndex();
549218885Sdim      assert(FPIndex && "No Frame Pointer Save Slot!");
550218885Sdim      FPOffset = FFI->getObjectOffset(FPIndex);
551218885Sdim    } else {
552218885Sdim      FPOffset = PPCFrameLowering::getFramePointerSaveOffset(isPPC64, isDarwinABI);
553218885Sdim    }
554218885Sdim  }
555218885Sdim
556218885Sdim  bool UsesTCRet =  RetOpcode == PPC::TCRETURNri ||
557218885Sdim    RetOpcode == PPC::TCRETURNdi ||
558218885Sdim    RetOpcode == PPC::TCRETURNai ||
559218885Sdim    RetOpcode == PPC::TCRETURNri8 ||
560218885Sdim    RetOpcode == PPC::TCRETURNdi8 ||
561218885Sdim    RetOpcode == PPC::TCRETURNai8;
562218885Sdim
563218885Sdim  if (UsesTCRet) {
564218885Sdim    int MaxTCRetDelta = FI->getTailCallSPDelta();
565218885Sdim    MachineOperand &StackAdjust = MBBI->getOperand(1);
566218885Sdim    assert(StackAdjust.isImm() && "Expecting immediate value.");
567218885Sdim    // Adjust stack pointer.
568218885Sdim    int StackAdj = StackAdjust.getImm();
569218885Sdim    int Delta = StackAdj - MaxTCRetDelta;
570218885Sdim    assert((Delta >= 0) && "Delta must be positive");
571218885Sdim    if (MaxTCRetDelta>0)
572218885Sdim      FrameSize += (StackAdj +Delta);
573218885Sdim    else
574218885Sdim      FrameSize += StackAdj;
575218885Sdim  }
576218885Sdim
577218885Sdim  if (FrameSize) {
578218885Sdim    // The loaded (or persistent) stack pointer value is offset by the 'stwu'
579218885Sdim    // on entry to the function.  Add this offset back now.
580218885Sdim    if (!isPPC64) {
581218885Sdim      // If this function contained a fastcc call and GuaranteedTailCallOpt is
582218885Sdim      // enabled (=> hasFastCall()==true) the fastcc call might contain a tail
583218885Sdim      // call which invalidates the stack pointer value in SP(0). So we use the
584218885Sdim      // value of R31 in this case.
585218885Sdim      if (FI->hasFastCall() && isInt<16>(FrameSize)) {
586218885Sdim        assert(hasFP(MF) && "Expecting a valid the frame pointer.");
587218885Sdim        BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1)
588218885Sdim          .addReg(PPC::R31).addImm(FrameSize);
589218885Sdim      } else if(FI->hasFastCall()) {
590218885Sdim        BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS), PPC::R0)
591218885Sdim          .addImm(FrameSize >> 16);
592218885Sdim        BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI), PPC::R0)
593218885Sdim          .addReg(PPC::R0, RegState::Kill)
594218885Sdim          .addImm(FrameSize & 0xFFFF);
595218885Sdim        BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD4))
596218885Sdim          .addReg(PPC::R1)
597218885Sdim          .addReg(PPC::R31)
598218885Sdim          .addReg(PPC::R0);
599218885Sdim      } else if (isInt<16>(FrameSize) &&
600218885Sdim                 (!ALIGN_STACK || TargetAlign >= MaxAlign) &&
601218885Sdim                 !MFI->hasVarSizedObjects()) {
602218885Sdim        BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), PPC::R1)
603218885Sdim          .addReg(PPC::R1).addImm(FrameSize);
604218885Sdim      } else {
605218885Sdim        BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ),PPC::R1)
606218885Sdim          .addImm(0).addReg(PPC::R1);
607218885Sdim      }
608218885Sdim    } else {
609218885Sdim      if (FI->hasFastCall() && isInt<16>(FrameSize)) {
610218885Sdim        assert(hasFP(MF) && "Expecting a valid the frame pointer.");
611218885Sdim        BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1)
612218885Sdim          .addReg(PPC::X31).addImm(FrameSize);
613218885Sdim      } else if(FI->hasFastCall()) {
614218885Sdim        BuildMI(MBB, MBBI, dl, TII.get(PPC::LIS8), PPC::X0)
615218885Sdim          .addImm(FrameSize >> 16);
616218885Sdim        BuildMI(MBB, MBBI, dl, TII.get(PPC::ORI8), PPC::X0)
617218885Sdim          .addReg(PPC::X0, RegState::Kill)
618218885Sdim          .addImm(FrameSize & 0xFFFF);
619218885Sdim        BuildMI(MBB, MBBI, dl, TII.get(PPC::ADD8))
620218885Sdim          .addReg(PPC::X1)
621218885Sdim          .addReg(PPC::X31)
622218885Sdim          .addReg(PPC::X0);
623218885Sdim      } else if (isInt<16>(FrameSize) && TargetAlign >= MaxAlign &&
624218885Sdim            !MFI->hasVarSizedObjects()) {
625218885Sdim        BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI8), PPC::X1)
626218885Sdim           .addReg(PPC::X1).addImm(FrameSize);
627218885Sdim      } else {
628218885Sdim        BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X1)
629218885Sdim           .addImm(0).addReg(PPC::X1);
630218885Sdim      }
631218885Sdim    }
632218885Sdim  }
633218885Sdim
634218885Sdim  if (isPPC64) {
635218885Sdim    if (MustSaveLR)
636218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X0)
637218885Sdim        .addImm(LROffset/4).addReg(PPC::X1);
638218885Sdim
639218885Sdim    if (HasFP)
640218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X31)
641218885Sdim        .addImm(FPOffset/4).addReg(PPC::X1);
642218885Sdim
643218885Sdim    if (MustSaveLR)
644218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR8)).addReg(PPC::X0);
645218885Sdim  } else {
646218885Sdim    if (MustSaveLR)
647218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R0)
648218885Sdim          .addImm(LROffset).addReg(PPC::R1);
649218885Sdim
650218885Sdim    if (HasFP)
651218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R31)
652218885Sdim          .addImm(FPOffset).addReg(PPC::R1);
653218885Sdim
654218885Sdim    if (MustSaveLR)
655218885Sdim      BuildMI(MBB, MBBI, dl, TII.get(PPC::MTLR)).addReg(PPC::R0);
656218885Sdim  }
657218885Sdim
658218885Sdim  // Callee pop calling convention. Pop parameter/linkage area. Used for tail
659218885Sdim  // call optimization
660218885Sdim  if (GuaranteedTailCallOpt && RetOpcode == PPC::BLR &&
661218885Sdim      MF.getFunction()->getCallingConv() == CallingConv::Fast) {
662218885Sdim     PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
663218885Sdim     unsigned CallerAllocatedAmt = FI->getMinReservedArea();
664218885Sdim     unsigned StackReg = isPPC64 ? PPC::X1 : PPC::R1;
665218885Sdim     unsigned FPReg = isPPC64 ? PPC::X31 : PPC::R31;
666218885Sdim     unsigned TmpReg = isPPC64 ? PPC::X0 : PPC::R0;
667218885Sdim     unsigned ADDIInstr = isPPC64 ? PPC::ADDI8 : PPC::ADDI;
668218885Sdim     unsigned ADDInstr = isPPC64 ? PPC::ADD8 : PPC::ADD4;
669218885Sdim     unsigned LISInstr = isPPC64 ? PPC::LIS8 : PPC::LIS;
670218885Sdim     unsigned ORIInstr = isPPC64 ? PPC::ORI8 : PPC::ORI;
671218885Sdim
672218885Sdim     if (CallerAllocatedAmt && isInt<16>(CallerAllocatedAmt)) {
673218885Sdim       BuildMI(MBB, MBBI, dl, TII.get(ADDIInstr), StackReg)
674218885Sdim         .addReg(StackReg).addImm(CallerAllocatedAmt);
675218885Sdim     } else {
676218885Sdim       BuildMI(MBB, MBBI, dl, TII.get(LISInstr), TmpReg)
677218885Sdim          .addImm(CallerAllocatedAmt >> 16);
678218885Sdim       BuildMI(MBB, MBBI, dl, TII.get(ORIInstr), TmpReg)
679218885Sdim          .addReg(TmpReg, RegState::Kill)
680218885Sdim          .addImm(CallerAllocatedAmt & 0xFFFF);
681218885Sdim       BuildMI(MBB, MBBI, dl, TII.get(ADDInstr))
682218885Sdim          .addReg(StackReg)
683218885Sdim          .addReg(FPReg)
684218885Sdim          .addReg(TmpReg);
685218885Sdim     }
686218885Sdim  } else if (RetOpcode == PPC::TCRETURNdi) {
687218885Sdim    MBBI = MBB.getLastNonDebugInstr();
688218885Sdim    MachineOperand &JumpTarget = MBBI->getOperand(0);
689218885Sdim    BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
690218885Sdim      addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
691218885Sdim  } else if (RetOpcode == PPC::TCRETURNri) {
692218885Sdim    MBBI = MBB.getLastNonDebugInstr();
693218885Sdim    assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
694218885Sdim    BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR));
695218885Sdim  } else if (RetOpcode == PPC::TCRETURNai) {
696218885Sdim    MBBI = MBB.getLastNonDebugInstr();
697218885Sdim    MachineOperand &JumpTarget = MBBI->getOperand(0);
698218885Sdim    BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm());
699218885Sdim  } else if (RetOpcode == PPC::TCRETURNdi8) {
700218885Sdim    MBBI = MBB.getLastNonDebugInstr();
701218885Sdim    MachineOperand &JumpTarget = MBBI->getOperand(0);
702218885Sdim    BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
703218885Sdim      addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
704218885Sdim  } else if (RetOpcode == PPC::TCRETURNri8) {
705218885Sdim    MBBI = MBB.getLastNonDebugInstr();
706218885Sdim    assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
707218885Sdim    BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR8));
708218885Sdim  } else if (RetOpcode == PPC::TCRETURNai8) {
709218885Sdim    MBBI = MBB.getLastNonDebugInstr();
710218885Sdim    MachineOperand &JumpTarget = MBBI->getOperand(0);
711218885Sdim    BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm());
712218885Sdim  }
713218885Sdim}
714218885Sdim
715218885Sdimvoid PPCFrameLowering::getInitialFrameState(std::vector<MachineMove> &Moves) const {
716218885Sdim  // Initial state of the frame pointer is R1.
717218885Sdim  MachineLocation Dst(MachineLocation::VirtualFP);
718218885Sdim  MachineLocation Src(PPC::R1, 0);
719218885Sdim  Moves.push_back(MachineMove(0, Dst, Src));
720218885Sdim}
721218885Sdim
722218885Sdimstatic bool spillsCR(const MachineFunction &MF) {
723218885Sdim  const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
724218885Sdim  return FuncInfo->isCRSpilled();
725218885Sdim}
726218885Sdim
727218885Sdim/// MustSaveLR - Return true if this function requires that we save the LR
728218885Sdim/// register onto the stack in the prolog and restore it in the epilog of the
729218885Sdim/// function.
730218885Sdimstatic bool MustSaveLR(const MachineFunction &MF, unsigned LR) {
731218885Sdim  const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>();
732218885Sdim
733218885Sdim  // We need a save/restore of LR if there is any def of LR (which is
734218885Sdim  // defined by calls, including the PIC setup sequence), or if there is
735218885Sdim  // some use of the LR stack slot (e.g. for builtin_return_address).
736218885Sdim  // (LR comes in 32 and 64 bit versions.)
737218885Sdim  MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR);
738218885Sdim  return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired();
739218885Sdim}
740218885Sdim
741218885Sdimvoid
742218885SdimPPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
743218885Sdim                                                   RegScavenger *RS) const {
744218885Sdim  const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
745218885Sdim
746218885Sdim  //  Save and clear the LR state.
747218885Sdim  PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
748218885Sdim  unsigned LR = RegInfo->getRARegister();
749218885Sdim  FI->setMustSaveLR(MustSaveLR(MF, LR));
750218885Sdim  MF.getRegInfo().setPhysRegUnused(LR);
751218885Sdim
752218885Sdim  //  Save R31 if necessary
753218885Sdim  int FPSI = FI->getFramePointerSaveIndex();
754218885Sdim  bool isPPC64 = Subtarget.isPPC64();
755218885Sdim  bool isDarwinABI  = Subtarget.isDarwinABI();
756218885Sdim  MachineFrameInfo *MFI = MF.getFrameInfo();
757218885Sdim
758218885Sdim  // If the frame pointer save index hasn't been defined yet.
759218885Sdim  if (!FPSI && needsFP(MF)) {
760218885Sdim    // Find out what the fix offset of the frame pointer save area.
761218885Sdim    int FPOffset = getFramePointerSaveOffset(isPPC64, isDarwinABI);
762218885Sdim    // Allocate the frame index for frame pointer save area.
763218885Sdim    FPSI = MFI->CreateFixedObject(isPPC64? 8 : 4, FPOffset, true);
764218885Sdim    // Save the result.
765218885Sdim    FI->setFramePointerSaveIndex(FPSI);
766218885Sdim  }
767218885Sdim
768218885Sdim  // Reserve stack space to move the linkage area to in case of a tail call.
769218885Sdim  int TCSPDelta = 0;
770218885Sdim  if (GuaranteedTailCallOpt && (TCSPDelta = FI->getTailCallSPDelta()) < 0) {
771218885Sdim    MFI->CreateFixedObject(-1 * TCSPDelta, TCSPDelta, true);
772218885Sdim  }
773218885Sdim
774218885Sdim  // Reserve a slot closest to SP or frame pointer if we have a dynalloc or
775218885Sdim  // a large stack, which will require scavenging a register to materialize a
776218885Sdim  // large offset.
777218885Sdim  // FIXME: this doesn't actually check stack size, so is a bit pessimistic
778218885Sdim  // FIXME: doesn't detect whether or not we need to spill vXX, which requires
779218885Sdim  //        r0 for now.
780218885Sdim
781218885Sdim  if (RegInfo->requiresRegisterScavenging(MF)) // FIXME (64-bit): Enable.
782218885Sdim    if (needsFP(MF) || spillsCR(MF)) {
783218885Sdim      const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;
784218885Sdim      const TargetRegisterClass *G8RC = &PPC::G8RCRegClass;
785218885Sdim      const TargetRegisterClass *RC = isPPC64 ? G8RC : GPRC;
786218885Sdim      RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
787218885Sdim                                                         RC->getAlignment(),
788218885Sdim                                                         false));
789218885Sdim    }
790218885Sdim}
791218885Sdim
792218885Sdimvoid PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF)
793218885Sdim                                                                        const {
794218885Sdim  // Early exit if not using the SVR4 ABI.
795218885Sdim  if (!Subtarget.isSVR4ABI())
796218885Sdim    return;
797218885Sdim
798218885Sdim  // Get callee saved register information.
799218885Sdim  MachineFrameInfo *FFI = MF.getFrameInfo();
800218885Sdim  const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo();
801218885Sdim
802218885Sdim  // Early exit if no callee saved registers are modified!
803218885Sdim  if (CSI.empty() && !needsFP(MF)) {
804218885Sdim    return;
805218885Sdim  }
806218885Sdim
807218885Sdim  unsigned MinGPR = PPC::R31;
808218885Sdim  unsigned MinG8R = PPC::X31;
809218885Sdim  unsigned MinFPR = PPC::F31;
810218885Sdim  unsigned MinVR = PPC::V31;
811218885Sdim
812218885Sdim  bool HasGPSaveArea = false;
813218885Sdim  bool HasG8SaveArea = false;
814218885Sdim  bool HasFPSaveArea = false;
815218885Sdim  bool HasCRSaveArea = false;
816218885Sdim  bool HasVRSAVESaveArea = false;
817218885Sdim  bool HasVRSaveArea = false;
818218885Sdim
819218885Sdim  SmallVector<CalleeSavedInfo, 18> GPRegs;
820218885Sdim  SmallVector<CalleeSavedInfo, 18> G8Regs;
821218885Sdim  SmallVector<CalleeSavedInfo, 18> FPRegs;
822218885Sdim  SmallVector<CalleeSavedInfo, 18> VRegs;
823218885Sdim
824218885Sdim  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
825218885Sdim    unsigned Reg = CSI[i].getReg();
826218885Sdim    if (PPC::GPRCRegisterClass->contains(Reg)) {
827218885Sdim      HasGPSaveArea = true;
828218885Sdim
829218885Sdim      GPRegs.push_back(CSI[i]);
830218885Sdim
831218885Sdim      if (Reg < MinGPR) {
832218885Sdim        MinGPR = Reg;
833218885Sdim      }
834218885Sdim    } else if (PPC::G8RCRegisterClass->contains(Reg)) {
835218885Sdim      HasG8SaveArea = true;
836218885Sdim
837218885Sdim      G8Regs.push_back(CSI[i]);
838218885Sdim
839218885Sdim      if (Reg < MinG8R) {
840218885Sdim        MinG8R = Reg;
841218885Sdim      }
842218885Sdim    } else if (PPC::F8RCRegisterClass->contains(Reg)) {
843218885Sdim      HasFPSaveArea = true;
844218885Sdim
845218885Sdim      FPRegs.push_back(CSI[i]);
846218885Sdim
847218885Sdim      if (Reg < MinFPR) {
848218885Sdim        MinFPR = Reg;
849218885Sdim      }
850218885Sdim// FIXME SVR4: Disable CR save area for now.
851218885Sdim    } else if (PPC::CRBITRCRegisterClass->contains(Reg)
852218885Sdim               || PPC::CRRCRegisterClass->contains(Reg)) {
853218885Sdim//      HasCRSaveArea = true;
854218885Sdim    } else if (PPC::VRSAVERCRegisterClass->contains(Reg)) {
855218885Sdim      HasVRSAVESaveArea = true;
856218885Sdim    } else if (PPC::VRRCRegisterClass->contains(Reg)) {
857218885Sdim      HasVRSaveArea = true;
858218885Sdim
859218885Sdim      VRegs.push_back(CSI[i]);
860218885Sdim
861218885Sdim      if (Reg < MinVR) {
862218885Sdim        MinVR = Reg;
863218885Sdim      }
864218885Sdim    } else {
865218885Sdim      llvm_unreachable("Unknown RegisterClass!");
866218885Sdim    }
867218885Sdim  }
868218885Sdim
869218885Sdim  PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>();
870218885Sdim
871218885Sdim  int64_t LowerBound = 0;
872218885Sdim
873218885Sdim  // Take into account stack space reserved for tail calls.
874218885Sdim  int TCSPDelta = 0;
875218885Sdim  if (GuaranteedTailCallOpt && (TCSPDelta = PFI->getTailCallSPDelta()) < 0) {
876218885Sdim    LowerBound = TCSPDelta;
877218885Sdim  }
878218885Sdim
879218885Sdim  // The Floating-point register save area is right below the back chain word
880218885Sdim  // of the previous stack frame.
881218885Sdim  if (HasFPSaveArea) {
882218885Sdim    for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) {
883218885Sdim      int FI = FPRegs[i].getFrameIdx();
884218885Sdim
885218885Sdim      FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
886218885Sdim    }
887218885Sdim
888218885Sdim    LowerBound -= (31 - PPCRegisterInfo::getRegisterNumbering(MinFPR) + 1) * 8;
889218885Sdim  }
890218885Sdim
891218885Sdim  // Check whether the frame pointer register is allocated. If so, make sure it
892218885Sdim  // is spilled to the correct offset.
893218885Sdim  if (needsFP(MF)) {
894218885Sdim    HasGPSaveArea = true;
895218885Sdim
896218885Sdim    int FI = PFI->getFramePointerSaveIndex();
897218885Sdim    assert(FI && "No Frame Pointer Save Slot!");
898218885Sdim
899218885Sdim    FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
900218885Sdim  }
901218885Sdim
902218885Sdim  // General register save area starts right below the Floating-point
903218885Sdim  // register save area.
904218885Sdim  if (HasGPSaveArea || HasG8SaveArea) {
905218885Sdim    // Move general register save area spill slots down, taking into account
906218885Sdim    // the size of the Floating-point register save area.
907218885Sdim    for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) {
908218885Sdim      int FI = GPRegs[i].getFrameIdx();
909218885Sdim
910218885Sdim      FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
911218885Sdim    }
912218885Sdim
913218885Sdim    // Move general register save area spill slots down, taking into account
914218885Sdim    // the size of the Floating-point register save area.
915218885Sdim    for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) {
916218885Sdim      int FI = G8Regs[i].getFrameIdx();
917218885Sdim
918218885Sdim      FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
919218885Sdim    }
920218885Sdim
921218885Sdim    unsigned MinReg =
922218885Sdim      std::min<unsigned>(PPCRegisterInfo::getRegisterNumbering(MinGPR),
923218885Sdim                         PPCRegisterInfo::getRegisterNumbering(MinG8R));
924218885Sdim
925218885Sdim    if (Subtarget.isPPC64()) {
926218885Sdim      LowerBound -= (31 - MinReg + 1) * 8;
927218885Sdim    } else {
928218885Sdim      LowerBound -= (31 - MinReg + 1) * 4;
929218885Sdim    }
930218885Sdim  }
931218885Sdim
932218885Sdim  // The CR save area is below the general register save area.
933218885Sdim  if (HasCRSaveArea) {
934218885Sdim    // FIXME SVR4: Is it actually possible to have multiple elements in CSI
935218885Sdim    //             which have the CR/CRBIT register class?
936218885Sdim    // Adjust the frame index of the CR spill slot.
937218885Sdim    for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
938218885Sdim      unsigned Reg = CSI[i].getReg();
939218885Sdim
940218885Sdim      if (PPC::CRBITRCRegisterClass->contains(Reg) ||
941218885Sdim          PPC::CRRCRegisterClass->contains(Reg)) {
942218885Sdim        int FI = CSI[i].getFrameIdx();
943218885Sdim
944218885Sdim        FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
945218885Sdim      }
946218885Sdim    }
947218885Sdim
948218885Sdim    LowerBound -= 4; // The CR save area is always 4 bytes long.
949218885Sdim  }
950218885Sdim
951218885Sdim  if (HasVRSAVESaveArea) {
952218885Sdim    // FIXME SVR4: Is it actually possible to have multiple elements in CSI
953218885Sdim    //             which have the VRSAVE register class?
954218885Sdim    // Adjust the frame index of the VRSAVE spill slot.
955218885Sdim    for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
956218885Sdim      unsigned Reg = CSI[i].getReg();
957218885Sdim
958218885Sdim      if (PPC::VRSAVERCRegisterClass->contains(Reg)) {
959218885Sdim        int FI = CSI[i].getFrameIdx();
960218885Sdim
961218885Sdim        FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
962218885Sdim      }
963218885Sdim    }
964218885Sdim
965218885Sdim    LowerBound -= 4; // The VRSAVE save area is always 4 bytes long.
966218885Sdim  }
967218885Sdim
968218885Sdim  if (HasVRSaveArea) {
969218885Sdim    // Insert alignment padding, we need 16-byte alignment.
970218885Sdim    LowerBound = (LowerBound - 15) & ~(15);
971218885Sdim
972218885Sdim    for (unsigned i = 0, e = VRegs.size(); i != e; ++i) {
973218885Sdim      int FI = VRegs[i].getFrameIdx();
974218885Sdim
975218885Sdim      FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
976218885Sdim    }
977218885Sdim  }
978218885Sdim}
979