Mips16FrameLowering.cpp revision 99cb622041a0839c7dfcf0263c5102a305a0fdb5
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 S1 = MRI->getDwarfRegNum(Mips::S1, true);
60  MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S1, -8));
61
62  unsigned S0 = MRI->getDwarfRegNum(Mips::S0, true);
63  MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S0, -12));
64
65  unsigned RA = MRI->getDwarfRegNum(Mips::RA, true);
66  MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, RA, -4));
67
68  if (hasFP(MF))
69    BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0)
70      .addReg(Mips::SP);
71
72}
73
74void Mips16FrameLowering::emitEpilogue(MachineFunction &MF,
75                                 MachineBasicBlock &MBB) const {
76  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
77  MachineFrameInfo *MFI = MF.getFrameInfo();
78  const Mips16InstrInfo &TII =
79    *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo());
80  DebugLoc dl = MBBI->getDebugLoc();
81  uint64_t StackSize = MFI->getStackSize();
82
83  if (!StackSize)
84    return;
85
86  if (hasFP(MF))
87    BuildMI(MBB, MBBI, dl, TII.get(Mips::Move32R16), Mips::SP)
88      .addReg(Mips::S0);
89
90  // Adjust stack.
91  // assumes stacksize multiple of 8
92  TII.restoreFrame(Mips::SP, StackSize, MBB, MBBI);
93}
94
95bool Mips16FrameLowering::
96spillCalleeSavedRegisters(MachineBasicBlock &MBB,
97                          MachineBasicBlock::iterator MI,
98                          const std::vector<CalleeSavedInfo> &CSI,
99                          const TargetRegisterInfo *TRI) const {
100  MachineFunction *MF = MBB.getParent();
101  MachineBasicBlock *EntryBlock = MF->begin();
102
103  //
104  // Registers RA, S0,S1 are the callee saved registers and they
105  // will be saved with the "save" instruction
106  // during emitPrologue
107  //
108  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
109    // Add the callee-saved register as live-in. Do not add if the register is
110    // RA and return address is taken, because it has already been added in
111    // method MipsTargetLowering::LowerRETURNADDR.
112    // It's killed at the spill, unless the register is RA and return address
113    // is taken.
114    unsigned Reg = CSI[i].getReg();
115    bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA)
116      && MF->getFrameInfo()->isReturnAddressTaken();
117    if (!IsRAAndRetAddrIsTaken)
118      EntryBlock->addLiveIn(Reg);
119  }
120
121  return true;
122}
123
124bool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
125                                          MachineBasicBlock::iterator MI,
126                                       const std::vector<CalleeSavedInfo> &CSI,
127                                       const TargetRegisterInfo *TRI) const {
128  //
129  // Registers RA,S0,S1 are the callee saved registers and they will be restored
130  // with the restore instruction during emitEpilogue.
131  // We need to override this virtual function, otherwise llvm will try and
132  // restore the registers on it's on from the stack.
133  //
134
135  return true;
136}
137
138// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
139void Mips16FrameLowering::
140eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
141                              MachineBasicBlock::iterator I) const {
142  if (!hasReservedCallFrame(MF)) {
143    int64_t Amount = I->getOperand(0).getImm();
144
145    if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
146      Amount = -Amount;
147
148    const Mips16InstrInfo &TII =
149      *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo());
150
151    TII.adjustStackPtr(Mips::SP, Amount, MBB, I);
152  }
153
154  MBB.erase(I);
155}
156
157bool
158Mips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
159  const MachineFrameInfo *MFI = MF.getFrameInfo();
160  // Reserve call frame if the size of the maximum call frame fits into 15-bit
161  // immediate field and there are no variable sized objects on the stack.
162  return isInt<15>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects();
163}
164
165void Mips16FrameLowering::
166processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
167                                     RegScavenger *RS) const {
168  MF.getRegInfo().setPhysRegUsed(Mips::RA);
169  MF.getRegInfo().setPhysRegUsed(Mips::S0);
170  MF.getRegInfo().setPhysRegUsed(Mips::S1);
171}
172
173const MipsFrameLowering *
174llvm::createMips16FrameLowering(const MipsSubtarget &ST) {
175  return new Mips16FrameLowering(ST);
176}
177