1064859bdSKazushi (Jam) Marukawa //===-- VEFrameLowering.cpp - VE Frame Information ------------------------===//
2064859bdSKazushi (Jam) Marukawa //
3064859bdSKazushi (Jam) Marukawa // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4064859bdSKazushi (Jam) Marukawa // See https://llvm.org/LICENSE.txt for license information.
5064859bdSKazushi (Jam) Marukawa // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6064859bdSKazushi (Jam) Marukawa //
7064859bdSKazushi (Jam) Marukawa //===----------------------------------------------------------------------===//
8064859bdSKazushi (Jam) Marukawa //
9064859bdSKazushi (Jam) Marukawa // This file contains the VE implementation of TargetFrameLowering class.
10064859bdSKazushi (Jam) Marukawa //
113a302349SKazushi (Jam) Marukawa // On VE, stack frames are structured as follows:
123a302349SKazushi (Jam) Marukawa //
133a302349SKazushi (Jam) Marukawa // The stack grows downward.
143a302349SKazushi (Jam) Marukawa //
153a302349SKazushi (Jam) Marukawa // All of the individual frame areas on the frame below are optional, i.e. it's
163a302349SKazushi (Jam) Marukawa // possible to create a function so that the particular area isn't present
173a302349SKazushi (Jam) Marukawa // in the frame.
183a302349SKazushi (Jam) Marukawa //
193a302349SKazushi (Jam) Marukawa // At function entry, the "frame" looks as follows:
203a302349SKazushi (Jam) Marukawa //
213a302349SKazushi (Jam) Marukawa // |                                              | Higher address
223a302349SKazushi (Jam) Marukawa // |----------------------------------------------|
233a302349SKazushi (Jam) Marukawa // | Parameter area for this function             |
243a302349SKazushi (Jam) Marukawa // |----------------------------------------------|
253a302349SKazushi (Jam) Marukawa // | Register save area (RSA) for this function   |
263a302349SKazushi (Jam) Marukawa // |----------------------------------------------|
273a302349SKazushi (Jam) Marukawa // | Return address for this function             |
283a302349SKazushi (Jam) Marukawa // |----------------------------------------------|
293a302349SKazushi (Jam) Marukawa // | Frame pointer for this function              |
303a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- sp
313a302349SKazushi (Jam) Marukawa // |                                              | Lower address
323a302349SKazushi (Jam) Marukawa //
333a302349SKazushi (Jam) Marukawa // VE doesn't use on demand stack allocation, so user code generated by LLVM
343a302349SKazushi (Jam) Marukawa // needs to call VEOS to allocate stack frame.  VE's ABI want to reduce the
353a302349SKazushi (Jam) Marukawa // number of VEOS calls, so ABI requires to allocate not only RSA (in general
363a302349SKazushi (Jam) Marukawa // CSR, callee saved register) area but also call frame at the prologue of
373a302349SKazushi (Jam) Marukawa // caller function.
383a302349SKazushi (Jam) Marukawa //
393a302349SKazushi (Jam) Marukawa // After the prologue has run, the frame has the following general structure.
403a302349SKazushi (Jam) Marukawa // Note that technically the last frame area (VLAs) doesn't get created until
413a302349SKazushi (Jam) Marukawa // in the main function body, after the prologue is run. However, it's depicted
423a302349SKazushi (Jam) Marukawa // here for completeness.
433a302349SKazushi (Jam) Marukawa //
443a302349SKazushi (Jam) Marukawa // |                                              | Higher address
453a302349SKazushi (Jam) Marukawa // |----------------------------------------------|
463a302349SKazushi (Jam) Marukawa // | Parameter area for this function             |
473a302349SKazushi (Jam) Marukawa // |----------------------------------------------|
483a302349SKazushi (Jam) Marukawa // | Register save area (RSA) for this function   |
493a302349SKazushi (Jam) Marukawa // |----------------------------------------------|
503a302349SKazushi (Jam) Marukawa // | Return address for this function             |
513a302349SKazushi (Jam) Marukawa // |----------------------------------------------|
523a302349SKazushi (Jam) Marukawa // | Frame pointer for this function              |
533a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- fp(=old sp)
543a302349SKazushi (Jam) Marukawa // |.empty.space.to.make.part.below.aligned.in....|
553a302349SKazushi (Jam) Marukawa // |.case.it.needs.more.than.the.standard.16-byte.| (size of this area is
563a302349SKazushi (Jam) Marukawa // |.alignment....................................|  unknown at compile time)
573a302349SKazushi (Jam) Marukawa // |----------------------------------------------|
583a302349SKazushi (Jam) Marukawa // | Local variables of fixed size including spill|
593a302349SKazushi (Jam) Marukawa // | slots                                        |
603a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- bp(not defined by ABI,
613a302349SKazushi (Jam) Marukawa // |.variable-sized.local.variables.(VLAs)........|       LLVM chooses SX17)
623a302349SKazushi (Jam) Marukawa // |..............................................| (size of this area is
633a302349SKazushi (Jam) Marukawa // |..............................................|  unknown at compile time)
643a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- stack top (returned by
653a302349SKazushi (Jam) Marukawa // | Parameter area for callee                    |               alloca)
663a302349SKazushi (Jam) Marukawa // |----------------------------------------------|
673a302349SKazushi (Jam) Marukawa // | Register save area (RSA) for callee          |
683a302349SKazushi (Jam) Marukawa // |----------------------------------------------|
693a302349SKazushi (Jam) Marukawa // | Return address for callee                    |
703a302349SKazushi (Jam) Marukawa // |----------------------------------------------|
713a302349SKazushi (Jam) Marukawa // | Frame pointer for callee                     |
723a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- sp
733a302349SKazushi (Jam) Marukawa // |                                              | Lower address
743a302349SKazushi (Jam) Marukawa //
753a302349SKazushi (Jam) Marukawa // To access the data in a frame, at-compile time, a constant offset must be
763a302349SKazushi (Jam) Marukawa // computable from one of the pointers (fp, bp, sp) to access it. The size
773a302349SKazushi (Jam) Marukawa // of the areas with a dotted background cannot be computed at compile-time
783a302349SKazushi (Jam) Marukawa // if they are present, making it required to have all three of fp, bp and
793a302349SKazushi (Jam) Marukawa // sp to be set up to be able to access all contents in the frame areas,
803a302349SKazushi (Jam) Marukawa // assuming all of the frame areas are non-empty.
813a302349SKazushi (Jam) Marukawa //
823a302349SKazushi (Jam) Marukawa // For most functions, some of the frame areas are empty. For those functions,
833a302349SKazushi (Jam) Marukawa // it may not be necessary to set up fp or bp:
843a302349SKazushi (Jam) Marukawa // * A base pointer is definitely needed when there are both VLAs and local
853a302349SKazushi (Jam) Marukawa //   variables with more-than-default alignment requirements.
863a302349SKazushi (Jam) Marukawa // * A frame pointer is definitely needed when there are local variables with
873a302349SKazushi (Jam) Marukawa //   more-than-default alignment requirements.
883a302349SKazushi (Jam) Marukawa //
893a302349SKazushi (Jam) Marukawa // In addition, VE ABI defines RSA frame, return address, and frame pointer
903a302349SKazushi (Jam) Marukawa // as follows:
913a302349SKazushi (Jam) Marukawa //
923a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- sp+176
933a302349SKazushi (Jam) Marukawa // | %s18...%s33                                  |
943a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- sp+48
953a302349SKazushi (Jam) Marukawa // | Linkage area register (%s17)                 |
963a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- sp+40
973a302349SKazushi (Jam) Marukawa // | Procedure linkage table register (%plt=%s16) |
983a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- sp+32
993a302349SKazushi (Jam) Marukawa // | Global offset table register (%got=%s15)     |
1003a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- sp+24
1013a302349SKazushi (Jam) Marukawa // | Thread pointer register (%tp=%s14)           |
1023a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- sp+16
1033a302349SKazushi (Jam) Marukawa // | Return address                               |
1043a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- sp+8
1053a302349SKazushi (Jam) Marukawa // | Frame pointer                                |
1063a302349SKazushi (Jam) Marukawa // |----------------------------------------------| <- sp+0
1073a302349SKazushi (Jam) Marukawa //
1083a302349SKazushi (Jam) Marukawa // NOTE: This description is based on VE ABI and description in
1093a302349SKazushi (Jam) Marukawa //       AArch64FrameLowering.cpp.  Thanks a lot.
110064859bdSKazushi (Jam) Marukawa //===----------------------------------------------------------------------===//
111064859bdSKazushi (Jam) Marukawa 
112064859bdSKazushi (Jam) Marukawa #include "VEFrameLowering.h"
113064859bdSKazushi (Jam) Marukawa #include "VEInstrInfo.h"
11492600c2eSKazushi (Jam) Marukawa #include "VEMachineFunctionInfo.h"
115064859bdSKazushi (Jam) Marukawa #include "VESubtarget.h"
116064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineFrameInfo.h"
117064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineFunction.h"
118064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineInstrBuilder.h"
119064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineModuleInfo.h"
120064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineRegisterInfo.h"
121064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/RegisterScavenging.h"
122064859bdSKazushi (Jam) Marukawa #include "llvm/IR/DataLayout.h"
123064859bdSKazushi (Jam) Marukawa #include "llvm/IR/Function.h"
124064859bdSKazushi (Jam) Marukawa #include "llvm/Support/CommandLine.h"
125064859bdSKazushi (Jam) Marukawa #include "llvm/Target/TargetOptions.h"
126064859bdSKazushi (Jam) Marukawa #include "llvm/Support/MathExtras.h"
127064859bdSKazushi (Jam) Marukawa 
128064859bdSKazushi (Jam) Marukawa using namespace llvm;
129064859bdSKazushi (Jam) Marukawa 
VEFrameLowering(const VESubtarget & ST)130064859bdSKazushi (Jam) Marukawa VEFrameLowering::VEFrameLowering(const VESubtarget &ST)
131064859bdSKazushi (Jam) Marukawa     : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(16), 0,
132dedaf3a2SKazushi (Jam) Marukawa                           Align(16)),
133dedaf3a2SKazushi (Jam) Marukawa       STI(ST) {}
134064859bdSKazushi (Jam) Marukawa 
emitPrologueInsns(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,uint64_t NumBytes,bool RequireFPUpdate) const135064859bdSKazushi (Jam) Marukawa void VEFrameLowering::emitPrologueInsns(MachineFunction &MF,
136064859bdSKazushi (Jam) Marukawa                                         MachineBasicBlock &MBB,
137064859bdSKazushi (Jam) Marukawa                                         MachineBasicBlock::iterator MBBI,
138dedaf3a2SKazushi (Jam) Marukawa                                         uint64_t NumBytes,
139064859bdSKazushi (Jam) Marukawa                                         bool RequireFPUpdate) const {
140686988a5SKazushi (Jam) Marukawa   const VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>();
14115a2bacaSKazushi (Jam) Marukawa   DebugLoc DL;
142686988a5SKazushi (Jam) Marukawa   const VEInstrInfo &TII = *STI.getInstrInfo();
14315a2bacaSKazushi (Jam) Marukawa 
144064859bdSKazushi (Jam) Marukawa   // Insert following codes here as prologue
145064859bdSKazushi (Jam) Marukawa   //
146686988a5SKazushi (Jam) Marukawa   //    st %fp, 0(, %sp)   iff !isLeafProc
147686988a5SKazushi (Jam) Marukawa   //    st %lr, 8(, %sp)   iff !isLeafProc
148686988a5SKazushi (Jam) Marukawa   //    st %got, 24(, %sp) iff hasGOT
149686988a5SKazushi (Jam) Marukawa   //    st %plt, 32(, %sp) iff hasGOT
150686988a5SKazushi (Jam) Marukawa   //    st %s17, 40(, %sp) iff hasBP
151686988a5SKazushi (Jam) Marukawa   if (!FuncInfo->isLeafProc()) {
15215a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::STrii))
153064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX11)
154064859bdSKazushi (Jam) Marukawa         .addImm(0)
155e981a46aSKazushi (Jam) Marukawa         .addImm(0)
156064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX9);
15715a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::STrii))
158064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX11)
159e981a46aSKazushi (Jam) Marukawa         .addImm(0)
160064859bdSKazushi (Jam) Marukawa         .addImm(8)
161064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX10);
162686988a5SKazushi (Jam) Marukawa   }
163686988a5SKazushi (Jam) Marukawa   if (hasGOT(MF)) {
16415a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::STrii))
165064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX11)
166e981a46aSKazushi (Jam) Marukawa         .addImm(0)
167064859bdSKazushi (Jam) Marukawa         .addImm(24)
168064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX15);
16915a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::STrii))
170064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX11)
171e981a46aSKazushi (Jam) Marukawa         .addImm(0)
172064859bdSKazushi (Jam) Marukawa         .addImm(32)
173064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX16);
174686988a5SKazushi (Jam) Marukawa   }
175dedaf3a2SKazushi (Jam) Marukawa   if (hasBP(MF))
17615a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::STrii))
177dedaf3a2SKazushi (Jam) Marukawa         .addReg(VE::SX11)
178dedaf3a2SKazushi (Jam) Marukawa         .addImm(0)
179dedaf3a2SKazushi (Jam) Marukawa         .addImm(40)
180dedaf3a2SKazushi (Jam) Marukawa         .addReg(VE::SX17);
181064859bdSKazushi (Jam) Marukawa }
182064859bdSKazushi (Jam) Marukawa 
emitEpilogueInsns(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,uint64_t NumBytes,bool RequireFPUpdate) const183064859bdSKazushi (Jam) Marukawa void VEFrameLowering::emitEpilogueInsns(MachineFunction &MF,
184064859bdSKazushi (Jam) Marukawa                                         MachineBasicBlock &MBB,
185064859bdSKazushi (Jam) Marukawa                                         MachineBasicBlock::iterator MBBI,
186dedaf3a2SKazushi (Jam) Marukawa                                         uint64_t NumBytes,
187064859bdSKazushi (Jam) Marukawa                                         bool RequireFPUpdate) const {
188686988a5SKazushi (Jam) Marukawa   const VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>();
18915a2bacaSKazushi (Jam) Marukawa   DebugLoc DL;
190686988a5SKazushi (Jam) Marukawa   const VEInstrInfo &TII = *STI.getInstrInfo();
19115a2bacaSKazushi (Jam) Marukawa 
192064859bdSKazushi (Jam) Marukawa   // Insert following codes here as epilogue
193064859bdSKazushi (Jam) Marukawa   //
194686988a5SKazushi (Jam) Marukawa   //    ld %s17, 40(, %sp) iff hasBP
195686988a5SKazushi (Jam) Marukawa   //    ld %plt, 32(, %sp) iff hasGOT
196686988a5SKazushi (Jam) Marukawa   //    ld %got, 24(, %sp) iff hasGOT
197686988a5SKazushi (Jam) Marukawa   //    ld %lr, 8(, %sp)   iff !isLeafProc
198686988a5SKazushi (Jam) Marukawa   //    ld %fp, 0(, %sp)   iff !isLeafProc
199dedaf3a2SKazushi (Jam) Marukawa   if (hasBP(MF))
20015a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::LDrii), VE::SX17)
201dedaf3a2SKazushi (Jam) Marukawa         .addReg(VE::SX11)
202dedaf3a2SKazushi (Jam) Marukawa         .addImm(0)
203dedaf3a2SKazushi (Jam) Marukawa         .addImm(40);
204686988a5SKazushi (Jam) Marukawa   if (hasGOT(MF)) {
20515a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::LDrii), VE::SX16)
206064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX11)
207e981a46aSKazushi (Jam) Marukawa         .addImm(0)
208064859bdSKazushi (Jam) Marukawa         .addImm(32);
20915a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::LDrii), VE::SX15)
210064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX11)
211e981a46aSKazushi (Jam) Marukawa         .addImm(0)
212064859bdSKazushi (Jam) Marukawa         .addImm(24);
213686988a5SKazushi (Jam) Marukawa   }
214686988a5SKazushi (Jam) Marukawa   if (!FuncInfo->isLeafProc()) {
21515a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::LDrii), VE::SX10)
216064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX11)
217e981a46aSKazushi (Jam) Marukawa         .addImm(0)
218064859bdSKazushi (Jam) Marukawa         .addImm(8);
21915a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::LDrii), VE::SX9)
220064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX11)
221e981a46aSKazushi (Jam) Marukawa         .addImm(0)
222064859bdSKazushi (Jam) Marukawa         .addImm(0);
223064859bdSKazushi (Jam) Marukawa   }
224686988a5SKazushi (Jam) Marukawa }
225064859bdSKazushi (Jam) Marukawa 
emitSPAdjustment(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,int64_t NumBytes,MaybeAlign MaybeAlign) const226064859bdSKazushi (Jam) Marukawa void VEFrameLowering::emitSPAdjustment(MachineFunction &MF,
227064859bdSKazushi (Jam) Marukawa                                        MachineBasicBlock &MBB,
228064859bdSKazushi (Jam) Marukawa                                        MachineBasicBlock::iterator MBBI,
229dedaf3a2SKazushi (Jam) Marukawa                                        int64_t NumBytes,
230dedaf3a2SKazushi (Jam) Marukawa                                        MaybeAlign MaybeAlign) const {
23115a2bacaSKazushi (Jam) Marukawa   DebugLoc DL;
2323bd78b7cSKazushi (Jam) Marukawa   const VEInstrInfo &TII = *STI.getInstrInfo();
233064859bdSKazushi (Jam) Marukawa 
2343bd78b7cSKazushi (Jam) Marukawa   if (NumBytes == 0) {
2353bd78b7cSKazushi (Jam) Marukawa     // Nothing to do here.
2363bd78b7cSKazushi (Jam) Marukawa   } else if (isInt<7>(NumBytes)) {
2373bd78b7cSKazushi (Jam) Marukawa     // adds.l %s11, NumBytes@lo, %s11
23815a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::ADDSLri), VE::SX11)
239064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX11)
240064859bdSKazushi (Jam) Marukawa         .addImm(NumBytes);
2413bd78b7cSKazushi (Jam) Marukawa   } else if (isInt<32>(NumBytes)) {
2423bd78b7cSKazushi (Jam) Marukawa     // lea %s11, NumBytes@lo(, %s11)
2433bd78b7cSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::LEArii), VE::SX11)
2443bd78b7cSKazushi (Jam) Marukawa         .addReg(VE::SX11)
2453bd78b7cSKazushi (Jam) Marukawa         .addImm(0)
2463bd78b7cSKazushi (Jam) Marukawa         .addImm(Lo_32(NumBytes));
2473bd78b7cSKazushi (Jam) Marukawa   } else {
248064859bdSKazushi (Jam) Marukawa     // Emit following codes.  This clobbers SX13 which we always know is
249064859bdSKazushi (Jam) Marukawa     // available here.
2503bd78b7cSKazushi (Jam) Marukawa     //   lea     %s13, NumBytes@lo
251064859bdSKazushi (Jam) Marukawa     //   and     %s13, %s13, (32)0
2523bd78b7cSKazushi (Jam) Marukawa     //   lea.sl  %sp, NumBytes@hi(%s13, %sp)
25315a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::LEAzii), VE::SX13)
254e981a46aSKazushi (Jam) Marukawa         .addImm(0)
255e981a46aSKazushi (Jam) Marukawa         .addImm(0)
256773ae62fSKazushi (Jam) Marukawa         .addImm(Lo_32(NumBytes));
25715a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::ANDrm), VE::SX13)
258064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX13)
259015dee1aSKazushi (Jam) Marukawa         .addImm(M0(32));
26015a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::LEASLrri), VE::SX11)
261064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX11)
262064859bdSKazushi (Jam) Marukawa         .addReg(VE::SX13)
263773ae62fSKazushi (Jam) Marukawa         .addImm(Hi_32(NumBytes));
2643bd78b7cSKazushi (Jam) Marukawa   }
265dedaf3a2SKazushi (Jam) Marukawa 
266dedaf3a2SKazushi (Jam) Marukawa   if (MaybeAlign) {
267dedaf3a2SKazushi (Jam) Marukawa     // and %sp, %sp, Align-1
26815a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::ANDrm), VE::SX11)
269dedaf3a2SKazushi (Jam) Marukawa         .addReg(VE::SX11)
270dedaf3a2SKazushi (Jam) Marukawa         .addImm(M1(64 - Log2_64(MaybeAlign.valueOrOne().value())));
271dedaf3a2SKazushi (Jam) Marukawa   }
272064859bdSKazushi (Jam) Marukawa }
273064859bdSKazushi (Jam) Marukawa 
emitSPExtend(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI) const274064859bdSKazushi (Jam) Marukawa void VEFrameLowering::emitSPExtend(MachineFunction &MF, MachineBasicBlock &MBB,
275dedaf3a2SKazushi (Jam) Marukawa                                    MachineBasicBlock::iterator MBBI) const {
27615a2bacaSKazushi (Jam) Marukawa   DebugLoc DL;
277686988a5SKazushi (Jam) Marukawa   const VEInstrInfo &TII = *STI.getInstrInfo();
278064859bdSKazushi (Jam) Marukawa 
279064859bdSKazushi (Jam) Marukawa   // Emit following codes.  It is not possible to insert multiple
280064859bdSKazushi (Jam) Marukawa   // BasicBlocks in PEI pass, so we emit two pseudo instructions here.
281064859bdSKazushi (Jam) Marukawa   //
282064859bdSKazushi (Jam) Marukawa   //   EXTEND_STACK                     // pseudo instrcution
283064859bdSKazushi (Jam) Marukawa   //   EXTEND_STACK_GUARD               // pseudo instrcution
284064859bdSKazushi (Jam) Marukawa   //
285064859bdSKazushi (Jam) Marukawa   // EXTEND_STACK pseudo will be converted by ExpandPostRA pass into
286064859bdSKazushi (Jam) Marukawa   // following instructions with multiple basic blocks later.
287064859bdSKazushi (Jam) Marukawa   //
288064859bdSKazushi (Jam) Marukawa   // thisBB:
289064859bdSKazushi (Jam) Marukawa   //   brge.l.t %sp, %sl, sinkBB
290064859bdSKazushi (Jam) Marukawa   // syscallBB:
291064859bdSKazushi (Jam) Marukawa   //   ld      %s61, 0x18(, %tp)        // load param area
292064859bdSKazushi (Jam) Marukawa   //   or      %s62, 0, %s0             // spill the value of %s0
293064859bdSKazushi (Jam) Marukawa   //   lea     %s63, 0x13b              // syscall # of grow
294064859bdSKazushi (Jam) Marukawa   //   shm.l   %s63, 0x0(%s61)          // store syscall # at addr:0
295064859bdSKazushi (Jam) Marukawa   //   shm.l   %sl, 0x8(%s61)           // store old limit at addr:8
296064859bdSKazushi (Jam) Marukawa   //   shm.l   %sp, 0x10(%s61)          // store new limit at addr:16
297064859bdSKazushi (Jam) Marukawa   //   monc                             // call monitor
298064859bdSKazushi (Jam) Marukawa   //   or      %s0, 0, %s62             // restore the value of %s0
299064859bdSKazushi (Jam) Marukawa   // sinkBB:
300064859bdSKazushi (Jam) Marukawa   //
301064859bdSKazushi (Jam) Marukawa   // EXTEND_STACK_GUARD pseudo will be simply eliminated by ExpandPostRA
302064859bdSKazushi (Jam) Marukawa   // pass.  This pseudo is required to be at the next of EXTEND_STACK
303064859bdSKazushi (Jam) Marukawa   // pseudo in order to protect iteration loop in ExpandPostRA.
30415a2bacaSKazushi (Jam) Marukawa   BuildMI(MBB, MBBI, DL, TII.get(VE::EXTEND_STACK));
30515a2bacaSKazushi (Jam) Marukawa   BuildMI(MBB, MBBI, DL, TII.get(VE::EXTEND_STACK_GUARD));
306064859bdSKazushi (Jam) Marukawa }
307064859bdSKazushi (Jam) Marukawa 
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const308064859bdSKazushi (Jam) Marukawa void VEFrameLowering::emitPrologue(MachineFunction &MF,
309064859bdSKazushi (Jam) Marukawa                                    MachineBasicBlock &MBB) const {
31044a4f939SKazushi (Jam) Marukawa   const VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>();
311064859bdSKazushi (Jam) Marukawa   assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
312064859bdSKazushi (Jam) Marukawa   MachineFrameInfo &MFI = MF.getFrameInfo();
313dedaf3a2SKazushi (Jam) Marukawa   const VEInstrInfo &TII = *STI.getInstrInfo();
314dedaf3a2SKazushi (Jam) Marukawa   const VERegisterInfo &RegInfo = *STI.getRegisterInfo();
315064859bdSKazushi (Jam) Marukawa   MachineBasicBlock::iterator MBBI = MBB.begin();
316*a9968c0aSTomas Matheson   bool NeedsStackRealignment = RegInfo.shouldRealignStack(MF);
31715a2bacaSKazushi (Jam) Marukawa 
318064859bdSKazushi (Jam) Marukawa   // Debug location must be unknown since the first debug location is used
319064859bdSKazushi (Jam) Marukawa   // to determine the end of the prologue.
32015a2bacaSKazushi (Jam) Marukawa   DebugLoc DL;
321064859bdSKazushi (Jam) Marukawa 
322*a9968c0aSTomas Matheson   if (NeedsStackRealignment && !RegInfo.canRealignStack(MF))
323064859bdSKazushi (Jam) Marukawa     report_fatal_error("Function \"" + Twine(MF.getName()) +
324064859bdSKazushi (Jam) Marukawa                        "\" required "
325064859bdSKazushi (Jam) Marukawa                        "stack re-alignment, but LLVM couldn't handle it "
326064859bdSKazushi (Jam) Marukawa                        "(probably because it has a dynamic alloca).");
327064859bdSKazushi (Jam) Marukawa 
328686988a5SKazushi (Jam) Marukawa   // Get the number of bytes to allocate from the FrameInfo.
329686988a5SKazushi (Jam) Marukawa   // This number of bytes is already aligned to ABI stack alignment.
330dedaf3a2SKazushi (Jam) Marukawa   uint64_t NumBytes = MFI.getStackSize();
331064859bdSKazushi (Jam) Marukawa 
332686988a5SKazushi (Jam) Marukawa   // Adjust stack size if this function is not a leaf function since the
333686988a5SKazushi (Jam) Marukawa   // VE ABI requires a reserved area at the top of stack as described in
334686988a5SKazushi (Jam) Marukawa   // VEFrameLowering.cpp.
335686988a5SKazushi (Jam) Marukawa   if (!FuncInfo->isLeafProc()) {
336686988a5SKazushi (Jam) Marukawa     // NOTE: The number is aligned to ABI stack alignment after adjustment.
337dedaf3a2SKazushi (Jam) Marukawa     NumBytes = STI.getAdjustedFrameSize(NumBytes);
338686988a5SKazushi (Jam) Marukawa   }
339064859bdSKazushi (Jam) Marukawa 
340064859bdSKazushi (Jam) Marukawa   // Finally, ensure that the size is sufficiently aligned for the
341064859bdSKazushi (Jam) Marukawa   // data on the stack.
342dedaf3a2SKazushi (Jam) Marukawa   NumBytes = alignTo(NumBytes, MFI.getMaxAlign());
343064859bdSKazushi (Jam) Marukawa 
344064859bdSKazushi (Jam) Marukawa   // Update stack size with corrected value.
345064859bdSKazushi (Jam) Marukawa   MFI.setStackSize(NumBytes);
346064859bdSKazushi (Jam) Marukawa 
34715a2bacaSKazushi (Jam) Marukawa   // Emit Prologue instructions to save multiple registers.
348064859bdSKazushi (Jam) Marukawa   emitPrologueInsns(MF, MBB, MBBI, NumBytes, true);
349064859bdSKazushi (Jam) Marukawa 
350686988a5SKazushi (Jam) Marukawa   // Emit instructions to save SP in FP as follows if this is not a leaf
351686988a5SKazushi (Jam) Marukawa   // function:
352686988a5SKazushi (Jam) Marukawa   //    or %fp, 0, %sp
353686988a5SKazushi (Jam) Marukawa   if (!FuncInfo->isLeafProc())
354686988a5SKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::ORri), VE::SX9)
355686988a5SKazushi (Jam) Marukawa         .addReg(VE::SX11)
356686988a5SKazushi (Jam) Marukawa         .addImm(0);
357686988a5SKazushi (Jam) Marukawa 
358064859bdSKazushi (Jam) Marukawa   // Emit stack adjust instructions
359dedaf3a2SKazushi (Jam) Marukawa   MaybeAlign RuntimeAlign =
360dedaf3a2SKazushi (Jam) Marukawa       NeedsStackRealignment ? MaybeAlign(MFI.getMaxAlign()) : None;
361686988a5SKazushi (Jam) Marukawa   assert((RuntimeAlign == None || !FuncInfo->isLeafProc()) &&
362686988a5SKazushi (Jam) Marukawa          "SP has to be saved in order to align variable sized stack object!");
363dedaf3a2SKazushi (Jam) Marukawa   emitSPAdjustment(MF, MBB, MBBI, -(int64_t)NumBytes, RuntimeAlign);
364dedaf3a2SKazushi (Jam) Marukawa 
365dedaf3a2SKazushi (Jam) Marukawa   if (hasBP(MF)) {
366dedaf3a2SKazushi (Jam) Marukawa     // Copy SP to BP.
36715a2bacaSKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::ORri), VE::SX17)
368dedaf3a2SKazushi (Jam) Marukawa         .addReg(VE::SX11)
369dedaf3a2SKazushi (Jam) Marukawa         .addImm(0);
370dedaf3a2SKazushi (Jam) Marukawa   }
371064859bdSKazushi (Jam) Marukawa 
372064859bdSKazushi (Jam) Marukawa   // Emit stack extend instructions
373686988a5SKazushi (Jam) Marukawa   if (NumBytes != 0)
374dedaf3a2SKazushi (Jam) Marukawa     emitSPExtend(MF, MBB, MBBI);
375064859bdSKazushi (Jam) Marukawa }
376064859bdSKazushi (Jam) Marukawa 
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const377064859bdSKazushi (Jam) Marukawa MachineBasicBlock::iterator VEFrameLowering::eliminateCallFramePseudoInstr(
378064859bdSKazushi (Jam) Marukawa     MachineFunction &MF, MachineBasicBlock &MBB,
379064859bdSKazushi (Jam) Marukawa     MachineBasicBlock::iterator I) const {
380064859bdSKazushi (Jam) Marukawa   if (!hasReservedCallFrame(MF)) {
381064859bdSKazushi (Jam) Marukawa     MachineInstr &MI = *I;
382dedaf3a2SKazushi (Jam) Marukawa     int64_t Size = MI.getOperand(0).getImm();
383064859bdSKazushi (Jam) Marukawa     if (MI.getOpcode() == VE::ADJCALLSTACKDOWN)
384064859bdSKazushi (Jam) Marukawa       Size = -Size;
385064859bdSKazushi (Jam) Marukawa 
386064859bdSKazushi (Jam) Marukawa     if (Size)
387064859bdSKazushi (Jam) Marukawa       emitSPAdjustment(MF, MBB, I, Size);
388064859bdSKazushi (Jam) Marukawa   }
389064859bdSKazushi (Jam) Marukawa   return MBB.erase(I);
390064859bdSKazushi (Jam) Marukawa }
391064859bdSKazushi (Jam) Marukawa 
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const392064859bdSKazushi (Jam) Marukawa void VEFrameLowering::emitEpilogue(MachineFunction &MF,
393064859bdSKazushi (Jam) Marukawa                                    MachineBasicBlock &MBB) const {
39444a4f939SKazushi (Jam) Marukawa   const VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>();
395686988a5SKazushi (Jam) Marukawa   DebugLoc DL;
396064859bdSKazushi (Jam) Marukawa   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
397064859bdSKazushi (Jam) Marukawa   MachineFrameInfo &MFI = MF.getFrameInfo();
398686988a5SKazushi (Jam) Marukawa   const VEInstrInfo &TII = *STI.getInstrInfo();
399064859bdSKazushi (Jam) Marukawa 
400dedaf3a2SKazushi (Jam) Marukawa   uint64_t NumBytes = MFI.getStackSize();
401064859bdSKazushi (Jam) Marukawa 
402686988a5SKazushi (Jam) Marukawa   // Emit instructions to retrieve original SP.
403686988a5SKazushi (Jam) Marukawa   if (!FuncInfo->isLeafProc()) {
404686988a5SKazushi (Jam) Marukawa     // If SP is saved in FP, retrieve it as follows:
405686988a5SKazushi (Jam) Marukawa     //    or %sp, 0, %fp     iff !isLeafProc
406686988a5SKazushi (Jam) Marukawa     BuildMI(MBB, MBBI, DL, TII.get(VE::ORri), VE::SX11)
407686988a5SKazushi (Jam) Marukawa         .addReg(VE::SX9)
408686988a5SKazushi (Jam) Marukawa         .addImm(0);
409686988a5SKazushi (Jam) Marukawa   } else {
410686988a5SKazushi (Jam) Marukawa     // Emit stack adjust instructions.
411686988a5SKazushi (Jam) Marukawa     emitSPAdjustment(MF, MBB, MBBI, NumBytes, None);
412686988a5SKazushi (Jam) Marukawa   }
41344a4f939SKazushi (Jam) Marukawa 
41415a2bacaSKazushi (Jam) Marukawa   // Emit Epilogue instructions to restore multiple registers.
415064859bdSKazushi (Jam) Marukawa   emitEpilogueInsns(MF, MBB, MBBI, NumBytes, true);
416064859bdSKazushi (Jam) Marukawa }
417064859bdSKazushi (Jam) Marukawa 
418064859bdSKazushi (Jam) Marukawa // hasFP - Return true if the specified function should have a dedicated frame
419dedaf3a2SKazushi (Jam) Marukawa // pointer register.  This is true if the function has variable sized allocas
42044a4f939SKazushi (Jam) Marukawa // or if frame pointer elimination is disabled.
hasFP(const MachineFunction & MF) const421064859bdSKazushi (Jam) Marukawa bool VEFrameLowering::hasFP(const MachineFunction &MF) const {
422064859bdSKazushi (Jam) Marukawa   const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
423064859bdSKazushi (Jam) Marukawa 
424064859bdSKazushi (Jam) Marukawa   const MachineFrameInfo &MFI = MF.getFrameInfo();
425064859bdSKazushi (Jam) Marukawa   return MF.getTarget().Options.DisableFramePointerElim(MF) ||
426*a9968c0aSTomas Matheson          RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
427064859bdSKazushi (Jam) Marukawa          MFI.isFrameAddressTaken();
428064859bdSKazushi (Jam) Marukawa }
429064859bdSKazushi (Jam) Marukawa 
hasBP(const MachineFunction & MF) const430dedaf3a2SKazushi (Jam) Marukawa bool VEFrameLowering::hasBP(const MachineFunction &MF) const {
431dedaf3a2SKazushi (Jam) Marukawa   const MachineFrameInfo &MFI = MF.getFrameInfo();
432dedaf3a2SKazushi (Jam) Marukawa   const TargetRegisterInfo *TRI = STI.getRegisterInfo();
433dedaf3a2SKazushi (Jam) Marukawa 
434*a9968c0aSTomas Matheson   return MFI.hasVarSizedObjects() && TRI->hasStackRealignment(MF);
435dedaf3a2SKazushi (Jam) Marukawa }
436dedaf3a2SKazushi (Jam) Marukawa 
hasGOT(const MachineFunction & MF) const437686988a5SKazushi (Jam) Marukawa bool VEFrameLowering::hasGOT(const MachineFunction &MF) const {
438686988a5SKazushi (Jam) Marukawa   const VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>();
439686988a5SKazushi (Jam) Marukawa 
440686988a5SKazushi (Jam) Marukawa   // If a global base register is assigned (!= 0), GOT is used.
441686988a5SKazushi (Jam) Marukawa   return FuncInfo->getGlobalBaseReg() != 0;
442686988a5SKazushi (Jam) Marukawa }
443686988a5SKazushi (Jam) Marukawa 
getFrameIndexReference(const MachineFunction & MF,int FI,Register & FrameReg) const444d57bba7cSSander de Smalen StackOffset VEFrameLowering::getFrameIndexReference(const MachineFunction &MF,
445d57bba7cSSander de Smalen                                                     int FI,
4462f8fb4d1SFangrui Song                                                     Register &FrameReg) const {
44792600c2eSKazushi (Jam) Marukawa   const MachineFrameInfo &MFI = MF.getFrameInfo();
448dedaf3a2SKazushi (Jam) Marukawa   const VERegisterInfo *RegInfo = STI.getRegisterInfo();
44992600c2eSKazushi (Jam) Marukawa   bool isFixed = MFI.isFixedObjectIndex(FI);
45092600c2eSKazushi (Jam) Marukawa 
451dedaf3a2SKazushi (Jam) Marukawa   int64_t FrameOffset = MF.getFrameInfo().getObjectOffset(FI);
45292600c2eSKazushi (Jam) Marukawa 
45344a4f939SKazushi (Jam) Marukawa   if (!hasFP(MF)) {
45444a4f939SKazushi (Jam) Marukawa     // If FP is not used, frame indexies are based on a %sp regiter.
455064859bdSKazushi (Jam) Marukawa     FrameReg = VE::SX11; // %sp
456d57bba7cSSander de Smalen     return StackOffset::getFixed(FrameOffset +
457d57bba7cSSander de Smalen                                  MF.getFrameInfo().getStackSize());
458064859bdSKazushi (Jam) Marukawa   }
459*a9968c0aSTomas Matheson   if (RegInfo->hasStackRealignment(MF) && !isFixed) {
46044a4f939SKazushi (Jam) Marukawa     // If data on stack require realignemnt, frame indexies are based on a %sp
46144a4f939SKazushi (Jam) Marukawa     // or %s17 (bp) register.  If there is a variable sized object, bp is used.
462dedaf3a2SKazushi (Jam) Marukawa     if (hasBP(MF))
463dedaf3a2SKazushi (Jam) Marukawa       FrameReg = VE::SX17; // %bp
464dedaf3a2SKazushi (Jam) Marukawa     else
465dedaf3a2SKazushi (Jam) Marukawa       FrameReg = VE::SX11; // %sp
466d57bba7cSSander de Smalen     return StackOffset::getFixed(FrameOffset +
467d57bba7cSSander de Smalen                                  MF.getFrameInfo().getStackSize());
468dedaf3a2SKazushi (Jam) Marukawa   }
46944a4f939SKazushi (Jam) Marukawa   // Use %fp by default.
470dedaf3a2SKazushi (Jam) Marukawa   FrameReg = RegInfo->getFrameRegister(MF);
471d57bba7cSSander de Smalen   return StackOffset::getFixed(FrameOffset);
472dedaf3a2SKazushi (Jam) Marukawa }
473064859bdSKazushi (Jam) Marukawa 
isLeafProc(MachineFunction & MF) const474064859bdSKazushi (Jam) Marukawa bool VEFrameLowering::isLeafProc(MachineFunction &MF) const {
475064859bdSKazushi (Jam) Marukawa 
476064859bdSKazushi (Jam) Marukawa   MachineRegisterInfo &MRI = MF.getRegInfo();
477064859bdSKazushi (Jam) Marukawa   MachineFrameInfo &MFI = MF.getFrameInfo();
478064859bdSKazushi (Jam) Marukawa 
479064859bdSKazushi (Jam) Marukawa   return !MFI.hasCalls()                 // No calls
480064859bdSKazushi (Jam) Marukawa          && !MRI.isPhysRegUsed(VE::SX18) // Registers within limits
481064859bdSKazushi (Jam) Marukawa                                          //   (s18 is first CSR)
482064859bdSKazushi (Jam) Marukawa          && !MRI.isPhysRegUsed(VE::SX11) // %sp un-used
483064859bdSKazushi (Jam) Marukawa          && !hasFP(MF);                  // Don't need %fp
484064859bdSKazushi (Jam) Marukawa }
485064859bdSKazushi (Jam) Marukawa 
determineCalleeSaves(MachineFunction & MF,BitVector & SavedRegs,RegScavenger * RS) const486064859bdSKazushi (Jam) Marukawa void VEFrameLowering::determineCalleeSaves(MachineFunction &MF,
487064859bdSKazushi (Jam) Marukawa                                            BitVector &SavedRegs,
488064859bdSKazushi (Jam) Marukawa                                            RegScavenger *RS) const {
489064859bdSKazushi (Jam) Marukawa   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
490064859bdSKazushi (Jam) Marukawa 
4913d872cbcSKazushi (Jam) Marukawa   // Functions having BP need to emit prologue and epilogue to allocate local
4923d872cbcSKazushi (Jam) Marukawa   // buffer on the stack even if the function is a leaf function.
493686988a5SKazushi (Jam) Marukawa   if (isLeafProc(MF) && !hasBP(MF)) {
49444a4f939SKazushi (Jam) Marukawa     VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>();
49544a4f939SKazushi (Jam) Marukawa     FuncInfo->setLeafProc(true);
49692600c2eSKazushi (Jam) Marukawa   }
497064859bdSKazushi (Jam) Marukawa }
498