LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Mips16FrameLowering.cpp
Go to the documentation of this file.
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"
16 #include "Mips16InstrInfo.h"
17 #include "MipsInstrInfo.h"
23 #include "llvm/IR/DataLayout.h"
24 #include "llvm/IR/Function.h"
27 
28 using namespace llvm;
29 
31  MachineBasicBlock &MBB = MF.front();
32  MachineFrameInfo *MFI = MF.getFrameInfo();
33  const Mips16InstrInfo &TII =
34  *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo());
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();
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 
78  MachineBasicBlock &MBB) const {
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 
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)
120  if (!IsRAAndRetAddrIsTaken)
121  EntryBlock->addLiveIn(Reg);
122  }
123 
124  return true;
125 }
126 
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
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 
160 bool
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 
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 
177 const MipsFrameLowering *
179  return new Mips16FrameLowering(ST);
180 }
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS) const
const MachineFunction * getParent() const
instr_iterator erase(instr_iterator I)
void setPhysRegUsed(unsigned Reg)
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number. Returns -1 if there is no equivalent va...
const MipsFrameLowering * createMips16FrameLowering(const MipsSubtarget &ST)
Create MipsFrameLowering objects.
void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
void makeFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition: MCDwarf.h:348
void addLiveIn(unsigned Reg)
bool isReturnAddressTaken() const
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA. Register remains the same, but offset is new...
Definition: MCDwarf.h:335
uint64_t getStackSize() const
MCSymbol * CreateTempSymbol()
Definition: MCContext.cpp:165
const HexagonInstrInfo * TII
void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
Adjust SP by Amount bytes.
Abstract Stack Frame Information.
const MachineBasicBlock & front() const
void emitPrologue(MachineFunction &MF) const
void restoreFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
bundle_iterator< MachineInstr, instr_iterator > iterator
bool hasReservedCallFrame(const MachineFunction &MF) const
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
virtual const TargetInstrInfo * getInstrInfo() const
const MCContext & getContext() const
unsigned getMaxCallFrameSize() const
MachineFrameInfo * getFrameInfo()
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:177
MachineRegisterInfo & getRegInfo()
#define I(x, y, z)
Definition: MD5.cpp:54
void addFrameInst(const MCCFIInstruction &Inst)
const TargetMachine & getTarget() const
bool hasVarSizedObjects() const
MachineModuleInfo & getMMI() const
const MCRegisterInfo & MRI
bool hasFP(const MachineFunction &MF) const