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::R4
, RegState::Kill
);
69 // Update FP with the new base value...
70 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::MOV16rr
), MSP430::R4
)
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::R4
);
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::R4
);
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::R4
);
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?
179 bool MSP430FrameLowering::spillCalleeSavedRegisters(
180 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MI
,
181 ArrayRef
<CalleeSavedInfo
> CSI
, const TargetRegisterInfo
*TRI
) const {
186 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
188 MachineFunction
&MF
= *MBB
.getParent();
189 const TargetInstrInfo
&TII
= *MF
.getSubtarget().getInstrInfo();
190 MSP430MachineFunctionInfo
*MFI
= MF
.getInfo
<MSP430MachineFunctionInfo
>();
191 MFI
->setCalleeSavedFrameSize(CSI
.size() * 2);
193 for (unsigned i
= CSI
.size(); i
!= 0; --i
) {
194 unsigned Reg
= CSI
[i
-1].getReg();
195 // Add the callee-saved register as live-in. It's killed at the spill.
197 BuildMI(MBB
, MI
, DL
, TII
.get(MSP430::PUSH16r
))
198 .addReg(Reg
, RegState::Kill
);
203 bool MSP430FrameLowering::restoreCalleeSavedRegisters(
204 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MI
,
205 MutableArrayRef
<CalleeSavedInfo
> CSI
, const TargetRegisterInfo
*TRI
) const {
210 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
212 MachineFunction
&MF
= *MBB
.getParent();
213 const TargetInstrInfo
&TII
= *MF
.getSubtarget().getInstrInfo();
215 for (unsigned i
= 0, e
= CSI
.size(); i
!= e
; ++i
)
216 BuildMI(MBB
, MI
, DL
, TII
.get(MSP430::POP16r
), CSI
[i
].getReg());
221 MachineBasicBlock::iterator
MSP430FrameLowering::eliminateCallFramePseudoInstr(
222 MachineFunction
&MF
, MachineBasicBlock
&MBB
,
223 MachineBasicBlock::iterator I
) const {
224 const MSP430InstrInfo
&TII
=
225 *static_cast<const MSP430InstrInfo
*>(MF
.getSubtarget().getInstrInfo());
226 if (!hasReservedCallFrame(MF
)) {
227 // If the stack pointer can be changed after prologue, turn the
228 // adjcallstackup instruction into a 'sub SP, <amt>' and the
229 // adjcallstackdown instruction into 'add SP, <amt>'
230 // TODO: consider using push / pop instead of sub + store / add
231 MachineInstr
&Old
= *I
;
232 uint64_t Amount
= TII
.getFrameSize(Old
);
234 // We need to keep the stack aligned properly. To do this, we round the
235 // amount of space needed for the outgoing arguments up to the next
236 // alignment boundary.
237 Amount
= alignTo(Amount
, getStackAlign());
239 MachineInstr
*New
= nullptr;
240 if (Old
.getOpcode() == TII
.getCallFrameSetupOpcode()) {
242 BuildMI(MF
, Old
.getDebugLoc(), TII
.get(MSP430::SUB16ri
), MSP430::SP
)
246 assert(Old
.getOpcode() == TII
.getCallFrameDestroyOpcode());
247 // factor out the amount the callee already popped.
248 Amount
-= TII
.getFramePoppedByCallee(Old
);
250 New
= BuildMI(MF
, Old
.getDebugLoc(), TII
.get(MSP430::ADD16ri
),
257 // The SRW implicit def is dead.
258 New
->getOperand(3).setIsDead();
260 // Replace the pseudo instruction with a new instruction...
264 } else if (I
->getOpcode() == TII
.getCallFrameDestroyOpcode()) {
265 // If we are performing frame pointer elimination and if the callee pops
266 // something off the stack pointer, add it back.
267 if (uint64_t CalleeAmt
= TII
.getFramePoppedByCallee(*I
)) {
268 MachineInstr
&Old
= *I
;
270 BuildMI(MF
, Old
.getDebugLoc(), TII
.get(MSP430::SUB16ri
), MSP430::SP
)
273 // The SRW implicit def is dead.
274 New
->getOperand(3).setIsDead();
284 MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction
&MF
,
285 RegScavenger
*) const {
286 // Create a frame entry for the FP register that must be saved.
288 int FrameIdx
= MF
.getFrameInfo().CreateFixedObject(2, -4, true);
290 assert(FrameIdx
== MF
.getFrameInfo().getObjectIndexBegin() &&
291 "Slot for FP register must be last in order to be found!");