xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp (revision 62987288060ff68c817b7056815aa9fb8ba8ecd7)
10b57cec5SDimitry Andric //===-- PPCFrameLowering.cpp - PPC Frame Information ----------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains the PPC implementation of TargetFrameLowering class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "PPCFrameLowering.h"
1481ad6265SDimitry Andric #include "MCTargetDesc/PPCPredicates.h"
150b57cec5SDimitry Andric #include "PPCInstrBuilder.h"
160b57cec5SDimitry Andric #include "PPCInstrInfo.h"
170b57cec5SDimitry Andric #include "PPCMachineFunctionInfo.h"
180b57cec5SDimitry Andric #include "PPCSubtarget.h"
190b57cec5SDimitry Andric #include "PPCTargetMachine.h"
200b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
2181ad6265SDimitry Andric #include "llvm/CodeGen/LivePhysRegs.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
260b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/RegisterScavenging.h"
280b57cec5SDimitry Andric #include "llvm/IR/Function.h"
290b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h"
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric using namespace llvm;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric #define DEBUG_TYPE "framelowering"
340b57cec5SDimitry Andric STATISTIC(NumPESpillVSR, "Number of spills to vector in prologue");
350b57cec5SDimitry Andric STATISTIC(NumPEReloadVSR, "Number of reloads from vector in epilogue");
365ffd83dbSDimitry Andric STATISTIC(NumPrologProbed, "Number of prologues probed");
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric static cl::opt<bool>
390b57cec5SDimitry Andric EnablePEVectorSpills("ppc-enable-pe-vector-spills",
400b57cec5SDimitry Andric                      cl::desc("Enable spills in prologue to vector registers."),
410b57cec5SDimitry Andric                      cl::init(false), cl::Hidden);
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric static unsigned computeReturnSaveOffset(const PPCSubtarget &STI) {
445ffd83dbSDimitry Andric   if (STI.isAIXABI())
450b57cec5SDimitry Andric     return STI.isPPC64() ? 16 : 8;
460b57cec5SDimitry Andric   // SVR4 ABI:
470b57cec5SDimitry Andric   return STI.isPPC64() ? 16 : 4;
480b57cec5SDimitry Andric }
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric static unsigned computeTOCSaveOffset(const PPCSubtarget &STI) {
518bcb0991SDimitry Andric   if (STI.isAIXABI())
528bcb0991SDimitry Andric     return STI.isPPC64() ? 40 : 20;
530b57cec5SDimitry Andric   return STI.isELFv2ABI() ? 24 : 40;
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric static unsigned computeFramePointerSaveOffset(const PPCSubtarget &STI) {
575ffd83dbSDimitry Andric   // First slot in the general register save area.
580b57cec5SDimitry Andric   return STI.isPPC64() ? -8U : -4U;
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric static unsigned computeLinkageSize(const PPCSubtarget &STI) {
625ffd83dbSDimitry Andric   if (STI.isAIXABI() || STI.isPPC64())
630b57cec5SDimitry Andric     return (STI.isELFv2ABI() ? 4 : 6) * (STI.isPPC64() ? 8 : 4);
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   // 32-bit SVR4 ABI:
660b57cec5SDimitry Andric   return 8;
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric static unsigned computeBasePointerSaveOffset(const PPCSubtarget &STI) {
705ffd83dbSDimitry Andric   // Third slot in the general purpose register save area.
715ffd83dbSDimitry Andric   if (STI.is32BitELFABI() && STI.getTargetMachine().isPositionIndependent())
725ffd83dbSDimitry Andric     return -12U;
730b57cec5SDimitry Andric 
745ffd83dbSDimitry Andric   // Second slot in the general purpose register save area.
755ffd83dbSDimitry Andric   return STI.isPPC64() ? -16U : -8U;
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric 
785ffd83dbSDimitry Andric static unsigned computeCRSaveOffset(const PPCSubtarget &STI) {
795ffd83dbSDimitry Andric   return (STI.isAIXABI() && !STI.isPPC64()) ? 4 : 8;
808bcb0991SDimitry Andric }
818bcb0991SDimitry Andric 
820b57cec5SDimitry Andric PPCFrameLowering::PPCFrameLowering(const PPCSubtarget &STI)
830b57cec5SDimitry Andric     : TargetFrameLowering(TargetFrameLowering::StackGrowsDown,
840b57cec5SDimitry Andric                           STI.getPlatformStackAlignment(), 0),
850b57cec5SDimitry Andric       Subtarget(STI), ReturnSaveOffset(computeReturnSaveOffset(Subtarget)),
860b57cec5SDimitry Andric       TOCSaveOffset(computeTOCSaveOffset(Subtarget)),
870b57cec5SDimitry Andric       FramePointerSaveOffset(computeFramePointerSaveOffset(Subtarget)),
880b57cec5SDimitry Andric       LinkageSize(computeLinkageSize(Subtarget)),
898bcb0991SDimitry Andric       BasePointerSaveOffset(computeBasePointerSaveOffset(Subtarget)),
905ffd83dbSDimitry Andric       CRSaveOffset(computeCRSaveOffset(Subtarget)) {}
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric // With the SVR4 ABI, callee-saved registers have fixed offsets on the stack.
930b57cec5SDimitry Andric const PPCFrameLowering::SpillSlot *PPCFrameLowering::getCalleeSavedSpillSlots(
940b57cec5SDimitry Andric     unsigned &NumEntries) const {
950b57cec5SDimitry Andric 
965ffd83dbSDimitry Andric // Floating-point register save area offsets.
975ffd83dbSDimitry Andric #define CALLEE_SAVED_FPRS \
985ffd83dbSDimitry Andric       {PPC::F31, -8},     \
995ffd83dbSDimitry Andric       {PPC::F30, -16},    \
1005ffd83dbSDimitry Andric       {PPC::F29, -24},    \
1015ffd83dbSDimitry Andric       {PPC::F28, -32},    \
1025ffd83dbSDimitry Andric       {PPC::F27, -40},    \
1035ffd83dbSDimitry Andric       {PPC::F26, -48},    \
1045ffd83dbSDimitry Andric       {PPC::F25, -56},    \
1055ffd83dbSDimitry Andric       {PPC::F24, -64},    \
1065ffd83dbSDimitry Andric       {PPC::F23, -72},    \
1075ffd83dbSDimitry Andric       {PPC::F22, -80},    \
1085ffd83dbSDimitry Andric       {PPC::F21, -88},    \
1095ffd83dbSDimitry Andric       {PPC::F20, -96},    \
1105ffd83dbSDimitry Andric       {PPC::F19, -104},   \
1115ffd83dbSDimitry Andric       {PPC::F18, -112},   \
1125ffd83dbSDimitry Andric       {PPC::F17, -120},   \
1135ffd83dbSDimitry Andric       {PPC::F16, -128},   \
1145ffd83dbSDimitry Andric       {PPC::F15, -136},   \
1155ffd83dbSDimitry Andric       {PPC::F14, -144}
1165ffd83dbSDimitry Andric 
1175ffd83dbSDimitry Andric // 32-bit general purpose register save area offsets shared by ELF and
1185ffd83dbSDimitry Andric // AIX. AIX has an extra CSR with r13.
1195ffd83dbSDimitry Andric #define CALLEE_SAVED_GPRS32 \
1205ffd83dbSDimitry Andric       {PPC::R31, -4},       \
1215ffd83dbSDimitry Andric       {PPC::R30, -8},       \
1225ffd83dbSDimitry Andric       {PPC::R29, -12},      \
1235ffd83dbSDimitry Andric       {PPC::R28, -16},      \
1245ffd83dbSDimitry Andric       {PPC::R27, -20},      \
1255ffd83dbSDimitry Andric       {PPC::R26, -24},      \
1265ffd83dbSDimitry Andric       {PPC::R25, -28},      \
1275ffd83dbSDimitry Andric       {PPC::R24, -32},      \
1285ffd83dbSDimitry Andric       {PPC::R23, -36},      \
1295ffd83dbSDimitry Andric       {PPC::R22, -40},      \
1305ffd83dbSDimitry Andric       {PPC::R21, -44},      \
1315ffd83dbSDimitry Andric       {PPC::R20, -48},      \
1325ffd83dbSDimitry Andric       {PPC::R19, -52},      \
1335ffd83dbSDimitry Andric       {PPC::R18, -56},      \
1345ffd83dbSDimitry Andric       {PPC::R17, -60},      \
1355ffd83dbSDimitry Andric       {PPC::R16, -64},      \
1365ffd83dbSDimitry Andric       {PPC::R15, -68},      \
1375ffd83dbSDimitry Andric       {PPC::R14, -72}
1385ffd83dbSDimitry Andric 
1395ffd83dbSDimitry Andric // 64-bit general purpose register save area offsets.
1405ffd83dbSDimitry Andric #define CALLEE_SAVED_GPRS64 \
1415ffd83dbSDimitry Andric       {PPC::X31, -8},       \
1425ffd83dbSDimitry Andric       {PPC::X30, -16},      \
1435ffd83dbSDimitry Andric       {PPC::X29, -24},      \
1445ffd83dbSDimitry Andric       {PPC::X28, -32},      \
1455ffd83dbSDimitry Andric       {PPC::X27, -40},      \
1465ffd83dbSDimitry Andric       {PPC::X26, -48},      \
1475ffd83dbSDimitry Andric       {PPC::X25, -56},      \
1485ffd83dbSDimitry Andric       {PPC::X24, -64},      \
1495ffd83dbSDimitry Andric       {PPC::X23, -72},      \
1505ffd83dbSDimitry Andric       {PPC::X22, -80},      \
1515ffd83dbSDimitry Andric       {PPC::X21, -88},      \
1525ffd83dbSDimitry Andric       {PPC::X20, -96},      \
1535ffd83dbSDimitry Andric       {PPC::X19, -104},     \
1545ffd83dbSDimitry Andric       {PPC::X18, -112},     \
1555ffd83dbSDimitry Andric       {PPC::X17, -120},     \
1565ffd83dbSDimitry Andric       {PPC::X16, -128},     \
1575ffd83dbSDimitry Andric       {PPC::X15, -136},     \
1585ffd83dbSDimitry Andric       {PPC::X14, -144}
1595ffd83dbSDimitry Andric 
1605ffd83dbSDimitry Andric // Vector register save area offsets.
1615ffd83dbSDimitry Andric #define CALLEE_SAVED_VRS \
1625ffd83dbSDimitry Andric       {PPC::V31, -16},   \
1635ffd83dbSDimitry Andric       {PPC::V30, -32},   \
1645ffd83dbSDimitry Andric       {PPC::V29, -48},   \
1655ffd83dbSDimitry Andric       {PPC::V28, -64},   \
1665ffd83dbSDimitry Andric       {PPC::V27, -80},   \
1675ffd83dbSDimitry Andric       {PPC::V26, -96},   \
1685ffd83dbSDimitry Andric       {PPC::V25, -112},  \
1695ffd83dbSDimitry Andric       {PPC::V24, -128},  \
1705ffd83dbSDimitry Andric       {PPC::V23, -144},  \
1715ffd83dbSDimitry Andric       {PPC::V22, -160},  \
1725ffd83dbSDimitry Andric       {PPC::V21, -176},  \
1735ffd83dbSDimitry Andric       {PPC::V20, -192}
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   // Note that the offsets here overlap, but this is fixed up in
1760b57cec5SDimitry Andric   // processFunctionBeforeFrameFinalized.
1770b57cec5SDimitry Andric 
1785ffd83dbSDimitry Andric   static const SpillSlot ELFOffsets32[] = {
1795ffd83dbSDimitry Andric       CALLEE_SAVED_FPRS,
1805ffd83dbSDimitry Andric       CALLEE_SAVED_GPRS32,
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric       // CR save area offset.  We map each of the nonvolatile CR fields
1830b57cec5SDimitry Andric       // to the slot for CR2, which is the first of the nonvolatile CR
1840b57cec5SDimitry Andric       // fields to be assigned, so that we only allocate one save slot.
1850b57cec5SDimitry Andric       // See PPCRegisterInfo::hasReservedSpillSlot() for more information.
1860b57cec5SDimitry Andric       {PPC::CR2, -4},
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric       // VRSAVE save area offset.
1890b57cec5SDimitry Andric       {PPC::VRSAVE, -4},
1900b57cec5SDimitry Andric 
1915ffd83dbSDimitry Andric       CALLEE_SAVED_VRS,
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric       // SPE register save area (overlaps Vector save area).
1940b57cec5SDimitry Andric       {PPC::S31, -8},
1950b57cec5SDimitry Andric       {PPC::S30, -16},
1960b57cec5SDimitry Andric       {PPC::S29, -24},
1970b57cec5SDimitry Andric       {PPC::S28, -32},
1980b57cec5SDimitry Andric       {PPC::S27, -40},
1990b57cec5SDimitry Andric       {PPC::S26, -48},
2000b57cec5SDimitry Andric       {PPC::S25, -56},
2010b57cec5SDimitry Andric       {PPC::S24, -64},
2020b57cec5SDimitry Andric       {PPC::S23, -72},
2030b57cec5SDimitry Andric       {PPC::S22, -80},
2040b57cec5SDimitry Andric       {PPC::S21, -88},
2050b57cec5SDimitry Andric       {PPC::S20, -96},
2060b57cec5SDimitry Andric       {PPC::S19, -104},
2070b57cec5SDimitry Andric       {PPC::S18, -112},
2080b57cec5SDimitry Andric       {PPC::S17, -120},
2090b57cec5SDimitry Andric       {PPC::S16, -128},
2100b57cec5SDimitry Andric       {PPC::S15, -136},
2110b57cec5SDimitry Andric       {PPC::S14, -144}};
2120b57cec5SDimitry Andric 
2135ffd83dbSDimitry Andric   static const SpillSlot ELFOffsets64[] = {
2145ffd83dbSDimitry Andric       CALLEE_SAVED_FPRS,
2155ffd83dbSDimitry Andric       CALLEE_SAVED_GPRS64,
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric       // VRSAVE save area offset.
2180b57cec5SDimitry Andric       {PPC::VRSAVE, -4},
2195ffd83dbSDimitry Andric       CALLEE_SAVED_VRS
2205ffd83dbSDimitry Andric   };
2210b57cec5SDimitry Andric 
222e8d8bef9SDimitry Andric   static const SpillSlot AIXOffsets32[] = {CALLEE_SAVED_FPRS,
2235ffd83dbSDimitry Andric                                            CALLEE_SAVED_GPRS32,
2245ffd83dbSDimitry Andric                                            // Add AIX's extra CSR.
2255ffd83dbSDimitry Andric                                            {PPC::R13, -76},
226e8d8bef9SDimitry Andric                                            CALLEE_SAVED_VRS};
2275ffd83dbSDimitry Andric 
2285ffd83dbSDimitry Andric   static const SpillSlot AIXOffsets64[] = {
229e8d8bef9SDimitry Andric       CALLEE_SAVED_FPRS, CALLEE_SAVED_GPRS64, CALLEE_SAVED_VRS};
2305ffd83dbSDimitry Andric 
2315ffd83dbSDimitry Andric   if (Subtarget.is64BitELFABI()) {
232bdd1243dSDimitry Andric     NumEntries = std::size(ELFOffsets64);
2335ffd83dbSDimitry Andric     return ELFOffsets64;
2345ffd83dbSDimitry Andric   }
2355ffd83dbSDimitry Andric 
2365ffd83dbSDimitry Andric   if (Subtarget.is32BitELFABI()) {
237bdd1243dSDimitry Andric     NumEntries = std::size(ELFOffsets32);
2385ffd83dbSDimitry Andric     return ELFOffsets32;
2395ffd83dbSDimitry Andric   }
2405ffd83dbSDimitry Andric 
2415ffd83dbSDimitry Andric   assert(Subtarget.isAIXABI() && "Unexpected ABI.");
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric   if (Subtarget.isPPC64()) {
244bdd1243dSDimitry Andric     NumEntries = std::size(AIXOffsets64);
2455ffd83dbSDimitry Andric     return AIXOffsets64;
2460b57cec5SDimitry Andric   }
2475ffd83dbSDimitry Andric 
248bdd1243dSDimitry Andric   NumEntries = std::size(AIXOffsets32);
2495ffd83dbSDimitry Andric   return AIXOffsets32;
2500b57cec5SDimitry Andric }
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric static bool spillsCR(const MachineFunction &MF) {
2530b57cec5SDimitry Andric   const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
2540b57cec5SDimitry Andric   return FuncInfo->isCRSpilled();
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric static bool hasSpills(const MachineFunction &MF) {
2580b57cec5SDimitry Andric   const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
2590b57cec5SDimitry Andric   return FuncInfo->hasSpills();
2600b57cec5SDimitry Andric }
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric static bool hasNonRISpills(const MachineFunction &MF) {
2630b57cec5SDimitry Andric   const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
2640b57cec5SDimitry Andric   return FuncInfo->hasNonRISpills();
2650b57cec5SDimitry Andric }
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric /// MustSaveLR - Return true if this function requires that we save the LR
2680b57cec5SDimitry Andric /// register onto the stack in the prolog and restore it in the epilog of the
2690b57cec5SDimitry Andric /// function.
2700b57cec5SDimitry Andric static bool MustSaveLR(const MachineFunction &MF, unsigned LR) {
2710b57cec5SDimitry Andric   const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>();
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   // We need a save/restore of LR if there is any def of LR (which is
2740b57cec5SDimitry Andric   // defined by calls, including the PIC setup sequence), or if there is
2750b57cec5SDimitry Andric   // some use of the LR stack slot (e.g. for builtin_return_address).
2760b57cec5SDimitry Andric   // (LR comes in 32 and 64 bit versions.)
2770b57cec5SDimitry Andric   MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR);
2780b57cec5SDimitry Andric   return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired();
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric /// determineFrameLayoutAndUpdate - Determine the size of the frame and maximum
2820b57cec5SDimitry Andric /// call frame size. Update the MachineFunction object with the stack size.
283349cc55cSDimitry Andric uint64_t
2840b57cec5SDimitry Andric PPCFrameLowering::determineFrameLayoutAndUpdate(MachineFunction &MF,
2850b57cec5SDimitry Andric                                                 bool UseEstimate) const {
2860b57cec5SDimitry Andric   unsigned NewMaxCallFrameSize = 0;
287349cc55cSDimitry Andric   uint64_t FrameSize = determineFrameLayout(MF, UseEstimate,
2880b57cec5SDimitry Andric                                             &NewMaxCallFrameSize);
2890b57cec5SDimitry Andric   MF.getFrameInfo().setStackSize(FrameSize);
2900b57cec5SDimitry Andric   MF.getFrameInfo().setMaxCallFrameSize(NewMaxCallFrameSize);
2910b57cec5SDimitry Andric   return FrameSize;
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric /// determineFrameLayout - Determine the size of the frame and maximum call
2950b57cec5SDimitry Andric /// frame size.
296349cc55cSDimitry Andric uint64_t
2970b57cec5SDimitry Andric PPCFrameLowering::determineFrameLayout(const MachineFunction &MF,
2980b57cec5SDimitry Andric                                        bool UseEstimate,
2990b57cec5SDimitry Andric                                        unsigned *NewMaxCallFrameSize) const {
3000b57cec5SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
3010b57cec5SDimitry Andric   const PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric   // Get the number of bytes to allocate from the FrameInfo
304349cc55cSDimitry Andric   uint64_t FrameSize =
3050b57cec5SDimitry Andric     UseEstimate ? MFI.estimateStackSize(MF) : MFI.getStackSize();
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric   // Get stack alignments. The frame must be aligned to the greatest of these:
3085ffd83dbSDimitry Andric   Align TargetAlign = getStackAlign(); // alignment required per the ABI
3095ffd83dbSDimitry Andric   Align MaxAlign = MFI.getMaxAlign();  // algmt required by data in frame
3105ffd83dbSDimitry Andric   Align Alignment = std::max(TargetAlign, MaxAlign);
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric   const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   unsigned LR = RegInfo->getRARegister();
3150b57cec5SDimitry Andric   bool DisableRedZone = MF.getFunction().hasFnAttribute(Attribute::NoRedZone);
3160b57cec5SDimitry Andric   bool CanUseRedZone = !MFI.hasVarSizedObjects() && // No dynamic alloca.
3170b57cec5SDimitry Andric                        !MFI.adjustsStack() &&       // No calls.
3180b57cec5SDimitry Andric                        !MustSaveLR(MF, LR) &&       // No need to save LR.
3190b57cec5SDimitry Andric                        !FI->mustSaveTOC() &&        // No need to save TOC.
3200fca6ea1SDimitry Andric                        !RegInfo->hasBasePointer(MF) && // No special alignment.
3210fca6ea1SDimitry Andric                        !MFI.isFrameAddressTaken();
3220b57cec5SDimitry Andric 
323e8d8bef9SDimitry Andric   // Note: for PPC32 SVR4ABI, we can still generate stackless
3240b57cec5SDimitry Andric   // code if all local vars are reg-allocated.
3250b57cec5SDimitry Andric   bool FitsInRedZone = FrameSize <= Subtarget.getRedZoneSize();
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   // Check whether we can skip adjusting the stack pointer (by using red zone)
3280b57cec5SDimitry Andric   if (!DisableRedZone && CanUseRedZone && FitsInRedZone) {
3290b57cec5SDimitry Andric     // No need for frame
3300b57cec5SDimitry Andric     return 0;
3310b57cec5SDimitry Andric   }
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric   // Get the maximum call frame size of all the calls.
3340b57cec5SDimitry Andric   unsigned maxCallFrameSize = MFI.getMaxCallFrameSize();
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric   // Maximum call frame needs to be at least big enough for linkage area.
3370b57cec5SDimitry Andric   unsigned minCallFrameSize = getLinkageSize();
3380b57cec5SDimitry Andric   maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize);
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric   // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
3410b57cec5SDimitry Andric   // that allocations will be aligned.
3420b57cec5SDimitry Andric   if (MFI.hasVarSizedObjects())
3435ffd83dbSDimitry Andric     maxCallFrameSize = alignTo(maxCallFrameSize, Alignment);
3440b57cec5SDimitry Andric 
3450b57cec5SDimitry Andric   // Update the new max call frame size if the caller passes in a valid pointer.
3460b57cec5SDimitry Andric   if (NewMaxCallFrameSize)
3470b57cec5SDimitry Andric     *NewMaxCallFrameSize = maxCallFrameSize;
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric   // Include call frame size in total.
3500b57cec5SDimitry Andric   FrameSize += maxCallFrameSize;
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric   // Make sure the frame is aligned.
3535ffd83dbSDimitry Andric   FrameSize = alignTo(FrameSize, Alignment);
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric   return FrameSize;
3560b57cec5SDimitry Andric }
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric // hasFP - Return true if the specified function actually has a dedicated frame
3590b57cec5SDimitry Andric // pointer register.
3600b57cec5SDimitry Andric bool PPCFrameLowering::hasFP(const MachineFunction &MF) const {
3610b57cec5SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
3620b57cec5SDimitry Andric   // FIXME: This is pretty much broken by design: hasFP() might be called really
3630b57cec5SDimitry Andric   // early, before the stack layout was calculated and thus hasFP() might return
3640b57cec5SDimitry Andric   // true or false here depending on the time of call.
3650b57cec5SDimitry Andric   return (MFI.getStackSize()) && needsFP(MF);
3660b57cec5SDimitry Andric }
3670b57cec5SDimitry Andric 
3680b57cec5SDimitry Andric // needsFP - Return true if the specified function should have a dedicated frame
3690b57cec5SDimitry Andric // pointer register.  This is true if the function has variable sized allocas or
3700b57cec5SDimitry Andric // if frame pointer elimination is disabled.
3710b57cec5SDimitry Andric bool PPCFrameLowering::needsFP(const MachineFunction &MF) const {
3720b57cec5SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
3730b57cec5SDimitry Andric 
3740b57cec5SDimitry Andric   // Naked functions have no stack frame pushed, so we don't have a frame
3750b57cec5SDimitry Andric   // pointer.
3760b57cec5SDimitry Andric   if (MF.getFunction().hasFnAttribute(Attribute::Naked))
3770b57cec5SDimitry Andric     return false;
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric   return MF.getTarget().Options.DisableFramePointerElim(MF) ||
3800b57cec5SDimitry Andric          MFI.hasVarSizedObjects() || MFI.hasStackMap() || MFI.hasPatchPoint() ||
381e8d8bef9SDimitry Andric          MF.exposesReturnsTwice() ||
3820b57cec5SDimitry Andric          (MF.getTarget().Options.GuaranteedTailCallOpt &&
3830b57cec5SDimitry Andric           MF.getInfo<PPCFunctionInfo>()->hasFastCall());
3840b57cec5SDimitry Andric }
3850b57cec5SDimitry Andric 
3860b57cec5SDimitry Andric void PPCFrameLowering::replaceFPWithRealFP(MachineFunction &MF) const {
3870fca6ea1SDimitry Andric   // When there is dynamic alloca in this function, we can not use the frame
3880fca6ea1SDimitry Andric   // pointer X31/R31 for the frameaddress lowering. In this case, only X1/R1
3890fca6ea1SDimitry Andric   // always points to the backchain.
3900fca6ea1SDimitry Andric   bool is31 = needsFP(MF) && !MF.getFrameInfo().hasVarSizedObjects();
3910b57cec5SDimitry Andric   unsigned FPReg  = is31 ? PPC::R31 : PPC::R1;
3920b57cec5SDimitry Andric   unsigned FP8Reg = is31 ? PPC::X31 : PPC::X1;
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric   const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
3950b57cec5SDimitry Andric   bool HasBP = RegInfo->hasBasePointer(MF);
3960b57cec5SDimitry Andric   unsigned BPReg  = HasBP ? (unsigned) RegInfo->getBaseRegister(MF) : FPReg;
3970b57cec5SDimitry Andric   unsigned BP8Reg = HasBP ? (unsigned) PPC::X30 : FP8Reg;
3980b57cec5SDimitry Andric 
3994824e7fdSDimitry Andric   for (MachineBasicBlock &MBB : MF)
4004824e7fdSDimitry Andric     for (MachineBasicBlock::iterator MBBI = MBB.end(); MBBI != MBB.begin();) {
4010b57cec5SDimitry Andric       --MBBI;
40206c3fb27SDimitry Andric       for (MachineOperand &MO : MBBI->operands()) {
4030b57cec5SDimitry Andric         if (!MO.isReg())
4040b57cec5SDimitry Andric           continue;
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric         switch (MO.getReg()) {
4070b57cec5SDimitry Andric         case PPC::FP:
4080b57cec5SDimitry Andric           MO.setReg(FPReg);
4090b57cec5SDimitry Andric           break;
4100b57cec5SDimitry Andric         case PPC::FP8:
4110b57cec5SDimitry Andric           MO.setReg(FP8Reg);
4120b57cec5SDimitry Andric           break;
4130b57cec5SDimitry Andric         case PPC::BP:
4140b57cec5SDimitry Andric           MO.setReg(BPReg);
4150b57cec5SDimitry Andric           break;
4160b57cec5SDimitry Andric         case PPC::BP8:
4170b57cec5SDimitry Andric           MO.setReg(BP8Reg);
4180b57cec5SDimitry Andric           break;
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric         }
4210b57cec5SDimitry Andric       }
4220b57cec5SDimitry Andric     }
4230b57cec5SDimitry Andric }
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric /*  This function will do the following:
4260b57cec5SDimitry Andric     - If MBB is an entry or exit block, set SR1 and SR2 to R0 and R12
4270b57cec5SDimitry Andric       respectively (defaults recommended by the ABI) and return true
4280b57cec5SDimitry Andric     - If MBB is not an entry block, initialize the register scavenger and look
4290b57cec5SDimitry Andric       for available registers.
4300b57cec5SDimitry Andric     - If the defaults (R0/R12) are available, return true
4310b57cec5SDimitry Andric     - If TwoUniqueRegsRequired is set to true, it looks for two unique
4320b57cec5SDimitry Andric       registers. Otherwise, look for a single available register.
4330b57cec5SDimitry Andric       - If the required registers are found, set SR1 and SR2 and return true.
4340b57cec5SDimitry Andric       - If the required registers are not found, set SR2 or both SR1 and SR2 to
4350b57cec5SDimitry Andric         PPC::NoRegister and return false.
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric     Note that if both SR1 and SR2 are valid parameters and TwoUniqueRegsRequired
4380b57cec5SDimitry Andric     is not set, this function will attempt to find two different registers, but
4390b57cec5SDimitry Andric     still return true if only one register is available (and set SR1 == SR2).
4400b57cec5SDimitry Andric */
4410b57cec5SDimitry Andric bool
4420b57cec5SDimitry Andric PPCFrameLowering::findScratchRegister(MachineBasicBlock *MBB,
4430b57cec5SDimitry Andric                                       bool UseAtEnd,
4440b57cec5SDimitry Andric                                       bool TwoUniqueRegsRequired,
4455ffd83dbSDimitry Andric                                       Register *SR1,
4465ffd83dbSDimitry Andric                                       Register *SR2) const {
4470b57cec5SDimitry Andric   RegScavenger RS;
4485ffd83dbSDimitry Andric   Register R0 =  Subtarget.isPPC64() ? PPC::X0 : PPC::R0;
4495ffd83dbSDimitry Andric   Register R12 = Subtarget.isPPC64() ? PPC::X12 : PPC::R12;
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric   // Set the defaults for the two scratch registers.
4520b57cec5SDimitry Andric   if (SR1)
4530b57cec5SDimitry Andric     *SR1 = R0;
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   if (SR2) {
4560b57cec5SDimitry Andric     assert (SR1 && "Asking for the second scratch register but not the first?");
4570b57cec5SDimitry Andric     *SR2 = R12;
4580b57cec5SDimitry Andric   }
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric   // If MBB is an entry or exit block, use R0 and R12 as the scratch registers.
4610b57cec5SDimitry Andric   if ((UseAtEnd && MBB->isReturnBlock()) ||
4620b57cec5SDimitry Andric       (!UseAtEnd && (&MBB->getParent()->front() == MBB)))
4630b57cec5SDimitry Andric     return true;
4640b57cec5SDimitry Andric 
46506c3fb27SDimitry Andric   if (UseAtEnd) {
46606c3fb27SDimitry Andric     // The scratch register will be used before the first terminator (or at the
46706c3fb27SDimitry Andric     // end of the block if there are no terminators).
4680b57cec5SDimitry Andric     MachineBasicBlock::iterator MBBI = MBB->getFirstTerminator();
46906c3fb27SDimitry Andric     if (MBBI == MBB->begin()) {
47006c3fb27SDimitry Andric       RS.enterBasicBlock(*MBB);
47106c3fb27SDimitry Andric     } else {
47206c3fb27SDimitry Andric       RS.enterBasicBlockEnd(*MBB);
4735f757f3fSDimitry Andric       RS.backward(MBBI);
47406c3fb27SDimitry Andric     }
47506c3fb27SDimitry Andric   } else {
47606c3fb27SDimitry Andric     // The scratch register will be used at the start of the block.
47706c3fb27SDimitry Andric     RS.enterBasicBlock(*MBB);
4780b57cec5SDimitry Andric   }
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric   // If the two registers are available, we're all good.
4810b57cec5SDimitry Andric   // Note that we only return here if both R0 and R12 are available because
4820b57cec5SDimitry Andric   // although the function may not require two unique registers, it may benefit
4830b57cec5SDimitry Andric   // from having two so we should try to provide them.
4840b57cec5SDimitry Andric   if (!RS.isRegUsed(R0) && !RS.isRegUsed(R12))
4850b57cec5SDimitry Andric     return true;
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric   // Get the list of callee-saved registers for the target.
4880b57cec5SDimitry Andric   const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
4890b57cec5SDimitry Andric   const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(MBB->getParent());
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric   // Get all the available registers in the block.
4920b57cec5SDimitry Andric   BitVector BV = RS.getRegsAvailable(Subtarget.isPPC64() ? &PPC::G8RCRegClass :
4930b57cec5SDimitry Andric                                      &PPC::GPRCRegClass);
4940b57cec5SDimitry Andric 
4950b57cec5SDimitry Andric   // We shouldn't use callee-saved registers as scratch registers as they may be
4960b57cec5SDimitry Andric   // available when looking for a candidate block for shrink wrapping but not
4970b57cec5SDimitry Andric   // available when the actual prologue/epilogue is being emitted because they
4980b57cec5SDimitry Andric   // were added as live-in to the prologue block by PrologueEpilogueInserter.
4990b57cec5SDimitry Andric   for (int i = 0; CSRegs[i]; ++i)
5000b57cec5SDimitry Andric     BV.reset(CSRegs[i]);
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric   // Set the first scratch register to the first available one.
5030b57cec5SDimitry Andric   if (SR1) {
5040b57cec5SDimitry Andric     int FirstScratchReg = BV.find_first();
5050b57cec5SDimitry Andric     *SR1 = FirstScratchReg == -1 ? (unsigned)PPC::NoRegister : FirstScratchReg;
5060b57cec5SDimitry Andric   }
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   // If there is another one available, set the second scratch register to that.
5090b57cec5SDimitry Andric   // Otherwise, set it to either PPC::NoRegister if this function requires two
5100b57cec5SDimitry Andric   // or to whatever SR1 is set to if this function doesn't require two.
5110b57cec5SDimitry Andric   if (SR2) {
5120b57cec5SDimitry Andric     int SecondScratchReg = BV.find_next(*SR1);
5130b57cec5SDimitry Andric     if (SecondScratchReg != -1)
5140b57cec5SDimitry Andric       *SR2 = SecondScratchReg;
5150b57cec5SDimitry Andric     else
5165ffd83dbSDimitry Andric       *SR2 = TwoUniqueRegsRequired ? Register() : *SR1;
5170b57cec5SDimitry Andric   }
5180b57cec5SDimitry Andric 
5190b57cec5SDimitry Andric   // Now that we've done our best to provide both registers, double check
5200b57cec5SDimitry Andric   // whether we were unable to provide enough.
5210b57cec5SDimitry Andric   if (BV.count() < (TwoUniqueRegsRequired ? 2U : 1U))
5220b57cec5SDimitry Andric     return false;
5230b57cec5SDimitry Andric 
5240b57cec5SDimitry Andric   return true;
5250b57cec5SDimitry Andric }
5260b57cec5SDimitry Andric 
5270b57cec5SDimitry Andric // We need a scratch register for spilling LR and for spilling CR. By default,
5280b57cec5SDimitry Andric // we use two scratch registers to hide latency. However, if only one scratch
5290b57cec5SDimitry Andric // register is available, we can adjust for that by not overlapping the spill
5300b57cec5SDimitry Andric // code. However, if we need to realign the stack (i.e. have a base pointer)
5310b57cec5SDimitry Andric // and the stack frame is large, we need two scratch registers.
532e8d8bef9SDimitry Andric // Also, stack probe requires two scratch registers, one for old sp, one for
533e8d8bef9SDimitry Andric // large frame and large probe size.
5340b57cec5SDimitry Andric bool
5350b57cec5SDimitry Andric PPCFrameLowering::twoUniqueScratchRegsRequired(MachineBasicBlock *MBB) const {
5360b57cec5SDimitry Andric   const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
5370b57cec5SDimitry Andric   MachineFunction &MF = *(MBB->getParent());
5380b57cec5SDimitry Andric   bool HasBP = RegInfo->hasBasePointer(MF);
5390b57cec5SDimitry Andric   unsigned FrameSize = determineFrameLayout(MF);
5400b57cec5SDimitry Andric   int NegFrameSize = -FrameSize;
5410b57cec5SDimitry Andric   bool IsLargeFrame = !isInt<16>(NegFrameSize);
5420b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
5435ffd83dbSDimitry Andric   Align MaxAlign = MFI.getMaxAlign();
5440b57cec5SDimitry Andric   bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
545e8d8bef9SDimitry Andric   const PPCTargetLowering &TLI = *Subtarget.getTargetLowering();
5460b57cec5SDimitry Andric 
547e8d8bef9SDimitry Andric   return ((IsLargeFrame || !HasRedZone) && HasBP && MaxAlign > 1) ||
548e8d8bef9SDimitry Andric          TLI.hasInlineStackProbe(MF);
5490b57cec5SDimitry Andric }
5500b57cec5SDimitry Andric 
5510b57cec5SDimitry Andric bool PPCFrameLowering::canUseAsPrologue(const MachineBasicBlock &MBB) const {
5520b57cec5SDimitry Andric   MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric   return findScratchRegister(TmpMBB, false,
5550b57cec5SDimitry Andric                              twoUniqueScratchRegsRequired(TmpMBB));
5560b57cec5SDimitry Andric }
5570b57cec5SDimitry Andric 
5580b57cec5SDimitry Andric bool PPCFrameLowering::canUseAsEpilogue(const MachineBasicBlock &MBB) const {
5590b57cec5SDimitry Andric   MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
5600b57cec5SDimitry Andric 
5610b57cec5SDimitry Andric   return findScratchRegister(TmpMBB, true);
5620b57cec5SDimitry Andric }
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric bool PPCFrameLowering::stackUpdateCanBeMoved(MachineFunction &MF) const {
5650b57cec5SDimitry Andric   const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
5660b57cec5SDimitry Andric   PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric   // Abort if there is no register info or function info.
5690b57cec5SDimitry Andric   if (!RegInfo || !FI)
5700b57cec5SDimitry Andric     return false;
5710b57cec5SDimitry Andric 
5720b57cec5SDimitry Andric   // Only move the stack update on ELFv2 ABI and PPC64.
5730b57cec5SDimitry Andric   if (!Subtarget.isELFv2ABI() || !Subtarget.isPPC64())
5740b57cec5SDimitry Andric     return false;
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric   // Check the frame size first and return false if it does not fit the
5770b57cec5SDimitry Andric   // requirements.
5780b57cec5SDimitry Andric   // We need a non-zero frame size as well as a frame that will fit in the red
5790b57cec5SDimitry Andric   // zone. This is because by moving the stack pointer update we are now storing
5800b57cec5SDimitry Andric   // to the red zone until the stack pointer is updated. If we get an interrupt
5810b57cec5SDimitry Andric   // inside the prologue but before the stack update we now have a number of
5820b57cec5SDimitry Andric   // stores to the red zone and those stores must all fit.
5830b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
5840b57cec5SDimitry Andric   unsigned FrameSize = MFI.getStackSize();
5850b57cec5SDimitry Andric   if (!FrameSize || FrameSize > Subtarget.getRedZoneSize())
5860b57cec5SDimitry Andric     return false;
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric   // Frame pointers and base pointers complicate matters so don't do anything
5890b57cec5SDimitry Andric   // if we have them. For example having a frame pointer will sometimes require
5900b57cec5SDimitry Andric   // a copy of r1 into r31 and that makes keeping track of updates to r1 more
591e8d8bef9SDimitry Andric   // difficult. Similar situation exists with setjmp.
592e8d8bef9SDimitry Andric   if (hasFP(MF) || RegInfo->hasBasePointer(MF) || MF.exposesReturnsTwice())
5930b57cec5SDimitry Andric     return false;
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric   // Calls to fast_cc functions use different rules for passing parameters on
5960b57cec5SDimitry Andric   // the stack from the ABI and using PIC base in the function imposes
5970b57cec5SDimitry Andric   // similar restrictions to using the base pointer. It is not generally safe
5980b57cec5SDimitry Andric   // to move the stack pointer update in these situations.
5990b57cec5SDimitry Andric   if (FI->hasFastCall() || FI->usesPICBase())
6000b57cec5SDimitry Andric     return false;
6010b57cec5SDimitry Andric 
6020b57cec5SDimitry Andric   // Finally we can move the stack update if we do not require register
6030b57cec5SDimitry Andric   // scavenging. Register scavenging can introduce more spills and so
6040b57cec5SDimitry Andric   // may make the frame size larger than we have computed.
6050b57cec5SDimitry Andric   return !RegInfo->requiresFrameIndexScavenging(MF);
6060b57cec5SDimitry Andric }
6070b57cec5SDimitry Andric 
6080b57cec5SDimitry Andric void PPCFrameLowering::emitPrologue(MachineFunction &MF,
6090b57cec5SDimitry Andric                                     MachineBasicBlock &MBB) const {
6100b57cec5SDimitry Andric   MachineBasicBlock::iterator MBBI = MBB.begin();
6110b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
6120b57cec5SDimitry Andric   const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
6130b57cec5SDimitry Andric   const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
6145ffd83dbSDimitry Andric   const PPCTargetLowering &TLI = *Subtarget.getTargetLowering();
6150b57cec5SDimitry Andric 
6160fca6ea1SDimitry Andric   const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
6170b57cec5SDimitry Andric   DebugLoc dl;
6185ffd83dbSDimitry Andric   // AIX assembler does not support cfi directives.
6195ffd83dbSDimitry Andric   const bool needsCFI = MF.needsFrameMoves() && !Subtarget.isAIXABI();
6200b57cec5SDimitry Andric 
621bdd1243dSDimitry Andric   const bool HasFastMFLR = Subtarget.hasFastMFLR();
622bdd1243dSDimitry Andric 
6230b57cec5SDimitry Andric   // Get processor type.
6240b57cec5SDimitry Andric   bool isPPC64 = Subtarget.isPPC64();
6250b57cec5SDimitry Andric   // Get the ABI.
6260b57cec5SDimitry Andric   bool isSVR4ABI = Subtarget.isSVR4ABI();
6270b57cec5SDimitry Andric   bool isELFv2ABI = Subtarget.isELFv2ABI();
628e8d8bef9SDimitry Andric   assert((isSVR4ABI || Subtarget.isAIXABI()) && "Unsupported PPC ABI.");
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric   // Work out frame sizes.
631349cc55cSDimitry Andric   uint64_t FrameSize = determineFrameLayoutAndUpdate(MF);
632349cc55cSDimitry Andric   int64_t NegFrameSize = -FrameSize;
63381ad6265SDimitry Andric   if (!isPPC64 && (!isInt<32>(FrameSize) || !isInt<32>(NegFrameSize)))
6340b57cec5SDimitry Andric     llvm_unreachable("Unhandled stack size!");
6350b57cec5SDimitry Andric 
6360b57cec5SDimitry Andric   if (MFI.isFrameAddressTaken())
6370b57cec5SDimitry Andric     replaceFPWithRealFP(MF);
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric   // Check if the link register (LR) must be saved.
6400b57cec5SDimitry Andric   PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
6410b57cec5SDimitry Andric   bool MustSaveLR = FI->mustSaveLR();
6420b57cec5SDimitry Andric   bool MustSaveTOC = FI->mustSaveTOC();
6435ffd83dbSDimitry Andric   const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
6440b57cec5SDimitry Andric   bool MustSaveCR = !MustSaveCRs.empty();
6450b57cec5SDimitry Andric   // Do we have a frame pointer and/or base pointer for this function?
6460b57cec5SDimitry Andric   bool HasFP = hasFP(MF);
6470b57cec5SDimitry Andric   bool HasBP = RegInfo->hasBasePointer(MF);
6480b57cec5SDimitry Andric   bool HasRedZone = isPPC64 || !isSVR4ABI;
649fe6060f1SDimitry Andric   bool HasROPProtect = Subtarget.hasROPProtect();
650fe6060f1SDimitry Andric   bool HasPrivileged = Subtarget.hasPrivileged();
6510b57cec5SDimitry Andric 
6525ffd83dbSDimitry Andric   Register SPReg       = isPPC64 ? PPC::X1  : PPC::R1;
6538bcb0991SDimitry Andric   Register BPReg = RegInfo->getBaseRegister(MF);
6545ffd83dbSDimitry Andric   Register FPReg       = isPPC64 ? PPC::X31 : PPC::R31;
6555ffd83dbSDimitry Andric   Register LRReg       = isPPC64 ? PPC::LR8 : PPC::LR;
6565ffd83dbSDimitry Andric   Register TOCReg      = isPPC64 ? PPC::X2 :  PPC::R2;
6575ffd83dbSDimitry Andric   Register ScratchReg;
6585ffd83dbSDimitry Andric   Register TempReg     = isPPC64 ? PPC::X12 : PPC::R12; // another scratch reg
6590b57cec5SDimitry Andric   //  ...(R12/X12 is volatile in both Darwin & SVR4, & can't be a function arg.)
6600b57cec5SDimitry Andric   const MCInstrDesc& MFLRInst = TII.get(isPPC64 ? PPC::MFLR8
6610b57cec5SDimitry Andric                                                 : PPC::MFLR );
6620b57cec5SDimitry Andric   const MCInstrDesc& StoreInst = TII.get(isPPC64 ? PPC::STD
6630b57cec5SDimitry Andric                                                  : PPC::STW );
6640b57cec5SDimitry Andric   const MCInstrDesc& StoreUpdtInst = TII.get(isPPC64 ? PPC::STDU
6650b57cec5SDimitry Andric                                                      : PPC::STWU );
6660b57cec5SDimitry Andric   const MCInstrDesc& StoreUpdtIdxInst = TII.get(isPPC64 ? PPC::STDUX
6670b57cec5SDimitry Andric                                                         : PPC::STWUX);
6680b57cec5SDimitry Andric   const MCInstrDesc& OrInst = TII.get(isPPC64 ? PPC::OR8
6690b57cec5SDimitry Andric                                               : PPC::OR );
6700b57cec5SDimitry Andric   const MCInstrDesc& SubtractCarryingInst = TII.get(isPPC64 ? PPC::SUBFC8
6710b57cec5SDimitry Andric                                                             : PPC::SUBFC);
6720b57cec5SDimitry Andric   const MCInstrDesc& SubtractImmCarryingInst = TII.get(isPPC64 ? PPC::SUBFIC8
6730b57cec5SDimitry Andric                                                                : PPC::SUBFIC);
6745ffd83dbSDimitry Andric   const MCInstrDesc &MoveFromCondRegInst = TII.get(isPPC64 ? PPC::MFCR8
6755ffd83dbSDimitry Andric                                                            : PPC::MFCR);
6765ffd83dbSDimitry Andric   const MCInstrDesc &StoreWordInst = TII.get(isPPC64 ? PPC::STW8 : PPC::STW);
677fe6060f1SDimitry Andric   const MCInstrDesc &HashST =
67804eeddc0SDimitry Andric       TII.get(isPPC64 ? (HasPrivileged ? PPC::HASHSTP8 : PPC::HASHST8)
67904eeddc0SDimitry Andric                       : (HasPrivileged ? PPC::HASHSTP : PPC::HASHST));
6800b57cec5SDimitry Andric 
6810b57cec5SDimitry Andric   // Regarding this assert: Even though LR is saved in the caller's frame (i.e.,
6820b57cec5SDimitry Andric   // LROffset is positive), that slot is callee-owned. Because PPC32 SVR4 has no
6830b57cec5SDimitry Andric   // Red Zone, an asynchronous event (a form of "callee") could claim a frame &
6840b57cec5SDimitry Andric   // overwrite it, so PPC32 SVR4 must claim at least a minimal frame to save LR.
6850b57cec5SDimitry Andric   assert((isPPC64 || !isSVR4ABI || !(!FrameSize && (MustSaveLR || HasFP))) &&
6860b57cec5SDimitry Andric          "FrameSize must be >0 to save/restore the FP or LR for 32-bit SVR4.");
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   // Using the same bool variable as below to suppress compiler warnings.
6895ffd83dbSDimitry Andric   bool SingleScratchReg = findScratchRegister(
690e8d8bef9SDimitry Andric       &MBB, false, twoUniqueScratchRegsRequired(&MBB), &ScratchReg, &TempReg);
6910b57cec5SDimitry Andric   assert(SingleScratchReg &&
6920b57cec5SDimitry Andric          "Required number of registers not available in this block");
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric   SingleScratchReg = ScratchReg == TempReg;
6950b57cec5SDimitry Andric 
696349cc55cSDimitry Andric   int64_t LROffset = getReturnSaveOffset();
6970b57cec5SDimitry Andric 
698349cc55cSDimitry Andric   int64_t FPOffset = 0;
6990b57cec5SDimitry Andric   if (HasFP) {
7000b57cec5SDimitry Andric     MachineFrameInfo &MFI = MF.getFrameInfo();
7010b57cec5SDimitry Andric     int FPIndex = FI->getFramePointerSaveIndex();
7020b57cec5SDimitry Andric     assert(FPIndex && "No Frame Pointer Save Slot!");
7030b57cec5SDimitry Andric     FPOffset = MFI.getObjectOffset(FPIndex);
7040b57cec5SDimitry Andric   }
7050b57cec5SDimitry Andric 
706349cc55cSDimitry Andric   int64_t BPOffset = 0;
7070b57cec5SDimitry Andric   if (HasBP) {
7080b57cec5SDimitry Andric     MachineFrameInfo &MFI = MF.getFrameInfo();
7090b57cec5SDimitry Andric     int BPIndex = FI->getBasePointerSaveIndex();
7100b57cec5SDimitry Andric     assert(BPIndex && "No Base Pointer Save Slot!");
7110b57cec5SDimitry Andric     BPOffset = MFI.getObjectOffset(BPIndex);
7120b57cec5SDimitry Andric   }
7130b57cec5SDimitry Andric 
714349cc55cSDimitry Andric   int64_t PBPOffset = 0;
7150b57cec5SDimitry Andric   if (FI->usesPICBase()) {
7160b57cec5SDimitry Andric     MachineFrameInfo &MFI = MF.getFrameInfo();
7170b57cec5SDimitry Andric     int PBPIndex = FI->getPICBasePointerSaveIndex();
7180b57cec5SDimitry Andric     assert(PBPIndex && "No PIC Base Pointer Save Slot!");
7190b57cec5SDimitry Andric     PBPOffset = MFI.getObjectOffset(PBPIndex);
7200b57cec5SDimitry Andric   }
7210b57cec5SDimitry Andric 
7220b57cec5SDimitry Andric   // Get stack alignments.
7235ffd83dbSDimitry Andric   Align MaxAlign = MFI.getMaxAlign();
7240b57cec5SDimitry Andric   if (HasBP && MaxAlign > 1)
7255ffd83dbSDimitry Andric     assert(Log2(MaxAlign) < 16 && "Invalid alignment!");
7260b57cec5SDimitry Andric 
7270b57cec5SDimitry Andric   // Frames of 32KB & larger require special handling because they cannot be
7280b57cec5SDimitry Andric   // indexed into with a simple STDU/STWU/STD/STW immediate offset operand.
7290b57cec5SDimitry Andric   bool isLargeFrame = !isInt<16>(NegFrameSize);
7300b57cec5SDimitry Andric 
7310b57cec5SDimitry Andric   // Check if we can move the stack update instruction (stdu) down the prologue
7320b57cec5SDimitry Andric   // past the callee saves. Hopefully this will avoid the situation where the
7330b57cec5SDimitry Andric   // saves are waiting for the update on the store with update to complete.
7340b57cec5SDimitry Andric   MachineBasicBlock::iterator StackUpdateLoc = MBBI;
7350b57cec5SDimitry Andric   bool MovingStackUpdateDown = false;
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric   // Check if we can move the stack update.
7380b57cec5SDimitry Andric   if (stackUpdateCanBeMoved(MF)) {
7390b57cec5SDimitry Andric     const std::vector<CalleeSavedInfo> &Info = MFI.getCalleeSavedInfo();
7400b57cec5SDimitry Andric     for (CalleeSavedInfo CSI : Info) {
741fe6060f1SDimitry Andric       // If the callee saved register is spilled to a register instead of the
742fe6060f1SDimitry Andric       // stack then the spill no longer uses the stack pointer.
743fe6060f1SDimitry Andric       // This can lead to two consequences:
744fe6060f1SDimitry Andric       // 1) We no longer need to update the stack because the function does not
745fe6060f1SDimitry Andric       //    spill any callee saved registers to stack.
746fe6060f1SDimitry Andric       // 2) We have a situation where we still have to update the stack pointer
747fe6060f1SDimitry Andric       //    even though some registers are spilled to other registers. In
748fe6060f1SDimitry Andric       //    this case the current code moves the stack update to an incorrect
749fe6060f1SDimitry Andric       //    position.
750fe6060f1SDimitry Andric       // In either case we should abort moving the stack update operation.
751fe6060f1SDimitry Andric       if (CSI.isSpilledToReg()) {
752fe6060f1SDimitry Andric         StackUpdateLoc = MBBI;
753fe6060f1SDimitry Andric         MovingStackUpdateDown = false;
754fe6060f1SDimitry Andric         break;
755fe6060f1SDimitry Andric       }
756fe6060f1SDimitry Andric 
7570b57cec5SDimitry Andric       int FrIdx = CSI.getFrameIdx();
7580b57cec5SDimitry Andric       // If the frame index is not negative the callee saved info belongs to a
7590b57cec5SDimitry Andric       // stack object that is not a fixed stack object. We ignore non-fixed
7600b57cec5SDimitry Andric       // stack objects because we won't move the stack update pointer past them.
7610b57cec5SDimitry Andric       if (FrIdx >= 0)
7620b57cec5SDimitry Andric         continue;
7630b57cec5SDimitry Andric 
7640b57cec5SDimitry Andric       if (MFI.isFixedObjectIndex(FrIdx) && MFI.getObjectOffset(FrIdx) < 0) {
7650b57cec5SDimitry Andric         StackUpdateLoc++;
7660b57cec5SDimitry Andric         MovingStackUpdateDown = true;
7670b57cec5SDimitry Andric       } else {
7680b57cec5SDimitry Andric         // We need all of the Frame Indices to meet these conditions.
7690b57cec5SDimitry Andric         // If they do not, abort the whole operation.
7700b57cec5SDimitry Andric         StackUpdateLoc = MBBI;
7710b57cec5SDimitry Andric         MovingStackUpdateDown = false;
7720b57cec5SDimitry Andric         break;
7730b57cec5SDimitry Andric       }
7740b57cec5SDimitry Andric     }
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric     // If the operation was not aborted then update the object offset.
7770b57cec5SDimitry Andric     if (MovingStackUpdateDown) {
7780b57cec5SDimitry Andric       for (CalleeSavedInfo CSI : Info) {
7790b57cec5SDimitry Andric         int FrIdx = CSI.getFrameIdx();
7800b57cec5SDimitry Andric         if (FrIdx < 0)
7810b57cec5SDimitry Andric           MFI.setObjectOffset(FrIdx, MFI.getObjectOffset(FrIdx) + NegFrameSize);
7820b57cec5SDimitry Andric       }
7830b57cec5SDimitry Andric     }
7840b57cec5SDimitry Andric   }
7850b57cec5SDimitry Andric 
7865ffd83dbSDimitry Andric   // Where in the prologue we move the CR fields depends on how many scratch
7875ffd83dbSDimitry Andric   // registers we have, and if we need to save the link register or not. This
7885ffd83dbSDimitry Andric   // lambda is to avoid duplicating the logic in 2 places.
7895ffd83dbSDimitry Andric   auto BuildMoveFromCR = [&]() {
7905ffd83dbSDimitry Andric     if (isELFv2ABI && MustSaveCRs.size() == 1) {
7915ffd83dbSDimitry Andric     // In the ELFv2 ABI, we are not required to save all CR fields.
7925ffd83dbSDimitry Andric     // If only one CR field is clobbered, it is more efficient to use
7935ffd83dbSDimitry Andric     // mfocrf to selectively save just that field, because mfocrf has short
7945ffd83dbSDimitry Andric     // latency compares to mfcr.
7955ffd83dbSDimitry Andric       assert(isPPC64 && "V2 ABI is 64-bit only.");
7965ffd83dbSDimitry Andric       MachineInstrBuilder MIB =
7975ffd83dbSDimitry Andric           BuildMI(MBB, MBBI, dl, TII.get(PPC::MFOCRF8), TempReg);
7985ffd83dbSDimitry Andric       MIB.addReg(MustSaveCRs[0], RegState::Kill);
7995ffd83dbSDimitry Andric     } else {
8005ffd83dbSDimitry Andric       MachineInstrBuilder MIB =
8015ffd83dbSDimitry Andric           BuildMI(MBB, MBBI, dl, MoveFromCondRegInst, TempReg);
8025ffd83dbSDimitry Andric       for (unsigned CRfield : MustSaveCRs)
8035ffd83dbSDimitry Andric         MIB.addReg(CRfield, RegState::ImplicitKill);
8045ffd83dbSDimitry Andric     }
8055ffd83dbSDimitry Andric   };
8065ffd83dbSDimitry Andric 
8070b57cec5SDimitry Andric   // If we need to spill the CR and the LR but we don't have two separate
8080b57cec5SDimitry Andric   // registers available, we must spill them one at a time
8090b57cec5SDimitry Andric   if (MustSaveCR && SingleScratchReg && MustSaveLR) {
8105ffd83dbSDimitry Andric     BuildMoveFromCR();
8115ffd83dbSDimitry Andric     BuildMI(MBB, MBBI, dl, StoreWordInst)
8120b57cec5SDimitry Andric         .addReg(TempReg, getKillRegState(true))
8135ffd83dbSDimitry Andric         .addImm(CRSaveOffset)
8140b57cec5SDimitry Andric         .addReg(SPReg);
8150b57cec5SDimitry Andric   }
8160b57cec5SDimitry Andric 
8170b57cec5SDimitry Andric   if (MustSaveLR)
8180b57cec5SDimitry Andric     BuildMI(MBB, MBBI, dl, MFLRInst, ScratchReg);
8190b57cec5SDimitry Andric 
8205ffd83dbSDimitry Andric   if (MustSaveCR && !(SingleScratchReg && MustSaveLR))
8215ffd83dbSDimitry Andric     BuildMoveFromCR();
8220b57cec5SDimitry Andric 
8230b57cec5SDimitry Andric   if (HasRedZone) {
8240b57cec5SDimitry Andric     if (HasFP)
8250b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, StoreInst)
8260b57cec5SDimitry Andric         .addReg(FPReg)
8270b57cec5SDimitry Andric         .addImm(FPOffset)
8280b57cec5SDimitry Andric         .addReg(SPReg);
8290b57cec5SDimitry Andric     if (FI->usesPICBase())
8300b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, StoreInst)
8310b57cec5SDimitry Andric         .addReg(PPC::R30)
8320b57cec5SDimitry Andric         .addImm(PBPOffset)
8330b57cec5SDimitry Andric         .addReg(SPReg);
8340b57cec5SDimitry Andric     if (HasBP)
8350b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, StoreInst)
8360b57cec5SDimitry Andric         .addReg(BPReg)
8370b57cec5SDimitry Andric         .addImm(BPOffset)
8380b57cec5SDimitry Andric         .addReg(SPReg);
8390b57cec5SDimitry Andric   }
8400b57cec5SDimitry Andric 
841fe6060f1SDimitry Andric   // Generate the instruction to store the LR. In the case where ROP protection
842fe6060f1SDimitry Andric   // is required the register holding the LR should not be killed as it will be
843fe6060f1SDimitry Andric   // used by the hash store instruction.
844bdd1243dSDimitry Andric   auto SaveLR = [&](int64_t Offset) {
845bdd1243dSDimitry Andric     assert(MustSaveLR && "LR is not required to be saved!");
8460b57cec5SDimitry Andric     BuildMI(MBB, StackUpdateLoc, dl, StoreInst)
847fe6060f1SDimitry Andric         .addReg(ScratchReg, getKillRegState(!HasROPProtect))
848bdd1243dSDimitry Andric         .addImm(Offset)
8490b57cec5SDimitry Andric         .addReg(SPReg);
8500b57cec5SDimitry Andric 
851fe6060f1SDimitry Andric     // Add the ROP protection Hash Store instruction.
852fe6060f1SDimitry Andric     // NOTE: This is technically a violation of the ABI. The hash can be saved
853fe6060f1SDimitry Andric     // up to 512 bytes into the Protected Zone. This can be outside of the
854fe6060f1SDimitry Andric     // initial 288 byte volatile program storage region in the Protected Zone.
855fe6060f1SDimitry Andric     // However, this restriction will be removed in an upcoming revision of the
856fe6060f1SDimitry Andric     // ABI.
857fe6060f1SDimitry Andric     if (HasROPProtect) {
858fe6060f1SDimitry Andric       const int SaveIndex = FI->getROPProtectionHashSaveIndex();
859349cc55cSDimitry Andric       const int64_t ImmOffset = MFI.getObjectOffset(SaveIndex);
860fe6060f1SDimitry Andric       assert((ImmOffset <= -8 && ImmOffset >= -512) &&
861fe6060f1SDimitry Andric              "ROP hash save offset out of range.");
862fe6060f1SDimitry Andric       assert(((ImmOffset & 0x7) == 0) &&
863fe6060f1SDimitry Andric              "ROP hash save offset must be 8 byte aligned.");
864fe6060f1SDimitry Andric       BuildMI(MBB, StackUpdateLoc, dl, HashST)
865fe6060f1SDimitry Andric           .addReg(ScratchReg, getKillRegState(true))
866fe6060f1SDimitry Andric           .addImm(ImmOffset)
867fe6060f1SDimitry Andric           .addReg(SPReg);
868fe6060f1SDimitry Andric     }
869bdd1243dSDimitry Andric   };
870bdd1243dSDimitry Andric 
871bdd1243dSDimitry Andric   if (MustSaveLR && HasFastMFLR)
872bdd1243dSDimitry Andric       SaveLR(LROffset);
873fe6060f1SDimitry Andric 
8740b57cec5SDimitry Andric   if (MustSaveCR &&
8755ffd83dbSDimitry Andric       !(SingleScratchReg && MustSaveLR)) {
8760b57cec5SDimitry Andric     assert(HasRedZone && "A red zone is always available on PPC64");
8775ffd83dbSDimitry Andric     BuildMI(MBB, MBBI, dl, StoreWordInst)
8780b57cec5SDimitry Andric       .addReg(TempReg, getKillRegState(true))
8795ffd83dbSDimitry Andric       .addImm(CRSaveOffset)
8800b57cec5SDimitry Andric       .addReg(SPReg);
8810b57cec5SDimitry Andric   }
8820b57cec5SDimitry Andric 
8830b57cec5SDimitry Andric   // Skip the rest if this is a leaf function & all spills fit in the Red Zone.
884bdd1243dSDimitry Andric   if (!FrameSize) {
885bdd1243dSDimitry Andric     if (MustSaveLR && !HasFastMFLR)
886bdd1243dSDimitry Andric       SaveLR(LROffset);
8870b57cec5SDimitry Andric     return;
888bdd1243dSDimitry Andric   }
8890b57cec5SDimitry Andric 
8900b57cec5SDimitry Andric   // Adjust stack pointer: r1 += NegFrameSize.
8910b57cec5SDimitry Andric   // If there is a preferred stack alignment, align R1 now
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric   if (HasBP && HasRedZone) {
8940b57cec5SDimitry Andric     // Save a copy of r1 as the base pointer.
8950b57cec5SDimitry Andric     BuildMI(MBB, MBBI, dl, OrInst, BPReg)
8960b57cec5SDimitry Andric       .addReg(SPReg)
8970b57cec5SDimitry Andric       .addReg(SPReg);
8980b57cec5SDimitry Andric   }
8990b57cec5SDimitry Andric 
9000b57cec5SDimitry Andric   // Have we generated a STUX instruction to claim stack frame? If so,
9010b57cec5SDimitry Andric   // the negated frame size will be placed in ScratchReg.
902bdd1243dSDimitry Andric   bool HasSTUX =
903bdd1243dSDimitry Andric       (TLI.hasInlineStackProbe(MF) && FrameSize > TLI.getStackProbeSize(MF)) ||
904bdd1243dSDimitry Andric       (HasBP && MaxAlign > 1) || isLargeFrame;
905bdd1243dSDimitry Andric 
906bdd1243dSDimitry Andric   // If we use STUX to update the stack pointer, we need the two scratch
907bdd1243dSDimitry Andric   // registers TempReg and ScratchReg, we have to save LR here which is stored
908bdd1243dSDimitry Andric   // in ScratchReg.
909bdd1243dSDimitry Andric   // If the offset can not be encoded into the store instruction, we also have
910bdd1243dSDimitry Andric   // to save LR here.
911bdd1243dSDimitry Andric   if (MustSaveLR && !HasFastMFLR &&
912bdd1243dSDimitry Andric       (HasSTUX || !isInt<16>(FrameSize + LROffset)))
913bdd1243dSDimitry Andric     SaveLR(LROffset);
9140b57cec5SDimitry Andric 
9155ffd83dbSDimitry Andric   // If FrameSize <= TLI.getStackProbeSize(MF), as POWER ABI requires backchain
9165ffd83dbSDimitry Andric   // pointer is always stored at SP, we will get a free probe due to an essential
9175ffd83dbSDimitry Andric   // STU(X) instruction.
9185ffd83dbSDimitry Andric   if (TLI.hasInlineStackProbe(MF) && FrameSize > TLI.getStackProbeSize(MF)) {
9195ffd83dbSDimitry Andric     // To be consistent with other targets, a pseudo instruction is emitted and
9205ffd83dbSDimitry Andric     // will be later expanded in `inlineStackProbe`.
9215ffd83dbSDimitry Andric     BuildMI(MBB, MBBI, dl,
9225ffd83dbSDimitry Andric             TII.get(isPPC64 ? PPC::PROBED_STACKALLOC_64
9235ffd83dbSDimitry Andric                             : PPC::PROBED_STACKALLOC_32))
92423408297SDimitry Andric         .addDef(TempReg)
92523408297SDimitry Andric         .addDef(ScratchReg) // ScratchReg stores the old sp.
9265ffd83dbSDimitry Andric         .addImm(NegFrameSize);
9275ffd83dbSDimitry Andric     // FIXME: HasSTUX is only read if HasRedZone is not set, in such case, we
9285ffd83dbSDimitry Andric     // update the ScratchReg to meet the assumption that ScratchReg contains
9295ffd83dbSDimitry Andric     // the NegFrameSize. This solution is rather tricky.
9305ffd83dbSDimitry Andric     if (!HasRedZone) {
9315ffd83dbSDimitry Andric       BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBF), ScratchReg)
93223408297SDimitry Andric           .addReg(ScratchReg)
9335ffd83dbSDimitry Andric           .addReg(SPReg);
9345ffd83dbSDimitry Andric     }
9355ffd83dbSDimitry Andric   } else {
9360b57cec5SDimitry Andric     // This condition must be kept in sync with canUseAsPrologue.
9370b57cec5SDimitry Andric     if (HasBP && MaxAlign > 1) {
9380b57cec5SDimitry Andric       if (isPPC64)
9390b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, TII.get(PPC::RLDICL), ScratchReg)
9400b57cec5SDimitry Andric             .addReg(SPReg)
9410b57cec5SDimitry Andric             .addImm(0)
9425ffd83dbSDimitry Andric             .addImm(64 - Log2(MaxAlign));
9430b57cec5SDimitry Andric       else // PPC32...
9440b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, TII.get(PPC::RLWINM), ScratchReg)
9450b57cec5SDimitry Andric             .addReg(SPReg)
9460b57cec5SDimitry Andric             .addImm(0)
9475ffd83dbSDimitry Andric             .addImm(32 - Log2(MaxAlign))
9480b57cec5SDimitry Andric             .addImm(31);
9490b57cec5SDimitry Andric       if (!isLargeFrame) {
9500b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, SubtractImmCarryingInst, ScratchReg)
9510b57cec5SDimitry Andric             .addReg(ScratchReg, RegState::Kill)
9520b57cec5SDimitry Andric             .addImm(NegFrameSize);
9530b57cec5SDimitry Andric       } else {
9540b57cec5SDimitry Andric         assert(!SingleScratchReg && "Only a single scratch reg available");
95581ad6265SDimitry Andric         TII.materializeImmPostRA(MBB, MBBI, dl, TempReg, NegFrameSize);
9560b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, SubtractCarryingInst, ScratchReg)
9570b57cec5SDimitry Andric             .addReg(ScratchReg, RegState::Kill)
9580b57cec5SDimitry Andric             .addReg(TempReg, RegState::Kill);
9590b57cec5SDimitry Andric       }
9600b57cec5SDimitry Andric 
9610b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, StoreUpdtIdxInst, SPReg)
9620b57cec5SDimitry Andric           .addReg(SPReg, RegState::Kill)
9630b57cec5SDimitry Andric           .addReg(SPReg)
9640b57cec5SDimitry Andric           .addReg(ScratchReg);
9650b57cec5SDimitry Andric     } else if (!isLargeFrame) {
9660b57cec5SDimitry Andric       BuildMI(MBB, StackUpdateLoc, dl, StoreUpdtInst, SPReg)
9670b57cec5SDimitry Andric           .addReg(SPReg)
9680b57cec5SDimitry Andric           .addImm(NegFrameSize)
9690b57cec5SDimitry Andric           .addReg(SPReg);
9700b57cec5SDimitry Andric     } else {
97181ad6265SDimitry Andric       TII.materializeImmPostRA(MBB, MBBI, dl, ScratchReg, NegFrameSize);
9720b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, StoreUpdtIdxInst, SPReg)
9730b57cec5SDimitry Andric           .addReg(SPReg, RegState::Kill)
9740b57cec5SDimitry Andric           .addReg(SPReg)
9750b57cec5SDimitry Andric           .addReg(ScratchReg);
9760b57cec5SDimitry Andric     }
9775ffd83dbSDimitry Andric   }
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric   // Save the TOC register after the stack pointer update if a prologue TOC
9800b57cec5SDimitry Andric   // save is required for the function.
9810b57cec5SDimitry Andric   if (MustSaveTOC) {
9820b57cec5SDimitry Andric     assert(isELFv2ABI && "TOC saves in the prologue only supported on ELFv2");
9830b57cec5SDimitry Andric     BuildMI(MBB, StackUpdateLoc, dl, TII.get(PPC::STD))
9840b57cec5SDimitry Andric       .addReg(TOCReg, getKillRegState(true))
9850b57cec5SDimitry Andric       .addImm(TOCSaveOffset)
9860b57cec5SDimitry Andric       .addReg(SPReg);
9870b57cec5SDimitry Andric   }
9880b57cec5SDimitry Andric 
9890b57cec5SDimitry Andric   if (!HasRedZone) {
9900b57cec5SDimitry Andric     assert(!isPPC64 && "A red zone is always available on PPC64");
9910b57cec5SDimitry Andric     if (HasSTUX) {
9920b57cec5SDimitry Andric       // The negated frame size is in ScratchReg, and the SPReg has been
9930b57cec5SDimitry Andric       // decremented by the frame size: SPReg = old SPReg + ScratchReg.
9940b57cec5SDimitry Andric       // Since FPOffset, PBPOffset, etc. are relative to the beginning of
9950b57cec5SDimitry Andric       // the stack frame (i.e. the old SP), ideally, we would put the old
9960b57cec5SDimitry Andric       // SP into a register and use it as the base for the stores. The
9970b57cec5SDimitry Andric       // problem is that the only available register may be ScratchReg,
9980b57cec5SDimitry Andric       // which could be R0, and R0 cannot be used as a base address.
9990b57cec5SDimitry Andric 
10000b57cec5SDimitry Andric       // First, set ScratchReg to the old SP. This may need to be modified
10010b57cec5SDimitry Andric       // later.
10020b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBF), ScratchReg)
10030b57cec5SDimitry Andric         .addReg(ScratchReg, RegState::Kill)
10040b57cec5SDimitry Andric         .addReg(SPReg);
10050b57cec5SDimitry Andric 
10060b57cec5SDimitry Andric       if (ScratchReg == PPC::R0) {
10070b57cec5SDimitry Andric         // R0 cannot be used as a base register, but it can be used as an
10080b57cec5SDimitry Andric         // index in a store-indexed.
10090b57cec5SDimitry Andric         int LastOffset = 0;
10100b57cec5SDimitry Andric         if (HasFP) {
10110b57cec5SDimitry Andric           // R0 += (FPOffset-LastOffset).
10120b57cec5SDimitry Andric           // Need addic, since addi treats R0 as 0.
10130b57cec5SDimitry Andric           BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), ScratchReg)
10140b57cec5SDimitry Andric             .addReg(ScratchReg)
10150b57cec5SDimitry Andric             .addImm(FPOffset-LastOffset);
10160b57cec5SDimitry Andric           LastOffset = FPOffset;
10170b57cec5SDimitry Andric           // Store FP into *R0.
10180b57cec5SDimitry Andric           BuildMI(MBB, MBBI, dl, TII.get(PPC::STWX))
10190b57cec5SDimitry Andric             .addReg(FPReg, RegState::Kill)  // Save FP.
10200b57cec5SDimitry Andric             .addReg(PPC::ZERO)
10210b57cec5SDimitry Andric             .addReg(ScratchReg);  // This will be the index (R0 is ok here).
10220b57cec5SDimitry Andric         }
10230b57cec5SDimitry Andric         if (FI->usesPICBase()) {
10240b57cec5SDimitry Andric           // R0 += (PBPOffset-LastOffset).
10250b57cec5SDimitry Andric           BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), ScratchReg)
10260b57cec5SDimitry Andric             .addReg(ScratchReg)
10270b57cec5SDimitry Andric             .addImm(PBPOffset-LastOffset);
10280b57cec5SDimitry Andric           LastOffset = PBPOffset;
10290b57cec5SDimitry Andric           BuildMI(MBB, MBBI, dl, TII.get(PPC::STWX))
10300b57cec5SDimitry Andric             .addReg(PPC::R30, RegState::Kill)  // Save PIC base pointer.
10310b57cec5SDimitry Andric             .addReg(PPC::ZERO)
10320b57cec5SDimitry Andric             .addReg(ScratchReg);  // This will be the index (R0 is ok here).
10330b57cec5SDimitry Andric         }
10340b57cec5SDimitry Andric         if (HasBP) {
10350b57cec5SDimitry Andric           // R0 += (BPOffset-LastOffset).
10360b57cec5SDimitry Andric           BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), ScratchReg)
10370b57cec5SDimitry Andric             .addReg(ScratchReg)
10380b57cec5SDimitry Andric             .addImm(BPOffset-LastOffset);
10390b57cec5SDimitry Andric           LastOffset = BPOffset;
10400b57cec5SDimitry Andric           BuildMI(MBB, MBBI, dl, TII.get(PPC::STWX))
10410b57cec5SDimitry Andric             .addReg(BPReg, RegState::Kill)  // Save BP.
10420b57cec5SDimitry Andric             .addReg(PPC::ZERO)
10430b57cec5SDimitry Andric             .addReg(ScratchReg);  // This will be the index (R0 is ok here).
10440b57cec5SDimitry Andric           // BP = R0-LastOffset
10450b57cec5SDimitry Andric           BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), BPReg)
10460b57cec5SDimitry Andric             .addReg(ScratchReg, RegState::Kill)
10470b57cec5SDimitry Andric             .addImm(-LastOffset);
10480b57cec5SDimitry Andric         }
10490b57cec5SDimitry Andric       } else {
10500b57cec5SDimitry Andric         // ScratchReg is not R0, so use it as the base register. It is
10510b57cec5SDimitry Andric         // already set to the old SP, so we can use the offsets directly.
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric         // Now that the stack frame has been allocated, save all the necessary
10540b57cec5SDimitry Andric         // registers using ScratchReg as the base address.
10550b57cec5SDimitry Andric         if (HasFP)
10560b57cec5SDimitry Andric           BuildMI(MBB, MBBI, dl, StoreInst)
10570b57cec5SDimitry Andric             .addReg(FPReg)
10580b57cec5SDimitry Andric             .addImm(FPOffset)
10590b57cec5SDimitry Andric             .addReg(ScratchReg);
10600b57cec5SDimitry Andric         if (FI->usesPICBase())
10610b57cec5SDimitry Andric           BuildMI(MBB, MBBI, dl, StoreInst)
10620b57cec5SDimitry Andric             .addReg(PPC::R30)
10630b57cec5SDimitry Andric             .addImm(PBPOffset)
10640b57cec5SDimitry Andric             .addReg(ScratchReg);
10650b57cec5SDimitry Andric         if (HasBP) {
10660b57cec5SDimitry Andric           BuildMI(MBB, MBBI, dl, StoreInst)
10670b57cec5SDimitry Andric             .addReg(BPReg)
10680b57cec5SDimitry Andric             .addImm(BPOffset)
10690b57cec5SDimitry Andric             .addReg(ScratchReg);
10700b57cec5SDimitry Andric           BuildMI(MBB, MBBI, dl, OrInst, BPReg)
10710b57cec5SDimitry Andric             .addReg(ScratchReg, RegState::Kill)
10720b57cec5SDimitry Andric             .addReg(ScratchReg);
10730b57cec5SDimitry Andric         }
10740b57cec5SDimitry Andric       }
10750b57cec5SDimitry Andric     } else {
10760b57cec5SDimitry Andric       // The frame size is a known 16-bit constant (fitting in the immediate
10770b57cec5SDimitry Andric       // field of STWU). To be here we have to be compiling for PPC32.
10780b57cec5SDimitry Andric       // Since the SPReg has been decreased by FrameSize, add it back to each
10790b57cec5SDimitry Andric       // offset.
10800b57cec5SDimitry Andric       if (HasFP)
10810b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, StoreInst)
10820b57cec5SDimitry Andric           .addReg(FPReg)
10830b57cec5SDimitry Andric           .addImm(FrameSize + FPOffset)
10840b57cec5SDimitry Andric           .addReg(SPReg);
10850b57cec5SDimitry Andric       if (FI->usesPICBase())
10860b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, StoreInst)
10870b57cec5SDimitry Andric           .addReg(PPC::R30)
10880b57cec5SDimitry Andric           .addImm(FrameSize + PBPOffset)
10890b57cec5SDimitry Andric           .addReg(SPReg);
10900b57cec5SDimitry Andric       if (HasBP) {
10910b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, StoreInst)
10920b57cec5SDimitry Andric           .addReg(BPReg)
10930b57cec5SDimitry Andric           .addImm(FrameSize + BPOffset)
10940b57cec5SDimitry Andric           .addReg(SPReg);
10950b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), BPReg)
10960b57cec5SDimitry Andric           .addReg(SPReg)
10970b57cec5SDimitry Andric           .addImm(FrameSize);
10980b57cec5SDimitry Andric       }
10990b57cec5SDimitry Andric     }
11000b57cec5SDimitry Andric   }
11010b57cec5SDimitry Andric 
1102bdd1243dSDimitry Andric   // Save the LR now.
1103bdd1243dSDimitry Andric   if (!HasSTUX && MustSaveLR && !HasFastMFLR && isInt<16>(FrameSize + LROffset))
1104bdd1243dSDimitry Andric     SaveLR(LROffset + FrameSize);
1105bdd1243dSDimitry Andric 
11060b57cec5SDimitry Andric   // Add Call Frame Information for the instructions we generated above.
11070b57cec5SDimitry Andric   if (needsCFI) {
11080b57cec5SDimitry Andric     unsigned CFIIndex;
11090b57cec5SDimitry Andric 
11100b57cec5SDimitry Andric     if (HasBP) {
11110b57cec5SDimitry Andric       // Define CFA in terms of BP. Do this in preference to using FP/SP,
11120b57cec5SDimitry Andric       // because if the stack needed aligning then CFA won't be at a fixed
11130b57cec5SDimitry Andric       // offset from FP/SP.
11140b57cec5SDimitry Andric       unsigned Reg = MRI->getDwarfRegNum(BPReg, true);
11150b57cec5SDimitry Andric       CFIIndex = MF.addFrameInst(
11160b57cec5SDimitry Andric           MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
11170b57cec5SDimitry Andric     } else {
11180b57cec5SDimitry Andric       // Adjust the definition of CFA to account for the change in SP.
11190b57cec5SDimitry Andric       assert(NegFrameSize);
11200b57cec5SDimitry Andric       CFIIndex = MF.addFrameInst(
11215ffd83dbSDimitry Andric           MCCFIInstruction::cfiDefCfaOffset(nullptr, -NegFrameSize));
11220b57cec5SDimitry Andric     }
11230b57cec5SDimitry Andric     BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11240b57cec5SDimitry Andric         .addCFIIndex(CFIIndex);
11250b57cec5SDimitry Andric 
11260b57cec5SDimitry Andric     if (HasFP) {
11270b57cec5SDimitry Andric       // Describe where FP was saved, at a fixed offset from CFA.
11280b57cec5SDimitry Andric       unsigned Reg = MRI->getDwarfRegNum(FPReg, true);
11290b57cec5SDimitry Andric       CFIIndex = MF.addFrameInst(
11300b57cec5SDimitry Andric           MCCFIInstruction::createOffset(nullptr, Reg, FPOffset));
11310b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11320b57cec5SDimitry Andric           .addCFIIndex(CFIIndex);
11330b57cec5SDimitry Andric     }
11340b57cec5SDimitry Andric 
11350b57cec5SDimitry Andric     if (FI->usesPICBase()) {
11360b57cec5SDimitry Andric       // Describe where FP was saved, at a fixed offset from CFA.
11370b57cec5SDimitry Andric       unsigned Reg = MRI->getDwarfRegNum(PPC::R30, true);
11380b57cec5SDimitry Andric       CFIIndex = MF.addFrameInst(
11390b57cec5SDimitry Andric           MCCFIInstruction::createOffset(nullptr, Reg, PBPOffset));
11400b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11410b57cec5SDimitry Andric           .addCFIIndex(CFIIndex);
11420b57cec5SDimitry Andric     }
11430b57cec5SDimitry Andric 
11440b57cec5SDimitry Andric     if (HasBP) {
11450b57cec5SDimitry Andric       // Describe where BP was saved, at a fixed offset from CFA.
11460b57cec5SDimitry Andric       unsigned Reg = MRI->getDwarfRegNum(BPReg, true);
11470b57cec5SDimitry Andric       CFIIndex = MF.addFrameInst(
11480b57cec5SDimitry Andric           MCCFIInstruction::createOffset(nullptr, Reg, BPOffset));
11490b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11500b57cec5SDimitry Andric           .addCFIIndex(CFIIndex);
11510b57cec5SDimitry Andric     }
11520b57cec5SDimitry Andric 
11530b57cec5SDimitry Andric     if (MustSaveLR) {
11540b57cec5SDimitry Andric       // Describe where LR was saved, at a fixed offset from CFA.
11550b57cec5SDimitry Andric       unsigned Reg = MRI->getDwarfRegNum(LRReg, true);
11560b57cec5SDimitry Andric       CFIIndex = MF.addFrameInst(
11570b57cec5SDimitry Andric           MCCFIInstruction::createOffset(nullptr, Reg, LROffset));
11580b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11590b57cec5SDimitry Andric           .addCFIIndex(CFIIndex);
11600b57cec5SDimitry Andric     }
11610b57cec5SDimitry Andric   }
11620b57cec5SDimitry Andric 
11630b57cec5SDimitry Andric   // If there is a frame pointer, copy R1 into R31
11640b57cec5SDimitry Andric   if (HasFP) {
11650b57cec5SDimitry Andric     BuildMI(MBB, MBBI, dl, OrInst, FPReg)
11660b57cec5SDimitry Andric       .addReg(SPReg)
11670b57cec5SDimitry Andric       .addReg(SPReg);
11680b57cec5SDimitry Andric 
11690b57cec5SDimitry Andric     if (!HasBP && needsCFI) {
11700b57cec5SDimitry Andric       // Change the definition of CFA from SP+offset to FP+offset, because SP
11710b57cec5SDimitry Andric       // will change at every alloca.
11720b57cec5SDimitry Andric       unsigned Reg = MRI->getDwarfRegNum(FPReg, true);
11730b57cec5SDimitry Andric       unsigned CFIIndex = MF.addFrameInst(
11740b57cec5SDimitry Andric           MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
11750b57cec5SDimitry Andric 
11760b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11770b57cec5SDimitry Andric           .addCFIIndex(CFIIndex);
11780b57cec5SDimitry Andric     }
11790b57cec5SDimitry Andric   }
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric   if (needsCFI) {
11820b57cec5SDimitry Andric     // Describe where callee saved registers were saved, at fixed offsets from
11830b57cec5SDimitry Andric     // CFA.
11840b57cec5SDimitry Andric     const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
11854824e7fdSDimitry Andric     for (const CalleeSavedInfo &I : CSI) {
118604eeddc0SDimitry Andric       Register Reg = I.getReg();
11870b57cec5SDimitry Andric       if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue;
11880b57cec5SDimitry Andric 
11890b57cec5SDimitry Andric       // This is a bit of a hack: CR2LT, CR2GT, CR2EQ and CR2UN are just
11900b57cec5SDimitry Andric       // subregisters of CR2. We just need to emit a move of CR2.
11910b57cec5SDimitry Andric       if (PPC::CRBITRCRegClass.contains(Reg))
11920b57cec5SDimitry Andric         continue;
11930b57cec5SDimitry Andric 
11940b57cec5SDimitry Andric       if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)
11950b57cec5SDimitry Andric         continue;
11960b57cec5SDimitry Andric 
11970b57cec5SDimitry Andric       // For 64-bit SVR4 when we have spilled CRs, the spill location
11980b57cec5SDimitry Andric       // is SP+8, not a frame-relative slot.
11990b57cec5SDimitry Andric       if (isSVR4ABI && isPPC64 && (PPC::CR2 <= Reg && Reg <= PPC::CR4)) {
12000b57cec5SDimitry Andric         // In the ELFv1 ABI, only CR2 is noted in CFI and stands in for
12010b57cec5SDimitry Andric         // the whole CR word.  In the ELFv2 ABI, every CR that was
12020b57cec5SDimitry Andric         // actually saved gets its own CFI record.
120304eeddc0SDimitry Andric         Register CRReg = isELFv2ABI? Reg : PPC::CR2;
12040b57cec5SDimitry Andric         unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
12055ffd83dbSDimitry Andric             nullptr, MRI->getDwarfRegNum(CRReg, true), CRSaveOffset));
12060b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
12070b57cec5SDimitry Andric             .addCFIIndex(CFIIndex);
12080b57cec5SDimitry Andric         continue;
12090b57cec5SDimitry Andric       }
12100b57cec5SDimitry Andric 
12114824e7fdSDimitry Andric       if (I.isSpilledToReg()) {
12124824e7fdSDimitry Andric         unsigned SpilledReg = I.getDstReg();
12130b57cec5SDimitry Andric         unsigned CFIRegister = MF.addFrameInst(MCCFIInstruction::createRegister(
12140b57cec5SDimitry Andric             nullptr, MRI->getDwarfRegNum(Reg, true),
12150b57cec5SDimitry Andric             MRI->getDwarfRegNum(SpilledReg, true)));
12160b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
12170b57cec5SDimitry Andric           .addCFIIndex(CFIRegister);
12180b57cec5SDimitry Andric       } else {
12194824e7fdSDimitry Andric         int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());
12200b57cec5SDimitry Andric         // We have changed the object offset above but we do not want to change
12210b57cec5SDimitry Andric         // the actual offsets in the CFI instruction so we have to undo the
12220b57cec5SDimitry Andric         // offset change here.
12230b57cec5SDimitry Andric         if (MovingStackUpdateDown)
12240b57cec5SDimitry Andric           Offset -= NegFrameSize;
12250b57cec5SDimitry Andric 
12260b57cec5SDimitry Andric         unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
12270b57cec5SDimitry Andric             nullptr, MRI->getDwarfRegNum(Reg, true), Offset));
12280b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
12290b57cec5SDimitry Andric             .addCFIIndex(CFIIndex);
12300b57cec5SDimitry Andric       }
12310b57cec5SDimitry Andric     }
12320b57cec5SDimitry Andric   }
12330b57cec5SDimitry Andric }
12340b57cec5SDimitry Andric 
12355ffd83dbSDimitry Andric void PPCFrameLowering::inlineStackProbe(MachineFunction &MF,
12365ffd83dbSDimitry Andric                                         MachineBasicBlock &PrologMBB) const {
12375ffd83dbSDimitry Andric   bool isPPC64 = Subtarget.isPPC64();
12385ffd83dbSDimitry Andric   const PPCTargetLowering &TLI = *Subtarget.getTargetLowering();
12395ffd83dbSDimitry Andric   const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
12405ffd83dbSDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
12410fca6ea1SDimitry Andric   const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
12425ffd83dbSDimitry Andric   // AIX assembler does not support cfi directives.
12435ffd83dbSDimitry Andric   const bool needsCFI = MF.needsFrameMoves() && !Subtarget.isAIXABI();
12445ffd83dbSDimitry Andric   auto StackAllocMIPos = llvm::find_if(PrologMBB, [](MachineInstr &MI) {
12455ffd83dbSDimitry Andric     int Opc = MI.getOpcode();
12465ffd83dbSDimitry Andric     return Opc == PPC::PROBED_STACKALLOC_64 || Opc == PPC::PROBED_STACKALLOC_32;
12475ffd83dbSDimitry Andric   });
12485ffd83dbSDimitry Andric   if (StackAllocMIPos == PrologMBB.end())
12495ffd83dbSDimitry Andric     return;
12505ffd83dbSDimitry Andric   const BasicBlock *ProbedBB = PrologMBB.getBasicBlock();
1251e8d8bef9SDimitry Andric   MachineBasicBlock *CurrentMBB = &PrologMBB;
12525ffd83dbSDimitry Andric   DebugLoc DL = PrologMBB.findDebugLoc(StackAllocMIPos);
12535ffd83dbSDimitry Andric   MachineInstr &MI = *StackAllocMIPos;
12545ffd83dbSDimitry Andric   int64_t NegFrameSize = MI.getOperand(2).getImm();
1255e8d8bef9SDimitry Andric   unsigned ProbeSize = TLI.getStackProbeSize(MF);
1256e8d8bef9SDimitry Andric   int64_t NegProbeSize = -(int64_t)ProbeSize;
12575ffd83dbSDimitry Andric   assert(isInt<32>(NegProbeSize) && "Unhandled probe size");
12585ffd83dbSDimitry Andric   int64_t NumBlocks = NegFrameSize / NegProbeSize;
12595ffd83dbSDimitry Andric   int64_t NegResidualSize = NegFrameSize % NegProbeSize;
12605ffd83dbSDimitry Andric   Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
12615ffd83dbSDimitry Andric   Register ScratchReg = MI.getOperand(0).getReg();
12625ffd83dbSDimitry Andric   Register FPReg = MI.getOperand(1).getReg();
12635ffd83dbSDimitry Andric   const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
12645ffd83dbSDimitry Andric   bool HasBP = RegInfo->hasBasePointer(MF);
1265e8d8bef9SDimitry Andric   Register BPReg = RegInfo->getBaseRegister(MF);
12665ffd83dbSDimitry Andric   Align MaxAlign = MFI.getMaxAlign();
126723408297SDimitry Andric   bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
12685ffd83dbSDimitry Andric   const MCInstrDesc &CopyInst = TII.get(isPPC64 ? PPC::OR8 : PPC::OR);
12695ffd83dbSDimitry Andric   // Subroutines to generate .cfi_* directives.
12705ffd83dbSDimitry Andric   auto buildDefCFAReg = [&](MachineBasicBlock &MBB,
12715ffd83dbSDimitry Andric                             MachineBasicBlock::iterator MBBI, Register Reg) {
12725ffd83dbSDimitry Andric     unsigned RegNum = MRI->getDwarfRegNum(Reg, true);
12735ffd83dbSDimitry Andric     unsigned CFIIndex = MF.addFrameInst(
12745ffd83dbSDimitry Andric         MCCFIInstruction::createDefCfaRegister(nullptr, RegNum));
12755ffd83dbSDimitry Andric     BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
12765ffd83dbSDimitry Andric         .addCFIIndex(CFIIndex);
12775ffd83dbSDimitry Andric   };
12785ffd83dbSDimitry Andric   auto buildDefCFA = [&](MachineBasicBlock &MBB,
12795ffd83dbSDimitry Andric                          MachineBasicBlock::iterator MBBI, Register Reg,
12805ffd83dbSDimitry Andric                          int Offset) {
12815ffd83dbSDimitry Andric     unsigned RegNum = MRI->getDwarfRegNum(Reg, true);
12825ffd83dbSDimitry Andric     unsigned CFIIndex = MBB.getParent()->addFrameInst(
12835ffd83dbSDimitry Andric         MCCFIInstruction::cfiDefCfa(nullptr, RegNum, Offset));
12845ffd83dbSDimitry Andric     BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
12855ffd83dbSDimitry Andric         .addCFIIndex(CFIIndex);
12865ffd83dbSDimitry Andric   };
12875ffd83dbSDimitry Andric   // Subroutine to determine if we can use the Imm as part of d-form.
12885ffd83dbSDimitry Andric   auto CanUseDForm = [](int64_t Imm) { return isInt<16>(Imm) && Imm % 4 == 0; };
12895ffd83dbSDimitry Andric   // Subroutine to materialize the Imm into TempReg.
12905ffd83dbSDimitry Andric   auto MaterializeImm = [&](MachineBasicBlock &MBB,
12915ffd83dbSDimitry Andric                             MachineBasicBlock::iterator MBBI, int64_t Imm,
12925ffd83dbSDimitry Andric                             Register &TempReg) {
12935ffd83dbSDimitry Andric     assert(isInt<32>(Imm) && "Unhandled imm");
12945ffd83dbSDimitry Andric     if (isInt<16>(Imm))
12955ffd83dbSDimitry Andric       BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::LI8 : PPC::LI), TempReg)
12965ffd83dbSDimitry Andric           .addImm(Imm);
12975ffd83dbSDimitry Andric     else {
12985ffd83dbSDimitry Andric       BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::LIS8 : PPC::LIS), TempReg)
12995ffd83dbSDimitry Andric           .addImm(Imm >> 16);
13005ffd83dbSDimitry Andric       BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::ORI8 : PPC::ORI), TempReg)
13015ffd83dbSDimitry Andric           .addReg(TempReg)
13025ffd83dbSDimitry Andric           .addImm(Imm & 0xFFFF);
13035ffd83dbSDimitry Andric     }
13045ffd83dbSDimitry Andric   };
13055ffd83dbSDimitry Andric   // Subroutine to store frame pointer and decrease stack pointer by probe size.
13065ffd83dbSDimitry Andric   auto allocateAndProbe = [&](MachineBasicBlock &MBB,
13075ffd83dbSDimitry Andric                               MachineBasicBlock::iterator MBBI, int64_t NegSize,
1308e8d8bef9SDimitry Andric                               Register NegSizeReg, bool UseDForm,
1309e8d8bef9SDimitry Andric                               Register StoreReg) {
13105ffd83dbSDimitry Andric     if (UseDForm)
13115ffd83dbSDimitry Andric       BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::STDU : PPC::STWU), SPReg)
1312e8d8bef9SDimitry Andric           .addReg(StoreReg)
13135ffd83dbSDimitry Andric           .addImm(NegSize)
13145ffd83dbSDimitry Andric           .addReg(SPReg);
13155ffd83dbSDimitry Andric     else
13165ffd83dbSDimitry Andric       BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
1317e8d8bef9SDimitry Andric           .addReg(StoreReg)
13185ffd83dbSDimitry Andric           .addReg(SPReg)
13195ffd83dbSDimitry Andric           .addReg(NegSizeReg);
13205ffd83dbSDimitry Andric   };
132123408297SDimitry Andric   // Used to probe stack when realignment is required.
132223408297SDimitry Andric   // Note that, according to ABI's requirement, *sp must always equals the
132323408297SDimitry Andric   // value of back-chain pointer, only st(w|d)u(x) can be used to update sp.
132423408297SDimitry Andric   // Following is pseudo code:
132523408297SDimitry Andric   // final_sp = (sp & align) + negframesize;
132623408297SDimitry Andric   // neg_gap = final_sp - sp;
132723408297SDimitry Andric   // while (neg_gap < negprobesize) {
132823408297SDimitry Andric   //   stdu fp, negprobesize(sp);
132923408297SDimitry Andric   //   neg_gap -= negprobesize;
133023408297SDimitry Andric   // }
133123408297SDimitry Andric   // stdux fp, sp, neg_gap
133223408297SDimitry Andric   //
133323408297SDimitry Andric   // When HasBP & HasRedzone, back-chain pointer is already saved in BPReg
133423408297SDimitry Andric   // before probe code, we don't need to save it, so we get one additional reg
133523408297SDimitry Andric   // that can be used to materialize the probeside if needed to use xform.
133623408297SDimitry Andric   // Otherwise, we can NOT materialize probeside, so we can only use Dform for
133723408297SDimitry Andric   // now.
133823408297SDimitry Andric   //
133923408297SDimitry Andric   // The allocations are:
134023408297SDimitry Andric   // if (HasBP && HasRedzone) {
134123408297SDimitry Andric   //   r0: materialize the probesize if needed so that we can use xform.
134223408297SDimitry Andric   //   r12: `neg_gap`
134323408297SDimitry Andric   // } else {
134423408297SDimitry Andric   //   r0: back-chain pointer
134523408297SDimitry Andric   //   r12: `neg_gap`.
134623408297SDimitry Andric   // }
134723408297SDimitry Andric   auto probeRealignedStack = [&](MachineBasicBlock &MBB,
134823408297SDimitry Andric                                  MachineBasicBlock::iterator MBBI,
134923408297SDimitry Andric                                  Register ScratchReg, Register TempReg) {
135023408297SDimitry Andric     assert(HasBP && "The function is supposed to have base pointer when its "
135123408297SDimitry Andric                     "stack is realigned.");
1352e8d8bef9SDimitry Andric     assert(isPowerOf2_64(ProbeSize) && "Probe size should be power of 2");
135323408297SDimitry Andric 
135423408297SDimitry Andric     // FIXME: We can eliminate this limitation if we get more infomation about
135523408297SDimitry Andric     // which part of redzone are already used. Used redzone can be treated
135623408297SDimitry Andric     // probed. But there might be `holes' in redzone probed, this could
135723408297SDimitry Andric     // complicate the implementation.
135823408297SDimitry Andric     assert(ProbeSize >= Subtarget.getRedZoneSize() &&
135923408297SDimitry Andric            "Probe size should be larger or equal to the size of red-zone so "
136023408297SDimitry Andric            "that red-zone is not clobbered by probing.");
136123408297SDimitry Andric 
136223408297SDimitry Andric     Register &FinalStackPtr = TempReg;
136323408297SDimitry Andric     // FIXME: We only support NegProbeSize materializable by DForm currently.
136423408297SDimitry Andric     // When HasBP && HasRedzone, we can use xform if we have an additional idle
136523408297SDimitry Andric     // register.
136623408297SDimitry Andric     NegProbeSize = std::max(NegProbeSize, -((int64_t)1 << 15));
136723408297SDimitry Andric     assert(isInt<16>(NegProbeSize) &&
136823408297SDimitry Andric            "NegProbeSize should be materializable by DForm");
1369e8d8bef9SDimitry Andric     Register CRReg = PPC::CR0;
137023408297SDimitry Andric     // Layout of output assembly kinda like:
1371e8d8bef9SDimitry Andric     // bb.0:
1372e8d8bef9SDimitry Andric     //   ...
137323408297SDimitry Andric     //   sub $scratchreg, $finalsp, r1
137423408297SDimitry Andric     //   cmpdi $scratchreg, <negprobesize>
137523408297SDimitry Andric     //   bge bb.2
137623408297SDimitry Andric     // bb.1:
137723408297SDimitry Andric     //   stdu <backchain>, <negprobesize>(r1)
137823408297SDimitry Andric     //   sub $scratchreg, $scratchreg, negprobesize
137923408297SDimitry Andric     //   cmpdi $scratchreg, <negprobesize>
138023408297SDimitry Andric     //   blt bb.1
1381e8d8bef9SDimitry Andric     // bb.2:
138223408297SDimitry Andric     //   stdux <backchain>, r1, $scratchreg
1383e8d8bef9SDimitry Andric     MachineFunction::iterator MBBInsertPoint = std::next(MBB.getIterator());
1384e8d8bef9SDimitry Andric     MachineBasicBlock *ProbeLoopBodyMBB = MF.CreateMachineBasicBlock(ProbedBB);
1385e8d8bef9SDimitry Andric     MF.insert(MBBInsertPoint, ProbeLoopBodyMBB);
1386e8d8bef9SDimitry Andric     MachineBasicBlock *ProbeExitMBB = MF.CreateMachineBasicBlock(ProbedBB);
1387e8d8bef9SDimitry Andric     MF.insert(MBBInsertPoint, ProbeExitMBB);
138823408297SDimitry Andric     // bb.2
138923408297SDimitry Andric     {
139023408297SDimitry Andric       Register BackChainPointer = HasRedZone ? BPReg : TempReg;
139123408297SDimitry Andric       allocateAndProbe(*ProbeExitMBB, ProbeExitMBB->end(), 0, ScratchReg, false,
139223408297SDimitry Andric                        BackChainPointer);
139323408297SDimitry Andric       if (HasRedZone)
139423408297SDimitry Andric         // PROBED_STACKALLOC_64 assumes Operand(1) stores the old sp, copy BPReg
139523408297SDimitry Andric         // to TempReg to satisfy it.
139623408297SDimitry Andric         BuildMI(*ProbeExitMBB, ProbeExitMBB->end(), DL, CopyInst, TempReg)
139723408297SDimitry Andric             .addReg(BPReg)
139823408297SDimitry Andric             .addReg(BPReg);
1399e8d8bef9SDimitry Andric       ProbeExitMBB->splice(ProbeExitMBB->end(), &MBB, MBBI, MBB.end());
1400e8d8bef9SDimitry Andric       ProbeExitMBB->transferSuccessorsAndUpdatePHIs(&MBB);
140123408297SDimitry Andric     }
1402e8d8bef9SDimitry Andric     // bb.0
140323408297SDimitry Andric     {
140423408297SDimitry Andric       BuildMI(&MBB, DL, TII.get(isPPC64 ? PPC::SUBF8 : PPC::SUBF), ScratchReg)
1405e8d8bef9SDimitry Andric           .addReg(SPReg)
140623408297SDimitry Andric           .addReg(FinalStackPtr);
140723408297SDimitry Andric       if (!HasRedZone)
140823408297SDimitry Andric         BuildMI(&MBB, DL, CopyInst, TempReg).addReg(SPReg).addReg(SPReg);
140923408297SDimitry Andric       BuildMI(&MBB, DL, TII.get(isPPC64 ? PPC::CMPDI : PPC::CMPWI), CRReg)
141023408297SDimitry Andric           .addReg(ScratchReg)
141123408297SDimitry Andric           .addImm(NegProbeSize);
141223408297SDimitry Andric       BuildMI(&MBB, DL, TII.get(PPC::BCC))
141323408297SDimitry Andric           .addImm(PPC::PRED_GE)
1414e8d8bef9SDimitry Andric           .addReg(CRReg)
1415e8d8bef9SDimitry Andric           .addMBB(ProbeExitMBB);
141623408297SDimitry Andric       MBB.addSuccessor(ProbeLoopBodyMBB);
141723408297SDimitry Andric       MBB.addSuccessor(ProbeExitMBB);
141823408297SDimitry Andric     }
141923408297SDimitry Andric     // bb.1
142023408297SDimitry Andric     {
142123408297SDimitry Andric       Register BackChainPointer = HasRedZone ? BPReg : TempReg;
142223408297SDimitry Andric       allocateAndProbe(*ProbeLoopBodyMBB, ProbeLoopBodyMBB->end(), NegProbeSize,
142323408297SDimitry Andric                        0, true /*UseDForm*/, BackChainPointer);
142423408297SDimitry Andric       BuildMI(ProbeLoopBodyMBB, DL, TII.get(isPPC64 ? PPC::ADDI8 : PPC::ADDI),
142523408297SDimitry Andric               ScratchReg)
142623408297SDimitry Andric           .addReg(ScratchReg)
142723408297SDimitry Andric           .addImm(-NegProbeSize);
142823408297SDimitry Andric       BuildMI(ProbeLoopBodyMBB, DL, TII.get(isPPC64 ? PPC::CMPDI : PPC::CMPWI),
142923408297SDimitry Andric               CRReg)
143023408297SDimitry Andric           .addReg(ScratchReg)
143123408297SDimitry Andric           .addImm(NegProbeSize);
1432e8d8bef9SDimitry Andric       BuildMI(ProbeLoopBodyMBB, DL, TII.get(PPC::BCC))
143323408297SDimitry Andric           .addImm(PPC::PRED_LT)
1434e8d8bef9SDimitry Andric           .addReg(CRReg)
1435e8d8bef9SDimitry Andric           .addMBB(ProbeLoopBodyMBB);
1436e8d8bef9SDimitry Andric       ProbeLoopBodyMBB->addSuccessor(ProbeExitMBB);
1437e8d8bef9SDimitry Andric       ProbeLoopBodyMBB->addSuccessor(ProbeLoopBodyMBB);
143823408297SDimitry Andric     }
1439e8d8bef9SDimitry Andric     // Update liveins.
14400fca6ea1SDimitry Andric     fullyRecomputeLiveIns({ProbeExitMBB, ProbeLoopBodyMBB});
1441e8d8bef9SDimitry Andric     return ProbeExitMBB;
1442e8d8bef9SDimitry Andric   };
1443e8d8bef9SDimitry Andric   // For case HasBP && MaxAlign > 1, we have to realign the SP by performing
144423408297SDimitry Andric   // SP = SP - SP % MaxAlign, thus make the probe more like dynamic probe since
144523408297SDimitry Andric   // the offset subtracted from SP is determined by SP's runtime value.
1446e8d8bef9SDimitry Andric   if (HasBP && MaxAlign > 1) {
144723408297SDimitry Andric     // Calculate final stack pointer.
144823408297SDimitry Andric     if (isPPC64)
144923408297SDimitry Andric       BuildMI(*CurrentMBB, {MI}, DL, TII.get(PPC::RLDICL), ScratchReg)
1450e8d8bef9SDimitry Andric           .addReg(SPReg)
145123408297SDimitry Andric           .addImm(0)
145223408297SDimitry Andric           .addImm(64 - Log2(MaxAlign));
145323408297SDimitry Andric     else
1454e8d8bef9SDimitry Andric       BuildMI(*CurrentMBB, {MI}, DL, TII.get(PPC::RLWINM), ScratchReg)
145523408297SDimitry Andric           .addReg(SPReg)
14565ffd83dbSDimitry Andric           .addImm(0)
14575ffd83dbSDimitry Andric           .addImm(32 - Log2(MaxAlign))
14585ffd83dbSDimitry Andric           .addImm(31);
145923408297SDimitry Andric     BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::SUBF8 : PPC::SUBF),
146023408297SDimitry Andric             FPReg)
1461590d96feSDimitry Andric         .addReg(ScratchReg)
1462590d96feSDimitry Andric         .addReg(SPReg);
146323408297SDimitry Andric     MaterializeImm(*CurrentMBB, {MI}, NegFrameSize, ScratchReg);
146423408297SDimitry Andric     BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::ADD8 : PPC::ADD4),
146523408297SDimitry Andric             FPReg)
146623408297SDimitry Andric         .addReg(ScratchReg)
146723408297SDimitry Andric         .addReg(FPReg);
146823408297SDimitry Andric     CurrentMBB = probeRealignedStack(*CurrentMBB, {MI}, ScratchReg, FPReg);
146923408297SDimitry Andric     if (needsCFI)
147023408297SDimitry Andric       buildDefCFAReg(*CurrentMBB, {MI}, FPReg);
1471e8d8bef9SDimitry Andric   } else {
1472e8d8bef9SDimitry Andric     // Initialize current frame pointer.
1473e8d8bef9SDimitry Andric     BuildMI(*CurrentMBB, {MI}, DL, CopyInst, FPReg).addReg(SPReg).addReg(SPReg);
1474e8d8bef9SDimitry Andric     // Use FPReg to calculate CFA.
1475e8d8bef9SDimitry Andric     if (needsCFI)
1476e8d8bef9SDimitry Andric       buildDefCFA(*CurrentMBB, {MI}, FPReg, 0);
14775ffd83dbSDimitry Andric     // Probe residual part.
14785ffd83dbSDimitry Andric     if (NegResidualSize) {
14795ffd83dbSDimitry Andric       bool ResidualUseDForm = CanUseDForm(NegResidualSize);
14805ffd83dbSDimitry Andric       if (!ResidualUseDForm)
1481e8d8bef9SDimitry Andric         MaterializeImm(*CurrentMBB, {MI}, NegResidualSize, ScratchReg);
1482e8d8bef9SDimitry Andric       allocateAndProbe(*CurrentMBB, {MI}, NegResidualSize, ScratchReg,
1483e8d8bef9SDimitry Andric                        ResidualUseDForm, FPReg);
14845ffd83dbSDimitry Andric     }
14855ffd83dbSDimitry Andric     bool UseDForm = CanUseDForm(NegProbeSize);
14865ffd83dbSDimitry Andric     // If number of blocks is small, just probe them directly.
14875ffd83dbSDimitry Andric     if (NumBlocks < 3) {
14885ffd83dbSDimitry Andric       if (!UseDForm)
1489e8d8bef9SDimitry Andric         MaterializeImm(*CurrentMBB, {MI}, NegProbeSize, ScratchReg);
14905ffd83dbSDimitry Andric       for (int i = 0; i < NumBlocks; ++i)
1491e8d8bef9SDimitry Andric         allocateAndProbe(*CurrentMBB, {MI}, NegProbeSize, ScratchReg, UseDForm,
1492e8d8bef9SDimitry Andric                          FPReg);
14935ffd83dbSDimitry Andric       if (needsCFI) {
14945ffd83dbSDimitry Andric         // Restore using SPReg to calculate CFA.
1495e8d8bef9SDimitry Andric         buildDefCFAReg(*CurrentMBB, {MI}, SPReg);
14965ffd83dbSDimitry Andric       }
14975ffd83dbSDimitry Andric     } else {
14985ffd83dbSDimitry Andric       // Since CTR is a volatile register and current shrinkwrap implementation
14995ffd83dbSDimitry Andric       // won't choose an MBB in a loop as the PrologMBB, it's safe to synthesize a
15005ffd83dbSDimitry Andric       // CTR loop to probe.
15015ffd83dbSDimitry Andric       // Calculate trip count and stores it in CTRReg.
1502e8d8bef9SDimitry Andric       MaterializeImm(*CurrentMBB, {MI}, NumBlocks, ScratchReg);
1503e8d8bef9SDimitry Andric       BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::MTCTR8 : PPC::MTCTR))
15045ffd83dbSDimitry Andric           .addReg(ScratchReg, RegState::Kill);
15055ffd83dbSDimitry Andric       if (!UseDForm)
1506e8d8bef9SDimitry Andric         MaterializeImm(*CurrentMBB, {MI}, NegProbeSize, ScratchReg);
15075ffd83dbSDimitry Andric       // Create MBBs of the loop.
15085ffd83dbSDimitry Andric       MachineFunction::iterator MBBInsertPoint =
1509e8d8bef9SDimitry Andric           std::next(CurrentMBB->getIterator());
15105ffd83dbSDimitry Andric       MachineBasicBlock *LoopMBB = MF.CreateMachineBasicBlock(ProbedBB);
15115ffd83dbSDimitry Andric       MF.insert(MBBInsertPoint, LoopMBB);
15125ffd83dbSDimitry Andric       MachineBasicBlock *ExitMBB = MF.CreateMachineBasicBlock(ProbedBB);
15135ffd83dbSDimitry Andric       MF.insert(MBBInsertPoint, ExitMBB);
15145ffd83dbSDimitry Andric       // Synthesize the loop body.
15155ffd83dbSDimitry Andric       allocateAndProbe(*LoopMBB, LoopMBB->end(), NegProbeSize, ScratchReg,
1516e8d8bef9SDimitry Andric                        UseDForm, FPReg);
15175ffd83dbSDimitry Andric       BuildMI(LoopMBB, DL, TII.get(isPPC64 ? PPC::BDNZ8 : PPC::BDNZ))
15185ffd83dbSDimitry Andric           .addMBB(LoopMBB);
15195ffd83dbSDimitry Andric       LoopMBB->addSuccessor(ExitMBB);
15205ffd83dbSDimitry Andric       LoopMBB->addSuccessor(LoopMBB);
15215ffd83dbSDimitry Andric       // Synthesize the exit MBB.
1522e8d8bef9SDimitry Andric       ExitMBB->splice(ExitMBB->end(), CurrentMBB,
15235ffd83dbSDimitry Andric                       std::next(MachineBasicBlock::iterator(MI)),
1524e8d8bef9SDimitry Andric                       CurrentMBB->end());
1525e8d8bef9SDimitry Andric       ExitMBB->transferSuccessorsAndUpdatePHIs(CurrentMBB);
1526e8d8bef9SDimitry Andric       CurrentMBB->addSuccessor(LoopMBB);
15275ffd83dbSDimitry Andric       if (needsCFI) {
15285ffd83dbSDimitry Andric         // Restore using SPReg to calculate CFA.
15295ffd83dbSDimitry Andric         buildDefCFAReg(*ExitMBB, ExitMBB->begin(), SPReg);
15305ffd83dbSDimitry Andric       }
15315ffd83dbSDimitry Andric       // Update liveins.
15320fca6ea1SDimitry Andric       fullyRecomputeLiveIns({ExitMBB, LoopMBB});
15335ffd83dbSDimitry Andric     }
153423408297SDimitry Andric   }
15355ffd83dbSDimitry Andric   ++NumPrologProbed;
15365ffd83dbSDimitry Andric   MI.eraseFromParent();
15375ffd83dbSDimitry Andric }
15385ffd83dbSDimitry Andric 
15390b57cec5SDimitry Andric void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
15400b57cec5SDimitry Andric                                     MachineBasicBlock &MBB) const {
15410b57cec5SDimitry Andric   MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
15420b57cec5SDimitry Andric   DebugLoc dl;
15430b57cec5SDimitry Andric 
15440b57cec5SDimitry Andric   if (MBBI != MBB.end())
15450b57cec5SDimitry Andric     dl = MBBI->getDebugLoc();
15460b57cec5SDimitry Andric 
15470b57cec5SDimitry Andric   const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
15480b57cec5SDimitry Andric   const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
15490b57cec5SDimitry Andric 
15500b57cec5SDimitry Andric   // Get alignment info so we know how to restore the SP.
15510b57cec5SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
15520b57cec5SDimitry Andric 
15530b57cec5SDimitry Andric   // Get the number of bytes allocated from the FrameInfo.
1554349cc55cSDimitry Andric   int64_t FrameSize = MFI.getStackSize();
15550b57cec5SDimitry Andric 
15560b57cec5SDimitry Andric   // Get processor type.
15570b57cec5SDimitry Andric   bool isPPC64 = Subtarget.isPPC64();
15580b57cec5SDimitry Andric 
15590b57cec5SDimitry Andric   // Check if the link register (LR) has been saved.
15600b57cec5SDimitry Andric   PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
15610b57cec5SDimitry Andric   bool MustSaveLR = FI->mustSaveLR();
15625ffd83dbSDimitry Andric   const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
15630b57cec5SDimitry Andric   bool MustSaveCR = !MustSaveCRs.empty();
15640b57cec5SDimitry Andric   // Do we have a frame pointer and/or base pointer for this function?
15650b57cec5SDimitry Andric   bool HasFP = hasFP(MF);
15660b57cec5SDimitry Andric   bool HasBP = RegInfo->hasBasePointer(MF);
15670b57cec5SDimitry Andric   bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
1568fe6060f1SDimitry Andric   bool HasROPProtect = Subtarget.hasROPProtect();
1569fe6060f1SDimitry Andric   bool HasPrivileged = Subtarget.hasPrivileged();
15700b57cec5SDimitry Andric 
15715ffd83dbSDimitry Andric   Register SPReg      = isPPC64 ? PPC::X1  : PPC::R1;
15728bcb0991SDimitry Andric   Register BPReg = RegInfo->getBaseRegister(MF);
15735ffd83dbSDimitry Andric   Register FPReg      = isPPC64 ? PPC::X31 : PPC::R31;
15745ffd83dbSDimitry Andric   Register ScratchReg;
15755ffd83dbSDimitry Andric   Register TempReg     = isPPC64 ? PPC::X12 : PPC::R12; // another scratch reg
15760b57cec5SDimitry Andric   const MCInstrDesc& MTLRInst = TII.get( isPPC64 ? PPC::MTLR8
15770b57cec5SDimitry Andric                                                  : PPC::MTLR );
15780b57cec5SDimitry Andric   const MCInstrDesc& LoadInst = TII.get( isPPC64 ? PPC::LD
15790b57cec5SDimitry Andric                                                  : PPC::LWZ );
15800b57cec5SDimitry Andric   const MCInstrDesc& LoadImmShiftedInst = TII.get( isPPC64 ? PPC::LIS8
15810b57cec5SDimitry Andric                                                            : PPC::LIS );
15820b57cec5SDimitry Andric   const MCInstrDesc& OrInst = TII.get(isPPC64 ? PPC::OR8
15830b57cec5SDimitry Andric                                               : PPC::OR );
15840b57cec5SDimitry Andric   const MCInstrDesc& OrImmInst = TII.get( isPPC64 ? PPC::ORI8
15850b57cec5SDimitry Andric                                                   : PPC::ORI );
15860b57cec5SDimitry Andric   const MCInstrDesc& AddImmInst = TII.get( isPPC64 ? PPC::ADDI8
15870b57cec5SDimitry Andric                                                    : PPC::ADDI );
15880b57cec5SDimitry Andric   const MCInstrDesc& AddInst = TII.get( isPPC64 ? PPC::ADD8
15890b57cec5SDimitry Andric                                                 : PPC::ADD4 );
15905ffd83dbSDimitry Andric   const MCInstrDesc& LoadWordInst = TII.get( isPPC64 ? PPC::LWZ8
15915ffd83dbSDimitry Andric                                                      : PPC::LWZ);
15925ffd83dbSDimitry Andric   const MCInstrDesc& MoveToCRInst = TII.get( isPPC64 ? PPC::MTOCRF8
15935ffd83dbSDimitry Andric                                                      : PPC::MTOCRF);
1594fe6060f1SDimitry Andric   const MCInstrDesc &HashChk =
159504eeddc0SDimitry Andric       TII.get(isPPC64 ? (HasPrivileged ? PPC::HASHCHKP8 : PPC::HASHCHK8)
159604eeddc0SDimitry Andric                       : (HasPrivileged ? PPC::HASHCHKP : PPC::HASHCHK));
1597349cc55cSDimitry Andric   int64_t LROffset = getReturnSaveOffset();
15980b57cec5SDimitry Andric 
1599349cc55cSDimitry Andric   int64_t FPOffset = 0;
16000b57cec5SDimitry Andric 
16010b57cec5SDimitry Andric   // Using the same bool variable as below to suppress compiler warnings.
16020b57cec5SDimitry Andric   bool SingleScratchReg = findScratchRegister(&MBB, true, false, &ScratchReg,
16030b57cec5SDimitry Andric                                               &TempReg);
16040b57cec5SDimitry Andric   assert(SingleScratchReg &&
16050b57cec5SDimitry Andric          "Could not find an available scratch register");
16060b57cec5SDimitry Andric 
16070b57cec5SDimitry Andric   SingleScratchReg = ScratchReg == TempReg;
16080b57cec5SDimitry Andric 
16090b57cec5SDimitry Andric   if (HasFP) {
16100b57cec5SDimitry Andric     int FPIndex = FI->getFramePointerSaveIndex();
16110b57cec5SDimitry Andric     assert(FPIndex && "No Frame Pointer Save Slot!");
16120b57cec5SDimitry Andric     FPOffset = MFI.getObjectOffset(FPIndex);
16130b57cec5SDimitry Andric   }
16140b57cec5SDimitry Andric 
1615349cc55cSDimitry Andric   int64_t BPOffset = 0;
16160b57cec5SDimitry Andric   if (HasBP) {
16170b57cec5SDimitry Andric       int BPIndex = FI->getBasePointerSaveIndex();
16180b57cec5SDimitry Andric       assert(BPIndex && "No Base Pointer Save Slot!");
16190b57cec5SDimitry Andric       BPOffset = MFI.getObjectOffset(BPIndex);
16200b57cec5SDimitry Andric   }
16210b57cec5SDimitry Andric 
1622349cc55cSDimitry Andric   int64_t PBPOffset = 0;
16230b57cec5SDimitry Andric   if (FI->usesPICBase()) {
16240b57cec5SDimitry Andric     int PBPIndex = FI->getPICBasePointerSaveIndex();
16250b57cec5SDimitry Andric     assert(PBPIndex && "No PIC Base Pointer Save Slot!");
16260b57cec5SDimitry Andric     PBPOffset = MFI.getObjectOffset(PBPIndex);
16270b57cec5SDimitry Andric   }
16280b57cec5SDimitry Andric 
16290b57cec5SDimitry Andric   bool IsReturnBlock = (MBBI != MBB.end() && MBBI->isReturn());
16300b57cec5SDimitry Andric 
16310b57cec5SDimitry Andric   if (IsReturnBlock) {
16320b57cec5SDimitry Andric     unsigned RetOpcode = MBBI->getOpcode();
16330b57cec5SDimitry Andric     bool UsesTCRet =  RetOpcode == PPC::TCRETURNri ||
16340b57cec5SDimitry Andric                       RetOpcode == PPC::TCRETURNdi ||
16350b57cec5SDimitry Andric                       RetOpcode == PPC::TCRETURNai ||
16360b57cec5SDimitry Andric                       RetOpcode == PPC::TCRETURNri8 ||
16370b57cec5SDimitry Andric                       RetOpcode == PPC::TCRETURNdi8 ||
16380b57cec5SDimitry Andric                       RetOpcode == PPC::TCRETURNai8;
16390b57cec5SDimitry Andric 
16400b57cec5SDimitry Andric     if (UsesTCRet) {
16410b57cec5SDimitry Andric       int MaxTCRetDelta = FI->getTailCallSPDelta();
16420b57cec5SDimitry Andric       MachineOperand &StackAdjust = MBBI->getOperand(1);
16430b57cec5SDimitry Andric       assert(StackAdjust.isImm() && "Expecting immediate value.");
16440b57cec5SDimitry Andric       // Adjust stack pointer.
16450b57cec5SDimitry Andric       int StackAdj = StackAdjust.getImm();
16460b57cec5SDimitry Andric       int Delta = StackAdj - MaxTCRetDelta;
16470b57cec5SDimitry Andric       assert((Delta >= 0) && "Delta must be positive");
16480b57cec5SDimitry Andric       if (MaxTCRetDelta>0)
16490b57cec5SDimitry Andric         FrameSize += (StackAdj +Delta);
16500b57cec5SDimitry Andric       else
16510b57cec5SDimitry Andric         FrameSize += StackAdj;
16520b57cec5SDimitry Andric     }
16530b57cec5SDimitry Andric   }
16540b57cec5SDimitry Andric 
16550b57cec5SDimitry Andric   // Frames of 32KB & larger require special handling because they cannot be
16560b57cec5SDimitry Andric   // indexed into with a simple LD/LWZ immediate offset operand.
16570b57cec5SDimitry Andric   bool isLargeFrame = !isInt<16>(FrameSize);
16580b57cec5SDimitry Andric 
16590b57cec5SDimitry Andric   // On targets without red zone, the SP needs to be restored last, so that
16600b57cec5SDimitry Andric   // all live contents of the stack frame are upwards of the SP. This means
16610b57cec5SDimitry Andric   // that we cannot restore SP just now, since there may be more registers
16620b57cec5SDimitry Andric   // to restore from the stack frame (e.g. R31). If the frame size is not
16630b57cec5SDimitry Andric   // a simple immediate value, we will need a spare register to hold the
16640b57cec5SDimitry Andric   // restored SP. If the frame size is known and small, we can simply adjust
16650b57cec5SDimitry Andric   // the offsets of the registers to be restored, and still use SP to restore
16660b57cec5SDimitry Andric   // them. In such case, the final update of SP will be to add the frame
16670b57cec5SDimitry Andric   // size to it.
16680b57cec5SDimitry Andric   // To simplify the code, set RBReg to the base register used to restore
16690b57cec5SDimitry Andric   // values from the stack, and set SPAdd to the value that needs to be added
16700b57cec5SDimitry Andric   // to the SP at the end. The default values are as if red zone was present.
16710b57cec5SDimitry Andric   unsigned RBReg = SPReg;
167281ad6265SDimitry Andric   uint64_t SPAdd = 0;
16730b57cec5SDimitry Andric 
16740b57cec5SDimitry Andric   // Check if we can move the stack update instruction up the epilogue
16750b57cec5SDimitry Andric   // past the callee saves. This will allow the move to LR instruction
16760b57cec5SDimitry Andric   // to be executed before the restores of the callee saves which means
16770b57cec5SDimitry Andric   // that the callee saves can hide the latency from the MTLR instrcution.
16780b57cec5SDimitry Andric   MachineBasicBlock::iterator StackUpdateLoc = MBBI;
16790b57cec5SDimitry Andric   if (stackUpdateCanBeMoved(MF)) {
16800b57cec5SDimitry Andric     const std::vector<CalleeSavedInfo> & Info = MFI.getCalleeSavedInfo();
16810b57cec5SDimitry Andric     for (CalleeSavedInfo CSI : Info) {
1682fe6060f1SDimitry Andric       // If the callee saved register is spilled to another register abort the
1683fe6060f1SDimitry Andric       // stack update movement.
1684fe6060f1SDimitry Andric       if (CSI.isSpilledToReg()) {
1685fe6060f1SDimitry Andric         StackUpdateLoc = MBBI;
1686fe6060f1SDimitry Andric         break;
1687fe6060f1SDimitry Andric       }
16880b57cec5SDimitry Andric       int FrIdx = CSI.getFrameIdx();
16890b57cec5SDimitry Andric       // If the frame index is not negative the callee saved info belongs to a
16900b57cec5SDimitry Andric       // stack object that is not a fixed stack object. We ignore non-fixed
16910b57cec5SDimitry Andric       // stack objects because we won't move the update of the stack pointer
16920b57cec5SDimitry Andric       // past them.
16930b57cec5SDimitry Andric       if (FrIdx >= 0)
16940b57cec5SDimitry Andric         continue;
16950b57cec5SDimitry Andric 
16960b57cec5SDimitry Andric       if (MFI.isFixedObjectIndex(FrIdx) && MFI.getObjectOffset(FrIdx) < 0)
16970b57cec5SDimitry Andric         StackUpdateLoc--;
16980b57cec5SDimitry Andric       else {
16990b57cec5SDimitry Andric         // Abort the operation as we can't update all CSR restores.
17000b57cec5SDimitry Andric         StackUpdateLoc = MBBI;
17010b57cec5SDimitry Andric         break;
17020b57cec5SDimitry Andric       }
17030b57cec5SDimitry Andric     }
17040b57cec5SDimitry Andric   }
17050b57cec5SDimitry Andric 
17060b57cec5SDimitry Andric   if (FrameSize) {
17070b57cec5SDimitry Andric     // In the prologue, the loaded (or persistent) stack pointer value is
17080b57cec5SDimitry Andric     // offset by the STDU/STDUX/STWU/STWUX instruction. For targets with red
17090b57cec5SDimitry Andric     // zone add this offset back now.
17100b57cec5SDimitry Andric 
1711e8d8bef9SDimitry Andric     // If the function has a base pointer, the stack pointer has been copied
1712e8d8bef9SDimitry Andric     // to it so we can restore it by copying in the other direction.
1713e8d8bef9SDimitry Andric     if (HasRedZone && HasBP) {
1714e8d8bef9SDimitry Andric       BuildMI(MBB, MBBI, dl, OrInst, RBReg).
1715e8d8bef9SDimitry Andric         addReg(BPReg).
1716e8d8bef9SDimitry Andric         addReg(BPReg);
1717e8d8bef9SDimitry Andric     }
17180b57cec5SDimitry Andric     // If this function contained a fastcc call and GuaranteedTailCallOpt is
17190b57cec5SDimitry Andric     // enabled (=> hasFastCall()==true) the fastcc call might contain a tail
17200b57cec5SDimitry Andric     // call which invalidates the stack pointer value in SP(0). So we use the
1721e8d8bef9SDimitry Andric     // value of R31 in this case. Similar situation exists with setjmp.
1722e8d8bef9SDimitry Andric     else if (FI->hasFastCall() || MF.exposesReturnsTwice()) {
17230b57cec5SDimitry Andric       assert(HasFP && "Expecting a valid frame pointer.");
17240b57cec5SDimitry Andric       if (!HasRedZone)
17250b57cec5SDimitry Andric         RBReg = FPReg;
17260b57cec5SDimitry Andric       if (!isLargeFrame) {
17270b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, AddImmInst, RBReg)
17280b57cec5SDimitry Andric           .addReg(FPReg).addImm(FrameSize);
17290b57cec5SDimitry Andric       } else {
173081ad6265SDimitry Andric         TII.materializeImmPostRA(MBB, MBBI, dl, ScratchReg, FrameSize);
17310b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, AddInst)
17320b57cec5SDimitry Andric           .addReg(RBReg)
17330b57cec5SDimitry Andric           .addReg(FPReg)
17340b57cec5SDimitry Andric           .addReg(ScratchReg);
17350b57cec5SDimitry Andric       }
17360b57cec5SDimitry Andric     } else if (!isLargeFrame && !HasBP && !MFI.hasVarSizedObjects()) {
17370b57cec5SDimitry Andric       if (HasRedZone) {
17380b57cec5SDimitry Andric         BuildMI(MBB, StackUpdateLoc, dl, AddImmInst, SPReg)
17390b57cec5SDimitry Andric           .addReg(SPReg)
17400b57cec5SDimitry Andric           .addImm(FrameSize);
17410b57cec5SDimitry Andric       } else {
17420b57cec5SDimitry Andric         // Make sure that adding FrameSize will not overflow the max offset
17430b57cec5SDimitry Andric         // size.
17440b57cec5SDimitry Andric         assert(FPOffset <= 0 && BPOffset <= 0 && PBPOffset <= 0 &&
17450b57cec5SDimitry Andric                "Local offsets should be negative");
17460b57cec5SDimitry Andric         SPAdd = FrameSize;
17470b57cec5SDimitry Andric         FPOffset += FrameSize;
17480b57cec5SDimitry Andric         BPOffset += FrameSize;
17490b57cec5SDimitry Andric         PBPOffset += FrameSize;
17500b57cec5SDimitry Andric       }
17510b57cec5SDimitry Andric     } else {
17520b57cec5SDimitry Andric       // We don't want to use ScratchReg as a base register, because it
17530b57cec5SDimitry Andric       // could happen to be R0. Use FP instead, but make sure to preserve it.
17540b57cec5SDimitry Andric       if (!HasRedZone) {
17550b57cec5SDimitry Andric         // If FP is not saved, copy it to ScratchReg.
17560b57cec5SDimitry Andric         if (!HasFP)
17570b57cec5SDimitry Andric           BuildMI(MBB, MBBI, dl, OrInst, ScratchReg)
17580b57cec5SDimitry Andric             .addReg(FPReg)
17590b57cec5SDimitry Andric             .addReg(FPReg);
17600b57cec5SDimitry Andric         RBReg = FPReg;
17610b57cec5SDimitry Andric       }
17620b57cec5SDimitry Andric       BuildMI(MBB, StackUpdateLoc, dl, LoadInst, RBReg)
17630b57cec5SDimitry Andric         .addImm(0)
17640b57cec5SDimitry Andric         .addReg(SPReg);
17650b57cec5SDimitry Andric     }
17660b57cec5SDimitry Andric   }
17670b57cec5SDimitry Andric   assert(RBReg != ScratchReg && "Should have avoided ScratchReg");
17680b57cec5SDimitry Andric   // If there is no red zone, ScratchReg may be needed for holding a useful
17690b57cec5SDimitry Andric   // value (although not the base register). Make sure it is not overwritten
17700b57cec5SDimitry Andric   // too early.
17710b57cec5SDimitry Andric 
17720b57cec5SDimitry Andric   // If we need to restore both the LR and the CR and we only have one
17730b57cec5SDimitry Andric   // available scratch register, we must do them one at a time.
17740b57cec5SDimitry Andric   if (MustSaveCR && SingleScratchReg && MustSaveLR) {
17750b57cec5SDimitry Andric     // Here TempReg == ScratchReg, and in the absence of red zone ScratchReg
17760b57cec5SDimitry Andric     // is live here.
17770b57cec5SDimitry Andric     assert(HasRedZone && "Expecting red zone");
17785ffd83dbSDimitry Andric     BuildMI(MBB, MBBI, dl, LoadWordInst, TempReg)
17795ffd83dbSDimitry Andric       .addImm(CRSaveOffset)
17800b57cec5SDimitry Andric       .addReg(SPReg);
17810b57cec5SDimitry Andric     for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
17825ffd83dbSDimitry Andric       BuildMI(MBB, MBBI, dl, MoveToCRInst, MustSaveCRs[i])
17830b57cec5SDimitry Andric         .addReg(TempReg, getKillRegState(i == e-1));
17840b57cec5SDimitry Andric   }
17850b57cec5SDimitry Andric 
17860b57cec5SDimitry Andric   // Delay restoring of the LR if ScratchReg is needed. This is ok, since
17870b57cec5SDimitry Andric   // LR is stored in the caller's stack frame. ScratchReg will be needed
17880b57cec5SDimitry Andric   // if RBReg is anything other than SP. We shouldn't use ScratchReg as
17890b57cec5SDimitry Andric   // a base register anyway, because it may happen to be R0.
17900b57cec5SDimitry Andric   bool LoadedLR = false;
17910b57cec5SDimitry Andric   if (MustSaveLR && RBReg == SPReg && isInt<16>(LROffset+SPAdd)) {
17920b57cec5SDimitry Andric     BuildMI(MBB, StackUpdateLoc, dl, LoadInst, ScratchReg)
17930b57cec5SDimitry Andric       .addImm(LROffset+SPAdd)
17940b57cec5SDimitry Andric       .addReg(RBReg);
17950b57cec5SDimitry Andric     LoadedLR = true;
17960b57cec5SDimitry Andric   }
17970b57cec5SDimitry Andric 
17980b57cec5SDimitry Andric   if (MustSaveCR && !(SingleScratchReg && MustSaveLR)) {
17990b57cec5SDimitry Andric     assert(RBReg == SPReg && "Should be using SP as a base register");
18005ffd83dbSDimitry Andric     BuildMI(MBB, MBBI, dl, LoadWordInst, TempReg)
18015ffd83dbSDimitry Andric       .addImm(CRSaveOffset)
18020b57cec5SDimitry Andric       .addReg(RBReg);
18030b57cec5SDimitry Andric   }
18040b57cec5SDimitry Andric 
18050b57cec5SDimitry Andric   if (HasFP) {
18060b57cec5SDimitry Andric     // If there is red zone, restore FP directly, since SP has already been
18070b57cec5SDimitry Andric     // restored. Otherwise, restore the value of FP into ScratchReg.
18080b57cec5SDimitry Andric     if (HasRedZone || RBReg == SPReg)
18090b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, LoadInst, FPReg)
18100b57cec5SDimitry Andric         .addImm(FPOffset)
18110b57cec5SDimitry Andric         .addReg(SPReg);
18120b57cec5SDimitry Andric     else
18130b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, LoadInst, ScratchReg)
18140b57cec5SDimitry Andric         .addImm(FPOffset)
18150b57cec5SDimitry Andric         .addReg(RBReg);
18160b57cec5SDimitry Andric   }
18170b57cec5SDimitry Andric 
18180b57cec5SDimitry Andric   if (FI->usesPICBase())
18190b57cec5SDimitry Andric     BuildMI(MBB, MBBI, dl, LoadInst, PPC::R30)
18200b57cec5SDimitry Andric       .addImm(PBPOffset)
18210b57cec5SDimitry Andric       .addReg(RBReg);
18220b57cec5SDimitry Andric 
18230b57cec5SDimitry Andric   if (HasBP)
18240b57cec5SDimitry Andric     BuildMI(MBB, MBBI, dl, LoadInst, BPReg)
18250b57cec5SDimitry Andric       .addImm(BPOffset)
18260b57cec5SDimitry Andric       .addReg(RBReg);
18270b57cec5SDimitry Andric 
18280b57cec5SDimitry Andric   // There is nothing more to be loaded from the stack, so now we can
18290b57cec5SDimitry Andric   // restore SP: SP = RBReg + SPAdd.
18300b57cec5SDimitry Andric   if (RBReg != SPReg || SPAdd != 0) {
18310b57cec5SDimitry Andric     assert(!HasRedZone && "This should not happen with red zone");
18320b57cec5SDimitry Andric     // If SPAdd is 0, generate a copy.
18330b57cec5SDimitry Andric     if (SPAdd == 0)
18340b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, OrInst, SPReg)
18350b57cec5SDimitry Andric         .addReg(RBReg)
18360b57cec5SDimitry Andric         .addReg(RBReg);
18370b57cec5SDimitry Andric     else
18380b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, AddImmInst, SPReg)
18390b57cec5SDimitry Andric         .addReg(RBReg)
18400b57cec5SDimitry Andric         .addImm(SPAdd);
18410b57cec5SDimitry Andric 
18420b57cec5SDimitry Andric     assert(RBReg != ScratchReg && "Should be using FP or SP as base register");
18430b57cec5SDimitry Andric     if (RBReg == FPReg)
18440b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, OrInst, FPReg)
18450b57cec5SDimitry Andric         .addReg(ScratchReg)
18460b57cec5SDimitry Andric         .addReg(ScratchReg);
18470b57cec5SDimitry Andric 
18480b57cec5SDimitry Andric     // Now load the LR from the caller's stack frame.
18490b57cec5SDimitry Andric     if (MustSaveLR && !LoadedLR)
18500b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, LoadInst, ScratchReg)
18510b57cec5SDimitry Andric         .addImm(LROffset)
18520b57cec5SDimitry Andric         .addReg(SPReg);
18530b57cec5SDimitry Andric   }
18540b57cec5SDimitry Andric 
18550b57cec5SDimitry Andric   if (MustSaveCR &&
18565ffd83dbSDimitry Andric       !(SingleScratchReg && MustSaveLR))
18570b57cec5SDimitry Andric     for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
18585ffd83dbSDimitry Andric       BuildMI(MBB, MBBI, dl, MoveToCRInst, MustSaveCRs[i])
18590b57cec5SDimitry Andric         .addReg(TempReg, getKillRegState(i == e-1));
18600b57cec5SDimitry Andric 
1861fe6060f1SDimitry Andric   if (MustSaveLR) {
1862fe6060f1SDimitry Andric     // If ROP protection is required, an extra instruction is added to compute a
1863fe6060f1SDimitry Andric     // hash and then compare it to the hash stored in the prologue.
1864fe6060f1SDimitry Andric     if (HasROPProtect) {
1865fe6060f1SDimitry Andric       const int SaveIndex = FI->getROPProtectionHashSaveIndex();
1866349cc55cSDimitry Andric       const int64_t ImmOffset = MFI.getObjectOffset(SaveIndex);
1867fe6060f1SDimitry Andric       assert((ImmOffset <= -8 && ImmOffset >= -512) &&
1868fe6060f1SDimitry Andric              "ROP hash check location offset out of range.");
1869fe6060f1SDimitry Andric       assert(((ImmOffset & 0x7) == 0) &&
1870fe6060f1SDimitry Andric              "ROP hash check location offset must be 8 byte aligned.");
1871fe6060f1SDimitry Andric       BuildMI(MBB, StackUpdateLoc, dl, HashChk)
1872fe6060f1SDimitry Andric           .addReg(ScratchReg)
1873fe6060f1SDimitry Andric           .addImm(ImmOffset)
1874fe6060f1SDimitry Andric           .addReg(SPReg);
1875fe6060f1SDimitry Andric     }
18760b57cec5SDimitry Andric     BuildMI(MBB, StackUpdateLoc, dl, MTLRInst).addReg(ScratchReg);
1877fe6060f1SDimitry Andric   }
18780b57cec5SDimitry Andric 
18790b57cec5SDimitry Andric   // Callee pop calling convention. Pop parameter/linkage area. Used for tail
18800b57cec5SDimitry Andric   // call optimization
18810b57cec5SDimitry Andric   if (IsReturnBlock) {
18820b57cec5SDimitry Andric     unsigned RetOpcode = MBBI->getOpcode();
18830b57cec5SDimitry Andric     if (MF.getTarget().Options.GuaranteedTailCallOpt &&
18840b57cec5SDimitry Andric         (RetOpcode == PPC::BLR || RetOpcode == PPC::BLR8) &&
18850b57cec5SDimitry Andric         MF.getFunction().getCallingConv() == CallingConv::Fast) {
18860b57cec5SDimitry Andric       PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
18870b57cec5SDimitry Andric       unsigned CallerAllocatedAmt = FI->getMinReservedArea();
18880b57cec5SDimitry Andric 
18890b57cec5SDimitry Andric       if (CallerAllocatedAmt && isInt<16>(CallerAllocatedAmt)) {
18900b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, AddImmInst, SPReg)
18910b57cec5SDimitry Andric           .addReg(SPReg).addImm(CallerAllocatedAmt);
18920b57cec5SDimitry Andric       } else {
18930b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, LoadImmShiftedInst, ScratchReg)
18940b57cec5SDimitry Andric           .addImm(CallerAllocatedAmt >> 16);
18950b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, OrImmInst, ScratchReg)
18960b57cec5SDimitry Andric           .addReg(ScratchReg, RegState::Kill)
18970b57cec5SDimitry Andric           .addImm(CallerAllocatedAmt & 0xFFFF);
18980b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, AddInst)
18990b57cec5SDimitry Andric           .addReg(SPReg)
19000b57cec5SDimitry Andric           .addReg(FPReg)
19010b57cec5SDimitry Andric           .addReg(ScratchReg);
19020b57cec5SDimitry Andric       }
19030b57cec5SDimitry Andric     } else {
19040b57cec5SDimitry Andric       createTailCallBranchInstr(MBB);
19050b57cec5SDimitry Andric     }
19060b57cec5SDimitry Andric   }
19070b57cec5SDimitry Andric }
19080b57cec5SDimitry Andric 
19090b57cec5SDimitry Andric void PPCFrameLowering::createTailCallBranchInstr(MachineBasicBlock &MBB) const {
19100b57cec5SDimitry Andric   MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
19110b57cec5SDimitry Andric 
19120b57cec5SDimitry Andric   // If we got this far a first terminator should exist.
19130b57cec5SDimitry Andric   assert(MBBI != MBB.end() && "Failed to find the first terminator.");
19140b57cec5SDimitry Andric 
19150b57cec5SDimitry Andric   DebugLoc dl = MBBI->getDebugLoc();
19160b57cec5SDimitry Andric   const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
19170b57cec5SDimitry Andric 
19185ffd83dbSDimitry Andric   // Create branch instruction for pseudo tail call return instruction.
19195ffd83dbSDimitry Andric   // The TCRETURNdi variants are direct calls. Valid targets for those are
19205ffd83dbSDimitry Andric   // MO_GlobalAddress operands as well as MO_ExternalSymbol with PC-Rel
19215ffd83dbSDimitry Andric   // since we can tail call external functions with PC-Rel (i.e. we don't need
19225ffd83dbSDimitry Andric   // to worry about different TOC pointers). Some of the external functions will
19235ffd83dbSDimitry Andric   // be MO_GlobalAddress while others like memcpy for example, are going to
19245ffd83dbSDimitry Andric   // be MO_ExternalSymbol.
19250b57cec5SDimitry Andric   unsigned RetOpcode = MBBI->getOpcode();
19260b57cec5SDimitry Andric   if (RetOpcode == PPC::TCRETURNdi) {
19270b57cec5SDimitry Andric     MBBI = MBB.getLastNonDebugInstr();
19280b57cec5SDimitry Andric     MachineOperand &JumpTarget = MBBI->getOperand(0);
19295ffd83dbSDimitry Andric     if (JumpTarget.isGlobal())
19300b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
19310b57cec5SDimitry Andric         addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
19325ffd83dbSDimitry Andric     else if (JumpTarget.isSymbol())
19335ffd83dbSDimitry Andric       BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
19345ffd83dbSDimitry Andric         addExternalSymbol(JumpTarget.getSymbolName());
19355ffd83dbSDimitry Andric     else
19365ffd83dbSDimitry Andric       llvm_unreachable("Expecting Global or External Symbol");
19370b57cec5SDimitry Andric   } else if (RetOpcode == PPC::TCRETURNri) {
19380b57cec5SDimitry Andric     MBBI = MBB.getLastNonDebugInstr();
19390b57cec5SDimitry Andric     assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
19400b57cec5SDimitry Andric     BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR));
19410b57cec5SDimitry Andric   } else if (RetOpcode == PPC::TCRETURNai) {
19420b57cec5SDimitry Andric     MBBI = MBB.getLastNonDebugInstr();
19430b57cec5SDimitry Andric     MachineOperand &JumpTarget = MBBI->getOperand(0);
19440b57cec5SDimitry Andric     BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm());
19450b57cec5SDimitry Andric   } else if (RetOpcode == PPC::TCRETURNdi8) {
19460b57cec5SDimitry Andric     MBBI = MBB.getLastNonDebugInstr();
19470b57cec5SDimitry Andric     MachineOperand &JumpTarget = MBBI->getOperand(0);
19485ffd83dbSDimitry Andric     if (JumpTarget.isGlobal())
19490b57cec5SDimitry Andric       BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
19500b57cec5SDimitry Andric         addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
19515ffd83dbSDimitry Andric     else if (JumpTarget.isSymbol())
19525ffd83dbSDimitry Andric       BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
19535ffd83dbSDimitry Andric         addExternalSymbol(JumpTarget.getSymbolName());
19545ffd83dbSDimitry Andric     else
19555ffd83dbSDimitry Andric       llvm_unreachable("Expecting Global or External Symbol");
19560b57cec5SDimitry Andric   } else if (RetOpcode == PPC::TCRETURNri8) {
19570b57cec5SDimitry Andric     MBBI = MBB.getLastNonDebugInstr();
19580b57cec5SDimitry Andric     assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
19590b57cec5SDimitry Andric     BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR8));
19600b57cec5SDimitry Andric   } else if (RetOpcode == PPC::TCRETURNai8) {
19610b57cec5SDimitry Andric     MBBI = MBB.getLastNonDebugInstr();
19620b57cec5SDimitry Andric     MachineOperand &JumpTarget = MBBI->getOperand(0);
19630b57cec5SDimitry Andric     BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm());
19640b57cec5SDimitry Andric   }
19650b57cec5SDimitry Andric }
19660b57cec5SDimitry Andric 
19670b57cec5SDimitry Andric void PPCFrameLowering::determineCalleeSaves(MachineFunction &MF,
19680b57cec5SDimitry Andric                                             BitVector &SavedRegs,
19690b57cec5SDimitry Andric                                             RegScavenger *RS) const {
19700b57cec5SDimitry Andric   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
19710fca6ea1SDimitry Andric   if (Subtarget.isAIXABI())
19720fca6ea1SDimitry Andric     updateCalleeSaves(MF, SavedRegs);
19730b57cec5SDimitry Andric 
19740b57cec5SDimitry Andric   const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
19750b57cec5SDimitry Andric 
197681ad6265SDimitry Andric   // Do not explicitly save the callee saved VSRp registers.
197781ad6265SDimitry Andric   // The individual VSR subregisters will be saved instead.
197881ad6265SDimitry Andric   SavedRegs.reset(PPC::VSRp26);
197981ad6265SDimitry Andric   SavedRegs.reset(PPC::VSRp27);
198081ad6265SDimitry Andric   SavedRegs.reset(PPC::VSRp28);
198181ad6265SDimitry Andric   SavedRegs.reset(PPC::VSRp29);
198281ad6265SDimitry Andric   SavedRegs.reset(PPC::VSRp30);
198381ad6265SDimitry Andric   SavedRegs.reset(PPC::VSRp31);
198481ad6265SDimitry Andric 
19850b57cec5SDimitry Andric   //  Save and clear the LR state.
19860b57cec5SDimitry Andric   PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
19870b57cec5SDimitry Andric   unsigned LR = RegInfo->getRARegister();
19880b57cec5SDimitry Andric   FI->setMustSaveLR(MustSaveLR(MF, LR));
19890b57cec5SDimitry Andric   SavedRegs.reset(LR);
19900b57cec5SDimitry Andric 
19910b57cec5SDimitry Andric   //  Save R31 if necessary
19920b57cec5SDimitry Andric   int FPSI = FI->getFramePointerSaveIndex();
19938bcb0991SDimitry Andric   const bool isPPC64 = Subtarget.isPPC64();
19940b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
19950b57cec5SDimitry Andric 
19960b57cec5SDimitry Andric   // If the frame pointer save index hasn't been defined yet.
19970b57cec5SDimitry Andric   if (!FPSI && needsFP(MF)) {
19980b57cec5SDimitry Andric     // Find out what the fix offset of the frame pointer save area.
19990b57cec5SDimitry Andric     int FPOffset = getFramePointerSaveOffset();
20000b57cec5SDimitry Andric     // Allocate the frame index for frame pointer save area.
20010b57cec5SDimitry Andric     FPSI = MFI.CreateFixedObject(isPPC64? 8 : 4, FPOffset, true);
20020b57cec5SDimitry Andric     // Save the result.
20030b57cec5SDimitry Andric     FI->setFramePointerSaveIndex(FPSI);
20040b57cec5SDimitry Andric   }
20050b57cec5SDimitry Andric 
20060b57cec5SDimitry Andric   int BPSI = FI->getBasePointerSaveIndex();
20070b57cec5SDimitry Andric   if (!BPSI && RegInfo->hasBasePointer(MF)) {
20080b57cec5SDimitry Andric     int BPOffset = getBasePointerSaveOffset();
20090b57cec5SDimitry Andric     // Allocate the frame index for the base pointer save area.
20100b57cec5SDimitry Andric     BPSI = MFI.CreateFixedObject(isPPC64? 8 : 4, BPOffset, true);
20110b57cec5SDimitry Andric     // Save the result.
20120b57cec5SDimitry Andric     FI->setBasePointerSaveIndex(BPSI);
20130b57cec5SDimitry Andric   }
20140b57cec5SDimitry Andric 
20150b57cec5SDimitry Andric   // Reserve stack space for the PIC Base register (R30).
20160b57cec5SDimitry Andric   // Only used in SVR4 32-bit.
20170b57cec5SDimitry Andric   if (FI->usesPICBase()) {
20180b57cec5SDimitry Andric     int PBPSI = MFI.CreateFixedObject(4, -8, true);
20190b57cec5SDimitry Andric     FI->setPICBasePointerSaveIndex(PBPSI);
20200b57cec5SDimitry Andric   }
20210b57cec5SDimitry Andric 
20220b57cec5SDimitry Andric   // Make sure we don't explicitly spill r31, because, for example, we have
20230b57cec5SDimitry Andric   // some inline asm which explicitly clobbers it, when we otherwise have a
20240b57cec5SDimitry Andric   // frame pointer and are using r31's spill slot for the prologue/epilogue
20250b57cec5SDimitry Andric   // code. Same goes for the base pointer and the PIC base register.
20260b57cec5SDimitry Andric   if (needsFP(MF))
20270b57cec5SDimitry Andric     SavedRegs.reset(isPPC64 ? PPC::X31 : PPC::R31);
2028*62987288SDimitry Andric   if (RegInfo->hasBasePointer(MF)) {
20290b57cec5SDimitry Andric     SavedRegs.reset(RegInfo->getBaseRegister(MF));
2030*62987288SDimitry Andric     // On AIX, when BaseRegister(R30) is used, need to spill r31 too to match
2031*62987288SDimitry Andric     // AIX trackback table requirement.
2032*62987288SDimitry Andric     if (!needsFP(MF) && !SavedRegs.test(isPPC64 ? PPC::X31 : PPC::R31) &&
2033*62987288SDimitry Andric         Subtarget.isAIXABI()) {
2034*62987288SDimitry Andric       assert(
2035*62987288SDimitry Andric           (RegInfo->getBaseRegister(MF) == (isPPC64 ? PPC::X30 : PPC::R30)) &&
2036*62987288SDimitry Andric           "Invalid base register on AIX!");
2037*62987288SDimitry Andric       SavedRegs.set(isPPC64 ? PPC::X31 : PPC::R31);
2038*62987288SDimitry Andric     }
2039*62987288SDimitry Andric   }
20400b57cec5SDimitry Andric   if (FI->usesPICBase())
20410b57cec5SDimitry Andric     SavedRegs.reset(PPC::R30);
20420b57cec5SDimitry Andric 
20430b57cec5SDimitry Andric   // Reserve stack space to move the linkage area to in case of a tail call.
20440b57cec5SDimitry Andric   int TCSPDelta = 0;
20450b57cec5SDimitry Andric   if (MF.getTarget().Options.GuaranteedTailCallOpt &&
20460b57cec5SDimitry Andric       (TCSPDelta = FI->getTailCallSPDelta()) < 0) {
20470b57cec5SDimitry Andric     MFI.CreateFixedObject(-1 * TCSPDelta, TCSPDelta, true);
20480b57cec5SDimitry Andric   }
20490b57cec5SDimitry Andric 
20505ffd83dbSDimitry Andric   // Allocate the nonvolatile CR spill slot iff the function uses CR 2, 3, or 4.
20515ffd83dbSDimitry Andric   // For 64-bit SVR4, and all flavors of AIX we create a FixedStack
20525ffd83dbSDimitry Andric   // object at the offset of the CR-save slot in the linkage area. The actual
20535ffd83dbSDimitry Andric   // save and restore of the condition register will be created as part of the
20545ffd83dbSDimitry Andric   // prologue and epilogue insertion, but the FixedStack object is needed to
20555ffd83dbSDimitry Andric   // keep the CalleSavedInfo valid.
20565ffd83dbSDimitry Andric   if ((SavedRegs.test(PPC::CR2) || SavedRegs.test(PPC::CR3) ||
20570b57cec5SDimitry Andric        SavedRegs.test(PPC::CR4))) {
20585ffd83dbSDimitry Andric     const uint64_t SpillSize = 4; // Condition register is always 4 bytes.
20595ffd83dbSDimitry Andric     const int64_t SpillOffset =
20605ffd83dbSDimitry Andric         Subtarget.isPPC64() ? 8 : Subtarget.isAIXABI() ? 4 : -4;
20615ffd83dbSDimitry Andric     int FrameIdx =
20625ffd83dbSDimitry Andric         MFI.CreateFixedObject(SpillSize, SpillOffset,
20635ffd83dbSDimitry Andric                               /* IsImmutable */ true, /* IsAliased */ false);
20640b57cec5SDimitry Andric     FI->setCRSpillFrameIndex(FrameIdx);
20650b57cec5SDimitry Andric   }
20660b57cec5SDimitry Andric }
20670b57cec5SDimitry Andric 
20680b57cec5SDimitry Andric void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
20690b57cec5SDimitry Andric                                                        RegScavenger *RS) const {
20700b57cec5SDimitry Andric   // Get callee saved register information.
20710b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
20720b57cec5SDimitry Andric   const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
20730b57cec5SDimitry Andric 
20740b57cec5SDimitry Andric   // If the function is shrink-wrapped, and if the function has a tail call, the
20750b57cec5SDimitry Andric   // tail call might not be in the new RestoreBlock, so real branch instruction
20760b57cec5SDimitry Andric   // won't be generated by emitEpilogue(), because shrink-wrap has chosen new
20770b57cec5SDimitry Andric   // RestoreBlock. So we handle this case here.
20780b57cec5SDimitry Andric   if (MFI.getSavePoint() && MFI.hasTailCall()) {
20790b57cec5SDimitry Andric     MachineBasicBlock *RestoreBlock = MFI.getRestorePoint();
20800b57cec5SDimitry Andric     for (MachineBasicBlock &MBB : MF) {
20810b57cec5SDimitry Andric       if (MBB.isReturnBlock() && (&MBB) != RestoreBlock)
20820b57cec5SDimitry Andric         createTailCallBranchInstr(MBB);
20830b57cec5SDimitry Andric     }
20840b57cec5SDimitry Andric   }
20850b57cec5SDimitry Andric 
20860b57cec5SDimitry Andric   // Early exit if no callee saved registers are modified!
20870b57cec5SDimitry Andric   if (CSI.empty() && !needsFP(MF)) {
20880b57cec5SDimitry Andric     addScavengingSpillSlot(MF, RS);
20890b57cec5SDimitry Andric     return;
20900b57cec5SDimitry Andric   }
20910b57cec5SDimitry Andric 
20920b57cec5SDimitry Andric   unsigned MinGPR = PPC::R31;
20930b57cec5SDimitry Andric   unsigned MinG8R = PPC::X31;
20940b57cec5SDimitry Andric   unsigned MinFPR = PPC::F31;
20950b57cec5SDimitry Andric   unsigned MinVR = Subtarget.hasSPE() ? PPC::S31 : PPC::V31;
20960b57cec5SDimitry Andric 
20970b57cec5SDimitry Andric   bool HasGPSaveArea = false;
20980b57cec5SDimitry Andric   bool HasG8SaveArea = false;
20990b57cec5SDimitry Andric   bool HasFPSaveArea = false;
21000b57cec5SDimitry Andric   bool HasVRSaveArea = false;
21010b57cec5SDimitry Andric 
21020b57cec5SDimitry Andric   SmallVector<CalleeSavedInfo, 18> GPRegs;
21030b57cec5SDimitry Andric   SmallVector<CalleeSavedInfo, 18> G8Regs;
21040b57cec5SDimitry Andric   SmallVector<CalleeSavedInfo, 18> FPRegs;
21050b57cec5SDimitry Andric   SmallVector<CalleeSavedInfo, 18> VRegs;
21060b57cec5SDimitry Andric 
21074824e7fdSDimitry Andric   for (const CalleeSavedInfo &I : CSI) {
210804eeddc0SDimitry Andric     Register Reg = I.getReg();
21090b57cec5SDimitry Andric     assert((!MF.getInfo<PPCFunctionInfo>()->mustSaveTOC() ||
21100b57cec5SDimitry Andric             (Reg != PPC::X2 && Reg != PPC::R2)) &&
21110b57cec5SDimitry Andric            "Not expecting to try to spill R2 in a function that must save TOC");
21128bcb0991SDimitry Andric     if (PPC::GPRCRegClass.contains(Reg)) {
21130b57cec5SDimitry Andric       HasGPSaveArea = true;
21140b57cec5SDimitry Andric 
21154824e7fdSDimitry Andric       GPRegs.push_back(I);
21160b57cec5SDimitry Andric 
21170b57cec5SDimitry Andric       if (Reg < MinGPR) {
21180b57cec5SDimitry Andric         MinGPR = Reg;
21190b57cec5SDimitry Andric       }
21200b57cec5SDimitry Andric     } else if (PPC::G8RCRegClass.contains(Reg)) {
21210b57cec5SDimitry Andric       HasG8SaveArea = true;
21220b57cec5SDimitry Andric 
21234824e7fdSDimitry Andric       G8Regs.push_back(I);
21240b57cec5SDimitry Andric 
21250b57cec5SDimitry Andric       if (Reg < MinG8R) {
21260b57cec5SDimitry Andric         MinG8R = Reg;
21270b57cec5SDimitry Andric       }
21280b57cec5SDimitry Andric     } else if (PPC::F8RCRegClass.contains(Reg)) {
21290b57cec5SDimitry Andric       HasFPSaveArea = true;
21300b57cec5SDimitry Andric 
21314824e7fdSDimitry Andric       FPRegs.push_back(I);
21320b57cec5SDimitry Andric 
21330b57cec5SDimitry Andric       if (Reg < MinFPR) {
21340b57cec5SDimitry Andric         MinFPR = Reg;
21350b57cec5SDimitry Andric       }
21360b57cec5SDimitry Andric     } else if (PPC::CRBITRCRegClass.contains(Reg) ||
21370b57cec5SDimitry Andric                PPC::CRRCRegClass.contains(Reg)) {
21380b57cec5SDimitry Andric       ; // do nothing, as we already know whether CRs are spilled
21390b57cec5SDimitry Andric     } else if (PPC::VRRCRegClass.contains(Reg) ||
21400b57cec5SDimitry Andric                PPC::SPERCRegClass.contains(Reg)) {
21410b57cec5SDimitry Andric       // Altivec and SPE are mutually exclusive, but have the same stack
21420b57cec5SDimitry Andric       // alignment requirements, so overload the save area for both cases.
21430b57cec5SDimitry Andric       HasVRSaveArea = true;
21440b57cec5SDimitry Andric 
21454824e7fdSDimitry Andric       VRegs.push_back(I);
21460b57cec5SDimitry Andric 
21470b57cec5SDimitry Andric       if (Reg < MinVR) {
21480b57cec5SDimitry Andric         MinVR = Reg;
21490b57cec5SDimitry Andric       }
21500b57cec5SDimitry Andric     } else {
21510b57cec5SDimitry Andric       llvm_unreachable("Unknown RegisterClass!");
21520b57cec5SDimitry Andric     }
21530b57cec5SDimitry Andric   }
21540b57cec5SDimitry Andric 
21550b57cec5SDimitry Andric   PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>();
21560b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
21570b57cec5SDimitry Andric 
21580b57cec5SDimitry Andric   int64_t LowerBound = 0;
21590b57cec5SDimitry Andric 
21600b57cec5SDimitry Andric   // Take into account stack space reserved for tail calls.
21610b57cec5SDimitry Andric   int TCSPDelta = 0;
21620b57cec5SDimitry Andric   if (MF.getTarget().Options.GuaranteedTailCallOpt &&
21630b57cec5SDimitry Andric       (TCSPDelta = PFI->getTailCallSPDelta()) < 0) {
21640b57cec5SDimitry Andric     LowerBound = TCSPDelta;
21650b57cec5SDimitry Andric   }
21660b57cec5SDimitry Andric 
21670b57cec5SDimitry Andric   // The Floating-point register save area is right below the back chain word
21680b57cec5SDimitry Andric   // of the previous stack frame.
21690b57cec5SDimitry Andric   if (HasFPSaveArea) {
21700b57cec5SDimitry Andric     for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) {
21710b57cec5SDimitry Andric       int FI = FPRegs[i].getFrameIdx();
21720b57cec5SDimitry Andric 
21730b57cec5SDimitry Andric       MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
21740b57cec5SDimitry Andric     }
21750b57cec5SDimitry Andric 
21760b57cec5SDimitry Andric     LowerBound -= (31 - TRI->getEncodingValue(MinFPR) + 1) * 8;
21770b57cec5SDimitry Andric   }
21780b57cec5SDimitry Andric 
21790b57cec5SDimitry Andric   // Check whether the frame pointer register is allocated. If so, make sure it
21800b57cec5SDimitry Andric   // is spilled to the correct offset.
21810b57cec5SDimitry Andric   if (needsFP(MF)) {
21820b57cec5SDimitry Andric     int FI = PFI->getFramePointerSaveIndex();
21830b57cec5SDimitry Andric     assert(FI && "No Frame Pointer Save Slot!");
21840b57cec5SDimitry Andric     MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
21850b57cec5SDimitry Andric     // FP is R31/X31, so no need to update MinGPR/MinG8R.
21860b57cec5SDimitry Andric     HasGPSaveArea = true;
21870b57cec5SDimitry Andric   }
21880b57cec5SDimitry Andric 
21890b57cec5SDimitry Andric   if (PFI->usesPICBase()) {
21900b57cec5SDimitry Andric     int FI = PFI->getPICBasePointerSaveIndex();
21910b57cec5SDimitry Andric     assert(FI && "No PIC Base Pointer Save Slot!");
21920b57cec5SDimitry Andric     MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
21930b57cec5SDimitry Andric 
21940b57cec5SDimitry Andric     MinGPR = std::min<unsigned>(MinGPR, PPC::R30);
21950b57cec5SDimitry Andric     HasGPSaveArea = true;
21960b57cec5SDimitry Andric   }
21970b57cec5SDimitry Andric 
21980b57cec5SDimitry Andric   const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
21990b57cec5SDimitry Andric   if (RegInfo->hasBasePointer(MF)) {
22000b57cec5SDimitry Andric     int FI = PFI->getBasePointerSaveIndex();
22010b57cec5SDimitry Andric     assert(FI && "No Base Pointer Save Slot!");
22020b57cec5SDimitry Andric     MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
22030b57cec5SDimitry Andric 
22048bcb0991SDimitry Andric     Register BP = RegInfo->getBaseRegister(MF);
22050b57cec5SDimitry Andric     if (PPC::G8RCRegClass.contains(BP)) {
22060b57cec5SDimitry Andric       MinG8R = std::min<unsigned>(MinG8R, BP);
22070b57cec5SDimitry Andric       HasG8SaveArea = true;
22080b57cec5SDimitry Andric     } else if (PPC::GPRCRegClass.contains(BP)) {
22090b57cec5SDimitry Andric       MinGPR = std::min<unsigned>(MinGPR, BP);
22100b57cec5SDimitry Andric       HasGPSaveArea = true;
22110b57cec5SDimitry Andric     }
22120b57cec5SDimitry Andric   }
22130b57cec5SDimitry Andric 
22140b57cec5SDimitry Andric   // General register save area starts right below the Floating-point
22150b57cec5SDimitry Andric   // register save area.
22160b57cec5SDimitry Andric   if (HasGPSaveArea || HasG8SaveArea) {
22170b57cec5SDimitry Andric     // Move general register save area spill slots down, taking into account
22180b57cec5SDimitry Andric     // the size of the Floating-point register save area.
22190b57cec5SDimitry Andric     for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) {
22200b57cec5SDimitry Andric       if (!GPRegs[i].isSpilledToReg()) {
22210b57cec5SDimitry Andric         int FI = GPRegs[i].getFrameIdx();
22220b57cec5SDimitry Andric         MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
22230b57cec5SDimitry Andric       }
22240b57cec5SDimitry Andric     }
22250b57cec5SDimitry Andric 
22260b57cec5SDimitry Andric     // Move general register save area spill slots down, taking into account
22270b57cec5SDimitry Andric     // the size of the Floating-point register save area.
22280b57cec5SDimitry Andric     for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) {
22290b57cec5SDimitry Andric       if (!G8Regs[i].isSpilledToReg()) {
22300b57cec5SDimitry Andric         int FI = G8Regs[i].getFrameIdx();
22310b57cec5SDimitry Andric         MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
22320b57cec5SDimitry Andric       }
22330b57cec5SDimitry Andric     }
22340b57cec5SDimitry Andric 
22350b57cec5SDimitry Andric     unsigned MinReg =
22360b57cec5SDimitry Andric       std::min<unsigned>(TRI->getEncodingValue(MinGPR),
22370b57cec5SDimitry Andric                          TRI->getEncodingValue(MinG8R));
22380b57cec5SDimitry Andric 
22395ffd83dbSDimitry Andric     const unsigned GPRegSize = Subtarget.isPPC64() ? 8 : 4;
22405ffd83dbSDimitry Andric     LowerBound -= (31 - MinReg + 1) * GPRegSize;
22410b57cec5SDimitry Andric   }
22420b57cec5SDimitry Andric 
22430b57cec5SDimitry Andric   // For 32-bit only, the CR save area is below the general register
22440b57cec5SDimitry Andric   // save area.  For 64-bit SVR4, the CR save area is addressed relative
22450b57cec5SDimitry Andric   // to the stack pointer and hence does not need an adjustment here.
22460b57cec5SDimitry Andric   // Only CR2 (the first nonvolatile spilled) has an associated frame
22470b57cec5SDimitry Andric   // index so that we have a single uniform save area.
22485ffd83dbSDimitry Andric   if (spillsCR(MF) && Subtarget.is32BitELFABI()) {
22490b57cec5SDimitry Andric     // Adjust the frame index of the CR spill slot.
22505ffd83dbSDimitry Andric     for (const auto &CSInfo : CSI) {
22515ffd83dbSDimitry Andric       if (CSInfo.getReg() == PPC::CR2) {
22525ffd83dbSDimitry Andric         int FI = CSInfo.getFrameIdx();
22530b57cec5SDimitry Andric         MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
22545ffd83dbSDimitry Andric         break;
22550b57cec5SDimitry Andric       }
22560b57cec5SDimitry Andric     }
22570b57cec5SDimitry Andric 
22580b57cec5SDimitry Andric     LowerBound -= 4; // The CR save area is always 4 bytes long.
22590b57cec5SDimitry Andric   }
22600b57cec5SDimitry Andric 
22610b57cec5SDimitry Andric   // Both Altivec and SPE have the same alignment and padding requirements
22620b57cec5SDimitry Andric   // within the stack frame.
22630b57cec5SDimitry Andric   if (HasVRSaveArea) {
22640b57cec5SDimitry Andric     // Insert alignment padding, we need 16-byte alignment. Note: for positive
22650b57cec5SDimitry Andric     // number the alignment formula is : y = (x + (n-1)) & (~(n-1)). But since
22660b57cec5SDimitry Andric     // we are using negative number here (the stack grows downward). We should
22670b57cec5SDimitry Andric     // use formula : y = x & (~(n-1)). Where x is the size before aligning, n
22680b57cec5SDimitry Andric     // is the alignment size ( n = 16 here) and y is the size after aligning.
22690b57cec5SDimitry Andric     assert(LowerBound <= 0 && "Expect LowerBound have a non-positive value!");
22700b57cec5SDimitry Andric     LowerBound &= ~(15);
22710b57cec5SDimitry Andric 
22720b57cec5SDimitry Andric     for (unsigned i = 0, e = VRegs.size(); i != e; ++i) {
22730b57cec5SDimitry Andric       int FI = VRegs[i].getFrameIdx();
22740b57cec5SDimitry Andric 
22750b57cec5SDimitry Andric       MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
22760b57cec5SDimitry Andric     }
22770b57cec5SDimitry Andric   }
22780b57cec5SDimitry Andric 
22790b57cec5SDimitry Andric   addScavengingSpillSlot(MF, RS);
22800b57cec5SDimitry Andric }
22810b57cec5SDimitry Andric 
22820b57cec5SDimitry Andric void
22830b57cec5SDimitry Andric PPCFrameLowering::addScavengingSpillSlot(MachineFunction &MF,
22840b57cec5SDimitry Andric                                          RegScavenger *RS) const {
22850b57cec5SDimitry Andric   // Reserve a slot closest to SP or frame pointer if we have a dynalloc or
22860b57cec5SDimitry Andric   // a large stack, which will require scavenging a register to materialize a
22870b57cec5SDimitry Andric   // large offset.
22880b57cec5SDimitry Andric 
22890b57cec5SDimitry Andric   // We need to have a scavenger spill slot for spills if the frame size is
22900b57cec5SDimitry Andric   // large. In case there is no free register for large-offset addressing,
22910b57cec5SDimitry Andric   // this slot is used for the necessary emergency spill. Also, we need the
22920b57cec5SDimitry Andric   // slot for dynamic stack allocations.
22930b57cec5SDimitry Andric 
22940b57cec5SDimitry Andric   // The scavenger might be invoked if the frame offset does not fit into
229506c3fb27SDimitry Andric   // the 16-bit immediate in case of not SPE and 8-bit in case of SPE.
229606c3fb27SDimitry Andric   // We don't know the complete frame size here because we've not yet computed
229706c3fb27SDimitry Andric   // callee-saved register spills or the needed alignment padding.
22980b57cec5SDimitry Andric   unsigned StackSize = determineFrameLayout(MF, true);
22990b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
230006c3fb27SDimitry Andric   bool NeedSpills = Subtarget.hasSPE() ? !isInt<8>(StackSize) : !isInt<16>(StackSize);
230106c3fb27SDimitry Andric 
2302e8d8bef9SDimitry Andric   if (MFI.hasVarSizedObjects() || spillsCR(MF) || hasNonRISpills(MF) ||
230306c3fb27SDimitry Andric       (hasSpills(MF) && NeedSpills)) {
23040b57cec5SDimitry Andric     const TargetRegisterClass &GPRC = PPC::GPRCRegClass;
23050b57cec5SDimitry Andric     const TargetRegisterClass &G8RC = PPC::G8RCRegClass;
23060b57cec5SDimitry Andric     const TargetRegisterClass &RC = Subtarget.isPPC64() ? G8RC : GPRC;
23070b57cec5SDimitry Andric     const TargetRegisterInfo &TRI = *Subtarget.getRegisterInfo();
23080b57cec5SDimitry Andric     unsigned Size = TRI.getSpillSize(RC);
23095ffd83dbSDimitry Andric     Align Alignment = TRI.getSpillAlign(RC);
23105ffd83dbSDimitry Andric     RS->addScavengingFrameIndex(MFI.CreateStackObject(Size, Alignment, false));
23110b57cec5SDimitry Andric 
23120b57cec5SDimitry Andric     // Might we have over-aligned allocas?
23135ffd83dbSDimitry Andric     bool HasAlVars =
23145ffd83dbSDimitry Andric         MFI.hasVarSizedObjects() && MFI.getMaxAlign() > getStackAlign();
23150b57cec5SDimitry Andric 
23160b57cec5SDimitry Andric     // These kinds of spills might need two registers.
2317e8d8bef9SDimitry Andric     if (spillsCR(MF) || HasAlVars)
23185ffd83dbSDimitry Andric       RS->addScavengingFrameIndex(
23195ffd83dbSDimitry Andric           MFI.CreateStackObject(Size, Alignment, false));
23200b57cec5SDimitry Andric   }
23210b57cec5SDimitry Andric }
23220b57cec5SDimitry Andric 
23230b57cec5SDimitry Andric // This function checks if a callee saved gpr can be spilled to a volatile
23240b57cec5SDimitry Andric // vector register. This occurs for leaf functions when the option
23250b57cec5SDimitry Andric // ppc-enable-pe-vector-spills is enabled. If there are any remaining registers
23260b57cec5SDimitry Andric // which were not spilled to vectors, return false so the target independent
23270b57cec5SDimitry Andric // code can handle them by assigning a FrameIdx to a stack slot.
23280b57cec5SDimitry Andric bool PPCFrameLowering::assignCalleeSavedSpillSlots(
23290b57cec5SDimitry Andric     MachineFunction &MF, const TargetRegisterInfo *TRI,
23300b57cec5SDimitry Andric     std::vector<CalleeSavedInfo> &CSI) const {
23310b57cec5SDimitry Andric 
23320b57cec5SDimitry Andric   if (CSI.empty())
23330b57cec5SDimitry Andric     return true; // Early exit if no callee saved registers are modified!
23340b57cec5SDimitry Andric 
233506c3fb27SDimitry Andric   const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
233606c3fb27SDimitry Andric   const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
233706c3fb27SDimitry Andric   const MachineRegisterInfo &MRI = MF.getRegInfo();
233806c3fb27SDimitry Andric 
233906c3fb27SDimitry Andric   if (Subtarget.hasSPE()) {
234006c3fb27SDimitry Andric     // In case of SPE we only have SuperRegs and CRs
234106c3fb27SDimitry Andric     // in our CalleSaveInfo vector.
234206c3fb27SDimitry Andric 
234306c3fb27SDimitry Andric     for (auto &CalleeSaveReg : CSI) {
23445f757f3fSDimitry Andric       MCPhysReg Reg = CalleeSaveReg.getReg();
23455f757f3fSDimitry Andric       MCPhysReg Lower = RegInfo->getSubReg(Reg, 1);
23465f757f3fSDimitry Andric       MCPhysReg Higher = RegInfo->getSubReg(Reg, 2);
234706c3fb27SDimitry Andric 
23485f757f3fSDimitry Andric       if ( // Check only for SuperRegs.
23495f757f3fSDimitry Andric           Lower &&
235006c3fb27SDimitry Andric           // Replace Reg if only lower-32 bits modified
23515f757f3fSDimitry Andric           !MRI.isPhysRegModified(Higher))
23525f757f3fSDimitry Andric         CalleeSaveReg = CalleeSavedInfo(Lower);
235306c3fb27SDimitry Andric     }
235406c3fb27SDimitry Andric   }
235506c3fb27SDimitry Andric 
23560b57cec5SDimitry Andric   // Early exit if cannot spill gprs to volatile vector registers.
23570b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
23580b57cec5SDimitry Andric   if (!EnablePEVectorSpills || MFI.hasCalls() || !Subtarget.hasP9Vector())
23590b57cec5SDimitry Andric     return false;
23600b57cec5SDimitry Andric 
23610b57cec5SDimitry Andric   // Build a BitVector of VSRs that can be used for spilling GPRs.
23620b57cec5SDimitry Andric   BitVector BVAllocatable = TRI->getAllocatableSet(MF);
23630b57cec5SDimitry Andric   BitVector BVCalleeSaved(TRI->getNumRegs());
23640b57cec5SDimitry Andric   for (unsigned i = 0; CSRegs[i]; ++i)
23650b57cec5SDimitry Andric     BVCalleeSaved.set(CSRegs[i]);
23660b57cec5SDimitry Andric 
23670b57cec5SDimitry Andric   for (unsigned Reg : BVAllocatable.set_bits()) {
2368fe6060f1SDimitry Andric     // Set to 0 if the register is not a volatile VSX register, or if it is
23690b57cec5SDimitry Andric     // used in the function.
2370fe6060f1SDimitry Andric     if (BVCalleeSaved[Reg] || !PPC::VSRCRegClass.contains(Reg) ||
237106c3fb27SDimitry Andric         MRI.isPhysRegUsed(Reg))
23720b57cec5SDimitry Andric       BVAllocatable.reset(Reg);
23730b57cec5SDimitry Andric   }
23740b57cec5SDimitry Andric 
23750b57cec5SDimitry Andric   bool AllSpilledToReg = true;
2376fe6060f1SDimitry Andric   unsigned LastVSRUsedForSpill = 0;
23770b57cec5SDimitry Andric   for (auto &CS : CSI) {
23780b57cec5SDimitry Andric     if (BVAllocatable.none())
23790b57cec5SDimitry Andric       return false;
23800b57cec5SDimitry Andric 
238104eeddc0SDimitry Andric     Register Reg = CS.getReg();
2382fe6060f1SDimitry Andric 
2383fe6060f1SDimitry Andric     if (!PPC::G8RCRegClass.contains(Reg)) {
23840b57cec5SDimitry Andric       AllSpilledToReg = false;
23850b57cec5SDimitry Andric       continue;
23860b57cec5SDimitry Andric     }
23870b57cec5SDimitry Andric 
2388fe6060f1SDimitry Andric     // For P9, we can reuse LastVSRUsedForSpill to spill two GPRs
2389fe6060f1SDimitry Andric     // into one VSR using the mtvsrdd instruction.
2390fe6060f1SDimitry Andric     if (LastVSRUsedForSpill != 0) {
2391fe6060f1SDimitry Andric       CS.setDstReg(LastVSRUsedForSpill);
2392fe6060f1SDimitry Andric       BVAllocatable.reset(LastVSRUsedForSpill);
2393fe6060f1SDimitry Andric       LastVSRUsedForSpill = 0;
2394fe6060f1SDimitry Andric       continue;
2395fe6060f1SDimitry Andric     }
2396fe6060f1SDimitry Andric 
23970b57cec5SDimitry Andric     unsigned VolatileVFReg = BVAllocatable.find_first();
23980b57cec5SDimitry Andric     if (VolatileVFReg < BVAllocatable.size()) {
23990b57cec5SDimitry Andric       CS.setDstReg(VolatileVFReg);
2400fe6060f1SDimitry Andric       LastVSRUsedForSpill = VolatileVFReg;
24010b57cec5SDimitry Andric     } else {
24020b57cec5SDimitry Andric       AllSpilledToReg = false;
24030b57cec5SDimitry Andric     }
24040b57cec5SDimitry Andric   }
24050b57cec5SDimitry Andric   return AllSpilledToReg;
24060b57cec5SDimitry Andric }
24070b57cec5SDimitry Andric 
24085ffd83dbSDimitry Andric bool PPCFrameLowering::spillCalleeSavedRegisters(
24095ffd83dbSDimitry Andric     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
24105ffd83dbSDimitry Andric     ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
24110b57cec5SDimitry Andric 
24120b57cec5SDimitry Andric   MachineFunction *MF = MBB.getParent();
24130b57cec5SDimitry Andric   const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
24140b57cec5SDimitry Andric   PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
24150b57cec5SDimitry Andric   bool MustSaveTOC = FI->mustSaveTOC();
24160b57cec5SDimitry Andric   DebugLoc DL;
24170b57cec5SDimitry Andric   bool CRSpilled = false;
24180b57cec5SDimitry Andric   MachineInstrBuilder CRMIB;
2419fe6060f1SDimitry Andric   BitVector Spilled(TRI->getNumRegs());
2420fe6060f1SDimitry Andric 
2421fe6060f1SDimitry Andric   VSRContainingGPRs.clear();
2422fe6060f1SDimitry Andric 
2423fe6060f1SDimitry Andric   // Map each VSR to GPRs to be spilled with into it. Single VSR can contain one
2424fe6060f1SDimitry Andric   // or two GPRs, so we need table to record information for later save/restore.
242581ad6265SDimitry Andric   for (const CalleeSavedInfo &Info : CSI) {
2426fe6060f1SDimitry Andric     if (Info.isSpilledToReg()) {
2427fe6060f1SDimitry Andric       auto &SpilledVSR =
2428fe6060f1SDimitry Andric           VSRContainingGPRs.FindAndConstruct(Info.getDstReg()).second;
2429fe6060f1SDimitry Andric       assert(SpilledVSR.second == 0 &&
2430fe6060f1SDimitry Andric              "Can't spill more than two GPRs into VSR!");
2431fe6060f1SDimitry Andric       if (SpilledVSR.first == 0)
2432fe6060f1SDimitry Andric         SpilledVSR.first = Info.getReg();
2433fe6060f1SDimitry Andric       else
2434fe6060f1SDimitry Andric         SpilledVSR.second = Info.getReg();
2435fe6060f1SDimitry Andric     }
243681ad6265SDimitry Andric   }
24370b57cec5SDimitry Andric 
24384824e7fdSDimitry Andric   for (const CalleeSavedInfo &I : CSI) {
243904eeddc0SDimitry Andric     Register Reg = I.getReg();
24400b57cec5SDimitry Andric 
24410b57cec5SDimitry Andric     // CR2 through CR4 are the nonvolatile CR fields.
24420b57cec5SDimitry Andric     bool IsCRField = PPC::CR2 <= Reg && Reg <= PPC::CR4;
24430b57cec5SDimitry Andric 
24440b57cec5SDimitry Andric     // Add the callee-saved register as live-in; it's killed at the spill.
24450b57cec5SDimitry Andric     // Do not do this for callee-saved registers that are live-in to the
24460b57cec5SDimitry Andric     // function because they will already be marked live-in and this will be
24470b57cec5SDimitry Andric     // adding it for a second time. It is an error to add the same register
24480b57cec5SDimitry Andric     // to the set more than once.
24490b57cec5SDimitry Andric     const MachineRegisterInfo &MRI = MF->getRegInfo();
24500b57cec5SDimitry Andric     bool IsLiveIn = MRI.isLiveIn(Reg);
24510b57cec5SDimitry Andric     if (!IsLiveIn)
24520b57cec5SDimitry Andric        MBB.addLiveIn(Reg);
24530b57cec5SDimitry Andric 
24540b57cec5SDimitry Andric     if (CRSpilled && IsCRField) {
24550b57cec5SDimitry Andric       CRMIB.addReg(Reg, RegState::ImplicitKill);
24560b57cec5SDimitry Andric       continue;
24570b57cec5SDimitry Andric     }
24580b57cec5SDimitry Andric 
24590b57cec5SDimitry Andric     // The actual spill will happen in the prologue.
24600b57cec5SDimitry Andric     if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)
24610b57cec5SDimitry Andric       continue;
24620b57cec5SDimitry Andric 
24630b57cec5SDimitry Andric     // Insert the spill to the stack frame.
24640b57cec5SDimitry Andric     if (IsCRField) {
24650b57cec5SDimitry Andric       PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
24665ffd83dbSDimitry Andric       if (!Subtarget.is32BitELFABI()) {
24670b57cec5SDimitry Andric         // The actual spill will happen at the start of the prologue.
24680b57cec5SDimitry Andric         FuncInfo->addMustSaveCR(Reg);
24690b57cec5SDimitry Andric       } else {
24700b57cec5SDimitry Andric         CRSpilled = true;
24710b57cec5SDimitry Andric         FuncInfo->setSpillsCR();
24720b57cec5SDimitry Andric 
24730b57cec5SDimitry Andric         // 32-bit:  FP-relative.  Note that we made sure CR2-CR4 all have
24740b57cec5SDimitry Andric         // the same frame index in PPCRegisterInfo::hasReservedSpillSlot.
24750b57cec5SDimitry Andric         CRMIB = BuildMI(*MF, DL, TII.get(PPC::MFCR), PPC::R12)
24760b57cec5SDimitry Andric                   .addReg(Reg, RegState::ImplicitKill);
24770b57cec5SDimitry Andric 
24780b57cec5SDimitry Andric         MBB.insert(MI, CRMIB);
24790b57cec5SDimitry Andric         MBB.insert(MI, addFrameReference(BuildMI(*MF, DL, TII.get(PPC::STW))
24800b57cec5SDimitry Andric                                          .addReg(PPC::R12,
24810b57cec5SDimitry Andric                                                  getKillRegState(true)),
24824824e7fdSDimitry Andric                                          I.getFrameIdx()));
24830b57cec5SDimitry Andric       }
24840b57cec5SDimitry Andric     } else {
24854824e7fdSDimitry Andric       if (I.isSpilledToReg()) {
24864824e7fdSDimitry Andric         unsigned Dst = I.getDstReg();
2487fe6060f1SDimitry Andric 
2488fe6060f1SDimitry Andric         if (Spilled[Dst])
2489fe6060f1SDimitry Andric           continue;
2490fe6060f1SDimitry Andric 
2491fe6060f1SDimitry Andric         if (VSRContainingGPRs[Dst].second != 0) {
2492fe6060f1SDimitry Andric           assert(Subtarget.hasP9Vector() &&
2493fe6060f1SDimitry Andric                  "mtvsrdd is unavailable on pre-P9 targets.");
2494fe6060f1SDimitry Andric 
2495fe6060f1SDimitry Andric           NumPESpillVSR += 2;
2496fe6060f1SDimitry Andric           BuildMI(MBB, MI, DL, TII.get(PPC::MTVSRDD), Dst)
2497fe6060f1SDimitry Andric               .addReg(VSRContainingGPRs[Dst].first, getKillRegState(true))
2498fe6060f1SDimitry Andric               .addReg(VSRContainingGPRs[Dst].second, getKillRegState(true));
2499fe6060f1SDimitry Andric         } else if (VSRContainingGPRs[Dst].second == 0) {
2500fe6060f1SDimitry Andric           assert(Subtarget.hasP8Vector() &&
2501fe6060f1SDimitry Andric                  "Can't move GPR to VSR on pre-P8 targets.");
2502fe6060f1SDimitry Andric 
2503fe6060f1SDimitry Andric           ++NumPESpillVSR;
2504fe6060f1SDimitry Andric           BuildMI(MBB, MI, DL, TII.get(PPC::MTVSRD),
2505fe6060f1SDimitry Andric                   TRI->getSubReg(Dst, PPC::sub_64))
2506fe6060f1SDimitry Andric               .addReg(VSRContainingGPRs[Dst].first, getKillRegState(true));
2507fe6060f1SDimitry Andric         } else {
2508fe6060f1SDimitry Andric           llvm_unreachable("More than two GPRs spilled to a VSR!");
2509fe6060f1SDimitry Andric         }
2510fe6060f1SDimitry Andric         Spilled.set(Dst);
25110b57cec5SDimitry Andric       } else {
25120b57cec5SDimitry Andric         const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
25130b57cec5SDimitry Andric         // Use !IsLiveIn for the kill flag.
25140b57cec5SDimitry Andric         // We do not want to kill registers that are live in this function
25150b57cec5SDimitry Andric         // before their use because they will become undefined registers.
25165ffd83dbSDimitry Andric         // Functions without NoUnwind need to preserve the order of elements in
25175ffd83dbSDimitry Andric         // saved vector registers.
25185ffd83dbSDimitry Andric         if (Subtarget.needsSwapsForVSXMemOps() &&
25195ffd83dbSDimitry Andric             !MF->getFunction().hasFnAttribute(Attribute::NoUnwind))
25205ffd83dbSDimitry Andric           TII.storeRegToStackSlotNoUpd(MBB, MI, Reg, !IsLiveIn,
25214824e7fdSDimitry Andric                                        I.getFrameIdx(), RC, TRI);
25225ffd83dbSDimitry Andric         else
2523bdd1243dSDimitry Andric           TII.storeRegToStackSlot(MBB, MI, Reg, !IsLiveIn, I.getFrameIdx(), RC,
2524bdd1243dSDimitry Andric                                   TRI, Register());
25250b57cec5SDimitry Andric       }
25260b57cec5SDimitry Andric     }
25270b57cec5SDimitry Andric   }
25280b57cec5SDimitry Andric   return true;
25290b57cec5SDimitry Andric }
25300b57cec5SDimitry Andric 
25315ffd83dbSDimitry Andric static void restoreCRs(bool is31, bool CR2Spilled, bool CR3Spilled,
25325ffd83dbSDimitry Andric                        bool CR4Spilled, MachineBasicBlock &MBB,
25335ffd83dbSDimitry Andric                        MachineBasicBlock::iterator MI,
25345ffd83dbSDimitry Andric                        ArrayRef<CalleeSavedInfo> CSI, unsigned CSIIndex) {
25350b57cec5SDimitry Andric 
25360b57cec5SDimitry Andric   MachineFunction *MF = MBB.getParent();
25370b57cec5SDimitry Andric   const PPCInstrInfo &TII = *MF->getSubtarget<PPCSubtarget>().getInstrInfo();
25380b57cec5SDimitry Andric   DebugLoc DL;
25395ffd83dbSDimitry Andric   unsigned MoveReg = PPC::R12;
25400b57cec5SDimitry Andric 
25410b57cec5SDimitry Andric   // 32-bit:  FP-relative
25425ffd83dbSDimitry Andric   MBB.insert(MI,
25435ffd83dbSDimitry Andric              addFrameReference(BuildMI(*MF, DL, TII.get(PPC::LWZ), MoveReg),
25440b57cec5SDimitry Andric                                CSI[CSIIndex].getFrameIdx()));
25450b57cec5SDimitry Andric 
25465ffd83dbSDimitry Andric   unsigned RestoreOp = PPC::MTOCRF;
25470b57cec5SDimitry Andric   if (CR2Spilled)
25480b57cec5SDimitry Andric     MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR2)
25490b57cec5SDimitry Andric                .addReg(MoveReg, getKillRegState(!CR3Spilled && !CR4Spilled)));
25500b57cec5SDimitry Andric 
25510b57cec5SDimitry Andric   if (CR3Spilled)
25520b57cec5SDimitry Andric     MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR3)
25530b57cec5SDimitry Andric                .addReg(MoveReg, getKillRegState(!CR4Spilled)));
25540b57cec5SDimitry Andric 
25550b57cec5SDimitry Andric   if (CR4Spilled)
25560b57cec5SDimitry Andric     MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR4)
25570b57cec5SDimitry Andric                .addReg(MoveReg, getKillRegState(true)));
25580b57cec5SDimitry Andric }
25590b57cec5SDimitry Andric 
25600b57cec5SDimitry Andric MachineBasicBlock::iterator PPCFrameLowering::
25610b57cec5SDimitry Andric eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
25620b57cec5SDimitry Andric                               MachineBasicBlock::iterator I) const {
25630b57cec5SDimitry Andric   const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
25640b57cec5SDimitry Andric   if (MF.getTarget().Options.GuaranteedTailCallOpt &&
25650b57cec5SDimitry Andric       I->getOpcode() == PPC::ADJCALLSTACKUP) {
25660b57cec5SDimitry Andric     // Add (actually subtract) back the amount the callee popped on return.
25670b57cec5SDimitry Andric     if (int CalleeAmt =  I->getOperand(1).getImm()) {
25680b57cec5SDimitry Andric       bool is64Bit = Subtarget.isPPC64();
25690b57cec5SDimitry Andric       CalleeAmt *= -1;
25700b57cec5SDimitry Andric       unsigned StackReg = is64Bit ? PPC::X1 : PPC::R1;
25710b57cec5SDimitry Andric       unsigned TmpReg = is64Bit ? PPC::X0 : PPC::R0;
25720b57cec5SDimitry Andric       unsigned ADDIInstr = is64Bit ? PPC::ADDI8 : PPC::ADDI;
25730b57cec5SDimitry Andric       unsigned ADDInstr = is64Bit ? PPC::ADD8 : PPC::ADD4;
25740b57cec5SDimitry Andric       unsigned LISInstr = is64Bit ? PPC::LIS8 : PPC::LIS;
25750b57cec5SDimitry Andric       unsigned ORIInstr = is64Bit ? PPC::ORI8 : PPC::ORI;
25760b57cec5SDimitry Andric       const DebugLoc &dl = I->getDebugLoc();
25770b57cec5SDimitry Andric 
25780b57cec5SDimitry Andric       if (isInt<16>(CalleeAmt)) {
25790b57cec5SDimitry Andric         BuildMI(MBB, I, dl, TII.get(ADDIInstr), StackReg)
25800b57cec5SDimitry Andric           .addReg(StackReg, RegState::Kill)
25810b57cec5SDimitry Andric           .addImm(CalleeAmt);
25820b57cec5SDimitry Andric       } else {
25830b57cec5SDimitry Andric         MachineBasicBlock::iterator MBBI = I;
25840b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, TII.get(LISInstr), TmpReg)
25850b57cec5SDimitry Andric           .addImm(CalleeAmt >> 16);
25860b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, TII.get(ORIInstr), TmpReg)
25870b57cec5SDimitry Andric           .addReg(TmpReg, RegState::Kill)
25880b57cec5SDimitry Andric           .addImm(CalleeAmt & 0xFFFF);
25890b57cec5SDimitry Andric         BuildMI(MBB, MBBI, dl, TII.get(ADDInstr), StackReg)
25900b57cec5SDimitry Andric           .addReg(StackReg, RegState::Kill)
25910b57cec5SDimitry Andric           .addReg(TmpReg);
25920b57cec5SDimitry Andric       }
25930b57cec5SDimitry Andric     }
25940b57cec5SDimitry Andric   }
25950b57cec5SDimitry Andric   // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
25960b57cec5SDimitry Andric   return MBB.erase(I);
25970b57cec5SDimitry Andric }
25980b57cec5SDimitry Andric 
25995ffd83dbSDimitry Andric static bool isCalleeSavedCR(unsigned Reg) {
26005ffd83dbSDimitry Andric   return PPC::CR2 == Reg || Reg == PPC::CR3 || Reg == PPC::CR4;
26015ffd83dbSDimitry Andric }
26020b57cec5SDimitry Andric 
26035ffd83dbSDimitry Andric bool PPCFrameLowering::restoreCalleeSavedRegisters(
26045ffd83dbSDimitry Andric     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
26055ffd83dbSDimitry Andric     MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
26060b57cec5SDimitry Andric   MachineFunction *MF = MBB.getParent();
26070b57cec5SDimitry Andric   const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
26080b57cec5SDimitry Andric   PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
26090b57cec5SDimitry Andric   bool MustSaveTOC = FI->mustSaveTOC();
26100b57cec5SDimitry Andric   bool CR2Spilled = false;
26110b57cec5SDimitry Andric   bool CR3Spilled = false;
26120b57cec5SDimitry Andric   bool CR4Spilled = false;
26130b57cec5SDimitry Andric   unsigned CSIIndex = 0;
2614fe6060f1SDimitry Andric   BitVector Restored(TRI->getNumRegs());
26150b57cec5SDimitry Andric 
26160b57cec5SDimitry Andric   // Initialize insertion-point logic; we will be restoring in reverse
26170b57cec5SDimitry Andric   // order of spill.
26180b57cec5SDimitry Andric   MachineBasicBlock::iterator I = MI, BeforeI = I;
26190b57cec5SDimitry Andric   bool AtStart = I == MBB.begin();
26200b57cec5SDimitry Andric 
26210b57cec5SDimitry Andric   if (!AtStart)
26220b57cec5SDimitry Andric     --BeforeI;
26230b57cec5SDimitry Andric 
26240b57cec5SDimitry Andric   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
262504eeddc0SDimitry Andric     Register Reg = CSI[i].getReg();
26260b57cec5SDimitry Andric 
26270b57cec5SDimitry Andric     if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)
26280b57cec5SDimitry Andric       continue;
26290b57cec5SDimitry Andric 
26305ffd83dbSDimitry Andric     // Restore of callee saved condition register field is handled during
26315ffd83dbSDimitry Andric     // epilogue insertion.
26325ffd83dbSDimitry Andric     if (isCalleeSavedCR(Reg) && !Subtarget.is32BitELFABI())
26335ffd83dbSDimitry Andric       continue;
26345ffd83dbSDimitry Andric 
26350b57cec5SDimitry Andric     if (Reg == PPC::CR2) {
26360b57cec5SDimitry Andric       CR2Spilled = true;
26370b57cec5SDimitry Andric       // The spill slot is associated only with CR2, which is the
26380b57cec5SDimitry Andric       // first nonvolatile spilled.  Save it here.
26390b57cec5SDimitry Andric       CSIIndex = i;
26400b57cec5SDimitry Andric       continue;
26410b57cec5SDimitry Andric     } else if (Reg == PPC::CR3) {
26420b57cec5SDimitry Andric       CR3Spilled = true;
26430b57cec5SDimitry Andric       continue;
26440b57cec5SDimitry Andric     } else if (Reg == PPC::CR4) {
26450b57cec5SDimitry Andric       CR4Spilled = true;
26460b57cec5SDimitry Andric       continue;
26470b57cec5SDimitry Andric     } else {
26485ffd83dbSDimitry Andric       // On 32-bit ELF when we first encounter a non-CR register after seeing at
26490b57cec5SDimitry Andric       // least one CR register, restore all spilled CRs together.
26505ffd83dbSDimitry Andric       if (CR2Spilled || CR3Spilled || CR4Spilled) {
26510b57cec5SDimitry Andric         bool is31 = needsFP(*MF);
26525ffd83dbSDimitry Andric         restoreCRs(is31, CR2Spilled, CR3Spilled, CR4Spilled, MBB, I, CSI,
26535ffd83dbSDimitry Andric                    CSIIndex);
26540b57cec5SDimitry Andric         CR2Spilled = CR3Spilled = CR4Spilled = false;
26550b57cec5SDimitry Andric       }
26560b57cec5SDimitry Andric 
26570b57cec5SDimitry Andric       if (CSI[i].isSpilledToReg()) {
26580b57cec5SDimitry Andric         DebugLoc DL;
2659fe6060f1SDimitry Andric         unsigned Dst = CSI[i].getDstReg();
2660fe6060f1SDimitry Andric 
2661fe6060f1SDimitry Andric         if (Restored[Dst])
2662fe6060f1SDimitry Andric           continue;
2663fe6060f1SDimitry Andric 
2664fe6060f1SDimitry Andric         if (VSRContainingGPRs[Dst].second != 0) {
2665fe6060f1SDimitry Andric           assert(Subtarget.hasP9Vector());
2666fe6060f1SDimitry Andric           NumPEReloadVSR += 2;
2667fe6060f1SDimitry Andric           BuildMI(MBB, I, DL, TII.get(PPC::MFVSRLD),
2668fe6060f1SDimitry Andric                   VSRContainingGPRs[Dst].second)
2669fe6060f1SDimitry Andric               .addReg(Dst);
2670fe6060f1SDimitry Andric           BuildMI(MBB, I, DL, TII.get(PPC::MFVSRD),
2671fe6060f1SDimitry Andric                   VSRContainingGPRs[Dst].first)
2672fe6060f1SDimitry Andric               .addReg(TRI->getSubReg(Dst, PPC::sub_64), getKillRegState(true));
2673fe6060f1SDimitry Andric         } else if (VSRContainingGPRs[Dst].second == 0) {
2674fe6060f1SDimitry Andric           assert(Subtarget.hasP8Vector());
2675fe6060f1SDimitry Andric           ++NumPEReloadVSR;
2676fe6060f1SDimitry Andric           BuildMI(MBB, I, DL, TII.get(PPC::MFVSRD),
2677fe6060f1SDimitry Andric                   VSRContainingGPRs[Dst].first)
2678fe6060f1SDimitry Andric               .addReg(TRI->getSubReg(Dst, PPC::sub_64), getKillRegState(true));
2679fe6060f1SDimitry Andric         } else {
2680fe6060f1SDimitry Andric           llvm_unreachable("More than two GPRs spilled to a VSR!");
2681fe6060f1SDimitry Andric         }
2682fe6060f1SDimitry Andric 
2683fe6060f1SDimitry Andric         Restored.set(Dst);
2684fe6060f1SDimitry Andric 
26850b57cec5SDimitry Andric       } else {
26860b57cec5SDimitry Andric         // Default behavior for non-CR saves.
26870b57cec5SDimitry Andric         const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
26885ffd83dbSDimitry Andric 
26895ffd83dbSDimitry Andric         // Functions without NoUnwind need to preserve the order of elements in
26905ffd83dbSDimitry Andric         // saved vector registers.
26915ffd83dbSDimitry Andric         if (Subtarget.needsSwapsForVSXMemOps() &&
26925ffd83dbSDimitry Andric             !MF->getFunction().hasFnAttribute(Attribute::NoUnwind))
26935ffd83dbSDimitry Andric           TII.loadRegFromStackSlotNoUpd(MBB, I, Reg, CSI[i].getFrameIdx(), RC,
26945ffd83dbSDimitry Andric                                         TRI);
26955ffd83dbSDimitry Andric         else
2696bdd1243dSDimitry Andric           TII.loadRegFromStackSlot(MBB, I, Reg, CSI[i].getFrameIdx(), RC, TRI,
2697bdd1243dSDimitry Andric                                    Register());
26985ffd83dbSDimitry Andric 
26990b57cec5SDimitry Andric         assert(I != MBB.begin() &&
27000b57cec5SDimitry Andric                "loadRegFromStackSlot didn't insert any code!");
27010b57cec5SDimitry Andric       }
27020b57cec5SDimitry Andric     }
27030b57cec5SDimitry Andric 
27040b57cec5SDimitry Andric     // Insert in reverse order.
27050b57cec5SDimitry Andric     if (AtStart)
27060b57cec5SDimitry Andric       I = MBB.begin();
27070b57cec5SDimitry Andric     else {
27080b57cec5SDimitry Andric       I = BeforeI;
27090b57cec5SDimitry Andric       ++I;
27100b57cec5SDimitry Andric     }
27110b57cec5SDimitry Andric   }
27120b57cec5SDimitry Andric 
27130b57cec5SDimitry Andric   // If we haven't yet spilled the CRs, do so now.
27140b57cec5SDimitry Andric   if (CR2Spilled || CR3Spilled || CR4Spilled) {
27155ffd83dbSDimitry Andric     assert(Subtarget.is32BitELFABI() &&
27165ffd83dbSDimitry Andric            "Only set CR[2|3|4]Spilled on 32-bit SVR4.");
27170b57cec5SDimitry Andric     bool is31 = needsFP(*MF);
27185ffd83dbSDimitry Andric     restoreCRs(is31, CR2Spilled, CR3Spilled, CR4Spilled, MBB, I, CSI, CSIIndex);
27190b57cec5SDimitry Andric   }
27200b57cec5SDimitry Andric 
27210b57cec5SDimitry Andric   return true;
27220b57cec5SDimitry Andric }
27230b57cec5SDimitry Andric 
2724349cc55cSDimitry Andric uint64_t PPCFrameLowering::getTOCSaveOffset() const {
27258bcb0991SDimitry Andric   return TOCSaveOffset;
27268bcb0991SDimitry Andric }
27278bcb0991SDimitry Andric 
2728349cc55cSDimitry Andric uint64_t PPCFrameLowering::getFramePointerSaveOffset() const {
27298bcb0991SDimitry Andric   return FramePointerSaveOffset;
27308bcb0991SDimitry Andric }
27318bcb0991SDimitry Andric 
2732349cc55cSDimitry Andric uint64_t PPCFrameLowering::getBasePointerSaveOffset() const {
27338bcb0991SDimitry Andric   return BasePointerSaveOffset;
27348bcb0991SDimitry Andric }
27358bcb0991SDimitry Andric 
27360b57cec5SDimitry Andric bool PPCFrameLowering::enableShrinkWrapping(const MachineFunction &MF) const {
27370b57cec5SDimitry Andric   if (MF.getInfo<PPCFunctionInfo>()->shrinkWrapDisabled())
27380b57cec5SDimitry Andric     return false;
2739fe6060f1SDimitry Andric   return !MF.getSubtarget<PPCSubtarget>().is32BitELFABI();
27400b57cec5SDimitry Andric }
27415f757f3fSDimitry Andric 
27420fca6ea1SDimitry Andric void PPCFrameLowering::updateCalleeSaves(const MachineFunction &MF,
27430fca6ea1SDimitry Andric                                          BitVector &SavedRegs) const {
27440fca6ea1SDimitry Andric   // The AIX ABI uses traceback tables for EH which require that if callee-saved
27450fca6ea1SDimitry Andric   // register N is used, all registers N-31 must be saved/restored.
27460fca6ea1SDimitry Andric   // NOTE: The check for AIX is not actually what is relevant. Traceback tables
27470fca6ea1SDimitry Andric   // on Linux have the same requirements. It is just that AIX is the only ABI
27480fca6ea1SDimitry Andric   // for which we actually use traceback tables. If another ABI needs to be
27490fca6ea1SDimitry Andric   // supported that also uses them, we can add a check such as
27500fca6ea1SDimitry Andric   // Subtarget.usesTraceBackTables().
27510fca6ea1SDimitry Andric   assert(Subtarget.isAIXABI() &&
27520fca6ea1SDimitry Andric          "Function updateCalleeSaves should only be called for AIX.");
27530fca6ea1SDimitry Andric 
27540fca6ea1SDimitry Andric   // If there are no callee saves then there is nothing to do.
27550fca6ea1SDimitry Andric   if (SavedRegs.none())
27560fca6ea1SDimitry Andric     return;
27570fca6ea1SDimitry Andric 
27580fca6ea1SDimitry Andric   const MCPhysReg *CSRegs =
27590fca6ea1SDimitry Andric       Subtarget.getRegisterInfo()->getCalleeSavedRegs(&MF);
27600fca6ea1SDimitry Andric   MCPhysReg LowestGPR = PPC::R31;
27610fca6ea1SDimitry Andric   MCPhysReg LowestG8R = PPC::X31;
27620fca6ea1SDimitry Andric   MCPhysReg LowestFPR = PPC::F31;
27630fca6ea1SDimitry Andric   MCPhysReg LowestVR = PPC::V31;
27640fca6ea1SDimitry Andric 
27650fca6ea1SDimitry Andric   // Traverse the CSRs twice so as not to rely on ascending ordering of
27660fca6ea1SDimitry Andric   // registers in the array. The first pass finds the lowest numbered
27670fca6ea1SDimitry Andric   // register and the second pass marks all higher numbered registers
27680fca6ea1SDimitry Andric   // for spilling.
27690fca6ea1SDimitry Andric   for (int i = 0; CSRegs[i]; i++) {
27700fca6ea1SDimitry Andric     // Get the lowest numbered register for each class that actually needs
27710fca6ea1SDimitry Andric     // to be saved.
27720fca6ea1SDimitry Andric     MCPhysReg Cand = CSRegs[i];
27730fca6ea1SDimitry Andric     if (!SavedRegs.test(Cand))
27740fca6ea1SDimitry Andric       continue;
27750fca6ea1SDimitry Andric     if (PPC::GPRCRegClass.contains(Cand) && Cand < LowestGPR)
27760fca6ea1SDimitry Andric       LowestGPR = Cand;
27770fca6ea1SDimitry Andric     else if (PPC::G8RCRegClass.contains(Cand) && Cand < LowestG8R)
27780fca6ea1SDimitry Andric       LowestG8R = Cand;
27790fca6ea1SDimitry Andric     else if ((PPC::F4RCRegClass.contains(Cand) ||
27800fca6ea1SDimitry Andric               PPC::F8RCRegClass.contains(Cand)) &&
27810fca6ea1SDimitry Andric              Cand < LowestFPR)
27820fca6ea1SDimitry Andric       LowestFPR = Cand;
27830fca6ea1SDimitry Andric     else if (PPC::VRRCRegClass.contains(Cand) && Cand < LowestVR)
27840fca6ea1SDimitry Andric       LowestVR = Cand;
27850fca6ea1SDimitry Andric   }
27860fca6ea1SDimitry Andric 
27870fca6ea1SDimitry Andric   for (int i = 0; CSRegs[i]; i++) {
27880fca6ea1SDimitry Andric     MCPhysReg Cand = CSRegs[i];
27890fca6ea1SDimitry Andric     if ((PPC::GPRCRegClass.contains(Cand) && Cand > LowestGPR) ||
27900fca6ea1SDimitry Andric         (PPC::G8RCRegClass.contains(Cand) && Cand > LowestG8R) ||
27910fca6ea1SDimitry Andric         ((PPC::F4RCRegClass.contains(Cand) ||
27920fca6ea1SDimitry Andric           PPC::F8RCRegClass.contains(Cand)) &&
27930fca6ea1SDimitry Andric          Cand > LowestFPR) ||
27940fca6ea1SDimitry Andric         (PPC::VRRCRegClass.contains(Cand) && Cand > LowestVR))
27950fca6ea1SDimitry Andric       SavedRegs.set(Cand);
27960fca6ea1SDimitry Andric   }
27970fca6ea1SDimitry Andric }
27980fca6ea1SDimitry Andric 
27995f757f3fSDimitry Andric uint64_t PPCFrameLowering::getStackThreshold() const {
28005f757f3fSDimitry Andric   // On PPC64, we use `stux r1, r1, <scratch_reg>` to extend the stack;
28015f757f3fSDimitry Andric   // use `add r1, r1, <scratch_reg>` to release the stack frame.
28025f757f3fSDimitry Andric   // Scratch register contains a signed 64-bit number, which is negative
28035f757f3fSDimitry Andric   // when extending the stack and is positive when releasing the stack frame.
28045f757f3fSDimitry Andric   // To make `stux` and `add` paired, the absolute value of the number contained
28055f757f3fSDimitry Andric   // in the scratch register should be the same. Thus the maximum stack size
28065f757f3fSDimitry Andric   // is (2^63)-1, i.e., LONG_MAX.
28075f757f3fSDimitry Andric   if (Subtarget.isPPC64())
28085f757f3fSDimitry Andric     return LONG_MAX;
28095f757f3fSDimitry Andric 
28105f757f3fSDimitry Andric   return TargetFrameLowering::getStackThreshold();
28115f757f3fSDimitry Andric }
2812