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 | bool hasFP(const MachineFunction &MF) const override; |
90 | StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, |
91 | Register &FrameReg) const override; |
92 | void |
93 | orderFrameObjects(const MachineFunction &MF, |
94 | SmallVectorImpl<int> &ObjectsToAllocate) const override; |
95 | |
96 | // Return the byte offset from the incoming stack pointer of Reg's |
97 | // ABI-defined save slot. Return 0 if no slot is defined for Reg. Adjust |
98 | // the offset in case MF has packed-stack. |
99 | unsigned getRegSpillOffset(MachineFunction &MF, Register Reg) const; |
100 | |
101 | bool usePackedStack(MachineFunction &MF) const; |
102 | |
103 | // Return the offset of the backchain. |
104 | unsigned getBackchainOffset(MachineFunction &MF) const override { |
105 | // The back chain is stored topmost with packed-stack. |
106 | return usePackedStack(MF) ? SystemZMC::ELFCallFrameSize - 8 : 0; |
107 | } |
108 | |
109 | // Return the offset of the return address. |
110 | int getReturnAddressOffset(MachineFunction &MF) const override { |
111 | return (usePackedStack(MF) ? -2 : 14) * getPointerSize(); |
112 | } |
113 | |
114 | // Get or create the frame index of where the old frame pointer is stored. |
115 | int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const override; |
116 | }; |
117 | |
118 | class SystemZXPLINKFrameLowering : public SystemZFrameLowering { |
119 | IndexedMap<unsigned> RegSpillOffsets; |
120 | |
121 | public: |
122 | SystemZXPLINKFrameLowering(unsigned PointerSize); |
123 | |
124 | bool |
125 | assignCalleeSavedSpillSlots(MachineFunction &MF, |
126 | const TargetRegisterInfo *TRI, |
127 | std::vector<CalleeSavedInfo> &CSI) const override; |
128 | |
129 | void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, |
130 | RegScavenger *RS) const override; |
131 | |
132 | bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, |
133 | MachineBasicBlock::iterator MBBI, |
134 | ArrayRef<CalleeSavedInfo> CSI, |
135 | const TargetRegisterInfo *TRI) const override; |
136 | |
137 | bool |
138 | restoreCalleeSavedRegisters(MachineBasicBlock &MBB, |
139 | MachineBasicBlock::iterator MBBII, |
140 | MutableArrayRef<CalleeSavedInfo> CSI, |
141 | const TargetRegisterInfo *TRI) const override; |
142 | |
143 | void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; |
144 | |
145 | void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; |
146 | |
147 | void inlineStackProbe(MachineFunction &MF, |
148 | MachineBasicBlock &PrologMBB) const override; |
149 | |
150 | bool hasFP(const MachineFunction &MF) 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 | } // end namespace llvm |
172 | |
173 | #endif |
174 | |