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 | |