1 //===-- MSP430FrameLowering.cpp - MSP430 Frame Information ----------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the MSP430 implementation of TargetFrameLowering class.
11 //===----------------------------------------------------------------------===//
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"
28 bool MSP430FrameLowering::hasFP(const MachineFunction
&MF
) const {
29 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
31 return (MF
.getTarget().Options
.DisableFramePointerElim(MF
) ||
32 MF
.getFrameInfo().hasVarSizedObjects() ||
33 MFI
.isFrameAddressTaken());
36 bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction
&MF
) const {
37 return !MF
.getFrameInfo().hasVarSizedObjects();
40 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());
48 MachineBasicBlock::iterator MBBI
= MBB
.begin();
49 DebugLoc DL
= MBBI
!= MBB
.end() ? MBBI
->getDebugLoc() : DebugLoc();
51 // Get the number of bytes to allocate from the FrameInfo.
52 uint64_t StackSize
= MFI
.getStackSize();
54 uint64_t NumBytes
= 0;
56 // Calculate required stack adjustment
57 uint64_t FrameSize
= StackSize
- 2;
58 NumBytes
= FrameSize
- MSP430FI
->getCalleeSavedFrameSize();
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
);
65 // Save FP into the appropriate stack slot...
66 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::PUSH16r
))
67 .addReg(MSP430::FP
, RegState::Kill
);
69 // Update FP with the new base value...
70 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::MOV16rr
), MSP430::FP
)
73 // Mark the FramePtr as live-in in every block except the entry.
74 for (MachineFunction::iterator I
= std::next(MF
.begin()), E
= MF
.end();
76 I
->addLiveIn(MSP430::FP
);
79 NumBytes
= StackSize
- MSP430FI
->getCalleeSavedFrameSize();
81 // Skip the callee-saved push instructions.
82 while (MBBI
!= MBB
.end() && (MBBI
->getOpcode() == MSP430::PUSH16r
))
85 if (MBBI
!= MBB
.end())
86 DL
= MBBI
->getDebugLoc();
88 if (NumBytes
) { // adjust stack pointer: SP -= numbytes
89 // If there is an SUB16ri of SP immediately before this instruction, merge
91 //NumBytes -= mergeSPUpdates(MBB, MBBI, true);
92 // If there is an ADD16ri or SUB16ri of SP immediately after this
93 // instruction, merge the two instructions.
94 // mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
98 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::SUB16ri
), MSP430::SP
)
99 .addReg(MSP430::SP
).addImm(NumBytes
);
100 // The SRW implicit def is dead.
101 MI
->getOperand(3).setIsDead();
106 void MSP430FrameLowering::emitEpilogue(MachineFunction
&MF
,
107 MachineBasicBlock
&MBB
) const {
108 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
109 MSP430MachineFunctionInfo
*MSP430FI
= MF
.getInfo
<MSP430MachineFunctionInfo
>();
110 const MSP430InstrInfo
&TII
=
111 *static_cast<const MSP430InstrInfo
*>(MF
.getSubtarget().getInstrInfo());
113 MachineBasicBlock::iterator MBBI
= MBB
.getLastNonDebugInstr();
114 unsigned RetOpcode
= MBBI
->getOpcode();
115 DebugLoc DL
= MBBI
->getDebugLoc();
119 case MSP430::RETI
: break; // These are ok
121 llvm_unreachable("Can only insert epilog into returning blocks");
124 // Get the number of bytes to allocate from the FrameInfo
125 uint64_t StackSize
= MFI
.getStackSize();
126 unsigned CSSize
= MSP430FI
->getCalleeSavedFrameSize();
127 uint64_t NumBytes
= 0;
130 // Calculate required stack adjustment
131 uint64_t FrameSize
= StackSize
- 2;
132 NumBytes
= FrameSize
- CSSize
;
135 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::POP16r
), MSP430::FP
);
137 NumBytes
= StackSize
- CSSize
;
139 // Skip the callee-saved pop instructions.
140 while (MBBI
!= MBB
.begin()) {
141 MachineBasicBlock::iterator PI
= std::prev(MBBI
);
142 unsigned Opc
= PI
->getOpcode();
143 if (Opc
!= MSP430::POP16r
&& !PI
->isTerminator())
148 DL
= MBBI
->getDebugLoc();
150 // If there is an ADD16ri or SUB16ri of SP immediately before this
151 // instruction, merge the two instructions.
152 //if (NumBytes || MFI.hasVarSizedObjects())
153 // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
155 if (MFI
.hasVarSizedObjects()) {
156 BuildMI(MBB
, MBBI
, DL
,
157 TII
.get(MSP430::MOV16rr
), MSP430::SP
).addReg(MSP430::FP
);
160 BuildMI(MBB
, MBBI
, DL
,
161 TII
.get(MSP430::SUB16ri
), MSP430::SP
)
162 .addReg(MSP430::SP
).addImm(CSSize
);
163 // The SRW implicit def is dead.
164 MI
->getOperand(3).setIsDead();
167 // adjust stack pointer back: SP += numbytes
170 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::ADD16ri
), MSP430::SP
)
171 .addReg(MSP430::SP
).addImm(NumBytes
);
172 // The SRW implicit def is dead.
173 MI
->getOperand(3).setIsDead();
178 // FIXME: Can we eleminate these in favour of generic code?
180 MSP430FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock
&MBB
,
181 MachineBasicBlock::iterator MI
,
182 const std::vector
<CalleeSavedInfo
> &CSI
,
183 const TargetRegisterInfo
*TRI
) const {
188 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
190 MachineFunction
&MF
= *MBB
.getParent();
191 const TargetInstrInfo
&TII
= *MF
.getSubtarget().getInstrInfo();
192 MSP430MachineFunctionInfo
*MFI
= MF
.getInfo
<MSP430MachineFunctionInfo
>();
193 MFI
->setCalleeSavedFrameSize(CSI
.size() * 2);
195 for (unsigned i
= CSI
.size(); i
!= 0; --i
) {
196 unsigned Reg
= CSI
[i
-1].getReg();
197 // Add the callee-saved register as live-in. It's killed at the spill.
199 BuildMI(MBB
, MI
, DL
, TII
.get(MSP430::PUSH16r
))
200 .addReg(Reg
, RegState::Kill
);
206 MSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock
&MBB
,
207 MachineBasicBlock::iterator MI
,
208 std::vector
<CalleeSavedInfo
> &CSI
,
209 const TargetRegisterInfo
*TRI
) const {
214 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
216 MachineFunction
&MF
= *MBB
.getParent();
217 const TargetInstrInfo
&TII
= *MF
.getSubtarget().getInstrInfo();
219 for (unsigned i
= 0, e
= CSI
.size(); i
!= e
; ++i
)
220 BuildMI(MBB
, MI
, DL
, TII
.get(MSP430::POP16r
), CSI
[i
].getReg());
225 MachineBasicBlock::iterator
MSP430FrameLowering::eliminateCallFramePseudoInstr(
226 MachineFunction
&MF
, MachineBasicBlock
&MBB
,
227 MachineBasicBlock::iterator I
) const {
228 const MSP430InstrInfo
&TII
=
229 *static_cast<const MSP430InstrInfo
*>(MF
.getSubtarget().getInstrInfo());
230 unsigned StackAlign
= getStackAlignment();
232 if (!hasReservedCallFrame(MF
)) {
233 // If the stack pointer can be changed after prologue, turn the
234 // adjcallstackup instruction into a 'sub SP, <amt>' and the
235 // adjcallstackdown instruction into 'add SP, <amt>'
236 // TODO: consider using push / pop instead of sub + store / add
237 MachineInstr
&Old
= *I
;
238 uint64_t Amount
= TII
.getFrameSize(Old
);
240 // We need to keep the stack aligned properly. To do this, we round the
241 // amount of space needed for the outgoing arguments up to the next
242 // alignment boundary.
243 Amount
= (Amount
+StackAlign
-1)/StackAlign
*StackAlign
;
245 MachineInstr
*New
= nullptr;
246 if (Old
.getOpcode() == TII
.getCallFrameSetupOpcode()) {
248 BuildMI(MF
, Old
.getDebugLoc(), TII
.get(MSP430::SUB16ri
), MSP430::SP
)
252 assert(Old
.getOpcode() == TII
.getCallFrameDestroyOpcode());
253 // factor out the amount the callee already popped.
254 Amount
-= TII
.getFramePoppedByCallee(Old
);
256 New
= BuildMI(MF
, Old
.getDebugLoc(), TII
.get(MSP430::ADD16ri
),
263 // The SRW implicit def is dead.
264 New
->getOperand(3).setIsDead();
266 // Replace the pseudo instruction with a new instruction...
270 } else if (I
->getOpcode() == TII
.getCallFrameDestroyOpcode()) {
271 // If we are performing frame pointer elimination and if the callee pops
272 // something off the stack pointer, add it back.
273 if (uint64_t CalleeAmt
= TII
.getFramePoppedByCallee(*I
)) {
274 MachineInstr
&Old
= *I
;
276 BuildMI(MF
, Old
.getDebugLoc(), TII
.get(MSP430::SUB16ri
), MSP430::SP
)
279 // The SRW implicit def is dead.
280 New
->getOperand(3).setIsDead();
290 MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction
&MF
,
291 RegScavenger
*) const {
292 // Create a frame entry for the FP register that must be saved.
294 int FrameIdx
= MF
.getFrameInfo().CreateFixedObject(2, -4, true);
296 assert(FrameIdx
== MF
.getFrameInfo().getObjectIndexBegin() &&
297 "Slot for FP register must be last in order to be found!");