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
computeReturnSaveOffset(const PPCSubtarget & STI)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
computeTOCSaveOffset(const PPCSubtarget & STI)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
computeFramePointerSaveOffset(const PPCSubtarget & STI)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
computeLinkageSize(const PPCSubtarget & STI)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
computeBasePointerSaveOffset(const PPCSubtarget & STI)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
computeCRSaveOffset(const PPCSubtarget & STI)785ffd83dbSDimitry Andric static unsigned computeCRSaveOffset(const PPCSubtarget &STI) {
795ffd83dbSDimitry Andric return (STI.isAIXABI() && !STI.isPPC64()) ? 4 : 8;
808bcb0991SDimitry Andric }
818bcb0991SDimitry Andric
PPCFrameLowering(const PPCSubtarget & STI)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.
getCalleeSavedSpillSlots(unsigned & NumEntries) const930b57cec5SDimitry 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
spillsCR(const MachineFunction & MF)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
hasSpills(const MachineFunction & MF)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
hasNonRISpills(const MachineFunction & MF)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.
MustSaveLR(const MachineFunction & MF,unsigned LR)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
determineFrameLayoutAndUpdate(MachineFunction & MF,bool UseEstimate) const2840b57cec5SDimitry 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
determineFrameLayout(const MachineFunction & MF,bool UseEstimate,unsigned * NewMaxCallFrameSize) const2970b57cec5SDimitry 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.
3200b57cec5SDimitry Andric !RegInfo->hasBasePointer(MF); // No special alignment.
3210b57cec5SDimitry Andric
322e8d8bef9SDimitry Andric // Note: for PPC32 SVR4ABI, we can still generate stackless
3230b57cec5SDimitry Andric // code if all local vars are reg-allocated.
3240b57cec5SDimitry Andric bool FitsInRedZone = FrameSize <= Subtarget.getRedZoneSize();
3250b57cec5SDimitry Andric
3260b57cec5SDimitry Andric // Check whether we can skip adjusting the stack pointer (by using red zone)
3270b57cec5SDimitry Andric if (!DisableRedZone && CanUseRedZone && FitsInRedZone) {
3280b57cec5SDimitry Andric // No need for frame
3290b57cec5SDimitry Andric return 0;
3300b57cec5SDimitry Andric }
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andric // Get the maximum call frame size of all the calls.
3330b57cec5SDimitry Andric unsigned maxCallFrameSize = MFI.getMaxCallFrameSize();
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric // Maximum call frame needs to be at least big enough for linkage area.
3360b57cec5SDimitry Andric unsigned minCallFrameSize = getLinkageSize();
3370b57cec5SDimitry Andric maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize);
3380b57cec5SDimitry Andric
3390b57cec5SDimitry Andric // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
3400b57cec5SDimitry Andric // that allocations will be aligned.
3410b57cec5SDimitry Andric if (MFI.hasVarSizedObjects())
3425ffd83dbSDimitry Andric maxCallFrameSize = alignTo(maxCallFrameSize, Alignment);
3430b57cec5SDimitry Andric
3440b57cec5SDimitry Andric // Update the new max call frame size if the caller passes in a valid pointer.
3450b57cec5SDimitry Andric if (NewMaxCallFrameSize)
3460b57cec5SDimitry Andric *NewMaxCallFrameSize = maxCallFrameSize;
3470b57cec5SDimitry Andric
3480b57cec5SDimitry Andric // Include call frame size in total.
3490b57cec5SDimitry Andric FrameSize += maxCallFrameSize;
3500b57cec5SDimitry Andric
3510b57cec5SDimitry Andric // Make sure the frame is aligned.
3525ffd83dbSDimitry Andric FrameSize = alignTo(FrameSize, Alignment);
3530b57cec5SDimitry Andric
3540b57cec5SDimitry Andric return FrameSize;
3550b57cec5SDimitry Andric }
3560b57cec5SDimitry Andric
3570b57cec5SDimitry Andric // hasFP - Return true if the specified function actually has a dedicated frame
3580b57cec5SDimitry Andric // pointer register.
hasFP(const MachineFunction & MF) const3590b57cec5SDimitry Andric bool PPCFrameLowering::hasFP(const MachineFunction &MF) const {
3600b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
3610b57cec5SDimitry Andric // FIXME: This is pretty much broken by design: hasFP() might be called really
3620b57cec5SDimitry Andric // early, before the stack layout was calculated and thus hasFP() might return
3630b57cec5SDimitry Andric // true or false here depending on the time of call.
3640b57cec5SDimitry Andric return (MFI.getStackSize()) && needsFP(MF);
3650b57cec5SDimitry Andric }
3660b57cec5SDimitry Andric
3670b57cec5SDimitry Andric // needsFP - Return true if the specified function should have a dedicated frame
3680b57cec5SDimitry Andric // pointer register. This is true if the function has variable sized allocas or
3690b57cec5SDimitry Andric // if frame pointer elimination is disabled.
needsFP(const MachineFunction & MF) const3700b57cec5SDimitry Andric bool PPCFrameLowering::needsFP(const MachineFunction &MF) const {
3710b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
3720b57cec5SDimitry Andric
3730b57cec5SDimitry Andric // Naked functions have no stack frame pushed, so we don't have a frame
3740b57cec5SDimitry Andric // pointer.
3750b57cec5SDimitry Andric if (MF.getFunction().hasFnAttribute(Attribute::Naked))
3760b57cec5SDimitry Andric return false;
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andric return MF.getTarget().Options.DisableFramePointerElim(MF) ||
3790b57cec5SDimitry Andric MFI.hasVarSizedObjects() || MFI.hasStackMap() || MFI.hasPatchPoint() ||
380e8d8bef9SDimitry Andric MF.exposesReturnsTwice() ||
3810b57cec5SDimitry Andric (MF.getTarget().Options.GuaranteedTailCallOpt &&
3820b57cec5SDimitry Andric MF.getInfo<PPCFunctionInfo>()->hasFastCall());
3830b57cec5SDimitry Andric }
3840b57cec5SDimitry Andric
replaceFPWithRealFP(MachineFunction & MF) const3850b57cec5SDimitry Andric void PPCFrameLowering::replaceFPWithRealFP(MachineFunction &MF) const {
3860b57cec5SDimitry Andric bool is31 = needsFP(MF);
3870b57cec5SDimitry Andric unsigned FPReg = is31 ? PPC::R31 : PPC::R1;
3880b57cec5SDimitry Andric unsigned FP8Reg = is31 ? PPC::X31 : PPC::X1;
3890b57cec5SDimitry Andric
3900b57cec5SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
3910b57cec5SDimitry Andric bool HasBP = RegInfo->hasBasePointer(MF);
3920b57cec5SDimitry Andric unsigned BPReg = HasBP ? (unsigned) RegInfo->getBaseRegister(MF) : FPReg;
3930b57cec5SDimitry Andric unsigned BP8Reg = HasBP ? (unsigned) PPC::X30 : FP8Reg;
3940b57cec5SDimitry Andric
3954824e7fdSDimitry Andric for (MachineBasicBlock &MBB : MF)
3964824e7fdSDimitry Andric for (MachineBasicBlock::iterator MBBI = MBB.end(); MBBI != MBB.begin();) {
3970b57cec5SDimitry Andric --MBBI;
398fe013be4SDimitry Andric for (MachineOperand &MO : MBBI->operands()) {
3990b57cec5SDimitry Andric if (!MO.isReg())
4000b57cec5SDimitry Andric continue;
4010b57cec5SDimitry Andric
4020b57cec5SDimitry Andric switch (MO.getReg()) {
4030b57cec5SDimitry Andric case PPC::FP:
4040b57cec5SDimitry Andric MO.setReg(FPReg);
4050b57cec5SDimitry Andric break;
4060b57cec5SDimitry Andric case PPC::FP8:
4070b57cec5SDimitry Andric MO.setReg(FP8Reg);
4080b57cec5SDimitry Andric break;
4090b57cec5SDimitry Andric case PPC::BP:
4100b57cec5SDimitry Andric MO.setReg(BPReg);
4110b57cec5SDimitry Andric break;
4120b57cec5SDimitry Andric case PPC::BP8:
4130b57cec5SDimitry Andric MO.setReg(BP8Reg);
4140b57cec5SDimitry Andric break;
4150b57cec5SDimitry Andric
4160b57cec5SDimitry Andric }
4170b57cec5SDimitry Andric }
4180b57cec5SDimitry Andric }
4190b57cec5SDimitry Andric }
4200b57cec5SDimitry Andric
4210b57cec5SDimitry Andric /* This function will do the following:
4220b57cec5SDimitry Andric - If MBB is an entry or exit block, set SR1 and SR2 to R0 and R12
4230b57cec5SDimitry Andric respectively (defaults recommended by the ABI) and return true
4240b57cec5SDimitry Andric - If MBB is not an entry block, initialize the register scavenger and look
4250b57cec5SDimitry Andric for available registers.
4260b57cec5SDimitry Andric - If the defaults (R0/R12) are available, return true
4270b57cec5SDimitry Andric - If TwoUniqueRegsRequired is set to true, it looks for two unique
4280b57cec5SDimitry Andric registers. Otherwise, look for a single available register.
4290b57cec5SDimitry Andric - If the required registers are found, set SR1 and SR2 and return true.
4300b57cec5SDimitry Andric - If the required registers are not found, set SR2 or both SR1 and SR2 to
4310b57cec5SDimitry Andric PPC::NoRegister and return false.
4320b57cec5SDimitry Andric
4330b57cec5SDimitry Andric Note that if both SR1 and SR2 are valid parameters and TwoUniqueRegsRequired
4340b57cec5SDimitry Andric is not set, this function will attempt to find two different registers, but
4350b57cec5SDimitry Andric still return true if only one register is available (and set SR1 == SR2).
4360b57cec5SDimitry Andric */
4370b57cec5SDimitry Andric bool
findScratchRegister(MachineBasicBlock * MBB,bool UseAtEnd,bool TwoUniqueRegsRequired,Register * SR1,Register * SR2) const4380b57cec5SDimitry Andric PPCFrameLowering::findScratchRegister(MachineBasicBlock *MBB,
4390b57cec5SDimitry Andric bool UseAtEnd,
4400b57cec5SDimitry Andric bool TwoUniqueRegsRequired,
4415ffd83dbSDimitry Andric Register *SR1,
4425ffd83dbSDimitry Andric Register *SR2) const {
4430b57cec5SDimitry Andric RegScavenger RS;
4445ffd83dbSDimitry Andric Register R0 = Subtarget.isPPC64() ? PPC::X0 : PPC::R0;
4455ffd83dbSDimitry Andric Register R12 = Subtarget.isPPC64() ? PPC::X12 : PPC::R12;
4460b57cec5SDimitry Andric
4470b57cec5SDimitry Andric // Set the defaults for the two scratch registers.
4480b57cec5SDimitry Andric if (SR1)
4490b57cec5SDimitry Andric *SR1 = R0;
4500b57cec5SDimitry Andric
4510b57cec5SDimitry Andric if (SR2) {
4520b57cec5SDimitry Andric assert (SR1 && "Asking for the second scratch register but not the first?");
4530b57cec5SDimitry Andric *SR2 = R12;
4540b57cec5SDimitry Andric }
4550b57cec5SDimitry Andric
4560b57cec5SDimitry Andric // If MBB is an entry or exit block, use R0 and R12 as the scratch registers.
4570b57cec5SDimitry Andric if ((UseAtEnd && MBB->isReturnBlock()) ||
4580b57cec5SDimitry Andric (!UseAtEnd && (&MBB->getParent()->front() == MBB)))
4590b57cec5SDimitry Andric return true;
4600b57cec5SDimitry Andric
461fe013be4SDimitry Andric if (UseAtEnd) {
462fe013be4SDimitry Andric // The scratch register will be used before the first terminator (or at the
463fe013be4SDimitry Andric // end of the block if there are no terminators).
4640b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI = MBB->getFirstTerminator();
465fe013be4SDimitry Andric if (MBBI == MBB->begin()) {
466fe013be4SDimitry Andric RS.enterBasicBlock(*MBB);
467fe013be4SDimitry Andric } else {
468fe013be4SDimitry Andric RS.enterBasicBlockEnd(*MBB);
469c9157d92SDimitry Andric RS.backward(MBBI);
470fe013be4SDimitry Andric }
471fe013be4SDimitry Andric } else {
472fe013be4SDimitry Andric // The scratch register will be used at the start of the block.
473fe013be4SDimitry Andric RS.enterBasicBlock(*MBB);
4740b57cec5SDimitry Andric }
4750b57cec5SDimitry Andric
4760b57cec5SDimitry Andric // If the two registers are available, we're all good.
4770b57cec5SDimitry Andric // Note that we only return here if both R0 and R12 are available because
4780b57cec5SDimitry Andric // although the function may not require two unique registers, it may benefit
4790b57cec5SDimitry Andric // from having two so we should try to provide them.
4800b57cec5SDimitry Andric if (!RS.isRegUsed(R0) && !RS.isRegUsed(R12))
4810b57cec5SDimitry Andric return true;
4820b57cec5SDimitry Andric
4830b57cec5SDimitry Andric // Get the list of callee-saved registers for the target.
4840b57cec5SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
4850b57cec5SDimitry Andric const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(MBB->getParent());
4860b57cec5SDimitry Andric
4870b57cec5SDimitry Andric // Get all the available registers in the block.
4880b57cec5SDimitry Andric BitVector BV = RS.getRegsAvailable(Subtarget.isPPC64() ? &PPC::G8RCRegClass :
4890b57cec5SDimitry Andric &PPC::GPRCRegClass);
4900b57cec5SDimitry Andric
4910b57cec5SDimitry Andric // We shouldn't use callee-saved registers as scratch registers as they may be
4920b57cec5SDimitry Andric // available when looking for a candidate block for shrink wrapping but not
4930b57cec5SDimitry Andric // available when the actual prologue/epilogue is being emitted because they
4940b57cec5SDimitry Andric // were added as live-in to the prologue block by PrologueEpilogueInserter.
4950b57cec5SDimitry Andric for (int i = 0; CSRegs[i]; ++i)
4960b57cec5SDimitry Andric BV.reset(CSRegs[i]);
4970b57cec5SDimitry Andric
4980b57cec5SDimitry Andric // Set the first scratch register to the first available one.
4990b57cec5SDimitry Andric if (SR1) {
5000b57cec5SDimitry Andric int FirstScratchReg = BV.find_first();
5010b57cec5SDimitry Andric *SR1 = FirstScratchReg == -1 ? (unsigned)PPC::NoRegister : FirstScratchReg;
5020b57cec5SDimitry Andric }
5030b57cec5SDimitry Andric
5040b57cec5SDimitry Andric // If there is another one available, set the second scratch register to that.
5050b57cec5SDimitry Andric // Otherwise, set it to either PPC::NoRegister if this function requires two
5060b57cec5SDimitry Andric // or to whatever SR1 is set to if this function doesn't require two.
5070b57cec5SDimitry Andric if (SR2) {
5080b57cec5SDimitry Andric int SecondScratchReg = BV.find_next(*SR1);
5090b57cec5SDimitry Andric if (SecondScratchReg != -1)
5100b57cec5SDimitry Andric *SR2 = SecondScratchReg;
5110b57cec5SDimitry Andric else
5125ffd83dbSDimitry Andric *SR2 = TwoUniqueRegsRequired ? Register() : *SR1;
5130b57cec5SDimitry Andric }
5140b57cec5SDimitry Andric
5150b57cec5SDimitry Andric // Now that we've done our best to provide both registers, double check
5160b57cec5SDimitry Andric // whether we were unable to provide enough.
5170b57cec5SDimitry Andric if (BV.count() < (TwoUniqueRegsRequired ? 2U : 1U))
5180b57cec5SDimitry Andric return false;
5190b57cec5SDimitry Andric
5200b57cec5SDimitry Andric return true;
5210b57cec5SDimitry Andric }
5220b57cec5SDimitry Andric
5230b57cec5SDimitry Andric // We need a scratch register for spilling LR and for spilling CR. By default,
5240b57cec5SDimitry Andric // we use two scratch registers to hide latency. However, if only one scratch
5250b57cec5SDimitry Andric // register is available, we can adjust for that by not overlapping the spill
5260b57cec5SDimitry Andric // code. However, if we need to realign the stack (i.e. have a base pointer)
5270b57cec5SDimitry Andric // and the stack frame is large, we need two scratch registers.
528e8d8bef9SDimitry Andric // Also, stack probe requires two scratch registers, one for old sp, one for
529e8d8bef9SDimitry Andric // large frame and large probe size.
5300b57cec5SDimitry Andric bool
twoUniqueScratchRegsRequired(MachineBasicBlock * MBB) const5310b57cec5SDimitry Andric PPCFrameLowering::twoUniqueScratchRegsRequired(MachineBasicBlock *MBB) const {
5320b57cec5SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
5330b57cec5SDimitry Andric MachineFunction &MF = *(MBB->getParent());
5340b57cec5SDimitry Andric bool HasBP = RegInfo->hasBasePointer(MF);
5350b57cec5SDimitry Andric unsigned FrameSize = determineFrameLayout(MF);
5360b57cec5SDimitry Andric int NegFrameSize = -FrameSize;
5370b57cec5SDimitry Andric bool IsLargeFrame = !isInt<16>(NegFrameSize);
5380b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
5395ffd83dbSDimitry Andric Align MaxAlign = MFI.getMaxAlign();
5400b57cec5SDimitry Andric bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
541e8d8bef9SDimitry Andric const PPCTargetLowering &TLI = *Subtarget.getTargetLowering();
5420b57cec5SDimitry Andric
543e8d8bef9SDimitry Andric return ((IsLargeFrame || !HasRedZone) && HasBP && MaxAlign > 1) ||
544e8d8bef9SDimitry Andric TLI.hasInlineStackProbe(MF);
5450b57cec5SDimitry Andric }
5460b57cec5SDimitry Andric
canUseAsPrologue(const MachineBasicBlock & MBB) const5470b57cec5SDimitry Andric bool PPCFrameLowering::canUseAsPrologue(const MachineBasicBlock &MBB) const {
5480b57cec5SDimitry Andric MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric return findScratchRegister(TmpMBB, false,
5510b57cec5SDimitry Andric twoUniqueScratchRegsRequired(TmpMBB));
5520b57cec5SDimitry Andric }
5530b57cec5SDimitry Andric
canUseAsEpilogue(const MachineBasicBlock & MBB) const5540b57cec5SDimitry Andric bool PPCFrameLowering::canUseAsEpilogue(const MachineBasicBlock &MBB) const {
5550b57cec5SDimitry Andric MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
5560b57cec5SDimitry Andric
5570b57cec5SDimitry Andric return findScratchRegister(TmpMBB, true);
5580b57cec5SDimitry Andric }
5590b57cec5SDimitry Andric
stackUpdateCanBeMoved(MachineFunction & MF) const5600b57cec5SDimitry Andric bool PPCFrameLowering::stackUpdateCanBeMoved(MachineFunction &MF) const {
5610b57cec5SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
5620b57cec5SDimitry Andric PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
5630b57cec5SDimitry Andric
5640b57cec5SDimitry Andric // Abort if there is no register info or function info.
5650b57cec5SDimitry Andric if (!RegInfo || !FI)
5660b57cec5SDimitry Andric return false;
5670b57cec5SDimitry Andric
5680b57cec5SDimitry Andric // Only move the stack update on ELFv2 ABI and PPC64.
5690b57cec5SDimitry Andric if (!Subtarget.isELFv2ABI() || !Subtarget.isPPC64())
5700b57cec5SDimitry Andric return false;
5710b57cec5SDimitry Andric
5720b57cec5SDimitry Andric // Check the frame size first and return false if it does not fit the
5730b57cec5SDimitry Andric // requirements.
5740b57cec5SDimitry Andric // We need a non-zero frame size as well as a frame that will fit in the red
5750b57cec5SDimitry Andric // zone. This is because by moving the stack pointer update we are now storing
5760b57cec5SDimitry Andric // to the red zone until the stack pointer is updated. If we get an interrupt
5770b57cec5SDimitry Andric // inside the prologue but before the stack update we now have a number of
5780b57cec5SDimitry Andric // stores to the red zone and those stores must all fit.
5790b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
5800b57cec5SDimitry Andric unsigned FrameSize = MFI.getStackSize();
5810b57cec5SDimitry Andric if (!FrameSize || FrameSize > Subtarget.getRedZoneSize())
5820b57cec5SDimitry Andric return false;
5830b57cec5SDimitry Andric
5840b57cec5SDimitry Andric // Frame pointers and base pointers complicate matters so don't do anything
5850b57cec5SDimitry Andric // if we have them. For example having a frame pointer will sometimes require
5860b57cec5SDimitry Andric // a copy of r1 into r31 and that makes keeping track of updates to r1 more
587e8d8bef9SDimitry Andric // difficult. Similar situation exists with setjmp.
588e8d8bef9SDimitry Andric if (hasFP(MF) || RegInfo->hasBasePointer(MF) || MF.exposesReturnsTwice())
5890b57cec5SDimitry Andric return false;
5900b57cec5SDimitry Andric
5910b57cec5SDimitry Andric // Calls to fast_cc functions use different rules for passing parameters on
5920b57cec5SDimitry Andric // the stack from the ABI and using PIC base in the function imposes
5930b57cec5SDimitry Andric // similar restrictions to using the base pointer. It is not generally safe
5940b57cec5SDimitry Andric // to move the stack pointer update in these situations.
5950b57cec5SDimitry Andric if (FI->hasFastCall() || FI->usesPICBase())
5960b57cec5SDimitry Andric return false;
5970b57cec5SDimitry Andric
5980b57cec5SDimitry Andric // Finally we can move the stack update if we do not require register
5990b57cec5SDimitry Andric // scavenging. Register scavenging can introduce more spills and so
6000b57cec5SDimitry Andric // may make the frame size larger than we have computed.
6010b57cec5SDimitry Andric return !RegInfo->requiresFrameIndexScavenging(MF);
6020b57cec5SDimitry Andric }
6030b57cec5SDimitry Andric
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const6040b57cec5SDimitry Andric void PPCFrameLowering::emitPrologue(MachineFunction &MF,
6050b57cec5SDimitry Andric MachineBasicBlock &MBB) const {
6060b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI = MBB.begin();
6070b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
6080b57cec5SDimitry Andric const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
6090b57cec5SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
6105ffd83dbSDimitry Andric const PPCTargetLowering &TLI = *Subtarget.getTargetLowering();
6110b57cec5SDimitry Andric
6120b57cec5SDimitry Andric MachineModuleInfo &MMI = MF.getMMI();
6130b57cec5SDimitry Andric const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
6140b57cec5SDimitry Andric DebugLoc dl;
6155ffd83dbSDimitry Andric // AIX assembler does not support cfi directives.
6165ffd83dbSDimitry Andric const bool needsCFI = MF.needsFrameMoves() && !Subtarget.isAIXABI();
6170b57cec5SDimitry Andric
618bdd1243dSDimitry Andric const bool HasFastMFLR = Subtarget.hasFastMFLR();
619bdd1243dSDimitry Andric
6200b57cec5SDimitry Andric // Get processor type.
6210b57cec5SDimitry Andric bool isPPC64 = Subtarget.isPPC64();
6220b57cec5SDimitry Andric // Get the ABI.
6230b57cec5SDimitry Andric bool isSVR4ABI = Subtarget.isSVR4ABI();
6240b57cec5SDimitry Andric bool isELFv2ABI = Subtarget.isELFv2ABI();
625e8d8bef9SDimitry Andric assert((isSVR4ABI || Subtarget.isAIXABI()) && "Unsupported PPC ABI.");
6260b57cec5SDimitry Andric
6270b57cec5SDimitry Andric // Work out frame sizes.
628349cc55cSDimitry Andric uint64_t FrameSize = determineFrameLayoutAndUpdate(MF);
629349cc55cSDimitry Andric int64_t NegFrameSize = -FrameSize;
63081ad6265SDimitry Andric if (!isPPC64 && (!isInt<32>(FrameSize) || !isInt<32>(NegFrameSize)))
6310b57cec5SDimitry Andric llvm_unreachable("Unhandled stack size!");
6320b57cec5SDimitry Andric
6330b57cec5SDimitry Andric if (MFI.isFrameAddressTaken())
6340b57cec5SDimitry Andric replaceFPWithRealFP(MF);
6350b57cec5SDimitry Andric
6360b57cec5SDimitry Andric // Check if the link register (LR) must be saved.
6370b57cec5SDimitry Andric PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
6380b57cec5SDimitry Andric bool MustSaveLR = FI->mustSaveLR();
6390b57cec5SDimitry Andric bool MustSaveTOC = FI->mustSaveTOC();
6405ffd83dbSDimitry Andric const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
6410b57cec5SDimitry Andric bool MustSaveCR = !MustSaveCRs.empty();
6420b57cec5SDimitry Andric // Do we have a frame pointer and/or base pointer for this function?
6430b57cec5SDimitry Andric bool HasFP = hasFP(MF);
6440b57cec5SDimitry Andric bool HasBP = RegInfo->hasBasePointer(MF);
6450b57cec5SDimitry Andric bool HasRedZone = isPPC64 || !isSVR4ABI;
646fe6060f1SDimitry Andric bool HasROPProtect = Subtarget.hasROPProtect();
647fe6060f1SDimitry Andric bool HasPrivileged = Subtarget.hasPrivileged();
6480b57cec5SDimitry Andric
6495ffd83dbSDimitry Andric Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
6508bcb0991SDimitry Andric Register BPReg = RegInfo->getBaseRegister(MF);
6515ffd83dbSDimitry Andric Register FPReg = isPPC64 ? PPC::X31 : PPC::R31;
6525ffd83dbSDimitry Andric Register LRReg = isPPC64 ? PPC::LR8 : PPC::LR;
6535ffd83dbSDimitry Andric Register TOCReg = isPPC64 ? PPC::X2 : PPC::R2;
6545ffd83dbSDimitry Andric Register ScratchReg;
6555ffd83dbSDimitry Andric Register TempReg = isPPC64 ? PPC::X12 : PPC::R12; // another scratch reg
6560b57cec5SDimitry Andric // ...(R12/X12 is volatile in both Darwin & SVR4, & can't be a function arg.)
6570b57cec5SDimitry Andric const MCInstrDesc& MFLRInst = TII.get(isPPC64 ? PPC::MFLR8
6580b57cec5SDimitry Andric : PPC::MFLR );
6590b57cec5SDimitry Andric const MCInstrDesc& StoreInst = TII.get(isPPC64 ? PPC::STD
6600b57cec5SDimitry Andric : PPC::STW );
6610b57cec5SDimitry Andric const MCInstrDesc& StoreUpdtInst = TII.get(isPPC64 ? PPC::STDU
6620b57cec5SDimitry Andric : PPC::STWU );
6630b57cec5SDimitry Andric const MCInstrDesc& StoreUpdtIdxInst = TII.get(isPPC64 ? PPC::STDUX
6640b57cec5SDimitry Andric : PPC::STWUX);
6650b57cec5SDimitry Andric const MCInstrDesc& OrInst = TII.get(isPPC64 ? PPC::OR8
6660b57cec5SDimitry Andric : PPC::OR );
6670b57cec5SDimitry Andric const MCInstrDesc& SubtractCarryingInst = TII.get(isPPC64 ? PPC::SUBFC8
6680b57cec5SDimitry Andric : PPC::SUBFC);
6690b57cec5SDimitry Andric const MCInstrDesc& SubtractImmCarryingInst = TII.get(isPPC64 ? PPC::SUBFIC8
6700b57cec5SDimitry Andric : PPC::SUBFIC);
6715ffd83dbSDimitry Andric const MCInstrDesc &MoveFromCondRegInst = TII.get(isPPC64 ? PPC::MFCR8
6725ffd83dbSDimitry Andric : PPC::MFCR);
6735ffd83dbSDimitry Andric const MCInstrDesc &StoreWordInst = TII.get(isPPC64 ? PPC::STW8 : PPC::STW);
674fe6060f1SDimitry Andric const MCInstrDesc &HashST =
67504eeddc0SDimitry Andric TII.get(isPPC64 ? (HasPrivileged ? PPC::HASHSTP8 : PPC::HASHST8)
67604eeddc0SDimitry Andric : (HasPrivileged ? PPC::HASHSTP : PPC::HASHST));
6770b57cec5SDimitry Andric
6780b57cec5SDimitry Andric // Regarding this assert: Even though LR is saved in the caller's frame (i.e.,
6790b57cec5SDimitry Andric // LROffset is positive), that slot is callee-owned. Because PPC32 SVR4 has no
6800b57cec5SDimitry Andric // Red Zone, an asynchronous event (a form of "callee") could claim a frame &
6810b57cec5SDimitry Andric // overwrite it, so PPC32 SVR4 must claim at least a minimal frame to save LR.
6820b57cec5SDimitry Andric assert((isPPC64 || !isSVR4ABI || !(!FrameSize && (MustSaveLR || HasFP))) &&
6830b57cec5SDimitry Andric "FrameSize must be >0 to save/restore the FP or LR for 32-bit SVR4.");
6840b57cec5SDimitry Andric
6850b57cec5SDimitry Andric // Using the same bool variable as below to suppress compiler warnings.
6865ffd83dbSDimitry Andric bool SingleScratchReg = findScratchRegister(
687e8d8bef9SDimitry Andric &MBB, false, twoUniqueScratchRegsRequired(&MBB), &ScratchReg, &TempReg);
6880b57cec5SDimitry Andric assert(SingleScratchReg &&
6890b57cec5SDimitry Andric "Required number of registers not available in this block");
6900b57cec5SDimitry Andric
6910b57cec5SDimitry Andric SingleScratchReg = ScratchReg == TempReg;
6920b57cec5SDimitry Andric
693349cc55cSDimitry Andric int64_t LROffset = getReturnSaveOffset();
6940b57cec5SDimitry Andric
695349cc55cSDimitry Andric int64_t FPOffset = 0;
6960b57cec5SDimitry Andric if (HasFP) {
6970b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
6980b57cec5SDimitry Andric int FPIndex = FI->getFramePointerSaveIndex();
6990b57cec5SDimitry Andric assert(FPIndex && "No Frame Pointer Save Slot!");
7000b57cec5SDimitry Andric FPOffset = MFI.getObjectOffset(FPIndex);
7010b57cec5SDimitry Andric }
7020b57cec5SDimitry Andric
703349cc55cSDimitry Andric int64_t BPOffset = 0;
7040b57cec5SDimitry Andric if (HasBP) {
7050b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
7060b57cec5SDimitry Andric int BPIndex = FI->getBasePointerSaveIndex();
7070b57cec5SDimitry Andric assert(BPIndex && "No Base Pointer Save Slot!");
7080b57cec5SDimitry Andric BPOffset = MFI.getObjectOffset(BPIndex);
7090b57cec5SDimitry Andric }
7100b57cec5SDimitry Andric
711349cc55cSDimitry Andric int64_t PBPOffset = 0;
7120b57cec5SDimitry Andric if (FI->usesPICBase()) {
7130b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
7140b57cec5SDimitry Andric int PBPIndex = FI->getPICBasePointerSaveIndex();
7150b57cec5SDimitry Andric assert(PBPIndex && "No PIC Base Pointer Save Slot!");
7160b57cec5SDimitry Andric PBPOffset = MFI.getObjectOffset(PBPIndex);
7170b57cec5SDimitry Andric }
7180b57cec5SDimitry Andric
7190b57cec5SDimitry Andric // Get stack alignments.
7205ffd83dbSDimitry Andric Align MaxAlign = MFI.getMaxAlign();
7210b57cec5SDimitry Andric if (HasBP && MaxAlign > 1)
7225ffd83dbSDimitry Andric assert(Log2(MaxAlign) < 16 && "Invalid alignment!");
7230b57cec5SDimitry Andric
7240b57cec5SDimitry Andric // Frames of 32KB & larger require special handling because they cannot be
7250b57cec5SDimitry Andric // indexed into with a simple STDU/STWU/STD/STW immediate offset operand.
7260b57cec5SDimitry Andric bool isLargeFrame = !isInt<16>(NegFrameSize);
7270b57cec5SDimitry Andric
7280b57cec5SDimitry Andric // Check if we can move the stack update instruction (stdu) down the prologue
7290b57cec5SDimitry Andric // past the callee saves. Hopefully this will avoid the situation where the
7300b57cec5SDimitry Andric // saves are waiting for the update on the store with update to complete.
7310b57cec5SDimitry Andric MachineBasicBlock::iterator StackUpdateLoc = MBBI;
7320b57cec5SDimitry Andric bool MovingStackUpdateDown = false;
7330b57cec5SDimitry Andric
7340b57cec5SDimitry Andric // Check if we can move the stack update.
7350b57cec5SDimitry Andric if (stackUpdateCanBeMoved(MF)) {
7360b57cec5SDimitry Andric const std::vector<CalleeSavedInfo> &Info = MFI.getCalleeSavedInfo();
7370b57cec5SDimitry Andric for (CalleeSavedInfo CSI : Info) {
738fe6060f1SDimitry Andric // If the callee saved register is spilled to a register instead of the
739fe6060f1SDimitry Andric // stack then the spill no longer uses the stack pointer.
740fe6060f1SDimitry Andric // This can lead to two consequences:
741fe6060f1SDimitry Andric // 1) We no longer need to update the stack because the function does not
742fe6060f1SDimitry Andric // spill any callee saved registers to stack.
743fe6060f1SDimitry Andric // 2) We have a situation where we still have to update the stack pointer
744fe6060f1SDimitry Andric // even though some registers are spilled to other registers. In
745fe6060f1SDimitry Andric // this case the current code moves the stack update to an incorrect
746fe6060f1SDimitry Andric // position.
747fe6060f1SDimitry Andric // In either case we should abort moving the stack update operation.
748fe6060f1SDimitry Andric if (CSI.isSpilledToReg()) {
749fe6060f1SDimitry Andric StackUpdateLoc = MBBI;
750fe6060f1SDimitry Andric MovingStackUpdateDown = false;
751fe6060f1SDimitry Andric break;
752fe6060f1SDimitry Andric }
753fe6060f1SDimitry Andric
7540b57cec5SDimitry Andric int FrIdx = CSI.getFrameIdx();
7550b57cec5SDimitry Andric // If the frame index is not negative the callee saved info belongs to a
7560b57cec5SDimitry Andric // stack object that is not a fixed stack object. We ignore non-fixed
7570b57cec5SDimitry Andric // stack objects because we won't move the stack update pointer past them.
7580b57cec5SDimitry Andric if (FrIdx >= 0)
7590b57cec5SDimitry Andric continue;
7600b57cec5SDimitry Andric
7610b57cec5SDimitry Andric if (MFI.isFixedObjectIndex(FrIdx) && MFI.getObjectOffset(FrIdx) < 0) {
7620b57cec5SDimitry Andric StackUpdateLoc++;
7630b57cec5SDimitry Andric MovingStackUpdateDown = true;
7640b57cec5SDimitry Andric } else {
7650b57cec5SDimitry Andric // We need all of the Frame Indices to meet these conditions.
7660b57cec5SDimitry Andric // If they do not, abort the whole operation.
7670b57cec5SDimitry Andric StackUpdateLoc = MBBI;
7680b57cec5SDimitry Andric MovingStackUpdateDown = false;
7690b57cec5SDimitry Andric break;
7700b57cec5SDimitry Andric }
7710b57cec5SDimitry Andric }
7720b57cec5SDimitry Andric
7730b57cec5SDimitry Andric // If the operation was not aborted then update the object offset.
7740b57cec5SDimitry Andric if (MovingStackUpdateDown) {
7750b57cec5SDimitry Andric for (CalleeSavedInfo CSI : Info) {
7760b57cec5SDimitry Andric int FrIdx = CSI.getFrameIdx();
7770b57cec5SDimitry Andric if (FrIdx < 0)
7780b57cec5SDimitry Andric MFI.setObjectOffset(FrIdx, MFI.getObjectOffset(FrIdx) + NegFrameSize);
7790b57cec5SDimitry Andric }
7800b57cec5SDimitry Andric }
7810b57cec5SDimitry Andric }
7820b57cec5SDimitry Andric
7835ffd83dbSDimitry Andric // Where in the prologue we move the CR fields depends on how many scratch
7845ffd83dbSDimitry Andric // registers we have, and if we need to save the link register or not. This
7855ffd83dbSDimitry Andric // lambda is to avoid duplicating the logic in 2 places.
7865ffd83dbSDimitry Andric auto BuildMoveFromCR = [&]() {
7875ffd83dbSDimitry Andric if (isELFv2ABI && MustSaveCRs.size() == 1) {
7885ffd83dbSDimitry Andric // In the ELFv2 ABI, we are not required to save all CR fields.
7895ffd83dbSDimitry Andric // If only one CR field is clobbered, it is more efficient to use
7905ffd83dbSDimitry Andric // mfocrf to selectively save just that field, because mfocrf has short
7915ffd83dbSDimitry Andric // latency compares to mfcr.
7925ffd83dbSDimitry Andric assert(isPPC64 && "V2 ABI is 64-bit only.");
7935ffd83dbSDimitry Andric MachineInstrBuilder MIB =
7945ffd83dbSDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::MFOCRF8), TempReg);
7955ffd83dbSDimitry Andric MIB.addReg(MustSaveCRs[0], RegState::Kill);
7965ffd83dbSDimitry Andric } else {
7975ffd83dbSDimitry Andric MachineInstrBuilder MIB =
7985ffd83dbSDimitry Andric BuildMI(MBB, MBBI, dl, MoveFromCondRegInst, TempReg);
7995ffd83dbSDimitry Andric for (unsigned CRfield : MustSaveCRs)
8005ffd83dbSDimitry Andric MIB.addReg(CRfield, RegState::ImplicitKill);
8015ffd83dbSDimitry Andric }
8025ffd83dbSDimitry Andric };
8035ffd83dbSDimitry Andric
8040b57cec5SDimitry Andric // If we need to spill the CR and the LR but we don't have two separate
8050b57cec5SDimitry Andric // registers available, we must spill them one at a time
8060b57cec5SDimitry Andric if (MustSaveCR && SingleScratchReg && MustSaveLR) {
8075ffd83dbSDimitry Andric BuildMoveFromCR();
8085ffd83dbSDimitry Andric BuildMI(MBB, MBBI, dl, StoreWordInst)
8090b57cec5SDimitry Andric .addReg(TempReg, getKillRegState(true))
8105ffd83dbSDimitry Andric .addImm(CRSaveOffset)
8110b57cec5SDimitry Andric .addReg(SPReg);
8120b57cec5SDimitry Andric }
8130b57cec5SDimitry Andric
8140b57cec5SDimitry Andric if (MustSaveLR)
8150b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, MFLRInst, ScratchReg);
8160b57cec5SDimitry Andric
8175ffd83dbSDimitry Andric if (MustSaveCR && !(SingleScratchReg && MustSaveLR))
8185ffd83dbSDimitry Andric BuildMoveFromCR();
8190b57cec5SDimitry Andric
8200b57cec5SDimitry Andric if (HasRedZone) {
8210b57cec5SDimitry Andric if (HasFP)
8220b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
8230b57cec5SDimitry Andric .addReg(FPReg)
8240b57cec5SDimitry Andric .addImm(FPOffset)
8250b57cec5SDimitry Andric .addReg(SPReg);
8260b57cec5SDimitry Andric if (FI->usesPICBase())
8270b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
8280b57cec5SDimitry Andric .addReg(PPC::R30)
8290b57cec5SDimitry Andric .addImm(PBPOffset)
8300b57cec5SDimitry Andric .addReg(SPReg);
8310b57cec5SDimitry Andric if (HasBP)
8320b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
8330b57cec5SDimitry Andric .addReg(BPReg)
8340b57cec5SDimitry Andric .addImm(BPOffset)
8350b57cec5SDimitry Andric .addReg(SPReg);
8360b57cec5SDimitry Andric }
8370b57cec5SDimitry Andric
838fe6060f1SDimitry Andric // Generate the instruction to store the LR. In the case where ROP protection
839fe6060f1SDimitry Andric // is required the register holding the LR should not be killed as it will be
840fe6060f1SDimitry Andric // used by the hash store instruction.
841bdd1243dSDimitry Andric auto SaveLR = [&](int64_t Offset) {
842bdd1243dSDimitry Andric assert(MustSaveLR && "LR is not required to be saved!");
8430b57cec5SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, StoreInst)
844fe6060f1SDimitry Andric .addReg(ScratchReg, getKillRegState(!HasROPProtect))
845bdd1243dSDimitry Andric .addImm(Offset)
8460b57cec5SDimitry Andric .addReg(SPReg);
8470b57cec5SDimitry Andric
848fe6060f1SDimitry Andric // Add the ROP protection Hash Store instruction.
849fe6060f1SDimitry Andric // NOTE: This is technically a violation of the ABI. The hash can be saved
850fe6060f1SDimitry Andric // up to 512 bytes into the Protected Zone. This can be outside of the
851fe6060f1SDimitry Andric // initial 288 byte volatile program storage region in the Protected Zone.
852fe6060f1SDimitry Andric // However, this restriction will be removed in an upcoming revision of the
853fe6060f1SDimitry Andric // ABI.
854fe6060f1SDimitry Andric if (HasROPProtect) {
855fe6060f1SDimitry Andric const int SaveIndex = FI->getROPProtectionHashSaveIndex();
856349cc55cSDimitry Andric const int64_t ImmOffset = MFI.getObjectOffset(SaveIndex);
857fe6060f1SDimitry Andric assert((ImmOffset <= -8 && ImmOffset >= -512) &&
858fe6060f1SDimitry Andric "ROP hash save offset out of range.");
859fe6060f1SDimitry Andric assert(((ImmOffset & 0x7) == 0) &&
860fe6060f1SDimitry Andric "ROP hash save offset must be 8 byte aligned.");
861fe6060f1SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, HashST)
862fe6060f1SDimitry Andric .addReg(ScratchReg, getKillRegState(true))
863fe6060f1SDimitry Andric .addImm(ImmOffset)
864fe6060f1SDimitry Andric .addReg(SPReg);
865fe6060f1SDimitry Andric }
866bdd1243dSDimitry Andric };
867bdd1243dSDimitry Andric
868bdd1243dSDimitry Andric if (MustSaveLR && HasFastMFLR)
869bdd1243dSDimitry Andric SaveLR(LROffset);
870fe6060f1SDimitry Andric
8710b57cec5SDimitry Andric if (MustSaveCR &&
8725ffd83dbSDimitry Andric !(SingleScratchReg && MustSaveLR)) {
8730b57cec5SDimitry Andric assert(HasRedZone && "A red zone is always available on PPC64");
8745ffd83dbSDimitry Andric BuildMI(MBB, MBBI, dl, StoreWordInst)
8750b57cec5SDimitry Andric .addReg(TempReg, getKillRegState(true))
8765ffd83dbSDimitry Andric .addImm(CRSaveOffset)
8770b57cec5SDimitry Andric .addReg(SPReg);
8780b57cec5SDimitry Andric }
8790b57cec5SDimitry Andric
8800b57cec5SDimitry Andric // Skip the rest if this is a leaf function & all spills fit in the Red Zone.
881bdd1243dSDimitry Andric if (!FrameSize) {
882bdd1243dSDimitry Andric if (MustSaveLR && !HasFastMFLR)
883bdd1243dSDimitry Andric SaveLR(LROffset);
8840b57cec5SDimitry Andric return;
885bdd1243dSDimitry Andric }
8860b57cec5SDimitry Andric
8870b57cec5SDimitry Andric // Adjust stack pointer: r1 += NegFrameSize.
8880b57cec5SDimitry Andric // If there is a preferred stack alignment, align R1 now
8890b57cec5SDimitry Andric
8900b57cec5SDimitry Andric if (HasBP && HasRedZone) {
8910b57cec5SDimitry Andric // Save a copy of r1 as the base pointer.
8920b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, BPReg)
8930b57cec5SDimitry Andric .addReg(SPReg)
8940b57cec5SDimitry Andric .addReg(SPReg);
8950b57cec5SDimitry Andric }
8960b57cec5SDimitry Andric
8970b57cec5SDimitry Andric // Have we generated a STUX instruction to claim stack frame? If so,
8980b57cec5SDimitry Andric // the negated frame size will be placed in ScratchReg.
899bdd1243dSDimitry Andric bool HasSTUX =
900bdd1243dSDimitry Andric (TLI.hasInlineStackProbe(MF) && FrameSize > TLI.getStackProbeSize(MF)) ||
901bdd1243dSDimitry Andric (HasBP && MaxAlign > 1) || isLargeFrame;
902bdd1243dSDimitry Andric
903bdd1243dSDimitry Andric // If we use STUX to update the stack pointer, we need the two scratch
904bdd1243dSDimitry Andric // registers TempReg and ScratchReg, we have to save LR here which is stored
905bdd1243dSDimitry Andric // in ScratchReg.
906bdd1243dSDimitry Andric // If the offset can not be encoded into the store instruction, we also have
907bdd1243dSDimitry Andric // to save LR here.
908bdd1243dSDimitry Andric if (MustSaveLR && !HasFastMFLR &&
909bdd1243dSDimitry Andric (HasSTUX || !isInt<16>(FrameSize + LROffset)))
910bdd1243dSDimitry Andric SaveLR(LROffset);
9110b57cec5SDimitry Andric
9125ffd83dbSDimitry Andric // If FrameSize <= TLI.getStackProbeSize(MF), as POWER ABI requires backchain
9135ffd83dbSDimitry Andric // pointer is always stored at SP, we will get a free probe due to an essential
9145ffd83dbSDimitry Andric // STU(X) instruction.
9155ffd83dbSDimitry Andric if (TLI.hasInlineStackProbe(MF) && FrameSize > TLI.getStackProbeSize(MF)) {
9165ffd83dbSDimitry Andric // To be consistent with other targets, a pseudo instruction is emitted and
9175ffd83dbSDimitry Andric // will be later expanded in `inlineStackProbe`.
9185ffd83dbSDimitry Andric BuildMI(MBB, MBBI, dl,
9195ffd83dbSDimitry Andric TII.get(isPPC64 ? PPC::PROBED_STACKALLOC_64
9205ffd83dbSDimitry Andric : PPC::PROBED_STACKALLOC_32))
92123408297SDimitry Andric .addDef(TempReg)
92223408297SDimitry Andric .addDef(ScratchReg) // ScratchReg stores the old sp.
9235ffd83dbSDimitry Andric .addImm(NegFrameSize);
9245ffd83dbSDimitry Andric // FIXME: HasSTUX is only read if HasRedZone is not set, in such case, we
9255ffd83dbSDimitry Andric // update the ScratchReg to meet the assumption that ScratchReg contains
9265ffd83dbSDimitry Andric // the NegFrameSize. This solution is rather tricky.
9275ffd83dbSDimitry Andric if (!HasRedZone) {
9285ffd83dbSDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBF), ScratchReg)
92923408297SDimitry Andric .addReg(ScratchReg)
9305ffd83dbSDimitry Andric .addReg(SPReg);
9315ffd83dbSDimitry Andric }
9325ffd83dbSDimitry Andric } else {
9330b57cec5SDimitry Andric // This condition must be kept in sync with canUseAsPrologue.
9340b57cec5SDimitry Andric if (HasBP && MaxAlign > 1) {
9350b57cec5SDimitry Andric if (isPPC64)
9360b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::RLDICL), ScratchReg)
9370b57cec5SDimitry Andric .addReg(SPReg)
9380b57cec5SDimitry Andric .addImm(0)
9395ffd83dbSDimitry Andric .addImm(64 - Log2(MaxAlign));
9400b57cec5SDimitry Andric else // PPC32...
9410b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::RLWINM), ScratchReg)
9420b57cec5SDimitry Andric .addReg(SPReg)
9430b57cec5SDimitry Andric .addImm(0)
9445ffd83dbSDimitry Andric .addImm(32 - Log2(MaxAlign))
9450b57cec5SDimitry Andric .addImm(31);
9460b57cec5SDimitry Andric if (!isLargeFrame) {
9470b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, SubtractImmCarryingInst, ScratchReg)
9480b57cec5SDimitry Andric .addReg(ScratchReg, RegState::Kill)
9490b57cec5SDimitry Andric .addImm(NegFrameSize);
9500b57cec5SDimitry Andric } else {
9510b57cec5SDimitry Andric assert(!SingleScratchReg && "Only a single scratch reg available");
95281ad6265SDimitry Andric TII.materializeImmPostRA(MBB, MBBI, dl, TempReg, NegFrameSize);
9530b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, SubtractCarryingInst, ScratchReg)
9540b57cec5SDimitry Andric .addReg(ScratchReg, RegState::Kill)
9550b57cec5SDimitry Andric .addReg(TempReg, RegState::Kill);
9560b57cec5SDimitry Andric }
9570b57cec5SDimitry Andric
9580b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, StoreUpdtIdxInst, SPReg)
9590b57cec5SDimitry Andric .addReg(SPReg, RegState::Kill)
9600b57cec5SDimitry Andric .addReg(SPReg)
9610b57cec5SDimitry Andric .addReg(ScratchReg);
9620b57cec5SDimitry Andric } else if (!isLargeFrame) {
9630b57cec5SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, StoreUpdtInst, SPReg)
9640b57cec5SDimitry Andric .addReg(SPReg)
9650b57cec5SDimitry Andric .addImm(NegFrameSize)
9660b57cec5SDimitry Andric .addReg(SPReg);
9670b57cec5SDimitry Andric } else {
96881ad6265SDimitry Andric TII.materializeImmPostRA(MBB, MBBI, dl, ScratchReg, NegFrameSize);
9690b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, StoreUpdtIdxInst, SPReg)
9700b57cec5SDimitry Andric .addReg(SPReg, RegState::Kill)
9710b57cec5SDimitry Andric .addReg(SPReg)
9720b57cec5SDimitry Andric .addReg(ScratchReg);
9730b57cec5SDimitry Andric }
9745ffd83dbSDimitry Andric }
9750b57cec5SDimitry Andric
9760b57cec5SDimitry Andric // Save the TOC register after the stack pointer update if a prologue TOC
9770b57cec5SDimitry Andric // save is required for the function.
9780b57cec5SDimitry Andric if (MustSaveTOC) {
9790b57cec5SDimitry Andric assert(isELFv2ABI && "TOC saves in the prologue only supported on ELFv2");
9800b57cec5SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, TII.get(PPC::STD))
9810b57cec5SDimitry Andric .addReg(TOCReg, getKillRegState(true))
9820b57cec5SDimitry Andric .addImm(TOCSaveOffset)
9830b57cec5SDimitry Andric .addReg(SPReg);
9840b57cec5SDimitry Andric }
9850b57cec5SDimitry Andric
9860b57cec5SDimitry Andric if (!HasRedZone) {
9870b57cec5SDimitry Andric assert(!isPPC64 && "A red zone is always available on PPC64");
9880b57cec5SDimitry Andric if (HasSTUX) {
9890b57cec5SDimitry Andric // The negated frame size is in ScratchReg, and the SPReg has been
9900b57cec5SDimitry Andric // decremented by the frame size: SPReg = old SPReg + ScratchReg.
9910b57cec5SDimitry Andric // Since FPOffset, PBPOffset, etc. are relative to the beginning of
9920b57cec5SDimitry Andric // the stack frame (i.e. the old SP), ideally, we would put the old
9930b57cec5SDimitry Andric // SP into a register and use it as the base for the stores. The
9940b57cec5SDimitry Andric // problem is that the only available register may be ScratchReg,
9950b57cec5SDimitry Andric // which could be R0, and R0 cannot be used as a base address.
9960b57cec5SDimitry Andric
9970b57cec5SDimitry Andric // First, set ScratchReg to the old SP. This may need to be modified
9980b57cec5SDimitry Andric // later.
9990b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBF), ScratchReg)
10000b57cec5SDimitry Andric .addReg(ScratchReg, RegState::Kill)
10010b57cec5SDimitry Andric .addReg(SPReg);
10020b57cec5SDimitry Andric
10030b57cec5SDimitry Andric if (ScratchReg == PPC::R0) {
10040b57cec5SDimitry Andric // R0 cannot be used as a base register, but it can be used as an
10050b57cec5SDimitry Andric // index in a store-indexed.
10060b57cec5SDimitry Andric int LastOffset = 0;
10070b57cec5SDimitry Andric if (HasFP) {
10080b57cec5SDimitry Andric // R0 += (FPOffset-LastOffset).
10090b57cec5SDimitry Andric // Need addic, since addi treats R0 as 0.
10100b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), ScratchReg)
10110b57cec5SDimitry Andric .addReg(ScratchReg)
10120b57cec5SDimitry Andric .addImm(FPOffset-LastOffset);
10130b57cec5SDimitry Andric LastOffset = FPOffset;
10140b57cec5SDimitry Andric // Store FP into *R0.
10150b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::STWX))
10160b57cec5SDimitry Andric .addReg(FPReg, RegState::Kill) // Save FP.
10170b57cec5SDimitry Andric .addReg(PPC::ZERO)
10180b57cec5SDimitry Andric .addReg(ScratchReg); // This will be the index (R0 is ok here).
10190b57cec5SDimitry Andric }
10200b57cec5SDimitry Andric if (FI->usesPICBase()) {
10210b57cec5SDimitry Andric // R0 += (PBPOffset-LastOffset).
10220b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), ScratchReg)
10230b57cec5SDimitry Andric .addReg(ScratchReg)
10240b57cec5SDimitry Andric .addImm(PBPOffset-LastOffset);
10250b57cec5SDimitry Andric LastOffset = PBPOffset;
10260b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::STWX))
10270b57cec5SDimitry Andric .addReg(PPC::R30, RegState::Kill) // Save PIC base pointer.
10280b57cec5SDimitry Andric .addReg(PPC::ZERO)
10290b57cec5SDimitry Andric .addReg(ScratchReg); // This will be the index (R0 is ok here).
10300b57cec5SDimitry Andric }
10310b57cec5SDimitry Andric if (HasBP) {
10320b57cec5SDimitry Andric // R0 += (BPOffset-LastOffset).
10330b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), ScratchReg)
10340b57cec5SDimitry Andric .addReg(ScratchReg)
10350b57cec5SDimitry Andric .addImm(BPOffset-LastOffset);
10360b57cec5SDimitry Andric LastOffset = BPOffset;
10370b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::STWX))
10380b57cec5SDimitry Andric .addReg(BPReg, RegState::Kill) // Save BP.
10390b57cec5SDimitry Andric .addReg(PPC::ZERO)
10400b57cec5SDimitry Andric .addReg(ScratchReg); // This will be the index (R0 is ok here).
10410b57cec5SDimitry Andric // BP = R0-LastOffset
10420b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDIC), BPReg)
10430b57cec5SDimitry Andric .addReg(ScratchReg, RegState::Kill)
10440b57cec5SDimitry Andric .addImm(-LastOffset);
10450b57cec5SDimitry Andric }
10460b57cec5SDimitry Andric } else {
10470b57cec5SDimitry Andric // ScratchReg is not R0, so use it as the base register. It is
10480b57cec5SDimitry Andric // already set to the old SP, so we can use the offsets directly.
10490b57cec5SDimitry Andric
10500b57cec5SDimitry Andric // Now that the stack frame has been allocated, save all the necessary
10510b57cec5SDimitry Andric // registers using ScratchReg as the base address.
10520b57cec5SDimitry Andric if (HasFP)
10530b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
10540b57cec5SDimitry Andric .addReg(FPReg)
10550b57cec5SDimitry Andric .addImm(FPOffset)
10560b57cec5SDimitry Andric .addReg(ScratchReg);
10570b57cec5SDimitry Andric if (FI->usesPICBase())
10580b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
10590b57cec5SDimitry Andric .addReg(PPC::R30)
10600b57cec5SDimitry Andric .addImm(PBPOffset)
10610b57cec5SDimitry Andric .addReg(ScratchReg);
10620b57cec5SDimitry Andric if (HasBP) {
10630b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
10640b57cec5SDimitry Andric .addReg(BPReg)
10650b57cec5SDimitry Andric .addImm(BPOffset)
10660b57cec5SDimitry Andric .addReg(ScratchReg);
10670b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, BPReg)
10680b57cec5SDimitry Andric .addReg(ScratchReg, RegState::Kill)
10690b57cec5SDimitry Andric .addReg(ScratchReg);
10700b57cec5SDimitry Andric }
10710b57cec5SDimitry Andric }
10720b57cec5SDimitry Andric } else {
10730b57cec5SDimitry Andric // The frame size is a known 16-bit constant (fitting in the immediate
10740b57cec5SDimitry Andric // field of STWU). To be here we have to be compiling for PPC32.
10750b57cec5SDimitry Andric // Since the SPReg has been decreased by FrameSize, add it back to each
10760b57cec5SDimitry Andric // offset.
10770b57cec5SDimitry Andric if (HasFP)
10780b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
10790b57cec5SDimitry Andric .addReg(FPReg)
10800b57cec5SDimitry Andric .addImm(FrameSize + FPOffset)
10810b57cec5SDimitry Andric .addReg(SPReg);
10820b57cec5SDimitry Andric if (FI->usesPICBase())
10830b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
10840b57cec5SDimitry Andric .addReg(PPC::R30)
10850b57cec5SDimitry Andric .addImm(FrameSize + PBPOffset)
10860b57cec5SDimitry Andric .addReg(SPReg);
10870b57cec5SDimitry Andric if (HasBP) {
10880b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, StoreInst)
10890b57cec5SDimitry Andric .addReg(BPReg)
10900b57cec5SDimitry Andric .addImm(FrameSize + BPOffset)
10910b57cec5SDimitry Andric .addReg(SPReg);
10920b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::ADDI), BPReg)
10930b57cec5SDimitry Andric .addReg(SPReg)
10940b57cec5SDimitry Andric .addImm(FrameSize);
10950b57cec5SDimitry Andric }
10960b57cec5SDimitry Andric }
10970b57cec5SDimitry Andric }
10980b57cec5SDimitry Andric
1099bdd1243dSDimitry Andric // Save the LR now.
1100bdd1243dSDimitry Andric if (!HasSTUX && MustSaveLR && !HasFastMFLR && isInt<16>(FrameSize + LROffset))
1101bdd1243dSDimitry Andric SaveLR(LROffset + FrameSize);
1102bdd1243dSDimitry Andric
11030b57cec5SDimitry Andric // Add Call Frame Information for the instructions we generated above.
11040b57cec5SDimitry Andric if (needsCFI) {
11050b57cec5SDimitry Andric unsigned CFIIndex;
11060b57cec5SDimitry Andric
11070b57cec5SDimitry Andric if (HasBP) {
11080b57cec5SDimitry Andric // Define CFA in terms of BP. Do this in preference to using FP/SP,
11090b57cec5SDimitry Andric // because if the stack needed aligning then CFA won't be at a fixed
11100b57cec5SDimitry Andric // offset from FP/SP.
11110b57cec5SDimitry Andric unsigned Reg = MRI->getDwarfRegNum(BPReg, true);
11120b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(
11130b57cec5SDimitry Andric MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
11140b57cec5SDimitry Andric } else {
11150b57cec5SDimitry Andric // Adjust the definition of CFA to account for the change in SP.
11160b57cec5SDimitry Andric assert(NegFrameSize);
11170b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(
11185ffd83dbSDimitry Andric MCCFIInstruction::cfiDefCfaOffset(nullptr, -NegFrameSize));
11190b57cec5SDimitry Andric }
11200b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11210b57cec5SDimitry Andric .addCFIIndex(CFIIndex);
11220b57cec5SDimitry Andric
11230b57cec5SDimitry Andric if (HasFP) {
11240b57cec5SDimitry Andric // Describe where FP was saved, at a fixed offset from CFA.
11250b57cec5SDimitry Andric unsigned Reg = MRI->getDwarfRegNum(FPReg, true);
11260b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(
11270b57cec5SDimitry Andric MCCFIInstruction::createOffset(nullptr, Reg, FPOffset));
11280b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11290b57cec5SDimitry Andric .addCFIIndex(CFIIndex);
11300b57cec5SDimitry Andric }
11310b57cec5SDimitry Andric
11320b57cec5SDimitry Andric if (FI->usesPICBase()) {
11330b57cec5SDimitry Andric // Describe where FP was saved, at a fixed offset from CFA.
11340b57cec5SDimitry Andric unsigned Reg = MRI->getDwarfRegNum(PPC::R30, true);
11350b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(
11360b57cec5SDimitry Andric MCCFIInstruction::createOffset(nullptr, Reg, PBPOffset));
11370b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11380b57cec5SDimitry Andric .addCFIIndex(CFIIndex);
11390b57cec5SDimitry Andric }
11400b57cec5SDimitry Andric
11410b57cec5SDimitry Andric if (HasBP) {
11420b57cec5SDimitry Andric // Describe where BP was saved, at a fixed offset from CFA.
11430b57cec5SDimitry Andric unsigned Reg = MRI->getDwarfRegNum(BPReg, true);
11440b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(
11450b57cec5SDimitry Andric MCCFIInstruction::createOffset(nullptr, Reg, BPOffset));
11460b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11470b57cec5SDimitry Andric .addCFIIndex(CFIIndex);
11480b57cec5SDimitry Andric }
11490b57cec5SDimitry Andric
11500b57cec5SDimitry Andric if (MustSaveLR) {
11510b57cec5SDimitry Andric // Describe where LR was saved, at a fixed offset from CFA.
11520b57cec5SDimitry Andric unsigned Reg = MRI->getDwarfRegNum(LRReg, true);
11530b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(
11540b57cec5SDimitry Andric MCCFIInstruction::createOffset(nullptr, Reg, LROffset));
11550b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11560b57cec5SDimitry Andric .addCFIIndex(CFIIndex);
11570b57cec5SDimitry Andric }
11580b57cec5SDimitry Andric }
11590b57cec5SDimitry Andric
11600b57cec5SDimitry Andric // If there is a frame pointer, copy R1 into R31
11610b57cec5SDimitry Andric if (HasFP) {
11620b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, FPReg)
11630b57cec5SDimitry Andric .addReg(SPReg)
11640b57cec5SDimitry Andric .addReg(SPReg);
11650b57cec5SDimitry Andric
11660b57cec5SDimitry Andric if (!HasBP && needsCFI) {
11670b57cec5SDimitry Andric // Change the definition of CFA from SP+offset to FP+offset, because SP
11680b57cec5SDimitry Andric // will change at every alloca.
11690b57cec5SDimitry Andric unsigned Reg = MRI->getDwarfRegNum(FPReg, true);
11700b57cec5SDimitry Andric unsigned CFIIndex = MF.addFrameInst(
11710b57cec5SDimitry Andric MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
11720b57cec5SDimitry Andric
11730b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
11740b57cec5SDimitry Andric .addCFIIndex(CFIIndex);
11750b57cec5SDimitry Andric }
11760b57cec5SDimitry Andric }
11770b57cec5SDimitry Andric
11780b57cec5SDimitry Andric if (needsCFI) {
11790b57cec5SDimitry Andric // Describe where callee saved registers were saved, at fixed offsets from
11800b57cec5SDimitry Andric // CFA.
11810b57cec5SDimitry Andric const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
11824824e7fdSDimitry Andric for (const CalleeSavedInfo &I : CSI) {
118304eeddc0SDimitry Andric Register Reg = I.getReg();
11840b57cec5SDimitry Andric if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue;
11850b57cec5SDimitry Andric
11860b57cec5SDimitry Andric // This is a bit of a hack: CR2LT, CR2GT, CR2EQ and CR2UN are just
11870b57cec5SDimitry Andric // subregisters of CR2. We just need to emit a move of CR2.
11880b57cec5SDimitry Andric if (PPC::CRBITRCRegClass.contains(Reg))
11890b57cec5SDimitry Andric continue;
11900b57cec5SDimitry Andric
11910b57cec5SDimitry Andric if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)
11920b57cec5SDimitry Andric continue;
11930b57cec5SDimitry Andric
11940b57cec5SDimitry Andric // For 64-bit SVR4 when we have spilled CRs, the spill location
11950b57cec5SDimitry Andric // is SP+8, not a frame-relative slot.
11960b57cec5SDimitry Andric if (isSVR4ABI && isPPC64 && (PPC::CR2 <= Reg && Reg <= PPC::CR4)) {
11970b57cec5SDimitry Andric // In the ELFv1 ABI, only CR2 is noted in CFI and stands in for
11980b57cec5SDimitry Andric // the whole CR word. In the ELFv2 ABI, every CR that was
11990b57cec5SDimitry Andric // actually saved gets its own CFI record.
120004eeddc0SDimitry Andric Register CRReg = isELFv2ABI? Reg : PPC::CR2;
12010b57cec5SDimitry Andric unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
12025ffd83dbSDimitry Andric nullptr, MRI->getDwarfRegNum(CRReg, true), CRSaveOffset));
12030b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
12040b57cec5SDimitry Andric .addCFIIndex(CFIIndex);
12050b57cec5SDimitry Andric continue;
12060b57cec5SDimitry Andric }
12070b57cec5SDimitry Andric
12084824e7fdSDimitry Andric if (I.isSpilledToReg()) {
12094824e7fdSDimitry Andric unsigned SpilledReg = I.getDstReg();
12100b57cec5SDimitry Andric unsigned CFIRegister = MF.addFrameInst(MCCFIInstruction::createRegister(
12110b57cec5SDimitry Andric nullptr, MRI->getDwarfRegNum(Reg, true),
12120b57cec5SDimitry Andric MRI->getDwarfRegNum(SpilledReg, true)));
12130b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
12140b57cec5SDimitry Andric .addCFIIndex(CFIRegister);
12150b57cec5SDimitry Andric } else {
12164824e7fdSDimitry Andric int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());
12170b57cec5SDimitry Andric // We have changed the object offset above but we do not want to change
12180b57cec5SDimitry Andric // the actual offsets in the CFI instruction so we have to undo the
12190b57cec5SDimitry Andric // offset change here.
12200b57cec5SDimitry Andric if (MovingStackUpdateDown)
12210b57cec5SDimitry Andric Offset -= NegFrameSize;
12220b57cec5SDimitry Andric
12230b57cec5SDimitry Andric unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
12240b57cec5SDimitry Andric nullptr, MRI->getDwarfRegNum(Reg, true), Offset));
12250b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
12260b57cec5SDimitry Andric .addCFIIndex(CFIIndex);
12270b57cec5SDimitry Andric }
12280b57cec5SDimitry Andric }
12290b57cec5SDimitry Andric }
12300b57cec5SDimitry Andric }
12310b57cec5SDimitry Andric
inlineStackProbe(MachineFunction & MF,MachineBasicBlock & PrologMBB) const12325ffd83dbSDimitry Andric void PPCFrameLowering::inlineStackProbe(MachineFunction &MF,
12335ffd83dbSDimitry Andric MachineBasicBlock &PrologMBB) const {
12345ffd83dbSDimitry Andric bool isPPC64 = Subtarget.isPPC64();
12355ffd83dbSDimitry Andric const PPCTargetLowering &TLI = *Subtarget.getTargetLowering();
12365ffd83dbSDimitry Andric const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
12375ffd83dbSDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
12385ffd83dbSDimitry Andric MachineModuleInfo &MMI = MF.getMMI();
12395ffd83dbSDimitry Andric const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
12405ffd83dbSDimitry Andric // AIX assembler does not support cfi directives.
12415ffd83dbSDimitry Andric const bool needsCFI = MF.needsFrameMoves() && !Subtarget.isAIXABI();
12425ffd83dbSDimitry Andric auto StackAllocMIPos = llvm::find_if(PrologMBB, [](MachineInstr &MI) {
12435ffd83dbSDimitry Andric int Opc = MI.getOpcode();
12445ffd83dbSDimitry Andric return Opc == PPC::PROBED_STACKALLOC_64 || Opc == PPC::PROBED_STACKALLOC_32;
12455ffd83dbSDimitry Andric });
12465ffd83dbSDimitry Andric if (StackAllocMIPos == PrologMBB.end())
12475ffd83dbSDimitry Andric return;
12485ffd83dbSDimitry Andric const BasicBlock *ProbedBB = PrologMBB.getBasicBlock();
1249e8d8bef9SDimitry Andric MachineBasicBlock *CurrentMBB = &PrologMBB;
12505ffd83dbSDimitry Andric DebugLoc DL = PrologMBB.findDebugLoc(StackAllocMIPos);
12515ffd83dbSDimitry Andric MachineInstr &MI = *StackAllocMIPos;
12525ffd83dbSDimitry Andric int64_t NegFrameSize = MI.getOperand(2).getImm();
1253e8d8bef9SDimitry Andric unsigned ProbeSize = TLI.getStackProbeSize(MF);
1254e8d8bef9SDimitry Andric int64_t NegProbeSize = -(int64_t)ProbeSize;
12555ffd83dbSDimitry Andric assert(isInt<32>(NegProbeSize) && "Unhandled probe size");
12565ffd83dbSDimitry Andric int64_t NumBlocks = NegFrameSize / NegProbeSize;
12575ffd83dbSDimitry Andric int64_t NegResidualSize = NegFrameSize % NegProbeSize;
12585ffd83dbSDimitry Andric Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
12595ffd83dbSDimitry Andric Register ScratchReg = MI.getOperand(0).getReg();
12605ffd83dbSDimitry Andric Register FPReg = MI.getOperand(1).getReg();
12615ffd83dbSDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
12625ffd83dbSDimitry Andric bool HasBP = RegInfo->hasBasePointer(MF);
1263e8d8bef9SDimitry Andric Register BPReg = RegInfo->getBaseRegister(MF);
12645ffd83dbSDimitry Andric Align MaxAlign = MFI.getMaxAlign();
126523408297SDimitry Andric bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
12665ffd83dbSDimitry Andric const MCInstrDesc &CopyInst = TII.get(isPPC64 ? PPC::OR8 : PPC::OR);
12675ffd83dbSDimitry Andric // Subroutines to generate .cfi_* directives.
12685ffd83dbSDimitry Andric auto buildDefCFAReg = [&](MachineBasicBlock &MBB,
12695ffd83dbSDimitry Andric MachineBasicBlock::iterator MBBI, Register Reg) {
12705ffd83dbSDimitry Andric unsigned RegNum = MRI->getDwarfRegNum(Reg, true);
12715ffd83dbSDimitry Andric unsigned CFIIndex = MF.addFrameInst(
12725ffd83dbSDimitry Andric MCCFIInstruction::createDefCfaRegister(nullptr, RegNum));
12735ffd83dbSDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
12745ffd83dbSDimitry Andric .addCFIIndex(CFIIndex);
12755ffd83dbSDimitry Andric };
12765ffd83dbSDimitry Andric auto buildDefCFA = [&](MachineBasicBlock &MBB,
12775ffd83dbSDimitry Andric MachineBasicBlock::iterator MBBI, Register Reg,
12785ffd83dbSDimitry Andric int Offset) {
12795ffd83dbSDimitry Andric unsigned RegNum = MRI->getDwarfRegNum(Reg, true);
12805ffd83dbSDimitry Andric unsigned CFIIndex = MBB.getParent()->addFrameInst(
12815ffd83dbSDimitry Andric MCCFIInstruction::cfiDefCfa(nullptr, RegNum, Offset));
12825ffd83dbSDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
12835ffd83dbSDimitry Andric .addCFIIndex(CFIIndex);
12845ffd83dbSDimitry Andric };
12855ffd83dbSDimitry Andric // Subroutine to determine if we can use the Imm as part of d-form.
12865ffd83dbSDimitry Andric auto CanUseDForm = [](int64_t Imm) { return isInt<16>(Imm) && Imm % 4 == 0; };
12875ffd83dbSDimitry Andric // Subroutine to materialize the Imm into TempReg.
12885ffd83dbSDimitry Andric auto MaterializeImm = [&](MachineBasicBlock &MBB,
12895ffd83dbSDimitry Andric MachineBasicBlock::iterator MBBI, int64_t Imm,
12905ffd83dbSDimitry Andric Register &TempReg) {
12915ffd83dbSDimitry Andric assert(isInt<32>(Imm) && "Unhandled imm");
12925ffd83dbSDimitry Andric if (isInt<16>(Imm))
12935ffd83dbSDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::LI8 : PPC::LI), TempReg)
12945ffd83dbSDimitry Andric .addImm(Imm);
12955ffd83dbSDimitry Andric else {
12965ffd83dbSDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::LIS8 : PPC::LIS), TempReg)
12975ffd83dbSDimitry Andric .addImm(Imm >> 16);
12985ffd83dbSDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::ORI8 : PPC::ORI), TempReg)
12995ffd83dbSDimitry Andric .addReg(TempReg)
13005ffd83dbSDimitry Andric .addImm(Imm & 0xFFFF);
13015ffd83dbSDimitry Andric }
13025ffd83dbSDimitry Andric };
13035ffd83dbSDimitry Andric // Subroutine to store frame pointer and decrease stack pointer by probe size.
13045ffd83dbSDimitry Andric auto allocateAndProbe = [&](MachineBasicBlock &MBB,
13055ffd83dbSDimitry Andric MachineBasicBlock::iterator MBBI, int64_t NegSize,
1306e8d8bef9SDimitry Andric Register NegSizeReg, bool UseDForm,
1307e8d8bef9SDimitry Andric Register StoreReg) {
13085ffd83dbSDimitry Andric if (UseDForm)
13095ffd83dbSDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::STDU : PPC::STWU), SPReg)
1310e8d8bef9SDimitry Andric .addReg(StoreReg)
13115ffd83dbSDimitry Andric .addImm(NegSize)
13125ffd83dbSDimitry Andric .addReg(SPReg);
13135ffd83dbSDimitry Andric else
13145ffd83dbSDimitry Andric BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
1315e8d8bef9SDimitry Andric .addReg(StoreReg)
13165ffd83dbSDimitry Andric .addReg(SPReg)
13175ffd83dbSDimitry Andric .addReg(NegSizeReg);
13185ffd83dbSDimitry Andric };
131923408297SDimitry Andric // Used to probe stack when realignment is required.
132023408297SDimitry Andric // Note that, according to ABI's requirement, *sp must always equals the
132123408297SDimitry Andric // value of back-chain pointer, only st(w|d)u(x) can be used to update sp.
132223408297SDimitry Andric // Following is pseudo code:
132323408297SDimitry Andric // final_sp = (sp & align) + negframesize;
132423408297SDimitry Andric // neg_gap = final_sp - sp;
132523408297SDimitry Andric // while (neg_gap < negprobesize) {
132623408297SDimitry Andric // stdu fp, negprobesize(sp);
132723408297SDimitry Andric // neg_gap -= negprobesize;
132823408297SDimitry Andric // }
132923408297SDimitry Andric // stdux fp, sp, neg_gap
133023408297SDimitry Andric //
133123408297SDimitry Andric // When HasBP & HasRedzone, back-chain pointer is already saved in BPReg
133223408297SDimitry Andric // before probe code, we don't need to save it, so we get one additional reg
133323408297SDimitry Andric // that can be used to materialize the probeside if needed to use xform.
133423408297SDimitry Andric // Otherwise, we can NOT materialize probeside, so we can only use Dform for
133523408297SDimitry Andric // now.
133623408297SDimitry Andric //
133723408297SDimitry Andric // The allocations are:
133823408297SDimitry Andric // if (HasBP && HasRedzone) {
133923408297SDimitry Andric // r0: materialize the probesize if needed so that we can use xform.
134023408297SDimitry Andric // r12: `neg_gap`
134123408297SDimitry Andric // } else {
134223408297SDimitry Andric // r0: back-chain pointer
134323408297SDimitry Andric // r12: `neg_gap`.
134423408297SDimitry Andric // }
134523408297SDimitry Andric auto probeRealignedStack = [&](MachineBasicBlock &MBB,
134623408297SDimitry Andric MachineBasicBlock::iterator MBBI,
134723408297SDimitry Andric Register ScratchReg, Register TempReg) {
134823408297SDimitry Andric assert(HasBP && "The function is supposed to have base pointer when its "
134923408297SDimitry Andric "stack is realigned.");
1350e8d8bef9SDimitry Andric assert(isPowerOf2_64(ProbeSize) && "Probe size should be power of 2");
135123408297SDimitry Andric
135223408297SDimitry Andric // FIXME: We can eliminate this limitation if we get more infomation about
135323408297SDimitry Andric // which part of redzone are already used. Used redzone can be treated
135423408297SDimitry Andric // probed. But there might be `holes' in redzone probed, this could
135523408297SDimitry Andric // complicate the implementation.
135623408297SDimitry Andric assert(ProbeSize >= Subtarget.getRedZoneSize() &&
135723408297SDimitry Andric "Probe size should be larger or equal to the size of red-zone so "
135823408297SDimitry Andric "that red-zone is not clobbered by probing.");
135923408297SDimitry Andric
136023408297SDimitry Andric Register &FinalStackPtr = TempReg;
136123408297SDimitry Andric // FIXME: We only support NegProbeSize materializable by DForm currently.
136223408297SDimitry Andric // When HasBP && HasRedzone, we can use xform if we have an additional idle
136323408297SDimitry Andric // register.
136423408297SDimitry Andric NegProbeSize = std::max(NegProbeSize, -((int64_t)1 << 15));
136523408297SDimitry Andric assert(isInt<16>(NegProbeSize) &&
136623408297SDimitry Andric "NegProbeSize should be materializable by DForm");
1367e8d8bef9SDimitry Andric Register CRReg = PPC::CR0;
136823408297SDimitry Andric // Layout of output assembly kinda like:
1369e8d8bef9SDimitry Andric // bb.0:
1370e8d8bef9SDimitry Andric // ...
137123408297SDimitry Andric // sub $scratchreg, $finalsp, r1
137223408297SDimitry Andric // cmpdi $scratchreg, <negprobesize>
137323408297SDimitry Andric // bge bb.2
137423408297SDimitry Andric // bb.1:
137523408297SDimitry Andric // stdu <backchain>, <negprobesize>(r1)
137623408297SDimitry Andric // sub $scratchreg, $scratchreg, negprobesize
137723408297SDimitry Andric // cmpdi $scratchreg, <negprobesize>
137823408297SDimitry Andric // blt bb.1
1379e8d8bef9SDimitry Andric // bb.2:
138023408297SDimitry Andric // stdux <backchain>, r1, $scratchreg
1381e8d8bef9SDimitry Andric MachineFunction::iterator MBBInsertPoint = std::next(MBB.getIterator());
1382e8d8bef9SDimitry Andric MachineBasicBlock *ProbeLoopBodyMBB = MF.CreateMachineBasicBlock(ProbedBB);
1383e8d8bef9SDimitry Andric MF.insert(MBBInsertPoint, ProbeLoopBodyMBB);
1384e8d8bef9SDimitry Andric MachineBasicBlock *ProbeExitMBB = MF.CreateMachineBasicBlock(ProbedBB);
1385e8d8bef9SDimitry Andric MF.insert(MBBInsertPoint, ProbeExitMBB);
138623408297SDimitry Andric // bb.2
138723408297SDimitry Andric {
138823408297SDimitry Andric Register BackChainPointer = HasRedZone ? BPReg : TempReg;
138923408297SDimitry Andric allocateAndProbe(*ProbeExitMBB, ProbeExitMBB->end(), 0, ScratchReg, false,
139023408297SDimitry Andric BackChainPointer);
139123408297SDimitry Andric if (HasRedZone)
139223408297SDimitry Andric // PROBED_STACKALLOC_64 assumes Operand(1) stores the old sp, copy BPReg
139323408297SDimitry Andric // to TempReg to satisfy it.
139423408297SDimitry Andric BuildMI(*ProbeExitMBB, ProbeExitMBB->end(), DL, CopyInst, TempReg)
139523408297SDimitry Andric .addReg(BPReg)
139623408297SDimitry Andric .addReg(BPReg);
1397e8d8bef9SDimitry Andric ProbeExitMBB->splice(ProbeExitMBB->end(), &MBB, MBBI, MBB.end());
1398e8d8bef9SDimitry Andric ProbeExitMBB->transferSuccessorsAndUpdatePHIs(&MBB);
139923408297SDimitry Andric }
1400e8d8bef9SDimitry Andric // bb.0
140123408297SDimitry Andric {
140223408297SDimitry Andric BuildMI(&MBB, DL, TII.get(isPPC64 ? PPC::SUBF8 : PPC::SUBF), ScratchReg)
1403e8d8bef9SDimitry Andric .addReg(SPReg)
140423408297SDimitry Andric .addReg(FinalStackPtr);
140523408297SDimitry Andric if (!HasRedZone)
140623408297SDimitry Andric BuildMI(&MBB, DL, CopyInst, TempReg).addReg(SPReg).addReg(SPReg);
140723408297SDimitry Andric BuildMI(&MBB, DL, TII.get(isPPC64 ? PPC::CMPDI : PPC::CMPWI), CRReg)
140823408297SDimitry Andric .addReg(ScratchReg)
140923408297SDimitry Andric .addImm(NegProbeSize);
141023408297SDimitry Andric BuildMI(&MBB, DL, TII.get(PPC::BCC))
141123408297SDimitry Andric .addImm(PPC::PRED_GE)
1412e8d8bef9SDimitry Andric .addReg(CRReg)
1413e8d8bef9SDimitry Andric .addMBB(ProbeExitMBB);
141423408297SDimitry Andric MBB.addSuccessor(ProbeLoopBodyMBB);
141523408297SDimitry Andric MBB.addSuccessor(ProbeExitMBB);
141623408297SDimitry Andric }
141723408297SDimitry Andric // bb.1
141823408297SDimitry Andric {
141923408297SDimitry Andric Register BackChainPointer = HasRedZone ? BPReg : TempReg;
142023408297SDimitry Andric allocateAndProbe(*ProbeLoopBodyMBB, ProbeLoopBodyMBB->end(), NegProbeSize,
142123408297SDimitry Andric 0, true /*UseDForm*/, BackChainPointer);
142223408297SDimitry Andric BuildMI(ProbeLoopBodyMBB, DL, TII.get(isPPC64 ? PPC::ADDI8 : PPC::ADDI),
142323408297SDimitry Andric ScratchReg)
142423408297SDimitry Andric .addReg(ScratchReg)
142523408297SDimitry Andric .addImm(-NegProbeSize);
142623408297SDimitry Andric BuildMI(ProbeLoopBodyMBB, DL, TII.get(isPPC64 ? PPC::CMPDI : PPC::CMPWI),
142723408297SDimitry Andric CRReg)
142823408297SDimitry Andric .addReg(ScratchReg)
142923408297SDimitry Andric .addImm(NegProbeSize);
1430e8d8bef9SDimitry Andric BuildMI(ProbeLoopBodyMBB, DL, TII.get(PPC::BCC))
143123408297SDimitry Andric .addImm(PPC::PRED_LT)
1432e8d8bef9SDimitry Andric .addReg(CRReg)
1433e8d8bef9SDimitry Andric .addMBB(ProbeLoopBodyMBB);
1434e8d8bef9SDimitry Andric ProbeLoopBodyMBB->addSuccessor(ProbeExitMBB);
1435e8d8bef9SDimitry Andric ProbeLoopBodyMBB->addSuccessor(ProbeLoopBodyMBB);
143623408297SDimitry Andric }
1437e8d8bef9SDimitry Andric // Update liveins.
1438*b9d9368bSDimitry Andric bool anyChange = false;
1439*b9d9368bSDimitry Andric do {
1440*b9d9368bSDimitry Andric anyChange = recomputeLiveIns(*ProbeExitMBB) ||
1441e8d8bef9SDimitry Andric recomputeLiveIns(*ProbeLoopBodyMBB);
1442*b9d9368bSDimitry Andric } while (anyChange);
1443e8d8bef9SDimitry Andric return ProbeExitMBB;
1444e8d8bef9SDimitry Andric };
1445e8d8bef9SDimitry Andric // For case HasBP && MaxAlign > 1, we have to realign the SP by performing
144623408297SDimitry Andric // SP = SP - SP % MaxAlign, thus make the probe more like dynamic probe since
144723408297SDimitry Andric // the offset subtracted from SP is determined by SP's runtime value.
1448e8d8bef9SDimitry Andric if (HasBP && MaxAlign > 1) {
144923408297SDimitry Andric // Calculate final stack pointer.
145023408297SDimitry Andric if (isPPC64)
145123408297SDimitry Andric BuildMI(*CurrentMBB, {MI}, DL, TII.get(PPC::RLDICL), ScratchReg)
1452e8d8bef9SDimitry Andric .addReg(SPReg)
145323408297SDimitry Andric .addImm(0)
145423408297SDimitry Andric .addImm(64 - Log2(MaxAlign));
145523408297SDimitry Andric else
1456e8d8bef9SDimitry Andric BuildMI(*CurrentMBB, {MI}, DL, TII.get(PPC::RLWINM), ScratchReg)
145723408297SDimitry Andric .addReg(SPReg)
14585ffd83dbSDimitry Andric .addImm(0)
14595ffd83dbSDimitry Andric .addImm(32 - Log2(MaxAlign))
14605ffd83dbSDimitry Andric .addImm(31);
146123408297SDimitry Andric BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::SUBF8 : PPC::SUBF),
146223408297SDimitry Andric FPReg)
1463590d96feSDimitry Andric .addReg(ScratchReg)
1464590d96feSDimitry Andric .addReg(SPReg);
146523408297SDimitry Andric MaterializeImm(*CurrentMBB, {MI}, NegFrameSize, ScratchReg);
146623408297SDimitry Andric BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::ADD8 : PPC::ADD4),
146723408297SDimitry Andric FPReg)
146823408297SDimitry Andric .addReg(ScratchReg)
146923408297SDimitry Andric .addReg(FPReg);
147023408297SDimitry Andric CurrentMBB = probeRealignedStack(*CurrentMBB, {MI}, ScratchReg, FPReg);
147123408297SDimitry Andric if (needsCFI)
147223408297SDimitry Andric buildDefCFAReg(*CurrentMBB, {MI}, FPReg);
1473e8d8bef9SDimitry Andric } else {
1474e8d8bef9SDimitry Andric // Initialize current frame pointer.
1475e8d8bef9SDimitry Andric BuildMI(*CurrentMBB, {MI}, DL, CopyInst, FPReg).addReg(SPReg).addReg(SPReg);
1476e8d8bef9SDimitry Andric // Use FPReg to calculate CFA.
1477e8d8bef9SDimitry Andric if (needsCFI)
1478e8d8bef9SDimitry Andric buildDefCFA(*CurrentMBB, {MI}, FPReg, 0);
14795ffd83dbSDimitry Andric // Probe residual part.
14805ffd83dbSDimitry Andric if (NegResidualSize) {
14815ffd83dbSDimitry Andric bool ResidualUseDForm = CanUseDForm(NegResidualSize);
14825ffd83dbSDimitry Andric if (!ResidualUseDForm)
1483e8d8bef9SDimitry Andric MaterializeImm(*CurrentMBB, {MI}, NegResidualSize, ScratchReg);
1484e8d8bef9SDimitry Andric allocateAndProbe(*CurrentMBB, {MI}, NegResidualSize, ScratchReg,
1485e8d8bef9SDimitry Andric ResidualUseDForm, FPReg);
14865ffd83dbSDimitry Andric }
14875ffd83dbSDimitry Andric bool UseDForm = CanUseDForm(NegProbeSize);
14885ffd83dbSDimitry Andric // If number of blocks is small, just probe them directly.
14895ffd83dbSDimitry Andric if (NumBlocks < 3) {
14905ffd83dbSDimitry Andric if (!UseDForm)
1491e8d8bef9SDimitry Andric MaterializeImm(*CurrentMBB, {MI}, NegProbeSize, ScratchReg);
14925ffd83dbSDimitry Andric for (int i = 0; i < NumBlocks; ++i)
1493e8d8bef9SDimitry Andric allocateAndProbe(*CurrentMBB, {MI}, NegProbeSize, ScratchReg, UseDForm,
1494e8d8bef9SDimitry Andric FPReg);
14955ffd83dbSDimitry Andric if (needsCFI) {
14965ffd83dbSDimitry Andric // Restore using SPReg to calculate CFA.
1497e8d8bef9SDimitry Andric buildDefCFAReg(*CurrentMBB, {MI}, SPReg);
14985ffd83dbSDimitry Andric }
14995ffd83dbSDimitry Andric } else {
15005ffd83dbSDimitry Andric // Since CTR is a volatile register and current shrinkwrap implementation
15015ffd83dbSDimitry Andric // won't choose an MBB in a loop as the PrologMBB, it's safe to synthesize a
15025ffd83dbSDimitry Andric // CTR loop to probe.
15035ffd83dbSDimitry Andric // Calculate trip count and stores it in CTRReg.
1504e8d8bef9SDimitry Andric MaterializeImm(*CurrentMBB, {MI}, NumBlocks, ScratchReg);
1505e8d8bef9SDimitry Andric BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::MTCTR8 : PPC::MTCTR))
15065ffd83dbSDimitry Andric .addReg(ScratchReg, RegState::Kill);
15075ffd83dbSDimitry Andric if (!UseDForm)
1508e8d8bef9SDimitry Andric MaterializeImm(*CurrentMBB, {MI}, NegProbeSize, ScratchReg);
15095ffd83dbSDimitry Andric // Create MBBs of the loop.
15105ffd83dbSDimitry Andric MachineFunction::iterator MBBInsertPoint =
1511e8d8bef9SDimitry Andric std::next(CurrentMBB->getIterator());
15125ffd83dbSDimitry Andric MachineBasicBlock *LoopMBB = MF.CreateMachineBasicBlock(ProbedBB);
15135ffd83dbSDimitry Andric MF.insert(MBBInsertPoint, LoopMBB);
15145ffd83dbSDimitry Andric MachineBasicBlock *ExitMBB = MF.CreateMachineBasicBlock(ProbedBB);
15155ffd83dbSDimitry Andric MF.insert(MBBInsertPoint, ExitMBB);
15165ffd83dbSDimitry Andric // Synthesize the loop body.
15175ffd83dbSDimitry Andric allocateAndProbe(*LoopMBB, LoopMBB->end(), NegProbeSize, ScratchReg,
1518e8d8bef9SDimitry Andric UseDForm, FPReg);
15195ffd83dbSDimitry Andric BuildMI(LoopMBB, DL, TII.get(isPPC64 ? PPC::BDNZ8 : PPC::BDNZ))
15205ffd83dbSDimitry Andric .addMBB(LoopMBB);
15215ffd83dbSDimitry Andric LoopMBB->addSuccessor(ExitMBB);
15225ffd83dbSDimitry Andric LoopMBB->addSuccessor(LoopMBB);
15235ffd83dbSDimitry Andric // Synthesize the exit MBB.
1524e8d8bef9SDimitry Andric ExitMBB->splice(ExitMBB->end(), CurrentMBB,
15255ffd83dbSDimitry Andric std::next(MachineBasicBlock::iterator(MI)),
1526e8d8bef9SDimitry Andric CurrentMBB->end());
1527e8d8bef9SDimitry Andric ExitMBB->transferSuccessorsAndUpdatePHIs(CurrentMBB);
1528e8d8bef9SDimitry Andric CurrentMBB->addSuccessor(LoopMBB);
15295ffd83dbSDimitry Andric if (needsCFI) {
15305ffd83dbSDimitry Andric // Restore using SPReg to calculate CFA.
15315ffd83dbSDimitry Andric buildDefCFAReg(*ExitMBB, ExitMBB->begin(), SPReg);
15325ffd83dbSDimitry Andric }
15335ffd83dbSDimitry Andric // Update liveins.
1534*b9d9368bSDimitry Andric bool anyChange = false;
1535*b9d9368bSDimitry Andric do {
1536*b9d9368bSDimitry Andric anyChange = recomputeLiveIns(*ExitMBB) || recomputeLiveIns(*LoopMBB);
1537*b9d9368bSDimitry Andric } while (anyChange);
15385ffd83dbSDimitry Andric }
153923408297SDimitry Andric }
15405ffd83dbSDimitry Andric ++NumPrologProbed;
15415ffd83dbSDimitry Andric MI.eraseFromParent();
15425ffd83dbSDimitry Andric }
15435ffd83dbSDimitry Andric
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const15440b57cec5SDimitry Andric void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
15450b57cec5SDimitry Andric MachineBasicBlock &MBB) const {
15460b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
15470b57cec5SDimitry Andric DebugLoc dl;
15480b57cec5SDimitry Andric
15490b57cec5SDimitry Andric if (MBBI != MBB.end())
15500b57cec5SDimitry Andric dl = MBBI->getDebugLoc();
15510b57cec5SDimitry Andric
15520b57cec5SDimitry Andric const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
15530b57cec5SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
15540b57cec5SDimitry Andric
15550b57cec5SDimitry Andric // Get alignment info so we know how to restore the SP.
15560b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo();
15570b57cec5SDimitry Andric
15580b57cec5SDimitry Andric // Get the number of bytes allocated from the FrameInfo.
1559349cc55cSDimitry Andric int64_t FrameSize = MFI.getStackSize();
15600b57cec5SDimitry Andric
15610b57cec5SDimitry Andric // Get processor type.
15620b57cec5SDimitry Andric bool isPPC64 = Subtarget.isPPC64();
15630b57cec5SDimitry Andric
15640b57cec5SDimitry Andric // Check if the link register (LR) has been saved.
15650b57cec5SDimitry Andric PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
15660b57cec5SDimitry Andric bool MustSaveLR = FI->mustSaveLR();
15675ffd83dbSDimitry Andric const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
15680b57cec5SDimitry Andric bool MustSaveCR = !MustSaveCRs.empty();
15690b57cec5SDimitry Andric // Do we have a frame pointer and/or base pointer for this function?
15700b57cec5SDimitry Andric bool HasFP = hasFP(MF);
15710b57cec5SDimitry Andric bool HasBP = RegInfo->hasBasePointer(MF);
15720b57cec5SDimitry Andric bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
1573fe6060f1SDimitry Andric bool HasROPProtect = Subtarget.hasROPProtect();
1574fe6060f1SDimitry Andric bool HasPrivileged = Subtarget.hasPrivileged();
15750b57cec5SDimitry Andric
15765ffd83dbSDimitry Andric Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
15778bcb0991SDimitry Andric Register BPReg = RegInfo->getBaseRegister(MF);
15785ffd83dbSDimitry Andric Register FPReg = isPPC64 ? PPC::X31 : PPC::R31;
15795ffd83dbSDimitry Andric Register ScratchReg;
15805ffd83dbSDimitry Andric Register TempReg = isPPC64 ? PPC::X12 : PPC::R12; // another scratch reg
15810b57cec5SDimitry Andric const MCInstrDesc& MTLRInst = TII.get( isPPC64 ? PPC::MTLR8
15820b57cec5SDimitry Andric : PPC::MTLR );
15830b57cec5SDimitry Andric const MCInstrDesc& LoadInst = TII.get( isPPC64 ? PPC::LD
15840b57cec5SDimitry Andric : PPC::LWZ );
15850b57cec5SDimitry Andric const MCInstrDesc& LoadImmShiftedInst = TII.get( isPPC64 ? PPC::LIS8
15860b57cec5SDimitry Andric : PPC::LIS );
15870b57cec5SDimitry Andric const MCInstrDesc& OrInst = TII.get(isPPC64 ? PPC::OR8
15880b57cec5SDimitry Andric : PPC::OR );
15890b57cec5SDimitry Andric const MCInstrDesc& OrImmInst = TII.get( isPPC64 ? PPC::ORI8
15900b57cec5SDimitry Andric : PPC::ORI );
15910b57cec5SDimitry Andric const MCInstrDesc& AddImmInst = TII.get( isPPC64 ? PPC::ADDI8
15920b57cec5SDimitry Andric : PPC::ADDI );
15930b57cec5SDimitry Andric const MCInstrDesc& AddInst = TII.get( isPPC64 ? PPC::ADD8
15940b57cec5SDimitry Andric : PPC::ADD4 );
15955ffd83dbSDimitry Andric const MCInstrDesc& LoadWordInst = TII.get( isPPC64 ? PPC::LWZ8
15965ffd83dbSDimitry Andric : PPC::LWZ);
15975ffd83dbSDimitry Andric const MCInstrDesc& MoveToCRInst = TII.get( isPPC64 ? PPC::MTOCRF8
15985ffd83dbSDimitry Andric : PPC::MTOCRF);
1599fe6060f1SDimitry Andric const MCInstrDesc &HashChk =
160004eeddc0SDimitry Andric TII.get(isPPC64 ? (HasPrivileged ? PPC::HASHCHKP8 : PPC::HASHCHK8)
160104eeddc0SDimitry Andric : (HasPrivileged ? PPC::HASHCHKP : PPC::HASHCHK));
1602349cc55cSDimitry Andric int64_t LROffset = getReturnSaveOffset();
16030b57cec5SDimitry Andric
1604349cc55cSDimitry Andric int64_t FPOffset = 0;
16050b57cec5SDimitry Andric
16060b57cec5SDimitry Andric // Using the same bool variable as below to suppress compiler warnings.
16070b57cec5SDimitry Andric bool SingleScratchReg = findScratchRegister(&MBB, true, false, &ScratchReg,
16080b57cec5SDimitry Andric &TempReg);
16090b57cec5SDimitry Andric assert(SingleScratchReg &&
16100b57cec5SDimitry Andric "Could not find an available scratch register");
16110b57cec5SDimitry Andric
16120b57cec5SDimitry Andric SingleScratchReg = ScratchReg == TempReg;
16130b57cec5SDimitry Andric
16140b57cec5SDimitry Andric if (HasFP) {
16150b57cec5SDimitry Andric int FPIndex = FI->getFramePointerSaveIndex();
16160b57cec5SDimitry Andric assert(FPIndex && "No Frame Pointer Save Slot!");
16170b57cec5SDimitry Andric FPOffset = MFI.getObjectOffset(FPIndex);
16180b57cec5SDimitry Andric }
16190b57cec5SDimitry Andric
1620349cc55cSDimitry Andric int64_t BPOffset = 0;
16210b57cec5SDimitry Andric if (HasBP) {
16220b57cec5SDimitry Andric int BPIndex = FI->getBasePointerSaveIndex();
16230b57cec5SDimitry Andric assert(BPIndex && "No Base Pointer Save Slot!");
16240b57cec5SDimitry Andric BPOffset = MFI.getObjectOffset(BPIndex);
16250b57cec5SDimitry Andric }
16260b57cec5SDimitry Andric
1627349cc55cSDimitry Andric int64_t PBPOffset = 0;
16280b57cec5SDimitry Andric if (FI->usesPICBase()) {
16290b57cec5SDimitry Andric int PBPIndex = FI->getPICBasePointerSaveIndex();
16300b57cec5SDimitry Andric assert(PBPIndex && "No PIC Base Pointer Save Slot!");
16310b57cec5SDimitry Andric PBPOffset = MFI.getObjectOffset(PBPIndex);
16320b57cec5SDimitry Andric }
16330b57cec5SDimitry Andric
16340b57cec5SDimitry Andric bool IsReturnBlock = (MBBI != MBB.end() && MBBI->isReturn());
16350b57cec5SDimitry Andric
16360b57cec5SDimitry Andric if (IsReturnBlock) {
16370b57cec5SDimitry Andric unsigned RetOpcode = MBBI->getOpcode();
16380b57cec5SDimitry Andric bool UsesTCRet = RetOpcode == PPC::TCRETURNri ||
16390b57cec5SDimitry Andric RetOpcode == PPC::TCRETURNdi ||
16400b57cec5SDimitry Andric RetOpcode == PPC::TCRETURNai ||
16410b57cec5SDimitry Andric RetOpcode == PPC::TCRETURNri8 ||
16420b57cec5SDimitry Andric RetOpcode == PPC::TCRETURNdi8 ||
16430b57cec5SDimitry Andric RetOpcode == PPC::TCRETURNai8;
16440b57cec5SDimitry Andric
16450b57cec5SDimitry Andric if (UsesTCRet) {
16460b57cec5SDimitry Andric int MaxTCRetDelta = FI->getTailCallSPDelta();
16470b57cec5SDimitry Andric MachineOperand &StackAdjust = MBBI->getOperand(1);
16480b57cec5SDimitry Andric assert(StackAdjust.isImm() && "Expecting immediate value.");
16490b57cec5SDimitry Andric // Adjust stack pointer.
16500b57cec5SDimitry Andric int StackAdj = StackAdjust.getImm();
16510b57cec5SDimitry Andric int Delta = StackAdj - MaxTCRetDelta;
16520b57cec5SDimitry Andric assert((Delta >= 0) && "Delta must be positive");
16530b57cec5SDimitry Andric if (MaxTCRetDelta>0)
16540b57cec5SDimitry Andric FrameSize += (StackAdj +Delta);
16550b57cec5SDimitry Andric else
16560b57cec5SDimitry Andric FrameSize += StackAdj;
16570b57cec5SDimitry Andric }
16580b57cec5SDimitry Andric }
16590b57cec5SDimitry Andric
16600b57cec5SDimitry Andric // Frames of 32KB & larger require special handling because they cannot be
16610b57cec5SDimitry Andric // indexed into with a simple LD/LWZ immediate offset operand.
16620b57cec5SDimitry Andric bool isLargeFrame = !isInt<16>(FrameSize);
16630b57cec5SDimitry Andric
16640b57cec5SDimitry Andric // On targets without red zone, the SP needs to be restored last, so that
16650b57cec5SDimitry Andric // all live contents of the stack frame are upwards of the SP. This means
16660b57cec5SDimitry Andric // that we cannot restore SP just now, since there may be more registers
16670b57cec5SDimitry Andric // to restore from the stack frame (e.g. R31). If the frame size is not
16680b57cec5SDimitry Andric // a simple immediate value, we will need a spare register to hold the
16690b57cec5SDimitry Andric // restored SP. If the frame size is known and small, we can simply adjust
16700b57cec5SDimitry Andric // the offsets of the registers to be restored, and still use SP to restore
16710b57cec5SDimitry Andric // them. In such case, the final update of SP will be to add the frame
16720b57cec5SDimitry Andric // size to it.
16730b57cec5SDimitry Andric // To simplify the code, set RBReg to the base register used to restore
16740b57cec5SDimitry Andric // values from the stack, and set SPAdd to the value that needs to be added
16750b57cec5SDimitry Andric // to the SP at the end. The default values are as if red zone was present.
16760b57cec5SDimitry Andric unsigned RBReg = SPReg;
167781ad6265SDimitry Andric uint64_t SPAdd = 0;
16780b57cec5SDimitry Andric
16790b57cec5SDimitry Andric // Check if we can move the stack update instruction up the epilogue
16800b57cec5SDimitry Andric // past the callee saves. This will allow the move to LR instruction
16810b57cec5SDimitry Andric // to be executed before the restores of the callee saves which means
16820b57cec5SDimitry Andric // that the callee saves can hide the latency from the MTLR instrcution.
16830b57cec5SDimitry Andric MachineBasicBlock::iterator StackUpdateLoc = MBBI;
16840b57cec5SDimitry Andric if (stackUpdateCanBeMoved(MF)) {
16850b57cec5SDimitry Andric const std::vector<CalleeSavedInfo> & Info = MFI.getCalleeSavedInfo();
16860b57cec5SDimitry Andric for (CalleeSavedInfo CSI : Info) {
1687fe6060f1SDimitry Andric // If the callee saved register is spilled to another register abort the
1688fe6060f1SDimitry Andric // stack update movement.
1689fe6060f1SDimitry Andric if (CSI.isSpilledToReg()) {
1690fe6060f1SDimitry Andric StackUpdateLoc = MBBI;
1691fe6060f1SDimitry Andric break;
1692fe6060f1SDimitry Andric }
16930b57cec5SDimitry Andric int FrIdx = CSI.getFrameIdx();
16940b57cec5SDimitry Andric // If the frame index is not negative the callee saved info belongs to a
16950b57cec5SDimitry Andric // stack object that is not a fixed stack object. We ignore non-fixed
16960b57cec5SDimitry Andric // stack objects because we won't move the update of the stack pointer
16970b57cec5SDimitry Andric // past them.
16980b57cec5SDimitry Andric if (FrIdx >= 0)
16990b57cec5SDimitry Andric continue;
17000b57cec5SDimitry Andric
17010b57cec5SDimitry Andric if (MFI.isFixedObjectIndex(FrIdx) && MFI.getObjectOffset(FrIdx) < 0)
17020b57cec5SDimitry Andric StackUpdateLoc--;
17030b57cec5SDimitry Andric else {
17040b57cec5SDimitry Andric // Abort the operation as we can't update all CSR restores.
17050b57cec5SDimitry Andric StackUpdateLoc = MBBI;
17060b57cec5SDimitry Andric break;
17070b57cec5SDimitry Andric }
17080b57cec5SDimitry Andric }
17090b57cec5SDimitry Andric }
17100b57cec5SDimitry Andric
17110b57cec5SDimitry Andric if (FrameSize) {
17120b57cec5SDimitry Andric // In the prologue, the loaded (or persistent) stack pointer value is
17130b57cec5SDimitry Andric // offset by the STDU/STDUX/STWU/STWUX instruction. For targets with red
17140b57cec5SDimitry Andric // zone add this offset back now.
17150b57cec5SDimitry Andric
1716e8d8bef9SDimitry Andric // If the function has a base pointer, the stack pointer has been copied
1717e8d8bef9SDimitry Andric // to it so we can restore it by copying in the other direction.
1718e8d8bef9SDimitry Andric if (HasRedZone && HasBP) {
1719e8d8bef9SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, RBReg).
1720e8d8bef9SDimitry Andric addReg(BPReg).
1721e8d8bef9SDimitry Andric addReg(BPReg);
1722e8d8bef9SDimitry Andric }
17230b57cec5SDimitry Andric // If this function contained a fastcc call and GuaranteedTailCallOpt is
17240b57cec5SDimitry Andric // enabled (=> hasFastCall()==true) the fastcc call might contain a tail
17250b57cec5SDimitry Andric // call which invalidates the stack pointer value in SP(0). So we use the
1726e8d8bef9SDimitry Andric // value of R31 in this case. Similar situation exists with setjmp.
1727e8d8bef9SDimitry Andric else if (FI->hasFastCall() || MF.exposesReturnsTwice()) {
17280b57cec5SDimitry Andric assert(HasFP && "Expecting a valid frame pointer.");
17290b57cec5SDimitry Andric if (!HasRedZone)
17300b57cec5SDimitry Andric RBReg = FPReg;
17310b57cec5SDimitry Andric if (!isLargeFrame) {
17320b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, AddImmInst, RBReg)
17330b57cec5SDimitry Andric .addReg(FPReg).addImm(FrameSize);
17340b57cec5SDimitry Andric } else {
173581ad6265SDimitry Andric TII.materializeImmPostRA(MBB, MBBI, dl, ScratchReg, FrameSize);
17360b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, AddInst)
17370b57cec5SDimitry Andric .addReg(RBReg)
17380b57cec5SDimitry Andric .addReg(FPReg)
17390b57cec5SDimitry Andric .addReg(ScratchReg);
17400b57cec5SDimitry Andric }
17410b57cec5SDimitry Andric } else if (!isLargeFrame && !HasBP && !MFI.hasVarSizedObjects()) {
17420b57cec5SDimitry Andric if (HasRedZone) {
17430b57cec5SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, AddImmInst, SPReg)
17440b57cec5SDimitry Andric .addReg(SPReg)
17450b57cec5SDimitry Andric .addImm(FrameSize);
17460b57cec5SDimitry Andric } else {
17470b57cec5SDimitry Andric // Make sure that adding FrameSize will not overflow the max offset
17480b57cec5SDimitry Andric // size.
17490b57cec5SDimitry Andric assert(FPOffset <= 0 && BPOffset <= 0 && PBPOffset <= 0 &&
17500b57cec5SDimitry Andric "Local offsets should be negative");
17510b57cec5SDimitry Andric SPAdd = FrameSize;
17520b57cec5SDimitry Andric FPOffset += FrameSize;
17530b57cec5SDimitry Andric BPOffset += FrameSize;
17540b57cec5SDimitry Andric PBPOffset += FrameSize;
17550b57cec5SDimitry Andric }
17560b57cec5SDimitry Andric } else {
17570b57cec5SDimitry Andric // We don't want to use ScratchReg as a base register, because it
17580b57cec5SDimitry Andric // could happen to be R0. Use FP instead, but make sure to preserve it.
17590b57cec5SDimitry Andric if (!HasRedZone) {
17600b57cec5SDimitry Andric // If FP is not saved, copy it to ScratchReg.
17610b57cec5SDimitry Andric if (!HasFP)
17620b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, ScratchReg)
17630b57cec5SDimitry Andric .addReg(FPReg)
17640b57cec5SDimitry Andric .addReg(FPReg);
17650b57cec5SDimitry Andric RBReg = FPReg;
17660b57cec5SDimitry Andric }
17670b57cec5SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, LoadInst, RBReg)
17680b57cec5SDimitry Andric .addImm(0)
17690b57cec5SDimitry Andric .addReg(SPReg);
17700b57cec5SDimitry Andric }
17710b57cec5SDimitry Andric }
17720b57cec5SDimitry Andric assert(RBReg != ScratchReg && "Should have avoided ScratchReg");
17730b57cec5SDimitry Andric // If there is no red zone, ScratchReg may be needed for holding a useful
17740b57cec5SDimitry Andric // value (although not the base register). Make sure it is not overwritten
17750b57cec5SDimitry Andric // too early.
17760b57cec5SDimitry Andric
17770b57cec5SDimitry Andric // If we need to restore both the LR and the CR and we only have one
17780b57cec5SDimitry Andric // available scratch register, we must do them one at a time.
17790b57cec5SDimitry Andric if (MustSaveCR && SingleScratchReg && MustSaveLR) {
17800b57cec5SDimitry Andric // Here TempReg == ScratchReg, and in the absence of red zone ScratchReg
17810b57cec5SDimitry Andric // is live here.
17820b57cec5SDimitry Andric assert(HasRedZone && "Expecting red zone");
17835ffd83dbSDimitry Andric BuildMI(MBB, MBBI, dl, LoadWordInst, TempReg)
17845ffd83dbSDimitry Andric .addImm(CRSaveOffset)
17850b57cec5SDimitry Andric .addReg(SPReg);
17860b57cec5SDimitry Andric for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
17875ffd83dbSDimitry Andric BuildMI(MBB, MBBI, dl, MoveToCRInst, MustSaveCRs[i])
17880b57cec5SDimitry Andric .addReg(TempReg, getKillRegState(i == e-1));
17890b57cec5SDimitry Andric }
17900b57cec5SDimitry Andric
17910b57cec5SDimitry Andric // Delay restoring of the LR if ScratchReg is needed. This is ok, since
17920b57cec5SDimitry Andric // LR is stored in the caller's stack frame. ScratchReg will be needed
17930b57cec5SDimitry Andric // if RBReg is anything other than SP. We shouldn't use ScratchReg as
17940b57cec5SDimitry Andric // a base register anyway, because it may happen to be R0.
17950b57cec5SDimitry Andric bool LoadedLR = false;
17960b57cec5SDimitry Andric if (MustSaveLR && RBReg == SPReg && isInt<16>(LROffset+SPAdd)) {
17970b57cec5SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, LoadInst, ScratchReg)
17980b57cec5SDimitry Andric .addImm(LROffset+SPAdd)
17990b57cec5SDimitry Andric .addReg(RBReg);
18000b57cec5SDimitry Andric LoadedLR = true;
18010b57cec5SDimitry Andric }
18020b57cec5SDimitry Andric
18030b57cec5SDimitry Andric if (MustSaveCR && !(SingleScratchReg && MustSaveLR)) {
18040b57cec5SDimitry Andric assert(RBReg == SPReg && "Should be using SP as a base register");
18055ffd83dbSDimitry Andric BuildMI(MBB, MBBI, dl, LoadWordInst, TempReg)
18065ffd83dbSDimitry Andric .addImm(CRSaveOffset)
18070b57cec5SDimitry Andric .addReg(RBReg);
18080b57cec5SDimitry Andric }
18090b57cec5SDimitry Andric
18100b57cec5SDimitry Andric if (HasFP) {
18110b57cec5SDimitry Andric // If there is red zone, restore FP directly, since SP has already been
18120b57cec5SDimitry Andric // restored. Otherwise, restore the value of FP into ScratchReg.
18130b57cec5SDimitry Andric if (HasRedZone || RBReg == SPReg)
18140b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, LoadInst, FPReg)
18150b57cec5SDimitry Andric .addImm(FPOffset)
18160b57cec5SDimitry Andric .addReg(SPReg);
18170b57cec5SDimitry Andric else
18180b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, LoadInst, ScratchReg)
18190b57cec5SDimitry Andric .addImm(FPOffset)
18200b57cec5SDimitry Andric .addReg(RBReg);
18210b57cec5SDimitry Andric }
18220b57cec5SDimitry Andric
18230b57cec5SDimitry Andric if (FI->usesPICBase())
18240b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, LoadInst, PPC::R30)
18250b57cec5SDimitry Andric .addImm(PBPOffset)
18260b57cec5SDimitry Andric .addReg(RBReg);
18270b57cec5SDimitry Andric
18280b57cec5SDimitry Andric if (HasBP)
18290b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, LoadInst, BPReg)
18300b57cec5SDimitry Andric .addImm(BPOffset)
18310b57cec5SDimitry Andric .addReg(RBReg);
18320b57cec5SDimitry Andric
18330b57cec5SDimitry Andric // There is nothing more to be loaded from the stack, so now we can
18340b57cec5SDimitry Andric // restore SP: SP = RBReg + SPAdd.
18350b57cec5SDimitry Andric if (RBReg != SPReg || SPAdd != 0) {
18360b57cec5SDimitry Andric assert(!HasRedZone && "This should not happen with red zone");
18370b57cec5SDimitry Andric // If SPAdd is 0, generate a copy.
18380b57cec5SDimitry Andric if (SPAdd == 0)
18390b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, SPReg)
18400b57cec5SDimitry Andric .addReg(RBReg)
18410b57cec5SDimitry Andric .addReg(RBReg);
18420b57cec5SDimitry Andric else
18430b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, AddImmInst, SPReg)
18440b57cec5SDimitry Andric .addReg(RBReg)
18450b57cec5SDimitry Andric .addImm(SPAdd);
18460b57cec5SDimitry Andric
18470b57cec5SDimitry Andric assert(RBReg != ScratchReg && "Should be using FP or SP as base register");
18480b57cec5SDimitry Andric if (RBReg == FPReg)
18490b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, OrInst, FPReg)
18500b57cec5SDimitry Andric .addReg(ScratchReg)
18510b57cec5SDimitry Andric .addReg(ScratchReg);
18520b57cec5SDimitry Andric
18530b57cec5SDimitry Andric // Now load the LR from the caller's stack frame.
18540b57cec5SDimitry Andric if (MustSaveLR && !LoadedLR)
18550b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, LoadInst, ScratchReg)
18560b57cec5SDimitry Andric .addImm(LROffset)
18570b57cec5SDimitry Andric .addReg(SPReg);
18580b57cec5SDimitry Andric }
18590b57cec5SDimitry Andric
18600b57cec5SDimitry Andric if (MustSaveCR &&
18615ffd83dbSDimitry Andric !(SingleScratchReg && MustSaveLR))
18620b57cec5SDimitry Andric for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
18635ffd83dbSDimitry Andric BuildMI(MBB, MBBI, dl, MoveToCRInst, MustSaveCRs[i])
18640b57cec5SDimitry Andric .addReg(TempReg, getKillRegState(i == e-1));
18650b57cec5SDimitry Andric
1866fe6060f1SDimitry Andric if (MustSaveLR) {
1867fe6060f1SDimitry Andric // If ROP protection is required, an extra instruction is added to compute a
1868fe6060f1SDimitry Andric // hash and then compare it to the hash stored in the prologue.
1869fe6060f1SDimitry Andric if (HasROPProtect) {
1870fe6060f1SDimitry Andric const int SaveIndex = FI->getROPProtectionHashSaveIndex();
1871349cc55cSDimitry Andric const int64_t ImmOffset = MFI.getObjectOffset(SaveIndex);
1872fe6060f1SDimitry Andric assert((ImmOffset <= -8 && ImmOffset >= -512) &&
1873fe6060f1SDimitry Andric "ROP hash check location offset out of range.");
1874fe6060f1SDimitry Andric assert(((ImmOffset & 0x7) == 0) &&
1875fe6060f1SDimitry Andric "ROP hash check location offset must be 8 byte aligned.");
1876fe6060f1SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, HashChk)
1877fe6060f1SDimitry Andric .addReg(ScratchReg)
1878fe6060f1SDimitry Andric .addImm(ImmOffset)
1879fe6060f1SDimitry Andric .addReg(SPReg);
1880fe6060f1SDimitry Andric }
18810b57cec5SDimitry Andric BuildMI(MBB, StackUpdateLoc, dl, MTLRInst).addReg(ScratchReg);
1882fe6060f1SDimitry Andric }
18830b57cec5SDimitry Andric
18840b57cec5SDimitry Andric // Callee pop calling convention. Pop parameter/linkage area. Used for tail
18850b57cec5SDimitry Andric // call optimization
18860b57cec5SDimitry Andric if (IsReturnBlock) {
18870b57cec5SDimitry Andric unsigned RetOpcode = MBBI->getOpcode();
18880b57cec5SDimitry Andric if (MF.getTarget().Options.GuaranteedTailCallOpt &&
18890b57cec5SDimitry Andric (RetOpcode == PPC::BLR || RetOpcode == PPC::BLR8) &&
18900b57cec5SDimitry Andric MF.getFunction().getCallingConv() == CallingConv::Fast) {
18910b57cec5SDimitry Andric PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
18920b57cec5SDimitry Andric unsigned CallerAllocatedAmt = FI->getMinReservedArea();
18930b57cec5SDimitry Andric
18940b57cec5SDimitry Andric if (CallerAllocatedAmt && isInt<16>(CallerAllocatedAmt)) {
18950b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, AddImmInst, SPReg)
18960b57cec5SDimitry Andric .addReg(SPReg).addImm(CallerAllocatedAmt);
18970b57cec5SDimitry Andric } else {
18980b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, LoadImmShiftedInst, ScratchReg)
18990b57cec5SDimitry Andric .addImm(CallerAllocatedAmt >> 16);
19000b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, OrImmInst, ScratchReg)
19010b57cec5SDimitry Andric .addReg(ScratchReg, RegState::Kill)
19020b57cec5SDimitry Andric .addImm(CallerAllocatedAmt & 0xFFFF);
19030b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, AddInst)
19040b57cec5SDimitry Andric .addReg(SPReg)
19050b57cec5SDimitry Andric .addReg(FPReg)
19060b57cec5SDimitry Andric .addReg(ScratchReg);
19070b57cec5SDimitry Andric }
19080b57cec5SDimitry Andric } else {
19090b57cec5SDimitry Andric createTailCallBranchInstr(MBB);
19100b57cec5SDimitry Andric }
19110b57cec5SDimitry Andric }
19120b57cec5SDimitry Andric }
19130b57cec5SDimitry Andric
createTailCallBranchInstr(MachineBasicBlock & MBB) const19140b57cec5SDimitry Andric void PPCFrameLowering::createTailCallBranchInstr(MachineBasicBlock &MBB) const {
19150b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
19160b57cec5SDimitry Andric
19170b57cec5SDimitry Andric // If we got this far a first terminator should exist.
19180b57cec5SDimitry Andric assert(MBBI != MBB.end() && "Failed to find the first terminator.");
19190b57cec5SDimitry Andric
19200b57cec5SDimitry Andric DebugLoc dl = MBBI->getDebugLoc();
19210b57cec5SDimitry Andric const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
19220b57cec5SDimitry Andric
19235ffd83dbSDimitry Andric // Create branch instruction for pseudo tail call return instruction.
19245ffd83dbSDimitry Andric // The TCRETURNdi variants are direct calls. Valid targets for those are
19255ffd83dbSDimitry Andric // MO_GlobalAddress operands as well as MO_ExternalSymbol with PC-Rel
19265ffd83dbSDimitry Andric // since we can tail call external functions with PC-Rel (i.e. we don't need
19275ffd83dbSDimitry Andric // to worry about different TOC pointers). Some of the external functions will
19285ffd83dbSDimitry Andric // be MO_GlobalAddress while others like memcpy for example, are going to
19295ffd83dbSDimitry Andric // be MO_ExternalSymbol.
19300b57cec5SDimitry Andric unsigned RetOpcode = MBBI->getOpcode();
19310b57cec5SDimitry Andric if (RetOpcode == PPC::TCRETURNdi) {
19320b57cec5SDimitry Andric MBBI = MBB.getLastNonDebugInstr();
19330b57cec5SDimitry Andric MachineOperand &JumpTarget = MBBI->getOperand(0);
19345ffd83dbSDimitry Andric if (JumpTarget.isGlobal())
19350b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
19360b57cec5SDimitry Andric addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
19375ffd83dbSDimitry Andric else if (JumpTarget.isSymbol())
19385ffd83dbSDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
19395ffd83dbSDimitry Andric addExternalSymbol(JumpTarget.getSymbolName());
19405ffd83dbSDimitry Andric else
19415ffd83dbSDimitry Andric llvm_unreachable("Expecting Global or External Symbol");
19420b57cec5SDimitry Andric } else if (RetOpcode == PPC::TCRETURNri) {
19430b57cec5SDimitry Andric MBBI = MBB.getLastNonDebugInstr();
19440b57cec5SDimitry Andric assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
19450b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR));
19460b57cec5SDimitry Andric } else if (RetOpcode == PPC::TCRETURNai) {
19470b57cec5SDimitry Andric MBBI = MBB.getLastNonDebugInstr();
19480b57cec5SDimitry Andric MachineOperand &JumpTarget = MBBI->getOperand(0);
19490b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm());
19500b57cec5SDimitry Andric } else if (RetOpcode == PPC::TCRETURNdi8) {
19510b57cec5SDimitry Andric MBBI = MBB.getLastNonDebugInstr();
19520b57cec5SDimitry Andric MachineOperand &JumpTarget = MBBI->getOperand(0);
19535ffd83dbSDimitry Andric if (JumpTarget.isGlobal())
19540b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
19550b57cec5SDimitry Andric addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
19565ffd83dbSDimitry Andric else if (JumpTarget.isSymbol())
19575ffd83dbSDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
19585ffd83dbSDimitry Andric addExternalSymbol(JumpTarget.getSymbolName());
19595ffd83dbSDimitry Andric else
19605ffd83dbSDimitry Andric llvm_unreachable("Expecting Global or External Symbol");
19610b57cec5SDimitry Andric } else if (RetOpcode == PPC::TCRETURNri8) {
19620b57cec5SDimitry Andric MBBI = MBB.getLastNonDebugInstr();
19630b57cec5SDimitry Andric assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
19640b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR8));
19650b57cec5SDimitry Andric } else if (RetOpcode == PPC::TCRETURNai8) {
19660b57cec5SDimitry Andric MBBI = MBB.getLastNonDebugInstr();
19670b57cec5SDimitry Andric MachineOperand &JumpTarget = MBBI->getOperand(0);
19680b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm());
19690b57cec5SDimitry Andric }
19700b57cec5SDimitry Andric }
19710b57cec5SDimitry Andric
determineCalleeSaves(MachineFunction & MF,BitVector & SavedRegs,RegScavenger * RS) const19720b57cec5SDimitry Andric void PPCFrameLowering::determineCalleeSaves(MachineFunction &MF,
19730b57cec5SDimitry Andric BitVector &SavedRegs,
19740b57cec5SDimitry Andric RegScavenger *RS) const {
19750b57cec5SDimitry Andric TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
19760b57cec5SDimitry Andric
19770b57cec5SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
19780b57cec5SDimitry Andric
197981ad6265SDimitry Andric // Do not explicitly save the callee saved VSRp registers.
198081ad6265SDimitry Andric // The individual VSR subregisters will be saved instead.
198181ad6265SDimitry Andric SavedRegs.reset(PPC::VSRp26);
198281ad6265SDimitry Andric SavedRegs.reset(PPC::VSRp27);
198381ad6265SDimitry Andric SavedRegs.reset(PPC::VSRp28);
198481ad6265SDimitry Andric SavedRegs.reset(PPC::VSRp29);
198581ad6265SDimitry Andric SavedRegs.reset(PPC::VSRp30);
198681ad6265SDimitry Andric SavedRegs.reset(PPC::VSRp31);
198781ad6265SDimitry Andric
19880b57cec5SDimitry Andric // Save and clear the LR state.
19890b57cec5SDimitry Andric PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
19900b57cec5SDimitry Andric unsigned LR = RegInfo->getRARegister();
19910b57cec5SDimitry Andric FI->setMustSaveLR(MustSaveLR(MF, LR));
19920b57cec5SDimitry Andric SavedRegs.reset(LR);
19930b57cec5SDimitry Andric
19940b57cec5SDimitry Andric // Save R31 if necessary
19950b57cec5SDimitry Andric int FPSI = FI->getFramePointerSaveIndex();
19968bcb0991SDimitry Andric const bool isPPC64 = Subtarget.isPPC64();
19970b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
19980b57cec5SDimitry Andric
19990b57cec5SDimitry Andric // If the frame pointer save index hasn't been defined yet.
20000b57cec5SDimitry Andric if (!FPSI && needsFP(MF)) {
20010b57cec5SDimitry Andric // Find out what the fix offset of the frame pointer save area.
20020b57cec5SDimitry Andric int FPOffset = getFramePointerSaveOffset();
20030b57cec5SDimitry Andric // Allocate the frame index for frame pointer save area.
20040b57cec5SDimitry Andric FPSI = MFI.CreateFixedObject(isPPC64? 8 : 4, FPOffset, true);
20050b57cec5SDimitry Andric // Save the result.
20060b57cec5SDimitry Andric FI->setFramePointerSaveIndex(FPSI);
20070b57cec5SDimitry Andric }
20080b57cec5SDimitry Andric
20090b57cec5SDimitry Andric int BPSI = FI->getBasePointerSaveIndex();
20100b57cec5SDimitry Andric if (!BPSI && RegInfo->hasBasePointer(MF)) {
20110b57cec5SDimitry Andric int BPOffset = getBasePointerSaveOffset();
20120b57cec5SDimitry Andric // Allocate the frame index for the base pointer save area.
20130b57cec5SDimitry Andric BPSI = MFI.CreateFixedObject(isPPC64? 8 : 4, BPOffset, true);
20140b57cec5SDimitry Andric // Save the result.
20150b57cec5SDimitry Andric FI->setBasePointerSaveIndex(BPSI);
20160b57cec5SDimitry Andric }
20170b57cec5SDimitry Andric
20180b57cec5SDimitry Andric // Reserve stack space for the PIC Base register (R30).
20190b57cec5SDimitry Andric // Only used in SVR4 32-bit.
20200b57cec5SDimitry Andric if (FI->usesPICBase()) {
20210b57cec5SDimitry Andric int PBPSI = MFI.CreateFixedObject(4, -8, true);
20220b57cec5SDimitry Andric FI->setPICBasePointerSaveIndex(PBPSI);
20230b57cec5SDimitry Andric }
20240b57cec5SDimitry Andric
20250b57cec5SDimitry Andric // Make sure we don't explicitly spill r31, because, for example, we have
20260b57cec5SDimitry Andric // some inline asm which explicitly clobbers it, when we otherwise have a
20270b57cec5SDimitry Andric // frame pointer and are using r31's spill slot for the prologue/epilogue
20280b57cec5SDimitry Andric // code. Same goes for the base pointer and the PIC base register.
20290b57cec5SDimitry Andric if (needsFP(MF))
20300b57cec5SDimitry Andric SavedRegs.reset(isPPC64 ? PPC::X31 : PPC::R31);
20310b57cec5SDimitry Andric if (RegInfo->hasBasePointer(MF))
20320b57cec5SDimitry Andric SavedRegs.reset(RegInfo->getBaseRegister(MF));
20330b57cec5SDimitry Andric if (FI->usesPICBase())
20340b57cec5SDimitry Andric SavedRegs.reset(PPC::R30);
20350b57cec5SDimitry Andric
20360b57cec5SDimitry Andric // Reserve stack space to move the linkage area to in case of a tail call.
20370b57cec5SDimitry Andric int TCSPDelta = 0;
20380b57cec5SDimitry Andric if (MF.getTarget().Options.GuaranteedTailCallOpt &&
20390b57cec5SDimitry Andric (TCSPDelta = FI->getTailCallSPDelta()) < 0) {
20400b57cec5SDimitry Andric MFI.CreateFixedObject(-1 * TCSPDelta, TCSPDelta, true);
20410b57cec5SDimitry Andric }
20420b57cec5SDimitry Andric
20435ffd83dbSDimitry Andric // Allocate the nonvolatile CR spill slot iff the function uses CR 2, 3, or 4.
20445ffd83dbSDimitry Andric // For 64-bit SVR4, and all flavors of AIX we create a FixedStack
20455ffd83dbSDimitry Andric // object at the offset of the CR-save slot in the linkage area. The actual
20465ffd83dbSDimitry Andric // save and restore of the condition register will be created as part of the
20475ffd83dbSDimitry Andric // prologue and epilogue insertion, but the FixedStack object is needed to
20485ffd83dbSDimitry Andric // keep the CalleSavedInfo valid.
20495ffd83dbSDimitry Andric if ((SavedRegs.test(PPC::CR2) || SavedRegs.test(PPC::CR3) ||
20500b57cec5SDimitry Andric SavedRegs.test(PPC::CR4))) {
20515ffd83dbSDimitry Andric const uint64_t SpillSize = 4; // Condition register is always 4 bytes.
20525ffd83dbSDimitry Andric const int64_t SpillOffset =
20535ffd83dbSDimitry Andric Subtarget.isPPC64() ? 8 : Subtarget.isAIXABI() ? 4 : -4;
20545ffd83dbSDimitry Andric int FrameIdx =
20555ffd83dbSDimitry Andric MFI.CreateFixedObject(SpillSize, SpillOffset,
20565ffd83dbSDimitry Andric /* IsImmutable */ true, /* IsAliased */ false);
20570b57cec5SDimitry Andric FI->setCRSpillFrameIndex(FrameIdx);
20580b57cec5SDimitry Andric }
20590b57cec5SDimitry Andric }
20600b57cec5SDimitry Andric
processFunctionBeforeFrameFinalized(MachineFunction & MF,RegScavenger * RS) const20610b57cec5SDimitry Andric void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
20620b57cec5SDimitry Andric RegScavenger *RS) const {
20630b57cec5SDimitry Andric // Get callee saved register information.
20640b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
20650b57cec5SDimitry Andric const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
20660b57cec5SDimitry Andric
20670b57cec5SDimitry Andric // If the function is shrink-wrapped, and if the function has a tail call, the
20680b57cec5SDimitry Andric // tail call might not be in the new RestoreBlock, so real branch instruction
20690b57cec5SDimitry Andric // won't be generated by emitEpilogue(), because shrink-wrap has chosen new
20700b57cec5SDimitry Andric // RestoreBlock. So we handle this case here.
20710b57cec5SDimitry Andric if (MFI.getSavePoint() && MFI.hasTailCall()) {
20720b57cec5SDimitry Andric MachineBasicBlock *RestoreBlock = MFI.getRestorePoint();
20730b57cec5SDimitry Andric for (MachineBasicBlock &MBB : MF) {
20740b57cec5SDimitry Andric if (MBB.isReturnBlock() && (&MBB) != RestoreBlock)
20750b57cec5SDimitry Andric createTailCallBranchInstr(MBB);
20760b57cec5SDimitry Andric }
20770b57cec5SDimitry Andric }
20780b57cec5SDimitry Andric
20790b57cec5SDimitry Andric // Early exit if no callee saved registers are modified!
20800b57cec5SDimitry Andric if (CSI.empty() && !needsFP(MF)) {
20810b57cec5SDimitry Andric addScavengingSpillSlot(MF, RS);
20820b57cec5SDimitry Andric return;
20830b57cec5SDimitry Andric }
20840b57cec5SDimitry Andric
20850b57cec5SDimitry Andric unsigned MinGPR = PPC::R31;
20860b57cec5SDimitry Andric unsigned MinG8R = PPC::X31;
20870b57cec5SDimitry Andric unsigned MinFPR = PPC::F31;
20880b57cec5SDimitry Andric unsigned MinVR = Subtarget.hasSPE() ? PPC::S31 : PPC::V31;
20890b57cec5SDimitry Andric
20900b57cec5SDimitry Andric bool HasGPSaveArea = false;
20910b57cec5SDimitry Andric bool HasG8SaveArea = false;
20920b57cec5SDimitry Andric bool HasFPSaveArea = false;
20930b57cec5SDimitry Andric bool HasVRSaveArea = false;
20940b57cec5SDimitry Andric
20950b57cec5SDimitry Andric SmallVector<CalleeSavedInfo, 18> GPRegs;
20960b57cec5SDimitry Andric SmallVector<CalleeSavedInfo, 18> G8Regs;
20970b57cec5SDimitry Andric SmallVector<CalleeSavedInfo, 18> FPRegs;
20980b57cec5SDimitry Andric SmallVector<CalleeSavedInfo, 18> VRegs;
20990b57cec5SDimitry Andric
21004824e7fdSDimitry Andric for (const CalleeSavedInfo &I : CSI) {
210104eeddc0SDimitry Andric Register Reg = I.getReg();
21020b57cec5SDimitry Andric assert((!MF.getInfo<PPCFunctionInfo>()->mustSaveTOC() ||
21030b57cec5SDimitry Andric (Reg != PPC::X2 && Reg != PPC::R2)) &&
21040b57cec5SDimitry Andric "Not expecting to try to spill R2 in a function that must save TOC");
21058bcb0991SDimitry Andric if (PPC::GPRCRegClass.contains(Reg)) {
21060b57cec5SDimitry Andric HasGPSaveArea = true;
21070b57cec5SDimitry Andric
21084824e7fdSDimitry Andric GPRegs.push_back(I);
21090b57cec5SDimitry Andric
21100b57cec5SDimitry Andric if (Reg < MinGPR) {
21110b57cec5SDimitry Andric MinGPR = Reg;
21120b57cec5SDimitry Andric }
21130b57cec5SDimitry Andric } else if (PPC::G8RCRegClass.contains(Reg)) {
21140b57cec5SDimitry Andric HasG8SaveArea = true;
21150b57cec5SDimitry Andric
21164824e7fdSDimitry Andric G8Regs.push_back(I);
21170b57cec5SDimitry Andric
21180b57cec5SDimitry Andric if (Reg < MinG8R) {
21190b57cec5SDimitry Andric MinG8R = Reg;
21200b57cec5SDimitry Andric }
21210b57cec5SDimitry Andric } else if (PPC::F8RCRegClass.contains(Reg)) {
21220b57cec5SDimitry Andric HasFPSaveArea = true;
21230b57cec5SDimitry Andric
21244824e7fdSDimitry Andric FPRegs.push_back(I);
21250b57cec5SDimitry Andric
21260b57cec5SDimitry Andric if (Reg < MinFPR) {
21270b57cec5SDimitry Andric MinFPR = Reg;
21280b57cec5SDimitry Andric }
21290b57cec5SDimitry Andric } else if (PPC::CRBITRCRegClass.contains(Reg) ||
21300b57cec5SDimitry Andric PPC::CRRCRegClass.contains(Reg)) {
21310b57cec5SDimitry Andric ; // do nothing, as we already know whether CRs are spilled
21320b57cec5SDimitry Andric } else if (PPC::VRRCRegClass.contains(Reg) ||
21330b57cec5SDimitry Andric PPC::SPERCRegClass.contains(Reg)) {
21340b57cec5SDimitry Andric // Altivec and SPE are mutually exclusive, but have the same stack
21350b57cec5SDimitry Andric // alignment requirements, so overload the save area for both cases.
21360b57cec5SDimitry Andric HasVRSaveArea = true;
21370b57cec5SDimitry Andric
21384824e7fdSDimitry Andric VRegs.push_back(I);
21390b57cec5SDimitry Andric
21400b57cec5SDimitry Andric if (Reg < MinVR) {
21410b57cec5SDimitry Andric MinVR = Reg;
21420b57cec5SDimitry Andric }
21430b57cec5SDimitry Andric } else {
21440b57cec5SDimitry Andric llvm_unreachable("Unknown RegisterClass!");
21450b57cec5SDimitry Andric }
21460b57cec5SDimitry Andric }
21470b57cec5SDimitry Andric
21480b57cec5SDimitry Andric PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>();
21490b57cec5SDimitry Andric const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
21500b57cec5SDimitry Andric
21510b57cec5SDimitry Andric int64_t LowerBound = 0;
21520b57cec5SDimitry Andric
21530b57cec5SDimitry Andric // Take into account stack space reserved for tail calls.
21540b57cec5SDimitry Andric int TCSPDelta = 0;
21550b57cec5SDimitry Andric if (MF.getTarget().Options.GuaranteedTailCallOpt &&
21560b57cec5SDimitry Andric (TCSPDelta = PFI->getTailCallSPDelta()) < 0) {
21570b57cec5SDimitry Andric LowerBound = TCSPDelta;
21580b57cec5SDimitry Andric }
21590b57cec5SDimitry Andric
21600b57cec5SDimitry Andric // The Floating-point register save area is right below the back chain word
21610b57cec5SDimitry Andric // of the previous stack frame.
21620b57cec5SDimitry Andric if (HasFPSaveArea) {
21630b57cec5SDimitry Andric for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) {
21640b57cec5SDimitry Andric int FI = FPRegs[i].getFrameIdx();
21650b57cec5SDimitry Andric
21660b57cec5SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
21670b57cec5SDimitry Andric }
21680b57cec5SDimitry Andric
21690b57cec5SDimitry Andric LowerBound -= (31 - TRI->getEncodingValue(MinFPR) + 1) * 8;
21700b57cec5SDimitry Andric }
21710b57cec5SDimitry Andric
21720b57cec5SDimitry Andric // Check whether the frame pointer register is allocated. If so, make sure it
21730b57cec5SDimitry Andric // is spilled to the correct offset.
21740b57cec5SDimitry Andric if (needsFP(MF)) {
21750b57cec5SDimitry Andric int FI = PFI->getFramePointerSaveIndex();
21760b57cec5SDimitry Andric assert(FI && "No Frame Pointer Save Slot!");
21770b57cec5SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
21780b57cec5SDimitry Andric // FP is R31/X31, so no need to update MinGPR/MinG8R.
21790b57cec5SDimitry Andric HasGPSaveArea = true;
21800b57cec5SDimitry Andric }
21810b57cec5SDimitry Andric
21820b57cec5SDimitry Andric if (PFI->usesPICBase()) {
21830b57cec5SDimitry Andric int FI = PFI->getPICBasePointerSaveIndex();
21840b57cec5SDimitry Andric assert(FI && "No PIC Base Pointer Save Slot!");
21850b57cec5SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
21860b57cec5SDimitry Andric
21870b57cec5SDimitry Andric MinGPR = std::min<unsigned>(MinGPR, PPC::R30);
21880b57cec5SDimitry Andric HasGPSaveArea = true;
21890b57cec5SDimitry Andric }
21900b57cec5SDimitry Andric
21910b57cec5SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
21920b57cec5SDimitry Andric if (RegInfo->hasBasePointer(MF)) {
21930b57cec5SDimitry Andric int FI = PFI->getBasePointerSaveIndex();
21940b57cec5SDimitry Andric assert(FI && "No Base Pointer Save Slot!");
21950b57cec5SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
21960b57cec5SDimitry Andric
21978bcb0991SDimitry Andric Register BP = RegInfo->getBaseRegister(MF);
21980b57cec5SDimitry Andric if (PPC::G8RCRegClass.contains(BP)) {
21990b57cec5SDimitry Andric MinG8R = std::min<unsigned>(MinG8R, BP);
22000b57cec5SDimitry Andric HasG8SaveArea = true;
22010b57cec5SDimitry Andric } else if (PPC::GPRCRegClass.contains(BP)) {
22020b57cec5SDimitry Andric MinGPR = std::min<unsigned>(MinGPR, BP);
22030b57cec5SDimitry Andric HasGPSaveArea = true;
22040b57cec5SDimitry Andric }
22050b57cec5SDimitry Andric }
22060b57cec5SDimitry Andric
22070b57cec5SDimitry Andric // General register save area starts right below the Floating-point
22080b57cec5SDimitry Andric // register save area.
22090b57cec5SDimitry Andric if (HasGPSaveArea || HasG8SaveArea) {
22100b57cec5SDimitry Andric // Move general register save area spill slots down, taking into account
22110b57cec5SDimitry Andric // the size of the Floating-point register save area.
22120b57cec5SDimitry Andric for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) {
22130b57cec5SDimitry Andric if (!GPRegs[i].isSpilledToReg()) {
22140b57cec5SDimitry Andric int FI = GPRegs[i].getFrameIdx();
22150b57cec5SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
22160b57cec5SDimitry Andric }
22170b57cec5SDimitry Andric }
22180b57cec5SDimitry Andric
22190b57cec5SDimitry Andric // Move general register save area spill slots down, taking into account
22200b57cec5SDimitry Andric // the size of the Floating-point register save area.
22210b57cec5SDimitry Andric for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) {
22220b57cec5SDimitry Andric if (!G8Regs[i].isSpilledToReg()) {
22230b57cec5SDimitry Andric int FI = G8Regs[i].getFrameIdx();
22240b57cec5SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
22250b57cec5SDimitry Andric }
22260b57cec5SDimitry Andric }
22270b57cec5SDimitry Andric
22280b57cec5SDimitry Andric unsigned MinReg =
22290b57cec5SDimitry Andric std::min<unsigned>(TRI->getEncodingValue(MinGPR),
22300b57cec5SDimitry Andric TRI->getEncodingValue(MinG8R));
22310b57cec5SDimitry Andric
22325ffd83dbSDimitry Andric const unsigned GPRegSize = Subtarget.isPPC64() ? 8 : 4;
22335ffd83dbSDimitry Andric LowerBound -= (31 - MinReg + 1) * GPRegSize;
22340b57cec5SDimitry Andric }
22350b57cec5SDimitry Andric
22360b57cec5SDimitry Andric // For 32-bit only, the CR save area is below the general register
22370b57cec5SDimitry Andric // save area. For 64-bit SVR4, the CR save area is addressed relative
22380b57cec5SDimitry Andric // to the stack pointer and hence does not need an adjustment here.
22390b57cec5SDimitry Andric // Only CR2 (the first nonvolatile spilled) has an associated frame
22400b57cec5SDimitry Andric // index so that we have a single uniform save area.
22415ffd83dbSDimitry Andric if (spillsCR(MF) && Subtarget.is32BitELFABI()) {
22420b57cec5SDimitry Andric // Adjust the frame index of the CR spill slot.
22435ffd83dbSDimitry Andric for (const auto &CSInfo : CSI) {
22445ffd83dbSDimitry Andric if (CSInfo.getReg() == PPC::CR2) {
22455ffd83dbSDimitry Andric int FI = CSInfo.getFrameIdx();
22460b57cec5SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
22475ffd83dbSDimitry Andric break;
22480b57cec5SDimitry Andric }
22490b57cec5SDimitry Andric }
22500b57cec5SDimitry Andric
22510b57cec5SDimitry Andric LowerBound -= 4; // The CR save area is always 4 bytes long.
22520b57cec5SDimitry Andric }
22530b57cec5SDimitry Andric
22540b57cec5SDimitry Andric // Both Altivec and SPE have the same alignment and padding requirements
22550b57cec5SDimitry Andric // within the stack frame.
22560b57cec5SDimitry Andric if (HasVRSaveArea) {
22570b57cec5SDimitry Andric // Insert alignment padding, we need 16-byte alignment. Note: for positive
22580b57cec5SDimitry Andric // number the alignment formula is : y = (x + (n-1)) & (~(n-1)). But since
22590b57cec5SDimitry Andric // we are using negative number here (the stack grows downward). We should
22600b57cec5SDimitry Andric // use formula : y = x & (~(n-1)). Where x is the size before aligning, n
22610b57cec5SDimitry Andric // is the alignment size ( n = 16 here) and y is the size after aligning.
22620b57cec5SDimitry Andric assert(LowerBound <= 0 && "Expect LowerBound have a non-positive value!");
22630b57cec5SDimitry Andric LowerBound &= ~(15);
22640b57cec5SDimitry Andric
22650b57cec5SDimitry Andric for (unsigned i = 0, e = VRegs.size(); i != e; ++i) {
22660b57cec5SDimitry Andric int FI = VRegs[i].getFrameIdx();
22670b57cec5SDimitry Andric
22680b57cec5SDimitry Andric MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI));
22690b57cec5SDimitry Andric }
22700b57cec5SDimitry Andric }
22710b57cec5SDimitry Andric
22720b57cec5SDimitry Andric addScavengingSpillSlot(MF, RS);
22730b57cec5SDimitry Andric }
22740b57cec5SDimitry Andric
22750b57cec5SDimitry Andric void
addScavengingSpillSlot(MachineFunction & MF,RegScavenger * RS) const22760b57cec5SDimitry Andric PPCFrameLowering::addScavengingSpillSlot(MachineFunction &MF,
22770b57cec5SDimitry Andric RegScavenger *RS) const {
22780b57cec5SDimitry Andric // Reserve a slot closest to SP or frame pointer if we have a dynalloc or
22790b57cec5SDimitry Andric // a large stack, which will require scavenging a register to materialize a
22800b57cec5SDimitry Andric // large offset.
22810b57cec5SDimitry Andric
22820b57cec5SDimitry Andric // We need to have a scavenger spill slot for spills if the frame size is
22830b57cec5SDimitry Andric // large. In case there is no free register for large-offset addressing,
22840b57cec5SDimitry Andric // this slot is used for the necessary emergency spill. Also, we need the
22850b57cec5SDimitry Andric // slot for dynamic stack allocations.
22860b57cec5SDimitry Andric
22870b57cec5SDimitry Andric // The scavenger might be invoked if the frame offset does not fit into
2288fe013be4SDimitry Andric // the 16-bit immediate in case of not SPE and 8-bit in case of SPE.
2289fe013be4SDimitry Andric // We don't know the complete frame size here because we've not yet computed
2290fe013be4SDimitry Andric // callee-saved register spills or the needed alignment padding.
22910b57cec5SDimitry Andric unsigned StackSize = determineFrameLayout(MF, true);
22920b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
2293fe013be4SDimitry Andric bool NeedSpills = Subtarget.hasSPE() ? !isInt<8>(StackSize) : !isInt<16>(StackSize);
2294fe013be4SDimitry Andric
2295e8d8bef9SDimitry Andric if (MFI.hasVarSizedObjects() || spillsCR(MF) || hasNonRISpills(MF) ||
2296fe013be4SDimitry Andric (hasSpills(MF) && NeedSpills)) {
22970b57cec5SDimitry Andric const TargetRegisterClass &GPRC = PPC::GPRCRegClass;
22980b57cec5SDimitry Andric const TargetRegisterClass &G8RC = PPC::G8RCRegClass;
22990b57cec5SDimitry Andric const TargetRegisterClass &RC = Subtarget.isPPC64() ? G8RC : GPRC;
23000b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *Subtarget.getRegisterInfo();
23010b57cec5SDimitry Andric unsigned Size = TRI.getSpillSize(RC);
23025ffd83dbSDimitry Andric Align Alignment = TRI.getSpillAlign(RC);
23035ffd83dbSDimitry Andric RS->addScavengingFrameIndex(MFI.CreateStackObject(Size, Alignment, false));
23040b57cec5SDimitry Andric
23050b57cec5SDimitry Andric // Might we have over-aligned allocas?
23065ffd83dbSDimitry Andric bool HasAlVars =
23075ffd83dbSDimitry Andric MFI.hasVarSizedObjects() && MFI.getMaxAlign() > getStackAlign();
23080b57cec5SDimitry Andric
23090b57cec5SDimitry Andric // These kinds of spills might need two registers.
2310e8d8bef9SDimitry Andric if (spillsCR(MF) || HasAlVars)
23115ffd83dbSDimitry Andric RS->addScavengingFrameIndex(
23125ffd83dbSDimitry Andric MFI.CreateStackObject(Size, Alignment, false));
23130b57cec5SDimitry Andric }
23140b57cec5SDimitry Andric }
23150b57cec5SDimitry Andric
23160b57cec5SDimitry Andric // This function checks if a callee saved gpr can be spilled to a volatile
23170b57cec5SDimitry Andric // vector register. This occurs for leaf functions when the option
23180b57cec5SDimitry Andric // ppc-enable-pe-vector-spills is enabled. If there are any remaining registers
23190b57cec5SDimitry Andric // which were not spilled to vectors, return false so the target independent
23200b57cec5SDimitry Andric // code can handle them by assigning a FrameIdx to a stack slot.
assignCalleeSavedSpillSlots(MachineFunction & MF,const TargetRegisterInfo * TRI,std::vector<CalleeSavedInfo> & CSI) const23210b57cec5SDimitry Andric bool PPCFrameLowering::assignCalleeSavedSpillSlots(
23220b57cec5SDimitry Andric MachineFunction &MF, const TargetRegisterInfo *TRI,
23230b57cec5SDimitry Andric std::vector<CalleeSavedInfo> &CSI) const {
23240b57cec5SDimitry Andric
23250b57cec5SDimitry Andric if (CSI.empty())
23260b57cec5SDimitry Andric return true; // Early exit if no callee saved registers are modified!
23270b57cec5SDimitry Andric
2328fe013be4SDimitry Andric const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
2329fe013be4SDimitry Andric const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
2330fe013be4SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo();
2331fe013be4SDimitry Andric
2332fe013be4SDimitry Andric if (Subtarget.hasSPE()) {
2333fe013be4SDimitry Andric // In case of SPE we only have SuperRegs and CRs
2334fe013be4SDimitry Andric // in our CalleSaveInfo vector.
2335fe013be4SDimitry Andric
2336fe013be4SDimitry Andric for (auto &CalleeSaveReg : CSI) {
2337c9157d92SDimitry Andric MCPhysReg Reg = CalleeSaveReg.getReg();
2338c9157d92SDimitry Andric MCPhysReg Lower = RegInfo->getSubReg(Reg, 1);
2339c9157d92SDimitry Andric MCPhysReg Higher = RegInfo->getSubReg(Reg, 2);
2340fe013be4SDimitry Andric
2341c9157d92SDimitry Andric if ( // Check only for SuperRegs.
2342c9157d92SDimitry Andric Lower &&
2343fe013be4SDimitry Andric // Replace Reg if only lower-32 bits modified
2344c9157d92SDimitry Andric !MRI.isPhysRegModified(Higher))
2345c9157d92SDimitry Andric CalleeSaveReg = CalleeSavedInfo(Lower);
2346fe013be4SDimitry Andric }
2347fe013be4SDimitry Andric }
2348fe013be4SDimitry Andric
23490b57cec5SDimitry Andric // Early exit if cannot spill gprs to volatile vector registers.
23500b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
23510b57cec5SDimitry Andric if (!EnablePEVectorSpills || MFI.hasCalls() || !Subtarget.hasP9Vector())
23520b57cec5SDimitry Andric return false;
23530b57cec5SDimitry Andric
23540b57cec5SDimitry Andric // Build a BitVector of VSRs that can be used for spilling GPRs.
23550b57cec5SDimitry Andric BitVector BVAllocatable = TRI->getAllocatableSet(MF);
23560b57cec5SDimitry Andric BitVector BVCalleeSaved(TRI->getNumRegs());
23570b57cec5SDimitry Andric for (unsigned i = 0; CSRegs[i]; ++i)
23580b57cec5SDimitry Andric BVCalleeSaved.set(CSRegs[i]);
23590b57cec5SDimitry Andric
23600b57cec5SDimitry Andric for (unsigned Reg : BVAllocatable.set_bits()) {
2361fe6060f1SDimitry Andric // Set to 0 if the register is not a volatile VSX register, or if it is
23620b57cec5SDimitry Andric // used in the function.
2363fe6060f1SDimitry Andric if (BVCalleeSaved[Reg] || !PPC::VSRCRegClass.contains(Reg) ||
2364fe013be4SDimitry Andric MRI.isPhysRegUsed(Reg))
23650b57cec5SDimitry Andric BVAllocatable.reset(Reg);
23660b57cec5SDimitry Andric }
23670b57cec5SDimitry Andric
23680b57cec5SDimitry Andric bool AllSpilledToReg = true;
2369fe6060f1SDimitry Andric unsigned LastVSRUsedForSpill = 0;
23700b57cec5SDimitry Andric for (auto &CS : CSI) {
23710b57cec5SDimitry Andric if (BVAllocatable.none())
23720b57cec5SDimitry Andric return false;
23730b57cec5SDimitry Andric
237404eeddc0SDimitry Andric Register Reg = CS.getReg();
2375fe6060f1SDimitry Andric
2376fe6060f1SDimitry Andric if (!PPC::G8RCRegClass.contains(Reg)) {
23770b57cec5SDimitry Andric AllSpilledToReg = false;
23780b57cec5SDimitry Andric continue;
23790b57cec5SDimitry Andric }
23800b57cec5SDimitry Andric
2381fe6060f1SDimitry Andric // For P9, we can reuse LastVSRUsedForSpill to spill two GPRs
2382fe6060f1SDimitry Andric // into one VSR using the mtvsrdd instruction.
2383fe6060f1SDimitry Andric if (LastVSRUsedForSpill != 0) {
2384fe6060f1SDimitry Andric CS.setDstReg(LastVSRUsedForSpill);
2385fe6060f1SDimitry Andric BVAllocatable.reset(LastVSRUsedForSpill);
2386fe6060f1SDimitry Andric LastVSRUsedForSpill = 0;
2387fe6060f1SDimitry Andric continue;
2388fe6060f1SDimitry Andric }
2389fe6060f1SDimitry Andric
23900b57cec5SDimitry Andric unsigned VolatileVFReg = BVAllocatable.find_first();
23910b57cec5SDimitry Andric if (VolatileVFReg < BVAllocatable.size()) {
23920b57cec5SDimitry Andric CS.setDstReg(VolatileVFReg);
2393fe6060f1SDimitry Andric LastVSRUsedForSpill = VolatileVFReg;
23940b57cec5SDimitry Andric } else {
23950b57cec5SDimitry Andric AllSpilledToReg = false;
23960b57cec5SDimitry Andric }
23970b57cec5SDimitry Andric }
23980b57cec5SDimitry Andric return AllSpilledToReg;
23990b57cec5SDimitry Andric }
24000b57cec5SDimitry Andric
spillCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,ArrayRef<CalleeSavedInfo> CSI,const TargetRegisterInfo * TRI) const24015ffd83dbSDimitry Andric bool PPCFrameLowering::spillCalleeSavedRegisters(
24025ffd83dbSDimitry Andric MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
24035ffd83dbSDimitry Andric ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
24040b57cec5SDimitry Andric
24050b57cec5SDimitry Andric MachineFunction *MF = MBB.getParent();
24060b57cec5SDimitry Andric const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
24070b57cec5SDimitry Andric PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
24080b57cec5SDimitry Andric bool MustSaveTOC = FI->mustSaveTOC();
24090b57cec5SDimitry Andric DebugLoc DL;
24100b57cec5SDimitry Andric bool CRSpilled = false;
24110b57cec5SDimitry Andric MachineInstrBuilder CRMIB;
2412fe6060f1SDimitry Andric BitVector Spilled(TRI->getNumRegs());
2413fe6060f1SDimitry Andric
2414fe6060f1SDimitry Andric VSRContainingGPRs.clear();
2415fe6060f1SDimitry Andric
2416fe6060f1SDimitry Andric // Map each VSR to GPRs to be spilled with into it. Single VSR can contain one
2417fe6060f1SDimitry Andric // or two GPRs, so we need table to record information for later save/restore.
241881ad6265SDimitry Andric for (const CalleeSavedInfo &Info : CSI) {
2419fe6060f1SDimitry Andric if (Info.isSpilledToReg()) {
2420fe6060f1SDimitry Andric auto &SpilledVSR =
2421fe6060f1SDimitry Andric VSRContainingGPRs.FindAndConstruct(Info.getDstReg()).second;
2422fe6060f1SDimitry Andric assert(SpilledVSR.second == 0 &&
2423fe6060f1SDimitry Andric "Can't spill more than two GPRs into VSR!");
2424fe6060f1SDimitry Andric if (SpilledVSR.first == 0)
2425fe6060f1SDimitry Andric SpilledVSR.first = Info.getReg();
2426fe6060f1SDimitry Andric else
2427fe6060f1SDimitry Andric SpilledVSR.second = Info.getReg();
2428fe6060f1SDimitry Andric }
242981ad6265SDimitry Andric }
24300b57cec5SDimitry Andric
24314824e7fdSDimitry Andric for (const CalleeSavedInfo &I : CSI) {
243204eeddc0SDimitry Andric Register Reg = I.getReg();
24330b57cec5SDimitry Andric
24340b57cec5SDimitry Andric // CR2 through CR4 are the nonvolatile CR fields.
24350b57cec5SDimitry Andric bool IsCRField = PPC::CR2 <= Reg && Reg <= PPC::CR4;
24360b57cec5SDimitry Andric
24370b57cec5SDimitry Andric // Add the callee-saved register as live-in; it's killed at the spill.
24380b57cec5SDimitry Andric // Do not do this for callee-saved registers that are live-in to the
24390b57cec5SDimitry Andric // function because they will already be marked live-in and this will be
24400b57cec5SDimitry Andric // adding it for a second time. It is an error to add the same register
24410b57cec5SDimitry Andric // to the set more than once.
24420b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF->getRegInfo();
24430b57cec5SDimitry Andric bool IsLiveIn = MRI.isLiveIn(Reg);
24440b57cec5SDimitry Andric if (!IsLiveIn)
24450b57cec5SDimitry Andric MBB.addLiveIn(Reg);
24460b57cec5SDimitry Andric
24470b57cec5SDimitry Andric if (CRSpilled && IsCRField) {
24480b57cec5SDimitry Andric CRMIB.addReg(Reg, RegState::ImplicitKill);
24490b57cec5SDimitry Andric continue;
24500b57cec5SDimitry Andric }
24510b57cec5SDimitry Andric
24520b57cec5SDimitry Andric // The actual spill will happen in the prologue.
24530b57cec5SDimitry Andric if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)
24540b57cec5SDimitry Andric continue;
24550b57cec5SDimitry Andric
24560b57cec5SDimitry Andric // Insert the spill to the stack frame.
24570b57cec5SDimitry Andric if (IsCRField) {
24580b57cec5SDimitry Andric PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
24595ffd83dbSDimitry Andric if (!Subtarget.is32BitELFABI()) {
24600b57cec5SDimitry Andric // The actual spill will happen at the start of the prologue.
24610b57cec5SDimitry Andric FuncInfo->addMustSaveCR(Reg);
24620b57cec5SDimitry Andric } else {
24630b57cec5SDimitry Andric CRSpilled = true;
24640b57cec5SDimitry Andric FuncInfo->setSpillsCR();
24650b57cec5SDimitry Andric
24660b57cec5SDimitry Andric // 32-bit: FP-relative. Note that we made sure CR2-CR4 all have
24670b57cec5SDimitry Andric // the same frame index in PPCRegisterInfo::hasReservedSpillSlot.
24680b57cec5SDimitry Andric CRMIB = BuildMI(*MF, DL, TII.get(PPC::MFCR), PPC::R12)
24690b57cec5SDimitry Andric .addReg(Reg, RegState::ImplicitKill);
24700b57cec5SDimitry Andric
24710b57cec5SDimitry Andric MBB.insert(MI, CRMIB);
24720b57cec5SDimitry Andric MBB.insert(MI, addFrameReference(BuildMI(*MF, DL, TII.get(PPC::STW))
24730b57cec5SDimitry Andric .addReg(PPC::R12,
24740b57cec5SDimitry Andric getKillRegState(true)),
24754824e7fdSDimitry Andric I.getFrameIdx()));
24760b57cec5SDimitry Andric }
24770b57cec5SDimitry Andric } else {
24784824e7fdSDimitry Andric if (I.isSpilledToReg()) {
24794824e7fdSDimitry Andric unsigned Dst = I.getDstReg();
2480fe6060f1SDimitry Andric
2481fe6060f1SDimitry Andric if (Spilled[Dst])
2482fe6060f1SDimitry Andric continue;
2483fe6060f1SDimitry Andric
2484fe6060f1SDimitry Andric if (VSRContainingGPRs[Dst].second != 0) {
2485fe6060f1SDimitry Andric assert(Subtarget.hasP9Vector() &&
2486fe6060f1SDimitry Andric "mtvsrdd is unavailable on pre-P9 targets.");
2487fe6060f1SDimitry Andric
2488fe6060f1SDimitry Andric NumPESpillVSR += 2;
2489fe6060f1SDimitry Andric BuildMI(MBB, MI, DL, TII.get(PPC::MTVSRDD), Dst)
2490fe6060f1SDimitry Andric .addReg(VSRContainingGPRs[Dst].first, getKillRegState(true))
2491fe6060f1SDimitry Andric .addReg(VSRContainingGPRs[Dst].second, getKillRegState(true));
2492fe6060f1SDimitry Andric } else if (VSRContainingGPRs[Dst].second == 0) {
2493fe6060f1SDimitry Andric assert(Subtarget.hasP8Vector() &&
2494fe6060f1SDimitry Andric "Can't move GPR to VSR on pre-P8 targets.");
2495fe6060f1SDimitry Andric
2496fe6060f1SDimitry Andric ++NumPESpillVSR;
2497fe6060f1SDimitry Andric BuildMI(MBB, MI, DL, TII.get(PPC::MTVSRD),
2498fe6060f1SDimitry Andric TRI->getSubReg(Dst, PPC::sub_64))
2499fe6060f1SDimitry Andric .addReg(VSRContainingGPRs[Dst].first, getKillRegState(true));
2500fe6060f1SDimitry Andric } else {
2501fe6060f1SDimitry Andric llvm_unreachable("More than two GPRs spilled to a VSR!");
2502fe6060f1SDimitry Andric }
2503fe6060f1SDimitry Andric Spilled.set(Dst);
25040b57cec5SDimitry Andric } else {
25050b57cec5SDimitry Andric const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
25060b57cec5SDimitry Andric // Use !IsLiveIn for the kill flag.
25070b57cec5SDimitry Andric // We do not want to kill registers that are live in this function
25080b57cec5SDimitry Andric // before their use because they will become undefined registers.
25095ffd83dbSDimitry Andric // Functions without NoUnwind need to preserve the order of elements in
25105ffd83dbSDimitry Andric // saved vector registers.
25115ffd83dbSDimitry Andric if (Subtarget.needsSwapsForVSXMemOps() &&
25125ffd83dbSDimitry Andric !MF->getFunction().hasFnAttribute(Attribute::NoUnwind))
25135ffd83dbSDimitry Andric TII.storeRegToStackSlotNoUpd(MBB, MI, Reg, !IsLiveIn,
25144824e7fdSDimitry Andric I.getFrameIdx(), RC, TRI);
25155ffd83dbSDimitry Andric else
2516bdd1243dSDimitry Andric TII.storeRegToStackSlot(MBB, MI, Reg, !IsLiveIn, I.getFrameIdx(), RC,
2517bdd1243dSDimitry Andric TRI, Register());
25180b57cec5SDimitry Andric }
25190b57cec5SDimitry Andric }
25200b57cec5SDimitry Andric }
25210b57cec5SDimitry Andric return true;
25220b57cec5SDimitry Andric }
25230b57cec5SDimitry Andric
restoreCRs(bool is31,bool CR2Spilled,bool CR3Spilled,bool CR4Spilled,MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,ArrayRef<CalleeSavedInfo> CSI,unsigned CSIIndex)25245ffd83dbSDimitry Andric static void restoreCRs(bool is31, bool CR2Spilled, bool CR3Spilled,
25255ffd83dbSDimitry Andric bool CR4Spilled, MachineBasicBlock &MBB,
25265ffd83dbSDimitry Andric MachineBasicBlock::iterator MI,
25275ffd83dbSDimitry Andric ArrayRef<CalleeSavedInfo> CSI, unsigned CSIIndex) {
25280b57cec5SDimitry Andric
25290b57cec5SDimitry Andric MachineFunction *MF = MBB.getParent();
25300b57cec5SDimitry Andric const PPCInstrInfo &TII = *MF->getSubtarget<PPCSubtarget>().getInstrInfo();
25310b57cec5SDimitry Andric DebugLoc DL;
25325ffd83dbSDimitry Andric unsigned MoveReg = PPC::R12;
25330b57cec5SDimitry Andric
25340b57cec5SDimitry Andric // 32-bit: FP-relative
25355ffd83dbSDimitry Andric MBB.insert(MI,
25365ffd83dbSDimitry Andric addFrameReference(BuildMI(*MF, DL, TII.get(PPC::LWZ), MoveReg),
25370b57cec5SDimitry Andric CSI[CSIIndex].getFrameIdx()));
25380b57cec5SDimitry Andric
25395ffd83dbSDimitry Andric unsigned RestoreOp = PPC::MTOCRF;
25400b57cec5SDimitry Andric if (CR2Spilled)
25410b57cec5SDimitry Andric MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR2)
25420b57cec5SDimitry Andric .addReg(MoveReg, getKillRegState(!CR3Spilled && !CR4Spilled)));
25430b57cec5SDimitry Andric
25440b57cec5SDimitry Andric if (CR3Spilled)
25450b57cec5SDimitry Andric MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR3)
25460b57cec5SDimitry Andric .addReg(MoveReg, getKillRegState(!CR4Spilled)));
25470b57cec5SDimitry Andric
25480b57cec5SDimitry Andric if (CR4Spilled)
25490b57cec5SDimitry Andric MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR4)
25500b57cec5SDimitry Andric .addReg(MoveReg, getKillRegState(true)));
25510b57cec5SDimitry Andric }
25520b57cec5SDimitry Andric
25530b57cec5SDimitry Andric MachineBasicBlock::iterator PPCFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const25540b57cec5SDimitry Andric eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
25550b57cec5SDimitry Andric MachineBasicBlock::iterator I) const {
25560b57cec5SDimitry Andric const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
25570b57cec5SDimitry Andric if (MF.getTarget().Options.GuaranteedTailCallOpt &&
25580b57cec5SDimitry Andric I->getOpcode() == PPC::ADJCALLSTACKUP) {
25590b57cec5SDimitry Andric // Add (actually subtract) back the amount the callee popped on return.
25600b57cec5SDimitry Andric if (int CalleeAmt = I->getOperand(1).getImm()) {
25610b57cec5SDimitry Andric bool is64Bit = Subtarget.isPPC64();
25620b57cec5SDimitry Andric CalleeAmt *= -1;
25630b57cec5SDimitry Andric unsigned StackReg = is64Bit ? PPC::X1 : PPC::R1;
25640b57cec5SDimitry Andric unsigned TmpReg = is64Bit ? PPC::X0 : PPC::R0;
25650b57cec5SDimitry Andric unsigned ADDIInstr = is64Bit ? PPC::ADDI8 : PPC::ADDI;
25660b57cec5SDimitry Andric unsigned ADDInstr = is64Bit ? PPC::ADD8 : PPC::ADD4;
25670b57cec5SDimitry Andric unsigned LISInstr = is64Bit ? PPC::LIS8 : PPC::LIS;
25680b57cec5SDimitry Andric unsigned ORIInstr = is64Bit ? PPC::ORI8 : PPC::ORI;
25690b57cec5SDimitry Andric const DebugLoc &dl = I->getDebugLoc();
25700b57cec5SDimitry Andric
25710b57cec5SDimitry Andric if (isInt<16>(CalleeAmt)) {
25720b57cec5SDimitry Andric BuildMI(MBB, I, dl, TII.get(ADDIInstr), StackReg)
25730b57cec5SDimitry Andric .addReg(StackReg, RegState::Kill)
25740b57cec5SDimitry Andric .addImm(CalleeAmt);
25750b57cec5SDimitry Andric } else {
25760b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI = I;
25770b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(LISInstr), TmpReg)
25780b57cec5SDimitry Andric .addImm(CalleeAmt >> 16);
25790b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(ORIInstr), TmpReg)
25800b57cec5SDimitry Andric .addReg(TmpReg, RegState::Kill)
25810b57cec5SDimitry Andric .addImm(CalleeAmt & 0xFFFF);
25820b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(ADDInstr), StackReg)
25830b57cec5SDimitry Andric .addReg(StackReg, RegState::Kill)
25840b57cec5SDimitry Andric .addReg(TmpReg);
25850b57cec5SDimitry Andric }
25860b57cec5SDimitry Andric }
25870b57cec5SDimitry Andric }
25880b57cec5SDimitry Andric // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
25890b57cec5SDimitry Andric return MBB.erase(I);
25900b57cec5SDimitry Andric }
25910b57cec5SDimitry Andric
isCalleeSavedCR(unsigned Reg)25925ffd83dbSDimitry Andric static bool isCalleeSavedCR(unsigned Reg) {
25935ffd83dbSDimitry Andric return PPC::CR2 == Reg || Reg == PPC::CR3 || Reg == PPC::CR4;
25945ffd83dbSDimitry Andric }
25950b57cec5SDimitry Andric
restoreCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,MutableArrayRef<CalleeSavedInfo> CSI,const TargetRegisterInfo * TRI) const25965ffd83dbSDimitry Andric bool PPCFrameLowering::restoreCalleeSavedRegisters(
25975ffd83dbSDimitry Andric MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
25985ffd83dbSDimitry Andric MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
25990b57cec5SDimitry Andric MachineFunction *MF = MBB.getParent();
26000b57cec5SDimitry Andric const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
26010b57cec5SDimitry Andric PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
26020b57cec5SDimitry Andric bool MustSaveTOC = FI->mustSaveTOC();
26030b57cec5SDimitry Andric bool CR2Spilled = false;
26040b57cec5SDimitry Andric bool CR3Spilled = false;
26050b57cec5SDimitry Andric bool CR4Spilled = false;
26060b57cec5SDimitry Andric unsigned CSIIndex = 0;
2607fe6060f1SDimitry Andric BitVector Restored(TRI->getNumRegs());
26080b57cec5SDimitry Andric
26090b57cec5SDimitry Andric // Initialize insertion-point logic; we will be restoring in reverse
26100b57cec5SDimitry Andric // order of spill.
26110b57cec5SDimitry Andric MachineBasicBlock::iterator I = MI, BeforeI = I;
26120b57cec5SDimitry Andric bool AtStart = I == MBB.begin();
26130b57cec5SDimitry Andric
26140b57cec5SDimitry Andric if (!AtStart)
26150b57cec5SDimitry Andric --BeforeI;
26160b57cec5SDimitry Andric
26170b57cec5SDimitry Andric for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
261804eeddc0SDimitry Andric Register Reg = CSI[i].getReg();
26190b57cec5SDimitry Andric
26200b57cec5SDimitry Andric if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)
26210b57cec5SDimitry Andric continue;
26220b57cec5SDimitry Andric
26235ffd83dbSDimitry Andric // Restore of callee saved condition register field is handled during
26245ffd83dbSDimitry Andric // epilogue insertion.
26255ffd83dbSDimitry Andric if (isCalleeSavedCR(Reg) && !Subtarget.is32BitELFABI())
26265ffd83dbSDimitry Andric continue;
26275ffd83dbSDimitry Andric
26280b57cec5SDimitry Andric if (Reg == PPC::CR2) {
26290b57cec5SDimitry Andric CR2Spilled = true;
26300b57cec5SDimitry Andric // The spill slot is associated only with CR2, which is the
26310b57cec5SDimitry Andric // first nonvolatile spilled. Save it here.
26320b57cec5SDimitry Andric CSIIndex = i;
26330b57cec5SDimitry Andric continue;
26340b57cec5SDimitry Andric } else if (Reg == PPC::CR3) {
26350b57cec5SDimitry Andric CR3Spilled = true;
26360b57cec5SDimitry Andric continue;
26370b57cec5SDimitry Andric } else if (Reg == PPC::CR4) {
26380b57cec5SDimitry Andric CR4Spilled = true;
26390b57cec5SDimitry Andric continue;
26400b57cec5SDimitry Andric } else {
26415ffd83dbSDimitry Andric // On 32-bit ELF when we first encounter a non-CR register after seeing at
26420b57cec5SDimitry Andric // least one CR register, restore all spilled CRs together.
26435ffd83dbSDimitry Andric if (CR2Spilled || CR3Spilled || CR4Spilled) {
26440b57cec5SDimitry Andric bool is31 = needsFP(*MF);
26455ffd83dbSDimitry Andric restoreCRs(is31, CR2Spilled, CR3Spilled, CR4Spilled, MBB, I, CSI,
26465ffd83dbSDimitry Andric CSIIndex);
26470b57cec5SDimitry Andric CR2Spilled = CR3Spilled = CR4Spilled = false;
26480b57cec5SDimitry Andric }
26490b57cec5SDimitry Andric
26500b57cec5SDimitry Andric if (CSI[i].isSpilledToReg()) {
26510b57cec5SDimitry Andric DebugLoc DL;
2652fe6060f1SDimitry Andric unsigned Dst = CSI[i].getDstReg();
2653fe6060f1SDimitry Andric
2654fe6060f1SDimitry Andric if (Restored[Dst])
2655fe6060f1SDimitry Andric continue;
2656fe6060f1SDimitry Andric
2657fe6060f1SDimitry Andric if (VSRContainingGPRs[Dst].second != 0) {
2658fe6060f1SDimitry Andric assert(Subtarget.hasP9Vector());
2659fe6060f1SDimitry Andric NumPEReloadVSR += 2;
2660fe6060f1SDimitry Andric BuildMI(MBB, I, DL, TII.get(PPC::MFVSRLD),
2661fe6060f1SDimitry Andric VSRContainingGPRs[Dst].second)
2662fe6060f1SDimitry Andric .addReg(Dst);
2663fe6060f1SDimitry Andric BuildMI(MBB, I, DL, TII.get(PPC::MFVSRD),
2664fe6060f1SDimitry Andric VSRContainingGPRs[Dst].first)
2665fe6060f1SDimitry Andric .addReg(TRI->getSubReg(Dst, PPC::sub_64), getKillRegState(true));
2666fe6060f1SDimitry Andric } else if (VSRContainingGPRs[Dst].second == 0) {
2667fe6060f1SDimitry Andric assert(Subtarget.hasP8Vector());
2668fe6060f1SDimitry Andric ++NumPEReloadVSR;
2669fe6060f1SDimitry Andric BuildMI(MBB, I, DL, TII.get(PPC::MFVSRD),
2670fe6060f1SDimitry Andric VSRContainingGPRs[Dst].first)
2671fe6060f1SDimitry Andric .addReg(TRI->getSubReg(Dst, PPC::sub_64), getKillRegState(true));
2672fe6060f1SDimitry Andric } else {
2673fe6060f1SDimitry Andric llvm_unreachable("More than two GPRs spilled to a VSR!");
2674fe6060f1SDimitry Andric }
2675fe6060f1SDimitry Andric
2676fe6060f1SDimitry Andric Restored.set(Dst);
2677fe6060f1SDimitry Andric
26780b57cec5SDimitry Andric } else {
26790b57cec5SDimitry Andric // Default behavior for non-CR saves.
26800b57cec5SDimitry Andric const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
26815ffd83dbSDimitry Andric
26825ffd83dbSDimitry Andric // Functions without NoUnwind need to preserve the order of elements in
26835ffd83dbSDimitry Andric // saved vector registers.
26845ffd83dbSDimitry Andric if (Subtarget.needsSwapsForVSXMemOps() &&
26855ffd83dbSDimitry Andric !MF->getFunction().hasFnAttribute(Attribute::NoUnwind))
26865ffd83dbSDimitry Andric TII.loadRegFromStackSlotNoUpd(MBB, I, Reg, CSI[i].getFrameIdx(), RC,
26875ffd83dbSDimitry Andric TRI);
26885ffd83dbSDimitry Andric else
2689bdd1243dSDimitry Andric TII.loadRegFromStackSlot(MBB, I, Reg, CSI[i].getFrameIdx(), RC, TRI,
2690bdd1243dSDimitry Andric Register());
26915ffd83dbSDimitry Andric
26920b57cec5SDimitry Andric assert(I != MBB.begin() &&
26930b57cec5SDimitry Andric "loadRegFromStackSlot didn't insert any code!");
26940b57cec5SDimitry Andric }
26950b57cec5SDimitry Andric }
26960b57cec5SDimitry Andric
26970b57cec5SDimitry Andric // Insert in reverse order.
26980b57cec5SDimitry Andric if (AtStart)
26990b57cec5SDimitry Andric I = MBB.begin();
27000b57cec5SDimitry Andric else {
27010b57cec5SDimitry Andric I = BeforeI;
27020b57cec5SDimitry Andric ++I;
27030b57cec5SDimitry Andric }
27040b57cec5SDimitry Andric }
27050b57cec5SDimitry Andric
27060b57cec5SDimitry Andric // If we haven't yet spilled the CRs, do so now.
27070b57cec5SDimitry Andric if (CR2Spilled || CR3Spilled || CR4Spilled) {
27085ffd83dbSDimitry Andric assert(Subtarget.is32BitELFABI() &&
27095ffd83dbSDimitry Andric "Only set CR[2|3|4]Spilled on 32-bit SVR4.");
27100b57cec5SDimitry Andric bool is31 = needsFP(*MF);
27115ffd83dbSDimitry Andric restoreCRs(is31, CR2Spilled, CR3Spilled, CR4Spilled, MBB, I, CSI, CSIIndex);
27120b57cec5SDimitry Andric }
27130b57cec5SDimitry Andric
27140b57cec5SDimitry Andric return true;
27150b57cec5SDimitry Andric }
27160b57cec5SDimitry Andric
getTOCSaveOffset() const2717349cc55cSDimitry Andric uint64_t PPCFrameLowering::getTOCSaveOffset() const {
27188bcb0991SDimitry Andric return TOCSaveOffset;
27198bcb0991SDimitry Andric }
27208bcb0991SDimitry Andric
getFramePointerSaveOffset() const2721349cc55cSDimitry Andric uint64_t PPCFrameLowering::getFramePointerSaveOffset() const {
27228bcb0991SDimitry Andric return FramePointerSaveOffset;
27238bcb0991SDimitry Andric }
27248bcb0991SDimitry Andric
getBasePointerSaveOffset() const2725349cc55cSDimitry Andric uint64_t PPCFrameLowering::getBasePointerSaveOffset() const {
27268bcb0991SDimitry Andric return BasePointerSaveOffset;
27278bcb0991SDimitry Andric }
27288bcb0991SDimitry Andric
enableShrinkWrapping(const MachineFunction & MF) const27290b57cec5SDimitry Andric bool PPCFrameLowering::enableShrinkWrapping(const MachineFunction &MF) const {
27300b57cec5SDimitry Andric if (MF.getInfo<PPCFunctionInfo>()->shrinkWrapDisabled())
27310b57cec5SDimitry Andric return false;
2732fe6060f1SDimitry Andric return !MF.getSubtarget<PPCSubtarget>().is32BitELFABI();
27330b57cec5SDimitry Andric }
2734c9157d92SDimitry Andric
getStackThreshold() const2735c9157d92SDimitry Andric uint64_t PPCFrameLowering::getStackThreshold() const {
2736c9157d92SDimitry Andric // On PPC64, we use `stux r1, r1, <scratch_reg>` to extend the stack;
2737c9157d92SDimitry Andric // use `add r1, r1, <scratch_reg>` to release the stack frame.
2738c9157d92SDimitry Andric // Scratch register contains a signed 64-bit number, which is negative
2739c9157d92SDimitry Andric // when extending the stack and is positive when releasing the stack frame.
2740c9157d92SDimitry Andric // To make `stux` and `add` paired, the absolute value of the number contained
2741c9157d92SDimitry Andric // in the scratch register should be the same. Thus the maximum stack size
2742c9157d92SDimitry Andric // is (2^63)-1, i.e., LONG_MAX.
2743c9157d92SDimitry Andric if (Subtarget.isPPC64())
2744c9157d92SDimitry Andric return LONG_MAX;
2745c9157d92SDimitry Andric
2746c9157d92SDimitry Andric return TargetFrameLowering::getStackThreshold();
2747c9157d92SDimitry Andric }
2748