163faed5bSDimitry Andric //===-- PPCFrameLowering.cpp - PPC Frame Information ----------------------===//
2cf099d11SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cf099d11SDimitry Andric //
7cf099d11SDimitry Andric //===----------------------------------------------------------------------===//
8cf099d11SDimitry Andric //
9cf099d11SDimitry Andric // This file contains the PPC implementation of TargetFrameLowering class.
10cf099d11SDimitry Andric //
11cf099d11SDimitry Andric //===----------------------------------------------------------------------===//
12cf099d11SDimitry Andric
13cf099d11SDimitry Andric #include "PPCFrameLowering.h"
14145449b1SDimitry Andric #include "MCTargetDesc/PPCPredicates.h"
15522600a2SDimitry Andric #include "PPCInstrBuilder.h"
164a16efa3SDimitry Andric #include "PPCInstrInfo.h"
17cf099d11SDimitry Andric #include "PPCMachineFunctionInfo.h"
185ca98fd9SDimitry Andric #include "PPCSubtarget.h"
195a5ac124SDimitry Andric #include "PPCTargetMachine.h"
20d8e91e46SDimitry Andric #include "llvm/ADT/Statistic.h"
21145449b1SDimitry Andric #include "llvm/CodeGen/LivePhysRegs.h"
22cf099d11SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
23cf099d11SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
24cf099d11SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
25cf099d11SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
26cf099d11SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
27cf099d11SDimitry Andric #include "llvm/CodeGen/RegisterScavenging.h"
284a16efa3SDimitry Andric #include "llvm/IR/Function.h"
29cf099d11SDimitry Andric #include "llvm/Target/TargetOptions.h"
30cf099d11SDimitry Andric
31cf099d11SDimitry Andric using namespace llvm;
32cf099d11SDimitry Andric
33d8e91e46SDimitry Andric #define DEBUG_TYPE "framelowering"
34d8e91e46SDimitry Andric STATISTIC(NumPESpillVSR, "Number of spills to vector in prologue");
35d8e91e46SDimitry Andric STATISTIC(NumPEReloadVSR, "Number of reloads from vector in epilogue");
36cfca06d7SDimitry Andric STATISTIC(NumPrologProbed, "Number of prologues probed");
37d8e91e46SDimitry Andric
38d8e91e46SDimitry Andric static cl::opt<bool>
39d8e91e46SDimitry Andric EnablePEVectorSpills("ppc-enable-pe-vector-spills",
40d8e91e46SDimitry Andric cl::desc("Enable spills in prologue to vector registers."),
41d8e91e46SDimitry Andric cl::init(false), cl::Hidden);
42d8e91e46SDimitry Andric
computeReturnSaveOffset(const PPCSubtarget & STI)435a5ac124SDimitry Andric static unsigned computeReturnSaveOffset(const PPCSubtarget &STI) {
44cfca06d7SDimitry Andric if (STI.isAIXABI())
455a5ac124SDimitry Andric return STI.isPPC64() ? 16 : 8;
465a5ac124SDimitry Andric // SVR4 ABI:
475a5ac124SDimitry Andric return STI.isPPC64() ? 16 : 4;
485a5ac124SDimitry Andric }
495a5ac124SDimitry Andric
computeTOCSaveOffset(const PPCSubtarget & STI)505a5ac124SDimitry Andric static unsigned computeTOCSaveOffset(const PPCSubtarget &STI) {
511d5ae102SDimitry Andric if (STI.isAIXABI())
521d5ae102SDimitry Andric return STI.isPPC64() ? 40 : 20;
535a5ac124SDimitry Andric return STI.isELFv2ABI() ? 24 : 40;
545a5ac124SDimitry Andric }
555a5ac124SDimitry Andric
computeFramePointerSaveOffset(const PPCSubtarget & STI)565a5ac124SDimitry Andric static unsigned computeFramePointerSaveOffset(const PPCSubtarget &STI) {
57cfca06d7SDimitry Andric // First slot in the general register save area.
585a5ac124SDimitry Andric return STI.isPPC64() ? -8U : -4U;
595a5ac124SDimitry Andric }
605a5ac124SDimitry Andric
computeLinkageSize(const PPCSubtarget & STI)615a5ac124SDimitry Andric static unsigned computeLinkageSize(const PPCSubtarget &STI) {
62cfca06d7SDimitry Andric if (STI.isAIXABI() || STI.isPPC64())
635a5ac124SDimitry Andric return (STI.isELFv2ABI() ? 4 : 6) * (STI.isPPC64() ? 8 : 4);
645a5ac124SDimitry Andric
65e6d15924SDimitry Andric // 32-bit SVR4 ABI:
665a5ac124SDimitry Andric return 8;
675a5ac124SDimitry Andric }
685a5ac124SDimitry Andric
computeBasePointerSaveOffset(const PPCSubtarget & STI)695a5ac124SDimitry Andric static unsigned computeBasePointerSaveOffset(const PPCSubtarget &STI) {
70cfca06d7SDimitry Andric // Third slot in the general purpose register save area.
71cfca06d7SDimitry Andric if (STI.is32BitELFABI() && STI.getTargetMachine().isPositionIndependent())
72cfca06d7SDimitry Andric return -12U;
735a5ac124SDimitry Andric
74cfca06d7SDimitry Andric // Second slot in the general purpose register save area.
75cfca06d7SDimitry Andric return STI.isPPC64() ? -16U : -8U;
765a5ac124SDimitry Andric }
775a5ac124SDimitry Andric
computeCRSaveOffset(const PPCSubtarget & STI)78cfca06d7SDimitry Andric static unsigned computeCRSaveOffset(const PPCSubtarget &STI) {
79cfca06d7SDimitry Andric return (STI.isAIXABI() && !STI.isPPC64()) ? 4 : 8;
801d5ae102SDimitry Andric }
811d5ae102SDimitry Andric
PPCFrameLowering(const PPCSubtarget & STI)825ca98fd9SDimitry Andric PPCFrameLowering::PPCFrameLowering(const PPCSubtarget &STI)
835ca98fd9SDimitry Andric : TargetFrameLowering(TargetFrameLowering::StackGrowsDown,
845a5ac124SDimitry Andric STI.getPlatformStackAlignment(), 0),
855a5ac124SDimitry Andric Subtarget(STI), ReturnSaveOffset(computeReturnSaveOffset(Subtarget)),
865a5ac124SDimitry Andric TOCSaveOffset(computeTOCSaveOffset(Subtarget)),
875a5ac124SDimitry Andric FramePointerSaveOffset(computeFramePointerSaveOffset(Subtarget)),
885a5ac124SDimitry Andric LinkageSize(computeLinkageSize(Subtarget)),
891d5ae102SDimitry Andric BasePointerSaveOffset(computeBasePointerSaveOffset(Subtarget)),
90cfca06d7SDimitry Andric CRSaveOffset(computeCRSaveOffset(Subtarget)) {}
915ca98fd9SDimitry Andric
925ca98fd9SDimitry Andric // With the SVR4 ABI, callee-saved registers have fixed offsets on the stack.
getCalleeSavedSpillSlots(unsigned & NumEntries) const935ca98fd9SDimitry Andric const PPCFrameLowering::SpillSlot *PPCFrameLowering::getCalleeSavedSpillSlots(
945ca98fd9SDimitry Andric unsigned &NumEntries) const {
955ca98fd9SDimitry Andric
96cfca06d7SDimitry Andric // Floating-point register save area offsets.
97cfca06d7SDimitry Andric #define CALLEE_SAVED_FPRS \
98cfca06d7SDimitry Andric {PPC::F31, -8}, \
99cfca06d7SDimitry Andric {PPC::F30, -16}, \
100cfca06d7SDimitry Andric {PPC::F29, -24}, \
101cfca06d7SDimitry Andric {PPC::F28, -32}, \
102cfca06d7SDimitry Andric {PPC::F27, -40}, \
103cfca06d7SDimitry Andric {PPC::F26, -48}, \
104cfca06d7SDimitry Andric {PPC::F25, -56}, \
105cfca06d7SDimitry Andric {PPC::F24, -64}, \
106cfca06d7SDimitry Andric {PPC::F23, -72}, \
107cfca06d7SDimitry Andric {PPC::F22, -80}, \
108cfca06d7SDimitry Andric {PPC::F21, -88}, \
109cfca06d7SDimitry Andric {PPC::F20, -96}, \
110cfca06d7SDimitry Andric {PPC::F19, -104}, \
111cfca06d7SDimitry Andric {PPC::F18, -112}, \
112cfca06d7SDimitry Andric {PPC::F17, -120}, \
113cfca06d7SDimitry Andric {PPC::F16, -128}, \
114cfca06d7SDimitry Andric {PPC::F15, -136}, \
115cfca06d7SDimitry Andric {PPC::F14, -144}
116cfca06d7SDimitry Andric
117cfca06d7SDimitry Andric // 32-bit general purpose register save area offsets shared by ELF and
118cfca06d7SDimitry Andric // AIX. AIX has an extra CSR with r13.
119cfca06d7SDimitry Andric #define CALLEE_SAVED_GPRS32 \
120cfca06d7SDimitry Andric {PPC::R31, -4}, \
121cfca06d7SDimitry Andric {PPC::R30, -8}, \
122cfca06d7SDimitry Andric {PPC::R29, -12}, \
123cfca06d7SDimitry Andric {PPC::R28, -16}, \
124cfca06d7SDimitry Andric {PPC::R27, -20}, \
125cfca06d7SDimitry Andric {PPC::R26, -24}, \
126cfca06d7SDimitry Andric {PPC::R25, -28}, \
127cfca06d7SDimitry Andric {PPC::R24, -32}, \
128cfca06d7SDimitry Andric {PPC::R23, -36}, \
129cfca06d7SDimitry Andric {PPC::R22, -40}, \
130cfca06d7SDimitry Andric {PPC::R21, -44}, \
131cfca06d7SDimitry Andric {PPC::R20, -48}, \
132cfca06d7SDimitry Andric {PPC::R19, -52}, \
133cfca06d7SDimitry Andric {PPC::R18, -56}, \
134cfca06d7SDimitry Andric {PPC::R17, -60}, \
135cfca06d7SDimitry Andric {PPC::R16, -64}, \
136cfca06d7SDimitry Andric {PPC::R15, -68}, \
137cfca06d7SDimitry Andric {PPC::R14, -72}
138cfca06d7SDimitry Andric
139cfca06d7SDimitry Andric // 64-bit general purpose register save area offsets.
140cfca06d7SDimitry Andric #define CALLEE_SAVED_GPRS64 \
141cfca06d7SDimitry Andric {PPC::X31, -8}, \
142cfca06d7SDimitry Andric {PPC::X30, -16}, \
143cfca06d7SDimitry Andric {PPC::X29, -24}, \
144cfca06d7SDimitry Andric {PPC::X28, -32}, \
145cfca06d7SDimitry Andric {PPC::X27, -40}, \
146cfca06d7SDimitry Andric {PPC::X26, -48}, \
147cfca06d7SDimitry Andric {PPC::X25, -56}, \
148cfca06d7SDimitry Andric {PPC::X24, -64}, \
149cfca06d7SDimitry Andric {PPC::X23, -72}, \
150cfca06d7SDimitry Andric {PPC::X22, -80}, \
151cfca06d7SDimitry Andric {PPC::X21, -88}, \
152cfca06d7SDimitry Andric {PPC::X20, -96}, \
153cfca06d7SDimitry Andric {PPC::X19, -104}, \
154cfca06d7SDimitry Andric {PPC::X18, -112}, \
155cfca06d7SDimitry Andric {PPC::X17, -120}, \
156cfca06d7SDimitry Andric {PPC::X16, -128}, \
157cfca06d7SDimitry Andric {PPC::X15, -136}, \
158cfca06d7SDimitry Andric {PPC::X14, -144}
159cfca06d7SDimitry Andric
160cfca06d7SDimitry Andric // Vector register save area offsets.
161cfca06d7SDimitry Andric #define CALLEE_SAVED_VRS \
162cfca06d7SDimitry Andric {PPC::V31, -16}, \
163cfca06d7SDimitry Andric {PPC::V30, -32}, \
164cfca06d7SDimitry Andric {PPC::V29, -48}, \
165cfca06d7SDimitry Andric {PPC::V28, -64}, \
166cfca06d7SDimitry Andric {PPC::V27, -80}, \
167cfca06d7SDimitry Andric {PPC::V26, -96}, \
168cfca06d7SDimitry Andric {PPC::V25, -112}, \
169cfca06d7SDimitry Andric {PPC::V24, -128}, \
170cfca06d7SDimitry Andric {PPC::V23, -144}, \
171cfca06d7SDimitry Andric {PPC::V22, -160}, \
172cfca06d7SDimitry Andric {PPC::V21, -176}, \
173cfca06d7SDimitry Andric {PPC::V20, -192}
1745ca98fd9SDimitry Andric
1755ca98fd9SDimitry Andric // Note that the offsets here overlap, but this is fixed up in
1765ca98fd9SDimitry Andric // processFunctionBeforeFrameFinalized.
1775ca98fd9SDimitry Andric
178cfca06d7SDimitry Andric static const SpillSlot ELFOffsets32[] = {
179cfca06d7SDimitry Andric CALLEE_SAVED_FPRS,
180cfca06d7SDimitry Andric CALLEE_SAVED_GPRS32,
1815ca98fd9SDimitry Andric
1825ca98fd9SDimitry Andric // CR save area offset. We map each of the nonvolatile CR fields
1835ca98fd9SDimitry Andric // to the slot for CR2, which is the first of the nonvolatile CR
1845ca98fd9SDimitry Andric // fields to be assigned, so that we only allocate one save slot.
1855ca98fd9SDimitry Andric // See PPCRegisterInfo::hasReservedSpillSlot() for more information.
1865ca98fd9SDimitry Andric {PPC::CR2, -4},
1875ca98fd9SDimitry Andric
1885ca98fd9SDimitry Andric // VRSAVE save area offset.
1895ca98fd9SDimitry Andric {PPC::VRSAVE, -4},
1905ca98fd9SDimitry Andric
191cfca06d7SDimitry Andric CALLEE_SAVED_VRS,
192eb11fae6SDimitry Andric
193eb11fae6SDimitry Andric // SPE register save area (overlaps Vector save area).
194eb11fae6SDimitry Andric {PPC::S31, -8},
195eb11fae6SDimitry Andric {PPC::S30, -16},
196eb11fae6SDimitry Andric {PPC::S29, -24},
197eb11fae6SDimitry Andric {PPC::S28, -32},
198eb11fae6SDimitry Andric {PPC::S27, -40},
199eb11fae6SDimitry Andric {PPC::S26, -48},
200eb11fae6SDimitry Andric {PPC::S25, -56},
201eb11fae6SDimitry Andric {PPC::S24, -64},
202eb11fae6SDimitry Andric {PPC::S23, -72},
203eb11fae6SDimitry Andric {PPC::S22, -80},
204eb11fae6SDimitry Andric {PPC::S21, -88},
205eb11fae6SDimitry Andric {PPC::S20, -96},
206eb11fae6SDimitry Andric {PPC::S19, -104},
207eb11fae6SDimitry Andric {PPC::S18, -112},
208eb11fae6SDimitry Andric {PPC::S17, -120},
209eb11fae6SDimitry Andric {PPC::S16, -128},
210eb11fae6SDimitry Andric {PPC::S15, -136},
211eb11fae6SDimitry Andric {PPC::S14, -144}};
2125ca98fd9SDimitry Andric
213cfca06d7SDimitry Andric static const SpillSlot ELFOffsets64[] = {
214cfca06d7SDimitry Andric CALLEE_SAVED_FPRS,
215cfca06d7SDimitry Andric CALLEE_SAVED_GPRS64,
2165ca98fd9SDimitry Andric
2175ca98fd9SDimitry Andric // VRSAVE save area offset.
2185ca98fd9SDimitry Andric {PPC::VRSAVE, -4},
219cfca06d7SDimitry Andric CALLEE_SAVED_VRS
220cfca06d7SDimitry Andric };
2215ca98fd9SDimitry Andric
222b60736ecSDimitry Andric static const SpillSlot AIXOffsets32[] = {CALLEE_SAVED_FPRS,
223cfca06d7SDimitry Andric CALLEE_SAVED_GPRS32,
224cfca06d7SDimitry Andric // Add AIX's extra CSR.
225cfca06d7SDimitry Andric {PPC::R13, -76},
226b60736ecSDimitry Andric CALLEE_SAVED_VRS};
227cfca06d7SDimitry Andric
228cfca06d7SDimitry Andric static const SpillSlot AIXOffsets64[] = {
229b60736ecSDimitry Andric CALLEE_SAVED_FPRS, CALLEE_SAVED_GPRS64, CALLEE_SAVED_VRS};
230cfca06d7SDimitry Andric
231cfca06d7SDimitry Andric if (Subtarget.is64BitELFABI()) {
232e3b55780SDimitry Andric NumEntries = std::size(ELFOffsets64);
233cfca06d7SDimitry Andric return ELFOffsets64;
234cfca06d7SDimitry Andric }
235cfca06d7SDimitry Andric
236cfca06d7SDimitry Andric if (Subtarget.is32BitELFABI()) {
237e3b55780SDimitry Andric NumEntries = std::size(ELFOffsets32);
238cfca06d7SDimitry Andric return ELFOffsets32;
239cfca06d7SDimitry Andric }
240cfca06d7SDimitry Andric
241cfca06d7SDimitry Andric assert(Subtarget.isAIXABI() && "Unexpected ABI.");
2425ca98fd9SDimitry Andric
2435ca98fd9SDimitry Andric if (Subtarget.isPPC64()) {
244e3b55780SDimitry Andric NumEntries = std::size(AIXOffsets64);
245cfca06d7SDimitry Andric return AIXOffsets64;
2465ca98fd9SDimitry Andric }
247cfca06d7SDimitry Andric
248e3b55780SDimitry Andric NumEntries = std::size(AIXOffsets32);
249cfca06d7SDimitry Andric return AIXOffsets32;
2505ca98fd9SDimitry Andric }
2515ca98fd9SDimitry Andric
spillsCR(const MachineFunction & MF)252522600a2SDimitry Andric static bool spillsCR(const MachineFunction &MF) {
253522600a2SDimitry Andric const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
254522600a2SDimitry Andric return FuncInfo->isCRSpilled();
255522600a2SDimitry Andric }
256522600a2SDimitry Andric
hasSpills(const MachineFunction & MF)2574a16efa3SDimitry Andric static bool hasSpills(const MachineFunction &MF) {
2584a16efa3SDimitry Andric const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
2594a16efa3SDimitry Andric return FuncInfo->hasSpills();
2604a16efa3SDimitry Andric }
2614a16efa3SDimitry Andric
hasNonRISpills(const MachineFunction & MF)2624a16efa3SDimitry Andric static bool hasNonRISpills(const MachineFunction &MF) {
2634a16efa3SDimitry Andric const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
2644a16efa3SDimitry Andric return FuncInfo->hasNonRISpills();
2654a16efa3SDimitry Andric }
2664a16efa3SDimitry Andric
2675a5ac124SDimitry Andric /// MustSaveLR - Return true if this function requires that we save the LR
2685a5ac124SDimitry Andric /// register onto the stack in the prolog and restore it in the epilog of the
2695a5ac124SDimitry Andric /// function.
MustSaveLR(const MachineFunction & MF,unsigned LR)2705a5ac124SDimitry Andric static bool MustSaveLR(const MachineFunction &MF, unsigned LR) {
2715a5ac124SDimitry Andric const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>();
2725a5ac124SDimitry Andric
2735a5ac124SDimitry Andric // We need a save/restore of LR if there is any def of LR (which is
2745a5ac124SDimitry Andric // defined by calls, including the PIC setup sequence), or if there is
2755a5ac124SDimitry Andric // some use of the LR stack slot (e.g. for builtin_return_address).
2765a5ac124SDimitry Andric // (LR comes in 32 and 64 bit versions.)
2775a5ac124SDimitry Andric MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR);
2785a5ac124SDimitry Andric return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired();
2795a5ac124SDimitry Andric }
2805a5ac124SDimitry Andric
281e6d15924SDimitry Andric /// determineFrameLayoutAndUpdate - Determine the size of the frame and maximum
282e6d15924SDimitry Andric /// call frame size. Update the MachineFunction object with the stack size.
283c0981da4SDimitry Andric uint64_t
determineFrameLayoutAndUpdate(MachineFunction & MF,bool UseEstimate) const284e6d15924SDimitry Andric PPCFrameLowering::determineFrameLayoutAndUpdate(MachineFunction &MF,
285e6d15924SDimitry Andric bool UseEstimate) const {
286e6d15924SDimitry Andric unsigned NewMaxCallFrameSize = 0;
287c0981da4SDimitry Andric uint64_t FrameSize = determineFrameLayout(MF, UseEstimate,
288e6d15924SDimitry Andric &NewMaxCallFrameSize);
289e6d15924SDimitry Andric MF.getFrameInfo().setStackSize(FrameSize);
290e6d15924SDimitry Andric MF.getFrameInfo().setMaxCallFrameSize(NewMaxCallFrameSize);
291e6d15924SDimitry Andric return FrameSize;
292e6d15924SDimitry Andric }
293e6d15924SDimitry Andric
294cf099d11SDimitry Andric /// determineFrameLayout - Determine the size of the frame and maximum call
295cf099d11SDimitry Andric /// frame size.
296c0981da4SDimitry Andric uint64_t
determineFrameLayout(const MachineFunction & MF,bool UseEstimate,unsigned * NewMaxCallFrameSize) const297e6d15924SDimitry Andric PPCFrameLowering::determineFrameLayout(const MachineFunction &MF,
298e6d15924SDimitry Andric bool UseEstimate,
299e6d15924SDimitry Andric unsigned *NewMaxCallFrameSize) const {
300e6d15924SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
301e6d15924SDimitry Andric const PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
302cf099d11SDimitry Andric
303cf099d11SDimitry Andric // Get the number of bytes to allocate from the FrameInfo
304c0981da4SDimitry Andric uint64_t FrameSize =
305b915e9e0SDimitry Andric UseEstimate ? MFI.estimateStackSize(MF) : MFI.getStackSize();
306cf099d11SDimitry Andric
307f8af5cf6SDimitry Andric // Get stack alignments. The frame must be aligned to the greatest of these:
308cfca06d7SDimitry Andric Align TargetAlign = getStackAlign(); // alignment required per the ABI
309cfca06d7SDimitry Andric Align MaxAlign = MFI.getMaxAlign(); // algmt required by data in frame
310cfca06d7SDimitry Andric Align Alignment = std::max(TargetAlign, MaxAlign);
311f8af5cf6SDimitry Andric
31271d5a254SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
313cf099d11SDimitry Andric
3145a5ac124SDimitry Andric unsigned LR = RegInfo->getRARegister();
315044eb2f6SDimitry Andric bool DisableRedZone = MF.getFunction().hasFnAttribute(Attribute::NoRedZone);
316ca089b24SDimitry Andric bool CanUseRedZone = !MFI.hasVarSizedObjects() && // No dynamic alloca.
317b915e9e0SDimitry Andric !MFI.adjustsStack() && // No calls.
318ca089b24SDimitry Andric !MustSaveLR(MF, LR) && // No need to save LR.
319e6d15924SDimitry Andric !FI->mustSaveTOC() && // No need to save TOC.
320ac9a064cSDimitry Andric !RegInfo->hasBasePointer(MF) && // No special alignment.
321ac9a064cSDimitry Andric !MFI.isFrameAddressTaken();
322ca089b24SDimitry Andric
323b60736ecSDimitry Andric // Note: for PPC32 SVR4ABI, we can still generate stackless
324ca089b24SDimitry Andric // code if all local vars are reg-allocated.
325ca089b24SDimitry Andric bool FitsInRedZone = FrameSize <= Subtarget.getRedZoneSize();
326ca089b24SDimitry Andric
327ca089b24SDimitry Andric // Check whether we can skip adjusting the stack pointer (by using red zone)
328ca089b24SDimitry Andric if (!DisableRedZone && CanUseRedZone && FitsInRedZone) {
329cf099d11SDimitry Andric // No need for frame
3304a16efa3SDimitry Andric return 0;
331cf099d11SDimitry Andric }
332cf099d11SDimitry Andric
333cf099d11SDimitry Andric // Get the maximum call frame size of all the calls.
334b915e9e0SDimitry Andric unsigned maxCallFrameSize = MFI.getMaxCallFrameSize();
335cf099d11SDimitry Andric
3365ca98fd9SDimitry Andric // Maximum call frame needs to be at least big enough for linkage area.
3375a5ac124SDimitry Andric unsigned minCallFrameSize = getLinkageSize();
338cf099d11SDimitry Andric maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize);
339cf099d11SDimitry Andric
340cf099d11SDimitry Andric // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
341cf099d11SDimitry Andric // that allocations will be aligned.
342b915e9e0SDimitry Andric if (MFI.hasVarSizedObjects())
343cfca06d7SDimitry Andric maxCallFrameSize = alignTo(maxCallFrameSize, Alignment);
344cf099d11SDimitry Andric
345e6d15924SDimitry Andric // Update the new max call frame size if the caller passes in a valid pointer.
346e6d15924SDimitry Andric if (NewMaxCallFrameSize)
347e6d15924SDimitry Andric *NewMaxCallFrameSize = maxCallFrameSize;
348cf099d11SDimitry Andric
349cf099d11SDimitry Andric // Include call frame size in total.
350cf099d11SDimitry Andric FrameSize += maxCallFrameSize;
351cf099d11SDimitry Andric
352cf099d11SDimitry Andric // Make sure the frame is aligned.
353cfca06d7SDimitry Andric FrameSize = alignTo(FrameSize, Alignment);
354cf099d11SDimitry Andric
3554a16efa3SDimitry Andric return FrameSize;
356cf099d11SDimitry Andric }
357cf099d11SDimitry Andric
358cf099d11SDimitry Andric // hasFP - Return true if the specified function actually has a dedicated frame
359cf099d11SDimitry Andric // pointer register.
hasFP(const MachineFunction & MF) const360cf099d11SDimitry Andric bool PPCFrameLowering::hasFP(const MachineFunction &MF) const {
361b915e9e0SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
362cf099d11SDimitry Andric // FIXME: This is pretty much broken by design: hasFP() might be called really
363cf099d11SDimitry Andric // early, before the stack layout was calculated and thus hasFP() might return
364cf099d11SDimitry Andric // true or false here depending on the time of call.
365b915e9e0SDimitry Andric return (MFI.getStackSize()) && needsFP(MF);
366cf099d11SDimitry Andric }
367cf099d11SDimitry Andric
368cf099d11SDimitry Andric // needsFP - Return true if the specified function should have a dedicated frame
369cf099d11SDimitry Andric // pointer register. This is true if the function has variable sized allocas or
370cf099d11SDimitry Andric // if frame pointer elimination is disabled.
needsFP(const MachineFunction & MF) const371cf099d11SDimitry Andric bool PPCFrameLowering::needsFP(const MachineFunction &MF) const {
372b915e9e0SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
373cf099d11SDimitry Andric
374cf099d11SDimitry Andric // Naked functions have no stack frame pushed, so we don't have a frame
375cf099d11SDimitry Andric // pointer.
376044eb2f6SDimitry Andric if (MF.getFunction().hasFnAttribute(Attribute::Naked))
377cf099d11SDimitry Andric return false;
378cf099d11SDimitry Andric
37963faed5bSDimitry Andric return MF.getTarget().Options.DisableFramePointerElim(MF) ||
380b915e9e0SDimitry Andric MFI.hasVarSizedObjects() || MFI.hasStackMap() || MFI.hasPatchPoint() ||
381b60736ecSDimitry Andric MF.exposesReturnsTwice() ||
38263faed5bSDimitry Andric (MF.getTarget().Options.GuaranteedTailCallOpt &&
38363faed5bSDimitry Andric MF.getInfo<PPCFunctionInfo>()->hasFastCall());
384cf099d11SDimitry Andric }
385cf099d11SDimitry Andric
replaceFPWithRealFP(MachineFunction & MF) const3864a16efa3SDimitry Andric void PPCFrameLowering::replaceFPWithRealFP(MachineFunction &MF) const {
387ac9a064cSDimitry Andric // When there is dynamic alloca in this function, we can not use the frame
388ac9a064cSDimitry Andric // pointer X31/R31 for the frameaddress lowering. In this case, only X1/R1
389ac9a064cSDimitry Andric // always points to the backchain.
390ac9a064cSDimitry Andric bool is31 = needsFP(MF) && !MF.getFrameInfo().hasVarSizedObjects();
3914a16efa3SDimitry Andric unsigned FPReg = is31 ? PPC::R31 : PPC::R1;
3924a16efa3SDimitry Andric unsigned FP8Reg = is31 ? PPC::X31 : PPC::X1;
3934a16efa3SDimitry Andric
39471d5a254SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
395f8af5cf6SDimitry Andric bool HasBP = RegInfo->hasBasePointer(MF);
3965ca98fd9SDimitry Andric unsigned BPReg = HasBP ? (unsigned) RegInfo->getBaseRegister(MF) : FPReg;
39708bbd35aSDimitry Andric unsigned BP8Reg = HasBP ? (unsigned) PPC::X30 : FP8Reg;
398f8af5cf6SDimitry Andric
399f65dcba8SDimitry Andric for (MachineBasicBlock &MBB : MF)
400f65dcba8SDimitry Andric for (MachineBasicBlock::iterator MBBI = MBB.end(); MBBI != MBB.begin();) {
4014a16efa3SDimitry Andric --MBBI;
4027fa27ce4SDimitry Andric for (MachineOperand &MO : MBBI->operands()) {
4034a16efa3SDimitry Andric if (!MO.isReg())
4044a16efa3SDimitry Andric continue;
4054a16efa3SDimitry Andric
4064a16efa3SDimitry Andric switch (MO.getReg()) {
4074a16efa3SDimitry Andric case PPC::FP:
4084a16efa3SDimitry Andric MO.setReg(FPReg);
4094a16efa3SDimitry Andric break;
4104a16efa3SDimitry Andric case PPC::FP8:
4114a16efa3SDimitry Andric MO.setReg(FP8Reg);
4124a16efa3SDimitry Andric break;
413f8af5cf6SDimitry Andric case PPC::BP:
414f8af5cf6SDimitry Andric MO.setReg(BPReg);
415f8af5cf6SDimitry Andric break;
416f8af5cf6SDimitry Andric case PPC::BP8:
417f8af5cf6SDimitry Andric MO.setReg(BP8Reg);
418f8af5cf6SDimitry Andric break;
419f8af5cf6SDimitry Andric
4204a16efa3SDimitry Andric }
4214a16efa3SDimitry Andric }
4224a16efa3SDimitry Andric }
4234a16efa3SDimitry Andric }
424cf099d11SDimitry Andric
425d9c9bd84SDimitry Andric /* This function will do the following:
426d9c9bd84SDimitry Andric - If MBB is an entry or exit block, set SR1 and SR2 to R0 and R12
427d9c9bd84SDimitry Andric respectively (defaults recommended by the ABI) and return true
428d9c9bd84SDimitry Andric - If MBB is not an entry block, initialize the register scavenger and look
429d9c9bd84SDimitry Andric for available registers.
430d9c9bd84SDimitry Andric - If the defaults (R0/R12) are available, return true
431d9c9bd84SDimitry Andric - If TwoUniqueRegsRequired is set to true, it looks for two unique
432d9c9bd84SDimitry Andric registers. Otherwise, look for a single available register.
433d9c9bd84SDimitry Andric - If the required registers are found, set SR1 and SR2 and return true.
434d9c9bd84SDimitry Andric - If the required registers are not found, set SR2 or both SR1 and SR2 to
435d9c9bd84SDimitry Andric PPC::NoRegister and return false.
436d9c9bd84SDimitry Andric
437d9c9bd84SDimitry Andric Note that if both SR1 and SR2 are valid parameters and TwoUniqueRegsRequired
438d9c9bd84SDimitry Andric is not set, this function will attempt to find two different registers, but
439d9c9bd84SDimitry Andric still return true if only one register is available (and set SR1 == SR2).
440d9c9bd84SDimitry Andric */
441d9c9bd84SDimitry Andric bool
findScratchRegister(MachineBasicBlock * MBB,bool UseAtEnd,bool TwoUniqueRegsRequired,Register * SR1,Register * SR2) const442d9c9bd84SDimitry Andric PPCFrameLowering::findScratchRegister(MachineBasicBlock *MBB,
443dd58ef01SDimitry Andric bool UseAtEnd,
444d9c9bd84SDimitry Andric bool TwoUniqueRegsRequired,
445cfca06d7SDimitry Andric Register *SR1,
446cfca06d7SDimitry Andric Register *SR2) const {
447dd58ef01SDimitry Andric RegScavenger RS;
448cfca06d7SDimitry Andric Register R0 = Subtarget.isPPC64() ? PPC::X0 : PPC::R0;
449cfca06d7SDimitry Andric Register R12 = Subtarget.isPPC64() ? PPC::X12 : PPC::R12;
450dd58ef01SDimitry Andric
451d9c9bd84SDimitry Andric // Set the defaults for the two scratch registers.
452d9c9bd84SDimitry Andric if (SR1)
453d9c9bd84SDimitry Andric *SR1 = R0;
454dd58ef01SDimitry Andric
455d9c9bd84SDimitry Andric if (SR2) {
456d9c9bd84SDimitry Andric assert (SR1 && "Asking for the second scratch register but not the first?");
457d9c9bd84SDimitry Andric *SR2 = R12;
458d9c9bd84SDimitry Andric }
459d9c9bd84SDimitry Andric
460d9c9bd84SDimitry Andric // If MBB is an entry or exit block, use R0 and R12 as the scratch registers.
461dd58ef01SDimitry Andric if ((UseAtEnd && MBB->isReturnBlock()) ||
462dd58ef01SDimitry Andric (!UseAtEnd && (&MBB->getParent()->front() == MBB)))
463dd58ef01SDimitry Andric return true;
464dd58ef01SDimitry Andric
4657fa27ce4SDimitry Andric if (UseAtEnd) {
4667fa27ce4SDimitry Andric // The scratch register will be used before the first terminator (or at the
4677fa27ce4SDimitry Andric // end of the block if there are no terminators).
468dd58ef01SDimitry Andric MachineBasicBlock::iterator MBBI = MBB->getFirstTerminator();
4697fa27ce4SDimitry Andric if (MBBI == MBB->begin()) {
4707fa27ce4SDimitry Andric RS.enterBasicBlock(*MBB);
4717fa27ce4SDimitry Andric } else {
4727fa27ce4SDimitry Andric RS.enterBasicBlockEnd(*MBB);
473b1c73532SDimitry Andric RS.backward(MBBI);
4747fa27ce4SDimitry Andric }
4757fa27ce4SDimitry Andric } else {
4767fa27ce4SDimitry Andric // The scratch register will be used at the start of the block.
4777fa27ce4SDimitry Andric RS.enterBasicBlock(*MBB);
478dd58ef01SDimitry Andric }
479dd58ef01SDimitry Andric
480d9c9bd84SDimitry Andric // If the two registers are available, we're all good.
481d9c9bd84SDimitry Andric // Note that we only return here if both R0 and R12 are available because
482d9c9bd84SDimitry Andric // although the function may not require two unique registers, it may benefit
483d9c9bd84SDimitry Andric // from having two so we should try to provide them.
484d9c9bd84SDimitry Andric if (!RS.isRegUsed(R0) && !RS.isRegUsed(R12))
485dd58ef01SDimitry Andric return true;
486dd58ef01SDimitry Andric
487d9c9bd84SDimitry Andric // Get the list of callee-saved registers for the target.
48871d5a254SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
489d9c9bd84SDimitry Andric const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(MBB->getParent());
490dd58ef01SDimitry Andric
491d9c9bd84SDimitry Andric // Get all the available registers in the block.
492d9c9bd84SDimitry Andric BitVector BV = RS.getRegsAvailable(Subtarget.isPPC64() ? &PPC::G8RCRegClass :
493d9c9bd84SDimitry Andric &PPC::GPRCRegClass);
494d9c9bd84SDimitry Andric
495d9c9bd84SDimitry Andric // We shouldn't use callee-saved registers as scratch registers as they may be
496d9c9bd84SDimitry Andric // available when looking for a candidate block for shrink wrapping but not
497d9c9bd84SDimitry Andric // available when the actual prologue/epilogue is being emitted because they
498d9c9bd84SDimitry Andric // were added as live-in to the prologue block by PrologueEpilogueInserter.
499d9c9bd84SDimitry Andric for (int i = 0; CSRegs[i]; ++i)
500d9c9bd84SDimitry Andric BV.reset(CSRegs[i]);
501d9c9bd84SDimitry Andric
502d9c9bd84SDimitry Andric // Set the first scratch register to the first available one.
503d9c9bd84SDimitry Andric if (SR1) {
504d9c9bd84SDimitry Andric int FirstScratchReg = BV.find_first();
505d9c9bd84SDimitry Andric *SR1 = FirstScratchReg == -1 ? (unsigned)PPC::NoRegister : FirstScratchReg;
506d9c9bd84SDimitry Andric }
507d9c9bd84SDimitry Andric
508d9c9bd84SDimitry Andric // If there is another one available, set the second scratch register to that.
509d9c9bd84SDimitry Andric // Otherwise, set it to either PPC::NoRegister if this function requires two
510d9c9bd84SDimitry Andric // or to whatever SR1 is set to if this function doesn't require two.
511d9c9bd84SDimitry Andric if (SR2) {
512d9c9bd84SDimitry Andric int SecondScratchReg = BV.find_next(*SR1);
513d9c9bd84SDimitry Andric if (SecondScratchReg != -1)
514d9c9bd84SDimitry Andric *SR2 = SecondScratchReg;
515d9c9bd84SDimitry Andric else
516cfca06d7SDimitry Andric *SR2 = TwoUniqueRegsRequired ? Register() : *SR1;
517d9c9bd84SDimitry Andric }
518d9c9bd84SDimitry Andric
519d9c9bd84SDimitry Andric // Now that we've done our best to provide both registers, double check
520d9c9bd84SDimitry Andric // whether we were unable to provide enough.
52101095a5dSDimitry Andric if (BV.count() < (TwoUniqueRegsRequired ? 2U : 1U))
522dd58ef01SDimitry Andric return false;
523dd58ef01SDimitry Andric
524dd58ef01SDimitry Andric return true;
525dd58ef01SDimitry Andric }
526dd58ef01SDimitry Andric
527d9c9bd84SDimitry Andric // We need a scratch register for spilling LR and for spilling CR. By default,
528d9c9bd84SDimitry Andric // we use two scratch registers to hide latency. However, if only one scratch
529d9c9bd84SDimitry Andric // register is available, we can adjust for that by not overlapping the spill
530d9c9bd84SDimitry Andric // code. However, if we need to realign the stack (i.e. have a base pointer)
531d9c9bd84SDimitry Andric // and the stack frame is large, we need two scratch registers.
532b60736ecSDimitry Andric // Also, stack probe requires two scratch registers, one for old sp, one for
533b60736ecSDimitry Andric // large frame and large probe size.
534d9c9bd84SDimitry Andric bool
twoUniqueScratchRegsRequired(MachineBasicBlock * MBB) const535d9c9bd84SDimitry Andric PPCFrameLowering::twoUniqueScratchRegsRequired(MachineBasicBlock *MBB) const {
53671d5a254SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
537d9c9bd84SDimitry Andric MachineFunction &MF = *(MBB->getParent());
538d9c9bd84SDimitry Andric bool HasBP = RegInfo->hasBasePointer(MF);
539e6d15924SDimitry Andric unsigned FrameSize = determineFrameLayout(MF);
540d9c9bd84SDimitry Andric int NegFrameSize = -FrameSize;
541d9c9bd84SDimitry Andric bool IsLargeFrame = !isInt<16>(NegFrameSize);
542b915e9e0SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
543cfca06d7SDimitry Andric Align MaxAlign = MFI.getMaxAlign();
544b915e9e0SDimitry Andric bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
545b60736ecSDimitry Andric const PPCTargetLowering &TLI = *Subtarget.getTargetLowering();
546d9c9bd84SDimitry Andric
547b60736ecSDimitry Andric return ((IsLargeFrame || !HasRedZone) && HasBP && MaxAlign > 1) ||
548b60736ecSDimitry Andric TLI.hasInlineStackProbe(MF);
549d9c9bd84SDimitry Andric }
550d9c9bd84SDimitry Andric
canUseAsPrologue(const MachineBasicBlock & MBB) const551dd58ef01SDimitry Andric bool PPCFrameLowering::canUseAsPrologue(const MachineBasicBlock &MBB) const {
552dd58ef01SDimitry Andric MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
553dd58ef01SDimitry Andric
554d9c9bd84SDimitry Andric return findScratchRegister(TmpMBB, false,
555d9c9bd84SDimitry Andric twoUniqueScratchRegsRequired(TmpMBB));
556dd58ef01SDimitry Andric }
557dd58ef01SDimitry Andric
canUseAsEpilogue(const MachineBasicBlock & MBB) const558dd58ef01SDimitry Andric bool PPCFrameLowering::canUseAsEpilogue(const MachineBasicBlock &MBB) const {
559dd58ef01SDimitry Andric MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
560dd58ef01SDimitry Andric
561d9c9bd84SDimitry Andric return findScratchRegister(TmpMBB, true);
562dd58ef01SDimitry Andric }
563dd58ef01SDimitry Andric
stackUpdateCanBeMoved(MachineFunction & MF) const564e6d15924SDimitry Andric bool PPCFrameLowering::stackUpdateCanBeMoved(MachineFunction &MF) const {
565e6d15924SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
566e6d15924SDimitry Andric PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
567e6d15924SDimitry Andric
568e6d15924SDimitry Andric // Abort if there is no register info or function info.
569e6d15924SDimitry Andric if (!RegInfo || !FI)
570e6d15924SDimitry Andric return false;
571e6d15924SDimitry Andric
572e6d15924SDimitry Andric // Only move the stack update on ELFv2 ABI and PPC64.
573e6d15924SDimitry Andric if (!Subtarget.isELFv2ABI() || !Subtarget.isPPC64())
574e6d15924SDimitry Andric return false;
575e6d15924SDimitry Andric
576e6d15924SDimitry Andric // Check the frame size first and return false if it does not fit the
577e6d15924SDimitry Andric // requirements.
578e6d15924SDimitry Andric // We need a non-zero frame size as well as a frame that will fit in the red
579e6d15924SDimitry Andric // zone. This is because by moving the stack pointer update we are now storing
580e6d15924SDimitry Andric // to the red zone until the stack pointer is updated. If we get an interrupt
581e6d15924SDimitry Andric // inside the prologue but before the stack update we now have a number of
582e6d15924SDimitry Andric // stores to the red zone and those stores must all fit.
583e6d15924SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
584e6d15924SDimitry Andric unsigned FrameSize = MFI.getStackSize();
585e6d15924SDimitry Andric if (!FrameSize || FrameSize > Subtarget.getRedZoneSize())
586e6d15924SDimitry Andric return false;
587e6d15924SDimitry Andric
588e6d15924SDimitry Andric // Frame pointers and base pointers complicate matters so don't do anything
589e6d15924SDimitry Andric // if we have them. For example having a frame pointer will sometimes require
590e6d15924SDimitry Andric // a copy of r1 into r31 and that makes keeping track of updates to r1 more
591b60736ecSDimitry Andric // difficult. Similar situation exists with setjmp.
592b60736ecSDimitry Andric if (hasFP(MF) || RegInfo->hasBasePointer(MF) || MF.exposesReturnsTwice())
593e6d15924SDimitry Andric return false;
594e6d15924SDimitry Andric
595e6d15924SDimitry Andric // Calls to fast_cc functions use different rules for passing parameters on
596e6d15924SDimitry Andric // the stack from the ABI and using PIC base in the function imposes
597e6d15924SDimitry Andric // similar restrictions to using the base pointer. It is not generally safe
598e6d15924SDimitry Andric // to move the stack pointer update in these situations.
599e6d15924SDimitry Andric if (FI->hasFastCall() || FI->usesPICBase())
600e6d15924SDimitry Andric return false;
601e6d15924SDimitry Andric
602e6d15924SDimitry Andric // Finally we can move the stack update if we do not require register
603e6d15924SDimitry Andric // scavenging. Register scavenging can introduce more spills and so
604e6d15924SDimitry Andric // may make the frame size larger than we have computed.
605e6d15924SDimitry Andric return !RegInfo->requiresFrameIndexScavenging(MF);
606e6d15924SDimitry Andric }
607e6d15924SDimitry Andric
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const6085a5ac124SDimitry Andric void PPCFrameLowering::emitPrologue(MachineFunction &MF,
6095a5ac124SDimitry Andric MachineBasicBlock &MBB) const {
610cf099d11SDimitry Andric MachineBasicBlock::iterator MBBI = MBB.begin();
611b915e9e0SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
61271d5a254SDimitry Andric const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
61371d5a254SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
614cfca06d7SDimitry Andric const PPCTargetLowering &TLI = *Subtarget.getTargetLowering();
615cf099d11SDimitry Andric
616ac9a064cSDimitry Andric const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
617cf099d11SDimitry Andric DebugLoc dl;
618cfca06d7SDimitry Andric // AIX assembler does not support cfi directives.
619cfca06d7SDimitry Andric const bool needsCFI = MF.needsFrameMoves() && !Subtarget.isAIXABI();
620cf099d11SDimitry Andric
621e3b55780SDimitry Andric const bool HasFastMFLR = Subtarget.hasFastMFLR();
622e3b55780SDimitry Andric
623f8af5cf6SDimitry Andric // Get processor type.
624f8af5cf6SDimitry Andric bool isPPC64 = Subtarget.isPPC64();
625f8af5cf6SDimitry Andric // Get the ABI.
626f8af5cf6SDimitry Andric bool isSVR4ABI = Subtarget.isSVR4ABI();
6275ca98fd9SDimitry Andric bool isELFv2ABI = Subtarget.isELFv2ABI();
628b60736ecSDimitry Andric assert((isSVR4ABI || Subtarget.isAIXABI()) && "Unsupported PPC ABI.");
629cf099d11SDimitry Andric
630cf099d11SDimitry Andric // Work out frame sizes.
631c0981da4SDimitry Andric uint64_t FrameSize = determineFrameLayoutAndUpdate(MF);
632c0981da4SDimitry Andric int64_t NegFrameSize = -FrameSize;
633145449b1SDimitry Andric if (!isPPC64 && (!isInt<32>(FrameSize) || !isInt<32>(NegFrameSize)))
634f8af5cf6SDimitry Andric llvm_unreachable("Unhandled stack size!");
635cf099d11SDimitry Andric
636b915e9e0SDimitry Andric if (MFI.isFrameAddressTaken())
6374a16efa3SDimitry Andric replaceFPWithRealFP(MF);
6384a16efa3SDimitry Andric
639cf099d11SDimitry Andric // Check if the link register (LR) must be saved.
640cf099d11SDimitry Andric PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
641cf099d11SDimitry Andric bool MustSaveLR = FI->mustSaveLR();
642e6d15924SDimitry Andric bool MustSaveTOC = FI->mustSaveTOC();
643cfca06d7SDimitry Andric const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
644d9c9bd84SDimitry Andric bool MustSaveCR = !MustSaveCRs.empty();
645f8af5cf6SDimitry Andric // Do we have a frame pointer and/or base pointer for this function?
646cf099d11SDimitry Andric bool HasFP = hasFP(MF);
647f8af5cf6SDimitry Andric bool HasBP = RegInfo->hasBasePointer(MF);
648b915e9e0SDimitry Andric bool HasRedZone = isPPC64 || !isSVR4ABI;
649344a3780SDimitry Andric bool HasROPProtect = Subtarget.hasROPProtect();
650344a3780SDimitry Andric bool HasPrivileged = Subtarget.hasPrivileged();
651f8af5cf6SDimitry Andric
652cfca06d7SDimitry Andric Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
6531d5ae102SDimitry Andric Register BPReg = RegInfo->getBaseRegister(MF);
654cfca06d7SDimitry Andric Register FPReg = isPPC64 ? PPC::X31 : PPC::R31;
655cfca06d7SDimitry Andric Register LRReg = isPPC64 ? PPC::LR8 : PPC::LR;
656cfca06d7SDimitry Andric Register TOCReg = isPPC64 ? PPC::X2 : PPC::R2;
657cfca06d7SDimitry Andric Register ScratchReg;
658cfca06d7SDimitry Andric Register TempReg = isPPC64 ? PPC::X12 : PPC::R12; // another scratch reg
659f8af5cf6SDimitry Andric // ...(R12/X12 is volatile in both Darwin & SVR4, & can't be a function arg.)
660f8af5cf6SDimitry Andric const MCInstrDesc& MFLRInst = TII.get(isPPC64 ? PPC::MFLR8
661f8af5cf6SDimitry Andric : PPC::MFLR );
662f8af5cf6SDimitry Andric const MCInstrDesc& StoreInst = TII.get(isPPC64 ? PPC::STD
663f8af5cf6SDimitry Andric : PPC::STW );
664f8af5cf6SDimitry Andric const MCInstrDesc& StoreUpdtInst = TII.get(isPPC64 ? PPC::STDU
665f8af5cf6SDimitry Andric : PPC::STWU );
666f8af5cf6SDimitry Andric const MCInstrDesc& StoreUpdtIdxInst = TII.get(isPPC64 ? PPC::STDUX
667f8af5cf6SDimitry Andric : PPC::STWUX);
668f8af5cf6SDimitry Andric const MCInstrDesc& OrInst = TII.get(isPPC64 ? PPC::OR8
669f8af5cf6SDimitry Andric : PPC::OR );
670f8af5cf6SDimitry Andric const MCInstrDesc& SubtractCarryingInst = TII.get(isPPC64 ? PPC::SUBFC8
671f8af5cf6SDimitry Andric : PPC::SUBFC);
672f8af5cf6SDimitry Andric const MCInstrDesc& SubtractImmCarryingInst = TII.get(isPPC64 ? PPC::SUBFIC8
673f8af5cf6SDimitry Andric : PPC::SUBFIC);
674cfca06d7SDimitry Andric const MCInstrDesc &MoveFromCondRegInst = TII.get(isPPC64 ? PPC::MFCR8
675cfca06d7SDimitry Andric : PPC::MFCR);
676cfca06d7SDimitry Andric const MCInstrDesc &StoreWordInst = TII.get(isPPC64 ? PPC::STW8 : PPC::STW);
677344a3780SDimitry Andric const MCInstrDesc &HashST =
6786f8fc217SDimitry Andric TII.get(isPPC64 ? (HasPrivileged ? PPC::HASHSTP8 : PPC::HASHST8)
6796f8fc217SDimitry Andric : (HasPrivileged ? PPC::HASHSTP : PPC::HASHST));
680f8af5cf6SDimitry Andric
681f8af5cf6SDimitry Andric // Regarding this assert: Even though LR is saved in the caller's frame (i.e.,
682f8af5cf6SDimitry Andric // LROffset is positive), that slot is callee-owned. Because PPC32 SVR4 has no
683f8af5cf6SDimitry Andric // Red Zone, an asynchronous event (a form of "callee") could claim a frame &
684f8af5cf6SDimitry Andric // overwrite it, so PPC32 SVR4 must claim at least a minimal frame to save LR.
685f8af5cf6SDimitry Andric assert((isPPC64 || !isSVR4ABI || !(!FrameSize && (MustSaveLR || HasFP))) &&
686f8af5cf6SDimitry Andric "FrameSize must be >0 to save/restore the FP or LR for 32-bit SVR4.");
687cf099d11SDimitry Andric
688b915e9e0SDimitry Andric // Using the same bool variable as below to suppress compiler warnings.
689cfca06d7SDimitry Andric bool SingleScratchReg = findScratchRegister(
690b60736ecSDimitry Andric &MBB, false, twoUniqueScratchRegsRequired(&MBB), &ScratchReg, &TempReg);
691d9c9bd84SDimitry Andric assert(SingleScratchReg &&
692d9c9bd84SDimitry Andric "Required number of registers not available in this block");
693d9c9bd84SDimitry Andric
694d9c9bd84SDimitry Andric SingleScratchReg = ScratchReg == TempReg;
695dd58ef01SDimitry Andric
696c0981da4SDimitry Andric int64_t LROffset = getReturnSaveOffset();
697cf099d11SDimitry Andric
698c0981da4SDimitry Andric int64_t FPOffset = 0;
699cf099d11SDimitry Andric if (HasFP) {
700b915e9e0SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
701cf099d11SDimitry Andric int FPIndex = FI->getFramePointerSaveIndex();
702cf099d11SDimitry Andric assert(FPIndex && "No Frame Pointer Save Slot!");
703b915e9e0SDimitry Andric FPOffset = MFI.getObjectOffset(FPIndex);
704cf099d11SDimitry Andric }
705cf099d11SDimitry Andric
706c0981da4SDimitry Andric int64_t BPOffset = 0;
707f8af5cf6SDimitry Andric if (HasBP) {
708b915e9e0SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
709f8af5cf6SDimitry Andric int BPIndex = FI->getBasePointerSaveIndex();
710f8af5cf6SDimitry Andric assert(BPIndex && "No Base Pointer Save Slot!");
711b915e9e0SDimitry Andric BPOffset = MFI.getObjectOffset(BPIndex);
712f8af5cf6SDimitry Andric }
713cf099d11SDimitry Andric
714c0981da4SDimitry Andric int64_t PBPOffset = 0;
71567c32a98SDimitry Andric if (FI->usesPICBase()) {
716b915e9e0SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
71767c32a98SDimitry Andric int PBPIndex = FI->getPICBasePointerSaveIndex();
71867c32a98SDimitry Andric assert(PBPIndex && "No PIC Base Pointer Save Slot!");
719b915e9e0SDimitry Andric PBPOffset = MFI.getObjectOffset(PBPIndex);
72067c32a98SDimitry Andric }
72167c32a98SDimitry Andric
722f8af5cf6SDimitry Andric // Get stack alignments.
723cfca06d7SDimitry Andric Align MaxAlign = MFI.getMaxAlign();
724f8af5cf6SDimitry Andric if (HasBP && MaxAlign > 1)
725cfca06d7SDimitry Andric assert(Log2(MaxAlign) < 16 && "Invalid alignment!");
726f8af5cf6SDimitry Andric
727f8af5cf6SDimitry Andric // Frames of 32KB & larger require special handling because they cannot be
728f8af5cf6SDimitry Andric // indexed into with a simple STDU/STWU/STD/STW immediate offset operand.
729f8af5cf6SDimitry Andric bool isLargeFrame = !isInt<16>(NegFrameSize);
730f8af5cf6SDimitry Andric
731e6d15924SDimitry Andric // Check if we can move the stack update instruction (stdu) down the prologue
732e6d15924SDimitry Andric // past the callee saves. Hopefully this will avoid the situation where the
733e6d15924SDimitry Andric // saves are waiting for the update on the store with update to complete.
734e6d15924SDimitry Andric MachineBasicBlock::iterator StackUpdateLoc = MBBI;
735e6d15924SDimitry Andric bool MovingStackUpdateDown = false;
736e6d15924SDimitry Andric
737e6d15924SDimitry Andric // Check if we can move the stack update.
738e6d15924SDimitry Andric if (stackUpdateCanBeMoved(MF)) {
739e6d15924SDimitry Andric const std::vector<CalleeSavedInfo> &Info = MFI.getCalleeSavedInfo();
740e6d15924SDimitry Andric for (CalleeSavedInfo CSI : Info) {
741344a3780SDimitry Andric // If the callee saved register is spilled to a register instead of the
742344a3780SDimitry Andric // stack then the spill no longer uses the stack pointer.
743344a3780SDimitry Andric // This can lead to two consequences:
744344a3780SDimitry Andric // 1) We no longer need to update the stack because the function does not
745344a3780SDimitry Andric // spill any callee saved registers to stack.
746344a3780SDimitry Andric // 2) We have a situation where we still have to update the stack pointer
747344a3780SDimitry Andric // even though some registers are spilled to other registers. In
748344a3780SDimitry Andric // this case the current code moves the stack update to an incorrect
749344a3780SDimitry Andric // position.
750344a3780SDimitry Andric // In either case we should abort moving the stack update operation.
751344a3780SDimitry Andric if (CSI.isSpilledToReg()) {
752344a3780SDimitry Andric StackUpdateLoc = MBBI;
753344a3780SDimitry Andric MovingStackUpdateDown = false;
754344a3780SDimitry Andric break;
755344a3780SDimitry Andric }
756344a3780SDimitry Andric
757e6d15924SDimitry Andric int FrIdx = CSI.getFrameIdx();
758e6d15924SDimitry Andric // If the frame index is not negative the callee saved info belongs to a
759e6d15924SDimitry Andric // stack object that is not a fixed stack object. We ignore non-fixed
760e6d15924SDimitry Andric // stack objects because we won't move the stack update pointer past them.
761e6d15924SDimitry Andric if (FrIdx >= 0)
762e6d15924SDimitry Andric continue;
763e6d15924SDimitry Andric
764e6d15924SDimitry Andric if (MFI.isFixedObjectIndex(FrIdx) && MFI.getObjectOffset(FrIdx) < 0) {
765e6d15924SDimitry Andric StackUpdateLoc++;
766e6d15924SDimitry Andric MovingStackUpdateDown = true;
767e6d15924SDimitry Andric } else {
768e6d15924SDimitry Andric // We need all of the Frame Indices to meet these conditions.
769e6d15924SDimitry Andric // If they do not, abort the whole operation.
770e6d15924SDimitry Andric StackUpdateLoc = MBBI;
771e6d15924SDimitry Andric MovingStackUpdateDown = false;
772e6d15924SDimitry Andric break;
773e6d15924SDimitry Andric }
774e6d15924SDimitry Andric }
775e6d15924SDimitry Andric
776e6d15924SDimitry Andric // If the operation was not aborted then update the object offset.
777e6d15924SDimitry Andric if (MovingStackUpdateDown) {
778e6d15924SDimitry Andric for (CalleeSavedInfo CSI : Info) {
779e6d15924SDimitry Andric int FrIdx = CSI.getFrameIdx();
780e6d15924SDimitry Andric if (FrIdx < 0)
781e6d15924SDimitry Andric MFI.setObjectOffset(FrIdx, MFI.getObjectOffset(FrIdx) + NegFrameSize);
782e6d15924SDimitry Andric }
783e6d15924SDimitry Andric }
784e6d15924SDimitry Andric }
785e6d15924SDimitry Andric
786cfca06d7SDimitry Andric // Where in the prologue we move the CR fields depends on how many scratch
787cfca06d7SDimitry Andric // registers we have, and if we need to save the link register or not. This
788cfca06d7SDimitry Andric // lambda is to avoid duplicating the logic in 2 places.
789cfca06d7SDimitry Andric auto BuildMoveFromCR = [&]() {
790cfca06d7SDimitry Andric if (isELFv2ABI && MustSaveCRs.size() == 1) {
791cfca06d7SDimitry Andric // In the ELFv2 ABI, we are not required to save all CR fields.
792cfca06d7SDimitry Andric // If only one CR field is clobbered, it is more efficient to use
793cfca06d7SDimitry Andric // mfocrf to selectively save just that field, because mfocrf has short
794cfca06d7SDimitry Andric // latency compares to mfcr.
795cfca06d7SDimitry Andric assert(isPPC64 && "V2 ABI is 64-bit only.");
796cfca06d7SDimitry Andric MachineInstrBuilder MIB =
797cfca06d7SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::MFOCRF8), TempReg);
798cfca06d7SDimitry Andric MIB.addReg(MustSaveCRs[0], RegState::Kill);
799cfca06d7SDimitry Andric } else {
800cfca06d7SDimitry Andric MachineInstrBuilder MIB =
801cfca06d7SDimitry Andric BuildMI(MBB, MBBI, dl, MoveFromCondRegInst, TempReg);
802cfca06d7SDimitry Andric for (unsigned CRfield : MustSaveCRs)
803cfca06d7SDimitry Andric MIB.addReg(CRfield, RegState::ImplicitKill);
804cfca06d7SDimitry Andric }
805cfca06d7SDimitry Andric };
806cfca06d7SDimitry Andric
807d9c9bd84SDimitry Andric // If we need to spill the CR and the LR but we don't have two separate
808d9c9bd84SDimitry Andric // registers available, we must spill them one at a time
809d9c9bd84SDimitry Andric if (MustSaveCR && SingleScratchReg && MustSaveLR) {
810cfca06d7SDimitry Andric BuildMoveFromCR();
811cfca06d7SDimitry Andric BuildMI(MBB, MBBI, dl, StoreWordInst)
812d9c9bd84SDimitry Andric .addReg(TempReg, getKillRegState(true))
813cfca06d7SDimitry Andric .addImm(CRSaveOffset)
814d9c9bd84SDimitry Andric .addReg(SPReg);
815d9c9bd84SDimitry Andric }
816d9c9bd84SDimitry Andric
817f8af5cf6SDimitry Andric if (MustSaveLR)
818f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, MFLRInst, ScratchReg);
819f8af5cf6SDimitry Andric
820cfca06d7SDimitry Andric if (MustSaveCR && !(SingleScratchReg && MustSaveLR))
821cfca06d7SDimitry Andric BuildMoveFromCR();
82259d6cff9SDimitry Andric
823b915e9e0SDimitry Andric if (HasRedZone) {
824cf099d11SDimitry Andric if (HasFP)
825f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
826f8af5cf6SDimitry Andric .addReg(FPReg)
827cf099d11SDimitry Andric .addImm(FPOffset)
828f8af5cf6SDimitry Andric .addReg(SPReg);
82967c32a98SDimitry Andric if (FI->usesPICBase())
83067c32a98SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
83167c32a98SDimitry Andric .addReg(PPC::R30)
83267c32a98SDimitry Andric .addImm(PBPOffset)
83367c32a98SDimitry Andric .addReg(SPReg);
834f8af5cf6SDimitry Andric if (HasBP)
835f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
836f8af5cf6SDimitry Andric .addReg(BPReg)
837f8af5cf6SDimitry Andric .addImm(BPOffset)
838f8af5cf6SDimitry Andric .addReg(SPReg);
839b915e9e0SDimitry Andric }
84059d6cff9SDimitry Andric
841344a3780SDimitry Andric // Generate the instruction to store the LR. In the case where ROP protection
842344a3780SDimitry Andric // is required the register holding the LR should not be killed as it will be
843344a3780SDimitry Andric // used by the hash store instruction.
844e3b55780SDimitry Andric auto SaveLR = [&](int64_t Offset) {
845e3b55780SDimitry Andric assert(MustSaveLR && "LR is not required to be saved!");
846e6d15924SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, StoreInst)
847344a3780SDimitry Andric .addReg(ScratchReg, getKillRegState(!HasROPProtect))
848e3b55780SDimitry Andric .addImm(Offset)
849f8af5cf6SDimitry Andric .addReg(SPReg);
850cf099d11SDimitry Andric
851344a3780SDimitry Andric // Add the ROP protection Hash Store instruction.
852344a3780SDimitry Andric // NOTE: This is technically a violation of the ABI. The hash can be saved
853344a3780SDimitry Andric // up to 512 bytes into the Protected Zone. This can be outside of the
854344a3780SDimitry Andric // initial 288 byte volatile program storage region in the Protected Zone.
855344a3780SDimitry Andric // However, this restriction will be removed in an upcoming revision of the
856344a3780SDimitry Andric // ABI.
857344a3780SDimitry Andric if (HasROPProtect) {
858344a3780SDimitry Andric const int SaveIndex = FI->getROPProtectionHashSaveIndex();
859c0981da4SDimitry Andric const int64_t ImmOffset = MFI.getObjectOffset(SaveIndex);
860344a3780SDimitry Andric assert((ImmOffset <= -8 && ImmOffset >= -512) &&
861344a3780SDimitry Andric "ROP hash save offset out of range.");
862344a3780SDimitry Andric assert(((ImmOffset & 0x7) == 0) &&
863344a3780SDimitry Andric "ROP hash save offset must be 8 byte aligned.");
864344a3780SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, HashST)
865344a3780SDimitry Andric .addReg(ScratchReg, getKillRegState(true))
866344a3780SDimitry Andric .addImm(ImmOffset)
867344a3780SDimitry Andric .addReg(SPReg);
868344a3780SDimitry Andric }
869e3b55780SDimitry Andric };
870e3b55780SDimitry Andric
871e3b55780SDimitry Andric if (MustSaveLR && HasFastMFLR)
872e3b55780SDimitry Andric SaveLR(LROffset);
873344a3780SDimitry Andric
874d9c9bd84SDimitry Andric if (MustSaveCR &&
875cfca06d7SDimitry Andric !(SingleScratchReg && MustSaveLR)) {
876b915e9e0SDimitry Andric assert(HasRedZone && "A red zone is always available on PPC64");
877cfca06d7SDimitry Andric BuildMI(MBB, MBBI, dl, StoreWordInst)
878f8af5cf6SDimitry Andric .addReg(TempReg, getKillRegState(true))
879cfca06d7SDimitry Andric .addImm(CRSaveOffset)
880f8af5cf6SDimitry Andric .addReg(SPReg);
881b915e9e0SDimitry Andric }
882f8af5cf6SDimitry Andric
883f8af5cf6SDimitry Andric // Skip the rest if this is a leaf function & all spills fit in the Red Zone.
884e3b55780SDimitry Andric if (!FrameSize) {
885e3b55780SDimitry Andric if (MustSaveLR && !HasFastMFLR)
886e3b55780SDimitry Andric SaveLR(LROffset);
887b915e9e0SDimitry Andric return;
888e3b55780SDimitry Andric }
889cf099d11SDimitry Andric
890cf099d11SDimitry Andric // Adjust stack pointer: r1 += NegFrameSize.
891cf099d11SDimitry Andric // If there is a preferred stack alignment, align R1 now
892cf099d11SDimitry Andric
893b915e9e0SDimitry Andric if (HasBP && HasRedZone) {
894f8af5cf6SDimitry Andric // Save a copy of r1 as the base pointer.
895f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, BPReg)
896f8af5cf6SDimitry Andric .addReg(SPReg)
897f8af5cf6SDimitry Andric .addReg(SPReg);
898f8af5cf6SDimitry Andric }
899f8af5cf6SDimitry Andric
900b915e9e0SDimitry Andric // Have we generated a STUX instruction to claim stack frame? If so,
901b915e9e0SDimitry Andric // the negated frame size will be placed in ScratchReg.
902e3b55780SDimitry Andric bool HasSTUX =
903e3b55780SDimitry Andric (TLI.hasInlineStackProbe(MF) && FrameSize > TLI.getStackProbeSize(MF)) ||
904e3b55780SDimitry Andric (HasBP && MaxAlign > 1) || isLargeFrame;
905e3b55780SDimitry Andric
906e3b55780SDimitry Andric // If we use STUX to update the stack pointer, we need the two scratch
907e3b55780SDimitry Andric // registers TempReg and ScratchReg, we have to save LR here which is stored
908e3b55780SDimitry Andric // in ScratchReg.
909e3b55780SDimitry Andric // If the offset can not be encoded into the store instruction, we also have
910e3b55780SDimitry Andric // to save LR here.
911e3b55780SDimitry Andric if (MustSaveLR && !HasFastMFLR &&
912e3b55780SDimitry Andric (HasSTUX || !isInt<16>(FrameSize + LROffset)))
913e3b55780SDimitry Andric SaveLR(LROffset);
914b915e9e0SDimitry Andric
915cfca06d7SDimitry Andric // If FrameSize <= TLI.getStackProbeSize(MF), as POWER ABI requires backchain
916cfca06d7SDimitry Andric // pointer is always stored at SP, we will get a free probe due to an essential
917cfca06d7SDimitry Andric // STU(X) instruction.
918cfca06d7SDimitry Andric if (TLI.hasInlineStackProbe(MF) && FrameSize > TLI.getStackProbeSize(MF)) {
919cfca06d7SDimitry Andric // To be consistent with other targets, a pseudo instruction is emitted and
920cfca06d7SDimitry Andric // will be later expanded in `inlineStackProbe`.
921cfca06d7SDimitry Andric BuildMI(MBB, MBBI, dl,
922cfca06d7SDimitry Andric TII.get(isPPC64 ? PPC::PROBED_STACKALLOC_64
923cfca06d7SDimitry Andric : PPC::PROBED_STACKALLOC_32))
924344a3780SDimitry Andric .addDef(TempReg)
925344a3780SDimitry Andric .addDef(ScratchReg) // ScratchReg stores the old sp.
926cfca06d7SDimitry Andric .addImm(NegFrameSize);
927cfca06d7SDimitry Andric // FIXME: HasSTUX is only read if HasRedZone is not set, in such case, we
928cfca06d7SDimitry Andric // update the ScratchReg to meet the assumption that ScratchReg contains
929cfca06d7SDimitry Andric // the NegFrameSize. This solution is rather tricky.
930cfca06d7SDimitry Andric if (!HasRedZone) {
931cfca06d7SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBF), ScratchReg)
932344a3780SDimitry Andric .addReg(ScratchReg)
933cfca06d7SDimitry Andric .addReg(SPReg);
934cfca06d7SDimitry Andric }
935cfca06d7SDimitry Andric } else {
936d9c9bd84SDimitry Andric // This condition must be kept in sync with canUseAsPrologue.
937f8af5cf6SDimitry Andric if (HasBP && MaxAlign > 1) {
938f8af5cf6SDimitry Andric if (isPPC64)
939f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::RLDICL), ScratchReg)
940f8af5cf6SDimitry Andric .addReg(SPReg)
941f8af5cf6SDimitry Andric .addImm(0)
942cfca06d7SDimitry Andric .addImm(64 - Log2(MaxAlign));
943f8af5cf6SDimitry Andric else // PPC32...
944f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::RLWINM), ScratchReg)
945f8af5cf6SDimitry Andric .addReg(SPReg)
946cf099d11SDimitry Andric .addImm(0)
947cfca06d7SDimitry Andric .addImm(32 - Log2(MaxAlign))
948cf099d11SDimitry Andric .addImm(31);
949f8af5cf6SDimitry Andric if (!isLargeFrame) {
950f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, SubtractImmCarryingInst, ScratchReg)
951f8af5cf6SDimitry Andric .addReg(ScratchReg, RegState::Kill)
952cf099d11SDimitry Andric .addImm(NegFrameSize);
953f8af5cf6SDimitry Andric } else {
954d9c9bd84SDimitry Andric assert(!SingleScratchReg && "Only a single scratch reg available");
955145449b1SDimitry Andric TII.materializeImmPostRA(MBB, MBBI, dl, TempReg, NegFrameSize);
956f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, SubtractCarryingInst, ScratchReg)
957f8af5cf6SDimitry Andric .addReg(ScratchReg, RegState::Kill)
958f8af5cf6SDimitry Andric .addReg(TempReg, RegState::Kill);
959f8af5cf6SDimitry Andric }
960b915e9e0SDimitry Andric
961f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, StoreUpdtIdxInst, SPReg)
962f8af5cf6SDimitry Andric .addReg(SPReg, RegState::Kill)
963f8af5cf6SDimitry Andric .addReg(SPReg)
964f8af5cf6SDimitry Andric .addReg(ScratchReg);
965f8af5cf6SDimitry Andric } else if (!isLargeFrame) {
966e6d15924SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, StoreUpdtInst, SPReg)
967f8af5cf6SDimitry Andric .addReg(SPReg)
968cf099d11SDimitry Andric .addImm(NegFrameSize)
969f8af5cf6SDimitry Andric .addReg(SPReg);
970cf099d11SDimitry Andric } else {
971145449b1SDimitry Andric TII.materializeImmPostRA(MBB, MBBI, dl, ScratchReg, NegFrameSize);
972f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, StoreUpdtIdxInst, SPReg)
973f8af5cf6SDimitry Andric .addReg(SPReg, RegState::Kill)
974f8af5cf6SDimitry Andric .addReg(SPReg)
975f8af5cf6SDimitry Andric .addReg(ScratchReg);
976b915e9e0SDimitry Andric }
977cfca06d7SDimitry Andric }
978b915e9e0SDimitry Andric
979e6d15924SDimitry Andric // Save the TOC register after the stack pointer update if a prologue TOC
980e6d15924SDimitry Andric // save is required for the function.
981e6d15924SDimitry Andric if (MustSaveTOC) {
982e6d15924SDimitry Andric assert(isELFv2ABI && "TOC saves in the prologue only supported on ELFv2");
983e6d15924SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, TII.get(PPC::STD))
984e6d15924SDimitry Andric .addReg(TOCReg, getKillRegState(true))
985e6d15924SDimitry Andric .addImm(TOCSaveOffset)
986e6d15924SDimitry Andric .addReg(SPReg);
987e6d15924SDimitry Andric }
988e6d15924SDimitry Andric
989b915e9e0SDimitry Andric if (!HasRedZone) {
990b915e9e0SDimitry Andric assert(!isPPC64 && "A red zone is always available on PPC64");
991b915e9e0SDimitry Andric if (HasSTUX) {
992b915e9e0SDimitry Andric // The negated frame size is in ScratchReg, and the SPReg has been
993b915e9e0SDimitry Andric // decremented by the frame size: SPReg = old SPReg + ScratchReg.
994b915e9e0SDimitry Andric // Since FPOffset, PBPOffset, etc. are relative to the beginning of
995b915e9e0SDimitry Andric // the stack frame (i.e. the old SP), ideally, we would put the old
996b915e9e0SDimitry Andric // SP into a register and use it as the base for the stores. The
997b915e9e0SDimitry Andric // problem is that the only available register may be ScratchReg,
998b915e9e0SDimitry Andric // which could be R0, and R0 cannot be used as a base address.
999b915e9e0SDimitry Andric
1000b915e9e0SDimitry Andric // First, set ScratchReg to the old SP. This may need to be modified
1001b915e9e0SDimitry Andric // later.
1002b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBF), ScratchReg)
1003b915e9e0SDimitry Andric .addReg(ScratchReg, RegState::Kill)
1004b915e9e0SDimitry Andric .addReg(SPReg);
1005b915e9e0SDimitry Andric
1006b915e9e0SDimitry Andric if (ScratchReg == PPC::R0) {
1007b915e9e0SDimitry Andric // R0 cannot be used as a base register, but it can be used as an
1008b915e9e0SDimitry Andric // index in a store-indexed.
1009b915e9e0SDimitry Andric int LastOffset = 0;
1010b915e9e0SDimitry Andric if (HasFP) {
1011b915e9e0SDimitry Andric // R0 += (FPOffset-LastOffset).
1012b915e9e0SDimitry Andric // Need addic, since addi treats R0 as 0.
1013b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), ScratchReg)
1014b915e9e0SDimitry Andric .addReg(ScratchReg)
1015b915e9e0SDimitry Andric .addImm(FPOffset-LastOffset);
1016b915e9e0SDimitry Andric LastOffset = FPOffset;
1017b915e9e0SDimitry Andric // Store FP into *R0.
1018b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::STWX))
1019b915e9e0SDimitry Andric .addReg(FPReg, RegState::Kill) // Save FP.
1020b915e9e0SDimitry Andric .addReg(PPC::ZERO)
1021b915e9e0SDimitry Andric .addReg(ScratchReg); // This will be the index (R0 is ok here).
1022b915e9e0SDimitry Andric }
1023b915e9e0SDimitry Andric if (FI->usesPICBase()) {
1024b915e9e0SDimitry Andric // R0 += (PBPOffset-LastOffset).
1025b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), ScratchReg)
1026b915e9e0SDimitry Andric .addReg(ScratchReg)
1027b915e9e0SDimitry Andric .addImm(PBPOffset-LastOffset);
1028b915e9e0SDimitry Andric LastOffset = PBPOffset;
1029b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::STWX))
1030b915e9e0SDimitry Andric .addReg(PPC::R30, RegState::Kill) // Save PIC base pointer.
1031b915e9e0SDimitry Andric .addReg(PPC::ZERO)
1032b915e9e0SDimitry Andric .addReg(ScratchReg); // This will be the index (R0 is ok here).
1033b915e9e0SDimitry Andric }
1034b915e9e0SDimitry Andric if (HasBP) {
1035b915e9e0SDimitry Andric // R0 += (BPOffset-LastOffset).
1036b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), ScratchReg)
1037b915e9e0SDimitry Andric .addReg(ScratchReg)
1038b915e9e0SDimitry Andric .addImm(BPOffset-LastOffset);
1039b915e9e0SDimitry Andric LastOffset = BPOffset;
1040b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::STWX))
1041b915e9e0SDimitry Andric .addReg(BPReg, RegState::Kill) // Save BP.
1042b915e9e0SDimitry Andric .addReg(PPC::ZERO)
1043b915e9e0SDimitry Andric .addReg(ScratchReg); // This will be the index (R0 is ok here).
1044b915e9e0SDimitry Andric // BP = R0-LastOffset
1045b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), BPReg)
1046b915e9e0SDimitry Andric .addReg(ScratchReg, RegState::Kill)
1047b915e9e0SDimitry Andric .addImm(-LastOffset);
1048b915e9e0SDimitry Andric }
1049b915e9e0SDimitry Andric } else {
1050b915e9e0SDimitry Andric // ScratchReg is not R0, so use it as the base register. It is
1051b915e9e0SDimitry Andric // already set to the old SP, so we can use the offsets directly.
1052b915e9e0SDimitry Andric
1053b915e9e0SDimitry Andric // Now that the stack frame has been allocated, save all the necessary
1054b915e9e0SDimitry Andric // registers using ScratchReg as the base address.
1055b915e9e0SDimitry Andric if (HasFP)
1056b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
1057b915e9e0SDimitry Andric .addReg(FPReg)
1058b915e9e0SDimitry Andric .addImm(FPOffset)
1059b915e9e0SDimitry Andric .addReg(ScratchReg);
1060b915e9e0SDimitry Andric if (FI->usesPICBase())
1061b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
1062b915e9e0SDimitry Andric .addReg(PPC::R30)
1063b915e9e0SDimitry Andric .addImm(PBPOffset)
1064b915e9e0SDimitry Andric .addReg(ScratchReg);
1065b915e9e0SDimitry Andric if (HasBP) {
1066b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
1067b915e9e0SDimitry Andric .addReg(BPReg)
1068b915e9e0SDimitry Andric .addImm(BPOffset)
1069b915e9e0SDimitry Andric .addReg(ScratchReg);
1070b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, BPReg)
1071b915e9e0SDimitry Andric .addReg(ScratchReg, RegState::Kill)
1072b915e9e0SDimitry Andric .addReg(ScratchReg);
1073b915e9e0SDimitry Andric }
1074b915e9e0SDimitry Andric }
1075b915e9e0SDimitry Andric } else {
1076b915e9e0SDimitry Andric // The frame size is a known 16-bit constant (fitting in the immediate
1077b915e9e0SDimitry Andric // field of STWU). To be here we have to be compiling for PPC32.
1078b915e9e0SDimitry Andric // Since the SPReg has been decreased by FrameSize, add it back to each
1079b915e9e0SDimitry Andric // offset.
1080b915e9e0SDimitry Andric if (HasFP)
1081b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
1082b915e9e0SDimitry Andric .addReg(FPReg)
1083b915e9e0SDimitry Andric .addImm(FrameSize + FPOffset)
1084b915e9e0SDimitry Andric .addReg(SPReg);
1085b915e9e0SDimitry Andric if (FI->usesPICBase())
1086b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
1087b915e9e0SDimitry Andric .addReg(PPC::R30)
1088b915e9e0SDimitry Andric .addImm(FrameSize + PBPOffset)
1089b915e9e0SDimitry Andric .addReg(SPReg);
1090b915e9e0SDimitry Andric if (HasBP) {
1091b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
1092b915e9e0SDimitry Andric .addReg(BPReg)
1093b915e9e0SDimitry Andric .addImm(FrameSize + BPOffset)
1094b915e9e0SDimitry Andric .addReg(SPReg);
1095b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), BPReg)
1096b915e9e0SDimitry Andric .addReg(SPReg)
1097b915e9e0SDimitry Andric .addImm(FrameSize);
1098b915e9e0SDimitry Andric }
1099b915e9e0SDimitry Andric }
1100cf099d11SDimitry Andric }
1101cf099d11SDimitry Andric
1102e3b55780SDimitry Andric // Save the LR now.
1103e3b55780SDimitry Andric if (!HasSTUX && MustSaveLR && !HasFastMFLR && isInt<16>(FrameSize + LROffset))
1104e3b55780SDimitry Andric SaveLR(LROffset + FrameSize);
1105e3b55780SDimitry Andric
11069f619479SDimitry Andric // Add Call Frame Information for the instructions we generated above.
11079f619479SDimitry Andric if (needsCFI) {
11089f619479SDimitry Andric unsigned CFIIndex;
11099f619479SDimitry Andric
11109f619479SDimitry Andric if (HasBP) {
11119f619479SDimitry Andric // Define CFA in terms of BP. Do this in preference to using FP/SP,
11129f619479SDimitry Andric // because if the stack needed aligning then CFA won't be at a fixed
11139f619479SDimitry Andric // offset from FP/SP.
11149f619479SDimitry Andric unsigned Reg = MRI->getDwarfRegNum(BPReg, true);
1115b915e9e0SDimitry Andric CFIIndex = MF.addFrameInst(
11169f619479SDimitry Andric MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
11179f619479SDimitry Andric } else {
11189f619479SDimitry Andric // Adjust the definition of CFA to account for the change in SP.
1119f8af5cf6SDimitry Andric assert(NegFrameSize);
1120b915e9e0SDimitry Andric CFIIndex = MF.addFrameInst(
1121cfca06d7SDimitry Andric MCCFIInstruction::cfiDefCfaOffset(nullptr, -NegFrameSize));
11229f619479SDimitry Andric }
11235ca98fd9SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11245ca98fd9SDimitry Andric .addCFIIndex(CFIIndex);
1125cf099d11SDimitry Andric
1126cf099d11SDimitry Andric if (HasFP) {
11279f619479SDimitry Andric // Describe where FP was saved, at a fixed offset from CFA.
1128f8af5cf6SDimitry Andric unsigned Reg = MRI->getDwarfRegNum(FPReg, true);
1129b915e9e0SDimitry Andric CFIIndex = MF.addFrameInst(
11305ca98fd9SDimitry Andric MCCFIInstruction::createOffset(nullptr, Reg, FPOffset));
11315ca98fd9SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11325ca98fd9SDimitry Andric .addCFIIndex(CFIIndex);
1133f8af5cf6SDimitry Andric }
1134f8af5cf6SDimitry Andric
113567c32a98SDimitry Andric if (FI->usesPICBase()) {
113667c32a98SDimitry Andric // Describe where FP was saved, at a fixed offset from CFA.
113767c32a98SDimitry Andric unsigned Reg = MRI->getDwarfRegNum(PPC::R30, true);
1138b915e9e0SDimitry Andric CFIIndex = MF.addFrameInst(
113967c32a98SDimitry Andric MCCFIInstruction::createOffset(nullptr, Reg, PBPOffset));
114067c32a98SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
114167c32a98SDimitry Andric .addCFIIndex(CFIIndex);
114267c32a98SDimitry Andric }
114367c32a98SDimitry Andric
1144f8af5cf6SDimitry Andric if (HasBP) {
11459f619479SDimitry Andric // Describe where BP was saved, at a fixed offset from CFA.
1146f8af5cf6SDimitry Andric unsigned Reg = MRI->getDwarfRegNum(BPReg, true);
1147b915e9e0SDimitry Andric CFIIndex = MF.addFrameInst(
11485ca98fd9SDimitry Andric MCCFIInstruction::createOffset(nullptr, Reg, BPOffset));
11495ca98fd9SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11505ca98fd9SDimitry Andric .addCFIIndex(CFIIndex);
1151cf099d11SDimitry Andric }
1152cf099d11SDimitry Andric
1153cf099d11SDimitry Andric if (MustSaveLR) {
11549f619479SDimitry Andric // Describe where LR was saved, at a fixed offset from CFA.
1155f8af5cf6SDimitry Andric unsigned Reg = MRI->getDwarfRegNum(LRReg, true);
1156b915e9e0SDimitry Andric CFIIndex = MF.addFrameInst(
11575ca98fd9SDimitry Andric MCCFIInstruction::createOffset(nullptr, Reg, LROffset));
11585ca98fd9SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11595ca98fd9SDimitry Andric .addCFIIndex(CFIIndex);
1160cf099d11SDimitry Andric }
1161cf099d11SDimitry Andric }
1162cf099d11SDimitry Andric
1163cf099d11SDimitry Andric // If there is a frame pointer, copy R1 into R31
1164cf099d11SDimitry Andric if (HasFP) {
1165f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, FPReg)
1166f8af5cf6SDimitry Andric .addReg(SPReg)
1167f8af5cf6SDimitry Andric .addReg(SPReg);
1168cf099d11SDimitry Andric
11699f619479SDimitry Andric if (!HasBP && needsCFI) {
11709f619479SDimitry Andric // Change the definition of CFA from SP+offset to FP+offset, because SP
11719f619479SDimitry Andric // will change at every alloca.
1172f8af5cf6SDimitry Andric unsigned Reg = MRI->getDwarfRegNum(FPReg, true);
1173b915e9e0SDimitry Andric unsigned CFIIndex = MF.addFrameInst(
11745ca98fd9SDimitry Andric MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
11755ca98fd9SDimitry Andric
11765ca98fd9SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11775ca98fd9SDimitry Andric .addCFIIndex(CFIIndex);
1178cf099d11SDimitry Andric }
1179cf099d11SDimitry Andric }
1180cf099d11SDimitry Andric
11819f619479SDimitry Andric if (needsCFI) {
11829f619479SDimitry Andric // Describe where callee saved registers were saved, at fixed offsets from
11839f619479SDimitry Andric // CFA.
1184b915e9e0SDimitry Andric const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
1185f65dcba8SDimitry Andric for (const CalleeSavedInfo &I : CSI) {
11866f8fc217SDimitry Andric Register Reg = I.getReg();
1187cf099d11SDimitry Andric if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue;
118856fe8f14SDimitry Andric
118956fe8f14SDimitry Andric // This is a bit of a hack: CR2LT, CR2GT, CR2EQ and CR2UN are just
119056fe8f14SDimitry Andric // subregisters of CR2. We just need to emit a move of CR2.
119158b69754SDimitry Andric if (PPC::CRBITRCRegClass.contains(Reg))
119256fe8f14SDimitry Andric continue;
119356fe8f14SDimitry Andric
1194e6d15924SDimitry Andric if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)
1195e6d15924SDimitry Andric continue;
1196e6d15924SDimitry Andric
1197522600a2SDimitry Andric // For 64-bit SVR4 when we have spilled CRs, the spill location
1198522600a2SDimitry Andric // is SP+8, not a frame-relative slot.
1199f8af5cf6SDimitry Andric if (isSVR4ABI && isPPC64 && (PPC::CR2 <= Reg && Reg <= PPC::CR4)) {
12005ca98fd9SDimitry Andric // In the ELFv1 ABI, only CR2 is noted in CFI and stands in for
12015ca98fd9SDimitry Andric // the whole CR word. In the ELFv2 ABI, every CR that was
12025ca98fd9SDimitry Andric // actually saved gets its own CFI record.
12036f8fc217SDimitry Andric Register CRReg = isELFv2ABI? Reg : PPC::CR2;
1204b915e9e0SDimitry Andric unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
1205cfca06d7SDimitry Andric nullptr, MRI->getDwarfRegNum(CRReg, true), CRSaveOffset));
12065ca98fd9SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
12075ca98fd9SDimitry Andric .addCFIIndex(CFIIndex);
1208522600a2SDimitry Andric continue;
1209522600a2SDimitry Andric }
1210522600a2SDimitry Andric
1211f65dcba8SDimitry Andric if (I.isSpilledToReg()) {
1212f65dcba8SDimitry Andric unsigned SpilledReg = I.getDstReg();
1213d8e91e46SDimitry Andric unsigned CFIRegister = MF.addFrameInst(MCCFIInstruction::createRegister(
1214d8e91e46SDimitry Andric nullptr, MRI->getDwarfRegNum(Reg, true),
1215d8e91e46SDimitry Andric MRI->getDwarfRegNum(SpilledReg, true)));
1216d8e91e46SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
1217d8e91e46SDimitry Andric .addCFIIndex(CFIRegister);
1218d8e91e46SDimitry Andric } else {
1219f65dcba8SDimitry Andric int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());
1220e6d15924SDimitry Andric // We have changed the object offset above but we do not want to change
1221e6d15924SDimitry Andric // the actual offsets in the CFI instruction so we have to undo the
1222e6d15924SDimitry Andric // offset change here.
1223e6d15924SDimitry Andric if (MovingStackUpdateDown)
1224e6d15924SDimitry Andric Offset -= NegFrameSize;
1225e6d15924SDimitry Andric
1226b915e9e0SDimitry Andric unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
12275ca98fd9SDimitry Andric nullptr, MRI->getDwarfRegNum(Reg, true), Offset));
12285ca98fd9SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
12295ca98fd9SDimitry Andric .addCFIIndex(CFIIndex);
1230cf099d11SDimitry Andric }
1231cf099d11SDimitry Andric }
1232cf099d11SDimitry Andric }
1233d8e91e46SDimitry Andric }
1234cf099d11SDimitry Andric
inlineStackProbe(MachineFunction & MF,MachineBasicBlock & PrologMBB) const1235cfca06d7SDimitry Andric void PPCFrameLowering::inlineStackProbe(MachineFunction &MF,
1236cfca06d7SDimitry Andric MachineBasicBlock &PrologMBB) const {
1237cfca06d7SDimitry Andric bool isPPC64 = Subtarget.isPPC64();
1238cfca06d7SDimitry Andric const PPCTargetLowering &TLI = *Subtarget.getTargetLowering();
1239cfca06d7SDimitry Andric const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
1240cfca06d7SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
1241ac9a064cSDimitry Andric const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
1242cfca06d7SDimitry Andric // AIX assembler does not support cfi directives.
1243cfca06d7SDimitry Andric const bool needsCFI = MF.needsFrameMoves() && !Subtarget.isAIXABI();
1244cfca06d7SDimitry Andric auto StackAllocMIPos = llvm::find_if(PrologMBB, [](MachineInstr &MI) {
1245cfca06d7SDimitry Andric int Opc = MI.getOpcode();
1246cfca06d7SDimitry Andric return Opc == PPC::PROBED_STACKALLOC_64 || Opc == PPC::PROBED_STACKALLOC_32;
1247cfca06d7SDimitry Andric });
1248cfca06d7SDimitry Andric if (StackAllocMIPos == PrologMBB.end())
1249cfca06d7SDimitry Andric return;
1250cfca06d7SDimitry Andric const BasicBlock *ProbedBB = PrologMBB.getBasicBlock();
1251b60736ecSDimitry Andric MachineBasicBlock *CurrentMBB = &PrologMBB;
1252cfca06d7SDimitry Andric DebugLoc DL = PrologMBB.findDebugLoc(StackAllocMIPos);
1253cfca06d7SDimitry Andric MachineInstr &MI = *StackAllocMIPos;
1254cfca06d7SDimitry Andric int64_t NegFrameSize = MI.getOperand(2).getImm();
1255b60736ecSDimitry Andric unsigned ProbeSize = TLI.getStackProbeSize(MF);
1256b60736ecSDimitry Andric int64_t NegProbeSize = -(int64_t)ProbeSize;
1257cfca06d7SDimitry Andric assert(isInt<32>(NegProbeSize) && "Unhandled probe size");
1258cfca06d7SDimitry Andric int64_t NumBlocks = NegFrameSize / NegProbeSize;
1259cfca06d7SDimitry Andric int64_t NegResidualSize = NegFrameSize % NegProbeSize;
1260cfca06d7SDimitry Andric Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
1261cfca06d7SDimitry Andric Register ScratchReg = MI.getOperand(0).getReg();
1262cfca06d7SDimitry Andric Register FPReg = MI.getOperand(1).getReg();
1263cfca06d7SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1264cfca06d7SDimitry Andric bool HasBP = RegInfo->hasBasePointer(MF);
1265b60736ecSDimitry Andric Register BPReg = RegInfo->getBaseRegister(MF);
1266cfca06d7SDimitry Andric Align MaxAlign = MFI.getMaxAlign();
1267344a3780SDimitry Andric bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
1268cfca06d7SDimitry Andric const MCInstrDesc &CopyInst = TII.get(isPPC64 ? PPC::OR8 : PPC::OR);
1269cfca06d7SDimitry Andric // Subroutines to generate .cfi_* directives.
1270cfca06d7SDimitry Andric auto buildDefCFAReg = [&](MachineBasicBlock &MBB,
1271cfca06d7SDimitry Andric MachineBasicBlock::iterator MBBI, Register Reg) {
1272cfca06d7SDimitry Andric unsigned RegNum = MRI->getDwarfRegNum(Reg, true);
1273cfca06d7SDimitry Andric unsigned CFIIndex = MF.addFrameInst(
1274cfca06d7SDimitry Andric MCCFIInstruction::createDefCfaRegister(nullptr, RegNum));
1275cfca06d7SDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
1276cfca06d7SDimitry Andric .addCFIIndex(CFIIndex);
1277cfca06d7SDimitry Andric };
1278cfca06d7SDimitry Andric auto buildDefCFA = [&](MachineBasicBlock &MBB,
1279cfca06d7SDimitry Andric MachineBasicBlock::iterator MBBI, Register Reg,
1280cfca06d7SDimitry Andric int Offset) {
1281cfca06d7SDimitry Andric unsigned RegNum = MRI->getDwarfRegNum(Reg, true);
1282cfca06d7SDimitry Andric unsigned CFIIndex = MBB.getParent()->addFrameInst(
1283cfca06d7SDimitry Andric MCCFIInstruction::cfiDefCfa(nullptr, RegNum, Offset));
1284cfca06d7SDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
1285cfca06d7SDimitry Andric .addCFIIndex(CFIIndex);
1286cfca06d7SDimitry Andric };
1287cfca06d7SDimitry Andric // Subroutine to determine if we can use the Imm as part of d-form.
1288cfca06d7SDimitry Andric auto CanUseDForm = [](int64_t Imm) { return isInt<16>(Imm) && Imm % 4 == 0; };
1289cfca06d7SDimitry Andric // Subroutine to materialize the Imm into TempReg.
1290cfca06d7SDimitry Andric auto MaterializeImm = [&](MachineBasicBlock &MBB,
1291cfca06d7SDimitry Andric MachineBasicBlock::iterator MBBI, int64_t Imm,
1292cfca06d7SDimitry Andric Register &TempReg) {
1293cfca06d7SDimitry Andric assert(isInt<32>(Imm) && "Unhandled imm");
1294cfca06d7SDimitry Andric if (isInt<16>(Imm))
1295cfca06d7SDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::LI8 : PPC::LI), TempReg)
1296cfca06d7SDimitry Andric .addImm(Imm);
1297cfca06d7SDimitry Andric else {
1298cfca06d7SDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::LIS8 : PPC::LIS), TempReg)
1299cfca06d7SDimitry Andric .addImm(Imm >> 16);
1300cfca06d7SDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::ORI8 : PPC::ORI), TempReg)
1301cfca06d7SDimitry Andric .addReg(TempReg)
1302cfca06d7SDimitry Andric .addImm(Imm & 0xFFFF);
1303cfca06d7SDimitry Andric }
1304cfca06d7SDimitry Andric };
1305cfca06d7SDimitry Andric // Subroutine to store frame pointer and decrease stack pointer by probe size.
1306cfca06d7SDimitry Andric auto allocateAndProbe = [&](MachineBasicBlock &MBB,
1307cfca06d7SDimitry Andric MachineBasicBlock::iterator MBBI, int64_t NegSize,
1308b60736ecSDimitry Andric Register NegSizeReg, bool UseDForm,
1309b60736ecSDimitry Andric Register StoreReg) {
1310cfca06d7SDimitry Andric if (UseDForm)
1311cfca06d7SDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::STDU : PPC::STWU), SPReg)
1312b60736ecSDimitry Andric .addReg(StoreReg)
1313cfca06d7SDimitry Andric .addImm(NegSize)
1314cfca06d7SDimitry Andric .addReg(SPReg);
1315cfca06d7SDimitry Andric else
1316cfca06d7SDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
1317b60736ecSDimitry Andric .addReg(StoreReg)
1318cfca06d7SDimitry Andric .addReg(SPReg)
1319cfca06d7SDimitry Andric .addReg(NegSizeReg);
1320cfca06d7SDimitry Andric };
1321344a3780SDimitry Andric // Used to probe stack when realignment is required.
1322344a3780SDimitry Andric // Note that, according to ABI's requirement, *sp must always equals the
1323344a3780SDimitry Andric // value of back-chain pointer, only st(w|d)u(x) can be used to update sp.
1324344a3780SDimitry Andric // Following is pseudo code:
1325344a3780SDimitry Andric // final_sp = (sp & align) + negframesize;
1326344a3780SDimitry Andric // neg_gap = final_sp - sp;
1327344a3780SDimitry Andric // while (neg_gap < negprobesize) {
1328344a3780SDimitry Andric // stdu fp, negprobesize(sp);
1329344a3780SDimitry Andric // neg_gap -= negprobesize;
1330344a3780SDimitry Andric // }
1331344a3780SDimitry Andric // stdux fp, sp, neg_gap
1332344a3780SDimitry Andric //
1333344a3780SDimitry Andric // When HasBP & HasRedzone, back-chain pointer is already saved in BPReg
1334344a3780SDimitry Andric // before probe code, we don't need to save it, so we get one additional reg
1335344a3780SDimitry Andric // that can be used to materialize the probeside if needed to use xform.
1336344a3780SDimitry Andric // Otherwise, we can NOT materialize probeside, so we can only use Dform for
1337344a3780SDimitry Andric // now.
1338344a3780SDimitry Andric //
1339344a3780SDimitry Andric // The allocations are:
1340344a3780SDimitry Andric // if (HasBP && HasRedzone) {
1341344a3780SDimitry Andric // r0: materialize the probesize if needed so that we can use xform.
1342344a3780SDimitry Andric // r12: `neg_gap`
1343344a3780SDimitry Andric // } else {
1344344a3780SDimitry Andric // r0: back-chain pointer
1345344a3780SDimitry Andric // r12: `neg_gap`.
1346344a3780SDimitry Andric // }
1347344a3780SDimitry Andric auto probeRealignedStack = [&](MachineBasicBlock &MBB,
1348344a3780SDimitry Andric MachineBasicBlock::iterator MBBI,
1349344a3780SDimitry Andric Register ScratchReg, Register TempReg) {
1350344a3780SDimitry Andric assert(HasBP && "The function is supposed to have base pointer when its "
1351344a3780SDimitry Andric "stack is realigned.");
1352b60736ecSDimitry Andric assert(isPowerOf2_64(ProbeSize) && "Probe size should be power of 2");
1353344a3780SDimitry Andric
1354344a3780SDimitry Andric // FIXME: We can eliminate this limitation if we get more infomation about
1355344a3780SDimitry Andric // which part of redzone are already used. Used redzone can be treated
1356344a3780SDimitry Andric // probed. But there might be `holes' in redzone probed, this could
1357344a3780SDimitry Andric // complicate the implementation.
1358344a3780SDimitry Andric assert(ProbeSize >= Subtarget.getRedZoneSize() &&
1359344a3780SDimitry Andric "Probe size should be larger or equal to the size of red-zone so "
1360344a3780SDimitry Andric "that red-zone is not clobbered by probing.");
1361344a3780SDimitry Andric
1362344a3780SDimitry Andric Register &FinalStackPtr = TempReg;
1363344a3780SDimitry Andric // FIXME: We only support NegProbeSize materializable by DForm currently.
1364344a3780SDimitry Andric // When HasBP && HasRedzone, we can use xform if we have an additional idle
1365344a3780SDimitry Andric // register.
1366344a3780SDimitry Andric NegProbeSize = std::max(NegProbeSize, -((int64_t)1 << 15));
1367344a3780SDimitry Andric assert(isInt<16>(NegProbeSize) &&
1368344a3780SDimitry Andric "NegProbeSize should be materializable by DForm");
1369b60736ecSDimitry Andric Register CRReg = PPC::CR0;
1370344a3780SDimitry Andric // Layout of output assembly kinda like:
1371b60736ecSDimitry Andric // bb.0:
1372b60736ecSDimitry Andric // ...
1373344a3780SDimitry Andric // sub $scratchreg, $finalsp, r1
1374344a3780SDimitry Andric // cmpdi $scratchreg, <negprobesize>
1375344a3780SDimitry Andric // bge bb.2
1376344a3780SDimitry Andric // bb.1:
1377344a3780SDimitry Andric // stdu <backchain>, <negprobesize>(r1)
1378344a3780SDimitry Andric // sub $scratchreg, $scratchreg, negprobesize
1379344a3780SDimitry Andric // cmpdi $scratchreg, <negprobesize>
1380344a3780SDimitry Andric // blt bb.1
1381b60736ecSDimitry Andric // bb.2:
1382344a3780SDimitry Andric // stdux <backchain>, r1, $scratchreg
1383b60736ecSDimitry Andric MachineFunction::iterator MBBInsertPoint = std::next(MBB.getIterator());
1384b60736ecSDimitry Andric MachineBasicBlock *ProbeLoopBodyMBB = MF.CreateMachineBasicBlock(ProbedBB);
1385b60736ecSDimitry Andric MF.insert(MBBInsertPoint, ProbeLoopBodyMBB);
1386b60736ecSDimitry Andric MachineBasicBlock *ProbeExitMBB = MF.CreateMachineBasicBlock(ProbedBB);
1387b60736ecSDimitry Andric MF.insert(MBBInsertPoint, ProbeExitMBB);
1388344a3780SDimitry Andric // bb.2
1389344a3780SDimitry Andric {
1390344a3780SDimitry Andric Register BackChainPointer = HasRedZone ? BPReg : TempReg;
1391344a3780SDimitry Andric allocateAndProbe(*ProbeExitMBB, ProbeExitMBB->end(), 0, ScratchReg, false,
1392344a3780SDimitry Andric BackChainPointer);
1393344a3780SDimitry Andric if (HasRedZone)
1394344a3780SDimitry Andric // PROBED_STACKALLOC_64 assumes Operand(1) stores the old sp, copy BPReg
1395344a3780SDimitry Andric // to TempReg to satisfy it.
1396344a3780SDimitry Andric BuildMI(*ProbeExitMBB, ProbeExitMBB->end(), DL, CopyInst, TempReg)
1397344a3780SDimitry Andric .addReg(BPReg)
1398344a3780SDimitry Andric .addReg(BPReg);
1399b60736ecSDimitry Andric ProbeExitMBB->splice(ProbeExitMBB->end(), &MBB, MBBI, MBB.end());
1400b60736ecSDimitry Andric ProbeExitMBB->transferSuccessorsAndUpdatePHIs(&MBB);
1401344a3780SDimitry Andric }
1402b60736ecSDimitry Andric // bb.0
1403344a3780SDimitry Andric {
1404344a3780SDimitry Andric BuildMI(&MBB, DL, TII.get(isPPC64 ? PPC::SUBF8 : PPC::SUBF), ScratchReg)
1405b60736ecSDimitry Andric .addReg(SPReg)
1406344a3780SDimitry Andric .addReg(FinalStackPtr);
1407344a3780SDimitry Andric if (!HasRedZone)
1408344a3780SDimitry Andric BuildMI(&MBB, DL, CopyInst, TempReg).addReg(SPReg).addReg(SPReg);
1409344a3780SDimitry Andric BuildMI(&MBB, DL, TII.get(isPPC64 ? PPC::CMPDI : PPC::CMPWI), CRReg)
1410344a3780SDimitry Andric .addReg(ScratchReg)
1411344a3780SDimitry Andric .addImm(NegProbeSize);
1412344a3780SDimitry Andric BuildMI(&MBB, DL, TII.get(PPC::BCC))
1413344a3780SDimitry Andric .addImm(PPC::PRED_GE)
1414b60736ecSDimitry Andric .addReg(CRReg)
1415b60736ecSDimitry Andric .addMBB(ProbeExitMBB);
1416344a3780SDimitry Andric MBB.addSuccessor(ProbeLoopBodyMBB);
1417344a3780SDimitry Andric MBB.addSuccessor(ProbeExitMBB);
1418344a3780SDimitry Andric }
1419344a3780SDimitry Andric // bb.1
1420344a3780SDimitry Andric {
1421344a3780SDimitry Andric Register BackChainPointer = HasRedZone ? BPReg : TempReg;
1422344a3780SDimitry Andric allocateAndProbe(*ProbeLoopBodyMBB, ProbeLoopBodyMBB->end(), NegProbeSize,
1423344a3780SDimitry Andric 0, true /*UseDForm*/, BackChainPointer);
1424344a3780SDimitry Andric BuildMI(ProbeLoopBodyMBB, DL, TII.get(isPPC64 ? PPC::ADDI8 : PPC::ADDI),
1425344a3780SDimitry Andric ScratchReg)
1426344a3780SDimitry Andric .addReg(ScratchReg)
1427344a3780SDimitry Andric .addImm(-NegProbeSize);
1428344a3780SDimitry Andric BuildMI(ProbeLoopBodyMBB, DL, TII.get(isPPC64 ? PPC::CMPDI : PPC::CMPWI),
1429344a3780SDimitry Andric CRReg)
1430344a3780SDimitry Andric .addReg(ScratchReg)
1431344a3780SDimitry Andric .addImm(NegProbeSize);
1432b60736ecSDimitry Andric BuildMI(ProbeLoopBodyMBB, DL, TII.get(PPC::BCC))
1433344a3780SDimitry Andric .addImm(PPC::PRED_LT)
1434b60736ecSDimitry Andric .addReg(CRReg)
1435b60736ecSDimitry Andric .addMBB(ProbeLoopBodyMBB);
1436b60736ecSDimitry Andric ProbeLoopBodyMBB->addSuccessor(ProbeExitMBB);
1437b60736ecSDimitry Andric ProbeLoopBodyMBB->addSuccessor(ProbeLoopBodyMBB);
1438344a3780SDimitry Andric }
1439b60736ecSDimitry Andric // Update liveins.
1440ac9a064cSDimitry Andric fullyRecomputeLiveIns({ProbeExitMBB, ProbeLoopBodyMBB});
1441b60736ecSDimitry Andric return ProbeExitMBB;
1442b60736ecSDimitry Andric };
1443b60736ecSDimitry Andric // For case HasBP && MaxAlign > 1, we have to realign the SP by performing
1444344a3780SDimitry Andric // SP = SP - SP % MaxAlign, thus make the probe more like dynamic probe since
1445344a3780SDimitry Andric // the offset subtracted from SP is determined by SP's runtime value.
1446b60736ecSDimitry Andric if (HasBP && MaxAlign > 1) {
1447344a3780SDimitry Andric // Calculate final stack pointer.
1448344a3780SDimitry Andric if (isPPC64)
1449344a3780SDimitry Andric BuildMI(*CurrentMBB, {MI}, DL, TII.get(PPC::RLDICL), ScratchReg)
1450b60736ecSDimitry Andric .addReg(SPReg)
1451344a3780SDimitry Andric .addImm(0)
1452344a3780SDimitry Andric .addImm(64 - Log2(MaxAlign));
1453344a3780SDimitry Andric else
1454b60736ecSDimitry Andric BuildMI(*CurrentMBB, {MI}, DL, TII.get(PPC::RLWINM), ScratchReg)
1455344a3780SDimitry Andric .addReg(SPReg)
1456cfca06d7SDimitry Andric .addImm(0)
1457cfca06d7SDimitry Andric .addImm(32 - Log2(MaxAlign))
1458cfca06d7SDimitry Andric .addImm(31);
1459344a3780SDimitry Andric BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::SUBF8 : PPC::SUBF),
1460344a3780SDimitry Andric FPReg)
1461b60736ecSDimitry Andric .addReg(ScratchReg)
1462b60736ecSDimitry Andric .addReg(SPReg);
1463344a3780SDimitry Andric MaterializeImm(*CurrentMBB, {MI}, NegFrameSize, ScratchReg);
1464344a3780SDimitry Andric BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::ADD8 : PPC::ADD4),
1465344a3780SDimitry Andric FPReg)
1466344a3780SDimitry Andric .addReg(ScratchReg)
1467344a3780SDimitry Andric .addReg(FPReg);
1468344a3780SDimitry Andric CurrentMBB = probeRealignedStack(*CurrentMBB, {MI}, ScratchReg, FPReg);
1469344a3780SDimitry Andric if (needsCFI)
1470344a3780SDimitry Andric buildDefCFAReg(*CurrentMBB, {MI}, FPReg);
1471b60736ecSDimitry Andric } else {
1472b60736ecSDimitry Andric // Initialize current frame pointer.
1473b60736ecSDimitry Andric BuildMI(*CurrentMBB, {MI}, DL, CopyInst, FPReg).addReg(SPReg).addReg(SPReg);
1474b60736ecSDimitry Andric // Use FPReg to calculate CFA.
1475b60736ecSDimitry Andric if (needsCFI)
1476b60736ecSDimitry Andric buildDefCFA(*CurrentMBB, {MI}, FPReg, 0);
1477cfca06d7SDimitry Andric // Probe residual part.
1478cfca06d7SDimitry Andric if (NegResidualSize) {
1479cfca06d7SDimitry Andric bool ResidualUseDForm = CanUseDForm(NegResidualSize);
1480cfca06d7SDimitry Andric if (!ResidualUseDForm)
1481b60736ecSDimitry Andric MaterializeImm(*CurrentMBB, {MI}, NegResidualSize, ScratchReg);
1482b60736ecSDimitry Andric allocateAndProbe(*CurrentMBB, {MI}, NegResidualSize, ScratchReg,
1483b60736ecSDimitry Andric ResidualUseDForm, FPReg);
1484cfca06d7SDimitry Andric }
1485cfca06d7SDimitry Andric bool UseDForm = CanUseDForm(NegProbeSize);
1486cfca06d7SDimitry Andric // If number of blocks is small, just probe them directly.
1487cfca06d7SDimitry Andric if (NumBlocks < 3) {
1488cfca06d7SDimitry Andric if (!UseDForm)
1489b60736ecSDimitry Andric MaterializeImm(*CurrentMBB, {MI}, NegProbeSize, ScratchReg);
1490cfca06d7SDimitry Andric for (int i = 0; i < NumBlocks; ++i)
1491b60736ecSDimitry Andric allocateAndProbe(*CurrentMBB, {MI}, NegProbeSize, ScratchReg, UseDForm,
1492b60736ecSDimitry Andric FPReg);
1493cfca06d7SDimitry Andric if (needsCFI) {
1494cfca06d7SDimitry Andric // Restore using SPReg to calculate CFA.
1495b60736ecSDimitry Andric buildDefCFAReg(*CurrentMBB, {MI}, SPReg);
1496cfca06d7SDimitry Andric }
1497cfca06d7SDimitry Andric } else {
1498cfca06d7SDimitry Andric // Since CTR is a volatile register and current shrinkwrap implementation
1499cfca06d7SDimitry Andric // won't choose an MBB in a loop as the PrologMBB, it's safe to synthesize a
1500cfca06d7SDimitry Andric // CTR loop to probe.
1501cfca06d7SDimitry Andric // Calculate trip count and stores it in CTRReg.
1502b60736ecSDimitry Andric MaterializeImm(*CurrentMBB, {MI}, NumBlocks, ScratchReg);
1503b60736ecSDimitry Andric BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::MTCTR8 : PPC::MTCTR))
1504cfca06d7SDimitry Andric .addReg(ScratchReg, RegState::Kill);
1505cfca06d7SDimitry Andric if (!UseDForm)
1506b60736ecSDimitry Andric MaterializeImm(*CurrentMBB, {MI}, NegProbeSize, ScratchReg);
1507cfca06d7SDimitry Andric // Create MBBs of the loop.
1508cfca06d7SDimitry Andric MachineFunction::iterator MBBInsertPoint =
1509b60736ecSDimitry Andric std::next(CurrentMBB->getIterator());
1510cfca06d7SDimitry Andric MachineBasicBlock *LoopMBB = MF.CreateMachineBasicBlock(ProbedBB);
1511cfca06d7SDimitry Andric MF.insert(MBBInsertPoint, LoopMBB);
1512cfca06d7SDimitry Andric MachineBasicBlock *ExitMBB = MF.CreateMachineBasicBlock(ProbedBB);
1513cfca06d7SDimitry Andric MF.insert(MBBInsertPoint, ExitMBB);
1514cfca06d7SDimitry Andric // Synthesize the loop body.
1515cfca06d7SDimitry Andric allocateAndProbe(*LoopMBB, LoopMBB->end(), NegProbeSize, ScratchReg,
1516b60736ecSDimitry Andric UseDForm, FPReg);
1517cfca06d7SDimitry Andric BuildMI(LoopMBB, DL, TII.get(isPPC64 ? PPC::BDNZ8 : PPC::BDNZ))
1518cfca06d7SDimitry Andric .addMBB(LoopMBB);
1519cfca06d7SDimitry Andric LoopMBB->addSuccessor(ExitMBB);
1520cfca06d7SDimitry Andric LoopMBB->addSuccessor(LoopMBB);
1521cfca06d7SDimitry Andric // Synthesize the exit MBB.
1522b60736ecSDimitry Andric ExitMBB->splice(ExitMBB->end(), CurrentMBB,
1523cfca06d7SDimitry Andric std::next(MachineBasicBlock::iterator(MI)),
1524b60736ecSDimitry Andric CurrentMBB->end());
1525b60736ecSDimitry Andric ExitMBB->transferSuccessorsAndUpdatePHIs(CurrentMBB);
1526b60736ecSDimitry Andric CurrentMBB->addSuccessor(LoopMBB);
1527cfca06d7SDimitry Andric if (needsCFI) {
1528cfca06d7SDimitry Andric // Restore using SPReg to calculate CFA.
1529cfca06d7SDimitry Andric buildDefCFAReg(*ExitMBB, ExitMBB->begin(), SPReg);
1530cfca06d7SDimitry Andric }
1531cfca06d7SDimitry Andric // Update liveins.
1532ac9a064cSDimitry Andric fullyRecomputeLiveIns({ExitMBB, LoopMBB});
1533cfca06d7SDimitry Andric }
1534344a3780SDimitry Andric }
1535cfca06d7SDimitry Andric ++NumPrologProbed;
1536cfca06d7SDimitry Andric MI.eraseFromParent();
1537cfca06d7SDimitry Andric }
1538cfca06d7SDimitry Andric
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const1539cf099d11SDimitry Andric void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
1540cf099d11SDimitry Andric MachineBasicBlock &MBB) const {
1541dd58ef01SDimitry Andric MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
1542dd58ef01SDimitry Andric DebugLoc dl;
1543dd58ef01SDimitry Andric
1544dd58ef01SDimitry Andric if (MBBI != MBB.end())
1545dd58ef01SDimitry Andric dl = MBBI->getDebugLoc();
1546dd58ef01SDimitry Andric
154771d5a254SDimitry Andric const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
154871d5a254SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1549cf099d11SDimitry Andric
1550f8af5cf6SDimitry Andric // Get alignment info so we know how to restore the SP.
1551b915e9e0SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
1552cf099d11SDimitry Andric
1553cf099d11SDimitry Andric // Get the number of bytes allocated from the FrameInfo.
1554c0981da4SDimitry Andric int64_t FrameSize = MFI.getStackSize();
1555cf099d11SDimitry Andric
1556cf099d11SDimitry Andric // Get processor type.
1557cf099d11SDimitry Andric bool isPPC64 = Subtarget.isPPC64();
1558f8af5cf6SDimitry Andric
1559cf099d11SDimitry Andric // Check if the link register (LR) has been saved.
1560cf099d11SDimitry Andric PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
1561cf099d11SDimitry Andric bool MustSaveLR = FI->mustSaveLR();
1562cfca06d7SDimitry Andric const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
1563d9c9bd84SDimitry Andric bool MustSaveCR = !MustSaveCRs.empty();
1564f8af5cf6SDimitry Andric // Do we have a frame pointer and/or base pointer for this function?
1565cf099d11SDimitry Andric bool HasFP = hasFP(MF);
1566f8af5cf6SDimitry Andric bool HasBP = RegInfo->hasBasePointer(MF);
1567b915e9e0SDimitry Andric bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
1568344a3780SDimitry Andric bool HasROPProtect = Subtarget.hasROPProtect();
1569344a3780SDimitry Andric bool HasPrivileged = Subtarget.hasPrivileged();
1570f8af5cf6SDimitry Andric
1571cfca06d7SDimitry Andric Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
15721d5ae102SDimitry Andric Register BPReg = RegInfo->getBaseRegister(MF);
1573cfca06d7SDimitry Andric Register FPReg = isPPC64 ? PPC::X31 : PPC::R31;
1574cfca06d7SDimitry Andric Register ScratchReg;
1575cfca06d7SDimitry Andric Register TempReg = isPPC64 ? PPC::X12 : PPC::R12; // another scratch reg
1576f8af5cf6SDimitry Andric const MCInstrDesc& MTLRInst = TII.get( isPPC64 ? PPC::MTLR8
1577f8af5cf6SDimitry Andric : PPC::MTLR );
1578f8af5cf6SDimitry Andric const MCInstrDesc& LoadInst = TII.get( isPPC64 ? PPC::LD
1579f8af5cf6SDimitry Andric : PPC::LWZ );
1580f8af5cf6SDimitry Andric const MCInstrDesc& LoadImmShiftedInst = TII.get( isPPC64 ? PPC::LIS8
1581f8af5cf6SDimitry Andric : PPC::LIS );
1582b915e9e0SDimitry Andric const MCInstrDesc& OrInst = TII.get(isPPC64 ? PPC::OR8
1583b915e9e0SDimitry Andric : PPC::OR );
1584f8af5cf6SDimitry Andric const MCInstrDesc& OrImmInst = TII.get( isPPC64 ? PPC::ORI8
1585f8af5cf6SDimitry Andric : PPC::ORI );
1586f8af5cf6SDimitry Andric const MCInstrDesc& AddImmInst = TII.get( isPPC64 ? PPC::ADDI8
1587f8af5cf6SDimitry Andric : PPC::ADDI );
1588f8af5cf6SDimitry Andric const MCInstrDesc& AddInst = TII.get( isPPC64 ? PPC::ADD8
1589f8af5cf6SDimitry Andric : PPC::ADD4 );
1590cfca06d7SDimitry Andric const MCInstrDesc& LoadWordInst = TII.get( isPPC64 ? PPC::LWZ8
1591cfca06d7SDimitry Andric : PPC::LWZ);
1592cfca06d7SDimitry Andric const MCInstrDesc& MoveToCRInst = TII.get( isPPC64 ? PPC::MTOCRF8
1593cfca06d7SDimitry Andric : PPC::MTOCRF);
1594344a3780SDimitry Andric const MCInstrDesc &HashChk =
15956f8fc217SDimitry Andric TII.get(isPPC64 ? (HasPrivileged ? PPC::HASHCHKP8 : PPC::HASHCHK8)
15966f8fc217SDimitry Andric : (HasPrivileged ? PPC::HASHCHKP : PPC::HASHCHK));
1597c0981da4SDimitry Andric int64_t LROffset = getReturnSaveOffset();
1598cf099d11SDimitry Andric
1599c0981da4SDimitry Andric int64_t FPOffset = 0;
1600dd58ef01SDimitry Andric
1601b915e9e0SDimitry Andric // Using the same bool variable as below to suppress compiler warnings.
1602d9c9bd84SDimitry Andric bool SingleScratchReg = findScratchRegister(&MBB, true, false, &ScratchReg,
1603d9c9bd84SDimitry Andric &TempReg);
1604d9c9bd84SDimitry Andric assert(SingleScratchReg &&
1605d9c9bd84SDimitry Andric "Could not find an available scratch register");
1606d9c9bd84SDimitry Andric
1607d9c9bd84SDimitry Andric SingleScratchReg = ScratchReg == TempReg;
1608dd58ef01SDimitry Andric
1609cf099d11SDimitry Andric if (HasFP) {
1610cf099d11SDimitry Andric int FPIndex = FI->getFramePointerSaveIndex();
1611cf099d11SDimitry Andric assert(FPIndex && "No Frame Pointer Save Slot!");
1612b915e9e0SDimitry Andric FPOffset = MFI.getObjectOffset(FPIndex);
1613cf099d11SDimitry Andric }
1614cf099d11SDimitry Andric
1615c0981da4SDimitry Andric int64_t BPOffset = 0;
1616f8af5cf6SDimitry Andric if (HasBP) {
1617f8af5cf6SDimitry Andric int BPIndex = FI->getBasePointerSaveIndex();
1618f8af5cf6SDimitry Andric assert(BPIndex && "No Base Pointer Save Slot!");
1619b915e9e0SDimitry Andric BPOffset = MFI.getObjectOffset(BPIndex);
1620f8af5cf6SDimitry Andric }
1621f8af5cf6SDimitry Andric
1622c0981da4SDimitry Andric int64_t PBPOffset = 0;
162367c32a98SDimitry Andric if (FI->usesPICBase()) {
162467c32a98SDimitry Andric int PBPIndex = FI->getPICBasePointerSaveIndex();
162567c32a98SDimitry Andric assert(PBPIndex && "No PIC Base Pointer Save Slot!");
1626b915e9e0SDimitry Andric PBPOffset = MFI.getObjectOffset(PBPIndex);
162767c32a98SDimitry Andric }
162867c32a98SDimitry Andric
1629dd58ef01SDimitry Andric bool IsReturnBlock = (MBBI != MBB.end() && MBBI->isReturn());
1630dd58ef01SDimitry Andric
1631dd58ef01SDimitry Andric if (IsReturnBlock) {
1632dd58ef01SDimitry Andric unsigned RetOpcode = MBBI->getOpcode();
1633cf099d11SDimitry Andric bool UsesTCRet = RetOpcode == PPC::TCRETURNri ||
1634cf099d11SDimitry Andric RetOpcode == PPC::TCRETURNdi ||
1635cf099d11SDimitry Andric RetOpcode == PPC::TCRETURNai ||
1636cf099d11SDimitry Andric RetOpcode == PPC::TCRETURNri8 ||
1637cf099d11SDimitry Andric RetOpcode == PPC::TCRETURNdi8 ||
1638cf099d11SDimitry Andric RetOpcode == PPC::TCRETURNai8;
1639cf099d11SDimitry Andric
1640cf099d11SDimitry Andric if (UsesTCRet) {
1641cf099d11SDimitry Andric int MaxTCRetDelta = FI->getTailCallSPDelta();
1642cf099d11SDimitry Andric MachineOperand &StackAdjust = MBBI->getOperand(1);
1643cf099d11SDimitry Andric assert(StackAdjust.isImm() && "Expecting immediate value.");
1644cf099d11SDimitry Andric // Adjust stack pointer.
1645cf099d11SDimitry Andric int StackAdj = StackAdjust.getImm();
1646cf099d11SDimitry Andric int Delta = StackAdj - MaxTCRetDelta;
1647cf099d11SDimitry Andric assert((Delta >= 0) && "Delta must be positive");
1648cf099d11SDimitry Andric if (MaxTCRetDelta>0)
1649cf099d11SDimitry Andric FrameSize += (StackAdj +Delta);
1650cf099d11SDimitry Andric else
1651cf099d11SDimitry Andric FrameSize += StackAdj;
1652cf099d11SDimitry Andric }
1653dd58ef01SDimitry Andric }
1654cf099d11SDimitry Andric
1655f8af5cf6SDimitry Andric // Frames of 32KB & larger require special handling because they cannot be
1656f8af5cf6SDimitry Andric // indexed into with a simple LD/LWZ immediate offset operand.
1657f8af5cf6SDimitry Andric bool isLargeFrame = !isInt<16>(FrameSize);
1658f8af5cf6SDimitry Andric
1659b915e9e0SDimitry Andric // On targets without red zone, the SP needs to be restored last, so that
1660b915e9e0SDimitry Andric // all live contents of the stack frame are upwards of the SP. This means
1661b915e9e0SDimitry Andric // that we cannot restore SP just now, since there may be more registers
1662b915e9e0SDimitry Andric // to restore from the stack frame (e.g. R31). If the frame size is not
1663b915e9e0SDimitry Andric // a simple immediate value, we will need a spare register to hold the
1664b915e9e0SDimitry Andric // restored SP. If the frame size is known and small, we can simply adjust
1665b915e9e0SDimitry Andric // the offsets of the registers to be restored, and still use SP to restore
1666b915e9e0SDimitry Andric // them. In such case, the final update of SP will be to add the frame
1667b915e9e0SDimitry Andric // size to it.
1668b915e9e0SDimitry Andric // To simplify the code, set RBReg to the base register used to restore
1669b915e9e0SDimitry Andric // values from the stack, and set SPAdd to the value that needs to be added
1670b915e9e0SDimitry Andric // to the SP at the end. The default values are as if red zone was present.
1671b915e9e0SDimitry Andric unsigned RBReg = SPReg;
1672145449b1SDimitry Andric uint64_t SPAdd = 0;
1673b915e9e0SDimitry Andric
1674e6d15924SDimitry Andric // Check if we can move the stack update instruction up the epilogue
1675e6d15924SDimitry Andric // past the callee saves. This will allow the move to LR instruction
1676e6d15924SDimitry Andric // to be executed before the restores of the callee saves which means
1677e6d15924SDimitry Andric // that the callee saves can hide the latency from the MTLR instrcution.
1678e6d15924SDimitry Andric MachineBasicBlock::iterator StackUpdateLoc = MBBI;
1679e6d15924SDimitry Andric if (stackUpdateCanBeMoved(MF)) {
1680e6d15924SDimitry Andric const std::vector<CalleeSavedInfo> & Info = MFI.getCalleeSavedInfo();
1681e6d15924SDimitry Andric for (CalleeSavedInfo CSI : Info) {
1682344a3780SDimitry Andric // If the callee saved register is spilled to another register abort the
1683344a3780SDimitry Andric // stack update movement.
1684344a3780SDimitry Andric if (CSI.isSpilledToReg()) {
1685344a3780SDimitry Andric StackUpdateLoc = MBBI;
1686344a3780SDimitry Andric break;
1687344a3780SDimitry Andric }
1688e6d15924SDimitry Andric int FrIdx = CSI.getFrameIdx();
1689e6d15924SDimitry Andric // If the frame index is not negative the callee saved info belongs to a
1690e6d15924SDimitry Andric // stack object that is not a fixed stack object. We ignore non-fixed
1691e6d15924SDimitry Andric // stack objects because we won't move the update of the stack pointer
1692e6d15924SDimitry Andric // past them.
1693e6d15924SDimitry Andric if (FrIdx >= 0)
1694e6d15924SDimitry Andric continue;
1695e6d15924SDimitry Andric
1696e6d15924SDimitry Andric if (MFI.isFixedObjectIndex(FrIdx) && MFI.getObjectOffset(FrIdx) < 0)
1697e6d15924SDimitry Andric StackUpdateLoc--;
1698e6d15924SDimitry Andric else {
1699e6d15924SDimitry Andric // Abort the operation as we can't update all CSR restores.
1700e6d15924SDimitry Andric StackUpdateLoc = MBBI;
1701e6d15924SDimitry Andric break;
1702e6d15924SDimitry Andric }
1703e6d15924SDimitry Andric }
1704e6d15924SDimitry Andric }
1705e6d15924SDimitry Andric
1706cf099d11SDimitry Andric if (FrameSize) {
1707b915e9e0SDimitry Andric // In the prologue, the loaded (or persistent) stack pointer value is
1708b915e9e0SDimitry Andric // offset by the STDU/STDUX/STWU/STWUX instruction. For targets with red
1709b915e9e0SDimitry Andric // zone add this offset back now.
1710f8af5cf6SDimitry Andric
1711b60736ecSDimitry Andric // If the function has a base pointer, the stack pointer has been copied
1712b60736ecSDimitry Andric // to it so we can restore it by copying in the other direction.
1713b60736ecSDimitry Andric if (HasRedZone && HasBP) {
1714b60736ecSDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, RBReg).
1715b60736ecSDimitry Andric addReg(BPReg).
1716b60736ecSDimitry Andric addReg(BPReg);
1717b60736ecSDimitry Andric }
1718cf099d11SDimitry Andric // If this function contained a fastcc call and GuaranteedTailCallOpt is
1719cf099d11SDimitry Andric // enabled (=> hasFastCall()==true) the fastcc call might contain a tail
1720cf099d11SDimitry Andric // call which invalidates the stack pointer value in SP(0). So we use the
1721b60736ecSDimitry Andric // value of R31 in this case. Similar situation exists with setjmp.
1722b60736ecSDimitry Andric else if (FI->hasFastCall() || MF.exposesReturnsTwice()) {
1723f8af5cf6SDimitry Andric assert(HasFP && "Expecting a valid frame pointer.");
1724b915e9e0SDimitry Andric if (!HasRedZone)
1725b915e9e0SDimitry Andric RBReg = FPReg;
1726f8af5cf6SDimitry Andric if (!isLargeFrame) {
1727b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, AddImmInst, RBReg)
1728f8af5cf6SDimitry Andric .addReg(FPReg).addImm(FrameSize);
1729f8af5cf6SDimitry Andric } else {
1730145449b1SDimitry Andric TII.materializeImmPostRA(MBB, MBBI, dl, ScratchReg, FrameSize);
1731f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, AddInst)
1732b915e9e0SDimitry Andric .addReg(RBReg)
1733f8af5cf6SDimitry Andric .addReg(FPReg)
1734f8af5cf6SDimitry Andric .addReg(ScratchReg);
1735f8af5cf6SDimitry Andric }
1736b915e9e0SDimitry Andric } else if (!isLargeFrame && !HasBP && !MFI.hasVarSizedObjects()) {
1737b915e9e0SDimitry Andric if (HasRedZone) {
1738e6d15924SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, AddImmInst, SPReg)
1739f8af5cf6SDimitry Andric .addReg(SPReg)
1740f8af5cf6SDimitry Andric .addImm(FrameSize);
1741cf099d11SDimitry Andric } else {
1742b915e9e0SDimitry Andric // Make sure that adding FrameSize will not overflow the max offset
1743b915e9e0SDimitry Andric // size.
1744b915e9e0SDimitry Andric assert(FPOffset <= 0 && BPOffset <= 0 && PBPOffset <= 0 &&
1745b915e9e0SDimitry Andric "Local offsets should be negative");
1746b915e9e0SDimitry Andric SPAdd = FrameSize;
1747b915e9e0SDimitry Andric FPOffset += FrameSize;
1748b915e9e0SDimitry Andric BPOffset += FrameSize;
1749b915e9e0SDimitry Andric PBPOffset += FrameSize;
1750b915e9e0SDimitry Andric }
1751b915e9e0SDimitry Andric } else {
1752b915e9e0SDimitry Andric // We don't want to use ScratchReg as a base register, because it
1753b915e9e0SDimitry Andric // could happen to be R0. Use FP instead, but make sure to preserve it.
1754b915e9e0SDimitry Andric if (!HasRedZone) {
1755b915e9e0SDimitry Andric // If FP is not saved, copy it to ScratchReg.
1756b915e9e0SDimitry Andric if (!HasFP)
1757b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, ScratchReg)
1758b915e9e0SDimitry Andric .addReg(FPReg)
1759b915e9e0SDimitry Andric .addReg(FPReg);
1760b915e9e0SDimitry Andric RBReg = FPReg;
1761b915e9e0SDimitry Andric }
1762e6d15924SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, LoadInst, RBReg)
1763f8af5cf6SDimitry Andric .addImm(0)
1764f8af5cf6SDimitry Andric .addReg(SPReg);
1765cf099d11SDimitry Andric }
1766f8af5cf6SDimitry Andric }
1767b915e9e0SDimitry Andric assert(RBReg != ScratchReg && "Should have avoided ScratchReg");
1768b915e9e0SDimitry Andric // If there is no red zone, ScratchReg may be needed for holding a useful
1769b915e9e0SDimitry Andric // value (although not the base register). Make sure it is not overwritten
1770b915e9e0SDimitry Andric // too early.
177159d6cff9SDimitry Andric
1772b915e9e0SDimitry Andric // If we need to restore both the LR and the CR and we only have one
1773b915e9e0SDimitry Andric // available scratch register, we must do them one at a time.
1774d9c9bd84SDimitry Andric if (MustSaveCR && SingleScratchReg && MustSaveLR) {
1775b915e9e0SDimitry Andric // Here TempReg == ScratchReg, and in the absence of red zone ScratchReg
1776b915e9e0SDimitry Andric // is live here.
1777b915e9e0SDimitry Andric assert(HasRedZone && "Expecting red zone");
1778cfca06d7SDimitry Andric BuildMI(MBB, MBBI, dl, LoadWordInst, TempReg)
1779cfca06d7SDimitry Andric .addImm(CRSaveOffset)
1780d9c9bd84SDimitry Andric .addReg(SPReg);
1781d9c9bd84SDimitry Andric for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
1782cfca06d7SDimitry Andric BuildMI(MBB, MBBI, dl, MoveToCRInst, MustSaveCRs[i])
1783d9c9bd84SDimitry Andric .addReg(TempReg, getKillRegState(i == e-1));
1784d9c9bd84SDimitry Andric }
1785d9c9bd84SDimitry Andric
1786b915e9e0SDimitry Andric // Delay restoring of the LR if ScratchReg is needed. This is ok, since
1787b915e9e0SDimitry Andric // LR is stored in the caller's stack frame. ScratchReg will be needed
1788b915e9e0SDimitry Andric // if RBReg is anything other than SP. We shouldn't use ScratchReg as
1789b915e9e0SDimitry Andric // a base register anyway, because it may happen to be R0.
1790b915e9e0SDimitry Andric bool LoadedLR = false;
1791b915e9e0SDimitry Andric if (MustSaveLR && RBReg == SPReg && isInt<16>(LROffset+SPAdd)) {
1792e6d15924SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, LoadInst, ScratchReg)
1793b915e9e0SDimitry Andric .addImm(LROffset+SPAdd)
1794b915e9e0SDimitry Andric .addReg(RBReg);
1795b915e9e0SDimitry Andric LoadedLR = true;
1796b915e9e0SDimitry Andric }
1797cf099d11SDimitry Andric
1798b915e9e0SDimitry Andric if (MustSaveCR && !(SingleScratchReg && MustSaveLR)) {
1799b915e9e0SDimitry Andric assert(RBReg == SPReg && "Should be using SP as a base register");
1800cfca06d7SDimitry Andric BuildMI(MBB, MBBI, dl, LoadWordInst, TempReg)
1801cfca06d7SDimitry Andric .addImm(CRSaveOffset)
1802b915e9e0SDimitry Andric .addReg(RBReg);
1803b915e9e0SDimitry Andric }
1804f8af5cf6SDimitry Andric
1805b915e9e0SDimitry Andric if (HasFP) {
1806b915e9e0SDimitry Andric // If there is red zone, restore FP directly, since SP has already been
1807b915e9e0SDimitry Andric // restored. Otherwise, restore the value of FP into ScratchReg.
1808b915e9e0SDimitry Andric if (HasRedZone || RBReg == SPReg)
1809f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, LoadInst, FPReg)
1810f8af5cf6SDimitry Andric .addImm(FPOffset)
1811f8af5cf6SDimitry Andric .addReg(SPReg);
1812b915e9e0SDimitry Andric else
1813b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, LoadInst, ScratchReg)
1814b915e9e0SDimitry Andric .addImm(FPOffset)
1815b915e9e0SDimitry Andric .addReg(RBReg);
1816b915e9e0SDimitry Andric }
1817f8af5cf6SDimitry Andric
181867c32a98SDimitry Andric if (FI->usesPICBase())
1819c46e6a59SDimitry Andric BuildMI(MBB, MBBI, dl, LoadInst, PPC::R30)
182067c32a98SDimitry Andric .addImm(PBPOffset)
1821b915e9e0SDimitry Andric .addReg(RBReg);
182267c32a98SDimitry Andric
1823f8af5cf6SDimitry Andric if (HasBP)
1824f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, LoadInst, BPReg)
1825f8af5cf6SDimitry Andric .addImm(BPOffset)
1826b915e9e0SDimitry Andric .addReg(RBReg);
1827b915e9e0SDimitry Andric
1828b915e9e0SDimitry Andric // There is nothing more to be loaded from the stack, so now we can
1829b915e9e0SDimitry Andric // restore SP: SP = RBReg + SPAdd.
1830b915e9e0SDimitry Andric if (RBReg != SPReg || SPAdd != 0) {
1831b915e9e0SDimitry Andric assert(!HasRedZone && "This should not happen with red zone");
1832b915e9e0SDimitry Andric // If SPAdd is 0, generate a copy.
1833b915e9e0SDimitry Andric if (SPAdd == 0)
1834b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, SPReg)
1835b915e9e0SDimitry Andric .addReg(RBReg)
1836b915e9e0SDimitry Andric .addReg(RBReg);
1837b915e9e0SDimitry Andric else
1838b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, AddImmInst, SPReg)
1839b915e9e0SDimitry Andric .addReg(RBReg)
1840b915e9e0SDimitry Andric .addImm(SPAdd);
1841b915e9e0SDimitry Andric
1842b915e9e0SDimitry Andric assert(RBReg != ScratchReg && "Should be using FP or SP as base register");
1843b915e9e0SDimitry Andric if (RBReg == FPReg)
1844b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, FPReg)
1845b915e9e0SDimitry Andric .addReg(ScratchReg)
1846b915e9e0SDimitry Andric .addReg(ScratchReg);
1847b915e9e0SDimitry Andric
1848b915e9e0SDimitry Andric // Now load the LR from the caller's stack frame.
1849b915e9e0SDimitry Andric if (MustSaveLR && !LoadedLR)
1850b915e9e0SDimitry Andric BuildMI(MBB, MBBI, dl, LoadInst, ScratchReg)
1851b915e9e0SDimitry Andric .addImm(LROffset)
1852f8af5cf6SDimitry Andric .addReg(SPReg);
1853b915e9e0SDimitry Andric }
1854f8af5cf6SDimitry Andric
1855d9c9bd84SDimitry Andric if (MustSaveCR &&
1856cfca06d7SDimitry Andric !(SingleScratchReg && MustSaveLR))
1857f8af5cf6SDimitry Andric for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
1858cfca06d7SDimitry Andric BuildMI(MBB, MBBI, dl, MoveToCRInst, MustSaveCRs[i])
1859f8af5cf6SDimitry Andric .addReg(TempReg, getKillRegState(i == e-1));
1860cf099d11SDimitry Andric
1861344a3780SDimitry Andric if (MustSaveLR) {
1862344a3780SDimitry Andric // If ROP protection is required, an extra instruction is added to compute a
1863344a3780SDimitry Andric // hash and then compare it to the hash stored in the prologue.
1864344a3780SDimitry Andric if (HasROPProtect) {
1865344a3780SDimitry Andric const int SaveIndex = FI->getROPProtectionHashSaveIndex();
1866c0981da4SDimitry Andric const int64_t ImmOffset = MFI.getObjectOffset(SaveIndex);
1867344a3780SDimitry Andric assert((ImmOffset <= -8 && ImmOffset >= -512) &&
1868344a3780SDimitry Andric "ROP hash check location offset out of range.");
1869344a3780SDimitry Andric assert(((ImmOffset & 0x7) == 0) &&
1870344a3780SDimitry Andric "ROP hash check location offset must be 8 byte aligned.");
1871344a3780SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, HashChk)
1872344a3780SDimitry Andric .addReg(ScratchReg)
1873344a3780SDimitry Andric .addImm(ImmOffset)
1874344a3780SDimitry Andric .addReg(SPReg);
1875344a3780SDimitry Andric }
1876e6d15924SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, MTLRInst).addReg(ScratchReg);
1877344a3780SDimitry Andric }
1878cf099d11SDimitry Andric
1879cf099d11SDimitry Andric // Callee pop calling convention. Pop parameter/linkage area. Used for tail
1880cf099d11SDimitry Andric // call optimization
1881dd58ef01SDimitry Andric if (IsReturnBlock) {
1882dd58ef01SDimitry Andric unsigned RetOpcode = MBBI->getOpcode();
188367c32a98SDimitry Andric if (MF.getTarget().Options.GuaranteedTailCallOpt &&
188467c32a98SDimitry Andric (RetOpcode == PPC::BLR || RetOpcode == PPC::BLR8) &&
1885044eb2f6SDimitry Andric MF.getFunction().getCallingConv() == CallingConv::Fast) {
1886cf099d11SDimitry Andric PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
1887cf099d11SDimitry Andric unsigned CallerAllocatedAmt = FI->getMinReservedArea();
1888cf099d11SDimitry Andric
1889cf099d11SDimitry Andric if (CallerAllocatedAmt && isInt<16>(CallerAllocatedAmt)) {
1890f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, AddImmInst, SPReg)
1891f8af5cf6SDimitry Andric .addReg(SPReg).addImm(CallerAllocatedAmt);
1892cf099d11SDimitry Andric } else {
1893f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, LoadImmShiftedInst, ScratchReg)
1894cf099d11SDimitry Andric .addImm(CallerAllocatedAmt >> 16);
1895f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, OrImmInst, ScratchReg)
1896f8af5cf6SDimitry Andric .addReg(ScratchReg, RegState::Kill)
1897cf099d11SDimitry Andric .addImm(CallerAllocatedAmt & 0xFFFF);
1898f8af5cf6SDimitry Andric BuildMI(MBB, MBBI, dl, AddInst)
1899f8af5cf6SDimitry Andric .addReg(SPReg)
1900cf099d11SDimitry Andric .addReg(FPReg)
1901f8af5cf6SDimitry Andric .addReg(ScratchReg);
1902cf099d11SDimitry Andric }
190301095a5dSDimitry Andric } else {
190401095a5dSDimitry Andric createTailCallBranchInstr(MBB);
190501095a5dSDimitry Andric }
190601095a5dSDimitry Andric }
190701095a5dSDimitry Andric }
190801095a5dSDimitry Andric
createTailCallBranchInstr(MachineBasicBlock & MBB) const190901095a5dSDimitry Andric void PPCFrameLowering::createTailCallBranchInstr(MachineBasicBlock &MBB) const {
191001095a5dSDimitry Andric MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
191101095a5dSDimitry Andric
1912c7dac04cSDimitry Andric // If we got this far a first terminator should exist.
1913c7dac04cSDimitry Andric assert(MBBI != MBB.end() && "Failed to find the first terminator.");
191401095a5dSDimitry Andric
1915c7dac04cSDimitry Andric DebugLoc dl = MBBI->getDebugLoc();
191671d5a254SDimitry Andric const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
191701095a5dSDimitry Andric
1918cfca06d7SDimitry Andric // Create branch instruction for pseudo tail call return instruction.
1919cfca06d7SDimitry Andric // The TCRETURNdi variants are direct calls. Valid targets for those are
1920cfca06d7SDimitry Andric // MO_GlobalAddress operands as well as MO_ExternalSymbol with PC-Rel
1921cfca06d7SDimitry Andric // since we can tail call external functions with PC-Rel (i.e. we don't need
1922cfca06d7SDimitry Andric // to worry about different TOC pointers). Some of the external functions will
1923cfca06d7SDimitry Andric // be MO_GlobalAddress while others like memcpy for example, are going to
1924cfca06d7SDimitry Andric // be MO_ExternalSymbol.
192501095a5dSDimitry Andric unsigned RetOpcode = MBBI->getOpcode();
192601095a5dSDimitry Andric if (RetOpcode == PPC::TCRETURNdi) {
1927cf099d11SDimitry Andric MBBI = MBB.getLastNonDebugInstr();
1928cf099d11SDimitry Andric MachineOperand &JumpTarget = MBBI->getOperand(0);
1929cfca06d7SDimitry Andric if (JumpTarget.isGlobal())
1930cf099d11SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
1931cf099d11SDimitry Andric addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
1932cfca06d7SDimitry Andric else if (JumpTarget.isSymbol())
1933cfca06d7SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
1934cfca06d7SDimitry Andric addExternalSymbol(JumpTarget.getSymbolName());
1935cfca06d7SDimitry Andric else
1936cfca06d7SDimitry Andric llvm_unreachable("Expecting Global or External Symbol");
1937cf099d11SDimitry Andric } else if (RetOpcode == PPC::TCRETURNri) {
1938cf099d11SDimitry Andric MBBI = MBB.getLastNonDebugInstr();
1939cf099d11SDimitry Andric assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
1940cf099d11SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR));
1941cf099d11SDimitry Andric } else if (RetOpcode == PPC::TCRETURNai) {
1942cf099d11SDimitry Andric MBBI = MBB.getLastNonDebugInstr();
1943cf099d11SDimitry Andric MachineOperand &JumpTarget = MBBI->getOperand(0);
1944cf099d11SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm());
1945cf099d11SDimitry Andric } else if (RetOpcode == PPC::TCRETURNdi8) {
1946cf099d11SDimitry Andric MBBI = MBB.getLastNonDebugInstr();
1947cf099d11SDimitry Andric MachineOperand &JumpTarget = MBBI->getOperand(0);
1948cfca06d7SDimitry Andric if (JumpTarget.isGlobal())
1949cf099d11SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
1950cf099d11SDimitry Andric addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
1951cfca06d7SDimitry Andric else if (JumpTarget.isSymbol())
1952cfca06d7SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
1953cfca06d7SDimitry Andric addExternalSymbol(JumpTarget.getSymbolName());
1954cfca06d7SDimitry Andric else
1955cfca06d7SDimitry Andric llvm_unreachable("Expecting Global or External Symbol");
1956cf099d11SDimitry Andric } else if (RetOpcode == PPC::TCRETURNri8) {
1957cf099d11SDimitry Andric MBBI = MBB.getLastNonDebugInstr();
1958cf099d11SDimitry Andric assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
1959cf099d11SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR8));
1960cf099d11SDimitry Andric } else if (RetOpcode == PPC::TCRETURNai8) {
1961cf099d11SDimitry Andric MBBI = MBB.getLastNonDebugInstr();
1962cf099d11SDimitry Andric MachineOperand &JumpTarget = MBBI->getOperand(0);
1963cf099d11SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm());
1964cf099d11SDimitry Andric }
1965cf099d11SDimitry Andric }
1966cf099d11SDimitry Andric
determineCalleeSaves(MachineFunction & MF,BitVector & SavedRegs,RegScavenger * RS) const1967ee8648bdSDimitry Andric void PPCFrameLowering::determineCalleeSaves(MachineFunction &MF,
1968ee8648bdSDimitry Andric BitVector &SavedRegs,
1969ee8648bdSDimitry Andric RegScavenger *RS) const {
1970ee8648bdSDimitry Andric TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
1971ac9a064cSDimitry Andric if (Subtarget.isAIXABI())
1972ac9a064cSDimitry Andric updateCalleeSaves(MF, SavedRegs);
1973ee8648bdSDimitry Andric
197471d5a254SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1975cf099d11SDimitry Andric
1976145449b1SDimitry Andric // Do not explicitly save the callee saved VSRp registers.
1977145449b1SDimitry Andric // The individual VSR subregisters will be saved instead.
1978145449b1SDimitry Andric SavedRegs.reset(PPC::VSRp26);
1979145449b1SDimitry Andric SavedRegs.reset(PPC::VSRp27);
1980145449b1SDimitry Andric SavedRegs.reset(PPC::VSRp28);
1981145449b1SDimitry Andric SavedRegs.reset(PPC::VSRp29);
1982145449b1SDimitry Andric SavedRegs.reset(PPC::VSRp30);
1983145449b1SDimitry Andric SavedRegs.reset(PPC::VSRp31);
1984145449b1SDimitry Andric
1985cf099d11SDimitry Andric // Save and clear the LR state.
1986cf099d11SDimitry Andric PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
1987cf099d11SDimitry Andric unsigned LR = RegInfo->getRARegister();
1988cf099d11SDimitry Andric FI->setMustSaveLR(MustSaveLR(MF, LR));
1989ee8648bdSDimitry Andric SavedRegs.reset(LR);
1990cf099d11SDimitry Andric
1991cf099d11SDimitry Andric // Save R31 if necessary
1992cf099d11SDimitry Andric int FPSI = FI->getFramePointerSaveIndex();
19931d5ae102SDimitry Andric const bool isPPC64 = Subtarget.isPPC64();
1994b915e9e0SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
1995cf099d11SDimitry Andric
1996cf099d11SDimitry Andric // If the frame pointer save index hasn't been defined yet.
1997cf099d11SDimitry Andric if (!FPSI && needsFP(MF)) {
1998cf099d11SDimitry Andric // Find out what the fix offset of the frame pointer save area.
19995a5ac124SDimitry Andric int FPOffset = getFramePointerSaveOffset();
2000cf099d11SDimitry Andric // Allocate the frame index for frame pointer save area.
2001b915e9e0SDimitry Andric FPSI = MFI.CreateFixedObject(isPPC64? 8 : 4, FPOffset, true);
2002cf099d11SDimitry Andric // Save the result.
2003cf099d11SDimitry Andric FI->setFramePointerSaveIndex(FPSI);
2004cf099d11SDimitry Andric }
2005cf099d11SDimitry Andric
2006f8af5cf6SDimitry Andric int BPSI = FI->getBasePointerSaveIndex();
2007f8af5cf6SDimitry Andric if (!BPSI && RegInfo->hasBasePointer(MF)) {
20085a5ac124SDimitry Andric int BPOffset = getBasePointerSaveOffset();
2009f8af5cf6SDimitry Andric // Allocate the frame index for the base pointer save area.
2010b915e9e0SDimitry Andric BPSI = MFI.CreateFixedObject(isPPC64? 8 : 4, BPOffset, true);
2011f8af5cf6SDimitry Andric // Save the result.
2012f8af5cf6SDimitry Andric FI->setBasePointerSaveIndex(BPSI);
2013f8af5cf6SDimitry Andric }
2014f8af5cf6SDimitry Andric
201567c32a98SDimitry Andric // Reserve stack space for the PIC Base register (R30).
201667c32a98SDimitry Andric // Only used in SVR4 32-bit.
201767c32a98SDimitry Andric if (FI->usesPICBase()) {
2018b915e9e0SDimitry Andric int PBPSI = MFI.CreateFixedObject(4, -8, true);
201967c32a98SDimitry Andric FI->setPICBasePointerSaveIndex(PBPSI);
202067c32a98SDimitry Andric }
202167c32a98SDimitry Andric
2022b915e9e0SDimitry Andric // Make sure we don't explicitly spill r31, because, for example, we have
2023eb11fae6SDimitry Andric // some inline asm which explicitly clobbers it, when we otherwise have a
2024b915e9e0SDimitry Andric // frame pointer and are using r31's spill slot for the prologue/epilogue
2025b915e9e0SDimitry Andric // code. Same goes for the base pointer and the PIC base register.
2026b915e9e0SDimitry Andric if (needsFP(MF))
2027b915e9e0SDimitry Andric SavedRegs.reset(isPPC64 ? PPC::X31 : PPC::R31);
2028adf62863SDimitry Andric if (RegInfo->hasBasePointer(MF)) {
2029b915e9e0SDimitry Andric SavedRegs.reset(RegInfo->getBaseRegister(MF));
2030adf62863SDimitry Andric // On AIX, when BaseRegister(R30) is used, need to spill r31 too to match
2031adf62863SDimitry Andric // AIX trackback table requirement.
2032adf62863SDimitry Andric if (!needsFP(MF) && !SavedRegs.test(isPPC64 ? PPC::X31 : PPC::R31) &&
2033adf62863SDimitry Andric Subtarget.isAIXABI()) {
2034adf62863SDimitry Andric assert(
2035adf62863SDimitry Andric (RegInfo->getBaseRegister(MF) == (isPPC64 ? PPC::X30 : PPC::R30)) &&
2036adf62863SDimitry Andric "Invalid base register on AIX!");
2037adf62863SDimitry Andric SavedRegs.set(isPPC64 ? PPC::X31 : PPC::R31);
2038adf62863SDimitry Andric }
2039adf62863SDimitry Andric }
2040b915e9e0SDimitry Andric if (FI->usesPICBase())
2041b915e9e0SDimitry Andric SavedRegs.reset(PPC::R30);
2042b915e9e0SDimitry Andric
2043cf099d11SDimitry Andric // Reserve stack space to move the linkage area to in case of a tail call.
2044cf099d11SDimitry Andric int TCSPDelta = 0;
204563faed5bSDimitry Andric if (MF.getTarget().Options.GuaranteedTailCallOpt &&
204663faed5bSDimitry Andric (TCSPDelta = FI->getTailCallSPDelta()) < 0) {
2047b915e9e0SDimitry Andric MFI.CreateFixedObject(-1 * TCSPDelta, TCSPDelta, true);
2048cf099d11SDimitry Andric }
2049cf099d11SDimitry Andric
2050cfca06d7SDimitry Andric // Allocate the nonvolatile CR spill slot iff the function uses CR 2, 3, or 4.
2051cfca06d7SDimitry Andric // For 64-bit SVR4, and all flavors of AIX we create a FixedStack
2052cfca06d7SDimitry Andric // object at the offset of the CR-save slot in the linkage area. The actual
2053cfca06d7SDimitry Andric // save and restore of the condition register will be created as part of the
2054cfca06d7SDimitry Andric // prologue and epilogue insertion, but the FixedStack object is needed to
2055cfca06d7SDimitry Andric // keep the CalleSavedInfo valid.
2056cfca06d7SDimitry Andric if ((SavedRegs.test(PPC::CR2) || SavedRegs.test(PPC::CR3) ||
2057ee8648bdSDimitry Andric SavedRegs.test(PPC::CR4))) {
2058cfca06d7SDimitry Andric const uint64_t SpillSize = 4; // Condition register is always 4 bytes.
2059cfca06d7SDimitry Andric const int64_t SpillOffset =
2060cfca06d7SDimitry Andric Subtarget.isPPC64() ? 8 : Subtarget.isAIXABI() ? 4 : -4;
2061cfca06d7SDimitry Andric int FrameIdx =
2062cfca06d7SDimitry Andric MFI.CreateFixedObject(SpillSize, SpillOffset,
2063cfca06d7SDimitry Andric /* IsImmutable */ true, /* IsAliased */ false);
20644a16efa3SDimitry Andric FI->setCRSpillFrameIndex(FrameIdx);
2065cf099d11SDimitry Andric }
2066cf099d11SDimitry Andric }
2067cf099d11SDimitry Andric
processFunctionBeforeFrameFinalized(MachineFunction & MF,RegScavenger * RS) const20684a16efa3SDimitry Andric void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
20694a16efa3SDimitry Andric RegScavenger *RS) const {
2070cf099d11SDimitry Andric // Get callee saved register information.
2071b915e9e0SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
2072b915e9e0SDimitry Andric const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
2073cf099d11SDimitry Andric
207401095a5dSDimitry Andric // If the function is shrink-wrapped, and if the function has a tail call, the
207501095a5dSDimitry Andric // tail call might not be in the new RestoreBlock, so real branch instruction
207601095a5dSDimitry Andric // won't be generated by emitEpilogue(), because shrink-wrap has chosen new
207701095a5dSDimitry Andric // RestoreBlock. So we handle this case here.
2078b915e9e0SDimitry Andric if (MFI.getSavePoint() && MFI.hasTailCall()) {
2079b915e9e0SDimitry Andric MachineBasicBlock *RestoreBlock = MFI.getRestorePoint();
208001095a5dSDimitry Andric for (MachineBasicBlock &MBB : MF) {
208101095a5dSDimitry Andric if (MBB.isReturnBlock() && (&MBB) != RestoreBlock)
208201095a5dSDimitry Andric createTailCallBranchInstr(MBB);
208301095a5dSDimitry Andric }
208401095a5dSDimitry Andric }
208501095a5dSDimitry Andric
2086cf099d11SDimitry Andric // Early exit if no callee saved registers are modified!
2087cf099d11SDimitry Andric if (CSI.empty() && !needsFP(MF)) {
20884a16efa3SDimitry Andric addScavengingSpillSlot(MF, RS);
2089cf099d11SDimitry Andric return;
2090cf099d11SDimitry Andric }
2091cf099d11SDimitry Andric
2092cf099d11SDimitry Andric unsigned MinGPR = PPC::R31;
2093cf099d11SDimitry Andric unsigned MinG8R = PPC::X31;
2094cf099d11SDimitry Andric unsigned MinFPR = PPC::F31;
2095eb11fae6SDimitry Andric unsigned MinVR = Subtarget.hasSPE() ? PPC::S31 : PPC::V31;
2096cf099d11SDimitry Andric
2097cf099d11SDimitry Andric bool HasGPSaveArea = false;
2098cf099d11SDimitry Andric bool HasG8SaveArea = false;
2099cf099d11SDimitry Andric bool HasFPSaveArea = false;
2100cf099d11SDimitry Andric bool HasVRSaveArea = false;
2101cf099d11SDimitry Andric
2102cf099d11SDimitry Andric SmallVector<CalleeSavedInfo, 18> GPRegs;
2103cf099d11SDimitry Andric SmallVector<CalleeSavedInfo, 18> G8Regs;
2104cf099d11SDimitry Andric SmallVector<CalleeSavedInfo, 18> FPRegs;
2105cf099d11SDimitry Andric SmallVector<CalleeSavedInfo, 18> VRegs;
2106cf099d11SDimitry Andric
2107f65dcba8SDimitry Andric for (const CalleeSavedInfo &I : CSI) {
21086f8fc217SDimitry Andric Register Reg = I.getReg();
2109e6d15924SDimitry Andric assert((!MF.getInfo<PPCFunctionInfo>()->mustSaveTOC() ||
2110e6d15924SDimitry Andric (Reg != PPC::X2 && Reg != PPC::R2)) &&
2111e6d15924SDimitry Andric "Not expecting to try to spill R2 in a function that must save TOC");
21121d5ae102SDimitry Andric if (PPC::GPRCRegClass.contains(Reg)) {
2113cf099d11SDimitry Andric HasGPSaveArea = true;
2114cf099d11SDimitry Andric
2115f65dcba8SDimitry Andric GPRegs.push_back(I);
2116cf099d11SDimitry Andric
2117cf099d11SDimitry Andric if (Reg < MinGPR) {
2118cf099d11SDimitry Andric MinGPR = Reg;
2119cf099d11SDimitry Andric }
212058b69754SDimitry Andric } else if (PPC::G8RCRegClass.contains(Reg)) {
2121cf099d11SDimitry Andric HasG8SaveArea = true;
2122cf099d11SDimitry Andric
2123f65dcba8SDimitry Andric G8Regs.push_back(I);
2124cf099d11SDimitry Andric
2125cf099d11SDimitry Andric if (Reg < MinG8R) {
2126cf099d11SDimitry Andric MinG8R = Reg;
2127cf099d11SDimitry Andric }
212858b69754SDimitry Andric } else if (PPC::F8RCRegClass.contains(Reg)) {
2129cf099d11SDimitry Andric HasFPSaveArea = true;
2130cf099d11SDimitry Andric
2131f65dcba8SDimitry Andric FPRegs.push_back(I);
2132cf099d11SDimitry Andric
2133cf099d11SDimitry Andric if (Reg < MinFPR) {
2134cf099d11SDimitry Andric MinFPR = Reg;
2135cf099d11SDimitry Andric }
213658b69754SDimitry Andric } else if (PPC::CRBITRCRegClass.contains(Reg) ||
213758b69754SDimitry Andric PPC::CRRCRegClass.contains(Reg)) {
2138522600a2SDimitry Andric ; // do nothing, as we already know whether CRs are spilled
2139eb11fae6SDimitry Andric } else if (PPC::VRRCRegClass.contains(Reg) ||
2140eb11fae6SDimitry Andric PPC::SPERCRegClass.contains(Reg)) {
2141eb11fae6SDimitry Andric // Altivec and SPE are mutually exclusive, but have the same stack
2142eb11fae6SDimitry Andric // alignment requirements, so overload the save area for both cases.
2143cf099d11SDimitry Andric HasVRSaveArea = true;
2144cf099d11SDimitry Andric
2145f65dcba8SDimitry Andric VRegs.push_back(I);
2146cf099d11SDimitry Andric
2147cf099d11SDimitry Andric if (Reg < MinVR) {
2148cf099d11SDimitry Andric MinVR = Reg;
2149cf099d11SDimitry Andric }
2150cf099d11SDimitry Andric } else {
2151cf099d11SDimitry Andric llvm_unreachable("Unknown RegisterClass!");
2152cf099d11SDimitry Andric }
2153cf099d11SDimitry Andric }
2154cf099d11SDimitry Andric
2155cf099d11SDimitry Andric PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>();
21565a5ac124SDimitry Andric const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
2157cf099d11SDimitry Andric
2158cf099d11SDimitry Andric int64_t LowerBound = 0;
2159cf099d11SDimitry Andric
2160cf099d11SDimitry Andric // Take into account stack space reserved for tail calls.
2161cf099d11SDimitry Andric int TCSPDelta = 0;
216263faed5bSDimitry Andric if (MF.getTarget().Options.GuaranteedTailCallOpt &&
216363faed5bSDimitry Andric (TCSPDelta = PFI->getTailCallSPDelta()) < 0) {
2164cf099d11SDimitry Andric LowerBound = TCSPDelta;
2165cf099d11SDimitry Andric }
2166cf099d11SDimitry Andric
2167cf099d11SDimitry Andric // The Floating-point register save area is right below the back chain word
2168cf099d11SDimitry Andric // of the previous stack frame.
2169cf099d11SDimitry Andric if (HasFPSaveArea) {
2170cf099d11SDimitry Andric for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) {
2171cf099d11SDimitry Andric int FI = FPRegs[i].getFrameIdx();
2172cf099d11SDimitry Andric
2173b915e9e0SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
2174cf099d11SDimitry Andric }
2175cf099d11SDimitry Andric
21764a16efa3SDimitry Andric LowerBound -= (31 - TRI->getEncodingValue(MinFPR) + 1) * 8;
2177cf099d11SDimitry Andric }
2178cf099d11SDimitry Andric
2179cf099d11SDimitry Andric // Check whether the frame pointer register is allocated. If so, make sure it
2180cf099d11SDimitry Andric // is spilled to the correct offset.
2181cf099d11SDimitry Andric if (needsFP(MF)) {
2182cf099d11SDimitry Andric int FI = PFI->getFramePointerSaveIndex();
2183cf099d11SDimitry Andric assert(FI && "No Frame Pointer Save Slot!");
2184b915e9e0SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
21857af96fb3SDimitry Andric // FP is R31/X31, so no need to update MinGPR/MinG8R.
21867af96fb3SDimitry Andric HasGPSaveArea = true;
2187cf099d11SDimitry Andric }
2188cf099d11SDimitry Andric
218967c32a98SDimitry Andric if (PFI->usesPICBase()) {
219067c32a98SDimitry Andric int FI = PFI->getPICBasePointerSaveIndex();
219167c32a98SDimitry Andric assert(FI && "No PIC Base Pointer Save Slot!");
2192b915e9e0SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
21937af96fb3SDimitry Andric
21947af96fb3SDimitry Andric MinGPR = std::min<unsigned>(MinGPR, PPC::R30);
21957af96fb3SDimitry Andric HasGPSaveArea = true;
219667c32a98SDimitry Andric }
219767c32a98SDimitry Andric
219871d5a254SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
2199f8af5cf6SDimitry Andric if (RegInfo->hasBasePointer(MF)) {
2200f8af5cf6SDimitry Andric int FI = PFI->getBasePointerSaveIndex();
2201f8af5cf6SDimitry Andric assert(FI && "No Base Pointer Save Slot!");
2202b915e9e0SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
22037af96fb3SDimitry Andric
22041d5ae102SDimitry Andric Register BP = RegInfo->getBaseRegister(MF);
22057af96fb3SDimitry Andric if (PPC::G8RCRegClass.contains(BP)) {
22067af96fb3SDimitry Andric MinG8R = std::min<unsigned>(MinG8R, BP);
22077af96fb3SDimitry Andric HasG8SaveArea = true;
22087af96fb3SDimitry Andric } else if (PPC::GPRCRegClass.contains(BP)) {
22097af96fb3SDimitry Andric MinGPR = std::min<unsigned>(MinGPR, BP);
22107af96fb3SDimitry Andric HasGPSaveArea = true;
22117af96fb3SDimitry Andric }
2212f8af5cf6SDimitry Andric }
2213f8af5cf6SDimitry Andric
2214cf099d11SDimitry Andric // General register save area starts right below the Floating-point
2215cf099d11SDimitry Andric // register save area.
2216cf099d11SDimitry Andric if (HasGPSaveArea || HasG8SaveArea) {
2217cf099d11SDimitry Andric // Move general register save area spill slots down, taking into account
2218cf099d11SDimitry Andric // the size of the Floating-point register save area.
2219cf099d11SDimitry Andric for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) {
2220d8e91e46SDimitry Andric if (!GPRegs[i].isSpilledToReg()) {
2221cf099d11SDimitry Andric int FI = GPRegs[i].getFrameIdx();
2222b915e9e0SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
2223cf099d11SDimitry Andric }
2224d8e91e46SDimitry Andric }
2225cf099d11SDimitry Andric
2226cf099d11SDimitry Andric // Move general register save area spill slots down, taking into account
2227cf099d11SDimitry Andric // the size of the Floating-point register save area.
2228cf099d11SDimitry Andric for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) {
2229d8e91e46SDimitry Andric if (!G8Regs[i].isSpilledToReg()) {
2230cf099d11SDimitry Andric int FI = G8Regs[i].getFrameIdx();
2231b915e9e0SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
2232cf099d11SDimitry Andric }
2233d8e91e46SDimitry Andric }
2234cf099d11SDimitry Andric
2235cf099d11SDimitry Andric unsigned MinReg =
22364a16efa3SDimitry Andric std::min<unsigned>(TRI->getEncodingValue(MinGPR),
22374a16efa3SDimitry Andric TRI->getEncodingValue(MinG8R));
2238cf099d11SDimitry Andric
2239cfca06d7SDimitry Andric const unsigned GPRegSize = Subtarget.isPPC64() ? 8 : 4;
2240cfca06d7SDimitry Andric LowerBound -= (31 - MinReg + 1) * GPRegSize;
2241cf099d11SDimitry Andric }
2242cf099d11SDimitry Andric
2243522600a2SDimitry Andric // For 32-bit only, the CR save area is below the general register
2244522600a2SDimitry Andric // save area. For 64-bit SVR4, the CR save area is addressed relative
2245522600a2SDimitry Andric // to the stack pointer and hence does not need an adjustment here.
2246522600a2SDimitry Andric // Only CR2 (the first nonvolatile spilled) has an associated frame
2247522600a2SDimitry Andric // index so that we have a single uniform save area.
2248cfca06d7SDimitry Andric if (spillsCR(MF) && Subtarget.is32BitELFABI()) {
2249cf099d11SDimitry Andric // Adjust the frame index of the CR spill slot.
2250cfca06d7SDimitry Andric for (const auto &CSInfo : CSI) {
2251cfca06d7SDimitry Andric if (CSInfo.getReg() == PPC::CR2) {
2252cfca06d7SDimitry Andric int FI = CSInfo.getFrameIdx();
2253b915e9e0SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
2254cfca06d7SDimitry Andric break;
2255cf099d11SDimitry Andric }
2256cf099d11SDimitry Andric }
2257cf099d11SDimitry Andric
2258cf099d11SDimitry Andric LowerBound -= 4; // The CR save area is always 4 bytes long.
2259cf099d11SDimitry Andric }
2260cf099d11SDimitry Andric
2261eb11fae6SDimitry Andric // Both Altivec and SPE have the same alignment and padding requirements
2262eb11fae6SDimitry Andric // within the stack frame.
2263cf099d11SDimitry Andric if (HasVRSaveArea) {
2264eb11fae6SDimitry Andric // Insert alignment padding, we need 16-byte alignment. Note: for positive
2265ca089b24SDimitry Andric // number the alignment formula is : y = (x + (n-1)) & (~(n-1)). But since
2266ca089b24SDimitry Andric // we are using negative number here (the stack grows downward). We should
2267ca089b24SDimitry Andric // use formula : y = x & (~(n-1)). Where x is the size before aligning, n
2268ca089b24SDimitry Andric // is the alignment size ( n = 16 here) and y is the size after aligning.
2269ca089b24SDimitry Andric assert(LowerBound <= 0 && "Expect LowerBound have a non-positive value!");
2270ca089b24SDimitry Andric LowerBound &= ~(15);
2271cf099d11SDimitry Andric
2272cf099d11SDimitry Andric for (unsigned i = 0, e = VRegs.size(); i != e; ++i) {
2273cf099d11SDimitry Andric int FI = VRegs[i].getFrameIdx();
2274cf099d11SDimitry Andric
2275b915e9e0SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
2276cf099d11SDimitry Andric }
2277cf099d11SDimitry Andric }
22784a16efa3SDimitry Andric
22794a16efa3SDimitry Andric addScavengingSpillSlot(MF, RS);
22804a16efa3SDimitry Andric }
22814a16efa3SDimitry Andric
22824a16efa3SDimitry Andric void
addScavengingSpillSlot(MachineFunction & MF,RegScavenger * RS) const22834a16efa3SDimitry Andric PPCFrameLowering::addScavengingSpillSlot(MachineFunction &MF,
22844a16efa3SDimitry Andric RegScavenger *RS) const {
22854a16efa3SDimitry Andric // Reserve a slot closest to SP or frame pointer if we have a dynalloc or
22864a16efa3SDimitry Andric // a large stack, which will require scavenging a register to materialize a
22874a16efa3SDimitry Andric // large offset.
22884a16efa3SDimitry Andric
22894a16efa3SDimitry Andric // We need to have a scavenger spill slot for spills if the frame size is
22904a16efa3SDimitry Andric // large. In case there is no free register for large-offset addressing,
22914a16efa3SDimitry Andric // this slot is used for the necessary emergency spill. Also, we need the
22924a16efa3SDimitry Andric // slot for dynamic stack allocations.
22934a16efa3SDimitry Andric
22944a16efa3SDimitry Andric // The scavenger might be invoked if the frame offset does not fit into
22957fa27ce4SDimitry Andric // the 16-bit immediate in case of not SPE and 8-bit in case of SPE.
22967fa27ce4SDimitry Andric // We don't know the complete frame size here because we've not yet computed
22977fa27ce4SDimitry Andric // callee-saved register spills or the needed alignment padding.
2298e6d15924SDimitry Andric unsigned StackSize = determineFrameLayout(MF, true);
2299b915e9e0SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
23007fa27ce4SDimitry Andric bool NeedSpills = Subtarget.hasSPE() ? !isInt<8>(StackSize) : !isInt<16>(StackSize);
23017fa27ce4SDimitry Andric
2302b60736ecSDimitry Andric if (MFI.hasVarSizedObjects() || spillsCR(MF) || hasNonRISpills(MF) ||
23037fa27ce4SDimitry Andric (hasSpills(MF) && NeedSpills)) {
230412f3ca4cSDimitry Andric const TargetRegisterClass &GPRC = PPC::GPRCRegClass;
230512f3ca4cSDimitry Andric const TargetRegisterClass &G8RC = PPC::G8RCRegClass;
230612f3ca4cSDimitry Andric const TargetRegisterClass &RC = Subtarget.isPPC64() ? G8RC : GPRC;
230712f3ca4cSDimitry Andric const TargetRegisterInfo &TRI = *Subtarget.getRegisterInfo();
230812f3ca4cSDimitry Andric unsigned Size = TRI.getSpillSize(RC);
2309cfca06d7SDimitry Andric Align Alignment = TRI.getSpillAlign(RC);
2310cfca06d7SDimitry Andric RS->addScavengingFrameIndex(MFI.CreateStackObject(Size, Alignment, false));
23114a16efa3SDimitry Andric
2312f8af5cf6SDimitry Andric // Might we have over-aligned allocas?
2313cfca06d7SDimitry Andric bool HasAlVars =
2314cfca06d7SDimitry Andric MFI.hasVarSizedObjects() && MFI.getMaxAlign() > getStackAlign();
2315f8af5cf6SDimitry Andric
23164a16efa3SDimitry Andric // These kinds of spills might need two registers.
2317b60736ecSDimitry Andric if (spillsCR(MF) || HasAlVars)
2318cfca06d7SDimitry Andric RS->addScavengingFrameIndex(
2319cfca06d7SDimitry Andric MFI.CreateStackObject(Size, Alignment, false));
23204a16efa3SDimitry Andric }
2321cf099d11SDimitry Andric }
2322522600a2SDimitry Andric
2323d8e91e46SDimitry Andric // This function checks if a callee saved gpr can be spilled to a volatile
2324d8e91e46SDimitry Andric // vector register. This occurs for leaf functions when the option
2325d8e91e46SDimitry Andric // ppc-enable-pe-vector-spills is enabled. If there are any remaining registers
2326d8e91e46SDimitry Andric // which were not spilled to vectors, return false so the target independent
2327d8e91e46SDimitry Andric // code can handle them by assigning a FrameIdx to a stack slot.
assignCalleeSavedSpillSlots(MachineFunction & MF,const TargetRegisterInfo * TRI,std::vector<CalleeSavedInfo> & CSI) const2328d8e91e46SDimitry Andric bool PPCFrameLowering::assignCalleeSavedSpillSlots(
2329d8e91e46SDimitry Andric MachineFunction &MF, const TargetRegisterInfo *TRI,
2330d8e91e46SDimitry Andric std::vector<CalleeSavedInfo> &CSI) const {
2331d8e91e46SDimitry Andric
2332d8e91e46SDimitry Andric if (CSI.empty())
2333d8e91e46SDimitry Andric return true; // Early exit if no callee saved registers are modified!
2334d8e91e46SDimitry Andric
23357fa27ce4SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
23367fa27ce4SDimitry Andric const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
23377fa27ce4SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo();
23387fa27ce4SDimitry Andric
23397fa27ce4SDimitry Andric if (Subtarget.hasSPE()) {
23407fa27ce4SDimitry Andric // In case of SPE we only have SuperRegs and CRs
23417fa27ce4SDimitry Andric // in our CalleSaveInfo vector.
23427fa27ce4SDimitry Andric
23437fa27ce4SDimitry Andric for (auto &CalleeSaveReg : CSI) {
2344b1c73532SDimitry Andric MCPhysReg Reg = CalleeSaveReg.getReg();
2345b1c73532SDimitry Andric MCPhysReg Lower = RegInfo->getSubReg(Reg, 1);
2346b1c73532SDimitry Andric MCPhysReg Higher = RegInfo->getSubReg(Reg, 2);
23477fa27ce4SDimitry Andric
2348b1c73532SDimitry Andric if ( // Check only for SuperRegs.
2349b1c73532SDimitry Andric Lower &&
23507fa27ce4SDimitry Andric // Replace Reg if only lower-32 bits modified
2351b1c73532SDimitry Andric !MRI.isPhysRegModified(Higher))
2352b1c73532SDimitry Andric CalleeSaveReg = CalleeSavedInfo(Lower);
23537fa27ce4SDimitry Andric }
23547fa27ce4SDimitry Andric }
23557fa27ce4SDimitry Andric
2356d8e91e46SDimitry Andric // Early exit if cannot spill gprs to volatile vector registers.
2357d8e91e46SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
2358d8e91e46SDimitry Andric if (!EnablePEVectorSpills || MFI.hasCalls() || !Subtarget.hasP9Vector())
2359d8e91e46SDimitry Andric return false;
2360d8e91e46SDimitry Andric
2361d8e91e46SDimitry Andric // Build a BitVector of VSRs that can be used for spilling GPRs.
2362d8e91e46SDimitry Andric BitVector BVAllocatable = TRI->getAllocatableSet(MF);
2363d8e91e46SDimitry Andric BitVector BVCalleeSaved(TRI->getNumRegs());
2364d8e91e46SDimitry Andric for (unsigned i = 0; CSRegs[i]; ++i)
2365d8e91e46SDimitry Andric BVCalleeSaved.set(CSRegs[i]);
2366d8e91e46SDimitry Andric
2367d8e91e46SDimitry Andric for (unsigned Reg : BVAllocatable.set_bits()) {
2368344a3780SDimitry Andric // Set to 0 if the register is not a volatile VSX register, or if it is
2369d8e91e46SDimitry Andric // used in the function.
2370344a3780SDimitry Andric if (BVCalleeSaved[Reg] || !PPC::VSRCRegClass.contains(Reg) ||
23717fa27ce4SDimitry Andric MRI.isPhysRegUsed(Reg))
2372d8e91e46SDimitry Andric BVAllocatable.reset(Reg);
2373d8e91e46SDimitry Andric }
2374d8e91e46SDimitry Andric
2375d8e91e46SDimitry Andric bool AllSpilledToReg = true;
2376344a3780SDimitry Andric unsigned LastVSRUsedForSpill = 0;
2377d8e91e46SDimitry Andric for (auto &CS : CSI) {
2378d8e91e46SDimitry Andric if (BVAllocatable.none())
2379d8e91e46SDimitry Andric return false;
2380d8e91e46SDimitry Andric
23816f8fc217SDimitry Andric Register Reg = CS.getReg();
2382344a3780SDimitry Andric
2383344a3780SDimitry Andric if (!PPC::G8RCRegClass.contains(Reg)) {
2384d8e91e46SDimitry Andric AllSpilledToReg = false;
2385d8e91e46SDimitry Andric continue;
2386d8e91e46SDimitry Andric }
2387d8e91e46SDimitry Andric
2388344a3780SDimitry Andric // For P9, we can reuse LastVSRUsedForSpill to spill two GPRs
2389344a3780SDimitry Andric // into one VSR using the mtvsrdd instruction.
2390344a3780SDimitry Andric if (LastVSRUsedForSpill != 0) {
2391344a3780SDimitry Andric CS.setDstReg(LastVSRUsedForSpill);
2392344a3780SDimitry Andric BVAllocatable.reset(LastVSRUsedForSpill);
2393344a3780SDimitry Andric LastVSRUsedForSpill = 0;
2394344a3780SDimitry Andric continue;
2395344a3780SDimitry Andric }
2396344a3780SDimitry Andric
2397d8e91e46SDimitry Andric unsigned VolatileVFReg = BVAllocatable.find_first();
2398d8e91e46SDimitry Andric if (VolatileVFReg < BVAllocatable.size()) {
2399d8e91e46SDimitry Andric CS.setDstReg(VolatileVFReg);
2400344a3780SDimitry Andric LastVSRUsedForSpill = VolatileVFReg;
2401d8e91e46SDimitry Andric } else {
2402d8e91e46SDimitry Andric AllSpilledToReg = false;
2403d8e91e46SDimitry Andric }
2404d8e91e46SDimitry Andric }
2405d8e91e46SDimitry Andric return AllSpilledToReg;
2406d8e91e46SDimitry Andric }
2407d8e91e46SDimitry Andric
spillCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,ArrayRef<CalleeSavedInfo> CSI,const TargetRegisterInfo * TRI) const2408cfca06d7SDimitry Andric bool PPCFrameLowering::spillCalleeSavedRegisters(
2409cfca06d7SDimitry Andric MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
2410cfca06d7SDimitry Andric ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
2411522600a2SDimitry Andric
2412522600a2SDimitry Andric MachineFunction *MF = MBB.getParent();
241371d5a254SDimitry Andric const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
2414e6d15924SDimitry Andric PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
2415e6d15924SDimitry Andric bool MustSaveTOC = FI->mustSaveTOC();
2416522600a2SDimitry Andric DebugLoc DL;
2417522600a2SDimitry Andric bool CRSpilled = false;
241859d6cff9SDimitry Andric MachineInstrBuilder CRMIB;
2419344a3780SDimitry Andric BitVector Spilled(TRI->getNumRegs());
2420344a3780SDimitry Andric
2421344a3780SDimitry Andric VSRContainingGPRs.clear();
2422344a3780SDimitry Andric
2423344a3780SDimitry Andric // Map each VSR to GPRs to be spilled with into it. Single VSR can contain one
2424344a3780SDimitry Andric // or two GPRs, so we need table to record information for later save/restore.
2425145449b1SDimitry Andric for (const CalleeSavedInfo &Info : CSI) {
2426344a3780SDimitry Andric if (Info.isSpilledToReg()) {
2427344a3780SDimitry Andric auto &SpilledVSR =
2428344a3780SDimitry Andric VSRContainingGPRs.FindAndConstruct(Info.getDstReg()).second;
2429344a3780SDimitry Andric assert(SpilledVSR.second == 0 &&
2430344a3780SDimitry Andric "Can't spill more than two GPRs into VSR!");
2431344a3780SDimitry Andric if (SpilledVSR.first == 0)
2432344a3780SDimitry Andric SpilledVSR.first = Info.getReg();
2433344a3780SDimitry Andric else
2434344a3780SDimitry Andric SpilledVSR.second = Info.getReg();
2435344a3780SDimitry Andric }
2436145449b1SDimitry Andric }
2437522600a2SDimitry Andric
2438f65dcba8SDimitry Andric for (const CalleeSavedInfo &I : CSI) {
24396f8fc217SDimitry Andric Register Reg = I.getReg();
2440f8af5cf6SDimitry Andric
2441522600a2SDimitry Andric // CR2 through CR4 are the nonvolatile CR fields.
2442522600a2SDimitry Andric bool IsCRField = PPC::CR2 <= Reg && Reg <= PPC::CR4;
2443522600a2SDimitry Andric
2444522600a2SDimitry Andric // Add the callee-saved register as live-in; it's killed at the spill.
2445eb11fae6SDimitry Andric // Do not do this for callee-saved registers that are live-in to the
2446eb11fae6SDimitry Andric // function because they will already be marked live-in and this will be
2447eb11fae6SDimitry Andric // adding it for a second time. It is an error to add the same register
2448eb11fae6SDimitry Andric // to the set more than once.
2449eb11fae6SDimitry Andric const MachineRegisterInfo &MRI = MF->getRegInfo();
2450eb11fae6SDimitry Andric bool IsLiveIn = MRI.isLiveIn(Reg);
2451eb11fae6SDimitry Andric if (!IsLiveIn)
2452522600a2SDimitry Andric MBB.addLiveIn(Reg);
2453522600a2SDimitry Andric
245459d6cff9SDimitry Andric if (CRSpilled && IsCRField) {
245559d6cff9SDimitry Andric CRMIB.addReg(Reg, RegState::ImplicitKill);
245659d6cff9SDimitry Andric continue;
245759d6cff9SDimitry Andric }
245859d6cff9SDimitry Andric
2459e6d15924SDimitry Andric // The actual spill will happen in the prologue.
2460e6d15924SDimitry Andric if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)
2461e6d15924SDimitry Andric continue;
2462e6d15924SDimitry Andric
2463522600a2SDimitry Andric // Insert the spill to the stack frame.
2464522600a2SDimitry Andric if (IsCRField) {
246559d6cff9SDimitry Andric PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
2466cfca06d7SDimitry Andric if (!Subtarget.is32BitELFABI()) {
246759d6cff9SDimitry Andric // The actual spill will happen at the start of the prologue.
246859d6cff9SDimitry Andric FuncInfo->addMustSaveCR(Reg);
2469522600a2SDimitry Andric } else {
247059d6cff9SDimitry Andric CRSpilled = true;
247159d6cff9SDimitry Andric FuncInfo->setSpillsCR();
247259d6cff9SDimitry Andric
2473522600a2SDimitry Andric // 32-bit: FP-relative. Note that we made sure CR2-CR4 all have
2474522600a2SDimitry Andric // the same frame index in PPCRegisterInfo::hasReservedSpillSlot.
247559d6cff9SDimitry Andric CRMIB = BuildMI(*MF, DL, TII.get(PPC::MFCR), PPC::R12)
247659d6cff9SDimitry Andric .addReg(Reg, RegState::ImplicitKill);
247759d6cff9SDimitry Andric
247859d6cff9SDimitry Andric MBB.insert(MI, CRMIB);
2479522600a2SDimitry Andric MBB.insert(MI, addFrameReference(BuildMI(*MF, DL, TII.get(PPC::STW))
2480522600a2SDimitry Andric .addReg(PPC::R12,
2481522600a2SDimitry Andric getKillRegState(true)),
2482f65dcba8SDimitry Andric I.getFrameIdx()));
2483522600a2SDimitry Andric }
2484522600a2SDimitry Andric } else {
2485f65dcba8SDimitry Andric if (I.isSpilledToReg()) {
2486f65dcba8SDimitry Andric unsigned Dst = I.getDstReg();
2487344a3780SDimitry Andric
2488344a3780SDimitry Andric if (Spilled[Dst])
2489344a3780SDimitry Andric continue;
2490344a3780SDimitry Andric
2491344a3780SDimitry Andric if (VSRContainingGPRs[Dst].second != 0) {
2492344a3780SDimitry Andric assert(Subtarget.hasP9Vector() &&
2493344a3780SDimitry Andric "mtvsrdd is unavailable on pre-P9 targets.");
2494344a3780SDimitry Andric
2495344a3780SDimitry Andric NumPESpillVSR += 2;
2496344a3780SDimitry Andric BuildMI(MBB, MI, DL, TII.get(PPC::MTVSRDD), Dst)
2497344a3780SDimitry Andric .addReg(VSRContainingGPRs[Dst].first, getKillRegState(true))
2498344a3780SDimitry Andric .addReg(VSRContainingGPRs[Dst].second, getKillRegState(true));
2499344a3780SDimitry Andric } else if (VSRContainingGPRs[Dst].second == 0) {
2500344a3780SDimitry Andric assert(Subtarget.hasP8Vector() &&
2501344a3780SDimitry Andric "Can't move GPR to VSR on pre-P8 targets.");
2502344a3780SDimitry Andric
2503344a3780SDimitry Andric ++NumPESpillVSR;
2504344a3780SDimitry Andric BuildMI(MBB, MI, DL, TII.get(PPC::MTVSRD),
2505344a3780SDimitry Andric TRI->getSubReg(Dst, PPC::sub_64))
2506344a3780SDimitry Andric .addReg(VSRContainingGPRs[Dst].first, getKillRegState(true));
2507344a3780SDimitry Andric } else {
2508344a3780SDimitry Andric llvm_unreachable("More than two GPRs spilled to a VSR!");
2509344a3780SDimitry Andric }
2510344a3780SDimitry Andric Spilled.set(Dst);
2511d8e91e46SDimitry Andric } else {
2512522600a2SDimitry Andric const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
2513eb11fae6SDimitry Andric // Use !IsLiveIn for the kill flag.
2514eb11fae6SDimitry Andric // We do not want to kill registers that are live in this function
2515eb11fae6SDimitry Andric // before their use because they will become undefined registers.
2516cfca06d7SDimitry Andric // Functions without NoUnwind need to preserve the order of elements in
2517cfca06d7SDimitry Andric // saved vector registers.
2518cfca06d7SDimitry Andric if (Subtarget.needsSwapsForVSXMemOps() &&
2519cfca06d7SDimitry Andric !MF->getFunction().hasFnAttribute(Attribute::NoUnwind))
2520cfca06d7SDimitry Andric TII.storeRegToStackSlotNoUpd(MBB, MI, Reg, !IsLiveIn,
2521f65dcba8SDimitry Andric I.getFrameIdx(), RC, TRI);
2522cfca06d7SDimitry Andric else
2523e3b55780SDimitry Andric TII.storeRegToStackSlot(MBB, MI, Reg, !IsLiveIn, I.getFrameIdx(), RC,
2524e3b55780SDimitry Andric TRI, Register());
2525522600a2SDimitry Andric }
2526522600a2SDimitry Andric }
2527d8e91e46SDimitry Andric }
2528522600a2SDimitry Andric return true;
2529522600a2SDimitry Andric }
2530522600a2SDimitry Andric
restoreCRs(bool is31,bool CR2Spilled,bool CR3Spilled,bool CR4Spilled,MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,ArrayRef<CalleeSavedInfo> CSI,unsigned CSIIndex)2531cfca06d7SDimitry Andric static void restoreCRs(bool is31, bool CR2Spilled, bool CR3Spilled,
2532cfca06d7SDimitry Andric bool CR4Spilled, MachineBasicBlock &MBB,
2533cfca06d7SDimitry Andric MachineBasicBlock::iterator MI,
2534cfca06d7SDimitry Andric ArrayRef<CalleeSavedInfo> CSI, unsigned CSIIndex) {
2535522600a2SDimitry Andric
2536522600a2SDimitry Andric MachineFunction *MF = MBB.getParent();
25375a5ac124SDimitry Andric const PPCInstrInfo &TII = *MF->getSubtarget<PPCSubtarget>().getInstrInfo();
2538522600a2SDimitry Andric DebugLoc DL;
2539cfca06d7SDimitry Andric unsigned MoveReg = PPC::R12;
2540522600a2SDimitry Andric
2541522600a2SDimitry Andric // 32-bit: FP-relative
2542cfca06d7SDimitry Andric MBB.insert(MI,
2543cfca06d7SDimitry Andric addFrameReference(BuildMI(*MF, DL, TII.get(PPC::LWZ), MoveReg),
2544522600a2SDimitry Andric CSI[CSIIndex].getFrameIdx()));
2545522600a2SDimitry Andric
2546cfca06d7SDimitry Andric unsigned RestoreOp = PPC::MTOCRF;
2547522600a2SDimitry Andric if (CR2Spilled)
2548522600a2SDimitry Andric MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR2)
25494a16efa3SDimitry Andric .addReg(MoveReg, getKillRegState(!CR3Spilled && !CR4Spilled)));
2550522600a2SDimitry Andric
2551522600a2SDimitry Andric if (CR3Spilled)
2552522600a2SDimitry Andric MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR3)
25534a16efa3SDimitry Andric .addReg(MoveReg, getKillRegState(!CR4Spilled)));
2554522600a2SDimitry Andric
2555522600a2SDimitry Andric if (CR4Spilled)
2556522600a2SDimitry Andric MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR4)
25574a16efa3SDimitry Andric .addReg(MoveReg, getKillRegState(true)));
25584a16efa3SDimitry Andric }
25594a16efa3SDimitry Andric
256001095a5dSDimitry Andric MachineBasicBlock::iterator PPCFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const25614a16efa3SDimitry Andric eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
25624a16efa3SDimitry Andric MachineBasicBlock::iterator I) const {
25635a5ac124SDimitry Andric const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
25644a16efa3SDimitry Andric if (MF.getTarget().Options.GuaranteedTailCallOpt &&
25654a16efa3SDimitry Andric I->getOpcode() == PPC::ADJCALLSTACKUP) {
25664a16efa3SDimitry Andric // Add (actually subtract) back the amount the callee popped on return.
25674a16efa3SDimitry Andric if (int CalleeAmt = I->getOperand(1).getImm()) {
25684a16efa3SDimitry Andric bool is64Bit = Subtarget.isPPC64();
25694a16efa3SDimitry Andric CalleeAmt *= -1;
25704a16efa3SDimitry Andric unsigned StackReg = is64Bit ? PPC::X1 : PPC::R1;
25714a16efa3SDimitry Andric unsigned TmpReg = is64Bit ? PPC::X0 : PPC::R0;
25724a16efa3SDimitry Andric unsigned ADDIInstr = is64Bit ? PPC::ADDI8 : PPC::ADDI;
25734a16efa3SDimitry Andric unsigned ADDInstr = is64Bit ? PPC::ADD8 : PPC::ADD4;
25744a16efa3SDimitry Andric unsigned LISInstr = is64Bit ? PPC::LIS8 : PPC::LIS;
25754a16efa3SDimitry Andric unsigned ORIInstr = is64Bit ? PPC::ORI8 : PPC::ORI;
2576b915e9e0SDimitry Andric const DebugLoc &dl = I->getDebugLoc();
25774a16efa3SDimitry Andric
25784a16efa3SDimitry Andric if (isInt<16>(CalleeAmt)) {
25794a16efa3SDimitry Andric BuildMI(MBB, I, dl, TII.get(ADDIInstr), StackReg)
25804a16efa3SDimitry Andric .addReg(StackReg, RegState::Kill)
25814a16efa3SDimitry Andric .addImm(CalleeAmt);
25824a16efa3SDimitry Andric } else {
25834a16efa3SDimitry Andric MachineBasicBlock::iterator MBBI = I;
25844a16efa3SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(LISInstr), TmpReg)
25854a16efa3SDimitry Andric .addImm(CalleeAmt >> 16);
25864a16efa3SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(ORIInstr), TmpReg)
25874a16efa3SDimitry Andric .addReg(TmpReg, RegState::Kill)
25884a16efa3SDimitry Andric .addImm(CalleeAmt & 0xFFFF);
25894a16efa3SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(ADDInstr), StackReg)
25904a16efa3SDimitry Andric .addReg(StackReg, RegState::Kill)
25914a16efa3SDimitry Andric .addReg(TmpReg);
25924a16efa3SDimitry Andric }
25934a16efa3SDimitry Andric }
25944a16efa3SDimitry Andric }
25954a16efa3SDimitry Andric // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
259601095a5dSDimitry Andric return MBB.erase(I);
2597522600a2SDimitry Andric }
2598522600a2SDimitry Andric
isCalleeSavedCR(unsigned Reg)2599cfca06d7SDimitry Andric static bool isCalleeSavedCR(unsigned Reg) {
2600cfca06d7SDimitry Andric return PPC::CR2 == Reg || Reg == PPC::CR3 || Reg == PPC::CR4;
2601cfca06d7SDimitry Andric }
2602522600a2SDimitry Andric
restoreCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,MutableArrayRef<CalleeSavedInfo> CSI,const TargetRegisterInfo * TRI) const2603cfca06d7SDimitry Andric bool PPCFrameLowering::restoreCalleeSavedRegisters(
2604cfca06d7SDimitry Andric MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
2605cfca06d7SDimitry Andric MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
2606522600a2SDimitry Andric MachineFunction *MF = MBB.getParent();
260771d5a254SDimitry Andric const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
2608e6d15924SDimitry Andric PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
2609e6d15924SDimitry Andric bool MustSaveTOC = FI->mustSaveTOC();
2610522600a2SDimitry Andric bool CR2Spilled = false;
2611522600a2SDimitry Andric bool CR3Spilled = false;
2612522600a2SDimitry Andric bool CR4Spilled = false;
2613522600a2SDimitry Andric unsigned CSIIndex = 0;
2614344a3780SDimitry Andric BitVector Restored(TRI->getNumRegs());
2615522600a2SDimitry Andric
2616522600a2SDimitry Andric // Initialize insertion-point logic; we will be restoring in reverse
2617522600a2SDimitry Andric // order of spill.
2618522600a2SDimitry Andric MachineBasicBlock::iterator I = MI, BeforeI = I;
2619522600a2SDimitry Andric bool AtStart = I == MBB.begin();
2620522600a2SDimitry Andric
2621522600a2SDimitry Andric if (!AtStart)
2622522600a2SDimitry Andric --BeforeI;
2623522600a2SDimitry Andric
2624522600a2SDimitry Andric for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
26256f8fc217SDimitry Andric Register Reg = CSI[i].getReg();
2626522600a2SDimitry Andric
2627e6d15924SDimitry Andric if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)
2628e6d15924SDimitry Andric continue;
2629e6d15924SDimitry Andric
2630cfca06d7SDimitry Andric // Restore of callee saved condition register field is handled during
2631cfca06d7SDimitry Andric // epilogue insertion.
2632cfca06d7SDimitry Andric if (isCalleeSavedCR(Reg) && !Subtarget.is32BitELFABI())
2633cfca06d7SDimitry Andric continue;
2634cfca06d7SDimitry Andric
2635522600a2SDimitry Andric if (Reg == PPC::CR2) {
2636522600a2SDimitry Andric CR2Spilled = true;
2637522600a2SDimitry Andric // The spill slot is associated only with CR2, which is the
2638522600a2SDimitry Andric // first nonvolatile spilled. Save it here.
2639522600a2SDimitry Andric CSIIndex = i;
2640522600a2SDimitry Andric continue;
2641522600a2SDimitry Andric } else if (Reg == PPC::CR3) {
2642522600a2SDimitry Andric CR3Spilled = true;
2643522600a2SDimitry Andric continue;
2644522600a2SDimitry Andric } else if (Reg == PPC::CR4) {
2645522600a2SDimitry Andric CR4Spilled = true;
2646522600a2SDimitry Andric continue;
2647522600a2SDimitry Andric } else {
2648cfca06d7SDimitry Andric // On 32-bit ELF when we first encounter a non-CR register after seeing at
2649522600a2SDimitry Andric // least one CR register, restore all spilled CRs together.
2650cfca06d7SDimitry Andric if (CR2Spilled || CR3Spilled || CR4Spilled) {
265159d6cff9SDimitry Andric bool is31 = needsFP(*MF);
2652cfca06d7SDimitry Andric restoreCRs(is31, CR2Spilled, CR3Spilled, CR4Spilled, MBB, I, CSI,
2653cfca06d7SDimitry Andric CSIIndex);
2654522600a2SDimitry Andric CR2Spilled = CR3Spilled = CR4Spilled = false;
2655522600a2SDimitry Andric }
2656522600a2SDimitry Andric
2657d8e91e46SDimitry Andric if (CSI[i].isSpilledToReg()) {
2658d8e91e46SDimitry Andric DebugLoc DL;
2659344a3780SDimitry Andric unsigned Dst = CSI[i].getDstReg();
2660344a3780SDimitry Andric
2661344a3780SDimitry Andric if (Restored[Dst])
2662344a3780SDimitry Andric continue;
2663344a3780SDimitry Andric
2664344a3780SDimitry Andric if (VSRContainingGPRs[Dst].second != 0) {
2665344a3780SDimitry Andric assert(Subtarget.hasP9Vector());
2666344a3780SDimitry Andric NumPEReloadVSR += 2;
2667344a3780SDimitry Andric BuildMI(MBB, I, DL, TII.get(PPC::MFVSRLD),
2668344a3780SDimitry Andric VSRContainingGPRs[Dst].second)
2669344a3780SDimitry Andric .addReg(Dst);
2670344a3780SDimitry Andric BuildMI(MBB, I, DL, TII.get(PPC::MFVSRD),
2671344a3780SDimitry Andric VSRContainingGPRs[Dst].first)
2672344a3780SDimitry Andric .addReg(TRI->getSubReg(Dst, PPC::sub_64), getKillRegState(true));
2673344a3780SDimitry Andric } else if (VSRContainingGPRs[Dst].second == 0) {
2674344a3780SDimitry Andric assert(Subtarget.hasP8Vector());
2675344a3780SDimitry Andric ++NumPEReloadVSR;
2676344a3780SDimitry Andric BuildMI(MBB, I, DL, TII.get(PPC::MFVSRD),
2677344a3780SDimitry Andric VSRContainingGPRs[Dst].first)
2678344a3780SDimitry Andric .addReg(TRI->getSubReg(Dst, PPC::sub_64), getKillRegState(true));
2679344a3780SDimitry Andric } else {
2680344a3780SDimitry Andric llvm_unreachable("More than two GPRs spilled to a VSR!");
2681344a3780SDimitry Andric }
2682344a3780SDimitry Andric
2683344a3780SDimitry Andric Restored.set(Dst);
2684344a3780SDimitry Andric
2685d8e91e46SDimitry Andric } else {
2686522600a2SDimitry Andric // Default behavior for non-CR saves.
2687522600a2SDimitry Andric const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
2688cfca06d7SDimitry Andric
2689cfca06d7SDimitry Andric // Functions without NoUnwind need to preserve the order of elements in
2690cfca06d7SDimitry Andric // saved vector registers.
2691cfca06d7SDimitry Andric if (Subtarget.needsSwapsForVSXMemOps() &&
2692cfca06d7SDimitry Andric !MF->getFunction().hasFnAttribute(Attribute::NoUnwind))
2693cfca06d7SDimitry Andric TII.loadRegFromStackSlotNoUpd(MBB, I, Reg, CSI[i].getFrameIdx(), RC,
2694cfca06d7SDimitry Andric TRI);
2695cfca06d7SDimitry Andric else
2696e3b55780SDimitry Andric TII.loadRegFromStackSlot(MBB, I, Reg, CSI[i].getFrameIdx(), RC, TRI,
2697e3b55780SDimitry Andric Register());
2698cfca06d7SDimitry Andric
2699522600a2SDimitry Andric assert(I != MBB.begin() &&
2700522600a2SDimitry Andric "loadRegFromStackSlot didn't insert any code!");
2701522600a2SDimitry Andric }
2702d8e91e46SDimitry Andric }
2703522600a2SDimitry Andric
2704522600a2SDimitry Andric // Insert in reverse order.
2705522600a2SDimitry Andric if (AtStart)
2706522600a2SDimitry Andric I = MBB.begin();
2707522600a2SDimitry Andric else {
2708522600a2SDimitry Andric I = BeforeI;
2709522600a2SDimitry Andric ++I;
2710522600a2SDimitry Andric }
2711522600a2SDimitry Andric }
2712522600a2SDimitry Andric
2713522600a2SDimitry Andric // If we haven't yet spilled the CRs, do so now.
271459d6cff9SDimitry Andric if (CR2Spilled || CR3Spilled || CR4Spilled) {
2715cfca06d7SDimitry Andric assert(Subtarget.is32BitELFABI() &&
2716cfca06d7SDimitry Andric "Only set CR[2|3|4]Spilled on 32-bit SVR4.");
271759d6cff9SDimitry Andric bool is31 = needsFP(*MF);
2718cfca06d7SDimitry Andric restoreCRs(is31, CR2Spilled, CR3Spilled, CR4Spilled, MBB, I, CSI, CSIIndex);
271959d6cff9SDimitry Andric }
2720522600a2SDimitry Andric
2721522600a2SDimitry Andric return true;
2722522600a2SDimitry Andric }
2723dd58ef01SDimitry Andric
getTOCSaveOffset() const2724c0981da4SDimitry Andric uint64_t PPCFrameLowering::getTOCSaveOffset() const {
27251d5ae102SDimitry Andric return TOCSaveOffset;
27261d5ae102SDimitry Andric }
27271d5ae102SDimitry Andric
getFramePointerSaveOffset() const2728c0981da4SDimitry Andric uint64_t PPCFrameLowering::getFramePointerSaveOffset() const {
27291d5ae102SDimitry Andric return FramePointerSaveOffset;
27301d5ae102SDimitry Andric }
27311d5ae102SDimitry Andric
getBasePointerSaveOffset() const2732c0981da4SDimitry Andric uint64_t PPCFrameLowering::getBasePointerSaveOffset() const {
27331d5ae102SDimitry Andric return BasePointerSaveOffset;
27341d5ae102SDimitry Andric }
27351d5ae102SDimitry Andric
enableShrinkWrapping(const MachineFunction & MF) const2736dd58ef01SDimitry Andric bool PPCFrameLowering::enableShrinkWrapping(const MachineFunction &MF) const {
2737eb11fae6SDimitry Andric if (MF.getInfo<PPCFunctionInfo>()->shrinkWrapDisabled())
2738eb11fae6SDimitry Andric return false;
2739344a3780SDimitry Andric return !MF.getSubtarget<PPCSubtarget>().is32BitELFABI();
2740dd58ef01SDimitry Andric }
2741b1c73532SDimitry Andric
updateCalleeSaves(const MachineFunction & MF,BitVector & SavedRegs) const2742ac9a064cSDimitry Andric void PPCFrameLowering::updateCalleeSaves(const MachineFunction &MF,
2743ac9a064cSDimitry Andric BitVector &SavedRegs) const {
2744ac9a064cSDimitry Andric // The AIX ABI uses traceback tables for EH which require that if callee-saved
2745ac9a064cSDimitry Andric // register N is used, all registers N-31 must be saved/restored.
2746ac9a064cSDimitry Andric // NOTE: The check for AIX is not actually what is relevant. Traceback tables
2747ac9a064cSDimitry Andric // on Linux have the same requirements. It is just that AIX is the only ABI
2748ac9a064cSDimitry Andric // for which we actually use traceback tables. If another ABI needs to be
2749ac9a064cSDimitry Andric // supported that also uses them, we can add a check such as
2750ac9a064cSDimitry Andric // Subtarget.usesTraceBackTables().
2751ac9a064cSDimitry Andric assert(Subtarget.isAIXABI() &&
2752ac9a064cSDimitry Andric "Function updateCalleeSaves should only be called for AIX.");
2753ac9a064cSDimitry Andric
2754ac9a064cSDimitry Andric // If there are no callee saves then there is nothing to do.
2755ac9a064cSDimitry Andric if (SavedRegs.none())
2756ac9a064cSDimitry Andric return;
2757ac9a064cSDimitry Andric
2758ac9a064cSDimitry Andric const MCPhysReg *CSRegs =
2759ac9a064cSDimitry Andric Subtarget.getRegisterInfo()->getCalleeSavedRegs(&MF);
2760ac9a064cSDimitry Andric MCPhysReg LowestGPR = PPC::R31;
2761ac9a064cSDimitry Andric MCPhysReg LowestG8R = PPC::X31;
2762ac9a064cSDimitry Andric MCPhysReg LowestFPR = PPC::F31;
2763ac9a064cSDimitry Andric MCPhysReg LowestVR = PPC::V31;
2764ac9a064cSDimitry Andric
2765ac9a064cSDimitry Andric // Traverse the CSRs twice so as not to rely on ascending ordering of
2766ac9a064cSDimitry Andric // registers in the array. The first pass finds the lowest numbered
2767ac9a064cSDimitry Andric // register and the second pass marks all higher numbered registers
2768ac9a064cSDimitry Andric // for spilling.
2769ac9a064cSDimitry Andric for (int i = 0; CSRegs[i]; i++) {
2770ac9a064cSDimitry Andric // Get the lowest numbered register for each class that actually needs
2771ac9a064cSDimitry Andric // to be saved.
2772ac9a064cSDimitry Andric MCPhysReg Cand = CSRegs[i];
2773ac9a064cSDimitry Andric if (!SavedRegs.test(Cand))
2774ac9a064cSDimitry Andric continue;
2775ac9a064cSDimitry Andric if (PPC::GPRCRegClass.contains(Cand) && Cand < LowestGPR)
2776ac9a064cSDimitry Andric LowestGPR = Cand;
2777ac9a064cSDimitry Andric else if (PPC::G8RCRegClass.contains(Cand) && Cand < LowestG8R)
2778ac9a064cSDimitry Andric LowestG8R = Cand;
2779ac9a064cSDimitry Andric else if ((PPC::F4RCRegClass.contains(Cand) ||
2780ac9a064cSDimitry Andric PPC::F8RCRegClass.contains(Cand)) &&
2781ac9a064cSDimitry Andric Cand < LowestFPR)
2782ac9a064cSDimitry Andric LowestFPR = Cand;
2783ac9a064cSDimitry Andric else if (PPC::VRRCRegClass.contains(Cand) && Cand < LowestVR)
2784ac9a064cSDimitry Andric LowestVR = Cand;
2785ac9a064cSDimitry Andric }
2786ac9a064cSDimitry Andric
2787ac9a064cSDimitry Andric for (int i = 0; CSRegs[i]; i++) {
2788ac9a064cSDimitry Andric MCPhysReg Cand = CSRegs[i];
2789ac9a064cSDimitry Andric if ((PPC::GPRCRegClass.contains(Cand) && Cand > LowestGPR) ||
2790ac9a064cSDimitry Andric (PPC::G8RCRegClass.contains(Cand) && Cand > LowestG8R) ||
2791ac9a064cSDimitry Andric ((PPC::F4RCRegClass.contains(Cand) ||
2792ac9a064cSDimitry Andric PPC::F8RCRegClass.contains(Cand)) &&
2793ac9a064cSDimitry Andric Cand > LowestFPR) ||
2794ac9a064cSDimitry Andric (PPC::VRRCRegClass.contains(Cand) && Cand > LowestVR))
2795ac9a064cSDimitry Andric SavedRegs.set(Cand);
2796ac9a064cSDimitry Andric }
2797ac9a064cSDimitry Andric }
2798ac9a064cSDimitry Andric
getStackThreshold() const2799b1c73532SDimitry Andric uint64_t PPCFrameLowering::getStackThreshold() const {
2800b1c73532SDimitry Andric // On PPC64, we use `stux r1, r1, <scratch_reg>` to extend the stack;
2801b1c73532SDimitry Andric // use `add r1, r1, <scratch_reg>` to release the stack frame.
2802b1c73532SDimitry Andric // Scratch register contains a signed 64-bit number, which is negative
2803b1c73532SDimitry Andric // when extending the stack and is positive when releasing the stack frame.
2804b1c73532SDimitry Andric // To make `stux` and `add` paired, the absolute value of the number contained
2805b1c73532SDimitry Andric // in the scratch register should be the same. Thus the maximum stack size
2806b1c73532SDimitry Andric // is (2^63)-1, i.e., LONG_MAX.
2807b1c73532SDimitry Andric if (Subtarget.isPPC64())
2808b1c73532SDimitry Andric return LONG_MAX;
2809b1c73532SDimitry Andric
2810b1c73532SDimitry Andric return TargetFrameLowering::getStackThreshold();
2811b1c73532SDimitry Andric }
2812