improve portability to avoid conflicting with std::next in c++'0x.
[oota-llvm.git] / lib / Target / SystemZ / SystemZRegisterInfo.cpp
1 //===- SystemZRegisterInfo.cpp - SystemZ Register 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 the TargetRegisterInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "SystemZ.h"
15 #include "SystemZInstrInfo.h"
16 #include "SystemZMachineFunctionInfo.h"
17 #include "SystemZRegisterInfo.h"
18 #include "SystemZSubtarget.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 #include "llvm/Target/TargetFrameInfo.h"
24 #include "llvm/Target/TargetInstrInfo.h"
25 #include "llvm/Target/TargetMachine.h"
26 #include "llvm/Target/TargetOptions.h"
27 #include "llvm/ADT/BitVector.h"
28 using namespace llvm;
29
30 SystemZRegisterInfo::SystemZRegisterInfo(SystemZTargetMachine &tm,
31                                          const SystemZInstrInfo &tii)
32   : SystemZGenRegisterInfo(SystemZ::ADJCALLSTACKUP, SystemZ::ADJCALLSTACKDOWN),
33     TM(tm), TII(tii) {
34 }
35
36 const unsigned*
37 SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
38   static const unsigned CalleeSavedRegs[] = {
39     SystemZ::R6D,  SystemZ::R7D,  SystemZ::R8D,  SystemZ::R9D,
40     SystemZ::R10D, SystemZ::R11D, SystemZ::R12D, SystemZ::R13D,
41     SystemZ::R14D, SystemZ::R15D,
42     SystemZ::F8L,  SystemZ::F9L,  SystemZ::F10L, SystemZ::F11L,
43     SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L,
44     0
45   };
46
47   return CalleeSavedRegs;
48 }
49
50 const TargetRegisterClass* const*
51 SystemZRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
52   static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
53     &SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
54     &SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
55     &SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
56     &SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
57     &SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
58     &SystemZ::FP64RegClass, &SystemZ::FP64RegClass,
59     &SystemZ::FP64RegClass, &SystemZ::FP64RegClass,
60     &SystemZ::FP64RegClass, &SystemZ::FP64RegClass,
61     &SystemZ::FP64RegClass, &SystemZ::FP64RegClass, 0
62   };
63   return CalleeSavedRegClasses;
64 }
65
66 BitVector SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
67   BitVector Reserved(getNumRegs());
68   if (hasFP(MF))
69     Reserved.set(SystemZ::R11D);
70   Reserved.set(SystemZ::R14D);
71   Reserved.set(SystemZ::R15D);
72   return Reserved;
73 }
74
75 /// needsFP - Return true if the specified function should have a dedicated
76 /// frame pointer register.  This is true if the function has variable sized
77 /// allocas or if frame pointer elimination is disabled.
78 bool SystemZRegisterInfo::hasFP(const MachineFunction &MF) const {
79   const MachineFrameInfo *MFI = MF.getFrameInfo();
80   return NoFramePointerElim || MFI->hasVarSizedObjects();
81 }
82
83 void SystemZRegisterInfo::
84 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
85                               MachineBasicBlock::iterator I) const {
86   MBB.erase(I);
87 }
88
89 int SystemZRegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
90   const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
91   MachineFrameInfo *MFI = MF.getFrameInfo();
92   SystemZMachineFunctionInfo *SystemZMFI =
93     MF.getInfo<SystemZMachineFunctionInfo>();
94   int Offset = MFI->getObjectOffset(FI) + MFI->getOffsetAdjustment();
95   uint64_t StackSize = MFI->getStackSize();
96
97   // Fixed objects are really located in the "previous" frame.
98   if (FI < 0)
99     StackSize -= SystemZMFI->getCalleeSavedFrameSize();
100
101   Offset += StackSize - TFI.getOffsetOfLocalArea();
102
103   // Skip the register save area if we generated the stack frame.
104   if (StackSize || MFI->hasCalls())
105     Offset -= TFI.getOffsetOfLocalArea();
106
107   return Offset;
108 }
109
110 unsigned
111 SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
112                                          int SPAdj, int *Value,
113                                          RegScavenger *RS) const {
114   assert(SPAdj == 0 && "Unxpected");
115
116   unsigned i = 0;
117   MachineInstr &MI = *II;
118   MachineFunction &MF = *MI.getParent()->getParent();
119   while (!MI.getOperand(i).isFI()) {
120     ++i;
121     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
122   }
123
124   int FrameIndex = MI.getOperand(i).getIndex();
125
126   unsigned BasePtr = (hasFP(MF) ? SystemZ::R11D : SystemZ::R15D);
127
128   // This must be part of a rri or ri operand memory reference.  Replace the
129   // FrameIndex with base register with BasePtr.  Add an offset to the
130   // displacement field.
131   MI.getOperand(i).ChangeToRegister(BasePtr, false);
132
133   // Offset is a either 12-bit unsigned or 20-bit signed integer.
134   // FIXME: handle "too long" displacements.
135   int Offset = getFrameIndexOffset(MF, FrameIndex) + MI.getOperand(i+1).getImm();
136
137   // Check whether displacement is too long to fit into 12 bit zext field.
138   MI.setDesc(TII.getMemoryInstr(MI.getOpcode(), Offset));
139
140   MI.getOperand(i+1).ChangeToImmediate(Offset);
141   return 0;
142 }
143
144 void
145 SystemZRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
146                                                        RegScavenger *RS) const {
147   // Determine whether R15/R14 will ever be clobbered inside the function. And
148   // if yes - mark it as 'callee' saved.
149   MachineFrameInfo *FFI = MF.getFrameInfo();
150   MachineRegisterInfo &MRI = MF.getRegInfo();
151
152   // Check whether high FPRs are ever used, if yes - we need to save R15 as
153   // well.
154   static const unsigned HighFPRs[] = {
155     SystemZ::F8L,  SystemZ::F9L,  SystemZ::F10L, SystemZ::F11L,
156     SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L,
157     SystemZ::F8S,  SystemZ::F9S,  SystemZ::F10S, SystemZ::F11S,
158     SystemZ::F12S, SystemZ::F13S, SystemZ::F14S, SystemZ::F15S,
159   };
160
161   bool HighFPRsUsed = false;
162   for (unsigned i = 0, e = array_lengthof(HighFPRs); i != e; ++i)
163     HighFPRsUsed |= MRI.isPhysRegUsed(HighFPRs[i]);
164
165   if (FFI->hasCalls())
166     /* FIXME: function is varargs */
167     /* FIXME: function grabs RA */
168     /* FIXME: function calls eh_return */
169     MRI.setPhysRegUsed(SystemZ::R14D);
170
171   if (HighFPRsUsed ||
172       FFI->hasCalls() ||
173       FFI->getObjectIndexEnd() != 0 || // Contains automatic variables
174       FFI->hasVarSizedObjects() // Function calls dynamic alloca's
175       /* FIXME: function is varargs */)
176     MRI.setPhysRegUsed(SystemZ::R15D);
177 }
178
179 /// emitSPUpdate - Emit a series of instructions to increment / decrement the
180 /// stack pointer by a constant value.
181 static
182 void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
183                   int64_t NumBytes, const TargetInstrInfo &TII) {
184   unsigned Opc; uint64_t Chunk;
185   bool isSub = NumBytes < 0;
186   uint64_t Offset = isSub ? -NumBytes : NumBytes;
187
188   if (Offset >= (1LL << 15) - 1) {
189     Opc = SystemZ::ADD64ri32;
190     Chunk = (1LL << 31) - 1;
191   } else {
192     Opc = SystemZ::ADD64ri16;
193     Chunk = (1LL << 15) - 1;
194   }
195
196   DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() :
197                  DebugLoc::getUnknownLoc());
198
199   while (Offset) {
200     uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
201     MachineInstr *MI =
202       BuildMI(MBB, MBBI, DL, TII.get(Opc), SystemZ::R15D)
203       .addReg(SystemZ::R15D).addImm((isSub ? -(int64_t)ThisVal : ThisVal));
204     // The PSW implicit def is dead.
205     MI->getOperand(3).setIsDead();
206     Offset -= ThisVal;
207   }
208 }
209
210 void SystemZRegisterInfo::emitPrologue(MachineFunction &MF) const {
211   MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
212   const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
213   MachineFrameInfo *MFI = MF.getFrameInfo();
214   SystemZMachineFunctionInfo *SystemZMFI =
215     MF.getInfo<SystemZMachineFunctionInfo>();
216   MachineBasicBlock::iterator MBBI = MBB.begin();
217   DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() :
218                  DebugLoc::getUnknownLoc());
219
220   // Get the number of bytes to allocate from the FrameInfo.
221   // Note that area for callee-saved stuff is already allocated, thus we need to
222   // 'undo' the stack movement.
223   uint64_t StackSize = MFI->getStackSize();
224   StackSize -= SystemZMFI->getCalleeSavedFrameSize();
225
226   uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
227
228   // Skip the callee-saved push instructions.
229   while (MBBI != MBB.end() &&
230          (MBBI->getOpcode() == SystemZ::MOV64mr ||
231           MBBI->getOpcode() == SystemZ::MOV64mrm))
232     ++MBBI;
233
234   if (MBBI != MBB.end())
235     DL = MBBI->getDebugLoc();
236
237   // adjust stack pointer: R15 -= numbytes
238   if (StackSize || MFI->hasCalls()) {
239     assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) &&
240            "Invalid stack frame calculation!");
241     emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, TII);
242   }
243
244   if (hasFP(MF)) {
245     // Update R11 with the new base value...
246     BuildMI(MBB, MBBI, DL, TII.get(SystemZ::MOV64rr), SystemZ::R11D)
247       .addReg(SystemZ::R15D);
248
249     // Mark the FramePtr as live-in in every block except the entry.
250     for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end();
251          I != E; ++I)
252       I->addLiveIn(SystemZ::R11D);
253
254   }
255 }
256
257 void SystemZRegisterInfo::emitEpilogue(MachineFunction &MF,
258                                      MachineBasicBlock &MBB) const {
259   const MachineFrameInfo *MFI = MF.getFrameInfo();
260   const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
261   MachineBasicBlock::iterator MBBI = prior(MBB.end());
262   SystemZMachineFunctionInfo *SystemZMFI =
263     MF.getInfo<SystemZMachineFunctionInfo>();
264   unsigned RetOpcode = MBBI->getOpcode();
265
266   switch (RetOpcode) {
267   case SystemZ::RET: break;  // These are ok
268   default:
269     assert(0 && "Can only insert epilog into returning blocks");
270   }
271
272   // Get the number of bytes to allocate from the FrameInfo
273   // Note that area for callee-saved stuff is already allocated, thus we need to
274   // 'undo' the stack movement.
275   uint64_t StackSize =
276     MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize();
277   uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
278
279   // Skip the final terminator instruction.
280   while (MBBI != MBB.begin()) {
281     MachineBasicBlock::iterator PI = prior(MBBI);
282     --MBBI;
283     if (!PI->getDesc().isTerminator())
284       break;
285   }
286
287   // During callee-saved restores emission stack frame was not yet finialized
288   // (and thus - the stack size was unknown). Tune the offset having full stack
289   // size in hands.
290   if (StackSize || MFI->hasCalls()) {
291     assert((MBBI->getOpcode() == SystemZ::MOV64rmm ||
292             MBBI->getOpcode() == SystemZ::MOV64rm) &&
293            "Expected to see callee-save register restore code");
294     assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) &&
295            "Invalid stack frame calculation!");
296
297     unsigned i = 0;
298     MachineInstr &MI = *MBBI;
299     while (!MI.getOperand(i).isImm()) {
300       ++i;
301       assert(i < MI.getNumOperands() && "Unexpected restore code!");
302     }
303
304     uint64_t Offset = NumBytes + MI.getOperand(i).getImm();
305     // If Offset does not fit into 20-bit signed displacement field we need to
306     // emit some additional code...
307     if (Offset > 524287) {
308       // Fold the displacement into load instruction as much as possible.
309       NumBytes = Offset - 524287;
310       Offset = 524287;
311       emitSPUpdate(MBB, MBBI, NumBytes, TII);
312     }
313
314     MI.getOperand(i).ChangeToImmediate(Offset);
315   }
316 }
317
318 unsigned SystemZRegisterInfo::getRARegister() const {
319   assert(0 && "What is the return address register");
320   return 0;
321 }
322
323 unsigned
324 SystemZRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
325   assert(0 && "What is the frame register");
326   return 0;
327 }
328
329 unsigned SystemZRegisterInfo::getEHExceptionRegister() const {
330   assert(0 && "What is the exception register");
331   return 0;
332 }
333
334 unsigned SystemZRegisterInfo::getEHHandlerRegister() const {
335   assert(0 && "What is the exception handler register");
336   return 0;
337 }
338
339 int SystemZRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
340   assert(0 && "What is the dwarf register number");
341   return -1;
342 }
343
344 #include "SystemZGenRegisterInfo.inc"