1*9880d681SAndroid Build Coastguard Worker //===-- SparcFrameLowering.cpp - Sparc Frame Information ------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the Sparc implementation of TargetFrameLowering class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "SparcFrameLowering.h"
15*9880d681SAndroid Build Coastguard Worker #include "SparcInstrInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "SparcMachineFunctionInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "SparcSubtarget.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOptions.h"
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker using namespace llvm;
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
31*9880d681SAndroid Build Coastguard Worker DisableLeafProc("disable-sparc-leaf-proc",
32*9880d681SAndroid Build Coastguard Worker cl::init(false),
33*9880d681SAndroid Build Coastguard Worker cl::desc("Disable Sparc leaf procedure optimization."),
34*9880d681SAndroid Build Coastguard Worker cl::Hidden);
35*9880d681SAndroid Build Coastguard Worker
SparcFrameLowering(const SparcSubtarget & ST)36*9880d681SAndroid Build Coastguard Worker SparcFrameLowering::SparcFrameLowering(const SparcSubtarget &ST)
37*9880d681SAndroid Build Coastguard Worker : TargetFrameLowering(TargetFrameLowering::StackGrowsDown,
38*9880d681SAndroid Build Coastguard Worker ST.is64Bit() ? 16 : 8, 0, ST.is64Bit() ? 16 : 8) {}
39*9880d681SAndroid Build Coastguard Worker
emitSPAdjustment(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,int NumBytes,unsigned ADDrr,unsigned ADDri) const40*9880d681SAndroid Build Coastguard Worker void SparcFrameLowering::emitSPAdjustment(MachineFunction &MF,
41*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB,
42*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI,
43*9880d681SAndroid Build Coastguard Worker int NumBytes,
44*9880d681SAndroid Build Coastguard Worker unsigned ADDrr,
45*9880d681SAndroid Build Coastguard Worker unsigned ADDri) const {
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker DebugLoc dl;
48*9880d681SAndroid Build Coastguard Worker const SparcInstrInfo &TII =
49*9880d681SAndroid Build Coastguard Worker *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo());
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker if (NumBytes >= -4096 && NumBytes < 4096) {
52*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(ADDri), SP::O6)
53*9880d681SAndroid Build Coastguard Worker .addReg(SP::O6).addImm(NumBytes);
54*9880d681SAndroid Build Coastguard Worker return;
55*9880d681SAndroid Build Coastguard Worker }
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker // Emit this the hard way. This clobbers G1 which we always know is
58*9880d681SAndroid Build Coastguard Worker // available here.
59*9880d681SAndroid Build Coastguard Worker if (NumBytes >= 0) {
60*9880d681SAndroid Build Coastguard Worker // Emit nonnegative numbers with sethi + or.
61*9880d681SAndroid Build Coastguard Worker // sethi %hi(NumBytes), %g1
62*9880d681SAndroid Build Coastguard Worker // or %g1, %lo(NumBytes), %g1
63*9880d681SAndroid Build Coastguard Worker // add %sp, %g1, %sp
64*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(SP::SETHIi), SP::G1)
65*9880d681SAndroid Build Coastguard Worker .addImm(HI22(NumBytes));
66*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(SP::ORri), SP::G1)
67*9880d681SAndroid Build Coastguard Worker .addReg(SP::G1).addImm(LO10(NumBytes));
68*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(ADDrr), SP::O6)
69*9880d681SAndroid Build Coastguard Worker .addReg(SP::O6).addReg(SP::G1);
70*9880d681SAndroid Build Coastguard Worker return ;
71*9880d681SAndroid Build Coastguard Worker }
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker // Emit negative numbers with sethi + xor.
74*9880d681SAndroid Build Coastguard Worker // sethi %hix(NumBytes), %g1
75*9880d681SAndroid Build Coastguard Worker // xor %g1, %lox(NumBytes), %g1
76*9880d681SAndroid Build Coastguard Worker // add %sp, %g1, %sp
77*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(SP::SETHIi), SP::G1)
78*9880d681SAndroid Build Coastguard Worker .addImm(HIX22(NumBytes));
79*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(SP::XORri), SP::G1)
80*9880d681SAndroid Build Coastguard Worker .addReg(SP::G1).addImm(LOX10(NumBytes));
81*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(ADDrr), SP::O6)
82*9880d681SAndroid Build Coastguard Worker .addReg(SP::O6).addReg(SP::G1);
83*9880d681SAndroid Build Coastguard Worker }
84*9880d681SAndroid Build Coastguard Worker
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const85*9880d681SAndroid Build Coastguard Worker void SparcFrameLowering::emitPrologue(MachineFunction &MF,
86*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB) const {
87*9880d681SAndroid Build Coastguard Worker SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Worker assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
90*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF.getFrameInfo();
91*9880d681SAndroid Build Coastguard Worker const SparcInstrInfo &TII =
92*9880d681SAndroid Build Coastguard Worker *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo());
93*9880d681SAndroid Build Coastguard Worker const SparcRegisterInfo &RegInfo =
94*9880d681SAndroid Build Coastguard Worker *static_cast<const SparcRegisterInfo *>(MF.getSubtarget().getRegisterInfo());
95*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI = MBB.begin();
96*9880d681SAndroid Build Coastguard Worker // Debug location must be unknown since the first debug location is used
97*9880d681SAndroid Build Coastguard Worker // to determine the end of the prologue.
98*9880d681SAndroid Build Coastguard Worker DebugLoc dl;
99*9880d681SAndroid Build Coastguard Worker bool NeedsStackRealignment = RegInfo.needsStackRealignment(MF);
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker // FIXME: unfortunately, returning false from canRealignStack
102*9880d681SAndroid Build Coastguard Worker // actually just causes needsStackRealignment to return false,
103*9880d681SAndroid Build Coastguard Worker // rather than reporting an error, as would be sensible. This is
104*9880d681SAndroid Build Coastguard Worker // poor, but fixing that bogosity is going to be a large project.
105*9880d681SAndroid Build Coastguard Worker // For now, just see if it's lied, and report an error here.
106*9880d681SAndroid Build Coastguard Worker if (!NeedsStackRealignment && MFI->getMaxAlignment() > getStackAlignment())
107*9880d681SAndroid Build Coastguard Worker report_fatal_error("Function \"" + Twine(MF.getName()) + "\" required "
108*9880d681SAndroid Build Coastguard Worker "stack re-alignment, but LLVM couldn't handle it "
109*9880d681SAndroid Build Coastguard Worker "(probably because it has a dynamic alloca).");
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker // Get the number of bytes to allocate from the FrameInfo
112*9880d681SAndroid Build Coastguard Worker int NumBytes = (int) MFI->getStackSize();
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker unsigned SAVEri = SP::SAVEri;
115*9880d681SAndroid Build Coastguard Worker unsigned SAVErr = SP::SAVErr;
116*9880d681SAndroid Build Coastguard Worker if (FuncInfo->isLeafProc()) {
117*9880d681SAndroid Build Coastguard Worker if (NumBytes == 0)
118*9880d681SAndroid Build Coastguard Worker return;
119*9880d681SAndroid Build Coastguard Worker SAVEri = SP::ADDri;
120*9880d681SAndroid Build Coastguard Worker SAVErr = SP::ADDrr;
121*9880d681SAndroid Build Coastguard Worker }
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker // The SPARC ABI is a bit odd in that it requires a reserved 92-byte
124*9880d681SAndroid Build Coastguard Worker // (128 in v9) area in the user's stack, starting at %sp. Thus, the
125*9880d681SAndroid Build Coastguard Worker // first part of the stack that can actually be used is located at
126*9880d681SAndroid Build Coastguard Worker // %sp + 92.
127*9880d681SAndroid Build Coastguard Worker //
128*9880d681SAndroid Build Coastguard Worker // We therefore need to add that offset to the total stack size
129*9880d681SAndroid Build Coastguard Worker // after all the stack objects are placed by
130*9880d681SAndroid Build Coastguard Worker // PrologEpilogInserter calculateFrameObjectOffsets. However, since the stack needs to be
131*9880d681SAndroid Build Coastguard Worker // aligned *after* the extra size is added, we need to disable
132*9880d681SAndroid Build Coastguard Worker // calculateFrameObjectOffsets's built-in stack alignment, by having
133*9880d681SAndroid Build Coastguard Worker // targetHandlesStackFrameRounding return true.
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Worker
136*9880d681SAndroid Build Coastguard Worker // Add the extra call frame stack size, if needed. (This is the same
137*9880d681SAndroid Build Coastguard Worker // code as in PrologEpilogInserter, but also gets disabled by
138*9880d681SAndroid Build Coastguard Worker // targetHandlesStackFrameRounding)
139*9880d681SAndroid Build Coastguard Worker if (MFI->adjustsStack() && hasReservedCallFrame(MF))
140*9880d681SAndroid Build Coastguard Worker NumBytes += MFI->getMaxCallFrameSize();
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker // Adds the SPARC subtarget-specific spill area to the stack
143*9880d681SAndroid Build Coastguard Worker // size. Also ensures target-required alignment.
144*9880d681SAndroid Build Coastguard Worker NumBytes = MF.getSubtarget<SparcSubtarget>().getAdjustedFrameSize(NumBytes);
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker // Finally, ensure that the size is sufficiently aligned for the
147*9880d681SAndroid Build Coastguard Worker // data on the stack.
148*9880d681SAndroid Build Coastguard Worker if (MFI->getMaxAlignment() > 0) {
149*9880d681SAndroid Build Coastguard Worker NumBytes = alignTo(NumBytes, MFI->getMaxAlignment());
150*9880d681SAndroid Build Coastguard Worker }
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Worker // Update stack size with corrected value.
153*9880d681SAndroid Build Coastguard Worker MFI->setStackSize(NumBytes);
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Worker emitSPAdjustment(MF, MBB, MBBI, -NumBytes, SAVErr, SAVEri);
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker MachineModuleInfo &MMI = MF.getMMI();
158*9880d681SAndroid Build Coastguard Worker unsigned regFP = RegInfo.getDwarfRegNum(SP::I6, true);
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Worker // Emit ".cfi_def_cfa_register 30".
161*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex =
162*9880d681SAndroid Build Coastguard Worker MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, regFP));
163*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
164*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex);
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Worker // Emit ".cfi_window_save".
167*9880d681SAndroid Build Coastguard Worker CFIIndex = MMI.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
168*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
169*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex);
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker unsigned regInRA = RegInfo.getDwarfRegNum(SP::I7, true);
172*9880d681SAndroid Build Coastguard Worker unsigned regOutRA = RegInfo.getDwarfRegNum(SP::O7, true);
173*9880d681SAndroid Build Coastguard Worker // Emit ".cfi_register 15, 31".
174*9880d681SAndroid Build Coastguard Worker CFIIndex = MMI.addFrameInst(
175*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createRegister(nullptr, regOutRA, regInRA));
176*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
177*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex);
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Worker if (NeedsStackRealignment) {
180*9880d681SAndroid Build Coastguard Worker // andn %o6, MaxAlign-1, %o6
181*9880d681SAndroid Build Coastguard Worker int MaxAlign = MFI->getMaxAlignment();
182*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(SP::ANDNri), SP::O6).addReg(SP::O6).addImm(MaxAlign - 1);
183*9880d681SAndroid Build Coastguard Worker }
184*9880d681SAndroid Build Coastguard Worker }
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator SparcFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const187*9880d681SAndroid Build Coastguard Worker eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
188*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I) const {
189*9880d681SAndroid Build Coastguard Worker if (!hasReservedCallFrame(MF)) {
190*9880d681SAndroid Build Coastguard Worker MachineInstr &MI = *I;
191*9880d681SAndroid Build Coastguard Worker int Size = MI.getOperand(0).getImm();
192*9880d681SAndroid Build Coastguard Worker if (MI.getOpcode() == SP::ADJCALLSTACKDOWN)
193*9880d681SAndroid Build Coastguard Worker Size = -Size;
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Worker if (Size)
196*9880d681SAndroid Build Coastguard Worker emitSPAdjustment(MF, MBB, I, Size, SP::ADDrr, SP::ADDri);
197*9880d681SAndroid Build Coastguard Worker }
198*9880d681SAndroid Build Coastguard Worker return MBB.erase(I);
199*9880d681SAndroid Build Coastguard Worker }
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Worker
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const202*9880d681SAndroid Build Coastguard Worker void SparcFrameLowering::emitEpilogue(MachineFunction &MF,
203*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB) const {
204*9880d681SAndroid Build Coastguard Worker SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
205*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
206*9880d681SAndroid Build Coastguard Worker const SparcInstrInfo &TII =
207*9880d681SAndroid Build Coastguard Worker *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo());
208*9880d681SAndroid Build Coastguard Worker DebugLoc dl = MBBI->getDebugLoc();
209*9880d681SAndroid Build Coastguard Worker assert(MBBI->getOpcode() == SP::RETL &&
210*9880d681SAndroid Build Coastguard Worker "Can only put epilog before 'retl' instruction!");
211*9880d681SAndroid Build Coastguard Worker if (!FuncInfo->isLeafProc()) {
212*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(SP::RESTORErr), SP::G0).addReg(SP::G0)
213*9880d681SAndroid Build Coastguard Worker .addReg(SP::G0);
214*9880d681SAndroid Build Coastguard Worker return;
215*9880d681SAndroid Build Coastguard Worker }
216*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF.getFrameInfo();
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker int NumBytes = (int) MFI->getStackSize();
219*9880d681SAndroid Build Coastguard Worker if (NumBytes == 0)
220*9880d681SAndroid Build Coastguard Worker return;
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker emitSPAdjustment(MF, MBB, MBBI, NumBytes, SP::ADDrr, SP::ADDri);
223*9880d681SAndroid Build Coastguard Worker }
224*9880d681SAndroid Build Coastguard Worker
hasReservedCallFrame(const MachineFunction & MF) const225*9880d681SAndroid Build Coastguard Worker bool SparcFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
226*9880d681SAndroid Build Coastguard Worker // Reserve call frame if there are no variable sized objects on the stack.
227*9880d681SAndroid Build Coastguard Worker return !MF.getFrameInfo()->hasVarSizedObjects();
228*9880d681SAndroid Build Coastguard Worker }
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Worker // hasFP - Return true if the specified function should have a dedicated frame
231*9880d681SAndroid Build Coastguard Worker // pointer register. This is true if the function has variable sized allocas or
232*9880d681SAndroid Build Coastguard Worker // if frame pointer elimination is disabled.
hasFP(const MachineFunction & MF) const233*9880d681SAndroid Build Coastguard Worker bool SparcFrameLowering::hasFP(const MachineFunction &MF) const {
234*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *MFI = MF.getFrameInfo();
237*9880d681SAndroid Build Coastguard Worker return MF.getTarget().Options.DisableFramePointerElim(MF) ||
238*9880d681SAndroid Build Coastguard Worker RegInfo->needsStackRealignment(MF) ||
239*9880d681SAndroid Build Coastguard Worker MFI->hasVarSizedObjects() ||
240*9880d681SAndroid Build Coastguard Worker MFI->isFrameAddressTaken();
241*9880d681SAndroid Build Coastguard Worker }
242*9880d681SAndroid Build Coastguard Worker
243*9880d681SAndroid Build Coastguard Worker
getFrameIndexReference(const MachineFunction & MF,int FI,unsigned & FrameReg) const244*9880d681SAndroid Build Coastguard Worker int SparcFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
245*9880d681SAndroid Build Coastguard Worker unsigned &FrameReg) const {
246*9880d681SAndroid Build Coastguard Worker const SparcSubtarget &Subtarget = MF.getSubtarget<SparcSubtarget>();
247*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *MFI = MF.getFrameInfo();
248*9880d681SAndroid Build Coastguard Worker const SparcRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
249*9880d681SAndroid Build Coastguard Worker const SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
250*9880d681SAndroid Build Coastguard Worker bool isFixed = MFI->isFixedObjectIndex(FI);
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker // Addressable stack objects are accessed using neg. offsets from
253*9880d681SAndroid Build Coastguard Worker // %fp, or positive offsets from %sp.
254*9880d681SAndroid Build Coastguard Worker bool UseFP;
255*9880d681SAndroid Build Coastguard Worker
256*9880d681SAndroid Build Coastguard Worker // Sparc uses FP-based references in general, even when "hasFP" is
257*9880d681SAndroid Build Coastguard Worker // false. That function is rather a misnomer, because %fp is
258*9880d681SAndroid Build Coastguard Worker // actually always available, unless isLeafProc.
259*9880d681SAndroid Build Coastguard Worker if (FuncInfo->isLeafProc()) {
260*9880d681SAndroid Build Coastguard Worker // If there's a leaf proc, all offsets need to be %sp-based,
261*9880d681SAndroid Build Coastguard Worker // because we haven't caused %fp to actually point to our frame.
262*9880d681SAndroid Build Coastguard Worker UseFP = false;
263*9880d681SAndroid Build Coastguard Worker } else if (isFixed) {
264*9880d681SAndroid Build Coastguard Worker // Otherwise, argument access should always use %fp.
265*9880d681SAndroid Build Coastguard Worker UseFP = true;
266*9880d681SAndroid Build Coastguard Worker } else if (RegInfo->needsStackRealignment(MF)) {
267*9880d681SAndroid Build Coastguard Worker // If there is dynamic stack realignment, all local object
268*9880d681SAndroid Build Coastguard Worker // references need to be via %sp, to take account of the
269*9880d681SAndroid Build Coastguard Worker // re-alignment.
270*9880d681SAndroid Build Coastguard Worker UseFP = false;
271*9880d681SAndroid Build Coastguard Worker } else {
272*9880d681SAndroid Build Coastguard Worker // Finally, default to using %fp.
273*9880d681SAndroid Build Coastguard Worker UseFP = true;
274*9880d681SAndroid Build Coastguard Worker }
275*9880d681SAndroid Build Coastguard Worker
276*9880d681SAndroid Build Coastguard Worker int64_t FrameOffset = MF.getFrameInfo()->getObjectOffset(FI) +
277*9880d681SAndroid Build Coastguard Worker Subtarget.getStackPointerBias();
278*9880d681SAndroid Build Coastguard Worker
279*9880d681SAndroid Build Coastguard Worker if (UseFP) {
280*9880d681SAndroid Build Coastguard Worker FrameReg = RegInfo->getFrameRegister(MF);
281*9880d681SAndroid Build Coastguard Worker return FrameOffset;
282*9880d681SAndroid Build Coastguard Worker } else {
283*9880d681SAndroid Build Coastguard Worker FrameReg = SP::O6; // %sp
284*9880d681SAndroid Build Coastguard Worker return FrameOffset + MF.getFrameInfo()->getStackSize();
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker }
287*9880d681SAndroid Build Coastguard Worker
verifyLeafProcRegUse(MachineRegisterInfo * MRI)288*9880d681SAndroid Build Coastguard Worker static bool LLVM_ATTRIBUTE_UNUSED verifyLeafProcRegUse(MachineRegisterInfo *MRI)
289*9880d681SAndroid Build Coastguard Worker {
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Worker for (unsigned reg = SP::I0; reg <= SP::I7; ++reg)
292*9880d681SAndroid Build Coastguard Worker if (!MRI->reg_nodbg_empty(reg))
293*9880d681SAndroid Build Coastguard Worker return false;
294*9880d681SAndroid Build Coastguard Worker
295*9880d681SAndroid Build Coastguard Worker for (unsigned reg = SP::L0; reg <= SP::L7; ++reg)
296*9880d681SAndroid Build Coastguard Worker if (!MRI->reg_nodbg_empty(reg))
297*9880d681SAndroid Build Coastguard Worker return false;
298*9880d681SAndroid Build Coastguard Worker
299*9880d681SAndroid Build Coastguard Worker return true;
300*9880d681SAndroid Build Coastguard Worker }
301*9880d681SAndroid Build Coastguard Worker
isLeafProc(MachineFunction & MF) const302*9880d681SAndroid Build Coastguard Worker bool SparcFrameLowering::isLeafProc(MachineFunction &MF) const
303*9880d681SAndroid Build Coastguard Worker {
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo &MRI = MF.getRegInfo();
306*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF.getFrameInfo();
307*9880d681SAndroid Build Coastguard Worker
308*9880d681SAndroid Build Coastguard Worker return !(MFI->hasCalls() // has calls
309*9880d681SAndroid Build Coastguard Worker || !MRI.reg_nodbg_empty(SP::L0) // Too many registers needed
310*9880d681SAndroid Build Coastguard Worker || !MRI.reg_nodbg_empty(SP::O6) // %SP is used
311*9880d681SAndroid Build Coastguard Worker || hasFP(MF)); // need %FP
312*9880d681SAndroid Build Coastguard Worker }
313*9880d681SAndroid Build Coastguard Worker
remapRegsForLeafProc(MachineFunction & MF) const314*9880d681SAndroid Build Coastguard Worker void SparcFrameLowering::remapRegsForLeafProc(MachineFunction &MF) const {
315*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo &MRI = MF.getRegInfo();
316*9880d681SAndroid Build Coastguard Worker // Remap %i[0-7] to %o[0-7].
317*9880d681SAndroid Build Coastguard Worker for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) {
318*9880d681SAndroid Build Coastguard Worker if (MRI.reg_nodbg_empty(reg))
319*9880d681SAndroid Build Coastguard Worker continue;
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker unsigned mapped_reg = reg - SP::I0 + SP::O0;
322*9880d681SAndroid Build Coastguard Worker assert(MRI.reg_nodbg_empty(mapped_reg));
323*9880d681SAndroid Build Coastguard Worker
324*9880d681SAndroid Build Coastguard Worker // Replace I register with O register.
325*9880d681SAndroid Build Coastguard Worker MRI.replaceRegWith(reg, mapped_reg);
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Worker // Also replace register pair super-registers.
328*9880d681SAndroid Build Coastguard Worker if ((reg - SP::I0) % 2 == 0) {
329*9880d681SAndroid Build Coastguard Worker unsigned preg = (reg - SP::I0) / 2 + SP::I0_I1;
330*9880d681SAndroid Build Coastguard Worker unsigned mapped_preg = preg - SP::I0_I1 + SP::O0_O1;
331*9880d681SAndroid Build Coastguard Worker MRI.replaceRegWith(preg, mapped_preg);
332*9880d681SAndroid Build Coastguard Worker }
333*9880d681SAndroid Build Coastguard Worker }
334*9880d681SAndroid Build Coastguard Worker
335*9880d681SAndroid Build Coastguard Worker // Rewrite MBB's Live-ins.
336*9880d681SAndroid Build Coastguard Worker for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
337*9880d681SAndroid Build Coastguard Worker MBB != E; ++MBB) {
338*9880d681SAndroid Build Coastguard Worker for (unsigned reg = SP::I0_I1; reg <= SP::I6_I7; ++reg) {
339*9880d681SAndroid Build Coastguard Worker if (!MBB->isLiveIn(reg))
340*9880d681SAndroid Build Coastguard Worker continue;
341*9880d681SAndroid Build Coastguard Worker MBB->removeLiveIn(reg);
342*9880d681SAndroid Build Coastguard Worker MBB->addLiveIn(reg - SP::I0_I1 + SP::O0_O1);
343*9880d681SAndroid Build Coastguard Worker }
344*9880d681SAndroid Build Coastguard Worker for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) {
345*9880d681SAndroid Build Coastguard Worker if (!MBB->isLiveIn(reg))
346*9880d681SAndroid Build Coastguard Worker continue;
347*9880d681SAndroid Build Coastguard Worker MBB->removeLiveIn(reg);
348*9880d681SAndroid Build Coastguard Worker MBB->addLiveIn(reg - SP::I0 + SP::O0);
349*9880d681SAndroid Build Coastguard Worker }
350*9880d681SAndroid Build Coastguard Worker }
351*9880d681SAndroid Build Coastguard Worker
352*9880d681SAndroid Build Coastguard Worker assert(verifyLeafProcRegUse(&MRI));
353*9880d681SAndroid Build Coastguard Worker #ifdef EXPENSIVE_CHECKS
354*9880d681SAndroid Build Coastguard Worker MF.verify(0, "After LeafProc Remapping");
355*9880d681SAndroid Build Coastguard Worker #endif
356*9880d681SAndroid Build Coastguard Worker }
357*9880d681SAndroid Build Coastguard Worker
determineCalleeSaves(MachineFunction & MF,BitVector & SavedRegs,RegScavenger * RS) const358*9880d681SAndroid Build Coastguard Worker void SparcFrameLowering::determineCalleeSaves(MachineFunction &MF,
359*9880d681SAndroid Build Coastguard Worker BitVector &SavedRegs,
360*9880d681SAndroid Build Coastguard Worker RegScavenger *RS) const {
361*9880d681SAndroid Build Coastguard Worker TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
362*9880d681SAndroid Build Coastguard Worker if (!DisableLeafProc && isLeafProc(MF)) {
363*9880d681SAndroid Build Coastguard Worker SparcMachineFunctionInfo *MFI = MF.getInfo<SparcMachineFunctionInfo>();
364*9880d681SAndroid Build Coastguard Worker MFI->setLeafProc(true);
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker remapRegsForLeafProc(MF);
367*9880d681SAndroid Build Coastguard Worker }
368*9880d681SAndroid Build Coastguard Worker
369*9880d681SAndroid Build Coastguard Worker }
370