blob: 70ee8b832767d26ee390ce93a648c959d60202f7 [file] [log] [blame]
Scott Michel266bc8f2007-12-04 22:23:35 +00001//===-- SPUTargetMachine.cpp - Define TargetMachine for Cell SPU ----------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Scott Michel266bc8f2007-12-04 22:23:35 +00007//
8//===----------------------------------------------------------------------===//
9//
10// Top-level implementation for the Cell SPU target.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPU.h"
15#include "SPUFrameInfo.h"
16#include "SPURegisterNames.h"
Anton Korobeynikov33464912010-11-15 00:06:54 +000017#include "SPUInstrBuilder.h"
18#include "SPUInstrInfo.h"
19#include "llvm/Function.h"
20#include "llvm/CodeGen/MachineFrameInfo.h"
21#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/CodeGen/MachineInstrBuilder.h"
23#include "llvm/CodeGen/MachineModuleInfo.h"
24#include "llvm/CodeGen/MachineRegisterInfo.h"
25#include "llvm/Target/TargetData.h"
26#include "llvm/Target/TargetOptions.h"
27#include "llvm/Support/CommandLine.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000028using namespace llvm;
29
30//===----------------------------------------------------------------------===//
31// SPUFrameInfo:
32//===----------------------------------------------------------------------===//
33
Anton Korobeynikov33464912010-11-15 00:06:54 +000034SPUFrameInfo::SPUFrameInfo(const SPUSubtarget &sti)
35 : TargetFrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0),
36 Subtarget(sti) {
Scott Michel266bc8f2007-12-04 22:23:35 +000037 LR[0].first = SPU::R0;
38 LR[0].second = 16;
39}
Anton Korobeynikov33464912010-11-15 00:06:54 +000040
41
42/// determineFrameLayout - Determine the size of the frame and maximum call
43/// frame size.
44void SPUFrameInfo::determineFrameLayout(MachineFunction &MF) const {
45 MachineFrameInfo *MFI = MF.getFrameInfo();
46
47 // Get the number of bytes to allocate from the FrameInfo
48 unsigned FrameSize = MFI->getStackSize();
49
50 // Get the alignments provided by the target, and the maximum alignment
51 // (if any) of the fixed frame objects.
52 unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
53 unsigned Align = std::max(TargetAlign, MFI->getMaxAlignment());
54 assert(isPowerOf2_32(Align) && "Alignment is not power of 2");
55 unsigned AlignMask = Align - 1;
56
57 // Get the maximum call frame size of all the calls.
58 unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
59
60 // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
61 // that allocations will be aligned.
62 if (MFI->hasVarSizedObjects())
63 maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask;
64
65 // Update maximum call frame size.
66 MFI->setMaxCallFrameSize(maxCallFrameSize);
67
68 // Include call frame size in total.
69 FrameSize += maxCallFrameSize;
70
71 // Make sure the frame is aligned.
72 FrameSize = (FrameSize + AlignMask) & ~AlignMask;
73
74 // Update frame info.
75 MFI->setStackSize(FrameSize);
76}
77
78void SPUFrameInfo::emitPrologue(MachineFunction &MF) const {
79 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
80 MachineBasicBlock::iterator MBBI = MBB.begin();
81 MachineFrameInfo *MFI = MF.getFrameInfo();
82 const SPUInstrInfo &TII =
83 *static_cast<const SPUInstrInfo*>(MF.getTarget().getInstrInfo());
84 MachineModuleInfo &MMI = MF.getMMI();
85 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
86
87 // Prepare for debug frame info.
88 bool hasDebugInfo = MMI.hasDebugInfo();
89 MCSymbol *FrameLabel = 0;
90
91 // Move MBBI back to the beginning of the function.
92 MBBI = MBB.begin();
93
94 // Work out frame sizes.
95 determineFrameLayout(MF);
96 int FrameSize = MFI->getStackSize();
97
98 assert((FrameSize & 0xf) == 0
99 && "SPURegisterInfo::emitPrologue: FrameSize not aligned");
100
101 // the "empty" frame size is 16 - just the register scavenger spill slot
102 if (FrameSize > 16 || MFI->adjustsStack()) {
103 FrameSize = -(FrameSize + SPUFrameInfo::minStackSize());
104 if (hasDebugInfo) {
105 // Mark effective beginning of when frame pointer becomes valid.
106 FrameLabel = MMI.getContext().CreateTempSymbol();
107 BuildMI(MBB, MBBI, dl, TII.get(SPU::PROLOG_LABEL)).addSym(FrameLabel);
108 }
109
110 // Adjust stack pointer, spilling $lr -> 16($sp) and $sp -> -FrameSize($sp)
111 // for the ABI
112 BuildMI(MBB, MBBI, dl, TII.get(SPU::STQDr32), SPU::R0).addImm(16)
113 .addReg(SPU::R1);
114 if (isInt<10>(FrameSize)) {
115 // Spill $sp to adjusted $sp
116 BuildMI(MBB, MBBI, dl, TII.get(SPU::STQDr32), SPU::R1).addImm(FrameSize)
117 .addReg(SPU::R1);
118 // Adjust $sp by required amout
119 BuildMI(MBB, MBBI, dl, TII.get(SPU::AIr32), SPU::R1).addReg(SPU::R1)
120 .addImm(FrameSize);
121 } else if (isInt<16>(FrameSize)) {
122 // Frame size can be loaded into ILr32n, so temporarily spill $r2 and use
123 // $r2 to adjust $sp:
124 BuildMI(MBB, MBBI, dl, TII.get(SPU::STQDr128), SPU::R2)
125 .addImm(-16)
126 .addReg(SPU::R1);
127 BuildMI(MBB, MBBI, dl, TII.get(SPU::ILr32), SPU::R2)
128 .addImm(FrameSize);
129 BuildMI(MBB, MBBI, dl, TII.get(SPU::STQXr32), SPU::R1)
130 .addReg(SPU::R2)
131 .addReg(SPU::R1);
132 BuildMI(MBB, MBBI, dl, TII.get(SPU::Ar32), SPU::R1)
133 .addReg(SPU::R1)
134 .addReg(SPU::R2);
135 BuildMI(MBB, MBBI, dl, TII.get(SPU::SFIr32), SPU::R2)
136 .addReg(SPU::R2)
137 .addImm(16);
138 BuildMI(MBB, MBBI, dl, TII.get(SPU::LQXr128), SPU::R2)
139 .addReg(SPU::R2)
140 .addReg(SPU::R1);
141 } else {
142 report_fatal_error("Unhandled frame size: " + Twine(FrameSize));
143 }
144
145 if (hasDebugInfo) {
146 std::vector<MachineMove> &Moves = MMI.getFrameMoves();
147
148 // Show update of SP.
149 MachineLocation SPDst(MachineLocation::VirtualFP);
150 MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize);
151 Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
152
153 // Add callee saved registers to move list.
154 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
155 for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
156 int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx());
157 unsigned Reg = CSI[I].getReg();
158 if (Reg == SPU::R0) continue;
159 MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
160 MachineLocation CSSrc(Reg);
161 Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc));
162 }
163
164 // Mark effective beginning of when frame pointer is ready.
165 MCSymbol *ReadyLabel = MMI.getContext().CreateTempSymbol();
166 BuildMI(MBB, MBBI, dl, TII.get(SPU::PROLOG_LABEL)).addSym(ReadyLabel);
167
168 MachineLocation FPDst(SPU::R1);
169 MachineLocation FPSrc(MachineLocation::VirtualFP);
170 Moves.push_back(MachineMove(ReadyLabel, FPDst, FPSrc));
171 }
172 } else {
173 // This is a leaf function -- insert a branch hint iff there are
174 // sufficient number instructions in the basic block. Note that
175 // this is just a best guess based on the basic block's size.
176 if (MBB.size() >= (unsigned) SPUFrameInfo::branchHintPenalty()) {
177 MachineBasicBlock::iterator MBBI = prior(MBB.end());
178 dl = MBBI->getDebugLoc();
179
180 // Insert terminator label
181 BuildMI(MBB, MBBI, dl, TII.get(SPU::PROLOG_LABEL))
182 .addSym(MMI.getContext().CreateTempSymbol());
183 }
184 }
185}
186
187void SPUFrameInfo::emitEpilogue(MachineFunction &MF,
188 MachineBasicBlock &MBB) const {
189 MachineBasicBlock::iterator MBBI = prior(MBB.end());
190 const SPUInstrInfo &TII =
191 *static_cast<const SPUInstrInfo*>(MF.getTarget().getInstrInfo());
192 const MachineFrameInfo *MFI = MF.getFrameInfo();
193 int FrameSize = MFI->getStackSize();
194 int LinkSlotOffset = SPUFrameInfo::stackSlotSize();
195 DebugLoc dl = MBBI->getDebugLoc();
196
197 assert(MBBI->getOpcode() == SPU::RET &&
198 "Can only insert epilog into returning blocks");
199 assert((FrameSize & 0xf) == 0 && "FrameSize not aligned");
200
201 // the "empty" frame size is 16 - just the register scavenger spill slot
202 if (FrameSize > 16 || MFI->adjustsStack()) {
203 FrameSize = FrameSize + SPUFrameInfo::minStackSize();
204 if (isInt<10>(FrameSize + LinkSlotOffset)) {
205 // Reload $lr, adjust $sp by required amount
206 // Note: We do this to slightly improve dual issue -- not by much, but it
207 // is an opportunity for dual issue.
208 BuildMI(MBB, MBBI, dl, TII.get(SPU::LQDr128), SPU::R0)
209 .addImm(FrameSize + LinkSlotOffset)
210 .addReg(SPU::R1);
211 BuildMI(MBB, MBBI, dl, TII.get(SPU::AIr32), SPU::R1)
212 .addReg(SPU::R1)
213 .addImm(FrameSize);
214 } else if (FrameSize <= (1 << 16) - 1 && FrameSize >= -(1 << 16)) {
215 // Frame size can be loaded into ILr32n, so temporarily spill $r2 and use
216 // $r2 to adjust $sp:
217 BuildMI(MBB, MBBI, dl, TII.get(SPU::STQDr128), SPU::R2)
218 .addImm(16)
219 .addReg(SPU::R1);
220 BuildMI(MBB, MBBI, dl, TII.get(SPU::ILr32), SPU::R2)
221 .addImm(FrameSize);
222 BuildMI(MBB, MBBI, dl, TII.get(SPU::Ar32), SPU::R1)
223 .addReg(SPU::R1)
224 .addReg(SPU::R2);
225 BuildMI(MBB, MBBI, dl, TII.get(SPU::LQDr128), SPU::R0)
226 .addImm(16)
227 .addReg(SPU::R1);
228 BuildMI(MBB, MBBI, dl, TII.get(SPU::SFIr32), SPU::R2).
229 addReg(SPU::R2)
230 .addImm(16);
231 BuildMI(MBB, MBBI, dl, TII.get(SPU::LQXr128), SPU::R2)
232 .addReg(SPU::R2)
233 .addReg(SPU::R1);
234 } else {
235 report_fatal_error("Unhandled frame size: " + Twine(FrameSize));
236 }
237 }
238}