1cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka//===-- MipsSEFrameLowering.cpp - Mips32/64 Frame Information -------------===//
2cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka//
3cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka//                     The LLVM Compiler Infrastructure
4cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka//
5cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka// This file is distributed under the University of Illinois Open Source
6cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka// License. See LICENSE.TXT for details.
7cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka//
8cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka//===----------------------------------------------------------------------===//
9cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka//
10cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka// This file contains the Mips32/64 implementation of TargetFrameLowering class.
11cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka//
12cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka//===----------------------------------------------------------------------===//
13cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
14cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka#include "MipsSEFrameLowering.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MCTargetDesc/MipsBaseInfo.h"
16cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka#include "MipsAnalyzeImmediate.h"
17cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka#include "MipsMachineFunction.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MipsSEInstrInfo.h"
19cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka#include "llvm/CodeGen/MachineFrameInfo.h"
20cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka#include "llvm/CodeGen/MachineFunction.h"
21cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka#include "llvm/CodeGen/MachineInstrBuilder.h"
22cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka#include "llvm/CodeGen/MachineModuleInfo.h"
23cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka#include "llvm/CodeGen/MachineRegisterInfo.h"
2411a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka#include "llvm/CodeGen/RegisterScavenging.h"
250b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h"
260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
27cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka#include "llvm/Support/CommandLine.h"
28d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetOptions.h"
29cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
30cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanakausing namespace llvm;
31cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
32544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanakaunsigned MipsSEFrameLowering::ehDataReg(unsigned I) const {
33544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  static const unsigned EhDataReg[] = {
34544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    Mips::A0, Mips::A1, Mips::A2, Mips::A3
35544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  };
36544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  static const unsigned EhDataReg64[] = {
37544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64
38544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  };
39544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
40544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  return STI.isABI_N64() ? EhDataReg64[I] : EhDataReg[I];
41544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka}
42544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
43cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanakavoid MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
44cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  MachineBasicBlock &MBB   = MF.front();
45cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  MachineFrameInfo *MFI    = MF.getFrameInfo();
46544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
47cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  const MipsRegisterInfo *RegInfo =
48cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
4971746220d3d1c3e8efba35038ac2ff14b4a4d3aeAkira Hatanaka  const MipsSEInstrInfo &TII =
5071746220d3d1c3e8efba35038ac2ff14b4a4d3aeAkira Hatanaka    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
51cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  MachineBasicBlock::iterator MBBI = MBB.begin();
52cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
53cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
54cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
55cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
56cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
57cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
58cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  // First, compute final stack size.
59cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  uint64_t StackSize = MFI->getStackSize();
60cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
61cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  // No need to allocate space on the stack.
62cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  if (StackSize == 0 && !MFI->adjustsStack()) return;
63cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
64cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  MachineModuleInfo &MMI = MF.getMMI();
65cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  std::vector<MachineMove> &Moves = MMI.getFrameMoves();
66cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  MachineLocation DstML, SrcML;
67cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
68cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  // Adjust stack.
6971746220d3d1c3e8efba35038ac2ff14b4a4d3aeAkira Hatanaka  TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
70cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
71cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  // emit ".cfi_def_cfa_offset StackSize"
72cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol();
73cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  BuildMI(MBB, MBBI, dl,
74cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka          TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel);
75cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  DstML = MachineLocation(MachineLocation::VirtualFP);
76cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize);
77cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML));
78cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
79cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
80cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
81cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  if (CSI.size()) {
82cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // Find the instruction past the last instruction that saves a callee-saved
83cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // register to the stack.
84cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    for (unsigned i = 0; i < CSI.size(); ++i)
85cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka      ++MBBI;
86cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
87cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // Iterate over list of callee-saved registers and emit .cfi_offset
88cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // directives.
89cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol();
90cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    BuildMI(MBB, MBBI, dl,
91cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka            TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel);
92cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
93cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
94cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka           E = CSI.end(); I != E; ++I) {
95cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka      int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
96cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka      unsigned Reg = I->getReg();
97cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
98cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka      // If Reg is a double precision register, emit two cfa_offsets,
99cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka      // one for each of the paired single precision registers.
100cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka      if (Mips::AFGR64RegClass.contains(Reg)) {
101cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka        MachineLocation DstML0(MachineLocation::VirtualFP, Offset);
102cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka        MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4);
103cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka        MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven));
104cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka        MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd));
105cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
106cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka        if (!STI.isLittle())
107cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka          std::swap(SrcML0, SrcML1);
108cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
109cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka        Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0));
110cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka        Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1));
111cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka      } else {
112cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka        // Reg is either in CPURegs or FGR32.
113cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka        DstML = MachineLocation(MachineLocation::VirtualFP, Offset);
114cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka        SrcML = MachineLocation(Reg);
115cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka        Moves.push_back(MachineMove(CSLabel, DstML, SrcML));
116cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka      }
117cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    }
118cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  }
119cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
120544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  if (MipsFI->callsEhReturn()) {
121544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    const TargetRegisterClass *RC = STI.isABI_N64() ?
122544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka        &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
123544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
124544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    // Insert instructions that spill eh data registers.
125544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    for (int I = 0; I < 4; ++I) {
126544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka      if (!MBB.isLiveIn(ehDataReg(I)))
127544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka        MBB.addLiveIn(ehDataReg(I));
128544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka      TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false,
129544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka                              MipsFI->getEhDataRegFI(I), RC, RegInfo);
130544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    }
131544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
132544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    // Emit .cfi_offset directives for eh data registers.
133544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    MCSymbol *CSLabel2 = MMI.getContext().CreateTempSymbol();
134544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    BuildMI(MBB, MBBI, dl,
135544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka            TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2);
136544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    for (int I = 0; I < 4; ++I) {
137544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka      int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I));
138544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka      DstML = MachineLocation(MachineLocation::VirtualFP, Offset);
139544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka      SrcML = MachineLocation(ehDataReg(I));
140544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka      Moves.push_back(MachineMove(CSLabel2, DstML, SrcML));
141544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    }
142544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  }
143544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
144cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  // if framepointer enabled, set it to point to the stack pointer.
145cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  if (hasFP(MF)) {
146cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // Insert instruction "move $fp, $sp" at this location.
147cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO);
148cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
149cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // emit ".cfi_def_cfa_register $fp"
150cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol();
151cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    BuildMI(MBB, MBBI, dl,
152cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka            TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel);
153cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    DstML = MachineLocation(FP);
154cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    SrcML = MachineLocation(MachineLocation::VirtualFP);
155cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML));
156cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  }
157cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka}
158cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
159cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanakavoid MipsSEFrameLowering::emitEpilogue(MachineFunction &MF,
160cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka                                       MachineBasicBlock &MBB) const {
161cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
162cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  MachineFrameInfo *MFI            = MF.getFrameInfo();
163544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
164544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  const MipsRegisterInfo *RegInfo =
165544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
16671746220d3d1c3e8efba35038ac2ff14b4a4d3aeAkira Hatanaka  const MipsSEInstrInfo &TII =
16771746220d3d1c3e8efba35038ac2ff14b4a4d3aeAkira Hatanaka    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
168cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  DebugLoc dl = MBBI->getDebugLoc();
169cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
170cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
171cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
172cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
173cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
174cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  // if framepointer enabled, restore the stack pointer.
175cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  if (hasFP(MF)) {
176cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // Find the first instruction that restores a callee-saved register.
177cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    MachineBasicBlock::iterator I = MBBI;
178cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
179cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
180cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka      --I;
181cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
182cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // Insert instruction "move $sp, $fp" at this location.
183cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO);
184cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  }
185cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
186544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  if (MipsFI->callsEhReturn()) {
187544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    const TargetRegisterClass *RC = STI.isABI_N64() ?
188544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka        &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
189544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
190544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    // Find first instruction that restores a callee-saved register.
191544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    MachineBasicBlock::iterator I = MBBI;
192544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
193544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka      --I;
194544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
195544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    // Insert instructions that restore eh data registers.
196544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    for (int J = 0; J < 4; ++J) {
197544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka      TII.loadRegFromStackSlot(MBB, I, ehDataReg(J), MipsFI->getEhDataRegFI(J),
198544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka                               RC, RegInfo);
199544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    }
200544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  }
201544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
202cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  // Get the number of bytes from FrameInfo
203cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  uint64_t StackSize = MFI->getStackSize();
204cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
205cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  if (!StackSize)
206cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    return;
207cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
208cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  // Adjust stack.
20971746220d3d1c3e8efba35038ac2ff14b4a4d3aeAkira Hatanaka  TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
210cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka}
211cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
212cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanakabool MipsSEFrameLowering::
213cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira HatanakaspillCalleeSavedRegisters(MachineBasicBlock &MBB,
214cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka                          MachineBasicBlock::iterator MI,
215cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka                          const std::vector<CalleeSavedInfo> &CSI,
216cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka                          const TargetRegisterInfo *TRI) const {
217cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  MachineFunction *MF = MBB.getParent();
218cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  MachineBasicBlock *EntryBlock = MF->begin();
219cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
220cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
221cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
222cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // Add the callee-saved register as live-in. Do not add if the register is
223cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // RA and return address is taken, because it has already been added in
224cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // method MipsTargetLowering::LowerRETURNADDR.
225cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // It's killed at the spill, unless the register is RA and return address
226cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // is taken.
227cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    unsigned Reg = CSI[i].getReg();
228cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
229cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka        && MF->getFrameInfo()->isReturnAddressTaken();
230cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    if (!IsRAAndRetAddrIsTaken)
231cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka      EntryBlock->addLiveIn(Reg);
232cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
233cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    // Insert the spill to the stack frame.
234cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    bool IsKill = !IsRAAndRetAddrIsTaken;
235cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
236cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill,
237cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka                            CSI[i].getFrameIdx(), RC, TRI);
238cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  }
239cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
240cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  return true;
241cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka}
242cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
243cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanakabool
244cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira HatanakaMipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
245cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  const MachineFrameInfo *MFI = MF.getFrameInfo();
246cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
247cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  // Reserve call frame if the size of the maximum call frame fits into 16-bit
248cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  // immediate field and there are no variable sized objects on the stack.
249cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  return isInt<16>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects();
250cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka}
251cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
252700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
253700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Benderskyvoid MipsSEFrameLowering::
254700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli BenderskyeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
255700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky                              MachineBasicBlock::iterator I) const {
256700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  const MipsSEInstrInfo &TII =
257700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
258700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
259700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  if (!hasReservedCallFrame(MF)) {
260700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    int64_t Amount = I->getOperand(0).getImm();
261700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
262700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
263700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      Amount = -Amount;
264700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
265700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
266700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    TII.adjustStackPtr(SP, Amount, MBB, I);
267700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  }
268700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
269700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  MBB.erase(I);
270700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky}
271700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
272cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanakavoid MipsSEFrameLowering::
273cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira HatanakaprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF,
274cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka                                     RegScavenger *RS) const {
275cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  MachineRegisterInfo &MRI = MF.getRegInfo();
276544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
277cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
278cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka
279cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  // Mark $fp as used if function has dedicated frame pointer.
280cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka  if (hasFP(MF))
281cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka    MRI.setPhysRegUsed(FP);
28211a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka
283544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  // Create spill slots for eh data registers if function calls eh_return.
284544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka  if (MipsFI->callsEhReturn())
285544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka    MipsFI->createEhDataRegsFI();
286544cc21cf4807116251a699d8b1d3d4bace21597Akira Hatanaka
28711a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka  // Set scavenging frame index if necessary.
28811a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka  uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() +
28911a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka    estimateStackSize(MF);
29011a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka
29111a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka  if (isInt<16>(MaxSPOffset))
29211a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka    return;
29311a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka
29411a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka  const TargetRegisterClass *RC = STI.isABI_N64() ?
29511a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka    &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
29611a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka  int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
29711a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka                                                RC->getAlignment(), false);
29811a45c214c26bdc49ef58c0eb214df5200867ceeAkira Hatanaka  RS->setScavengingFrameIndex(FI);
299cdb3ba71ce550c5a41c84c3678225a39d6f0a414Akira Hatanaka}
300af2662606745bdebaa2cb43096274ce3d33b665fAkira Hatanaka
301af2662606745bdebaa2cb43096274ce3d33b665fAkira Hatanakaconst MipsFrameLowering *
302af2662606745bdebaa2cb43096274ce3d33b665fAkira Hatanakallvm::createMipsSEFrameLowering(const MipsSubtarget &ST) {
303af2662606745bdebaa2cb43096274ce3d33b665fAkira Hatanaka  return new MipsSEFrameLowering(ST);
304af2662606745bdebaa2cb43096274ce3d33b665fAkira Hatanaka}
305