Mips16FrameLowering.cpp revision 263508
1//===-- Mips16FrameLowering.cpp - Mips16 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 Mips16 implementation of TargetFrameLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Mips16FrameLowering.h"
15#include "MCTargetDesc/MipsBaseInfo.h"
16#include "Mips16InstrInfo.h"
17#include "MipsInstrInfo.h"
18#include "llvm/CodeGen/MachineFrameInfo.h"
19#include "llvm/CodeGen/MachineFunction.h"
20#include "llvm/CodeGen/MachineInstrBuilder.h"
21#include "llvm/CodeGen/MachineModuleInfo.h"
22#include "llvm/CodeGen/MachineRegisterInfo.h"
23#include "llvm/IR/DataLayout.h"
24#include "llvm/IR/Function.h"
25#include "llvm/Support/CommandLine.h"
26#include "llvm/Target/TargetOptions.h"
27
28using namespace llvm;
29
30void Mips16FrameLowering::emitPrologue(MachineFunction &MF) const {
31  MachineBasicBlock &MBB = MF.front();
32  MachineFrameInfo *MFI = MF.getFrameInfo();
33  const Mips16InstrInfo &TII =
34    *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo());
35  MachineBasicBlock::iterator MBBI = MBB.begin();
36  DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
37  uint64_t StackSize = MFI->getStackSize();
38
39  // No need to allocate space on the stack.
40  if (StackSize == 0 && !MFI->adjustsStack()) return;
41
42  MachineModuleInfo &MMI = MF.getMMI();
43  const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
44  MachineLocation DstML, SrcML;
45
46  // Adjust stack.
47  TII.makeFrame(Mips::SP, StackSize, MBB, MBBI);
48
49  // emit ".cfi_def_cfa_offset StackSize"
50  MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol();
51  BuildMI(MBB, MBBI, dl,
52          TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel);
53  MMI.addFrameInst(
54      MCCFIInstruction::createDefCfaOffset(AdjustSPLabel, -StackSize));
55
56  MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol();
57  BuildMI(MBB, MBBI, dl,
58          TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel);
59  unsigned S2 = MRI->getDwarfRegNum(Mips::S2, true);
60  MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S2, -8));
61
62  unsigned S1 = MRI->getDwarfRegNum(Mips::S1, true);
63  MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S1, -12));
64
65  unsigned S0 = MRI->getDwarfRegNum(Mips::S0, true);
66  MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S0, -16));
67
68  unsigned RA = MRI->getDwarfRegNum(Mips::RA, true);
69  MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, RA, -4));
70
71  if (hasFP(MF))
72    BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0)
73      .addReg(Mips::SP);
74
75}
76
77void Mips16FrameLowering::emitEpilogue(MachineFunction &MF,
78                                 MachineBasicBlock &MBB) const {
79  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
80  MachineFrameInfo *MFI = MF.getFrameInfo();
81  const Mips16InstrInfo &TII =
82    *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo());
83  DebugLoc dl = MBBI->getDebugLoc();
84  uint64_t StackSize = MFI->getStackSize();
85
86  if (!StackSize)
87    return;
88
89  if (hasFP(MF))
90    BuildMI(MBB, MBBI, dl, TII.get(Mips::Move32R16), Mips::SP)
91      .addReg(Mips::S0);
92
93  // Adjust stack.
94  // assumes stacksize multiple of 8
95  TII.restoreFrame(Mips::SP, StackSize, MBB, MBBI);
96}
97
98bool Mips16FrameLowering::
99spillCalleeSavedRegisters(MachineBasicBlock &MBB,
100                          MachineBasicBlock::iterator MI,
101                          const std::vector<CalleeSavedInfo> &CSI,
102                          const TargetRegisterInfo *TRI) const {
103  MachineFunction *MF = MBB.getParent();
104  MachineBasicBlock *EntryBlock = MF->begin();
105
106  //
107  // Registers RA, S0,S1 are the callee saved registers and they
108  // will be saved with the "save" instruction
109  // during emitPrologue
110  //
111  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
112    // Add the callee-saved register as live-in. Do not add if the register is
113    // RA and return address is taken, because it has already been added in
114    // method MipsTargetLowering::LowerRETURNADDR.
115    // It's killed at the spill, unless the register is RA and return address
116    // is taken.
117    unsigned Reg = CSI[i].getReg();
118    bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA)
119      && MF->getFrameInfo()->isReturnAddressTaken();
120    if (!IsRAAndRetAddrIsTaken)
121      EntryBlock->addLiveIn(Reg);
122  }
123
124  return true;
125}
126
127bool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
128                                          MachineBasicBlock::iterator MI,
129                                       const std::vector<CalleeSavedInfo> &CSI,
130                                       const TargetRegisterInfo *TRI) const {
131  //
132  // Registers RA,S0,S1 are the callee saved registers and they will be restored
133  // with the restore instruction during emitEpilogue.
134  // We need to override this virtual function, otherwise llvm will try and
135  // restore the registers on it's on from the stack.
136  //
137
138  return true;
139}
140
141// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
142void Mips16FrameLowering::
143eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
144                              MachineBasicBlock::iterator I) const {
145  if (!hasReservedCallFrame(MF)) {
146    int64_t Amount = I->getOperand(0).getImm();
147
148    if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
149      Amount = -Amount;
150
151    const Mips16InstrInfo &TII =
152      *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo());
153
154    TII.adjustStackPtr(Mips::SP, Amount, MBB, I);
155  }
156
157  MBB.erase(I);
158}
159
160bool
161Mips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
162  const MachineFrameInfo *MFI = MF.getFrameInfo();
163  // Reserve call frame if the size of the maximum call frame fits into 15-bit
164  // immediate field and there are no variable sized objects on the stack.
165  return isInt<15>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects();
166}
167
168void Mips16FrameLowering::
169processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
170                                     RegScavenger *RS) const {
171  MF.getRegInfo().setPhysRegUsed(Mips::RA);
172  MF.getRegInfo().setPhysRegUsed(Mips::S0);
173  MF.getRegInfo().setPhysRegUsed(Mips::S1);
174  MF.getRegInfo().setPhysRegUsed(Mips::S2);
175}
176
177const MipsFrameLowering *
178llvm::createMips16FrameLowering(const MipsSubtarget &ST) {
179  return new Mips16FrameLowering(ST);
180}
181