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