1de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//===-- LanaiFrameLowering.cpp - Lanai Frame Information ------------------===//
2de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
3de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//                     The LLVM Compiler Infrastructure
4de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
5de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source
6de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// License. See LICENSE.TXT for details.
7de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
8de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//===----------------------------------------------------------------------===//
9de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
10de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// This file contains the Lanai implementation of TargetFrameLowering class.
11de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
12de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//===----------------------------------------------------------------------===//
13de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
14de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "LanaiFrameLowering.h"
15de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
16de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "LanaiInstrInfo.h"
17de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "LanaiMachineFunctionInfo.h"
18de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "LanaiSubtarget.h"
19de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/CodeGen/MachineFrameInfo.h"
20de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/CodeGen/MachineFunction.h"
21de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/CodeGen/MachineInstrBuilder.h"
22de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/CodeGen/MachineRegisterInfo.h"
23de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/IR/Function.h"
24de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
25de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarusing namespace llvm;
26de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
27de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// Determines the size of the frame and maximum call frame size.
28de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const {
29de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MachineFrameInfo *MFI = MF.getFrameInfo();
30de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const LanaiRegisterInfo *LRI = STI.getRegisterInfo();
31de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
32de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Get the number of bytes to allocate from the FrameInfo.
33de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned FrameSize = MFI->getStackSize();
34de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
35de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Get the alignment.
36de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned StackAlign = LRI->needsStackRealignment(MF) ? MFI->getMaxAlignment()
37de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                       : getStackAlignment();
38de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
39de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Get the maximum call frame size of all the calls.
40de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned MaxCallFrameSize = MFI->getMaxCallFrameSize();
41de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
42de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // If we have dynamic alloca then MaxCallFrameSize needs to be aligned so
43de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // that allocations will be aligned.
44de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (MFI->hasVarSizedObjects())
45de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign);
46de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
47de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Update maximum call frame size.
48de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MFI->setMaxCallFrameSize(MaxCallFrameSize);
49de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
50de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Include call frame size in total.
51de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!(hasReservedCallFrame(MF) && MFI->adjustsStack()))
52de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    FrameSize += MaxCallFrameSize;
53de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
54de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Make sure the frame is aligned.
55de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  FrameSize = alignTo(FrameSize, StackAlign);
56de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
57de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Update frame info.
58de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MFI->setStackSize(FrameSize);
59de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
60de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
61de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// Iterates through each basic block in a machine function and replaces
62de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// ADJDYNALLOC pseudo instructions with a Lanai:ADDI with the
63de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// maximum call frame size as the immediate.
64de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction &MF) const {
65de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const LanaiInstrInfo &LII =
66de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
67de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned MaxCallFrameSize = MF.getFrameInfo()->getMaxCallFrameSize();
68de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
69de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); MBB != E;
70de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar       ++MBB) {
71de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    MachineBasicBlock::iterator MBBI = MBB->begin();
72de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    while (MBBI != MBB->end()) {
73de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      MachineInstr &MI = *MBBI++;
74de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (MI.getOpcode() == Lanai::ADJDYNALLOC) {
75de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        DebugLoc DL = MI.getDebugLoc();
76de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        unsigned Dst = MI.getOperand(0).getReg();
77de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        unsigned Src = MI.getOperand(1).getReg();
78de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
79de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        BuildMI(*MBB, MI, DL, LII.get(Lanai::ADD_I_LO), Dst)
80de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            .addReg(Src)
81de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            .addImm(MaxCallFrameSize);
82de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        MI.eraseFromParent();
83de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
84de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
85de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
86de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
87de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
88de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// Generates the following sequence for function entry:
89de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//   st %fp,-4[*%sp]        !push old FP
90de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//   add %sp,8,%fp          !generate new FP
91de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//   sub %sp,0x4,%sp        !allocate stack space (as needed)
92de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid LanaiFrameLowering::emitPrologue(MachineFunction &MF,
93de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                      MachineBasicBlock &MBB) const {
94de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
95de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
96de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MachineFrameInfo *MFI = MF.getFrameInfo();
97de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const LanaiInstrInfo &LII =
98de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
99de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MachineBasicBlock::iterator MBBI = MBB.begin();
100de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
101de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Debug location must be unknown since the first debug location is used
102de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // to determine the end of the prologue.
103de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  DebugLoc DL;
104de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
105de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Determine the correct frame layout
106de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  determineFrameLayout(MF);
107de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
108de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // FIXME: This appears to be overallocating.  Needs investigation.
109de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Get the number of bytes to allocate from the FrameInfo.
110de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned StackSize = MFI->getStackSize();
111de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
112de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Push old FP
113de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // st %fp,-4[*%sp]
114de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  BuildMI(MBB, MBBI, DL, LII.get(Lanai::SW_RI))
115de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .addReg(Lanai::FP)
116de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .addReg(Lanai::SP)
117de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .addImm(-4)
118de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .addImm(LPAC::makePreOp(LPAC::ADD))
119de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .setMIFlag(MachineInstr::FrameSetup);
120de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
121de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Generate new FP
122de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // add %sp,8,%fp
123de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::FP)
124de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .addReg(Lanai::SP)
125de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .addImm(8)
126de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .setMIFlag(MachineInstr::FrameSetup);
127de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
128de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Allocate space on the stack if needed
129de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // sub %sp,StackSize,%sp
130de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (StackSize != 0) {
131de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    BuildMI(MBB, MBBI, DL, LII.get(Lanai::SUB_I_LO), Lanai::SP)
132de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        .addReg(Lanai::SP)
133de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        .addImm(StackSize)
134de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        .setMIFlag(MachineInstr::FrameSetup);
135de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
136de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
137de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Replace ADJDYNANALLOC
138de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (MFI->hasVarSizedObjects())
139de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    replaceAdjDynAllocPseudo(MF);
140de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
141de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
142de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarMachineBasicBlock::iterator LanaiFrameLowering::eliminateCallFramePseudoInstr(
143de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    MachineFunction &MF, MachineBasicBlock &MBB,
144de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    MachineBasicBlock::iterator I) const {
145de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
146de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return MBB.erase(I);
147de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
148de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
149de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// The function epilogue should not depend on the current stack pointer!
150de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// It should use the frame pointer only.  This is mandatory because
151de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// of alloca; we also take advantage of it to omit stack adjustments
152de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// before returning.
153de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
154de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// Note that when we go to restore the preserved register values we must
155de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// not try to address their slots by using offsets from the stack pointer.
156de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// That's because the stack pointer may have been moved during the function
157de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// execution due to a call to alloca().  Rather, we must restore all
158de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// preserved registers via offsets from the frame pointer value.
159de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
160de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// Note also that when the current frame is being "popped" (by adjusting
161de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// the value of the stack pointer) on function exit, we must (for the
162de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// sake of alloca) set the new value of the stack pointer based upon
163de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// the current value of the frame pointer.  We can't just add what we
164de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// believe to be the (static) frame size to the stack pointer because
165de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// if we did that, and alloca() had been called during this function,
166de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// we would end up returning *without* having fully deallocated all of
167de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// the space grabbed by alloca.  If that happened, and a function
168de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// containing one or more alloca() calls was called over and over again,
169de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// then the stack would grow without limit!
170de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//
171de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// RET is lowered to
172de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//      ld -4[%fp],%pc  # modify %pc (two delay slots)
173de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// as the return address is in the stack frame and mov to pc is allowed.
174de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// emitEpilogue emits
175de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//      mov %fp,%sp     # restore the stack pointer
176de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//      ld -8[%fp],%fp  # restore the caller's frame pointer
177de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// before RET and the delay slot filler will move RET such that these
178de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// instructions execute in the delay slots of the load to PC.
179de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid LanaiFrameLowering::emitEpilogue(MachineFunction &MF,
180de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                      MachineBasicBlock &MBB) const {
181de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
182de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const LanaiInstrInfo &LII =
183de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
184de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  DebugLoc DL = MBBI->getDebugLoc();
185de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
186de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Restore the stack pointer using the callee's frame pointer value.
187de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::SP)
188de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .addReg(Lanai::FP)
189de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .addImm(0);
190de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
191de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Restore the frame pointer from the stack.
192de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  BuildMI(MBB, MBBI, DL, LII.get(Lanai::LDW_RI), Lanai::FP)
193de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .addReg(Lanai::FP)
194de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .addImm(-8)
195de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      .addImm(LPAC::ADD);
196de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
197de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
198de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid LanaiFrameLowering::determineCalleeSaves(MachineFunction &MF,
199de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                              BitVector &SavedRegs,
200de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                              RegScavenger *RS) const {
201de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
202de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
203de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MachineFrameInfo *MFI = MF.getFrameInfo();
204de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const LanaiRegisterInfo *LRI =
205de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      static_cast<const LanaiRegisterInfo *>(STI.getRegisterInfo());
206de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  int Offset = -4;
207de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
208de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Reserve 4 bytes for the saved RCA
209de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MFI->CreateFixedObject(4, Offset, true);
210de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Offset -= 4;
211de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
212de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Reserve 4 bytes for the saved FP
213de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MFI->CreateFixedObject(4, Offset, true);
214de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Offset -= 4;
215de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
216de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (LRI->hasBasePointer(MF)) {
217de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    MFI->CreateFixedObject(4, Offset, true);
218de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    SavedRegs.reset(LRI->getBaseRegister());
219de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
221