1 | //===-- M68kFrameLowering.h - Define frame lowering for M68k ----*- 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 | /// \file |
10 | /// This file contains the M68k declaration of TargetFrameLowering class. |
11 | /// |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_LIB_TARGET_M68K_M68KFRAMELOWERING_H |
15 | #define LLVM_LIB_TARGET_M68K_M68KFRAMELOWERING_H |
16 | |
17 | #include "M68k.h" |
18 | |
19 | #include "llvm/CodeGen/TargetFrameLowering.h" |
20 | |
21 | namespace llvm { |
22 | class MachineInstrBuilder; |
23 | class MCCFIInstruction; |
24 | class M68kSubtarget; |
25 | class M68kRegisterInfo; |
26 | struct Align; |
27 | |
28 | class M68kFrameLowering : public TargetFrameLowering { |
29 | // Cached subtarget predicates. |
30 | const M68kSubtarget &STI; |
31 | const TargetInstrInfo &TII; |
32 | const M68kRegisterInfo *TRI; |
33 | |
34 | /// Stack slot size in bytes. |
35 | unsigned SlotSize; |
36 | |
37 | unsigned StackPtr; |
38 | |
39 | /// If we're forcing a stack realignment we can't rely on just the frame |
40 | /// info, we need to know the ABI stack alignment as well in case we have a |
41 | /// call out. Otherwise just make sure we have some alignment - we'll go |
42 | /// with the minimum SlotSize. |
43 | uint64_t calculateMaxStackAlign(const MachineFunction &MF) const; |
44 | |
45 | /// Adjusts the stack pointer using LEA, SUB, or ADD. |
46 | MachineInstrBuilder BuildStackAdjustment(MachineBasicBlock &MBB, |
47 | MachineBasicBlock::iterator MBBI, |
48 | const DebugLoc &DL, int64_t Offset, |
49 | bool InEpilogue) const; |
50 | |
51 | /// Aligns the stack pointer by ANDing it with -MaxAlign. |
52 | void BuildStackAlignAND(MachineBasicBlock &MBB, |
53 | MachineBasicBlock::iterator MBBI, const DebugLoc &DL, |
54 | unsigned Reg, uint64_t MaxAlign) const; |
55 | |
56 | /// Wraps up getting a CFI index and building a MachineInstr for it. |
57 | void BuildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, |
58 | const DebugLoc &DL, const MCCFIInstruction &CFIInst) const; |
59 | |
60 | void emitPrologueCalleeSavedFrameMoves(MachineBasicBlock &MBB, |
61 | MachineBasicBlock::iterator MBBI, |
62 | const DebugLoc &DL) const; |
63 | |
64 | unsigned getPSPSlotOffsetFromSP(const MachineFunction &MF) const; |
65 | |
66 | public: |
67 | explicit M68kFrameLowering(const M68kSubtarget &sti, Align Alignment); |
68 | |
69 | static const M68kFrameLowering *create(const M68kSubtarget &ST); |
70 | |
71 | /// This method is called during prolog/epilog code insertion to eliminate |
72 | /// call frame setup and destroy pseudo instructions (but only if the Target |
73 | /// is using them). It is responsible for eliminating these instructions, |
74 | /// replacing them with concrete instructions. This method need only be |
75 | /// implemented if using call frame setup/destroy pseudo instructions. |
76 | /// Returns an iterator pointing to the instruction after the replaced one. |
77 | MachineBasicBlock::iterator |
78 | eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, |
79 | MachineBasicBlock::iterator MI) const override; |
80 | |
81 | /// Insert prolog code into the function. |
82 | void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; |
83 | |
84 | /// Insert epilog code into the function. |
85 | void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; |
86 | |
87 | /// This method determines which of the registers reported by |
88 | /// TargetRegisterInfo::getCalleeSavedRegs() should actually get saved. |
89 | /// The default implementation checks populates the \p SavedRegs bitset with |
90 | /// all registers which are modified in the function, targets may override |
91 | /// this function to save additional registers. |
92 | /// This method also sets up the register scavenger ensuring there is a free |
93 | /// register or a frameindex available. |
94 | void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, |
95 | RegScavenger *RS = nullptr) const override; |
96 | |
97 | /// Allows target to override spill slot assignment logic. If implemented, |
98 | /// assignCalleeSavedSpillSlots() should assign frame slots to all CSI |
99 | /// entries and return true. If this method returns false, spill slots will |
100 | /// be assigned using generic implementation. assignCalleeSavedSpillSlots() |
101 | /// may add, delete or rearrange elements of CSI. |
102 | bool |
103 | assignCalleeSavedSpillSlots(MachineFunction &MF, |
104 | const TargetRegisterInfo *TRI, |
105 | std::vector<CalleeSavedInfo> &CSI) const override; |
106 | |
107 | /// Issues instruction(s) to spill all callee saved registers and returns |
108 | /// true if it isn't possible / profitable to do so by issuing a series of |
109 | /// store instructions via storeRegToStackSlot(). Returns false otherwise. |
110 | bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, |
111 | MachineBasicBlock::iterator MI, |
112 | ArrayRef<CalleeSavedInfo> CSI, |
113 | const TargetRegisterInfo *TRI) const override; |
114 | |
115 | /// Issues instruction(s) to restore all callee saved registers and returns |
116 | /// true if it isn't possible / profitable to do so by issuing a series of |
117 | /// load instructions via loadRegToStackSlot(). Returns false otherwise. |
118 | bool |
119 | restoreCalleeSavedRegisters(MachineBasicBlock &MBB, |
120 | MachineBasicBlock::iterator MI, |
121 | MutableArrayRef<CalleeSavedInfo> CSI, |
122 | const TargetRegisterInfo *TRI) const override; |
123 | |
124 | /// Return true if the specified function should have a dedicated frame |
125 | /// pointer register. This is true if the function has variable sized |
126 | /// allocas, if it needs dynamic stack realignment, if frame pointer |
127 | /// elimination is disabled, or if the frame address is taken. |
128 | bool hasFP(const MachineFunction &MF) const override; |
129 | |
130 | /// Under normal circumstances, when a frame pointer is not required, we |
131 | /// reserve argument space for call sites in the function immediately on |
132 | /// entry to the current function. This eliminates the need for add/sub sp |
133 | /// brackets around call sites. Returns true if the call frame is included as |
134 | /// part of the stack frame. |
135 | bool hasReservedCallFrame(const MachineFunction &MF) const override; |
136 | |
137 | /// If there is a reserved call frame, the call frame pseudos can be |
138 | /// simplified. Having a FP, as in the default implementation, is not |
139 | /// sufficient here since we can't always use it. Use a more nuanced |
140 | /// condition. |
141 | bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override; |
142 | |
143 | // Do we need to perform FI resolution for this function. Normally, this is |
144 | // required only when the function has any stack objects. However, FI |
145 | // resolution actually has another job, not apparent from the title - it |
146 | // resolves callframe setup/destroy that were not simplified earlier. |
147 | // |
148 | // So, this is required for M68k functions that have push sequences even |
149 | // when there are no stack objects. |
150 | bool needsFrameIndexResolution(const MachineFunction &MF) const override; |
151 | |
152 | /// This method should return the base register and offset used to reference |
153 | /// a frame index location. The offset is returned directly, and the base |
154 | /// register is returned via FrameReg. |
155 | StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, |
156 | Register &FrameReg) const override; |
157 | |
158 | /// Check the instruction before/after the passed instruction. If |
159 | /// it is an ADD/SUB/LEA instruction it is deleted argument and the |
160 | /// stack adjustment is returned as a positive value for ADD/LEA and |
161 | /// a negative for SUB. |
162 | int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, |
163 | bool doMergeWithPrevious) const; |
164 | |
165 | /// Emit a series of instructions to increment / decrement the stack |
166 | /// pointer by a constant value. |
167 | void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, |
168 | int64_t NumBytes, bool InEpilogue) const; |
169 | }; |
170 | } // namespace llvm |
171 | |
172 | #endif // LLVM_LIB_TARGET_M68K_M68KFRAMELOWERING_H |
173 | |