MipsSEFrameLowering.cpp revision 99ad6ac65e8c97a0d3c9d884285dda01f793b7d1
1//===-- MipsSEFrameLowering.cpp - Mips32/64 Frame Information -------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the Mips32/64 implementation of TargetFrameLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "MipsSEFrameLowering.h"
15#include "MCTargetDesc/MipsBaseInfo.h"
16#include "MipsAnalyzeImmediate.h"
17#include "MipsMachineFunction.h"
18#include "MipsSEInstrInfo.h"
19#include "llvm/CodeGen/MachineFrameInfo.h"
20#include "llvm/CodeGen/MachineFunction.h"
21#include "llvm/CodeGen/MachineInstrBuilder.h"
22#include "llvm/CodeGen/MachineModuleInfo.h"
23#include "llvm/CodeGen/MachineRegisterInfo.h"
24#include "llvm/CodeGen/RegisterScavenging.h"
25#include "llvm/IR/DataLayout.h"
26#include "llvm/IR/Function.h"
27#include "llvm/Support/CommandLine.h"
28#include "llvm/Target/TargetOptions.h"
29
30using namespace llvm;
31
32namespace {
33typedef MachineBasicBlock::iterator Iter;
34
35/// Helper class to expand pseudos.
36class ExpandPseudo {
37public:
38  ExpandPseudo(MachineFunction &MF);
39  bool expand();
40
41private:
42  bool expandInstr(MachineBasicBlock &MBB, Iter I);
43  void expandLoadCCond(MachineBasicBlock &MBB, Iter I);
44  void expandStoreCCond(MachineBasicBlock &MBB, Iter I);
45  void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize);
46  void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize);
47  bool expandCopy(MachineBasicBlock &MBB, Iter I);
48  bool expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned Dst,
49                     unsigned Src, unsigned RegSize);
50
51  MachineFunction &MF;
52  const MipsSEInstrInfo &TII;
53  const MipsRegisterInfo &RegInfo;
54  MachineRegisterInfo &MRI;
55};
56}
57
58ExpandPseudo::ExpandPseudo(MachineFunction &MF_)
59  : MF(MF_),
60    TII(*static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo())),
61    RegInfo(TII.getRegisterInfo()), MRI(MF.getRegInfo()) {}
62
63bool ExpandPseudo::expand() {
64  bool Expanded = false;
65
66  for (MachineFunction::iterator BB = MF.begin(), BBEnd = MF.end();
67       BB != BBEnd; ++BB)
68    for (Iter I = BB->begin(), End = BB->end(); I != End;)
69      Expanded |= expandInstr(*BB, I++);
70
71  return Expanded;
72}
73
74bool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) {
75  switch(I->getOpcode()) {
76  case Mips::LOAD_CCOND_DSP:
77  case Mips::LOAD_CCOND_DSP_P8:
78    expandLoadCCond(MBB, I);
79    break;
80  case Mips::STORE_CCOND_DSP:
81  case Mips::STORE_CCOND_DSP_P8:
82    expandStoreCCond(MBB, I);
83    break;
84  case Mips::LOAD_AC64:
85  case Mips::LOAD_AC64_P8:
86  case Mips::LOAD_AC_DSP:
87  case Mips::LOAD_AC_DSP_P8:
88    expandLoadACC(MBB, I, 4);
89    break;
90  case Mips::LOAD_AC128:
91  case Mips::LOAD_AC128_P8:
92    expandLoadACC(MBB, I, 8);
93    break;
94  case Mips::STORE_AC64:
95  case Mips::STORE_AC64_P8:
96  case Mips::STORE_AC_DSP:
97  case Mips::STORE_AC_DSP_P8:
98    expandStoreACC(MBB, I, 4);
99    break;
100  case Mips::STORE_AC128:
101  case Mips::STORE_AC128_P8:
102    expandStoreACC(MBB, I, 8);
103    break;
104  case TargetOpcode::COPY:
105    if (!expandCopy(MBB, I))
106      return false;
107    break;
108  default:
109    return false;
110  }
111
112  MBB.erase(I);
113  return true;
114}
115
116void ExpandPseudo::expandLoadCCond(MachineBasicBlock &MBB, Iter I) {
117  //  load $vr, FI
118  //  copy ccond, $vr
119
120  assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
121
122  const TargetRegisterClass *RC = RegInfo.intRegClass(4);
123  unsigned VR = MRI.createVirtualRegister(RC);
124  unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
125
126  TII.loadRegFromStack(MBB, I, VR, FI, RC, &RegInfo, 0);
127  BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), Dst)
128    .addReg(VR, RegState::Kill);
129}
130
131void ExpandPseudo::expandStoreCCond(MachineBasicBlock &MBB, Iter I) {
132  //  copy $vr, ccond
133  //  store $vr, FI
134
135  assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
136
137  const TargetRegisterClass *RC = RegInfo.intRegClass(4);
138  unsigned VR = MRI.createVirtualRegister(RC);
139  unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
140
141  BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), VR)
142    .addReg(Src, getKillRegState(I->getOperand(0).isKill()));
143  TII.storeRegToStack(MBB, I, VR, true, FI, RC, &RegInfo, 0);
144}
145
146void ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I,
147                                 unsigned RegSize) {
148  //  load $vr0, FI
149  //  copy lo, $vr0
150  //  load $vr1, FI + 4
151  //  copy hi, $vr1
152
153  assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
154
155  const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
156  unsigned VR0 = MRI.createVirtualRegister(RC);
157  unsigned VR1 = MRI.createVirtualRegister(RC);
158  unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
159  unsigned Lo = RegInfo.getSubReg(Dst, Mips::sub_lo);
160  unsigned Hi = RegInfo.getSubReg(Dst, Mips::sub_hi);
161  DebugLoc DL = I->getDebugLoc();
162  const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY);
163
164  TII.loadRegFromStack(MBB, I, VR0, FI, RC, &RegInfo, 0);
165  BuildMI(MBB, I, DL, Desc, Lo).addReg(VR0, RegState::Kill);
166  TII.loadRegFromStack(MBB, I, VR1, FI, RC, &RegInfo, RegSize);
167  BuildMI(MBB, I, DL, Desc, Hi).addReg(VR1, RegState::Kill);
168}
169
170void ExpandPseudo::expandStoreACC(MachineBasicBlock &MBB, Iter I,
171                                  unsigned RegSize) {
172  //  copy $vr0, lo
173  //  store $vr0, FI
174  //  copy $vr1, hi
175  //  store $vr1, FI + 4
176
177  assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
178
179  const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
180  unsigned VR0 = MRI.createVirtualRegister(RC);
181  unsigned VR1 = MRI.createVirtualRegister(RC);
182  unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
183  unsigned SrcKill = getKillRegState(I->getOperand(0).isKill());
184  unsigned Lo = RegInfo.getSubReg(Src, Mips::sub_lo);
185  unsigned Hi = RegInfo.getSubReg(Src, Mips::sub_hi);
186  DebugLoc DL = I->getDebugLoc();
187
188  BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR0).addReg(Lo, SrcKill);
189  TII.storeRegToStack(MBB, I, VR0, true, FI, RC, &RegInfo, 0);
190  BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR1).addReg(Hi, SrcKill);
191  TII.storeRegToStack(MBB, I, VR1, true, FI, RC, &RegInfo, RegSize);
192}
193
194bool ExpandPseudo::expandCopy(MachineBasicBlock &MBB, Iter I) {
195  unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg();
196
197  if (Mips::ACRegsDSPRegClass.contains(Dst, Src))
198    return expandCopyACC(MBB, I, Dst, Src, 4);
199
200  if (Mips::ACRegs128RegClass.contains(Dst, Src))
201    return expandCopyACC(MBB, I, Dst, Src, 8);
202
203  return false;
204}
205
206bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned Dst,
207                                 unsigned Src, unsigned RegSize) {
208  //  copy $vr0, src_lo
209  //  copy dst_lo, $vr0
210  //  copy $vr1, src_hi
211  //  copy dst_hi, $vr1
212
213  const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
214  unsigned VR0 = MRI.createVirtualRegister(RC);
215  unsigned VR1 = MRI.createVirtualRegister(RC);
216  unsigned SrcKill = getKillRegState(I->getOperand(1).isKill());
217  unsigned DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo);
218  unsigned DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi);
219  unsigned SrcLo = RegInfo.getSubReg(Src, Mips::sub_lo);
220  unsigned SrcHi = RegInfo.getSubReg(Src, Mips::sub_hi);
221  DebugLoc DL = I->getDebugLoc();
222
223  BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR0).addReg(SrcLo, SrcKill);
224  BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstLo)
225    .addReg(VR0, RegState::Kill);
226  BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR1).addReg(SrcHi, SrcKill);
227  BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstHi)
228    .addReg(VR1, RegState::Kill);
229  return true;
230}
231
232unsigned MipsSEFrameLowering::ehDataReg(unsigned I) const {
233  static const unsigned EhDataReg[] = {
234    Mips::A0, Mips::A1, Mips::A2, Mips::A3
235  };
236  static const unsigned EhDataReg64[] = {
237    Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64
238  };
239
240  return STI.isABI_N64() ? EhDataReg64[I] : EhDataReg[I];
241}
242
243void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
244  MachineBasicBlock &MBB   = MF.front();
245  MachineFrameInfo *MFI    = MF.getFrameInfo();
246  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
247  const MipsRegisterInfo *RegInfo =
248    static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
249  const MipsSEInstrInfo &TII =
250    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
251  MachineBasicBlock::iterator MBBI = MBB.begin();
252  DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
253  unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
254  unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
255  unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
256  unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
257
258  // First, compute final stack size.
259  uint64_t StackSize = MFI->getStackSize();
260
261  // No need to allocate space on the stack.
262  if (StackSize == 0 && !MFI->adjustsStack()) return;
263
264  MachineModuleInfo &MMI = MF.getMMI();
265  std::vector<MachineMove> &Moves = MMI.getFrameMoves();
266  MachineLocation DstML, SrcML;
267
268  // Adjust stack.
269  TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
270
271  // emit ".cfi_def_cfa_offset StackSize"
272  MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol();
273  BuildMI(MBB, MBBI, dl,
274          TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel);
275  DstML = MachineLocation(MachineLocation::VirtualFP);
276  SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize);
277  Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML));
278
279  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
280
281  if (CSI.size()) {
282    // Find the instruction past the last instruction that saves a callee-saved
283    // register to the stack.
284    for (unsigned i = 0; i < CSI.size(); ++i)
285      ++MBBI;
286
287    // Iterate over list of callee-saved registers and emit .cfi_offset
288    // directives.
289    MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol();
290    BuildMI(MBB, MBBI, dl,
291            TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel);
292
293    for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
294           E = CSI.end(); I != E; ++I) {
295      int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
296      unsigned Reg = I->getReg();
297
298      // If Reg is a double precision register, emit two cfa_offsets,
299      // one for each of the paired single precision registers.
300      if (Mips::AFGR64RegClass.contains(Reg)) {
301        MachineLocation DstML0(MachineLocation::VirtualFP, Offset);
302        MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4);
303        MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven));
304        MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd));
305
306        if (!STI.isLittle())
307          std::swap(SrcML0, SrcML1);
308
309        Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0));
310        Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1));
311      } else {
312        // Reg is either in CPURegs or FGR32.
313        DstML = MachineLocation(MachineLocation::VirtualFP, Offset);
314        SrcML = MachineLocation(Reg);
315        Moves.push_back(MachineMove(CSLabel, DstML, SrcML));
316      }
317    }
318  }
319
320  if (MipsFI->callsEhReturn()) {
321    const TargetRegisterClass *RC = STI.isABI_N64() ?
322        &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
323
324    // Insert instructions that spill eh data registers.
325    for (int I = 0; I < 4; ++I) {
326      if (!MBB.isLiveIn(ehDataReg(I)))
327        MBB.addLiveIn(ehDataReg(I));
328      TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false,
329                              MipsFI->getEhDataRegFI(I), RC, RegInfo);
330    }
331
332    // Emit .cfi_offset directives for eh data registers.
333    MCSymbol *CSLabel2 = MMI.getContext().CreateTempSymbol();
334    BuildMI(MBB, MBBI, dl,
335            TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2);
336    for (int I = 0; I < 4; ++I) {
337      int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I));
338      DstML = MachineLocation(MachineLocation::VirtualFP, Offset);
339      SrcML = MachineLocation(ehDataReg(I));
340      Moves.push_back(MachineMove(CSLabel2, DstML, SrcML));
341    }
342  }
343
344  // if framepointer enabled, set it to point to the stack pointer.
345  if (hasFP(MF)) {
346    // Insert instruction "move $fp, $sp" at this location.
347    BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO);
348
349    // emit ".cfi_def_cfa_register $fp"
350    MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol();
351    BuildMI(MBB, MBBI, dl,
352            TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel);
353    DstML = MachineLocation(FP);
354    SrcML = MachineLocation(MachineLocation::VirtualFP);
355    Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML));
356  }
357}
358
359void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF,
360                                       MachineBasicBlock &MBB) const {
361  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
362  MachineFrameInfo *MFI            = MF.getFrameInfo();
363  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
364  const MipsRegisterInfo *RegInfo =
365    static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
366  const MipsSEInstrInfo &TII =
367    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
368  DebugLoc dl = MBBI->getDebugLoc();
369  unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
370  unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
371  unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
372  unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
373
374  // if framepointer enabled, restore the stack pointer.
375  if (hasFP(MF)) {
376    // Find the first instruction that restores a callee-saved register.
377    MachineBasicBlock::iterator I = MBBI;
378
379    for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
380      --I;
381
382    // Insert instruction "move $sp, $fp" at this location.
383    BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO);
384  }
385
386  if (MipsFI->callsEhReturn()) {
387    const TargetRegisterClass *RC = STI.isABI_N64() ?
388        &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
389
390    // Find first instruction that restores a callee-saved register.
391    MachineBasicBlock::iterator I = MBBI;
392    for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
393      --I;
394
395    // Insert instructions that restore eh data registers.
396    for (int J = 0; J < 4; ++J) {
397      TII.loadRegFromStackSlot(MBB, I, ehDataReg(J), MipsFI->getEhDataRegFI(J),
398                               RC, RegInfo);
399    }
400  }
401
402  // Get the number of bytes from FrameInfo
403  uint64_t StackSize = MFI->getStackSize();
404
405  if (!StackSize)
406    return;
407
408  // Adjust stack.
409  TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
410}
411
412bool MipsSEFrameLowering::
413spillCalleeSavedRegisters(MachineBasicBlock &MBB,
414                          MachineBasicBlock::iterator MI,
415                          const std::vector<CalleeSavedInfo> &CSI,
416                          const TargetRegisterInfo *TRI) const {
417  MachineFunction *MF = MBB.getParent();
418  MachineBasicBlock *EntryBlock = MF->begin();
419  const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
420
421  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
422    // Add the callee-saved register as live-in. Do not add if the register is
423    // RA and return address is taken, because it has already been added in
424    // method MipsTargetLowering::LowerRETURNADDR.
425    // It's killed at the spill, unless the register is RA and return address
426    // is taken.
427    unsigned Reg = CSI[i].getReg();
428    bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
429        && MF->getFrameInfo()->isReturnAddressTaken();
430    if (!IsRAAndRetAddrIsTaken)
431      EntryBlock->addLiveIn(Reg);
432
433    // Insert the spill to the stack frame.
434    bool IsKill = !IsRAAndRetAddrIsTaken;
435    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
436    TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill,
437                            CSI[i].getFrameIdx(), RC, TRI);
438  }
439
440  return true;
441}
442
443bool
444MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
445  const MachineFrameInfo *MFI = MF.getFrameInfo();
446
447  // Reserve call frame if the size of the maximum call frame fits into 16-bit
448  // immediate field and there are no variable sized objects on the stack.
449  // Make sure the second register scavenger spill slot can be accessed with one
450  // instruction.
451  return isInt<16>(MFI->getMaxCallFrameSize() + getStackAlignment()) &&
452    !MFI->hasVarSizedObjects();
453}
454
455// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
456void MipsSEFrameLowering::
457eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
458                              MachineBasicBlock::iterator I) const {
459  const MipsSEInstrInfo &TII =
460    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
461
462  if (!hasReservedCallFrame(MF)) {
463    int64_t Amount = I->getOperand(0).getImm();
464
465    if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
466      Amount = -Amount;
467
468    unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
469    TII.adjustStackPtr(SP, Amount, MBB, I);
470  }
471
472  MBB.erase(I);
473}
474
475void MipsSEFrameLowering::
476processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
477                                     RegScavenger *RS) const {
478  MachineRegisterInfo &MRI = MF.getRegInfo();
479  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
480  unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
481
482  // Mark $fp as used if function has dedicated frame pointer.
483  if (hasFP(MF))
484    MRI.setPhysRegUsed(FP);
485
486  // Create spill slots for eh data registers if function calls eh_return.
487  if (MipsFI->callsEhReturn())
488    MipsFI->createEhDataRegsFI();
489
490  // Expand pseudo instructions which load, store or copy accumulators.
491  // Add an emergency spill slot if a pseudo was expanded.
492  if (ExpandPseudo(MF).expand()) {
493    // The spill slot should be half the size of the accumulator. If target is
494    // mips64, it should be 64-bit, otherwise it should be 32-bt.
495    const TargetRegisterClass *RC = STI.hasMips64() ?
496      &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
497    int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
498                                                  RC->getAlignment(), false);
499    RS->addScavengingFrameIndex(FI);
500  }
501
502  // Set scavenging frame index if necessary.
503  uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() +
504    estimateStackSize(MF);
505
506  if (isInt<16>(MaxSPOffset))
507    return;
508
509  const TargetRegisterClass *RC = STI.isABI_N64() ?
510    &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
511  int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
512                                                RC->getAlignment(), false);
513  RS->addScavengingFrameIndex(FI);
514}
515
516const MipsFrameLowering *
517llvm::createMipsSEFrameLowering(const MipsSubtarget &ST) {
518  return new MipsSEFrameLowering(ST);
519}
520