1 //===-- SystemZFrameLowering.h - Frame lowering for SystemZ -----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZFRAMELOWERING_H 10 #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZFRAMELOWERING_H 11 12 #include "MCTargetDesc/SystemZMCTargetDesc.h" 13 #include "SystemZInstrBuilder.h" 14 #include "SystemZMachineFunctionInfo.h" 15 #include "llvm/ADT/IndexedMap.h" 16 #include "llvm/CodeGen/TargetFrameLowering.h" 17 #include "llvm/Support/TypeSize.h" 18 19 namespace llvm { 20 class SystemZSubtarget; 21 22 class SystemZFrameLowering : public TargetFrameLowering { 23 public: 24 SystemZFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl, 25 bool StackReal, unsigned PointerSize); 26 27 static std::unique_ptr<SystemZFrameLowering> 28 create(const SystemZSubtarget &STI); 29 30 // Override TargetFrameLowering. 31 bool allocateScavengingFrameIndexesNearIncomingSP( 32 const MachineFunction &MF) const override { 33 // SystemZ wants normal register scavenging slots, as close to the stack or 34 // frame pointer as possible. 35 // The default implementation assumes an x86-like layout, where the frame 36 // pointer is at the opposite end of the frame from the stack pointer. 37 // This meant that when frame pointer elimination was disabled, 38 // the slots ended up being as close as possible to the incoming 39 // stack pointer, which is the opposite of what we want on SystemZ. 40 return false; 41 } 42 43 bool hasReservedCallFrame(const MachineFunction &MF) const override; 44 45 // Return the offset of the backchain. 46 virtual unsigned getBackchainOffset(MachineFunction &MF) const = 0; 47 48 // Return the offset of the return address. 49 virtual int getReturnAddressOffset(MachineFunction &MF) const = 0; 50 51 // Get or create the frame index of where the old frame pointer is stored. 52 virtual int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const = 0; 53 54 // Return the size of a pointer (in bytes). 55 unsigned getPointerSize() const { return PointerSize; } 56 57 private: 58 unsigned PointerSize; 59 }; 60 61 class SystemZELFFrameLowering : public SystemZFrameLowering { 62 IndexedMap<unsigned> RegSpillOffsets; 63 64 public: 65 SystemZELFFrameLowering(unsigned PointerSize); 66 67 // Override TargetFrameLowering. 68 bool 69 assignCalleeSavedSpillSlots(MachineFunction &MF, 70 const TargetRegisterInfo *TRI, 71 std::vector<CalleeSavedInfo> &CSI) const override; 72 void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, 73 RegScavenger *RS) const override; 74 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 75 MachineBasicBlock::iterator MBBI, 76 ArrayRef<CalleeSavedInfo> CSI, 77 const TargetRegisterInfo *TRI) const override; 78 bool 79 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 80 MachineBasicBlock::iterator MBBII, 81 MutableArrayRef<CalleeSavedInfo> CSI, 82 const TargetRegisterInfo *TRI) const override; 83 void processFunctionBeforeFrameFinalized(MachineFunction &MF, 84 RegScavenger *RS) const override; 85 void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 86 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 87 void inlineStackProbe(MachineFunction &MF, 88 MachineBasicBlock &PrologMBB) const override; 89 StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, 90 Register &FrameReg) const override; 91 void 92 orderFrameObjects(const MachineFunction &MF, 93 SmallVectorImpl<int> &ObjectsToAllocate) const override; 94 95 // Return the byte offset from the incoming stack pointer of Reg's 96 // ABI-defined save slot. Return 0 if no slot is defined for Reg. Adjust 97 // the offset in case MF has packed-stack. 98 unsigned getRegSpillOffset(MachineFunction &MF, Register Reg) const; 99 100 bool usePackedStack(MachineFunction &MF) const; 101 102 // Return the offset of the backchain. 103 unsigned getBackchainOffset(MachineFunction &MF) const override { 104 // The back chain is stored topmost with packed-stack. 105 return usePackedStack(MF) ? SystemZMC::ELFCallFrameSize - 8 : 0; 106 } 107 108 // Return the offset of the return address. 109 int getReturnAddressOffset(MachineFunction &MF) const override { 110 return (usePackedStack(MF) ? -2 : 14) * getPointerSize(); 111 } 112 113 // Get or create the frame index of where the old frame pointer is stored. 114 int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const override; 115 116 protected: 117 bool hasFPImpl(const MachineFunction &MF) const override; 118 }; 119 120 class SystemZXPLINKFrameLowering : public SystemZFrameLowering { 121 IndexedMap<unsigned> RegSpillOffsets; 122 123 public: 124 SystemZXPLINKFrameLowering(unsigned PointerSize); 125 126 bool 127 assignCalleeSavedSpillSlots(MachineFunction &MF, 128 const TargetRegisterInfo *TRI, 129 std::vector<CalleeSavedInfo> &CSI) const override; 130 131 void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, 132 RegScavenger *RS) const override; 133 134 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 135 MachineBasicBlock::iterator MBBI, 136 ArrayRef<CalleeSavedInfo> CSI, 137 const TargetRegisterInfo *TRI) const override; 138 139 bool 140 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 141 MachineBasicBlock::iterator MBBII, 142 MutableArrayRef<CalleeSavedInfo> CSI, 143 const TargetRegisterInfo *TRI) const override; 144 145 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 146 147 void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 148 149 void inlineStackProbe(MachineFunction &MF, 150 MachineBasicBlock &PrologMBB) const override; 151 152 void processFunctionBeforeFrameFinalized(MachineFunction &MF, 153 RegScavenger *RS) const override; 154 155 void determineFrameLayout(MachineFunction &MF) const; 156 157 // Return the offset of the backchain. 158 unsigned getBackchainOffset(MachineFunction &MF) const override { 159 // The back chain is always the first element of the frame. 160 return 0; 161 } 162 163 // Return the offset of the return address. 164 int getReturnAddressOffset(MachineFunction &MF) const override { 165 return 3 * getPointerSize(); 166 } 167 168 // Get or create the frame index of where the old frame pointer is stored. 169 int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const override; 170 171 protected: 172 bool hasFPImpl(const MachineFunction &MF) const override; 173 }; 174 } // end namespace llvm 175 176 #endif 177