blob: 331b917415ba0206ac5d3af884b18a0b2a4bf9ff [file] [log] [blame]
Anton Korobeynikov33464912010-11-15 00:06:54 +00001//=====- 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
28using namespace llvm;
29
Anton Korobeynikovd0c38172010-11-18 21:19:35 +000030
31/// needsFP - Return true if the specified function should have a dedicated
32/// frame pointer register. This is true if the function has variable sized
33/// allocas or if frame pointer elimination is disabled.
34bool SystemZFrameInfo::hasFP(const MachineFunction &MF) const {
35 const MachineFrameInfo *MFI = MF.getFrameInfo();
36 return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
37}
38
Anton Korobeynikov33464912010-11-15 00:06:54 +000039/// emitSPUpdate - Emit a series of instructions to increment / decrement the
40/// stack pointer by a constant value.
41static
42void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
43 int64_t NumBytes, const TargetInstrInfo &TII) {
44 unsigned Opc; uint64_t Chunk;
45 bool isSub = NumBytes < 0;
46 uint64_t Offset = isSub ? -NumBytes : NumBytes;
47
48 if (Offset >= (1LL << 15) - 1) {
49 Opc = SystemZ::ADD64ri32;
50 Chunk = (1LL << 31) - 1;
51 } else {
52 Opc = SystemZ::ADD64ri16;
53 Chunk = (1LL << 15) - 1;
54 }
55
56 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
57
58 while (Offset) {
59 uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
60 MachineInstr *MI =
61 BuildMI(MBB, MBBI, DL, TII.get(Opc), SystemZ::R15D)
62 .addReg(SystemZ::R15D).addImm(isSub ? -ThisVal : ThisVal);
63 // The PSW implicit def is dead.
64 MI->getOperand(3).setIsDead();
65 Offset -= ThisVal;
66 }
67}
68
69void SystemZFrameInfo::emitPrologue(MachineFunction &MF) const {
70 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
71 const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
72 MachineFrameInfo *MFI = MF.getFrameInfo();
Anton Korobeynikov33464912010-11-15 00:06:54 +000073 const SystemZInstrInfo &TII =
74 *static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo());
75 SystemZMachineFunctionInfo *SystemZMFI =
76 MF.getInfo<SystemZMachineFunctionInfo>();
77 MachineBasicBlock::iterator MBBI = MBB.begin();
78 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
79
80 // Get the number of bytes to allocate from the FrameInfo.
81 // Note that area for callee-saved stuff is already allocated, thus we need to
82 // 'undo' the stack movement.
83 uint64_t StackSize = MFI->getStackSize();
84 StackSize -= SystemZMFI->getCalleeSavedFrameSize();
85
86 uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
87
88 // Skip the callee-saved push instructions.
89 while (MBBI != MBB.end() &&
90 (MBBI->getOpcode() == SystemZ::MOV64mr ||
91 MBBI->getOpcode() == SystemZ::MOV64mrm))
92 ++MBBI;
93
94 if (MBBI != MBB.end())
95 DL = MBBI->getDebugLoc();
96
97 // adjust stack pointer: R15 -= numbytes
98 if (StackSize || MFI->hasCalls()) {
99 assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) &&
100 "Invalid stack frame calculation!");
101 emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, TII);
102 }
103
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000104 if (hasFP(MF)) {
Anton Korobeynikov33464912010-11-15 00:06:54 +0000105 // Update R11 with the new base value...
106 BuildMI(MBB, MBBI, DL, TII.get(SystemZ::MOV64rr), SystemZ::R11D)
107 .addReg(SystemZ::R15D);
108
109 // Mark the FramePtr as live-in in every block except the entry.
110 for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end();
111 I != E; ++I)
112 I->addLiveIn(SystemZ::R11D);
113
114 }
115}
116
117void SystemZFrameInfo::emitEpilogue(MachineFunction &MF,
118 MachineBasicBlock &MBB) const {
119 const MachineFrameInfo *MFI = MF.getFrameInfo();
120 const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
121 MachineBasicBlock::iterator MBBI = prior(MBB.end());
122 const SystemZInstrInfo &TII =
123 *static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo());
124 SystemZMachineFunctionInfo *SystemZMFI =
125 MF.getInfo<SystemZMachineFunctionInfo>();
126 unsigned RetOpcode = MBBI->getOpcode();
127
128 switch (RetOpcode) {
129 case SystemZ::RET: break; // These are ok
130 default:
131 assert(0 && "Can only insert epilog into returning blocks");
132 }
133
134 // Get the number of bytes to allocate from the FrameInfo
135 // Note that area for callee-saved stuff is already allocated, thus we need to
136 // 'undo' the stack movement.
137 uint64_t StackSize =
138 MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize();
139 uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
140
141 // Skip the final terminator instruction.
142 while (MBBI != MBB.begin()) {
143 MachineBasicBlock::iterator PI = prior(MBBI);
144 --MBBI;
145 if (!PI->getDesc().isTerminator())
146 break;
147 }
148
149 // During callee-saved restores emission stack frame was not yet finialized
150 // (and thus - the stack size was unknown). Tune the offset having full stack
151 // size in hands.
152 if (StackSize || MFI->hasCalls()) {
153 assert((MBBI->getOpcode() == SystemZ::MOV64rmm ||
154 MBBI->getOpcode() == SystemZ::MOV64rm) &&
155 "Expected to see callee-save register restore code");
156 assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) &&
157 "Invalid stack frame calculation!");
158
159 unsigned i = 0;
160 MachineInstr &MI = *MBBI;
161 while (!MI.getOperand(i).isImm()) {
162 ++i;
163 assert(i < MI.getNumOperands() && "Unexpected restore code!");
164 }
165
166 uint64_t Offset = NumBytes + MI.getOperand(i).getImm();
167 // If Offset does not fit into 20-bit signed displacement field we need to
168 // emit some additional code...
169 if (Offset > 524287) {
170 // Fold the displacement into load instruction as much as possible.
171 NumBytes = Offset - 524287;
172 Offset = 524287;
173 emitSPUpdate(MBB, MBBI, NumBytes, TII);
174 }
175
176 MI.getOperand(i).ChangeToImmediate(Offset);
177 }
178}
Anton Korobeynikov82f58742010-11-20 15:59:32 +0000179
180int SystemZFrameInfo::getFrameIndexOffset(const MachineFunction &MF,
181 int FI) const {
182 const MachineFrameInfo *MFI = MF.getFrameInfo();
183 const SystemZMachineFunctionInfo *SystemZMFI =
184 MF.getInfo<SystemZMachineFunctionInfo>();
185 int Offset = MFI->getObjectOffset(FI) + MFI->getOffsetAdjustment();
186 uint64_t StackSize = MFI->getStackSize();
187
188 // Fixed objects are really located in the "previous" frame.
189 if (FI < 0)
190 StackSize -= SystemZMFI->getCalleeSavedFrameSize();
191
192 Offset += StackSize - getOffsetOfLocalArea();
193
194 // Skip the register save area if we generated the stack frame.
195 if (StackSize || MFI->hasCalls())
196 Offset -= getOffsetOfLocalArea();
197
198 return Offset;
199}