Move callee-saved regs spills / reloads to TFI
[oota-llvm.git] / lib / Target / SystemZ / SystemZFrameInfo.cpp
1 //=====- SystemZFrameInfo.cpp - SystemZ Frame Information ------*- C++ -*-====//
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 SystemZ implementation of TargetFrameInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "SystemZFrameInfo.h"
15 #include "SystemZInstrBuilder.h"
16 #include "SystemZInstrInfo.h"
17 #include "SystemZMachineFunctionInfo.h"
18 #include "llvm/Function.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/Target/TargetData.h"
25 #include "llvm/Target/TargetOptions.h"
26 #include "llvm/Support/CommandLine.h"
27
28 using namespace llvm;
29
30 SystemZFrameInfo::SystemZFrameInfo(const SystemZSubtarget &sti)
31   : TargetFrameInfo(TargetFrameInfo::StackGrowsDown, 8, -160), STI(sti) {
32   // Fill the spill offsets map
33   static const unsigned SpillOffsTab[][2] = {
34     { SystemZ::R2D,  0x10 },
35     { SystemZ::R3D,  0x18 },
36     { SystemZ::R4D,  0x20 },
37     { SystemZ::R5D,  0x28 },
38     { SystemZ::R6D,  0x30 },
39     { SystemZ::R7D,  0x38 },
40     { SystemZ::R8D,  0x40 },
41     { SystemZ::R9D,  0x48 },
42     { SystemZ::R10D, 0x50 },
43     { SystemZ::R11D, 0x58 },
44     { SystemZ::R12D, 0x60 },
45     { SystemZ::R13D, 0x68 },
46     { SystemZ::R14D, 0x70 },
47     { SystemZ::R15D, 0x78 }
48   };
49
50   RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS);
51
52   for (unsigned i = 0, e = array_lengthof(SpillOffsTab); i != e; ++i)
53     RegSpillOffsets[SpillOffsTab[i][0]] = SpillOffsTab[i][1];
54 }
55
56 /// needsFP - Return true if the specified function should have a dedicated
57 /// frame pointer register.  This is true if the function has variable sized
58 /// allocas or if frame pointer elimination is disabled.
59 bool SystemZFrameInfo::hasFP(const MachineFunction &MF) const {
60   const MachineFrameInfo *MFI = MF.getFrameInfo();
61   return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
62 }
63
64 /// emitSPUpdate - Emit a series of instructions to increment / decrement the
65 /// stack pointer by a constant value.
66 static
67 void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
68                   int64_t NumBytes, const TargetInstrInfo &TII) {
69   unsigned Opc; uint64_t Chunk;
70   bool isSub = NumBytes < 0;
71   uint64_t Offset = isSub ? -NumBytes : NumBytes;
72
73   if (Offset >= (1LL << 15) - 1) {
74     Opc = SystemZ::ADD64ri32;
75     Chunk = (1LL << 31) - 1;
76   } else {
77     Opc = SystemZ::ADD64ri16;
78     Chunk = (1LL << 15) - 1;
79   }
80
81   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
82
83   while (Offset) {
84     uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
85     MachineInstr *MI =
86       BuildMI(MBB, MBBI, DL, TII.get(Opc), SystemZ::R15D)
87       .addReg(SystemZ::R15D).addImm(isSub ? -ThisVal : ThisVal);
88     // The PSW implicit def is dead.
89     MI->getOperand(3).setIsDead();
90     Offset -= ThisVal;
91   }
92 }
93
94 void SystemZFrameInfo::emitPrologue(MachineFunction &MF) const {
95   MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
96   const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
97   MachineFrameInfo *MFI = MF.getFrameInfo();
98   const SystemZInstrInfo &TII =
99     *static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo());
100   SystemZMachineFunctionInfo *SystemZMFI =
101     MF.getInfo<SystemZMachineFunctionInfo>();
102   MachineBasicBlock::iterator MBBI = MBB.begin();
103   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
104
105   // Get the number of bytes to allocate from the FrameInfo.
106   // Note that area for callee-saved stuff is already allocated, thus we need to
107   // 'undo' the stack movement.
108   uint64_t StackSize = MFI->getStackSize();
109   StackSize -= SystemZMFI->getCalleeSavedFrameSize();
110
111   uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
112
113   // Skip the callee-saved push instructions.
114   while (MBBI != MBB.end() &&
115          (MBBI->getOpcode() == SystemZ::MOV64mr ||
116           MBBI->getOpcode() == SystemZ::MOV64mrm))
117     ++MBBI;
118
119   if (MBBI != MBB.end())
120     DL = MBBI->getDebugLoc();
121
122   // adjust stack pointer: R15 -= numbytes
123   if (StackSize || MFI->hasCalls()) {
124     assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) &&
125            "Invalid stack frame calculation!");
126     emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, TII);
127   }
128
129   if (hasFP(MF)) {
130     // Update R11 with the new base value...
131     BuildMI(MBB, MBBI, DL, TII.get(SystemZ::MOV64rr), SystemZ::R11D)
132       .addReg(SystemZ::R15D);
133
134     // Mark the FramePtr as live-in in every block except the entry.
135     for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end();
136          I != E; ++I)
137       I->addLiveIn(SystemZ::R11D);
138
139   }
140 }
141
142 void SystemZFrameInfo::emitEpilogue(MachineFunction &MF,
143                                     MachineBasicBlock &MBB) const {
144   const MachineFrameInfo *MFI = MF.getFrameInfo();
145   const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
146   MachineBasicBlock::iterator MBBI = prior(MBB.end());
147   const SystemZInstrInfo &TII =
148     *static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo());
149   SystemZMachineFunctionInfo *SystemZMFI =
150     MF.getInfo<SystemZMachineFunctionInfo>();
151   unsigned RetOpcode = MBBI->getOpcode();
152
153   switch (RetOpcode) {
154   case SystemZ::RET: break;  // These are ok
155   default:
156     assert(0 && "Can only insert epilog into returning blocks");
157   }
158
159   // Get the number of bytes to allocate from the FrameInfo
160   // Note that area for callee-saved stuff is already allocated, thus we need to
161   // 'undo' the stack movement.
162   uint64_t StackSize =
163     MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize();
164   uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
165
166   // Skip the final terminator instruction.
167   while (MBBI != MBB.begin()) {
168     MachineBasicBlock::iterator PI = prior(MBBI);
169     --MBBI;
170     if (!PI->getDesc().isTerminator())
171       break;
172   }
173
174   // During callee-saved restores emission stack frame was not yet finialized
175   // (and thus - the stack size was unknown). Tune the offset having full stack
176   // size in hands.
177   if (StackSize || MFI->hasCalls()) {
178     assert((MBBI->getOpcode() == SystemZ::MOV64rmm ||
179             MBBI->getOpcode() == SystemZ::MOV64rm) &&
180            "Expected to see callee-save register restore code");
181     assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) &&
182            "Invalid stack frame calculation!");
183
184     unsigned i = 0;
185     MachineInstr &MI = *MBBI;
186     while (!MI.getOperand(i).isImm()) {
187       ++i;
188       assert(i < MI.getNumOperands() && "Unexpected restore code!");
189     }
190
191     uint64_t Offset = NumBytes + MI.getOperand(i).getImm();
192     // If Offset does not fit into 20-bit signed displacement field we need to
193     // emit some additional code...
194     if (Offset > 524287) {
195       // Fold the displacement into load instruction as much as possible.
196       NumBytes = Offset - 524287;
197       Offset = 524287;
198       emitSPUpdate(MBB, MBBI, NumBytes, TII);
199     }
200
201     MI.getOperand(i).ChangeToImmediate(Offset);
202   }
203 }
204
205 int SystemZFrameInfo::getFrameIndexOffset(const MachineFunction &MF,
206                                           int FI) const {
207   const MachineFrameInfo *MFI = MF.getFrameInfo();
208   const SystemZMachineFunctionInfo *SystemZMFI =
209     MF.getInfo<SystemZMachineFunctionInfo>();
210   int Offset = MFI->getObjectOffset(FI) + MFI->getOffsetAdjustment();
211   uint64_t StackSize = MFI->getStackSize();
212
213   // Fixed objects are really located in the "previous" frame.
214   if (FI < 0)
215     StackSize -= SystemZMFI->getCalleeSavedFrameSize();
216
217   Offset += StackSize - getOffsetOfLocalArea();
218
219   // Skip the register save area if we generated the stack frame.
220   if (StackSize || MFI->hasCalls())
221     Offset -= getOffsetOfLocalArea();
222
223   return Offset;
224 }
225
226 bool
227 SystemZFrameInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
228                                             MachineBasicBlock::iterator MI,
229                                         const std::vector<CalleeSavedInfo> &CSI,
230                                           const TargetRegisterInfo *TRI) const {
231   if (CSI.empty())
232     return false;
233
234   DebugLoc DL;
235   if (MI != MBB.end()) DL = MI->getDebugLoc();
236
237   MachineFunction &MF = *MBB.getParent();
238   const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
239   SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
240   unsigned CalleeFrameSize = 0;
241
242   // Scan the callee-saved and find the bounds of register spill area.
243   unsigned LowReg = 0, HighReg = 0, StartOffset = -1U, EndOffset = 0;
244   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
245     unsigned Reg = CSI[i].getReg();
246     if (!SystemZ::FP64RegClass.contains(Reg)) {
247       unsigned Offset = RegSpillOffsets[Reg];
248       CalleeFrameSize += 8;
249       if (StartOffset > Offset) {
250         LowReg = Reg; StartOffset = Offset;
251       }
252       if (EndOffset < Offset) {
253         HighReg = Reg; EndOffset = RegSpillOffsets[Reg];
254       }
255     }
256   }
257
258   // Save information for epilogue inserter.
259   MFI->setCalleeSavedFrameSize(CalleeFrameSize);
260   MFI->setLowReg(LowReg); MFI->setHighReg(HighReg);
261
262   // Save GPRs
263   if (StartOffset) {
264     // Build a store instruction. Use STORE MULTIPLE instruction if there are many
265     // registers to store, otherwise - just STORE.
266     MachineInstrBuilder MIB =
267       BuildMI(MBB, MI, DL, TII.get((LowReg == HighReg ?
268                                     SystemZ::MOV64mr : SystemZ::MOV64mrm)));
269
270     // Add store operands.
271     MIB.addReg(SystemZ::R15D).addImm(StartOffset);
272     if (LowReg == HighReg)
273       MIB.addReg(0);
274     MIB.addReg(LowReg, RegState::Kill);
275     if (LowReg != HighReg)
276       MIB.addReg(HighReg, RegState::Kill);
277
278     // Do a second scan adding regs as being killed by instruction
279     for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
280       unsigned Reg = CSI[i].getReg();
281       // Add the callee-saved register as live-in. It's killed at the spill.
282       MBB.addLiveIn(Reg);
283       if (Reg != LowReg && Reg != HighReg)
284         MIB.addReg(Reg, RegState::ImplicitKill);
285     }
286   }
287
288   // Save FPRs
289   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
290     unsigned Reg = CSI[i].getReg();
291     if (SystemZ::FP64RegClass.contains(Reg)) {
292       MBB.addLiveIn(Reg);
293       TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(),
294                               &SystemZ::FP64RegClass, TRI);
295     }
296   }
297
298   return true;
299 }
300
301 bool
302 SystemZFrameInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
303                                               MachineBasicBlock::iterator MI,
304                                         const std::vector<CalleeSavedInfo> &CSI,
305                                           const TargetRegisterInfo *TRI) const {
306   if (CSI.empty())
307     return false;
308
309   DebugLoc DL;
310   if (MI != MBB.end()) DL = MI->getDebugLoc();
311
312   MachineFunction &MF = *MBB.getParent();
313   const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
314   SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
315
316   // Restore FP registers
317   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
318     unsigned Reg = CSI[i].getReg();
319     if (SystemZ::FP64RegClass.contains(Reg))
320       TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(),
321                                &SystemZ::FP64RegClass, TRI);
322   }
323
324   // Restore GP registers
325   unsigned LowReg = MFI->getLowReg(), HighReg = MFI->getHighReg();
326   unsigned StartOffset = RegSpillOffsets[LowReg];
327
328   if (StartOffset) {
329     // Build a load instruction. Use LOAD MULTIPLE instruction if there are many
330     // registers to load, otherwise - just LOAD.
331     MachineInstrBuilder MIB =
332       BuildMI(MBB, MI, DL, TII.get((LowReg == HighReg ?
333                                     SystemZ::MOV64rm : SystemZ::MOV64rmm)));
334     // Add store operands.
335     MIB.addReg(LowReg, RegState::Define);
336     if (LowReg != HighReg)
337       MIB.addReg(HighReg, RegState::Define);
338
339     MIB.addReg(hasFP(MF) ? SystemZ::R11D : SystemZ::R15D);
340     MIB.addImm(StartOffset);
341     if (LowReg == HighReg)
342       MIB.addReg(0);
343
344     // Do a second scan adding regs as being defined by instruction
345     for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
346       unsigned Reg = CSI[i].getReg();
347       if (Reg != LowReg && Reg != HighReg)
348         MIB.addReg(Reg, RegState::ImplicitDefine);
349     }
350   }
351
352   return true;
353 }