MipsSEFrameLowering.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
12d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===-- MipsSEFrameLowering.cpp - Mips32/64 Frame Information -------------===//
22d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//                     The LLVM Compiler Infrastructure
42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file is distributed under the University of Illinois Open Source
62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// License. See LICENSE.TXT for details.
72d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===//
92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file contains the Mips32/64 implementation of TargetFrameLowering class.
112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===//
132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "MipsSEFrameLowering.h"
152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "MCTargetDesc/MipsBaseInfo.h"
162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "MipsAnalyzeImmediate.h"
172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "MipsMachineFunction.h"
185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include "MipsSEInstrInfo.h"
195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include "llvm/CodeGen/MachineFrameInfo.h"
205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include "llvm/CodeGen/MachineFunction.h"
215d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include "llvm/CodeGen/MachineInstrBuilder.h"
225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include "llvm/CodeGen/MachineModuleInfo.h"
232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/CodeGen/MachineRegisterInfo.h"
242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/CodeGen/RegisterScavenging.h"
252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/IR/DataLayout.h"
262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/IR/Function.h"
272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/Support/CommandLine.h"
282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "llvm/Target/TargetOptions.h"
292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesusing namespace llvm;
312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesnamespace {
332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef MachineBasicBlock::iterator Iter;
342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic std::pair<unsigned, unsigned> getMFHiLoOpc(unsigned Src) {
362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (Mips::ACC64RegClass.contains(Src))
372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return std::make_pair((unsigned)Mips::PseudoMFHI,
382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                          (unsigned)Mips::PseudoMFLO);
392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (Mips::ACC64DSPRegClass.contains(Src))
412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return std::make_pair((unsigned)Mips::MFHI_DSP, (unsigned)Mips::MFLO_DSP);
422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (Mips::ACC128RegClass.contains(Src))
442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return std::make_pair((unsigned)Mips::PseudoMFHI64,
452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                          (unsigned)Mips::PseudoMFLO64);
462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return std::make_pair(0, 0);
482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines/// Helper class to expand pseudos.
512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesclass ExpandPseudo {
522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinespublic:
532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ExpandPseudo(MachineFunction &MF);
542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  bool expand();
552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesprivate:
572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  bool expandInstr(MachineBasicBlock &MBB, Iter I);
582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void expandLoadCCond(MachineBasicBlock &MBB, Iter I);
592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void expandStoreCCond(MachineBasicBlock &MBB, Iter I);
602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize);
612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned MFHiOpc,
622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                      unsigned MFLoOpc, unsigned RegSize);
632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  bool expandCopy(MachineBasicBlock &MBB, Iter I);
642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  bool expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned MFHiOpc,
652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                     unsigned MFLoOpc);
662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MachineFunction &MF;
682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MachineRegisterInfo &MRI;
692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines};
702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesExpandPseudo::ExpandPseudo(MachineFunction &MF_)
732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  : MF(MF_), MRI(MF.getRegInfo()) {}
742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesbool ExpandPseudo::expand() {
762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  bool Expanded = false;
772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  for (MachineFunction::iterator BB = MF.begin(), BBEnd = MF.end();
792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines       BB != BBEnd; ++BB)
802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    for (Iter I = BB->begin(), End = BB->end(); I != End;)
812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      Expanded |= expandInstr(*BB, I++);
822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return Expanded;
842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesbool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) {
872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  switch(I->getOpcode()) {
882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  case Mips::LOAD_CCOND_DSP:
892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    expandLoadCCond(MBB, I);
902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    break;
912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  case Mips::STORE_CCOND_DSP:
922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    expandStoreCCond(MBB, I);
932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    break;
94  case Mips::LOAD_ACC64:
95  case Mips::LOAD_ACC64DSP:
96    expandLoadACC(MBB, I, 4);
97    break;
98  case Mips::LOAD_ACC128:
99    expandLoadACC(MBB, I, 8);
100    break;
101  case Mips::STORE_ACC64:
102    expandStoreACC(MBB, I, Mips::PseudoMFHI, Mips::PseudoMFLO, 4);
103    break;
104  case Mips::STORE_ACC64DSP:
105    expandStoreACC(MBB, I, Mips::MFHI_DSP, Mips::MFLO_DSP, 4);
106    break;
107  case Mips::STORE_ACC128:
108    expandStoreACC(MBB, I, Mips::PseudoMFHI64, Mips::PseudoMFLO64, 8);
109    break;
110  case TargetOpcode::COPY:
111    if (!expandCopy(MBB, I))
112      return false;
113    break;
114  default:
115    return false;
116  }
117
118  MBB.erase(I);
119  return true;
120}
121
122void ExpandPseudo::expandLoadCCond(MachineBasicBlock &MBB, Iter I) {
123  //  load $vr, FI
124  //  copy ccond, $vr
125
126  assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
127
128  const MipsSEInstrInfo &TII =
129    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
130  const MipsRegisterInfo &RegInfo =
131    *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
132
133  const TargetRegisterClass *RC = RegInfo.intRegClass(4);
134  unsigned VR = MRI.createVirtualRegister(RC);
135  unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
136
137  TII.loadRegFromStack(MBB, I, VR, FI, RC, &RegInfo, 0);
138  BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), Dst)
139    .addReg(VR, RegState::Kill);
140}
141
142void ExpandPseudo::expandStoreCCond(MachineBasicBlock &MBB, Iter I) {
143  //  copy $vr, ccond
144  //  store $vr, FI
145
146  assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
147
148  const MipsSEInstrInfo &TII =
149    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
150  const MipsRegisterInfo &RegInfo =
151    *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
152
153  const TargetRegisterClass *RC = RegInfo.intRegClass(4);
154  unsigned VR = MRI.createVirtualRegister(RC);
155  unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
156
157  BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), VR)
158    .addReg(Src, getKillRegState(I->getOperand(0).isKill()));
159  TII.storeRegToStack(MBB, I, VR, true, FI, RC, &RegInfo, 0);
160}
161
162void ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I,
163                                 unsigned RegSize) {
164  //  load $vr0, FI
165  //  copy lo, $vr0
166  //  load $vr1, FI + 4
167  //  copy hi, $vr1
168
169  assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
170
171  const MipsSEInstrInfo &TII =
172    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
173  const MipsRegisterInfo &RegInfo =
174    *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
175
176  const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
177  unsigned VR0 = MRI.createVirtualRegister(RC);
178  unsigned VR1 = MRI.createVirtualRegister(RC);
179  unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
180  unsigned Lo = RegInfo.getSubReg(Dst, Mips::sub_lo);
181  unsigned Hi = RegInfo.getSubReg(Dst, Mips::sub_hi);
182  DebugLoc DL = I->getDebugLoc();
183  const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY);
184
185  TII.loadRegFromStack(MBB, I, VR0, FI, RC, &RegInfo, 0);
186  BuildMI(MBB, I, DL, Desc, Lo).addReg(VR0, RegState::Kill);
187  TII.loadRegFromStack(MBB, I, VR1, FI, RC, &RegInfo, RegSize);
188  BuildMI(MBB, I, DL, Desc, Hi).addReg(VR1, RegState::Kill);
189}
190
191void ExpandPseudo::expandStoreACC(MachineBasicBlock &MBB, Iter I,
192                                  unsigned MFHiOpc, unsigned MFLoOpc,
193                                  unsigned RegSize) {
194  //  mflo $vr0, src
195  //  store $vr0, FI
196  //  mfhi $vr1, src
197  //  store $vr1, FI + 4
198
199  assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
200
201  const MipsSEInstrInfo &TII =
202    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
203  const MipsRegisterInfo &RegInfo =
204    *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
205
206  const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
207  unsigned VR0 = MRI.createVirtualRegister(RC);
208  unsigned VR1 = MRI.createVirtualRegister(RC);
209  unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
210  unsigned SrcKill = getKillRegState(I->getOperand(0).isKill());
211  DebugLoc DL = I->getDebugLoc();
212
213  BuildMI(MBB, I, DL, TII.get(MFLoOpc), VR0).addReg(Src);
214  TII.storeRegToStack(MBB, I, VR0, true, FI, RC, &RegInfo, 0);
215  BuildMI(MBB, I, DL, TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);
216  TII.storeRegToStack(MBB, I, VR1, true, FI, RC, &RegInfo, RegSize);
217}
218
219bool ExpandPseudo::expandCopy(MachineBasicBlock &MBB, Iter I) {
220  unsigned Src = I->getOperand(1).getReg();
221  std::pair<unsigned, unsigned> Opcodes = getMFHiLoOpc(Src);
222
223  if (!Opcodes.first)
224    return false;
225
226  return expandCopyACC(MBB, I, Opcodes.first, Opcodes.second);
227}
228
229bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I,
230                                 unsigned MFHiOpc, unsigned MFLoOpc) {
231  //  mflo $vr0, src
232  //  copy dst_lo, $vr0
233  //  mfhi $vr1, src
234  //  copy dst_hi, $vr1
235
236  const MipsSEInstrInfo &TII =
237    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
238  const MipsRegisterInfo &RegInfo =
239    *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
240
241  unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg();
242  unsigned VRegSize = RegInfo.getMinimalPhysRegClass(Dst)->getSize() / 2;
243  const TargetRegisterClass *RC = RegInfo.intRegClass(VRegSize);
244  unsigned VR0 = MRI.createVirtualRegister(RC);
245  unsigned VR1 = MRI.createVirtualRegister(RC);
246  unsigned SrcKill = getKillRegState(I->getOperand(1).isKill());
247  unsigned DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo);
248  unsigned DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi);
249  DebugLoc DL = I->getDebugLoc();
250
251  BuildMI(MBB, I, DL, TII.get(MFLoOpc), VR0).addReg(Src);
252  BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstLo)
253    .addReg(VR0, RegState::Kill);
254  BuildMI(MBB, I, DL, TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);
255  BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstHi)
256    .addReg(VR1, RegState::Kill);
257  return true;
258}
259
260unsigned MipsSEFrameLowering::ehDataReg(unsigned I) const {
261  static const unsigned EhDataReg[] = {
262    Mips::A0, Mips::A1, Mips::A2, Mips::A3
263  };
264  static const unsigned EhDataReg64[] = {
265    Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64
266  };
267
268  return STI.isABI_N64() ? EhDataReg64[I] : EhDataReg[I];
269}
270
271void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
272  MachineBasicBlock &MBB   = MF.front();
273  MachineFrameInfo *MFI    = MF.getFrameInfo();
274  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
275
276  const MipsSEInstrInfo &TII =
277    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
278  const MipsRegisterInfo &RegInfo =
279    *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
280
281  MachineBasicBlock::iterator MBBI = MBB.begin();
282  DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
283  unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
284  unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
285  unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
286  unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
287
288  // First, compute final stack size.
289  uint64_t StackSize = MFI->getStackSize();
290
291  // No need to allocate space on the stack.
292  if (StackSize == 0 && !MFI->adjustsStack()) return;
293
294  MachineModuleInfo &MMI = MF.getMMI();
295  const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
296  MachineLocation DstML, SrcML;
297
298  // Adjust stack.
299  TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
300
301  // emit ".cfi_def_cfa_offset StackSize"
302  unsigned CFIIndex = MMI.addFrameInst(
303      MCCFIInstruction::createDefCfaOffset(nullptr, -StackSize));
304  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
305      .addCFIIndex(CFIIndex);
306
307  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
308
309  if (CSI.size()) {
310    // Find the instruction past the last instruction that saves a callee-saved
311    // register to the stack.
312    for (unsigned i = 0; i < CSI.size(); ++i)
313      ++MBBI;
314
315    // Iterate over list of callee-saved registers and emit .cfi_offset
316    // directives.
317    for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
318           E = CSI.end(); I != E; ++I) {
319      int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
320      unsigned Reg = I->getReg();
321
322      // If Reg is a double precision register, emit two cfa_offsets,
323      // one for each of the paired single precision registers.
324      if (Mips::AFGR64RegClass.contains(Reg)) {
325        unsigned Reg0 =
326            MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_lo), true);
327        unsigned Reg1 =
328            MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_hi), true);
329
330        if (!STI.isLittle())
331          std::swap(Reg0, Reg1);
332
333        unsigned CFIIndex = MMI.addFrameInst(
334            MCCFIInstruction::createOffset(nullptr, Reg0, Offset));
335        BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
336            .addCFIIndex(CFIIndex);
337
338        CFIIndex = MMI.addFrameInst(
339            MCCFIInstruction::createOffset(nullptr, Reg1, Offset + 4));
340        BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
341            .addCFIIndex(CFIIndex);
342      } else {
343        // Reg is either in GPR32 or FGR32.
344        unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset(
345            nullptr, MRI->getDwarfRegNum(Reg, 1), Offset));
346        BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
347            .addCFIIndex(CFIIndex);
348      }
349    }
350  }
351
352  if (MipsFI->callsEhReturn()) {
353    const TargetRegisterClass *RC = STI.isABI_N64() ?
354        &Mips::GPR64RegClass : &Mips::GPR32RegClass;
355
356    // Insert instructions that spill eh data registers.
357    for (int I = 0; I < 4; ++I) {
358      if (!MBB.isLiveIn(ehDataReg(I)))
359        MBB.addLiveIn(ehDataReg(I));
360      TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false,
361                              MipsFI->getEhDataRegFI(I), RC, &RegInfo);
362    }
363
364    // Emit .cfi_offset directives for eh data registers.
365    for (int I = 0; I < 4; ++I) {
366      int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I));
367      unsigned Reg = MRI->getDwarfRegNum(ehDataReg(I), true);
368      unsigned CFIIndex = MMI.addFrameInst(
369          MCCFIInstruction::createOffset(nullptr, Reg, Offset));
370      BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
371          .addCFIIndex(CFIIndex);
372    }
373  }
374
375  // if framepointer enabled, set it to point to the stack pointer.
376  if (hasFP(MF)) {
377    // Insert instruction "move $fp, $sp" at this location.
378    BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO);
379
380    // emit ".cfi_def_cfa_register $fp"
381    unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(
382        nullptr, MRI->getDwarfRegNum(FP, true)));
383    BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
384        .addCFIIndex(CFIIndex);
385  }
386}
387
388void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF,
389                                       MachineBasicBlock &MBB) const {
390  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
391  MachineFrameInfo *MFI            = MF.getFrameInfo();
392  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
393
394  const MipsSEInstrInfo &TII =
395    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
396  const MipsRegisterInfo &RegInfo =
397    *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
398
399  DebugLoc dl = MBBI->getDebugLoc();
400  unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
401  unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
402  unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
403  unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
404
405  // if framepointer enabled, restore the stack pointer.
406  if (hasFP(MF)) {
407    // Find the first instruction that restores a callee-saved register.
408    MachineBasicBlock::iterator I = MBBI;
409
410    for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
411      --I;
412
413    // Insert instruction "move $sp, $fp" at this location.
414    BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO);
415  }
416
417  if (MipsFI->callsEhReturn()) {
418    const TargetRegisterClass *RC = STI.isABI_N64() ?
419        &Mips::GPR64RegClass : &Mips::GPR32RegClass;
420
421    // Find first instruction that restores a callee-saved register.
422    MachineBasicBlock::iterator I = MBBI;
423    for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
424      --I;
425
426    // Insert instructions that restore eh data registers.
427    for (int J = 0; J < 4; ++J) {
428      TII.loadRegFromStackSlot(MBB, I, ehDataReg(J), MipsFI->getEhDataRegFI(J),
429                               RC, &RegInfo);
430    }
431  }
432
433  // Get the number of bytes from FrameInfo
434  uint64_t StackSize = MFI->getStackSize();
435
436  if (!StackSize)
437    return;
438
439  // Adjust stack.
440  TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
441}
442
443bool MipsSEFrameLowering::
444spillCalleeSavedRegisters(MachineBasicBlock &MBB,
445                          MachineBasicBlock::iterator MI,
446                          const std::vector<CalleeSavedInfo> &CSI,
447                          const TargetRegisterInfo *TRI) const {
448  MachineFunction *MF = MBB.getParent();
449  MachineBasicBlock *EntryBlock = MF->begin();
450  const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
451
452  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
453    // Add the callee-saved register as live-in. Do not add if the register is
454    // RA and return address is taken, because it has already been added in
455    // method MipsTargetLowering::LowerRETURNADDR.
456    // It's killed at the spill, unless the register is RA and return address
457    // is taken.
458    unsigned Reg = CSI[i].getReg();
459    bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
460        && MF->getFrameInfo()->isReturnAddressTaken();
461    if (!IsRAAndRetAddrIsTaken)
462      EntryBlock->addLiveIn(Reg);
463
464    // Insert the spill to the stack frame.
465    bool IsKill = !IsRAAndRetAddrIsTaken;
466    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
467    TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill,
468                            CSI[i].getFrameIdx(), RC, TRI);
469  }
470
471  return true;
472}
473
474bool
475MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
476  const MachineFrameInfo *MFI = MF.getFrameInfo();
477
478  // Reserve call frame if the size of the maximum call frame fits into 16-bit
479  // immediate field and there are no variable sized objects on the stack.
480  // Make sure the second register scavenger spill slot can be accessed with one
481  // instruction.
482  return isInt<16>(MFI->getMaxCallFrameSize() + getStackAlignment()) &&
483    !MFI->hasVarSizedObjects();
484}
485
486// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
487void MipsSEFrameLowering::
488eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
489                              MachineBasicBlock::iterator I) const {
490  const MipsSEInstrInfo &TII =
491    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
492
493  if (!hasReservedCallFrame(MF)) {
494    int64_t Amount = I->getOperand(0).getImm();
495
496    if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
497      Amount = -Amount;
498
499    unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
500    TII.adjustStackPtr(SP, Amount, MBB, I);
501  }
502
503  MBB.erase(I);
504}
505
506void MipsSEFrameLowering::
507processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
508                                     RegScavenger *RS) const {
509  MachineRegisterInfo &MRI = MF.getRegInfo();
510  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
511  unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
512
513  // Mark $fp as used if function has dedicated frame pointer.
514  if (hasFP(MF))
515    MRI.setPhysRegUsed(FP);
516
517  // Create spill slots for eh data registers if function calls eh_return.
518  if (MipsFI->callsEhReturn())
519    MipsFI->createEhDataRegsFI();
520
521  // Expand pseudo instructions which load, store or copy accumulators.
522  // Add an emergency spill slot if a pseudo was expanded.
523  if (ExpandPseudo(MF).expand()) {
524    // The spill slot should be half the size of the accumulator. If target is
525    // mips64, it should be 64-bit, otherwise it should be 32-bt.
526    const TargetRegisterClass *RC = STI.hasMips64() ?
527      &Mips::GPR64RegClass : &Mips::GPR32RegClass;
528    int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
529                                                  RC->getAlignment(), false);
530    RS->addScavengingFrameIndex(FI);
531  }
532
533  // Set scavenging frame index if necessary.
534  uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() +
535    estimateStackSize(MF);
536
537  if (isInt<16>(MaxSPOffset))
538    return;
539
540  const TargetRegisterClass *RC = STI.isABI_N64() ?
541    &Mips::GPR64RegClass : &Mips::GPR32RegClass;
542  int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
543                                                RC->getAlignment(), false);
544  RS->addScavengingFrameIndex(FI);
545}
546
547const MipsFrameLowering *
548llvm::createMipsSEFrameLowering(const MipsSubtarget &ST) {
549  return new MipsSEFrameLowering(ST);
550}
551