Mips16FrameLowering.cpp revision 276479
1239310Sdim//===-- Mips16FrameLowering.cpp - Mips16 Frame Information ----------------===//
2239310Sdim//
3239310Sdim//                     The LLVM Compiler Infrastructure
4239310Sdim//
5239310Sdim// This file is distributed under the University of Illinois Open Source
6239310Sdim// License. See LICENSE.TXT for details.
7239310Sdim//
8239310Sdim//===----------------------------------------------------------------------===//
9239310Sdim//
10239310Sdim// This file contains the Mips16 implementation of TargetFrameLowering class.
11239310Sdim//
12239310Sdim//===----------------------------------------------------------------------===//
13239310Sdim
14239310Sdim#include "Mips16FrameLowering.h"
15249423Sdim#include "MCTargetDesc/MipsBaseInfo.h"
16249423Sdim#include "Mips16InstrInfo.h"
17239310Sdim#include "MipsInstrInfo.h"
18276479Sdim#include "MipsRegisterInfo.h"
19276479Sdim#include "MipsSubtarget.h"
20239310Sdim#include "llvm/CodeGen/MachineFrameInfo.h"
21239310Sdim#include "llvm/CodeGen/MachineFunction.h"
22239310Sdim#include "llvm/CodeGen/MachineInstrBuilder.h"
23239310Sdim#include "llvm/CodeGen/MachineModuleInfo.h"
24239310Sdim#include "llvm/CodeGen/MachineRegisterInfo.h"
25249423Sdim#include "llvm/IR/DataLayout.h"
26249423Sdim#include "llvm/IR/Function.h"
27249423Sdim#include "llvm/Support/CommandLine.h"
28239310Sdim#include "llvm/Target/TargetOptions.h"
29239310Sdim
30239310Sdimusing namespace llvm;
31239310Sdim
32276479SdimMips16FrameLowering::Mips16FrameLowering(const MipsSubtarget &STI)
33276479Sdim    : MipsFrameLowering(STI, STI.stackAlignment()) {}
34276479Sdim
35239310Sdimvoid Mips16FrameLowering::emitPrologue(MachineFunction &MF) const {
36239310Sdim  MachineBasicBlock &MBB = MF.front();
37239310Sdim  MachineFrameInfo *MFI = MF.getFrameInfo();
38249423Sdim  const Mips16InstrInfo &TII =
39249423Sdim    *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo());
40239310Sdim  MachineBasicBlock::iterator MBBI = MBB.begin();
41239310Sdim  DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
42239310Sdim  uint64_t StackSize = MFI->getStackSize();
43239310Sdim
44239310Sdim  // No need to allocate space on the stack.
45239310Sdim  if (StackSize == 0 && !MFI->adjustsStack()) return;
46239310Sdim
47249423Sdim  MachineModuleInfo &MMI = MF.getMMI();
48261991Sdim  const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
49249423Sdim  MachineLocation DstML, SrcML;
50249423Sdim
51239310Sdim  // Adjust stack.
52249423Sdim  TII.makeFrame(Mips::SP, StackSize, MBB, MBBI);
53243830Sdim
54249423Sdim  // emit ".cfi_def_cfa_offset StackSize"
55276479Sdim  unsigned CFIIndex = MMI.addFrameInst(
56276479Sdim      MCCFIInstruction::createDefCfaOffset(nullptr, -StackSize));
57276479Sdim  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
58276479Sdim      .addCFIIndex(CFIIndex);
59249423Sdim
60276479Sdim  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
61249423Sdim
62276479Sdim  if (CSI.size()) {
63276479Sdim    const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
64249423Sdim
65276479Sdim    for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
66276479Sdim         E = CSI.end(); I != E; ++I) {
67276479Sdim      int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
68276479Sdim      unsigned Reg = I->getReg();
69276479Sdim      unsigned DReg = MRI->getDwarfRegNum(Reg, true);
70276479Sdim      unsigned CFIIndex = MMI.addFrameInst(
71276479Sdim          MCCFIInstruction::createOffset(nullptr, DReg, Offset));
72276479Sdim      BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
73276479Sdim          .addCFIIndex(CFIIndex);
74276479Sdim    }
75276479Sdim  }
76243830Sdim  if (hasFP(MF))
77243830Sdim    BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0)
78276479Sdim      .addReg(Mips::SP).setMIFlag(MachineInstr::FrameSetup);
79243830Sdim
80239310Sdim}
81239310Sdim
82239310Sdimvoid Mips16FrameLowering::emitEpilogue(MachineFunction &MF,
83239310Sdim                                 MachineBasicBlock &MBB) const {
84239310Sdim  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
85239310Sdim  MachineFrameInfo *MFI = MF.getFrameInfo();
86249423Sdim  const Mips16InstrInfo &TII =
87249423Sdim    *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo());
88239310Sdim  DebugLoc dl = MBBI->getDebugLoc();
89239310Sdim  uint64_t StackSize = MFI->getStackSize();
90239310Sdim
91239310Sdim  if (!StackSize)
92239310Sdim    return;
93239310Sdim
94243830Sdim  if (hasFP(MF))
95243830Sdim    BuildMI(MBB, MBBI, dl, TII.get(Mips::Move32R16), Mips::SP)
96243830Sdim      .addReg(Mips::S0);
97243830Sdim
98239310Sdim  // Adjust stack.
99249423Sdim  // assumes stacksize multiple of 8
100249423Sdim  TII.restoreFrame(Mips::SP, StackSize, MBB, MBBI);
101239310Sdim}
102239310Sdim
103239310Sdimbool Mips16FrameLowering::
104239310SdimspillCalleeSavedRegisters(MachineBasicBlock &MBB,
105239310Sdim                          MachineBasicBlock::iterator MI,
106239310Sdim                          const std::vector<CalleeSavedInfo> &CSI,
107239310Sdim                          const TargetRegisterInfo *TRI) const {
108243830Sdim  MachineFunction *MF = MBB.getParent();
109243830Sdim  MachineBasicBlock *EntryBlock = MF->begin();
110243830Sdim
111243830Sdim  //
112243830Sdim  // Registers RA, S0,S1 are the callee saved registers and they
113243830Sdim  // will be saved with the "save" instruction
114243830Sdim  // during emitPrologue
115243830Sdim  //
116243830Sdim  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
117243830Sdim    // Add the callee-saved register as live-in. Do not add if the register is
118243830Sdim    // RA and return address is taken, because it has already been added in
119243830Sdim    // method MipsTargetLowering::LowerRETURNADDR.
120243830Sdim    // It's killed at the spill, unless the register is RA and return address
121243830Sdim    // is taken.
122243830Sdim    unsigned Reg = CSI[i].getReg();
123243830Sdim    bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA)
124243830Sdim      && MF->getFrameInfo()->isReturnAddressTaken();
125243830Sdim    if (!IsRAAndRetAddrIsTaken)
126243830Sdim      EntryBlock->addLiveIn(Reg);
127243830Sdim  }
128243830Sdim
129239310Sdim  return true;
130239310Sdim}
131239310Sdim
132243830Sdimbool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
133243830Sdim                                          MachineBasicBlock::iterator MI,
134243830Sdim                                       const std::vector<CalleeSavedInfo> &CSI,
135243830Sdim                                       const TargetRegisterInfo *TRI) const {
136243830Sdim  //
137243830Sdim  // Registers RA,S0,S1 are the callee saved registers and they will be restored
138243830Sdim  // with the restore instruction during emitEpilogue.
139243830Sdim  // We need to override this virtual function, otherwise llvm will try and
140243830Sdim  // restore the registers on it's on from the stack.
141243830Sdim  //
142243830Sdim
143243830Sdim  return true;
144243830Sdim}
145243830Sdim
146249423Sdim// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
147249423Sdimvoid Mips16FrameLowering::
148249423SdimeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
149249423Sdim                              MachineBasicBlock::iterator I) const {
150249423Sdim  if (!hasReservedCallFrame(MF)) {
151249423Sdim    int64_t Amount = I->getOperand(0).getImm();
152249423Sdim
153249423Sdim    if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
154249423Sdim      Amount = -Amount;
155249423Sdim
156249423Sdim    const Mips16InstrInfo &TII =
157249423Sdim      *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo());
158249423Sdim
159249423Sdim    TII.adjustStackPtr(Mips::SP, Amount, MBB, I);
160249423Sdim  }
161249423Sdim
162249423Sdim  MBB.erase(I);
163249423Sdim}
164249423Sdim
165239310Sdimbool
166239310SdimMips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
167243830Sdim  const MachineFrameInfo *MFI = MF.getFrameInfo();
168243830Sdim  // Reserve call frame if the size of the maximum call frame fits into 15-bit
169243830Sdim  // immediate field and there are no variable sized objects on the stack.
170243830Sdim  return isInt<15>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects();
171239310Sdim}
172239310Sdim
173239310Sdimvoid Mips16FrameLowering::
174239310SdimprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF,
175239310Sdim                                     RegScavenger *RS) const {
176276479Sdim  const Mips16InstrInfo &TII =
177276479Sdim    *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo());
178276479Sdim  const MipsRegisterInfo &RI = TII.getRegisterInfo();
179276479Sdim  const BitVector Reserved = RI.getReservedRegs(MF);
180276479Sdim  bool SaveS2 = Reserved[Mips::S2];
181276479Sdim  if (SaveS2)
182276479Sdim    MF.getRegInfo().setPhysRegUsed(Mips::S2);
183276479Sdim  if (hasFP(MF))
184276479Sdim    MF.getRegInfo().setPhysRegUsed(Mips::S0);
185239310Sdim}
186239310Sdim
187239310Sdimconst MipsFrameLowering *
188239310Sdimllvm::createMips16FrameLowering(const MipsSubtarget &ST) {
189239310Sdim  return new Mips16FrameLowering(ST);
190239310Sdim}
191