1 //=====- SystemZFrameInfo.cpp - SystemZ Frame Information ------*- C++ -*-====//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the SystemZ implementation of TargetFrameInfo class.
12 //===----------------------------------------------------------------------===//
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"
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.
34 bool SystemZFrameInfo::hasFP(const MachineFunction &MF) const {
35 const MachineFrameInfo *MFI = MF.getFrameInfo();
36 return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
39 /// emitSPUpdate - Emit a series of instructions to increment / decrement the
40 /// stack pointer by a constant value.
42 void 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;
48 if (Offset >= (1LL << 15) - 1) {
49 Opc = SystemZ::ADD64ri32;
50 Chunk = (1LL << 31) - 1;
52 Opc = SystemZ::ADD64ri16;
53 Chunk = (1LL << 15) - 1;
56 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
59 uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
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();
69 void 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();
73 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();
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();
86 uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
88 // Skip the callee-saved push instructions.
89 while (MBBI != MBB.end() &&
90 (MBBI->getOpcode() == SystemZ::MOV64mr ||
91 MBBI->getOpcode() == SystemZ::MOV64mrm))
94 if (MBBI != MBB.end())
95 DL = MBBI->getDebugLoc();
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);
105 // Update R11 with the new base value...
106 BuildMI(MBB, MBBI, DL, TII.get(SystemZ::MOV64rr), SystemZ::R11D)
107 .addReg(SystemZ::R15D);
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();
112 I->addLiveIn(SystemZ::R11D);
117 void 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();
129 case SystemZ::RET: break; // These are ok
131 assert(0 && "Can only insert epilog into returning blocks");
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.
138 MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize();
139 uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
141 // Skip the final terminator instruction.
142 while (MBBI != MBB.begin()) {
143 MachineBasicBlock::iterator PI = prior(MBBI);
145 if (!PI->getDesc().isTerminator())
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
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!");
160 MachineInstr &MI = *MBBI;
161 while (!MI.getOperand(i).isImm()) {
163 assert(i < MI.getNumOperands() && "Unexpected restore code!");
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;
173 emitSPUpdate(MBB, MBBI, NumBytes, TII);
176 MI.getOperand(i).ChangeToImmediate(Offset);