1 //===-- MSP430FrameLowering.cpp - MSP430 Frame Information ----------------===//
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 // This file contains the MSP430 implementation of TargetFrameLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "MSP430FrameLowering.h"
14 #include "MSP430InstrInfo.h"
15 #include "MSP430MachineFunctionInfo.h"
16 #include "MSP430Subtarget.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineModuleInfo.h"
21 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 #include "llvm/IR/DataLayout.h"
23 #include "llvm/IR/Function.h"
24 #include "llvm/Target/TargetOptions.h"
25
26 using namespace llvm;
27
hasFP(const MachineFunction & MF) const28 bool MSP430FrameLowering::hasFP(const MachineFunction &MF) const {
29 const MachineFrameInfo &MFI = MF.getFrameInfo();
30
31 return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
32 MF.getFrameInfo().hasVarSizedObjects() ||
33 MFI.isFrameAddressTaken());
34 }
35
hasReservedCallFrame(const MachineFunction & MF) const36 bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
37 return !MF.getFrameInfo().hasVarSizedObjects();
38 }
39
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const40 void MSP430FrameLowering::emitPrologue(MachineFunction &MF,
41 MachineBasicBlock &MBB) const {
42 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
43 MachineFrameInfo &MFI = MF.getFrameInfo();
44 MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
45 const MSP430InstrInfo &TII =
46 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
47
48 MachineBasicBlock::iterator MBBI = MBB.begin();
49 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
50
51 // Get the number of bytes to allocate from the FrameInfo.
52 uint64_t StackSize = MFI.getStackSize();
53
54 uint64_t NumBytes = 0;
55 if (hasFP(MF)) {
56 // Calculate required stack adjustment
57 uint64_t FrameSize = StackSize - 2;
58 NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize();
59
60 // Get the offset of the stack slot for the EBP register... which is
61 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
62 // Update the frame offset adjustment.
63 MFI.setOffsetAdjustment(-NumBytes);
64
65 // Save FP into the appropriate stack slot...
66 BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r))
67 .addReg(MSP430::R4, RegState::Kill);
68
69 // Update FP with the new base value...
70 BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::R4)
71 .addReg(MSP430::SP);
72
73 // Mark the FramePtr as live-in in every block except the entry.
74 for (MachineBasicBlock &MBBJ : llvm::drop_begin(MF))
75 MBBJ.addLiveIn(MSP430::R4);
76
77 } else
78 NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize();
79
80 // Skip the callee-saved push instructions.
81 while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r))
82 ++MBBI;
83
84 if (MBBI != MBB.end())
85 DL = MBBI->getDebugLoc();
86
87 if (NumBytes) { // adjust stack pointer: SP -= numbytes
88 // If there is an SUB16ri of SP immediately before this instruction, merge
89 // the two.
90 //NumBytes -= mergeSPUpdates(MBB, MBBI, true);
91 // If there is an ADD16ri or SUB16ri of SP immediately after this
92 // instruction, merge the two instructions.
93 // mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
94
95 if (NumBytes) {
96 MachineInstr *MI =
97 BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SP)
98 .addReg(MSP430::SP).addImm(NumBytes);
99 // The SRW implicit def is dead.
100 MI->getOperand(3).setIsDead();
101 }
102 }
103 }
104
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const105 void MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
106 MachineBasicBlock &MBB) const {
107 const MachineFrameInfo &MFI = MF.getFrameInfo();
108 MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
109 const MSP430InstrInfo &TII =
110 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
111
112 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
113 unsigned RetOpcode = MBBI->getOpcode();
114 DebugLoc DL = MBBI->getDebugLoc();
115
116 switch (RetOpcode) {
117 case MSP430::RET:
118 case MSP430::RETI: break; // These are ok
119 default:
120 llvm_unreachable("Can only insert epilog into returning blocks");
121 }
122
123 // Get the number of bytes to allocate from the FrameInfo
124 uint64_t StackSize = MFI.getStackSize();
125 unsigned CSSize = MSP430FI->getCalleeSavedFrameSize();
126 uint64_t NumBytes = 0;
127
128 if (hasFP(MF)) {
129 // Calculate required stack adjustment
130 uint64_t FrameSize = StackSize - 2;
131 NumBytes = FrameSize - CSSize;
132
133 // pop FP.
134 BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::R4);
135 } else
136 NumBytes = StackSize - CSSize;
137
138 // Skip the callee-saved pop instructions.
139 while (MBBI != MBB.begin()) {
140 MachineBasicBlock::iterator PI = std::prev(MBBI);
141 unsigned Opc = PI->getOpcode();
142 if (Opc != MSP430::POP16r && !PI->isTerminator())
143 break;
144 --MBBI;
145 }
146
147 DL = MBBI->getDebugLoc();
148
149 // If there is an ADD16ri or SUB16ri of SP immediately before this
150 // instruction, merge the two instructions.
151 //if (NumBytes || MFI.hasVarSizedObjects())
152 // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
153
154 if (MFI.hasVarSizedObjects()) {
155 BuildMI(MBB, MBBI, DL,
156 TII.get(MSP430::MOV16rr), MSP430::SP).addReg(MSP430::R4);
157 if (CSSize) {
158 MachineInstr *MI =
159 BuildMI(MBB, MBBI, DL,
160 TII.get(MSP430::SUB16ri), MSP430::SP)
161 .addReg(MSP430::SP).addImm(CSSize);
162 // The SRW implicit def is dead.
163 MI->getOperand(3).setIsDead();
164 }
165 } else {
166 // adjust stack pointer back: SP += numbytes
167 if (NumBytes) {
168 MachineInstr *MI =
169 BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SP)
170 .addReg(MSP430::SP).addImm(NumBytes);
171 // The SRW implicit def is dead.
172 MI->getOperand(3).setIsDead();
173 }
174 }
175 }
176
177 // FIXME: Can we eleminate these in favour of generic code?
spillCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,ArrayRef<CalleeSavedInfo> CSI,const TargetRegisterInfo * TRI) const178 bool MSP430FrameLowering::spillCalleeSavedRegisters(
179 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
180 ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
181 if (CSI.empty())
182 return false;
183
184 DebugLoc DL;
185 if (MI != MBB.end()) DL = MI->getDebugLoc();
186
187 MachineFunction &MF = *MBB.getParent();
188 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
189 MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>();
190 MFI->setCalleeSavedFrameSize(CSI.size() * 2);
191
192 for (const CalleeSavedInfo &I : llvm::reverse(CSI)) {
193 Register Reg = I.getReg();
194 // Add the callee-saved register as live-in. It's killed at the spill.
195 MBB.addLiveIn(Reg);
196 BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r))
197 .addReg(Reg, RegState::Kill);
198 }
199 return true;
200 }
201
restoreCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,MutableArrayRef<CalleeSavedInfo> CSI,const TargetRegisterInfo * TRI) const202 bool MSP430FrameLowering::restoreCalleeSavedRegisters(
203 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
204 MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
205 if (CSI.empty())
206 return false;
207
208 DebugLoc DL;
209 if (MI != MBB.end()) DL = MI->getDebugLoc();
210
211 MachineFunction &MF = *MBB.getParent();
212 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
213
214 for (const CalleeSavedInfo &I : CSI)
215 BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), I.getReg());
216
217 return true;
218 }
219
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const220 MachineBasicBlock::iterator MSP430FrameLowering::eliminateCallFramePseudoInstr(
221 MachineFunction &MF, MachineBasicBlock &MBB,
222 MachineBasicBlock::iterator I) const {
223 const MSP430InstrInfo &TII =
224 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
225 if (!hasReservedCallFrame(MF)) {
226 // If the stack pointer can be changed after prologue, turn the
227 // adjcallstackup instruction into a 'sub SP, <amt>' and the
228 // adjcallstackdown instruction into 'add SP, <amt>'
229 // TODO: consider using push / pop instead of sub + store / add
230 MachineInstr &Old = *I;
231 uint64_t Amount = TII.getFrameSize(Old);
232 if (Amount != 0) {
233 // We need to keep the stack aligned properly. To do this, we round the
234 // amount of space needed for the outgoing arguments up to the next
235 // alignment boundary.
236 Amount = alignTo(Amount, getStackAlign());
237
238 MachineInstr *New = nullptr;
239 if (Old.getOpcode() == TII.getCallFrameSetupOpcode()) {
240 New =
241 BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP)
242 .addReg(MSP430::SP)
243 .addImm(Amount);
244 } else {
245 assert(Old.getOpcode() == TII.getCallFrameDestroyOpcode());
246 // factor out the amount the callee already popped.
247 Amount -= TII.getFramePoppedByCallee(Old);
248 if (Amount)
249 New = BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::ADD16ri),
250 MSP430::SP)
251 .addReg(MSP430::SP)
252 .addImm(Amount);
253 }
254
255 if (New) {
256 // The SRW implicit def is dead.
257 New->getOperand(3).setIsDead();
258
259 // Replace the pseudo instruction with a new instruction...
260 MBB.insert(I, New);
261 }
262 }
263 } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
264 // If we are performing frame pointer elimination and if the callee pops
265 // something off the stack pointer, add it back.
266 if (uint64_t CalleeAmt = TII.getFramePoppedByCallee(*I)) {
267 MachineInstr &Old = *I;
268 MachineInstr *New =
269 BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP)
270 .addReg(MSP430::SP)
271 .addImm(CalleeAmt);
272 // The SRW implicit def is dead.
273 New->getOperand(3).setIsDead();
274
275 MBB.insert(I, New);
276 }
277 }
278
279 return MBB.erase(I);
280 }
281
282 void
processFunctionBeforeFrameFinalized(MachineFunction & MF,RegScavenger *) const283 MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
284 RegScavenger *) const {
285 // Create a frame entry for the FP register that must be saved.
286 if (hasFP(MF)) {
287 int FrameIdx = MF.getFrameInfo().CreateFixedObject(2, -4, true);
288 (void)FrameIdx;
289 assert(FrameIdx == MF.getFrameInfo().getObjectIndexBegin() &&
290 "Slot for FP register must be last in order to be found!");
291 }
292 }
293