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