[mips] Define a function which returns the GPR register class.
[oota-llvm.git] / lib / Target / Mips / MipsSEFrameLowering.cpp
1 //===-- MipsSEFrameLowering.cpp - Mips32/64 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 Mips32/64 implementation of TargetFrameLowering class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "MipsSEFrameLowering.h"
15 #include "MCTargetDesc/MipsBaseInfo.h"
16 #include "MipsAnalyzeImmediate.h"
17 #include "MipsMachineFunction.h"
18 #include "MipsSEInstrInfo.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineModuleInfo.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/CodeGen/RegisterScavenging.h"
25 #include "llvm/IR/DataLayout.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/Support/CommandLine.h"
28 #include "llvm/Target/TargetOptions.h"
29
30 using namespace llvm;
31
32 unsigned MipsSEFrameLowering::ehDataReg(unsigned I) const {
33   static const unsigned EhDataReg[] = {
34     Mips::A0, Mips::A1, Mips::A2, Mips::A3
35   };
36   static const unsigned EhDataReg64[] = {
37     Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64
38   };
39
40   return STI.isABI_N64() ? EhDataReg64[I] : EhDataReg[I];
41 }
42
43 void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
44   MachineBasicBlock &MBB   = MF.front();
45   MachineFrameInfo *MFI    = MF.getFrameInfo();
46   MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
47   const MipsRegisterInfo *RegInfo =
48     static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
49   const MipsSEInstrInfo &TII =
50     *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
51   MachineBasicBlock::iterator MBBI = MBB.begin();
52   DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
53   unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
54   unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
55   unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
56   unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
57
58   // First, compute final stack size.
59   uint64_t StackSize = MFI->getStackSize();
60
61   // No need to allocate space on the stack.
62   if (StackSize == 0 && !MFI->adjustsStack()) return;
63
64   MachineModuleInfo &MMI = MF.getMMI();
65   std::vector<MachineMove> &Moves = MMI.getFrameMoves();
66   MachineLocation DstML, SrcML;
67
68   // Adjust stack.
69   TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
70
71   // emit ".cfi_def_cfa_offset StackSize"
72   MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol();
73   BuildMI(MBB, MBBI, dl,
74           TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel);
75   DstML = MachineLocation(MachineLocation::VirtualFP);
76   SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize);
77   Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML));
78
79   const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
80
81   if (CSI.size()) {
82     // Find the instruction past the last instruction that saves a callee-saved
83     // register to the stack.
84     for (unsigned i = 0; i < CSI.size(); ++i)
85       ++MBBI;
86
87     // Iterate over list of callee-saved registers and emit .cfi_offset
88     // directives.
89     MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol();
90     BuildMI(MBB, MBBI, dl,
91             TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel);
92
93     for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
94            E = CSI.end(); I != E; ++I) {
95       int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
96       unsigned Reg = I->getReg();
97
98       // If Reg is a double precision register, emit two cfa_offsets,
99       // one for each of the paired single precision registers.
100       if (Mips::AFGR64RegClass.contains(Reg)) {
101         MachineLocation DstML0(MachineLocation::VirtualFP, Offset);
102         MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4);
103         MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven));
104         MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd));
105
106         if (!STI.isLittle())
107           std::swap(SrcML0, SrcML1);
108
109         Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0));
110         Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1));
111       } else {
112         // Reg is either in CPURegs or FGR32.
113         DstML = MachineLocation(MachineLocation::VirtualFP, Offset);
114         SrcML = MachineLocation(Reg);
115         Moves.push_back(MachineMove(CSLabel, DstML, SrcML));
116       }
117     }
118   }
119
120   if (MipsFI->callsEhReturn()) {
121     const TargetRegisterClass *RC = STI.isABI_N64() ?
122         &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
123
124     // Insert instructions that spill eh data registers.
125     for (int I = 0; I < 4; ++I) {
126       if (!MBB.isLiveIn(ehDataReg(I)))
127         MBB.addLiveIn(ehDataReg(I));
128       TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false,
129                               MipsFI->getEhDataRegFI(I), RC, RegInfo);
130     }
131
132     // Emit .cfi_offset directives for eh data registers.
133     MCSymbol *CSLabel2 = MMI.getContext().CreateTempSymbol();
134     BuildMI(MBB, MBBI, dl,
135             TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2);
136     for (int I = 0; I < 4; ++I) {
137       int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I));
138       DstML = MachineLocation(MachineLocation::VirtualFP, Offset);
139       SrcML = MachineLocation(ehDataReg(I));
140       Moves.push_back(MachineMove(CSLabel2, DstML, SrcML));
141     }
142   }
143
144   // if framepointer enabled, set it to point to the stack pointer.
145   if (hasFP(MF)) {
146     // Insert instruction "move $fp, $sp" at this location.
147     BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO);
148
149     // emit ".cfi_def_cfa_register $fp"
150     MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol();
151     BuildMI(MBB, MBBI, dl,
152             TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel);
153     DstML = MachineLocation(FP);
154     SrcML = MachineLocation(MachineLocation::VirtualFP);
155     Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML));
156   }
157 }
158
159 void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF,
160                                        MachineBasicBlock &MBB) const {
161   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
162   MachineFrameInfo *MFI            = MF.getFrameInfo();
163   MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
164   const MipsRegisterInfo *RegInfo =
165     static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
166   const MipsSEInstrInfo &TII =
167     *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
168   DebugLoc dl = MBBI->getDebugLoc();
169   unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
170   unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
171   unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
172   unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
173
174   // if framepointer enabled, restore the stack pointer.
175   if (hasFP(MF)) {
176     // Find the first instruction that restores a callee-saved register.
177     MachineBasicBlock::iterator I = MBBI;
178
179     for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
180       --I;
181
182     // Insert instruction "move $sp, $fp" at this location.
183     BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO);
184   }
185
186   if (MipsFI->callsEhReturn()) {
187     const TargetRegisterClass *RC = STI.isABI_N64() ?
188         &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
189
190     // Find first instruction that restores a callee-saved register.
191     MachineBasicBlock::iterator I = MBBI;
192     for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
193       --I;
194
195     // Insert instructions that restore eh data registers.
196     for (int J = 0; J < 4; ++J) {
197       TII.loadRegFromStackSlot(MBB, I, ehDataReg(J), MipsFI->getEhDataRegFI(J),
198                                RC, RegInfo);
199     }
200   }
201
202   // Get the number of bytes from FrameInfo
203   uint64_t StackSize = MFI->getStackSize();
204
205   if (!StackSize)
206     return;
207
208   // Adjust stack.
209   TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
210 }
211
212 bool MipsSEFrameLowering::
213 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
214                           MachineBasicBlock::iterator MI,
215                           const std::vector<CalleeSavedInfo> &CSI,
216                           const TargetRegisterInfo *TRI) const {
217   MachineFunction *MF = MBB.getParent();
218   MachineBasicBlock *EntryBlock = MF->begin();
219   const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
220
221   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
222     // Add the callee-saved register as live-in. Do not add if the register is
223     // RA and return address is taken, because it has already been added in
224     // method MipsTargetLowering::LowerRETURNADDR.
225     // It's killed at the spill, unless the register is RA and return address
226     // is taken.
227     unsigned Reg = CSI[i].getReg();
228     bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
229         && MF->getFrameInfo()->isReturnAddressTaken();
230     if (!IsRAAndRetAddrIsTaken)
231       EntryBlock->addLiveIn(Reg);
232
233     // Insert the spill to the stack frame.
234     bool IsKill = !IsRAAndRetAddrIsTaken;
235     const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
236     TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill,
237                             CSI[i].getFrameIdx(), RC, TRI);
238   }
239
240   return true;
241 }
242
243 bool
244 MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
245   const MachineFrameInfo *MFI = MF.getFrameInfo();
246
247   // Reserve call frame if the size of the maximum call frame fits into 16-bit
248   // immediate field and there are no variable sized objects on the stack.
249   return isInt<16>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects();
250 }
251
252 // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
253 void MipsSEFrameLowering::
254 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
255                               MachineBasicBlock::iterator I) const {
256   const MipsSEInstrInfo &TII =
257     *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
258
259   if (!hasReservedCallFrame(MF)) {
260     int64_t Amount = I->getOperand(0).getImm();
261
262     if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
263       Amount = -Amount;
264
265     unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
266     TII.adjustStackPtr(SP, Amount, MBB, I);
267   }
268
269   MBB.erase(I);
270 }
271
272 void MipsSEFrameLowering::
273 processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
274                                      RegScavenger *RS) const {
275   MachineRegisterInfo &MRI = MF.getRegInfo();
276   MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
277   unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
278
279   // Mark $fp as used if function has dedicated frame pointer.
280   if (hasFP(MF))
281     MRI.setPhysRegUsed(FP);
282
283   // Create spill slots for eh data registers if function calls eh_return.
284   if (MipsFI->callsEhReturn())
285     MipsFI->createEhDataRegsFI();
286
287   // Set scavenging frame index if necessary.
288   uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() +
289     estimateStackSize(MF);
290
291   if (isInt<16>(MaxSPOffset))
292     return;
293
294   const TargetRegisterClass *RC = STI.isABI_N64() ?
295     &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
296   int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
297                                                 RC->getAlignment(), false);
298   RS->addScavengingFrameIndex(FI);
299 }
300
301 const MipsFrameLowering *
302 llvm::createMipsSEFrameLowering(const MipsSubtarget &ST) {
303   return new MipsSEFrameLowering(ST);
304 }