1 //===-- SPUTargetMachine.cpp - Define TargetMachine for Cell SPU ----------===//
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 // Top-level implementation for the Cell SPU target.
12 //===----------------------------------------------------------------------===//
15 #include "SPUFrameLowering.h"
16 #include "SPURegisterNames.h"
17 #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/CodeGen/RegisterScavenging.h"
26 #include "llvm/Target/TargetData.h"
27 #include "llvm/Target/TargetOptions.h"
28 #include "llvm/Support/CommandLine.h"
31 //===----------------------------------------------------------------------===//
33 //===----------------------------------------------------------------------===//
35 SPUFrameLowering::SPUFrameLowering(const SPUSubtarget
&sti
)
36 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown
, 16, 0),
38 LR
[0].first
= SPU::R0
;
43 //--------------------------------------------------------------------------
44 // hasFP - Return true if the specified function actually has a dedicated frame
45 // pointer register. This is true if the function needs a frame pointer and has
46 // a non-zero stack size.
47 bool SPUFrameLowering::hasFP(const MachineFunction
&MF
) const {
48 const MachineFrameInfo
*MFI
= MF
.getFrameInfo();
50 return MFI
->getStackSize() &&
51 (DisableFramePointerElim(MF
) || MFI
->hasVarSizedObjects());
55 /// determineFrameLayout - Determine the size of the frame and maximum call
57 void SPUFrameLowering::determineFrameLayout(MachineFunction
&MF
) const {
58 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
60 // Get the number of bytes to allocate from the FrameInfo
61 unsigned FrameSize
= MFI
->getStackSize();
63 // Get the alignments provided by the target, and the maximum alignment
64 // (if any) of the fixed frame objects.
65 unsigned TargetAlign
= getStackAlignment();
66 unsigned Align
= std::max(TargetAlign
, MFI
->getMaxAlignment());
67 assert(isPowerOf2_32(Align
) && "Alignment is not power of 2");
68 unsigned AlignMask
= Align
- 1;
70 // Get the maximum call frame size of all the calls.
71 unsigned maxCallFrameSize
= MFI
->getMaxCallFrameSize();
73 // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
74 // that allocations will be aligned.
75 if (MFI
->hasVarSizedObjects())
76 maxCallFrameSize
= (maxCallFrameSize
+ AlignMask
) & ~AlignMask
;
78 // Update maximum call frame size.
79 MFI
->setMaxCallFrameSize(maxCallFrameSize
);
81 // Include call frame size in total.
82 FrameSize
+= maxCallFrameSize
;
84 // Make sure the frame is aligned.
85 FrameSize
= (FrameSize
+ AlignMask
) & ~AlignMask
;
88 MFI
->setStackSize(FrameSize
);
91 void SPUFrameLowering::emitPrologue(MachineFunction
&MF
) const {
92 MachineBasicBlock
&MBB
= MF
.front(); // Prolog goes in entry BB
93 MachineBasicBlock::iterator MBBI
= MBB
.begin();
94 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
95 const SPUInstrInfo
&TII
=
96 *static_cast<const SPUInstrInfo
*>(MF
.getTarget().getInstrInfo());
97 MachineModuleInfo
&MMI
= MF
.getMMI();
98 DebugLoc dl
= MBBI
!= MBB
.end() ? MBBI
->getDebugLoc() : DebugLoc();
100 // Prepare for debug frame info.
101 bool hasDebugInfo
= MMI
.hasDebugInfo();
102 MCSymbol
*FrameLabel
= 0;
104 // Move MBBI back to the beginning of the function.
107 // Work out frame sizes.
108 determineFrameLayout(MF
);
109 int FrameSize
= MFI
->getStackSize();
111 assert((FrameSize
& 0xf) == 0
112 && "SPURegisterInfo::emitPrologue: FrameSize not aligned");
114 // the "empty" frame size is 16 - just the register scavenger spill slot
115 if (FrameSize
> 16 || MFI
->adjustsStack()) {
116 FrameSize
= -(FrameSize
+ SPUFrameLowering::minStackSize());
118 // Mark effective beginning of when frame pointer becomes valid.
119 FrameLabel
= MMI
.getContext().CreateTempSymbol();
120 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::PROLOG_LABEL
)).addSym(FrameLabel
);
123 // Adjust stack pointer, spilling $lr -> 16($sp) and $sp -> -FrameSize($sp)
125 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::STQDr32
), SPU::R0
).addImm(16)
127 if (isInt
<10>(FrameSize
)) {
128 // Spill $sp to adjusted $sp
129 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::STQDr32
), SPU::R1
).addImm(FrameSize
)
131 // Adjust $sp by required amout
132 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::AIr32
), SPU::R1
).addReg(SPU::R1
)
134 } else if (isInt
<16>(FrameSize
)) {
135 // Frame size can be loaded into ILr32n, so temporarily spill $r2 and use
136 // $r2 to adjust $sp:
137 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::STQDr128
), SPU::R2
)
140 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::ILr32
), SPU::R2
)
142 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::STQXr32
), SPU::R1
)
145 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::Ar32
), SPU::R1
)
148 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::SFIr32
), SPU::R2
)
151 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::LQXr128
), SPU::R2
)
155 report_fatal_error("Unhandled frame size: " + Twine(FrameSize
));
159 std::vector
<MachineMove
> &Moves
= MMI
.getFrameMoves();
161 // Show update of SP.
162 MachineLocation
SPDst(MachineLocation::VirtualFP
);
163 MachineLocation
SPSrc(MachineLocation::VirtualFP
, -FrameSize
);
164 Moves
.push_back(MachineMove(FrameLabel
, SPDst
, SPSrc
));
166 // Add callee saved registers to move list.
167 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
->getCalleeSavedInfo();
168 for (unsigned I
= 0, E
= CSI
.size(); I
!= E
; ++I
) {
169 int Offset
= MFI
->getObjectOffset(CSI
[I
].getFrameIdx());
170 unsigned Reg
= CSI
[I
].getReg();
171 if (Reg
== SPU::R0
) continue;
172 MachineLocation
CSDst(MachineLocation::VirtualFP
, Offset
);
173 MachineLocation
CSSrc(Reg
);
174 Moves
.push_back(MachineMove(FrameLabel
, CSDst
, CSSrc
));
177 // Mark effective beginning of when frame pointer is ready.
178 MCSymbol
*ReadyLabel
= MMI
.getContext().CreateTempSymbol();
179 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::PROLOG_LABEL
)).addSym(ReadyLabel
);
181 MachineLocation
FPDst(SPU::R1
);
182 MachineLocation
FPSrc(MachineLocation::VirtualFP
);
183 Moves
.push_back(MachineMove(ReadyLabel
, FPDst
, FPSrc
));
186 // This is a leaf function -- insert a branch hint iff there are
187 // sufficient number instructions in the basic block. Note that
188 // this is just a best guess based on the basic block's size.
189 if (MBB
.size() >= (unsigned) SPUFrameLowering::branchHintPenalty()) {
190 MachineBasicBlock::iterator MBBI
= MBB
.getLastNonDebugInstr();
191 dl
= MBBI
->getDebugLoc();
193 // Insert terminator label
194 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::PROLOG_LABEL
))
195 .addSym(MMI
.getContext().CreateTempSymbol());
200 void SPUFrameLowering::emitEpilogue(MachineFunction
&MF
,
201 MachineBasicBlock
&MBB
) const {
202 MachineBasicBlock::iterator MBBI
= MBB
.getLastNonDebugInstr();
203 const SPUInstrInfo
&TII
=
204 *static_cast<const SPUInstrInfo
*>(MF
.getTarget().getInstrInfo());
205 const MachineFrameInfo
*MFI
= MF
.getFrameInfo();
206 int FrameSize
= MFI
->getStackSize();
207 int LinkSlotOffset
= SPUFrameLowering::stackSlotSize();
208 DebugLoc dl
= MBBI
->getDebugLoc();
210 assert(MBBI
->getOpcode() == SPU::RET
&&
211 "Can only insert epilog into returning blocks");
212 assert((FrameSize
& 0xf) == 0 && "FrameSize not aligned");
214 // the "empty" frame size is 16 - just the register scavenger spill slot
215 if (FrameSize
> 16 || MFI
->adjustsStack()) {
216 FrameSize
= FrameSize
+ SPUFrameLowering::minStackSize();
217 if (isInt
<10>(FrameSize
+ LinkSlotOffset
)) {
218 // Reload $lr, adjust $sp by required amount
219 // Note: We do this to slightly improve dual issue -- not by much, but it
220 // is an opportunity for dual issue.
221 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::LQDr128
), SPU::R0
)
222 .addImm(FrameSize
+ LinkSlotOffset
)
224 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::AIr32
), SPU::R1
)
227 } else if (FrameSize
<= (1 << 16) - 1 && FrameSize
>= -(1 << 16)) {
228 // Frame size can be loaded into ILr32n, so temporarily spill $r2 and use
229 // $r2 to adjust $sp:
230 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::STQDr128
), SPU::R2
)
233 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::ILr32
), SPU::R2
)
235 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::Ar32
), SPU::R1
)
238 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::LQDr128
), SPU::R0
)
241 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::SFIr32
), SPU::R2
).
244 BuildMI(MBB
, MBBI
, dl
, TII
.get(SPU::LQXr128
), SPU::R2
)
248 report_fatal_error("Unhandled frame size: " + Twine(FrameSize
));
253 void SPUFrameLowering::getInitialFrameState(std::vector
<MachineMove
> &Moves
)
255 // Initial state of the frame pointer is R1.
256 MachineLocation
Dst(MachineLocation::VirtualFP
);
257 MachineLocation
Src(SPU::R1
, 0);
258 Moves
.push_back(MachineMove(0, Dst
, Src
));
261 void SPUFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction
&MF
,
262 RegScavenger
*RS
) const{
263 // Mark LR and SP unused, since the prolog spills them to stack and
264 // we don't want anyone else to spill them for us.
266 // Also, unless R2 is really used someday, don't spill it automatically.
267 MF
.getRegInfo().setPhysRegUnused(SPU::R0
);
268 MF
.getRegInfo().setPhysRegUnused(SPU::R1
);
269 MF
.getRegInfo().setPhysRegUnused(SPU::R2
);
271 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
272 const TargetRegisterClass
*RC
= &SPU::R32CRegClass
;
273 RS
->setScavengingFrameIndex(MFI
->CreateStackObject(RC
->getSize(),