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