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 isFPCloseToIncomingSP() const override { return false; }
33   bool hasReservedCallFrame(const MachineFunction &MF) const override;
34   MachineBasicBlock::iterator
35   eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
36                                 MachineBasicBlock::iterator MI) const override;
37 };
38 
39 class SystemZELFFrameLowering : public SystemZFrameLowering {
40   IndexedMap<unsigned> RegSpillOffsets;
41 
42 public:
43   SystemZELFFrameLowering();
44 
45   // Override TargetFrameLowering.
46   bool isFPCloseToIncomingSP() const override { return false; }
47   bool
48   assignCalleeSavedSpillSlots(MachineFunction &MF,
49                               const TargetRegisterInfo *TRI,
50                               std::vector<CalleeSavedInfo> &CSI) const override;
51   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
52                             RegScavenger *RS) const override;
53   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
54                                  MachineBasicBlock::iterator MBBI,
55                                  ArrayRef<CalleeSavedInfo> CSI,
56                                  const TargetRegisterInfo *TRI) const override;
57   bool
58   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
59                               MachineBasicBlock::iterator MBBII,
60                               MutableArrayRef<CalleeSavedInfo> CSI,
61                               const TargetRegisterInfo *TRI) const override;
62   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
63                                            RegScavenger *RS) const override;
64   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
65   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
66   void inlineStackProbe(MachineFunction &MF,
67                         MachineBasicBlock &PrologMBB) const override;
68   bool hasFP(const MachineFunction &MF) const override;
69   StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
70                                      Register &FrameReg) const override;
71 
72   // Return the byte offset from the incoming stack pointer of Reg's
73   // ABI-defined save slot.  Return 0 if no slot is defined for Reg.  Adjust
74   // the offset in case MF has packed-stack.
75   unsigned getRegSpillOffset(MachineFunction &MF, Register Reg) const;
76 
77   bool usePackedStack(MachineFunction &MF) const;
78 
79   // Return the offset of the backchain.
80   unsigned getBackchainOffset(MachineFunction &MF) const {
81     // The back chain is stored topmost with packed-stack.
82     return usePackedStack(MF) ? SystemZMC::ELFCallFrameSize - 8 : 0;
83   }
84 
85   // Get or create the frame index of where the old frame pointer is stored.
86   int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const;
87 };
88 
89 class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
90   IndexedMap<unsigned> RegSpillOffsets;
91 
92 public:
93   SystemZXPLINKFrameLowering();
94 
95   bool
96   assignCalleeSavedSpillSlots(MachineFunction &MF,
97                               const TargetRegisterInfo *TRI,
98                               std::vector<CalleeSavedInfo> &CSI) const override;
99 
100   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
101                             RegScavenger *RS) const override;
102 
103   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
104                                  MachineBasicBlock::iterator MBBI,
105                                  ArrayRef<CalleeSavedInfo> CSI,
106                                  const TargetRegisterInfo *TRI) const override;
107 
108   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
109 
110   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
111 
112   bool hasFP(const MachineFunction &MF) const override;
113 };
114 } // end namespace llvm
115 
116 #endif
117