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