xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/VE/VEFrameLowering.cpp (revision 480093f4440d54b30b3025afeac24b48f2ba7a2e)
1*480093f4SDimitry Andric //===-- VEFrameLowering.cpp - VE Frame Information ------------------------===//
2*480093f4SDimitry Andric //
3*480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*480093f4SDimitry Andric //
7*480093f4SDimitry Andric //===----------------------------------------------------------------------===//
8*480093f4SDimitry Andric //
9*480093f4SDimitry Andric // This file contains the VE implementation of TargetFrameLowering class.
10*480093f4SDimitry Andric //
11*480093f4SDimitry Andric //===----------------------------------------------------------------------===//
12*480093f4SDimitry Andric 
13*480093f4SDimitry Andric #include "VEFrameLowering.h"
14*480093f4SDimitry Andric #include "VEInstrInfo.h"
15*480093f4SDimitry Andric #include "VESubtarget.h"
16*480093f4SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
17*480093f4SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
18*480093f4SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
19*480093f4SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
20*480093f4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
21*480093f4SDimitry Andric #include "llvm/CodeGen/RegisterScavenging.h"
22*480093f4SDimitry Andric #include "llvm/IR/DataLayout.h"
23*480093f4SDimitry Andric #include "llvm/IR/Function.h"
24*480093f4SDimitry Andric #include "llvm/Support/CommandLine.h"
25*480093f4SDimitry Andric #include "llvm/Target/TargetOptions.h"
26*480093f4SDimitry Andric #include "llvm/Support/MathExtras.h"
27*480093f4SDimitry Andric 
28*480093f4SDimitry Andric using namespace llvm;
29*480093f4SDimitry Andric 
30*480093f4SDimitry Andric VEFrameLowering::VEFrameLowering(const VESubtarget &ST)
31*480093f4SDimitry Andric     : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(16), 0,
32*480093f4SDimitry Andric                           Align(16)) {}
33*480093f4SDimitry Andric 
34*480093f4SDimitry Andric void VEFrameLowering::emitPrologueInsns(MachineFunction &MF,
35*480093f4SDimitry Andric                                         MachineBasicBlock &MBB,
36*480093f4SDimitry Andric                                         MachineBasicBlock::iterator MBBI,
37*480093f4SDimitry Andric                                         int NumBytes,
38*480093f4SDimitry Andric                                         bool RequireFPUpdate) const {
39*480093f4SDimitry Andric 
40*480093f4SDimitry Andric   DebugLoc dl;
41*480093f4SDimitry Andric   const VEInstrInfo &TII =
42*480093f4SDimitry Andric       *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
43*480093f4SDimitry Andric   // Insert following codes here as prologue
44*480093f4SDimitry Andric   //
45*480093f4SDimitry Andric   //    st %fp, 0(,%sp)
46*480093f4SDimitry Andric   //    st %lr, 8(,%sp)
47*480093f4SDimitry Andric   //    st %got, 24(,%sp)
48*480093f4SDimitry Andric   //    st %plt, 32(,%sp)
49*480093f4SDimitry Andric   //    or %fp, 0, %sp
50*480093f4SDimitry Andric 
51*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::STSri))
52*480093f4SDimitry Andric       .addReg(VE::SX11)
53*480093f4SDimitry Andric       .addImm(0)
54*480093f4SDimitry Andric       .addReg(VE::SX9);
55*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::STSri))
56*480093f4SDimitry Andric       .addReg(VE::SX11)
57*480093f4SDimitry Andric       .addImm(8)
58*480093f4SDimitry Andric       .addReg(VE::SX10);
59*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::STSri))
60*480093f4SDimitry Andric       .addReg(VE::SX11)
61*480093f4SDimitry Andric       .addImm(24)
62*480093f4SDimitry Andric       .addReg(VE::SX15);
63*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::STSri))
64*480093f4SDimitry Andric       .addReg(VE::SX11)
65*480093f4SDimitry Andric       .addImm(32)
66*480093f4SDimitry Andric       .addReg(VE::SX16);
67*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::ORri), VE::SX9)
68*480093f4SDimitry Andric       .addReg(VE::SX11)
69*480093f4SDimitry Andric       .addImm(0);
70*480093f4SDimitry Andric }
71*480093f4SDimitry Andric 
72*480093f4SDimitry Andric void VEFrameLowering::emitEpilogueInsns(MachineFunction &MF,
73*480093f4SDimitry Andric                                         MachineBasicBlock &MBB,
74*480093f4SDimitry Andric                                         MachineBasicBlock::iterator MBBI,
75*480093f4SDimitry Andric                                         int NumBytes,
76*480093f4SDimitry Andric                                         bool RequireFPUpdate) const {
77*480093f4SDimitry Andric 
78*480093f4SDimitry Andric   DebugLoc dl;
79*480093f4SDimitry Andric   const VEInstrInfo &TII =
80*480093f4SDimitry Andric       *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
81*480093f4SDimitry Andric   // Insert following codes here as epilogue
82*480093f4SDimitry Andric   //
83*480093f4SDimitry Andric   //    or %sp, 0, %fp
84*480093f4SDimitry Andric   //    ld %got, 32(,%sp)
85*480093f4SDimitry Andric   //    ld %plt, 24(,%sp)
86*480093f4SDimitry Andric   //    ld %lr, 8(,%sp)
87*480093f4SDimitry Andric   //    ld %fp, 0(,%sp)
88*480093f4SDimitry Andric 
89*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::ORri), VE::SX11)
90*480093f4SDimitry Andric       .addReg(VE::SX9)
91*480093f4SDimitry Andric       .addImm(0);
92*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::LDSri), VE::SX16)
93*480093f4SDimitry Andric       .addReg(VE::SX11)
94*480093f4SDimitry Andric       .addImm(32);
95*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::LDSri), VE::SX15)
96*480093f4SDimitry Andric       .addReg(VE::SX11)
97*480093f4SDimitry Andric       .addImm(24);
98*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::LDSri), VE::SX10)
99*480093f4SDimitry Andric       .addReg(VE::SX11)
100*480093f4SDimitry Andric       .addImm(8);
101*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::LDSri), VE::SX9)
102*480093f4SDimitry Andric       .addReg(VE::SX11)
103*480093f4SDimitry Andric       .addImm(0);
104*480093f4SDimitry Andric }
105*480093f4SDimitry Andric 
106*480093f4SDimitry Andric void VEFrameLowering::emitSPAdjustment(MachineFunction &MF,
107*480093f4SDimitry Andric                                        MachineBasicBlock &MBB,
108*480093f4SDimitry Andric                                        MachineBasicBlock::iterator MBBI,
109*480093f4SDimitry Andric                                        int NumBytes) const {
110*480093f4SDimitry Andric   DebugLoc dl;
111*480093f4SDimitry Andric   const VEInstrInfo &TII =
112*480093f4SDimitry Andric       *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
113*480093f4SDimitry Andric 
114*480093f4SDimitry Andric   if (NumBytes >= -64 && NumBytes < 63) {
115*480093f4SDimitry Andric     BuildMI(MBB, MBBI, dl, TII.get(VE::ADXri), VE::SX11)
116*480093f4SDimitry Andric         .addReg(VE::SX11)
117*480093f4SDimitry Andric         .addImm(NumBytes);
118*480093f4SDimitry Andric     return;
119*480093f4SDimitry Andric   }
120*480093f4SDimitry Andric 
121*480093f4SDimitry Andric   // Emit following codes.  This clobbers SX13 which we always know is
122*480093f4SDimitry Andric   // available here.
123*480093f4SDimitry Andric   //   lea     %s13,%lo(NumBytes)
124*480093f4SDimitry Andric   //   and     %s13,%s13,(32)0
125*480093f4SDimitry Andric   //   lea.sl  %sp,%hi(NumBytes)(%sp, %s13)
126*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::LEAzzi), VE::SX13)
127*480093f4SDimitry Andric       .addImm(LO32(NumBytes));
128*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::ANDrm0), VE::SX13)
129*480093f4SDimitry Andric       .addReg(VE::SX13)
130*480093f4SDimitry Andric       .addImm(32);
131*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::LEASLrri), VE::SX11)
132*480093f4SDimitry Andric       .addReg(VE::SX11)
133*480093f4SDimitry Andric       .addReg(VE::SX13)
134*480093f4SDimitry Andric       .addImm(HI32(NumBytes));
135*480093f4SDimitry Andric }
136*480093f4SDimitry Andric 
137*480093f4SDimitry Andric void VEFrameLowering::emitSPExtend(MachineFunction &MF, MachineBasicBlock &MBB,
138*480093f4SDimitry Andric                                    MachineBasicBlock::iterator MBBI,
139*480093f4SDimitry Andric                                    int NumBytes) const {
140*480093f4SDimitry Andric   DebugLoc dl;
141*480093f4SDimitry Andric   const VEInstrInfo &TII =
142*480093f4SDimitry Andric       *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
143*480093f4SDimitry Andric 
144*480093f4SDimitry Andric   // Emit following codes.  It is not possible to insert multiple
145*480093f4SDimitry Andric   // BasicBlocks in PEI pass, so we emit two pseudo instructions here.
146*480093f4SDimitry Andric   //
147*480093f4SDimitry Andric   //   EXTEND_STACK                     // pseudo instrcution
148*480093f4SDimitry Andric   //   EXTEND_STACK_GUARD               // pseudo instrcution
149*480093f4SDimitry Andric   //
150*480093f4SDimitry Andric   // EXTEND_STACK pseudo will be converted by ExpandPostRA pass into
151*480093f4SDimitry Andric   // following instructions with multiple basic blocks later.
152*480093f4SDimitry Andric   //
153*480093f4SDimitry Andric   // thisBB:
154*480093f4SDimitry Andric   //   brge.l.t %sp, %sl, sinkBB
155*480093f4SDimitry Andric   // syscallBB:
156*480093f4SDimitry Andric   //   ld      %s61, 0x18(, %tp)        // load param area
157*480093f4SDimitry Andric   //   or      %s62, 0, %s0             // spill the value of %s0
158*480093f4SDimitry Andric   //   lea     %s63, 0x13b              // syscall # of grow
159*480093f4SDimitry Andric   //   shm.l   %s63, 0x0(%s61)          // store syscall # at addr:0
160*480093f4SDimitry Andric   //   shm.l   %sl, 0x8(%s61)           // store old limit at addr:8
161*480093f4SDimitry Andric   //   shm.l   %sp, 0x10(%s61)          // store new limit at addr:16
162*480093f4SDimitry Andric   //   monc                             // call monitor
163*480093f4SDimitry Andric   //   or      %s0, 0, %s62             // restore the value of %s0
164*480093f4SDimitry Andric   // sinkBB:
165*480093f4SDimitry Andric   //
166*480093f4SDimitry Andric   // EXTEND_STACK_GUARD pseudo will be simply eliminated by ExpandPostRA
167*480093f4SDimitry Andric   // pass.  This pseudo is required to be at the next of EXTEND_STACK
168*480093f4SDimitry Andric   // pseudo in order to protect iteration loop in ExpandPostRA.
169*480093f4SDimitry Andric 
170*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::EXTEND_STACK));
171*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(VE::EXTEND_STACK_GUARD));
172*480093f4SDimitry Andric }
173*480093f4SDimitry Andric 
174*480093f4SDimitry Andric void VEFrameLowering::emitPrologue(MachineFunction &MF,
175*480093f4SDimitry Andric                                    MachineBasicBlock &MBB) const {
176*480093f4SDimitry Andric   assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
177*480093f4SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
178*480093f4SDimitry Andric   const VESubtarget &Subtarget = MF.getSubtarget<VESubtarget>();
179*480093f4SDimitry Andric   const VEInstrInfo &TII =
180*480093f4SDimitry Andric       *static_cast<const VEInstrInfo *>(Subtarget.getInstrInfo());
181*480093f4SDimitry Andric   const VERegisterInfo &RegInfo =
182*480093f4SDimitry Andric       *static_cast<const VERegisterInfo *>(Subtarget.getRegisterInfo());
183*480093f4SDimitry Andric   MachineBasicBlock::iterator MBBI = MBB.begin();
184*480093f4SDimitry Andric   // Debug location must be unknown since the first debug location is used
185*480093f4SDimitry Andric   // to determine the end of the prologue.
186*480093f4SDimitry Andric   DebugLoc dl;
187*480093f4SDimitry Andric   bool NeedsStackRealignment = RegInfo.needsStackRealignment(MF);
188*480093f4SDimitry Andric 
189*480093f4SDimitry Andric   // FIXME: unfortunately, returning false from canRealignStack
190*480093f4SDimitry Andric   // actually just causes needsStackRealignment to return false,
191*480093f4SDimitry Andric   // rather than reporting an error, as would be sensible. This is
192*480093f4SDimitry Andric   // poor, but fixing that bogosity is going to be a large project.
193*480093f4SDimitry Andric   // For now, just see if it's lied, and report an error here.
194*480093f4SDimitry Andric   if (!NeedsStackRealignment && MFI.getMaxAlignment() > getStackAlignment())
195*480093f4SDimitry Andric     report_fatal_error("Function \"" + Twine(MF.getName()) +
196*480093f4SDimitry Andric                        "\" required "
197*480093f4SDimitry Andric                        "stack re-alignment, but LLVM couldn't handle it "
198*480093f4SDimitry Andric                        "(probably because it has a dynamic alloca).");
199*480093f4SDimitry Andric 
200*480093f4SDimitry Andric   // Get the number of bytes to allocate from the FrameInfo
201*480093f4SDimitry Andric   int NumBytes = (int)MFI.getStackSize();
202*480093f4SDimitry Andric   // The VE ABI requires a reserved 176-byte area in the user's stack, starting
203*480093f4SDimitry Andric   // at %sp + 16. This is for the callee Register Save Area (RSA).
204*480093f4SDimitry Andric   //
205*480093f4SDimitry Andric   // We therefore need to add that offset to the total stack size
206*480093f4SDimitry Andric   // after all the stack objects are placed by
207*480093f4SDimitry Andric   // PrologEpilogInserter calculateFrameObjectOffsets. However, since the stack
208*480093f4SDimitry Andric   // needs to be aligned *after* the extra size is added, we need to disable
209*480093f4SDimitry Andric   // calculateFrameObjectOffsets's built-in stack alignment, by having
210*480093f4SDimitry Andric   // targetHandlesStackFrameRounding return true.
211*480093f4SDimitry Andric 
212*480093f4SDimitry Andric   // Add the extra call frame stack size, if needed. (This is the same
213*480093f4SDimitry Andric   // code as in PrologEpilogInserter, but also gets disabled by
214*480093f4SDimitry Andric   // targetHandlesStackFrameRounding)
215*480093f4SDimitry Andric   if (MFI.adjustsStack() && hasReservedCallFrame(MF))
216*480093f4SDimitry Andric     NumBytes += MFI.getMaxCallFrameSize();
217*480093f4SDimitry Andric 
218*480093f4SDimitry Andric   // Adds the VE subtarget-specific spill area to the stack
219*480093f4SDimitry Andric   // size. Also ensures target-required alignment.
220*480093f4SDimitry Andric   NumBytes = Subtarget.getAdjustedFrameSize(NumBytes);
221*480093f4SDimitry Andric 
222*480093f4SDimitry Andric   // Finally, ensure that the size is sufficiently aligned for the
223*480093f4SDimitry Andric   // data on the stack.
224*480093f4SDimitry Andric   if (MFI.getMaxAlignment() > 0) {
225*480093f4SDimitry Andric     NumBytes = alignTo(NumBytes, MFI.getMaxAlignment());
226*480093f4SDimitry Andric   }
227*480093f4SDimitry Andric 
228*480093f4SDimitry Andric   // Update stack size with corrected value.
229*480093f4SDimitry Andric   MFI.setStackSize(NumBytes);
230*480093f4SDimitry Andric 
231*480093f4SDimitry Andric   // Emit Prologue instructions to save %lr
232*480093f4SDimitry Andric   emitPrologueInsns(MF, MBB, MBBI, NumBytes, true);
233*480093f4SDimitry Andric 
234*480093f4SDimitry Andric   // Emit stack adjust instructions
235*480093f4SDimitry Andric   emitSPAdjustment(MF, MBB, MBBI, -NumBytes);
236*480093f4SDimitry Andric 
237*480093f4SDimitry Andric   // Emit stack extend instructions
238*480093f4SDimitry Andric   emitSPExtend(MF, MBB, MBBI, -NumBytes);
239*480093f4SDimitry Andric 
240*480093f4SDimitry Andric   unsigned regFP = RegInfo.getDwarfRegNum(VE::SX9, true);
241*480093f4SDimitry Andric 
242*480093f4SDimitry Andric   // Emit ".cfi_def_cfa_register 30".
243*480093f4SDimitry Andric   unsigned CFIIndex =
244*480093f4SDimitry Andric       MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, regFP));
245*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
246*480093f4SDimitry Andric       .addCFIIndex(CFIIndex);
247*480093f4SDimitry Andric 
248*480093f4SDimitry Andric   // Emit ".cfi_window_save".
249*480093f4SDimitry Andric   CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
250*480093f4SDimitry Andric   BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
251*480093f4SDimitry Andric       .addCFIIndex(CFIIndex);
252*480093f4SDimitry Andric }
253*480093f4SDimitry Andric 
254*480093f4SDimitry Andric MachineBasicBlock::iterator VEFrameLowering::eliminateCallFramePseudoInstr(
255*480093f4SDimitry Andric     MachineFunction &MF, MachineBasicBlock &MBB,
256*480093f4SDimitry Andric     MachineBasicBlock::iterator I) const {
257*480093f4SDimitry Andric   if (!hasReservedCallFrame(MF)) {
258*480093f4SDimitry Andric     MachineInstr &MI = *I;
259*480093f4SDimitry Andric     int Size = MI.getOperand(0).getImm();
260*480093f4SDimitry Andric     if (MI.getOpcode() == VE::ADJCALLSTACKDOWN)
261*480093f4SDimitry Andric       Size = -Size;
262*480093f4SDimitry Andric 
263*480093f4SDimitry Andric     if (Size)
264*480093f4SDimitry Andric       emitSPAdjustment(MF, MBB, I, Size);
265*480093f4SDimitry Andric   }
266*480093f4SDimitry Andric   return MBB.erase(I);
267*480093f4SDimitry Andric }
268*480093f4SDimitry Andric 
269*480093f4SDimitry Andric void VEFrameLowering::emitEpilogue(MachineFunction &MF,
270*480093f4SDimitry Andric                                    MachineBasicBlock &MBB) const {
271*480093f4SDimitry Andric   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
272*480093f4SDimitry Andric   DebugLoc dl = MBBI->getDebugLoc();
273*480093f4SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
274*480093f4SDimitry Andric 
275*480093f4SDimitry Andric   int NumBytes = (int)MFI.getStackSize();
276*480093f4SDimitry Andric 
277*480093f4SDimitry Andric   // Emit Epilogue instructions to restore %lr
278*480093f4SDimitry Andric   emitEpilogueInsns(MF, MBB, MBBI, NumBytes, true);
279*480093f4SDimitry Andric }
280*480093f4SDimitry Andric 
281*480093f4SDimitry Andric bool VEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
282*480093f4SDimitry Andric   // Reserve call frame if there are no variable sized objects on the stack.
283*480093f4SDimitry Andric   return !MF.getFrameInfo().hasVarSizedObjects();
284*480093f4SDimitry Andric }
285*480093f4SDimitry Andric 
286*480093f4SDimitry Andric // hasFP - Return true if the specified function should have a dedicated frame
287*480093f4SDimitry Andric // pointer register.  This is true if the function has variable sized allocas or
288*480093f4SDimitry Andric // if frame pointer elimination is disabled.
289*480093f4SDimitry Andric bool VEFrameLowering::hasFP(const MachineFunction &MF) const {
290*480093f4SDimitry Andric   const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
291*480093f4SDimitry Andric 
292*480093f4SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
293*480093f4SDimitry Andric   return MF.getTarget().Options.DisableFramePointerElim(MF) ||
294*480093f4SDimitry Andric          RegInfo->needsStackRealignment(MF) || MFI.hasVarSizedObjects() ||
295*480093f4SDimitry Andric          MFI.isFrameAddressTaken();
296*480093f4SDimitry Andric }
297*480093f4SDimitry Andric 
298*480093f4SDimitry Andric int VEFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
299*480093f4SDimitry Andric                                             unsigned &FrameReg) const {
300*480093f4SDimitry Andric   // Addressable stack objects are accessed using neg. offsets from
301*480093f4SDimitry Andric   // %fp, or positive offsets from %sp.
302*480093f4SDimitry Andric   int64_t FrameOffset = MF.getFrameInfo().getObjectOffset(FI);
303*480093f4SDimitry Andric   FrameReg = VE::SX11; // %sp
304*480093f4SDimitry Andric   return FrameOffset + MF.getFrameInfo().getStackSize();
305*480093f4SDimitry Andric }
306*480093f4SDimitry Andric 
307*480093f4SDimitry Andric bool VEFrameLowering::isLeafProc(MachineFunction &MF) const {
308*480093f4SDimitry Andric 
309*480093f4SDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
310*480093f4SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
311*480093f4SDimitry Andric 
312*480093f4SDimitry Andric   return !MFI.hasCalls()                 // No calls
313*480093f4SDimitry Andric          && !MRI.isPhysRegUsed(VE::SX18) // Registers within limits
314*480093f4SDimitry Andric                                          //   (s18 is first CSR)
315*480093f4SDimitry Andric          && !MRI.isPhysRegUsed(VE::SX11) // %sp un-used
316*480093f4SDimitry Andric          && !hasFP(MF);                  // Don't need %fp
317*480093f4SDimitry Andric }
318*480093f4SDimitry Andric 
319*480093f4SDimitry Andric void VEFrameLowering::determineCalleeSaves(MachineFunction &MF,
320*480093f4SDimitry Andric                                            BitVector &SavedRegs,
321*480093f4SDimitry Andric                                            RegScavenger *RS) const {
322*480093f4SDimitry Andric   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
323*480093f4SDimitry Andric 
324*480093f4SDimitry Andric   assert(isLeafProc(MF) && "TODO implement for non-leaf procs");
325*480093f4SDimitry Andric }
326