1*9880d681SAndroid Build Coastguard Worker //===- AArch64FrameLowering.cpp - AArch64 Frame Lowering -------*- C++ -*-====//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the AArch64 implementation of TargetFrameLowering class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker // On AArch64, stack frames are structured as follows:
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker // The stack grows downward.
15*9880d681SAndroid Build Coastguard Worker //
16*9880d681SAndroid Build Coastguard Worker // All of the individual frame areas on the frame below are optional, i.e. it's
17*9880d681SAndroid Build Coastguard Worker // possible to create a function so that the particular area isn't present
18*9880d681SAndroid Build Coastguard Worker // in the frame.
19*9880d681SAndroid Build Coastguard Worker //
20*9880d681SAndroid Build Coastguard Worker // At function entry, the "frame" looks as follows:
21*9880d681SAndroid Build Coastguard Worker //
22*9880d681SAndroid Build Coastguard Worker // | | Higher address
23*9880d681SAndroid Build Coastguard Worker // |-----------------------------------|
24*9880d681SAndroid Build Coastguard Worker // | |
25*9880d681SAndroid Build Coastguard Worker // | arguments passed on the stack |
26*9880d681SAndroid Build Coastguard Worker // | |
27*9880d681SAndroid Build Coastguard Worker // |-----------------------------------| <- sp
28*9880d681SAndroid Build Coastguard Worker // | | Lower address
29*9880d681SAndroid Build Coastguard Worker //
30*9880d681SAndroid Build Coastguard Worker //
31*9880d681SAndroid Build Coastguard Worker // After the prologue has run, the frame has the following general structure.
32*9880d681SAndroid Build Coastguard Worker // Note that this doesn't depict the case where a red-zone is used. Also,
33*9880d681SAndroid Build Coastguard Worker // technically the last frame area (VLAs) doesn't get created until in the
34*9880d681SAndroid Build Coastguard Worker // main function body, after the prologue is run. However, it's depicted here
35*9880d681SAndroid Build Coastguard Worker // for completeness.
36*9880d681SAndroid Build Coastguard Worker //
37*9880d681SAndroid Build Coastguard Worker // | | Higher address
38*9880d681SAndroid Build Coastguard Worker // |-----------------------------------|
39*9880d681SAndroid Build Coastguard Worker // | |
40*9880d681SAndroid Build Coastguard Worker // | arguments passed on the stack |
41*9880d681SAndroid Build Coastguard Worker // | |
42*9880d681SAndroid Build Coastguard Worker // |-----------------------------------|
43*9880d681SAndroid Build Coastguard Worker // | |
44*9880d681SAndroid Build Coastguard Worker // | prev_fp, prev_lr |
45*9880d681SAndroid Build Coastguard Worker // | (a.k.a. "frame record") |
46*9880d681SAndroid Build Coastguard Worker // |-----------------------------------| <- fp(=x29)
47*9880d681SAndroid Build Coastguard Worker // | |
48*9880d681SAndroid Build Coastguard Worker // | other callee-saved registers |
49*9880d681SAndroid Build Coastguard Worker // | |
50*9880d681SAndroid Build Coastguard Worker // |-----------------------------------|
51*9880d681SAndroid Build Coastguard Worker // |.empty.space.to.make.part.below....|
52*9880d681SAndroid Build Coastguard Worker // |.aligned.in.case.it.needs.more.than| (size of this area is unknown at
53*9880d681SAndroid Build Coastguard Worker // |.the.standard.16-byte.alignment....| compile time; if present)
54*9880d681SAndroid Build Coastguard Worker // |-----------------------------------|
55*9880d681SAndroid Build Coastguard Worker // | |
56*9880d681SAndroid Build Coastguard Worker // | local variables of fixed size |
57*9880d681SAndroid Build Coastguard Worker // | including spill slots |
58*9880d681SAndroid Build Coastguard Worker // |-----------------------------------| <- bp(not defined by ABI,
59*9880d681SAndroid Build Coastguard Worker // |.variable-sized.local.variables....| LLVM chooses X19)
60*9880d681SAndroid Build Coastguard Worker // |.(VLAs)............................| (size of this area is unknown at
61*9880d681SAndroid Build Coastguard Worker // |...................................| compile time)
62*9880d681SAndroid Build Coastguard Worker // |-----------------------------------| <- sp
63*9880d681SAndroid Build Coastguard Worker // | | Lower address
64*9880d681SAndroid Build Coastguard Worker //
65*9880d681SAndroid Build Coastguard Worker //
66*9880d681SAndroid Build Coastguard Worker // To access the data in a frame, at-compile time, a constant offset must be
67*9880d681SAndroid Build Coastguard Worker // computable from one of the pointers (fp, bp, sp) to access it. The size
68*9880d681SAndroid Build Coastguard Worker // of the areas with a dotted background cannot be computed at compile-time
69*9880d681SAndroid Build Coastguard Worker // if they are present, making it required to have all three of fp, bp and
70*9880d681SAndroid Build Coastguard Worker // sp to be set up to be able to access all contents in the frame areas,
71*9880d681SAndroid Build Coastguard Worker // assuming all of the frame areas are non-empty.
72*9880d681SAndroid Build Coastguard Worker //
73*9880d681SAndroid Build Coastguard Worker // For most functions, some of the frame areas are empty. For those functions,
74*9880d681SAndroid Build Coastguard Worker // it may not be necessary to set up fp or bp:
75*9880d681SAndroid Build Coastguard Worker // * A base pointer is definitely needed when there are both VLAs and local
76*9880d681SAndroid Build Coastguard Worker // variables with more-than-default alignment requirements.
77*9880d681SAndroid Build Coastguard Worker // * A frame pointer is definitely needed when there are local variables with
78*9880d681SAndroid Build Coastguard Worker // more-than-default alignment requirements.
79*9880d681SAndroid Build Coastguard Worker //
80*9880d681SAndroid Build Coastguard Worker // In some cases when a base pointer is not strictly needed, it is generated
81*9880d681SAndroid Build Coastguard Worker // anyway when offsets from the frame pointer to access local variables become
82*9880d681SAndroid Build Coastguard Worker // so large that the offset can't be encoded in the immediate fields of loads
83*9880d681SAndroid Build Coastguard Worker // or stores.
84*9880d681SAndroid Build Coastguard Worker //
85*9880d681SAndroid Build Coastguard Worker // FIXME: also explain the redzone concept.
86*9880d681SAndroid Build Coastguard Worker // FIXME: also explain the concept of reserved call frames.
87*9880d681SAndroid Build Coastguard Worker //
88*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker #include "AArch64FrameLowering.h"
91*9880d681SAndroid Build Coastguard Worker #include "AArch64InstrInfo.h"
92*9880d681SAndroid Build Coastguard Worker #include "AArch64MachineFunctionInfo.h"
93*9880d681SAndroid Build Coastguard Worker #include "AArch64Subtarget.h"
94*9880d681SAndroid Build Coastguard Worker #include "AArch64TargetMachine.h"
95*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
96*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LivePhysRegs.h"
97*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
98*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
99*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
100*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfo.h"
101*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
102*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/RegisterScavenging.h"
103*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
104*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
105*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
106*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
107*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker using namespace llvm;
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "frame-info"
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> EnableRedZone("aarch64-redzone",
114*9880d681SAndroid Build Coastguard Worker cl::desc("enable use of redzone on AArch64"),
115*9880d681SAndroid Build Coastguard Worker cl::init(false), cl::Hidden);
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker STATISTIC(NumRedZoneFunctions, "Number of functions using red zone");
118*9880d681SAndroid Build Coastguard Worker
canUseRedZone(const MachineFunction & MF) const119*9880d681SAndroid Build Coastguard Worker bool AArch64FrameLowering::canUseRedZone(const MachineFunction &MF) const {
120*9880d681SAndroid Build Coastguard Worker if (!EnableRedZone)
121*9880d681SAndroid Build Coastguard Worker return false;
122*9880d681SAndroid Build Coastguard Worker // Don't use the red zone if the function explicitly asks us not to.
123*9880d681SAndroid Build Coastguard Worker // This is typically used for kernel code.
124*9880d681SAndroid Build Coastguard Worker if (MF.getFunction()->hasFnAttribute(Attribute::NoRedZone))
125*9880d681SAndroid Build Coastguard Worker return false;
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *MFI = MF.getFrameInfo();
128*9880d681SAndroid Build Coastguard Worker const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
129*9880d681SAndroid Build Coastguard Worker unsigned NumBytes = AFI->getLocalStackSize();
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker return !(MFI->hasCalls() || hasFP(MF) || NumBytes > 128);
132*9880d681SAndroid Build Coastguard Worker }
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Worker /// hasFP - Return true if the specified function should have a dedicated frame
135*9880d681SAndroid Build Coastguard Worker /// pointer register.
hasFP(const MachineFunction & MF) const136*9880d681SAndroid Build Coastguard Worker bool AArch64FrameLowering::hasFP(const MachineFunction &MF) const {
137*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *MFI = MF.getFrameInfo();
138*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
139*9880d681SAndroid Build Coastguard Worker // Retain behavior of always omitting the FP for leaf functions when possible.
140*9880d681SAndroid Build Coastguard Worker return (MFI->hasCalls() &&
141*9880d681SAndroid Build Coastguard Worker MF.getTarget().Options.DisableFramePointerElim(MF)) ||
142*9880d681SAndroid Build Coastguard Worker MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken() ||
143*9880d681SAndroid Build Coastguard Worker MFI->hasStackMap() || MFI->hasPatchPoint() ||
144*9880d681SAndroid Build Coastguard Worker RegInfo->needsStackRealignment(MF);
145*9880d681SAndroid Build Coastguard Worker }
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
148*9880d681SAndroid Build Coastguard Worker /// not required, we reserve argument space for call sites in the function
149*9880d681SAndroid Build Coastguard Worker /// immediately on entry to the current function. This eliminates the need for
150*9880d681SAndroid Build Coastguard Worker /// add/sub sp brackets around call sites. Returns true if the call frame is
151*9880d681SAndroid Build Coastguard Worker /// included as part of the stack frame.
152*9880d681SAndroid Build Coastguard Worker bool
hasReservedCallFrame(const MachineFunction & MF) const153*9880d681SAndroid Build Coastguard Worker AArch64FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
154*9880d681SAndroid Build Coastguard Worker return !MF.getFrameInfo()->hasVarSizedObjects();
155*9880d681SAndroid Build Coastguard Worker }
156*9880d681SAndroid Build Coastguard Worker
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const157*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator AArch64FrameLowering::eliminateCallFramePseudoInstr(
158*9880d681SAndroid Build Coastguard Worker MachineFunction &MF, MachineBasicBlock &MBB,
159*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I) const {
160*9880d681SAndroid Build Coastguard Worker const AArch64InstrInfo *TII =
161*9880d681SAndroid Build Coastguard Worker static_cast<const AArch64InstrInfo *>(MF.getSubtarget().getInstrInfo());
162*9880d681SAndroid Build Coastguard Worker DebugLoc DL = I->getDebugLoc();
163*9880d681SAndroid Build Coastguard Worker unsigned Opc = I->getOpcode();
164*9880d681SAndroid Build Coastguard Worker bool IsDestroy = Opc == TII->getCallFrameDestroyOpcode();
165*9880d681SAndroid Build Coastguard Worker uint64_t CalleePopAmount = IsDestroy ? I->getOperand(1).getImm() : 0;
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Worker const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
168*9880d681SAndroid Build Coastguard Worker if (!TFI->hasReservedCallFrame(MF)) {
169*9880d681SAndroid Build Coastguard Worker unsigned Align = getStackAlignment();
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker int64_t Amount = I->getOperand(0).getImm();
172*9880d681SAndroid Build Coastguard Worker Amount = alignTo(Amount, Align);
173*9880d681SAndroid Build Coastguard Worker if (!IsDestroy)
174*9880d681SAndroid Build Coastguard Worker Amount = -Amount;
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker // N.b. if CalleePopAmount is valid but zero (i.e. callee would pop, but it
177*9880d681SAndroid Build Coastguard Worker // doesn't have to pop anything), then the first operand will be zero too so
178*9880d681SAndroid Build Coastguard Worker // this adjustment is a no-op.
179*9880d681SAndroid Build Coastguard Worker if (CalleePopAmount == 0) {
180*9880d681SAndroid Build Coastguard Worker // FIXME: in-function stack adjustment for calls is limited to 24-bits
181*9880d681SAndroid Build Coastguard Worker // because there's no guaranteed temporary register available.
182*9880d681SAndroid Build Coastguard Worker //
183*9880d681SAndroid Build Coastguard Worker // ADD/SUB (immediate) has only LSL #0 and LSL #12 available.
184*9880d681SAndroid Build Coastguard Worker // 1) For offset <= 12-bit, we use LSL #0
185*9880d681SAndroid Build Coastguard Worker // 2) For 12-bit <= offset <= 24-bit, we use two instructions. One uses
186*9880d681SAndroid Build Coastguard Worker // LSL #0, and the other uses LSL #12.
187*9880d681SAndroid Build Coastguard Worker //
188*9880d681SAndroid Build Coastguard Worker // Most call frames will be allocated at the start of a function so
189*9880d681SAndroid Build Coastguard Worker // this is OK, but it is a limitation that needs dealing with.
190*9880d681SAndroid Build Coastguard Worker assert(Amount > -0xffffff && Amount < 0xffffff && "call frame too large");
191*9880d681SAndroid Build Coastguard Worker emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP, Amount, TII);
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker } else if (CalleePopAmount != 0) {
194*9880d681SAndroid Build Coastguard Worker // If the calling convention demands that the callee pops arguments from the
195*9880d681SAndroid Build Coastguard Worker // stack, we want to add it back if we have a reserved call frame.
196*9880d681SAndroid Build Coastguard Worker assert(CalleePopAmount < 0xffffff && "call frame too large");
197*9880d681SAndroid Build Coastguard Worker emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP, -CalleePopAmount,
198*9880d681SAndroid Build Coastguard Worker TII);
199*9880d681SAndroid Build Coastguard Worker }
200*9880d681SAndroid Build Coastguard Worker return MBB.erase(I);
201*9880d681SAndroid Build Coastguard Worker }
202*9880d681SAndroid Build Coastguard Worker
emitCalleeSavedFrameMoves(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI) const203*9880d681SAndroid Build Coastguard Worker void AArch64FrameLowering::emitCalleeSavedFrameMoves(
204*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const {
205*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = *MBB.getParent();
206*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF.getFrameInfo();
207*9880d681SAndroid Build Coastguard Worker MachineModuleInfo &MMI = MF.getMMI();
208*9880d681SAndroid Build Coastguard Worker const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
209*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
210*9880d681SAndroid Build Coastguard Worker DebugLoc DL = MBB.findDebugLoc(MBBI);
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker // Add callee saved registers to move list.
213*9880d681SAndroid Build Coastguard Worker const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
214*9880d681SAndroid Build Coastguard Worker if (CSI.empty())
215*9880d681SAndroid Build Coastguard Worker return;
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Worker for (const auto &Info : CSI) {
218*9880d681SAndroid Build Coastguard Worker unsigned Reg = Info.getReg();
219*9880d681SAndroid Build Coastguard Worker int64_t Offset =
220*9880d681SAndroid Build Coastguard Worker MFI->getObjectOffset(Info.getFrameIdx()) - getOffsetOfLocalArea();
221*9880d681SAndroid Build Coastguard Worker unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
222*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(
223*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createOffset(nullptr, DwarfReg, Offset));
224*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
225*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex)
226*9880d681SAndroid Build Coastguard Worker .setMIFlags(MachineInstr::FrameSetup);
227*9880d681SAndroid Build Coastguard Worker }
228*9880d681SAndroid Build Coastguard Worker }
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Worker // Find a scratch register that we can use at the start of the prologue to
231*9880d681SAndroid Build Coastguard Worker // re-align the stack pointer. We avoid using callee-save registers since they
232*9880d681SAndroid Build Coastguard Worker // may appear to be free when this is called from canUseAsPrologue (during
233*9880d681SAndroid Build Coastguard Worker // shrink wrapping), but then no longer be free when this is called from
234*9880d681SAndroid Build Coastguard Worker // emitPrologue.
235*9880d681SAndroid Build Coastguard Worker //
236*9880d681SAndroid Build Coastguard Worker // FIXME: This is a bit conservative, since in the above case we could use one
237*9880d681SAndroid Build Coastguard Worker // of the callee-save registers as a scratch temp to re-align the stack pointer,
238*9880d681SAndroid Build Coastguard Worker // but we would then have to make sure that we were in fact saving at least one
239*9880d681SAndroid Build Coastguard Worker // callee-save register in the prologue, which is additional complexity that
240*9880d681SAndroid Build Coastguard Worker // doesn't seem worth the benefit.
findScratchNonCalleeSaveRegister(MachineBasicBlock * MBB)241*9880d681SAndroid Build Coastguard Worker static unsigned findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB) {
242*9880d681SAndroid Build Coastguard Worker MachineFunction *MF = MBB->getParent();
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Worker // If MBB is an entry block, use X9 as the scratch register
245*9880d681SAndroid Build Coastguard Worker if (&MF->front() == MBB)
246*9880d681SAndroid Build Coastguard Worker return AArch64::X9;
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
249*9880d681SAndroid Build Coastguard Worker LivePhysRegs LiveRegs(&TRI);
250*9880d681SAndroid Build Coastguard Worker LiveRegs.addLiveIns(*MBB);
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker // Mark callee saved registers as used so we will not choose them.
253*9880d681SAndroid Build Coastguard Worker const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>();
254*9880d681SAndroid Build Coastguard Worker const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
255*9880d681SAndroid Build Coastguard Worker const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(MF);
256*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; CSRegs[i]; ++i)
257*9880d681SAndroid Build Coastguard Worker LiveRegs.addReg(CSRegs[i]);
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker // Prefer X9 since it was historically used for the prologue scratch reg.
260*9880d681SAndroid Build Coastguard Worker const MachineRegisterInfo &MRI = MF->getRegInfo();
261*9880d681SAndroid Build Coastguard Worker if (LiveRegs.available(MRI, AArch64::X9))
262*9880d681SAndroid Build Coastguard Worker return AArch64::X9;
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Worker for (unsigned Reg : AArch64::GPR64RegClass) {
265*9880d681SAndroid Build Coastguard Worker if (LiveRegs.available(MRI, Reg))
266*9880d681SAndroid Build Coastguard Worker return Reg;
267*9880d681SAndroid Build Coastguard Worker }
268*9880d681SAndroid Build Coastguard Worker return AArch64::NoRegister;
269*9880d681SAndroid Build Coastguard Worker }
270*9880d681SAndroid Build Coastguard Worker
canUseAsPrologue(const MachineBasicBlock & MBB) const271*9880d681SAndroid Build Coastguard Worker bool AArch64FrameLowering::canUseAsPrologue(
272*9880d681SAndroid Build Coastguard Worker const MachineBasicBlock &MBB) const {
273*9880d681SAndroid Build Coastguard Worker const MachineFunction *MF = MBB.getParent();
274*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
275*9880d681SAndroid Build Coastguard Worker const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>();
276*9880d681SAndroid Build Coastguard Worker const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker // Don't need a scratch register if we're not going to re-align the stack.
279*9880d681SAndroid Build Coastguard Worker if (!RegInfo->needsStackRealignment(*MF))
280*9880d681SAndroid Build Coastguard Worker return true;
281*9880d681SAndroid Build Coastguard Worker // Otherwise, we can use any block as long as it has a scratch register
282*9880d681SAndroid Build Coastguard Worker // available.
283*9880d681SAndroid Build Coastguard Worker return findScratchNonCalleeSaveRegister(TmpMBB) != AArch64::NoRegister;
284*9880d681SAndroid Build Coastguard Worker }
285*9880d681SAndroid Build Coastguard Worker
shouldCombineCSRLocalStackBump(MachineFunction & MF,unsigned StackBumpBytes) const286*9880d681SAndroid Build Coastguard Worker bool AArch64FrameLowering::shouldCombineCSRLocalStackBump(
287*9880d681SAndroid Build Coastguard Worker MachineFunction &MF, unsigned StackBumpBytes) const {
288*9880d681SAndroid Build Coastguard Worker AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
289*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *MFI = MF.getFrameInfo();
290*9880d681SAndroid Build Coastguard Worker const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
291*9880d681SAndroid Build Coastguard Worker const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker if (AFI->getLocalStackSize() == 0)
294*9880d681SAndroid Build Coastguard Worker return false;
295*9880d681SAndroid Build Coastguard Worker
296*9880d681SAndroid Build Coastguard Worker // 512 is the maximum immediate for stp/ldp that will be used for
297*9880d681SAndroid Build Coastguard Worker // callee-save save/restores
298*9880d681SAndroid Build Coastguard Worker if (StackBumpBytes >= 512)
299*9880d681SAndroid Build Coastguard Worker return false;
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker if (MFI->hasVarSizedObjects())
302*9880d681SAndroid Build Coastguard Worker return false;
303*9880d681SAndroid Build Coastguard Worker
304*9880d681SAndroid Build Coastguard Worker if (RegInfo->needsStackRealignment(MF))
305*9880d681SAndroid Build Coastguard Worker return false;
306*9880d681SAndroid Build Coastguard Worker
307*9880d681SAndroid Build Coastguard Worker // This isn't strictly necessary, but it simplifies things a bit since the
308*9880d681SAndroid Build Coastguard Worker // current RedZone handling code assumes the SP is adjusted by the
309*9880d681SAndroid Build Coastguard Worker // callee-save save/restore code.
310*9880d681SAndroid Build Coastguard Worker if (canUseRedZone(MF))
311*9880d681SAndroid Build Coastguard Worker return false;
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker return true;
314*9880d681SAndroid Build Coastguard Worker }
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker // Convert callee-save register save/restore instruction to do stack pointer
317*9880d681SAndroid Build Coastguard Worker // decrement/increment to allocate/deallocate the callee-save stack area by
318*9880d681SAndroid Build Coastguard Worker // converting store/load to use pre/post increment version.
convertCalleeSaveRestoreToSPPrePostIncDec(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,const DebugLoc & DL,const TargetInstrInfo * TII,int CSStackSizeInc)319*9880d681SAndroid Build Coastguard Worker static MachineBasicBlock::iterator convertCalleeSaveRestoreToSPPrePostIncDec(
320*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
321*9880d681SAndroid Build Coastguard Worker const DebugLoc &DL, const TargetInstrInfo *TII, int CSStackSizeInc) {
322*9880d681SAndroid Build Coastguard Worker
323*9880d681SAndroid Build Coastguard Worker unsigned NewOpc;
324*9880d681SAndroid Build Coastguard Worker bool NewIsUnscaled = false;
325*9880d681SAndroid Build Coastguard Worker switch (MBBI->getOpcode()) {
326*9880d681SAndroid Build Coastguard Worker default:
327*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unexpected callee-save save/restore opcode!");
328*9880d681SAndroid Build Coastguard Worker case AArch64::STPXi:
329*9880d681SAndroid Build Coastguard Worker NewOpc = AArch64::STPXpre;
330*9880d681SAndroid Build Coastguard Worker break;
331*9880d681SAndroid Build Coastguard Worker case AArch64::STPDi:
332*9880d681SAndroid Build Coastguard Worker NewOpc = AArch64::STPDpre;
333*9880d681SAndroid Build Coastguard Worker break;
334*9880d681SAndroid Build Coastguard Worker case AArch64::STRXui:
335*9880d681SAndroid Build Coastguard Worker NewOpc = AArch64::STRXpre;
336*9880d681SAndroid Build Coastguard Worker NewIsUnscaled = true;
337*9880d681SAndroid Build Coastguard Worker break;
338*9880d681SAndroid Build Coastguard Worker case AArch64::STRDui:
339*9880d681SAndroid Build Coastguard Worker NewOpc = AArch64::STRDpre;
340*9880d681SAndroid Build Coastguard Worker NewIsUnscaled = true;
341*9880d681SAndroid Build Coastguard Worker break;
342*9880d681SAndroid Build Coastguard Worker case AArch64::LDPXi:
343*9880d681SAndroid Build Coastguard Worker NewOpc = AArch64::LDPXpost;
344*9880d681SAndroid Build Coastguard Worker break;
345*9880d681SAndroid Build Coastguard Worker case AArch64::LDPDi:
346*9880d681SAndroid Build Coastguard Worker NewOpc = AArch64::LDPDpost;
347*9880d681SAndroid Build Coastguard Worker break;
348*9880d681SAndroid Build Coastguard Worker case AArch64::LDRXui:
349*9880d681SAndroid Build Coastguard Worker NewOpc = AArch64::LDRXpost;
350*9880d681SAndroid Build Coastguard Worker NewIsUnscaled = true;
351*9880d681SAndroid Build Coastguard Worker break;
352*9880d681SAndroid Build Coastguard Worker case AArch64::LDRDui:
353*9880d681SAndroid Build Coastguard Worker NewOpc = AArch64::LDRDpost;
354*9880d681SAndroid Build Coastguard Worker NewIsUnscaled = true;
355*9880d681SAndroid Build Coastguard Worker break;
356*9880d681SAndroid Build Coastguard Worker }
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc));
359*9880d681SAndroid Build Coastguard Worker MIB.addReg(AArch64::SP, RegState::Define);
360*9880d681SAndroid Build Coastguard Worker
361*9880d681SAndroid Build Coastguard Worker // Copy all operands other than the immediate offset.
362*9880d681SAndroid Build Coastguard Worker unsigned OpndIdx = 0;
363*9880d681SAndroid Build Coastguard Worker for (unsigned OpndEnd = MBBI->getNumOperands() - 1; OpndIdx < OpndEnd;
364*9880d681SAndroid Build Coastguard Worker ++OpndIdx)
365*9880d681SAndroid Build Coastguard Worker MIB.addOperand(MBBI->getOperand(OpndIdx));
366*9880d681SAndroid Build Coastguard Worker
367*9880d681SAndroid Build Coastguard Worker assert(MBBI->getOperand(OpndIdx).getImm() == 0 &&
368*9880d681SAndroid Build Coastguard Worker "Unexpected immediate offset in first/last callee-save save/restore "
369*9880d681SAndroid Build Coastguard Worker "instruction!");
370*9880d681SAndroid Build Coastguard Worker assert(MBBI->getOperand(OpndIdx - 1).getReg() == AArch64::SP &&
371*9880d681SAndroid Build Coastguard Worker "Unexpected base register in callee-save save/restore instruction!");
372*9880d681SAndroid Build Coastguard Worker // Last operand is immediate offset that needs fixing.
373*9880d681SAndroid Build Coastguard Worker assert(CSStackSizeInc % 8 == 0);
374*9880d681SAndroid Build Coastguard Worker int64_t CSStackSizeIncImm = CSStackSizeInc;
375*9880d681SAndroid Build Coastguard Worker if (!NewIsUnscaled)
376*9880d681SAndroid Build Coastguard Worker CSStackSizeIncImm /= 8;
377*9880d681SAndroid Build Coastguard Worker MIB.addImm(CSStackSizeIncImm);
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Worker MIB.setMIFlags(MBBI->getFlags());
380*9880d681SAndroid Build Coastguard Worker MIB.setMemRefs(MBBI->memoperands_begin(), MBBI->memoperands_end());
381*9880d681SAndroid Build Coastguard Worker
382*9880d681SAndroid Build Coastguard Worker return std::prev(MBB.erase(MBBI));
383*9880d681SAndroid Build Coastguard Worker }
384*9880d681SAndroid Build Coastguard Worker
385*9880d681SAndroid Build Coastguard Worker // Fixup callee-save register save/restore instructions to take into account
386*9880d681SAndroid Build Coastguard Worker // combined SP bump by adding the local stack size to the stack offsets.
fixupCalleeSaveRestoreStackOffset(MachineInstr & MI,unsigned LocalStackSize)387*9880d681SAndroid Build Coastguard Worker static void fixupCalleeSaveRestoreStackOffset(MachineInstr &MI,
388*9880d681SAndroid Build Coastguard Worker unsigned LocalStackSize) {
389*9880d681SAndroid Build Coastguard Worker unsigned Opc = MI.getOpcode();
390*9880d681SAndroid Build Coastguard Worker (void)Opc;
391*9880d681SAndroid Build Coastguard Worker assert((Opc == AArch64::STPXi || Opc == AArch64::STPDi ||
392*9880d681SAndroid Build Coastguard Worker Opc == AArch64::STRXui || Opc == AArch64::STRDui ||
393*9880d681SAndroid Build Coastguard Worker Opc == AArch64::LDPXi || Opc == AArch64::LDPDi ||
394*9880d681SAndroid Build Coastguard Worker Opc == AArch64::LDRXui || Opc == AArch64::LDRDui) &&
395*9880d681SAndroid Build Coastguard Worker "Unexpected callee-save save/restore opcode!");
396*9880d681SAndroid Build Coastguard Worker
397*9880d681SAndroid Build Coastguard Worker unsigned OffsetIdx = MI.getNumExplicitOperands() - 1;
398*9880d681SAndroid Build Coastguard Worker assert(MI.getOperand(OffsetIdx - 1).getReg() == AArch64::SP &&
399*9880d681SAndroid Build Coastguard Worker "Unexpected base register in callee-save save/restore instruction!");
400*9880d681SAndroid Build Coastguard Worker // Last operand is immediate offset that needs fixing.
401*9880d681SAndroid Build Coastguard Worker MachineOperand &OffsetOpnd = MI.getOperand(OffsetIdx);
402*9880d681SAndroid Build Coastguard Worker // All generated opcodes have scaled offsets.
403*9880d681SAndroid Build Coastguard Worker assert(LocalStackSize % 8 == 0);
404*9880d681SAndroid Build Coastguard Worker OffsetOpnd.setImm(OffsetOpnd.getImm() + LocalStackSize / 8);
405*9880d681SAndroid Build Coastguard Worker }
406*9880d681SAndroid Build Coastguard Worker
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const407*9880d681SAndroid Build Coastguard Worker void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
408*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB) const {
409*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI = MBB.begin();
410*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *MFI = MF.getFrameInfo();
411*9880d681SAndroid Build Coastguard Worker const Function *Fn = MF.getFunction();
412*9880d681SAndroid Build Coastguard Worker const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
413*9880d681SAndroid Build Coastguard Worker const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
414*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII = Subtarget.getInstrInfo();
415*9880d681SAndroid Build Coastguard Worker MachineModuleInfo &MMI = MF.getMMI();
416*9880d681SAndroid Build Coastguard Worker AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
417*9880d681SAndroid Build Coastguard Worker bool needsFrameMoves = MMI.hasDebugInfo() || Fn->needsUnwindTableEntry();
418*9880d681SAndroid Build Coastguard Worker bool HasFP = hasFP(MF);
419*9880d681SAndroid Build Coastguard Worker
420*9880d681SAndroid Build Coastguard Worker // Debug location must be unknown since the first debug location is used
421*9880d681SAndroid Build Coastguard Worker // to determine the end of the prologue.
422*9880d681SAndroid Build Coastguard Worker DebugLoc DL;
423*9880d681SAndroid Build Coastguard Worker
424*9880d681SAndroid Build Coastguard Worker // All calls are tail calls in GHC calling conv, and functions have no
425*9880d681SAndroid Build Coastguard Worker // prologue/epilogue.
426*9880d681SAndroid Build Coastguard Worker if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
427*9880d681SAndroid Build Coastguard Worker return;
428*9880d681SAndroid Build Coastguard Worker
429*9880d681SAndroid Build Coastguard Worker int NumBytes = (int)MFI->getStackSize();
430*9880d681SAndroid Build Coastguard Worker if (!AFI->hasStackFrame()) {
431*9880d681SAndroid Build Coastguard Worker assert(!HasFP && "unexpected function without stack frame but with FP");
432*9880d681SAndroid Build Coastguard Worker
433*9880d681SAndroid Build Coastguard Worker // All of the stack allocation is for locals.
434*9880d681SAndroid Build Coastguard Worker AFI->setLocalStackSize(NumBytes);
435*9880d681SAndroid Build Coastguard Worker
436*9880d681SAndroid Build Coastguard Worker if (!NumBytes)
437*9880d681SAndroid Build Coastguard Worker return;
438*9880d681SAndroid Build Coastguard Worker // REDZONE: If the stack size is less than 128 bytes, we don't need
439*9880d681SAndroid Build Coastguard Worker // to actually allocate.
440*9880d681SAndroid Build Coastguard Worker if (canUseRedZone(MF))
441*9880d681SAndroid Build Coastguard Worker ++NumRedZoneFunctions;
442*9880d681SAndroid Build Coastguard Worker else {
443*9880d681SAndroid Build Coastguard Worker emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP, -NumBytes, TII,
444*9880d681SAndroid Build Coastguard Worker MachineInstr::FrameSetup);
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Worker // Label used to tie together the PROLOG_LABEL and the MachineMoves.
447*9880d681SAndroid Build Coastguard Worker MCSymbol *FrameLabel = MMI.getContext().createTempSymbol();
448*9880d681SAndroid Build Coastguard Worker // Encode the stack size of the leaf function.
449*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(
450*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createDefCfaOffset(FrameLabel, -NumBytes));
451*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
452*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex)
453*9880d681SAndroid Build Coastguard Worker .setMIFlags(MachineInstr::FrameSetup);
454*9880d681SAndroid Build Coastguard Worker }
455*9880d681SAndroid Build Coastguard Worker return;
456*9880d681SAndroid Build Coastguard Worker }
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker auto CSStackSize = AFI->getCalleeSavedStackSize();
459*9880d681SAndroid Build Coastguard Worker // All of the remaining stack allocations are for locals.
460*9880d681SAndroid Build Coastguard Worker AFI->setLocalStackSize(NumBytes - CSStackSize);
461*9880d681SAndroid Build Coastguard Worker
462*9880d681SAndroid Build Coastguard Worker bool CombineSPBump = shouldCombineCSRLocalStackBump(MF, NumBytes);
463*9880d681SAndroid Build Coastguard Worker if (CombineSPBump) {
464*9880d681SAndroid Build Coastguard Worker emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP, -NumBytes, TII,
465*9880d681SAndroid Build Coastguard Worker MachineInstr::FrameSetup);
466*9880d681SAndroid Build Coastguard Worker NumBytes = 0;
467*9880d681SAndroid Build Coastguard Worker } else if (CSStackSize != 0) {
468*9880d681SAndroid Build Coastguard Worker MBBI = convertCalleeSaveRestoreToSPPrePostIncDec(MBB, MBBI, DL, TII,
469*9880d681SAndroid Build Coastguard Worker -CSStackSize);
470*9880d681SAndroid Build Coastguard Worker NumBytes -= CSStackSize;
471*9880d681SAndroid Build Coastguard Worker }
472*9880d681SAndroid Build Coastguard Worker assert(NumBytes >= 0 && "Negative stack allocation size!?");
473*9880d681SAndroid Build Coastguard Worker
474*9880d681SAndroid Build Coastguard Worker // Move past the saves of the callee-saved registers, fixing up the offsets
475*9880d681SAndroid Build Coastguard Worker // and pre-inc if we decided to combine the callee-save and local stack
476*9880d681SAndroid Build Coastguard Worker // pointer bump above.
477*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator End = MBB.end();
478*9880d681SAndroid Build Coastguard Worker while (MBBI != End && MBBI->getFlag(MachineInstr::FrameSetup)) {
479*9880d681SAndroid Build Coastguard Worker if (CombineSPBump)
480*9880d681SAndroid Build Coastguard Worker fixupCalleeSaveRestoreStackOffset(*MBBI, AFI->getLocalStackSize());
481*9880d681SAndroid Build Coastguard Worker ++MBBI;
482*9880d681SAndroid Build Coastguard Worker }
483*9880d681SAndroid Build Coastguard Worker if (HasFP) {
484*9880d681SAndroid Build Coastguard Worker // Only set up FP if we actually need to. Frame pointer is fp = sp - 16.
485*9880d681SAndroid Build Coastguard Worker int FPOffset = CSStackSize - 16;
486*9880d681SAndroid Build Coastguard Worker if (CombineSPBump)
487*9880d681SAndroid Build Coastguard Worker FPOffset += AFI->getLocalStackSize();
488*9880d681SAndroid Build Coastguard Worker
489*9880d681SAndroid Build Coastguard Worker // Issue sub fp, sp, FPOffset or
490*9880d681SAndroid Build Coastguard Worker // mov fp,sp when FPOffset is zero.
491*9880d681SAndroid Build Coastguard Worker // Note: All stores of callee-saved registers are marked as "FrameSetup".
492*9880d681SAndroid Build Coastguard Worker // This code marks the instruction(s) that set the FP also.
493*9880d681SAndroid Build Coastguard Worker emitFrameOffset(MBB, MBBI, DL, AArch64::FP, AArch64::SP, FPOffset, TII,
494*9880d681SAndroid Build Coastguard Worker MachineInstr::FrameSetup);
495*9880d681SAndroid Build Coastguard Worker }
496*9880d681SAndroid Build Coastguard Worker
497*9880d681SAndroid Build Coastguard Worker // Allocate space for the rest of the frame.
498*9880d681SAndroid Build Coastguard Worker if (NumBytes) {
499*9880d681SAndroid Build Coastguard Worker const bool NeedsRealignment = RegInfo->needsStackRealignment(MF);
500*9880d681SAndroid Build Coastguard Worker unsigned scratchSPReg = AArch64::SP;
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Worker if (NeedsRealignment) {
503*9880d681SAndroid Build Coastguard Worker scratchSPReg = findScratchNonCalleeSaveRegister(&MBB);
504*9880d681SAndroid Build Coastguard Worker assert(scratchSPReg != AArch64::NoRegister);
505*9880d681SAndroid Build Coastguard Worker }
506*9880d681SAndroid Build Coastguard Worker
507*9880d681SAndroid Build Coastguard Worker // If we're a leaf function, try using the red zone.
508*9880d681SAndroid Build Coastguard Worker if (!canUseRedZone(MF))
509*9880d681SAndroid Build Coastguard Worker // FIXME: in the case of dynamic re-alignment, NumBytes doesn't have
510*9880d681SAndroid Build Coastguard Worker // the correct value here, as NumBytes also includes padding bytes,
511*9880d681SAndroid Build Coastguard Worker // which shouldn't be counted here.
512*9880d681SAndroid Build Coastguard Worker emitFrameOffset(MBB, MBBI, DL, scratchSPReg, AArch64::SP, -NumBytes, TII,
513*9880d681SAndroid Build Coastguard Worker MachineInstr::FrameSetup);
514*9880d681SAndroid Build Coastguard Worker
515*9880d681SAndroid Build Coastguard Worker if (NeedsRealignment) {
516*9880d681SAndroid Build Coastguard Worker const unsigned Alignment = MFI->getMaxAlignment();
517*9880d681SAndroid Build Coastguard Worker const unsigned NrBitsToZero = countTrailingZeros(Alignment);
518*9880d681SAndroid Build Coastguard Worker assert(NrBitsToZero > 1);
519*9880d681SAndroid Build Coastguard Worker assert(scratchSPReg != AArch64::SP);
520*9880d681SAndroid Build Coastguard Worker
521*9880d681SAndroid Build Coastguard Worker // SUB X9, SP, NumBytes
522*9880d681SAndroid Build Coastguard Worker // -- X9 is temporary register, so shouldn't contain any live data here,
523*9880d681SAndroid Build Coastguard Worker // -- free to use. This is already produced by emitFrameOffset above.
524*9880d681SAndroid Build Coastguard Worker // AND SP, X9, 0b11111...0000
525*9880d681SAndroid Build Coastguard Worker // The logical immediates have a non-trivial encoding. The following
526*9880d681SAndroid Build Coastguard Worker // formula computes the encoded immediate with all ones but
527*9880d681SAndroid Build Coastguard Worker // NrBitsToZero zero bits as least significant bits.
528*9880d681SAndroid Build Coastguard Worker uint32_t andMaskEncoded = (1 << 12) // = N
529*9880d681SAndroid Build Coastguard Worker | ((64 - NrBitsToZero) << 6) // immr
530*9880d681SAndroid Build Coastguard Worker | ((64 - NrBitsToZero - 1) << 0); // imms
531*9880d681SAndroid Build Coastguard Worker
532*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, TII->get(AArch64::ANDXri), AArch64::SP)
533*9880d681SAndroid Build Coastguard Worker .addReg(scratchSPReg, RegState::Kill)
534*9880d681SAndroid Build Coastguard Worker .addImm(andMaskEncoded);
535*9880d681SAndroid Build Coastguard Worker AFI->setStackRealigned(true);
536*9880d681SAndroid Build Coastguard Worker }
537*9880d681SAndroid Build Coastguard Worker }
538*9880d681SAndroid Build Coastguard Worker
539*9880d681SAndroid Build Coastguard Worker // If we need a base pointer, set it up here. It's whatever the value of the
540*9880d681SAndroid Build Coastguard Worker // stack pointer is at this point. Any variable size objects will be allocated
541*9880d681SAndroid Build Coastguard Worker // after this, so we can still use the base pointer to reference locals.
542*9880d681SAndroid Build Coastguard Worker //
543*9880d681SAndroid Build Coastguard Worker // FIXME: Clarify FrameSetup flags here.
544*9880d681SAndroid Build Coastguard Worker // Note: Use emitFrameOffset() like above for FP if the FrameSetup flag is
545*9880d681SAndroid Build Coastguard Worker // needed.
546*9880d681SAndroid Build Coastguard Worker if (RegInfo->hasBasePointer(MF)) {
547*9880d681SAndroid Build Coastguard Worker TII->copyPhysReg(MBB, MBBI, DL, RegInfo->getBaseRegister(), AArch64::SP,
548*9880d681SAndroid Build Coastguard Worker false);
549*9880d681SAndroid Build Coastguard Worker }
550*9880d681SAndroid Build Coastguard Worker
551*9880d681SAndroid Build Coastguard Worker if (needsFrameMoves) {
552*9880d681SAndroid Build Coastguard Worker const DataLayout &TD = MF.getDataLayout();
553*9880d681SAndroid Build Coastguard Worker const int StackGrowth = -TD.getPointerSize(0);
554*9880d681SAndroid Build Coastguard Worker unsigned FramePtr = RegInfo->getFrameRegister(MF);
555*9880d681SAndroid Build Coastguard Worker // An example of the prologue:
556*9880d681SAndroid Build Coastguard Worker //
557*9880d681SAndroid Build Coastguard Worker // .globl __foo
558*9880d681SAndroid Build Coastguard Worker // .align 2
559*9880d681SAndroid Build Coastguard Worker // __foo:
560*9880d681SAndroid Build Coastguard Worker // Ltmp0:
561*9880d681SAndroid Build Coastguard Worker // .cfi_startproc
562*9880d681SAndroid Build Coastguard Worker // .cfi_personality 155, ___gxx_personality_v0
563*9880d681SAndroid Build Coastguard Worker // Leh_func_begin:
564*9880d681SAndroid Build Coastguard Worker // .cfi_lsda 16, Lexception33
565*9880d681SAndroid Build Coastguard Worker //
566*9880d681SAndroid Build Coastguard Worker // stp xa,bx, [sp, -#offset]!
567*9880d681SAndroid Build Coastguard Worker // ...
568*9880d681SAndroid Build Coastguard Worker // stp x28, x27, [sp, #offset-32]
569*9880d681SAndroid Build Coastguard Worker // stp fp, lr, [sp, #offset-16]
570*9880d681SAndroid Build Coastguard Worker // add fp, sp, #offset - 16
571*9880d681SAndroid Build Coastguard Worker // sub sp, sp, #1360
572*9880d681SAndroid Build Coastguard Worker //
573*9880d681SAndroid Build Coastguard Worker // The Stack:
574*9880d681SAndroid Build Coastguard Worker // +-------------------------------------------+
575*9880d681SAndroid Build Coastguard Worker // 10000 | ........ | ........ | ........ | ........ |
576*9880d681SAndroid Build Coastguard Worker // 10004 | ........ | ........ | ........ | ........ |
577*9880d681SAndroid Build Coastguard Worker // +-------------------------------------------+
578*9880d681SAndroid Build Coastguard Worker // 10008 | ........ | ........ | ........ | ........ |
579*9880d681SAndroid Build Coastguard Worker // 1000c | ........ | ........ | ........ | ........ |
580*9880d681SAndroid Build Coastguard Worker // +===========================================+
581*9880d681SAndroid Build Coastguard Worker // 10010 | X28 Register |
582*9880d681SAndroid Build Coastguard Worker // 10014 | X28 Register |
583*9880d681SAndroid Build Coastguard Worker // +-------------------------------------------+
584*9880d681SAndroid Build Coastguard Worker // 10018 | X27 Register |
585*9880d681SAndroid Build Coastguard Worker // 1001c | X27 Register |
586*9880d681SAndroid Build Coastguard Worker // +===========================================+
587*9880d681SAndroid Build Coastguard Worker // 10020 | Frame Pointer |
588*9880d681SAndroid Build Coastguard Worker // 10024 | Frame Pointer |
589*9880d681SAndroid Build Coastguard Worker // +-------------------------------------------+
590*9880d681SAndroid Build Coastguard Worker // 10028 | Link Register |
591*9880d681SAndroid Build Coastguard Worker // 1002c | Link Register |
592*9880d681SAndroid Build Coastguard Worker // +===========================================+
593*9880d681SAndroid Build Coastguard Worker // 10030 | ........ | ........ | ........ | ........ |
594*9880d681SAndroid Build Coastguard Worker // 10034 | ........ | ........ | ........ | ........ |
595*9880d681SAndroid Build Coastguard Worker // +-------------------------------------------+
596*9880d681SAndroid Build Coastguard Worker // 10038 | ........ | ........ | ........ | ........ |
597*9880d681SAndroid Build Coastguard Worker // 1003c | ........ | ........ | ........ | ........ |
598*9880d681SAndroid Build Coastguard Worker // +-------------------------------------------+
599*9880d681SAndroid Build Coastguard Worker //
600*9880d681SAndroid Build Coastguard Worker // [sp] = 10030 :: >>initial value<<
601*9880d681SAndroid Build Coastguard Worker // sp = 10020 :: stp fp, lr, [sp, #-16]!
602*9880d681SAndroid Build Coastguard Worker // fp = sp == 10020 :: mov fp, sp
603*9880d681SAndroid Build Coastguard Worker // [sp] == 10020 :: stp x28, x27, [sp, #-16]!
604*9880d681SAndroid Build Coastguard Worker // sp == 10010 :: >>final value<<
605*9880d681SAndroid Build Coastguard Worker //
606*9880d681SAndroid Build Coastguard Worker // The frame pointer (w29) points to address 10020. If we use an offset of
607*9880d681SAndroid Build Coastguard Worker // '16' from 'w29', we get the CFI offsets of -8 for w30, -16 for w29, -24
608*9880d681SAndroid Build Coastguard Worker // for w27, and -32 for w28:
609*9880d681SAndroid Build Coastguard Worker //
610*9880d681SAndroid Build Coastguard Worker // Ltmp1:
611*9880d681SAndroid Build Coastguard Worker // .cfi_def_cfa w29, 16
612*9880d681SAndroid Build Coastguard Worker // Ltmp2:
613*9880d681SAndroid Build Coastguard Worker // .cfi_offset w30, -8
614*9880d681SAndroid Build Coastguard Worker // Ltmp3:
615*9880d681SAndroid Build Coastguard Worker // .cfi_offset w29, -16
616*9880d681SAndroid Build Coastguard Worker // Ltmp4:
617*9880d681SAndroid Build Coastguard Worker // .cfi_offset w27, -24
618*9880d681SAndroid Build Coastguard Worker // Ltmp5:
619*9880d681SAndroid Build Coastguard Worker // .cfi_offset w28, -32
620*9880d681SAndroid Build Coastguard Worker
621*9880d681SAndroid Build Coastguard Worker if (HasFP) {
622*9880d681SAndroid Build Coastguard Worker // Define the current CFA rule to use the provided FP.
623*9880d681SAndroid Build Coastguard Worker unsigned Reg = RegInfo->getDwarfRegNum(FramePtr, true);
624*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(
625*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createDefCfa(nullptr, Reg, 2 * StackGrowth));
626*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
627*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex)
628*9880d681SAndroid Build Coastguard Worker .setMIFlags(MachineInstr::FrameSetup);
629*9880d681SAndroid Build Coastguard Worker } else {
630*9880d681SAndroid Build Coastguard Worker // Encode the stack size of the leaf function.
631*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(
632*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createDefCfaOffset(nullptr, -MFI->getStackSize()));
633*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
634*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex)
635*9880d681SAndroid Build Coastguard Worker .setMIFlags(MachineInstr::FrameSetup);
636*9880d681SAndroid Build Coastguard Worker }
637*9880d681SAndroid Build Coastguard Worker
638*9880d681SAndroid Build Coastguard Worker // Now emit the moves for whatever callee saved regs we have (including FP,
639*9880d681SAndroid Build Coastguard Worker // LR if those are saved).
640*9880d681SAndroid Build Coastguard Worker emitCalleeSavedFrameMoves(MBB, MBBI);
641*9880d681SAndroid Build Coastguard Worker }
642*9880d681SAndroid Build Coastguard Worker }
643*9880d681SAndroid Build Coastguard Worker
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const644*9880d681SAndroid Build Coastguard Worker void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
645*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB) const {
646*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
647*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF.getFrameInfo();
648*9880d681SAndroid Build Coastguard Worker const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
649*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII = Subtarget.getInstrInfo();
650*9880d681SAndroid Build Coastguard Worker DebugLoc DL;
651*9880d681SAndroid Build Coastguard Worker bool IsTailCallReturn = false;
652*9880d681SAndroid Build Coastguard Worker if (MBB.end() != MBBI) {
653*9880d681SAndroid Build Coastguard Worker DL = MBBI->getDebugLoc();
654*9880d681SAndroid Build Coastguard Worker unsigned RetOpcode = MBBI->getOpcode();
655*9880d681SAndroid Build Coastguard Worker IsTailCallReturn = RetOpcode == AArch64::TCRETURNdi ||
656*9880d681SAndroid Build Coastguard Worker RetOpcode == AArch64::TCRETURNri;
657*9880d681SAndroid Build Coastguard Worker }
658*9880d681SAndroid Build Coastguard Worker int NumBytes = MFI->getStackSize();
659*9880d681SAndroid Build Coastguard Worker const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
660*9880d681SAndroid Build Coastguard Worker
661*9880d681SAndroid Build Coastguard Worker // All calls are tail calls in GHC calling conv, and functions have no
662*9880d681SAndroid Build Coastguard Worker // prologue/epilogue.
663*9880d681SAndroid Build Coastguard Worker if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
664*9880d681SAndroid Build Coastguard Worker return;
665*9880d681SAndroid Build Coastguard Worker
666*9880d681SAndroid Build Coastguard Worker // Initial and residual are named for consistency with the prologue. Note that
667*9880d681SAndroid Build Coastguard Worker // in the epilogue, the residual adjustment is executed first.
668*9880d681SAndroid Build Coastguard Worker uint64_t ArgumentPopSize = 0;
669*9880d681SAndroid Build Coastguard Worker if (IsTailCallReturn) {
670*9880d681SAndroid Build Coastguard Worker MachineOperand &StackAdjust = MBBI->getOperand(1);
671*9880d681SAndroid Build Coastguard Worker
672*9880d681SAndroid Build Coastguard Worker // For a tail-call in a callee-pops-arguments environment, some or all of
673*9880d681SAndroid Build Coastguard Worker // the stack may actually be in use for the call's arguments, this is
674*9880d681SAndroid Build Coastguard Worker // calculated during LowerCall and consumed here...
675*9880d681SAndroid Build Coastguard Worker ArgumentPopSize = StackAdjust.getImm();
676*9880d681SAndroid Build Coastguard Worker } else {
677*9880d681SAndroid Build Coastguard Worker // ... otherwise the amount to pop is *all* of the argument space,
678*9880d681SAndroid Build Coastguard Worker // conveniently stored in the MachineFunctionInfo by
679*9880d681SAndroid Build Coastguard Worker // LowerFormalArguments. This will, of course, be zero for the C calling
680*9880d681SAndroid Build Coastguard Worker // convention.
681*9880d681SAndroid Build Coastguard Worker ArgumentPopSize = AFI->getArgumentStackToRestore();
682*9880d681SAndroid Build Coastguard Worker }
683*9880d681SAndroid Build Coastguard Worker
684*9880d681SAndroid Build Coastguard Worker // The stack frame should be like below,
685*9880d681SAndroid Build Coastguard Worker //
686*9880d681SAndroid Build Coastguard Worker // ---------------------- ---
687*9880d681SAndroid Build Coastguard Worker // | | |
688*9880d681SAndroid Build Coastguard Worker // | BytesInStackArgArea| CalleeArgStackSize
689*9880d681SAndroid Build Coastguard Worker // | (NumReusableBytes) | (of tail call)
690*9880d681SAndroid Build Coastguard Worker // | | ---
691*9880d681SAndroid Build Coastguard Worker // | | |
692*9880d681SAndroid Build Coastguard Worker // ---------------------| --- |
693*9880d681SAndroid Build Coastguard Worker // | | | |
694*9880d681SAndroid Build Coastguard Worker // | CalleeSavedReg | | |
695*9880d681SAndroid Build Coastguard Worker // | (CalleeSavedStackSize)| | |
696*9880d681SAndroid Build Coastguard Worker // | | | |
697*9880d681SAndroid Build Coastguard Worker // ---------------------| | NumBytes
698*9880d681SAndroid Build Coastguard Worker // | | StackSize (StackAdjustUp)
699*9880d681SAndroid Build Coastguard Worker // | LocalStackSize | | |
700*9880d681SAndroid Build Coastguard Worker // | (covering callee | | |
701*9880d681SAndroid Build Coastguard Worker // | args) | | |
702*9880d681SAndroid Build Coastguard Worker // | | | |
703*9880d681SAndroid Build Coastguard Worker // ---------------------- --- ---
704*9880d681SAndroid Build Coastguard Worker //
705*9880d681SAndroid Build Coastguard Worker // So NumBytes = StackSize + BytesInStackArgArea - CalleeArgStackSize
706*9880d681SAndroid Build Coastguard Worker // = StackSize + ArgumentPopSize
707*9880d681SAndroid Build Coastguard Worker //
708*9880d681SAndroid Build Coastguard Worker // AArch64TargetLowering::LowerCall figures out ArgumentPopSize and keeps
709*9880d681SAndroid Build Coastguard Worker // it as the 2nd argument of AArch64ISD::TC_RETURN.
710*9880d681SAndroid Build Coastguard Worker
711*9880d681SAndroid Build Coastguard Worker auto CSStackSize = AFI->getCalleeSavedStackSize();
712*9880d681SAndroid Build Coastguard Worker bool CombineSPBump = shouldCombineCSRLocalStackBump(MF, NumBytes);
713*9880d681SAndroid Build Coastguard Worker
714*9880d681SAndroid Build Coastguard Worker if (!CombineSPBump && CSStackSize != 0)
715*9880d681SAndroid Build Coastguard Worker convertCalleeSaveRestoreToSPPrePostIncDec(
716*9880d681SAndroid Build Coastguard Worker MBB, std::prev(MBB.getFirstTerminator()), DL, TII, CSStackSize);
717*9880d681SAndroid Build Coastguard Worker
718*9880d681SAndroid Build Coastguard Worker // Move past the restores of the callee-saved registers.
719*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator LastPopI = MBB.getFirstTerminator();
720*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator Begin = MBB.begin();
721*9880d681SAndroid Build Coastguard Worker while (LastPopI != Begin) {
722*9880d681SAndroid Build Coastguard Worker --LastPopI;
723*9880d681SAndroid Build Coastguard Worker if (!LastPopI->getFlag(MachineInstr::FrameDestroy)) {
724*9880d681SAndroid Build Coastguard Worker ++LastPopI;
725*9880d681SAndroid Build Coastguard Worker break;
726*9880d681SAndroid Build Coastguard Worker } else if (CombineSPBump)
727*9880d681SAndroid Build Coastguard Worker fixupCalleeSaveRestoreStackOffset(*LastPopI, AFI->getLocalStackSize());
728*9880d681SAndroid Build Coastguard Worker }
729*9880d681SAndroid Build Coastguard Worker
730*9880d681SAndroid Build Coastguard Worker // If there is a single SP update, insert it before the ret and we're done.
731*9880d681SAndroid Build Coastguard Worker if (CombineSPBump) {
732*9880d681SAndroid Build Coastguard Worker emitFrameOffset(MBB, MBB.getFirstTerminator(), DL, AArch64::SP, AArch64::SP,
733*9880d681SAndroid Build Coastguard Worker NumBytes + ArgumentPopSize, TII,
734*9880d681SAndroid Build Coastguard Worker MachineInstr::FrameDestroy);
735*9880d681SAndroid Build Coastguard Worker return;
736*9880d681SAndroid Build Coastguard Worker }
737*9880d681SAndroid Build Coastguard Worker
738*9880d681SAndroid Build Coastguard Worker NumBytes -= CSStackSize;
739*9880d681SAndroid Build Coastguard Worker assert(NumBytes >= 0 && "Negative stack allocation size!?");
740*9880d681SAndroid Build Coastguard Worker
741*9880d681SAndroid Build Coastguard Worker if (!hasFP(MF)) {
742*9880d681SAndroid Build Coastguard Worker bool RedZone = canUseRedZone(MF);
743*9880d681SAndroid Build Coastguard Worker // If this was a redzone leaf function, we don't need to restore the
744*9880d681SAndroid Build Coastguard Worker // stack pointer (but we may need to pop stack args for fastcc).
745*9880d681SAndroid Build Coastguard Worker if (RedZone && ArgumentPopSize == 0)
746*9880d681SAndroid Build Coastguard Worker return;
747*9880d681SAndroid Build Coastguard Worker
748*9880d681SAndroid Build Coastguard Worker bool NoCalleeSaveRestore = CSStackSize == 0;
749*9880d681SAndroid Build Coastguard Worker int StackRestoreBytes = RedZone ? 0 : NumBytes;
750*9880d681SAndroid Build Coastguard Worker if (NoCalleeSaveRestore)
751*9880d681SAndroid Build Coastguard Worker StackRestoreBytes += ArgumentPopSize;
752*9880d681SAndroid Build Coastguard Worker emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
753*9880d681SAndroid Build Coastguard Worker StackRestoreBytes, TII, MachineInstr::FrameDestroy);
754*9880d681SAndroid Build Coastguard Worker // If we were able to combine the local stack pop with the argument pop,
755*9880d681SAndroid Build Coastguard Worker // then we're done.
756*9880d681SAndroid Build Coastguard Worker if (NoCalleeSaveRestore || ArgumentPopSize == 0)
757*9880d681SAndroid Build Coastguard Worker return;
758*9880d681SAndroid Build Coastguard Worker NumBytes = 0;
759*9880d681SAndroid Build Coastguard Worker }
760*9880d681SAndroid Build Coastguard Worker
761*9880d681SAndroid Build Coastguard Worker // Restore the original stack pointer.
762*9880d681SAndroid Build Coastguard Worker // FIXME: Rather than doing the math here, we should instead just use
763*9880d681SAndroid Build Coastguard Worker // non-post-indexed loads for the restores if we aren't actually going to
764*9880d681SAndroid Build Coastguard Worker // be able to save any instructions.
765*9880d681SAndroid Build Coastguard Worker if (MFI->hasVarSizedObjects() || AFI->isStackRealigned())
766*9880d681SAndroid Build Coastguard Worker emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::FP,
767*9880d681SAndroid Build Coastguard Worker -CSStackSize + 16, TII, MachineInstr::FrameDestroy);
768*9880d681SAndroid Build Coastguard Worker else if (NumBytes)
769*9880d681SAndroid Build Coastguard Worker emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP, NumBytes, TII,
770*9880d681SAndroid Build Coastguard Worker MachineInstr::FrameDestroy);
771*9880d681SAndroid Build Coastguard Worker
772*9880d681SAndroid Build Coastguard Worker // This must be placed after the callee-save restore code because that code
773*9880d681SAndroid Build Coastguard Worker // assumes the SP is at the same location as it was after the callee-save save
774*9880d681SAndroid Build Coastguard Worker // code in the prologue.
775*9880d681SAndroid Build Coastguard Worker if (ArgumentPopSize)
776*9880d681SAndroid Build Coastguard Worker emitFrameOffset(MBB, MBB.getFirstTerminator(), DL, AArch64::SP, AArch64::SP,
777*9880d681SAndroid Build Coastguard Worker ArgumentPopSize, TII, MachineInstr::FrameDestroy);
778*9880d681SAndroid Build Coastguard Worker }
779*9880d681SAndroid Build Coastguard Worker
780*9880d681SAndroid Build Coastguard Worker /// getFrameIndexReference - Provide a base+offset reference to an FI slot for
781*9880d681SAndroid Build Coastguard Worker /// debug info. It's the same as what we use for resolving the code-gen
782*9880d681SAndroid Build Coastguard Worker /// references for now. FIXME: This can go wrong when references are
783*9880d681SAndroid Build Coastguard Worker /// SP-relative and simple call frames aren't used.
getFrameIndexReference(const MachineFunction & MF,int FI,unsigned & FrameReg) const784*9880d681SAndroid Build Coastguard Worker int AArch64FrameLowering::getFrameIndexReference(const MachineFunction &MF,
785*9880d681SAndroid Build Coastguard Worker int FI,
786*9880d681SAndroid Build Coastguard Worker unsigned &FrameReg) const {
787*9880d681SAndroid Build Coastguard Worker return resolveFrameIndexReference(MF, FI, FrameReg);
788*9880d681SAndroid Build Coastguard Worker }
789*9880d681SAndroid Build Coastguard Worker
resolveFrameIndexReference(const MachineFunction & MF,int FI,unsigned & FrameReg,bool PreferFP) const790*9880d681SAndroid Build Coastguard Worker int AArch64FrameLowering::resolveFrameIndexReference(const MachineFunction &MF,
791*9880d681SAndroid Build Coastguard Worker int FI, unsigned &FrameReg,
792*9880d681SAndroid Build Coastguard Worker bool PreferFP) const {
793*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *MFI = MF.getFrameInfo();
794*9880d681SAndroid Build Coastguard Worker const AArch64RegisterInfo *RegInfo = static_cast<const AArch64RegisterInfo *>(
795*9880d681SAndroid Build Coastguard Worker MF.getSubtarget().getRegisterInfo());
796*9880d681SAndroid Build Coastguard Worker const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
797*9880d681SAndroid Build Coastguard Worker int FPOffset = MFI->getObjectOffset(FI) + 16;
798*9880d681SAndroid Build Coastguard Worker int Offset = MFI->getObjectOffset(FI) + MFI->getStackSize();
799*9880d681SAndroid Build Coastguard Worker bool isFixed = MFI->isFixedObjectIndex(FI);
800*9880d681SAndroid Build Coastguard Worker
801*9880d681SAndroid Build Coastguard Worker // Use frame pointer to reference fixed objects. Use it for locals if
802*9880d681SAndroid Build Coastguard Worker // there are VLAs or a dynamically realigned SP (and thus the SP isn't
803*9880d681SAndroid Build Coastguard Worker // reliable as a base). Make sure useFPForScavengingIndex() does the
804*9880d681SAndroid Build Coastguard Worker // right thing for the emergency spill slot.
805*9880d681SAndroid Build Coastguard Worker bool UseFP = false;
806*9880d681SAndroid Build Coastguard Worker if (AFI->hasStackFrame()) {
807*9880d681SAndroid Build Coastguard Worker // Note: Keeping the following as multiple 'if' statements rather than
808*9880d681SAndroid Build Coastguard Worker // merging to a single expression for readability.
809*9880d681SAndroid Build Coastguard Worker //
810*9880d681SAndroid Build Coastguard Worker // Argument access should always use the FP.
811*9880d681SAndroid Build Coastguard Worker if (isFixed) {
812*9880d681SAndroid Build Coastguard Worker UseFP = hasFP(MF);
813*9880d681SAndroid Build Coastguard Worker } else if (hasFP(MF) && !RegInfo->hasBasePointer(MF) &&
814*9880d681SAndroid Build Coastguard Worker !RegInfo->needsStackRealignment(MF)) {
815*9880d681SAndroid Build Coastguard Worker // Use SP or FP, whichever gives us the best chance of the offset
816*9880d681SAndroid Build Coastguard Worker // being in range for direct access. If the FPOffset is positive,
817*9880d681SAndroid Build Coastguard Worker // that'll always be best, as the SP will be even further away.
818*9880d681SAndroid Build Coastguard Worker // If the FPOffset is negative, we have to keep in mind that the
819*9880d681SAndroid Build Coastguard Worker // available offset range for negative offsets is smaller than for
820*9880d681SAndroid Build Coastguard Worker // positive ones. If we have variable sized objects, we're stuck with
821*9880d681SAndroid Build Coastguard Worker // using the FP regardless, though, as the SP offset is unknown
822*9880d681SAndroid Build Coastguard Worker // and we don't have a base pointer available. If an offset is
823*9880d681SAndroid Build Coastguard Worker // available via the FP and the SP, use whichever is closest.
824*9880d681SAndroid Build Coastguard Worker if (PreferFP || MFI->hasVarSizedObjects() || FPOffset >= 0 ||
825*9880d681SAndroid Build Coastguard Worker (FPOffset >= -256 && Offset > -FPOffset))
826*9880d681SAndroid Build Coastguard Worker UseFP = true;
827*9880d681SAndroid Build Coastguard Worker }
828*9880d681SAndroid Build Coastguard Worker }
829*9880d681SAndroid Build Coastguard Worker
830*9880d681SAndroid Build Coastguard Worker assert((isFixed || !RegInfo->needsStackRealignment(MF) || !UseFP) &&
831*9880d681SAndroid Build Coastguard Worker "In the presence of dynamic stack pointer realignment, "
832*9880d681SAndroid Build Coastguard Worker "non-argument objects cannot be accessed through the frame pointer");
833*9880d681SAndroid Build Coastguard Worker
834*9880d681SAndroid Build Coastguard Worker if (UseFP) {
835*9880d681SAndroid Build Coastguard Worker FrameReg = RegInfo->getFrameRegister(MF);
836*9880d681SAndroid Build Coastguard Worker return FPOffset;
837*9880d681SAndroid Build Coastguard Worker }
838*9880d681SAndroid Build Coastguard Worker
839*9880d681SAndroid Build Coastguard Worker // Use the base pointer if we have one.
840*9880d681SAndroid Build Coastguard Worker if (RegInfo->hasBasePointer(MF))
841*9880d681SAndroid Build Coastguard Worker FrameReg = RegInfo->getBaseRegister();
842*9880d681SAndroid Build Coastguard Worker else {
843*9880d681SAndroid Build Coastguard Worker FrameReg = AArch64::SP;
844*9880d681SAndroid Build Coastguard Worker // If we're using the red zone for this function, the SP won't actually
845*9880d681SAndroid Build Coastguard Worker // be adjusted, so the offsets will be negative. They're also all
846*9880d681SAndroid Build Coastguard Worker // within range of the signed 9-bit immediate instructions.
847*9880d681SAndroid Build Coastguard Worker if (canUseRedZone(MF))
848*9880d681SAndroid Build Coastguard Worker Offset -= AFI->getLocalStackSize();
849*9880d681SAndroid Build Coastguard Worker }
850*9880d681SAndroid Build Coastguard Worker
851*9880d681SAndroid Build Coastguard Worker return Offset;
852*9880d681SAndroid Build Coastguard Worker }
853*9880d681SAndroid Build Coastguard Worker
getPrologueDeath(MachineFunction & MF,unsigned Reg)854*9880d681SAndroid Build Coastguard Worker static unsigned getPrologueDeath(MachineFunction &MF, unsigned Reg) {
855*9880d681SAndroid Build Coastguard Worker // Do not set a kill flag on values that are also marked as live-in. This
856*9880d681SAndroid Build Coastguard Worker // happens with the @llvm-returnaddress intrinsic and with arguments passed in
857*9880d681SAndroid Build Coastguard Worker // callee saved registers.
858*9880d681SAndroid Build Coastguard Worker // Omitting the kill flags is conservatively correct even if the live-in
859*9880d681SAndroid Build Coastguard Worker // is not used after all.
860*9880d681SAndroid Build Coastguard Worker bool IsLiveIn = MF.getRegInfo().isLiveIn(Reg);
861*9880d681SAndroid Build Coastguard Worker return getKillRegState(!IsLiveIn);
862*9880d681SAndroid Build Coastguard Worker }
863*9880d681SAndroid Build Coastguard Worker
produceCompactUnwindFrame(MachineFunction & MF)864*9880d681SAndroid Build Coastguard Worker static bool produceCompactUnwindFrame(MachineFunction &MF) {
865*9880d681SAndroid Build Coastguard Worker const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
866*9880d681SAndroid Build Coastguard Worker AttributeSet Attrs = MF.getFunction()->getAttributes();
867*9880d681SAndroid Build Coastguard Worker return Subtarget.isTargetMachO() &&
868*9880d681SAndroid Build Coastguard Worker !(Subtarget.getTargetLowering()->supportSwiftError() &&
869*9880d681SAndroid Build Coastguard Worker Attrs.hasAttrSomewhere(Attribute::SwiftError));
870*9880d681SAndroid Build Coastguard Worker }
871*9880d681SAndroid Build Coastguard Worker
872*9880d681SAndroid Build Coastguard Worker
873*9880d681SAndroid Build Coastguard Worker struct RegPairInfo {
RegPairInfoRegPairInfo874*9880d681SAndroid Build Coastguard Worker RegPairInfo() : Reg1(AArch64::NoRegister), Reg2(AArch64::NoRegister) {}
875*9880d681SAndroid Build Coastguard Worker unsigned Reg1;
876*9880d681SAndroid Build Coastguard Worker unsigned Reg2;
877*9880d681SAndroid Build Coastguard Worker int FrameIdx;
878*9880d681SAndroid Build Coastguard Worker int Offset;
879*9880d681SAndroid Build Coastguard Worker bool IsGPR;
isPairedRegPairInfo880*9880d681SAndroid Build Coastguard Worker bool isPaired() const { return Reg2 != AArch64::NoRegister; }
881*9880d681SAndroid Build Coastguard Worker };
882*9880d681SAndroid Build Coastguard Worker
computeCalleeSaveRegisterPairs(MachineFunction & MF,const std::vector<CalleeSavedInfo> & CSI,const TargetRegisterInfo * TRI,SmallVectorImpl<RegPairInfo> & RegPairs)883*9880d681SAndroid Build Coastguard Worker static void computeCalleeSaveRegisterPairs(
884*9880d681SAndroid Build Coastguard Worker MachineFunction &MF, const std::vector<CalleeSavedInfo> &CSI,
885*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI, SmallVectorImpl<RegPairInfo> &RegPairs) {
886*9880d681SAndroid Build Coastguard Worker
887*9880d681SAndroid Build Coastguard Worker if (CSI.empty())
888*9880d681SAndroid Build Coastguard Worker return;
889*9880d681SAndroid Build Coastguard Worker
890*9880d681SAndroid Build Coastguard Worker AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
891*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF.getFrameInfo();
892*9880d681SAndroid Build Coastguard Worker CallingConv::ID CC = MF.getFunction()->getCallingConv();
893*9880d681SAndroid Build Coastguard Worker unsigned Count = CSI.size();
894*9880d681SAndroid Build Coastguard Worker (void)CC;
895*9880d681SAndroid Build Coastguard Worker // MachO's compact unwind format relies on all registers being stored in
896*9880d681SAndroid Build Coastguard Worker // pairs.
897*9880d681SAndroid Build Coastguard Worker assert((!produceCompactUnwindFrame(MF) ||
898*9880d681SAndroid Build Coastguard Worker CC == CallingConv::PreserveMost ||
899*9880d681SAndroid Build Coastguard Worker (Count & 1) == 0) &&
900*9880d681SAndroid Build Coastguard Worker "Odd number of callee-saved regs to spill!");
901*9880d681SAndroid Build Coastguard Worker unsigned Offset = AFI->getCalleeSavedStackSize();
902*9880d681SAndroid Build Coastguard Worker
903*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < Count; ++i) {
904*9880d681SAndroid Build Coastguard Worker RegPairInfo RPI;
905*9880d681SAndroid Build Coastguard Worker RPI.Reg1 = CSI[i].getReg();
906*9880d681SAndroid Build Coastguard Worker
907*9880d681SAndroid Build Coastguard Worker assert(AArch64::GPR64RegClass.contains(RPI.Reg1) ||
908*9880d681SAndroid Build Coastguard Worker AArch64::FPR64RegClass.contains(RPI.Reg1));
909*9880d681SAndroid Build Coastguard Worker RPI.IsGPR = AArch64::GPR64RegClass.contains(RPI.Reg1);
910*9880d681SAndroid Build Coastguard Worker
911*9880d681SAndroid Build Coastguard Worker // Add the next reg to the pair if it is in the same register class.
912*9880d681SAndroid Build Coastguard Worker if (i + 1 < Count) {
913*9880d681SAndroid Build Coastguard Worker unsigned NextReg = CSI[i + 1].getReg();
914*9880d681SAndroid Build Coastguard Worker if ((RPI.IsGPR && AArch64::GPR64RegClass.contains(NextReg)) ||
915*9880d681SAndroid Build Coastguard Worker (!RPI.IsGPR && AArch64::FPR64RegClass.contains(NextReg)))
916*9880d681SAndroid Build Coastguard Worker RPI.Reg2 = NextReg;
917*9880d681SAndroid Build Coastguard Worker }
918*9880d681SAndroid Build Coastguard Worker
919*9880d681SAndroid Build Coastguard Worker // GPRs and FPRs are saved in pairs of 64-bit regs. We expect the CSI
920*9880d681SAndroid Build Coastguard Worker // list to come in sorted by frame index so that we can issue the store
921*9880d681SAndroid Build Coastguard Worker // pair instructions directly. Assert if we see anything otherwise.
922*9880d681SAndroid Build Coastguard Worker //
923*9880d681SAndroid Build Coastguard Worker // The order of the registers in the list is controlled by
924*9880d681SAndroid Build Coastguard Worker // getCalleeSavedRegs(), so they will always be in-order, as well.
925*9880d681SAndroid Build Coastguard Worker assert((!RPI.isPaired() ||
926*9880d681SAndroid Build Coastguard Worker (CSI[i].getFrameIdx() + 1 == CSI[i + 1].getFrameIdx())) &&
927*9880d681SAndroid Build Coastguard Worker "Out of order callee saved regs!");
928*9880d681SAndroid Build Coastguard Worker
929*9880d681SAndroid Build Coastguard Worker // MachO's compact unwind format relies on all registers being stored in
930*9880d681SAndroid Build Coastguard Worker // adjacent register pairs.
931*9880d681SAndroid Build Coastguard Worker assert((!produceCompactUnwindFrame(MF) ||
932*9880d681SAndroid Build Coastguard Worker CC == CallingConv::PreserveMost ||
933*9880d681SAndroid Build Coastguard Worker (RPI.isPaired() &&
934*9880d681SAndroid Build Coastguard Worker ((RPI.Reg1 == AArch64::LR && RPI.Reg2 == AArch64::FP) ||
935*9880d681SAndroid Build Coastguard Worker RPI.Reg1 + 1 == RPI.Reg2))) &&
936*9880d681SAndroid Build Coastguard Worker "Callee-save registers not saved as adjacent register pair!");
937*9880d681SAndroid Build Coastguard Worker
938*9880d681SAndroid Build Coastguard Worker RPI.FrameIdx = CSI[i].getFrameIdx();
939*9880d681SAndroid Build Coastguard Worker
940*9880d681SAndroid Build Coastguard Worker if (Count * 8 != AFI->getCalleeSavedStackSize() && !RPI.isPaired()) {
941*9880d681SAndroid Build Coastguard Worker // Round up size of non-pair to pair size if we need to pad the
942*9880d681SAndroid Build Coastguard Worker // callee-save area to ensure 16-byte alignment.
943*9880d681SAndroid Build Coastguard Worker Offset -= 16;
944*9880d681SAndroid Build Coastguard Worker assert(MFI->getObjectAlignment(RPI.FrameIdx) <= 16);
945*9880d681SAndroid Build Coastguard Worker MFI->setObjectAlignment(RPI.FrameIdx, 16);
946*9880d681SAndroid Build Coastguard Worker AFI->setCalleeSaveStackHasFreeSpace(true);
947*9880d681SAndroid Build Coastguard Worker } else
948*9880d681SAndroid Build Coastguard Worker Offset -= RPI.isPaired() ? 16 : 8;
949*9880d681SAndroid Build Coastguard Worker assert(Offset % 8 == 0);
950*9880d681SAndroid Build Coastguard Worker RPI.Offset = Offset / 8;
951*9880d681SAndroid Build Coastguard Worker assert((RPI.Offset >= -64 && RPI.Offset <= 63) &&
952*9880d681SAndroid Build Coastguard Worker "Offset out of bounds for LDP/STP immediate");
953*9880d681SAndroid Build Coastguard Worker
954*9880d681SAndroid Build Coastguard Worker RegPairs.push_back(RPI);
955*9880d681SAndroid Build Coastguard Worker if (RPI.isPaired())
956*9880d681SAndroid Build Coastguard Worker ++i;
957*9880d681SAndroid Build Coastguard Worker }
958*9880d681SAndroid Build Coastguard Worker }
959*9880d681SAndroid Build Coastguard Worker
spillCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const std::vector<CalleeSavedInfo> & CSI,const TargetRegisterInfo * TRI) const960*9880d681SAndroid Build Coastguard Worker bool AArch64FrameLowering::spillCalleeSavedRegisters(
961*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
962*9880d681SAndroid Build Coastguard Worker const std::vector<CalleeSavedInfo> &CSI,
963*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) const {
964*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = *MBB.getParent();
965*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
966*9880d681SAndroid Build Coastguard Worker DebugLoc DL;
967*9880d681SAndroid Build Coastguard Worker SmallVector<RegPairInfo, 8> RegPairs;
968*9880d681SAndroid Build Coastguard Worker
969*9880d681SAndroid Build Coastguard Worker computeCalleeSaveRegisterPairs(MF, CSI, TRI, RegPairs);
970*9880d681SAndroid Build Coastguard Worker
971*9880d681SAndroid Build Coastguard Worker for (auto RPII = RegPairs.rbegin(), RPIE = RegPairs.rend(); RPII != RPIE;
972*9880d681SAndroid Build Coastguard Worker ++RPII) {
973*9880d681SAndroid Build Coastguard Worker RegPairInfo RPI = *RPII;
974*9880d681SAndroid Build Coastguard Worker unsigned Reg1 = RPI.Reg1;
975*9880d681SAndroid Build Coastguard Worker unsigned Reg2 = RPI.Reg2;
976*9880d681SAndroid Build Coastguard Worker unsigned StrOpc;
977*9880d681SAndroid Build Coastguard Worker
978*9880d681SAndroid Build Coastguard Worker // Issue sequence of spills for cs regs. The first spill may be converted
979*9880d681SAndroid Build Coastguard Worker // to a pre-decrement store later by emitPrologue if the callee-save stack
980*9880d681SAndroid Build Coastguard Worker // area allocation can't be combined with the local stack area allocation.
981*9880d681SAndroid Build Coastguard Worker // For example:
982*9880d681SAndroid Build Coastguard Worker // stp x22, x21, [sp, #0] // addImm(+0)
983*9880d681SAndroid Build Coastguard Worker // stp x20, x19, [sp, #16] // addImm(+2)
984*9880d681SAndroid Build Coastguard Worker // stp fp, lr, [sp, #32] // addImm(+4)
985*9880d681SAndroid Build Coastguard Worker // Rationale: This sequence saves uop updates compared to a sequence of
986*9880d681SAndroid Build Coastguard Worker // pre-increment spills like stp xi,xj,[sp,#-16]!
987*9880d681SAndroid Build Coastguard Worker // Note: Similar rationale and sequence for restores in epilog.
988*9880d681SAndroid Build Coastguard Worker if (RPI.IsGPR)
989*9880d681SAndroid Build Coastguard Worker StrOpc = RPI.isPaired() ? AArch64::STPXi : AArch64::STRXui;
990*9880d681SAndroid Build Coastguard Worker else
991*9880d681SAndroid Build Coastguard Worker StrOpc = RPI.isPaired() ? AArch64::STPDi : AArch64::STRDui;
992*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "CSR spill: (" << TRI->getName(Reg1);
993*9880d681SAndroid Build Coastguard Worker if (RPI.isPaired())
994*9880d681SAndroid Build Coastguard Worker dbgs() << ", " << TRI->getName(Reg2);
995*9880d681SAndroid Build Coastguard Worker dbgs() << ") -> fi#(" << RPI.FrameIdx;
996*9880d681SAndroid Build Coastguard Worker if (RPI.isPaired())
997*9880d681SAndroid Build Coastguard Worker dbgs() << ", " << RPI.FrameIdx+1;
998*9880d681SAndroid Build Coastguard Worker dbgs() << ")\n");
999*9880d681SAndroid Build Coastguard Worker
1000*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc));
1001*9880d681SAndroid Build Coastguard Worker MBB.addLiveIn(Reg1);
1002*9880d681SAndroid Build Coastguard Worker if (RPI.isPaired()) {
1003*9880d681SAndroid Build Coastguard Worker MBB.addLiveIn(Reg2);
1004*9880d681SAndroid Build Coastguard Worker MIB.addReg(Reg2, getPrologueDeath(MF, Reg2));
1005*9880d681SAndroid Build Coastguard Worker MIB.addMemOperand(MF.getMachineMemOperand(
1006*9880d681SAndroid Build Coastguard Worker MachinePointerInfo::getFixedStack(MF, RPI.FrameIdx + 1),
1007*9880d681SAndroid Build Coastguard Worker MachineMemOperand::MOStore, 8, 8));
1008*9880d681SAndroid Build Coastguard Worker }
1009*9880d681SAndroid Build Coastguard Worker MIB.addReg(Reg1, getPrologueDeath(MF, Reg1))
1010*9880d681SAndroid Build Coastguard Worker .addReg(AArch64::SP)
1011*9880d681SAndroid Build Coastguard Worker .addImm(RPI.Offset) // [sp, #offset*8], where factor*8 is implicit
1012*9880d681SAndroid Build Coastguard Worker .setMIFlag(MachineInstr::FrameSetup);
1013*9880d681SAndroid Build Coastguard Worker MIB.addMemOperand(MF.getMachineMemOperand(
1014*9880d681SAndroid Build Coastguard Worker MachinePointerInfo::getFixedStack(MF, RPI.FrameIdx),
1015*9880d681SAndroid Build Coastguard Worker MachineMemOperand::MOStore, 8, 8));
1016*9880d681SAndroid Build Coastguard Worker }
1017*9880d681SAndroid Build Coastguard Worker return true;
1018*9880d681SAndroid Build Coastguard Worker }
1019*9880d681SAndroid Build Coastguard Worker
restoreCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const std::vector<CalleeSavedInfo> & CSI,const TargetRegisterInfo * TRI) const1020*9880d681SAndroid Build Coastguard Worker bool AArch64FrameLowering::restoreCalleeSavedRegisters(
1021*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
1022*9880d681SAndroid Build Coastguard Worker const std::vector<CalleeSavedInfo> &CSI,
1023*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) const {
1024*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = *MBB.getParent();
1025*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
1026*9880d681SAndroid Build Coastguard Worker DebugLoc DL;
1027*9880d681SAndroid Build Coastguard Worker SmallVector<RegPairInfo, 8> RegPairs;
1028*9880d681SAndroid Build Coastguard Worker
1029*9880d681SAndroid Build Coastguard Worker if (MI != MBB.end())
1030*9880d681SAndroid Build Coastguard Worker DL = MI->getDebugLoc();
1031*9880d681SAndroid Build Coastguard Worker
1032*9880d681SAndroid Build Coastguard Worker computeCalleeSaveRegisterPairs(MF, CSI, TRI, RegPairs);
1033*9880d681SAndroid Build Coastguard Worker
1034*9880d681SAndroid Build Coastguard Worker for (auto RPII = RegPairs.begin(), RPIE = RegPairs.end(); RPII != RPIE;
1035*9880d681SAndroid Build Coastguard Worker ++RPII) {
1036*9880d681SAndroid Build Coastguard Worker RegPairInfo RPI = *RPII;
1037*9880d681SAndroid Build Coastguard Worker unsigned Reg1 = RPI.Reg1;
1038*9880d681SAndroid Build Coastguard Worker unsigned Reg2 = RPI.Reg2;
1039*9880d681SAndroid Build Coastguard Worker
1040*9880d681SAndroid Build Coastguard Worker // Issue sequence of restores for cs regs. The last restore may be converted
1041*9880d681SAndroid Build Coastguard Worker // to a post-increment load later by emitEpilogue if the callee-save stack
1042*9880d681SAndroid Build Coastguard Worker // area allocation can't be combined with the local stack area allocation.
1043*9880d681SAndroid Build Coastguard Worker // For example:
1044*9880d681SAndroid Build Coastguard Worker // ldp fp, lr, [sp, #32] // addImm(+4)
1045*9880d681SAndroid Build Coastguard Worker // ldp x20, x19, [sp, #16] // addImm(+2)
1046*9880d681SAndroid Build Coastguard Worker // ldp x22, x21, [sp, #0] // addImm(+0)
1047*9880d681SAndroid Build Coastguard Worker // Note: see comment in spillCalleeSavedRegisters()
1048*9880d681SAndroid Build Coastguard Worker unsigned LdrOpc;
1049*9880d681SAndroid Build Coastguard Worker if (RPI.IsGPR)
1050*9880d681SAndroid Build Coastguard Worker LdrOpc = RPI.isPaired() ? AArch64::LDPXi : AArch64::LDRXui;
1051*9880d681SAndroid Build Coastguard Worker else
1052*9880d681SAndroid Build Coastguard Worker LdrOpc = RPI.isPaired() ? AArch64::LDPDi : AArch64::LDRDui;
1053*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "CSR restore: (" << TRI->getName(Reg1);
1054*9880d681SAndroid Build Coastguard Worker if (RPI.isPaired())
1055*9880d681SAndroid Build Coastguard Worker dbgs() << ", " << TRI->getName(Reg2);
1056*9880d681SAndroid Build Coastguard Worker dbgs() << ") -> fi#(" << RPI.FrameIdx;
1057*9880d681SAndroid Build Coastguard Worker if (RPI.isPaired())
1058*9880d681SAndroid Build Coastguard Worker dbgs() << ", " << RPI.FrameIdx+1;
1059*9880d681SAndroid Build Coastguard Worker dbgs() << ")\n");
1060*9880d681SAndroid Build Coastguard Worker
1061*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(LdrOpc));
1062*9880d681SAndroid Build Coastguard Worker if (RPI.isPaired()) {
1063*9880d681SAndroid Build Coastguard Worker MIB.addReg(Reg2, getDefRegState(true));
1064*9880d681SAndroid Build Coastguard Worker MIB.addMemOperand(MF.getMachineMemOperand(
1065*9880d681SAndroid Build Coastguard Worker MachinePointerInfo::getFixedStack(MF, RPI.FrameIdx + 1),
1066*9880d681SAndroid Build Coastguard Worker MachineMemOperand::MOLoad, 8, 8));
1067*9880d681SAndroid Build Coastguard Worker }
1068*9880d681SAndroid Build Coastguard Worker MIB.addReg(Reg1, getDefRegState(true))
1069*9880d681SAndroid Build Coastguard Worker .addReg(AArch64::SP)
1070*9880d681SAndroid Build Coastguard Worker .addImm(RPI.Offset) // [sp, #offset*8] where the factor*8 is implicit
1071*9880d681SAndroid Build Coastguard Worker .setMIFlag(MachineInstr::FrameDestroy);
1072*9880d681SAndroid Build Coastguard Worker MIB.addMemOperand(MF.getMachineMemOperand(
1073*9880d681SAndroid Build Coastguard Worker MachinePointerInfo::getFixedStack(MF, RPI.FrameIdx),
1074*9880d681SAndroid Build Coastguard Worker MachineMemOperand::MOLoad, 8, 8));
1075*9880d681SAndroid Build Coastguard Worker }
1076*9880d681SAndroid Build Coastguard Worker return true;
1077*9880d681SAndroid Build Coastguard Worker }
1078*9880d681SAndroid Build Coastguard Worker
determineCalleeSaves(MachineFunction & MF,BitVector & SavedRegs,RegScavenger * RS) const1079*9880d681SAndroid Build Coastguard Worker void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF,
1080*9880d681SAndroid Build Coastguard Worker BitVector &SavedRegs,
1081*9880d681SAndroid Build Coastguard Worker RegScavenger *RS) const {
1082*9880d681SAndroid Build Coastguard Worker // All calls are tail calls in GHC calling conv, and functions have no
1083*9880d681SAndroid Build Coastguard Worker // prologue/epilogue.
1084*9880d681SAndroid Build Coastguard Worker if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
1085*9880d681SAndroid Build Coastguard Worker return;
1086*9880d681SAndroid Build Coastguard Worker
1087*9880d681SAndroid Build Coastguard Worker TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
1088*9880d681SAndroid Build Coastguard Worker const AArch64RegisterInfo *RegInfo = static_cast<const AArch64RegisterInfo *>(
1089*9880d681SAndroid Build Coastguard Worker MF.getSubtarget().getRegisterInfo());
1090*9880d681SAndroid Build Coastguard Worker AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
1091*9880d681SAndroid Build Coastguard Worker unsigned UnspilledCSGPR = AArch64::NoRegister;
1092*9880d681SAndroid Build Coastguard Worker unsigned UnspilledCSGPRPaired = AArch64::NoRegister;
1093*9880d681SAndroid Build Coastguard Worker
1094*9880d681SAndroid Build Coastguard Worker // The frame record needs to be created by saving the appropriate registers
1095*9880d681SAndroid Build Coastguard Worker if (hasFP(MF)) {
1096*9880d681SAndroid Build Coastguard Worker SavedRegs.set(AArch64::FP);
1097*9880d681SAndroid Build Coastguard Worker SavedRegs.set(AArch64::LR);
1098*9880d681SAndroid Build Coastguard Worker }
1099*9880d681SAndroid Build Coastguard Worker
1100*9880d681SAndroid Build Coastguard Worker unsigned BasePointerReg = AArch64::NoRegister;
1101*9880d681SAndroid Build Coastguard Worker if (RegInfo->hasBasePointer(MF))
1102*9880d681SAndroid Build Coastguard Worker BasePointerReg = RegInfo->getBaseRegister();
1103*9880d681SAndroid Build Coastguard Worker
1104*9880d681SAndroid Build Coastguard Worker bool ExtraCSSpill = false;
1105*9880d681SAndroid Build Coastguard Worker const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
1106*9880d681SAndroid Build Coastguard Worker // Figure out which callee-saved registers to save/restore.
1107*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; CSRegs[i]; ++i) {
1108*9880d681SAndroid Build Coastguard Worker const unsigned Reg = CSRegs[i];
1109*9880d681SAndroid Build Coastguard Worker
1110*9880d681SAndroid Build Coastguard Worker // Add the base pointer register to SavedRegs if it is callee-save.
1111*9880d681SAndroid Build Coastguard Worker if (Reg == BasePointerReg)
1112*9880d681SAndroid Build Coastguard Worker SavedRegs.set(Reg);
1113*9880d681SAndroid Build Coastguard Worker
1114*9880d681SAndroid Build Coastguard Worker bool RegUsed = SavedRegs.test(Reg);
1115*9880d681SAndroid Build Coastguard Worker unsigned PairedReg = CSRegs[i ^ 1];
1116*9880d681SAndroid Build Coastguard Worker if (!RegUsed) {
1117*9880d681SAndroid Build Coastguard Worker if (AArch64::GPR64RegClass.contains(Reg) &&
1118*9880d681SAndroid Build Coastguard Worker !RegInfo->isReservedReg(MF, Reg)) {
1119*9880d681SAndroid Build Coastguard Worker UnspilledCSGPR = Reg;
1120*9880d681SAndroid Build Coastguard Worker UnspilledCSGPRPaired = PairedReg;
1121*9880d681SAndroid Build Coastguard Worker }
1122*9880d681SAndroid Build Coastguard Worker continue;
1123*9880d681SAndroid Build Coastguard Worker }
1124*9880d681SAndroid Build Coastguard Worker
1125*9880d681SAndroid Build Coastguard Worker // MachO's compact unwind format relies on all registers being stored in
1126*9880d681SAndroid Build Coastguard Worker // pairs.
1127*9880d681SAndroid Build Coastguard Worker // FIXME: the usual format is actually better if unwinding isn't needed.
1128*9880d681SAndroid Build Coastguard Worker if (produceCompactUnwindFrame(MF) && !SavedRegs.test(PairedReg)) {
1129*9880d681SAndroid Build Coastguard Worker SavedRegs.set(PairedReg);
1130*9880d681SAndroid Build Coastguard Worker if (AArch64::GPR64RegClass.contains(PairedReg) &&
1131*9880d681SAndroid Build Coastguard Worker !RegInfo->isReservedReg(MF, PairedReg))
1132*9880d681SAndroid Build Coastguard Worker ExtraCSSpill = true;
1133*9880d681SAndroid Build Coastguard Worker }
1134*9880d681SAndroid Build Coastguard Worker }
1135*9880d681SAndroid Build Coastguard Worker
1136*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "*** determineCalleeSaves\nUsed CSRs:";
1137*9880d681SAndroid Build Coastguard Worker for (int Reg = SavedRegs.find_first(); Reg != -1;
1138*9880d681SAndroid Build Coastguard Worker Reg = SavedRegs.find_next(Reg))
1139*9880d681SAndroid Build Coastguard Worker dbgs() << ' ' << PrintReg(Reg, RegInfo);
1140*9880d681SAndroid Build Coastguard Worker dbgs() << "\n";);
1141*9880d681SAndroid Build Coastguard Worker
1142*9880d681SAndroid Build Coastguard Worker // If any callee-saved registers are used, the frame cannot be eliminated.
1143*9880d681SAndroid Build Coastguard Worker unsigned NumRegsSpilled = SavedRegs.count();
1144*9880d681SAndroid Build Coastguard Worker bool CanEliminateFrame = NumRegsSpilled == 0;
1145*9880d681SAndroid Build Coastguard Worker
1146*9880d681SAndroid Build Coastguard Worker // FIXME: Set BigStack if any stack slot references may be out of range.
1147*9880d681SAndroid Build Coastguard Worker // For now, just conservatively guestimate based on unscaled indexing
1148*9880d681SAndroid Build Coastguard Worker // range. We'll end up allocating an unnecessary spill slot a lot, but
1149*9880d681SAndroid Build Coastguard Worker // realistically that's not a big deal at this stage of the game.
1150*9880d681SAndroid Build Coastguard Worker // The CSR spill slots have not been allocated yet, so estimateStackSize
1151*9880d681SAndroid Build Coastguard Worker // won't include them.
1152*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF.getFrameInfo();
1153*9880d681SAndroid Build Coastguard Worker unsigned CFSize = MFI->estimateStackSize(MF) + 8 * NumRegsSpilled;
1154*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Estimated stack frame size: " << CFSize << " bytes.\n");
1155*9880d681SAndroid Build Coastguard Worker bool BigStack = (CFSize >= 256);
1156*9880d681SAndroid Build Coastguard Worker if (BigStack || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF))
1157*9880d681SAndroid Build Coastguard Worker AFI->setHasStackFrame(true);
1158*9880d681SAndroid Build Coastguard Worker
1159*9880d681SAndroid Build Coastguard Worker // Estimate if we might need to scavenge a register at some point in order
1160*9880d681SAndroid Build Coastguard Worker // to materialize a stack offset. If so, either spill one additional
1161*9880d681SAndroid Build Coastguard Worker // callee-saved register or reserve a special spill slot to facilitate
1162*9880d681SAndroid Build Coastguard Worker // register scavenging. If we already spilled an extra callee-saved register
1163*9880d681SAndroid Build Coastguard Worker // above to keep the number of spills even, we don't need to do anything else
1164*9880d681SAndroid Build Coastguard Worker // here.
1165*9880d681SAndroid Build Coastguard Worker if (BigStack && !ExtraCSSpill) {
1166*9880d681SAndroid Build Coastguard Worker if (UnspilledCSGPR != AArch64::NoRegister) {
1167*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Spilling " << PrintReg(UnspilledCSGPR, RegInfo)
1168*9880d681SAndroid Build Coastguard Worker << " to get a scratch register.\n");
1169*9880d681SAndroid Build Coastguard Worker SavedRegs.set(UnspilledCSGPR);
1170*9880d681SAndroid Build Coastguard Worker // MachO's compact unwind format relies on all registers being stored in
1171*9880d681SAndroid Build Coastguard Worker // pairs, so if we need to spill one extra for BigStack, then we need to
1172*9880d681SAndroid Build Coastguard Worker // store the pair.
1173*9880d681SAndroid Build Coastguard Worker if (produceCompactUnwindFrame(MF))
1174*9880d681SAndroid Build Coastguard Worker SavedRegs.set(UnspilledCSGPRPaired);
1175*9880d681SAndroid Build Coastguard Worker ExtraCSSpill = true;
1176*9880d681SAndroid Build Coastguard Worker NumRegsSpilled = SavedRegs.count();
1177*9880d681SAndroid Build Coastguard Worker }
1178*9880d681SAndroid Build Coastguard Worker
1179*9880d681SAndroid Build Coastguard Worker // If we didn't find an extra callee-saved register to spill, create
1180*9880d681SAndroid Build Coastguard Worker // an emergency spill slot.
1181*9880d681SAndroid Build Coastguard Worker if (!ExtraCSSpill) {
1182*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = &AArch64::GPR64RegClass;
1183*9880d681SAndroid Build Coastguard Worker int FI = MFI->CreateStackObject(RC->getSize(), RC->getAlignment(), false);
1184*9880d681SAndroid Build Coastguard Worker RS->addScavengingFrameIndex(FI);
1185*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "No available CS registers, allocated fi#" << FI
1186*9880d681SAndroid Build Coastguard Worker << " as the emergency spill slot.\n");
1187*9880d681SAndroid Build Coastguard Worker }
1188*9880d681SAndroid Build Coastguard Worker }
1189*9880d681SAndroid Build Coastguard Worker
1190*9880d681SAndroid Build Coastguard Worker // Round up to register pair alignment to avoid additional SP adjustment
1191*9880d681SAndroid Build Coastguard Worker // instructions.
1192*9880d681SAndroid Build Coastguard Worker AFI->setCalleeSavedStackSize(alignTo(8 * NumRegsSpilled, 16));
1193*9880d681SAndroid Build Coastguard Worker }
1194*9880d681SAndroid Build Coastguard Worker
enableStackSlotScavenging(const MachineFunction & MF) const1195*9880d681SAndroid Build Coastguard Worker bool AArch64FrameLowering::enableStackSlotScavenging(
1196*9880d681SAndroid Build Coastguard Worker const MachineFunction &MF) const {
1197*9880d681SAndroid Build Coastguard Worker const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
1198*9880d681SAndroid Build Coastguard Worker return AFI->hasCalleeSaveStackFreeSpace();
1199*9880d681SAndroid Build Coastguard Worker }
1200