xref: /aosp_15_r20/external/llvm/lib/Target/Sparc/SparcFrameLowering.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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