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 SystemZTargetMachine; 21 class SystemZSubtarget; 22 23 class SystemZFrameLowering : public TargetFrameLowering { 24 public: 25 SystemZFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl, 26 bool StackReal); 27 28 static std::unique_ptr<SystemZFrameLowering> 29 create(const SystemZSubtarget &STI); 30 31 // Override TargetFrameLowering. 32 bool allocateScavengingFrameIndexesNearIncomingSP( 33 const MachineFunction &MF) const override { 34 // SystemZ wants normal register scavenging slots, as close to the stack or 35 // frame pointer as possible. 36 // The default implementation assumes an x86-like layout, where the frame 37 // pointer is at the opposite end of the frame from the stack pointer. 38 // This meant that when frame pointer elimination was disabled, 39 // the slots ended up being as close as possible to the incoming 40 // stack pointer, which is the opposite of what we want on SystemZ. 41 return false; 42 } 43 44 bool hasReservedCallFrame(const MachineFunction &MF) const override; 45 MachineBasicBlock::iterator 46 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 47 MachineBasicBlock::iterator MI) const override; 48 }; 49 50 class SystemZELFFrameLowering : public SystemZFrameLowering { 51 IndexedMap<unsigned> RegSpillOffsets; 52 53 public: 54 SystemZELFFrameLowering(); 55 56 // Override TargetFrameLowering. 57 bool 58 assignCalleeSavedSpillSlots(MachineFunction &MF, 59 const TargetRegisterInfo *TRI, 60 std::vector<CalleeSavedInfo> &CSI) const override; 61 void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, 62 RegScavenger *RS) const override; 63 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 64 MachineBasicBlock::iterator MBBI, 65 ArrayRef<CalleeSavedInfo> CSI, 66 const TargetRegisterInfo *TRI) const override; 67 bool 68 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 69 MachineBasicBlock::iterator MBBII, 70 MutableArrayRef<CalleeSavedInfo> CSI, 71 const TargetRegisterInfo *TRI) const override; 72 void processFunctionBeforeFrameFinalized(MachineFunction &MF, 73 RegScavenger *RS) const override; 74 void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 75 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 76 void inlineStackProbe(MachineFunction &MF, 77 MachineBasicBlock &PrologMBB) const override; 78 bool hasFP(const MachineFunction &MF) const override; 79 StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, 80 Register &FrameReg) const override; 81 82 // Return the byte offset from the incoming stack pointer of Reg's 83 // ABI-defined save slot. Return 0 if no slot is defined for Reg. Adjust 84 // the offset in case MF has packed-stack. 85 unsigned getRegSpillOffset(MachineFunction &MF, Register Reg) const; 86 87 bool usePackedStack(MachineFunction &MF) const; 88 89 // Return the offset of the backchain. 90 unsigned getBackchainOffset(MachineFunction &MF) const { 91 // The back chain is stored topmost with packed-stack. 92 return usePackedStack(MF) ? SystemZMC::ELFCallFrameSize - 8 : 0; 93 } 94 95 // Get or create the frame index of where the old frame pointer is stored. 96 int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const; 97 }; 98 99 class SystemZXPLINKFrameLowering : public SystemZFrameLowering { 100 IndexedMap<unsigned> RegSpillOffsets; 101 102 public: 103 SystemZXPLINKFrameLowering(); 104 105 bool 106 assignCalleeSavedSpillSlots(MachineFunction &MF, 107 const TargetRegisterInfo *TRI, 108 std::vector<CalleeSavedInfo> &CSI) const override; 109 110 void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, 111 RegScavenger *RS) const override; 112 113 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 114 MachineBasicBlock::iterator MBBI, 115 ArrayRef<CalleeSavedInfo> CSI, 116 const TargetRegisterInfo *TRI) const override; 117 118 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 119 120 void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 121 122 bool hasFP(const MachineFunction &MF) const override; 123 }; 124 } // end namespace llvm 125 126 #endif 127