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/Target/TargetOptions.h"
25 MSP430FrameLowering::MSP430FrameLowering(const MSP430Subtarget
&STI
)
26 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown
, Align(2), -2,
28 STI(STI
), TII(*STI
.getInstrInfo()), TRI(STI
.getRegisterInfo()) {}
30 bool MSP430FrameLowering::hasFPImpl(const MachineFunction
&MF
) const {
31 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
33 return (MF
.getTarget().Options
.DisableFramePointerElim(MF
) ||
34 MF
.getFrameInfo().hasVarSizedObjects() ||
35 MFI
.isFrameAddressTaken());
38 bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction
&MF
) const {
39 return !MF
.getFrameInfo().hasVarSizedObjects();
42 void MSP430FrameLowering::BuildCFI(MachineBasicBlock
&MBB
,
43 MachineBasicBlock::iterator MBBI
,
45 const MCCFIInstruction
&CFIInst
,
46 MachineInstr::MIFlag Flag
) const {
47 MachineFunction
&MF
= *MBB
.getParent();
48 unsigned CFIIndex
= MF
.addFrameInst(CFIInst
);
49 BuildMI(MBB
, MBBI
, DL
, TII
.get(TargetOpcode::CFI_INSTRUCTION
))
50 .addCFIIndex(CFIIndex
)
54 void MSP430FrameLowering::emitCalleeSavedFrameMoves(
55 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
56 const DebugLoc
&DL
, bool IsPrologue
) const {
57 MachineFunction
&MF
= *MBB
.getParent();
58 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
59 const MCRegisterInfo
*MRI
= MF
.getContext().getRegisterInfo();
61 // Add callee saved registers to move list.
62 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
.getCalleeSavedInfo();
65 for (const CalleeSavedInfo
&I
: CSI
) {
66 int64_t Offset
= MFI
.getObjectOffset(I
.getFrameIdx());
67 Register Reg
= I
.getReg();
68 unsigned DwarfReg
= MRI
->getDwarfRegNum(Reg
, true);
71 BuildCFI(MBB
, MBBI
, DL
,
72 MCCFIInstruction::createOffset(nullptr, DwarfReg
, Offset
));
74 BuildCFI(MBB
, MBBI
, DL
,
75 MCCFIInstruction::createRestore(nullptr, DwarfReg
));
80 void MSP430FrameLowering::emitPrologue(MachineFunction
&MF
,
81 MachineBasicBlock
&MBB
) const {
82 assert(&MF
.front() == &MBB
&& "Shrink-wrapping not yet supported");
83 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
84 MSP430MachineFunctionInfo
*MSP430FI
= MF
.getInfo
<MSP430MachineFunctionInfo
>();
85 const MSP430InstrInfo
&TII
=
86 *static_cast<const MSP430InstrInfo
*>(MF
.getSubtarget().getInstrInfo());
88 MachineBasicBlock::iterator MBBI
= MBB
.begin();
89 DebugLoc DL
= MBBI
!= MBB
.end() ? MBBI
->getDebugLoc() : DebugLoc();
91 // Get the number of bytes to allocate from the FrameInfo.
92 uint64_t StackSize
= MFI
.getStackSize();
95 uint64_t NumBytes
= 0;
97 // Calculate required stack adjustment
98 uint64_t FrameSize
= StackSize
- 2;
99 NumBytes
= FrameSize
- MSP430FI
->getCalleeSavedFrameSize();
101 // Get the offset of the stack slot for the EBP register... which is
102 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
103 // Update the frame offset adjustment.
104 MFI
.setOffsetAdjustment(-NumBytes
);
106 // Save FP into the appropriate stack slot...
107 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::PUSH16r
))
108 .addReg(MSP430::R4
, RegState::Kill
)
109 .setMIFlag(MachineInstr::FrameSetup
);
111 // Mark the place where FP was saved.
112 // Define the current CFA rule to use the provided offset.
113 BuildCFI(MBB
, MBBI
, DL
,
114 MCCFIInstruction::cfiDefCfaOffset(nullptr, -2 * stackGrowth
),
115 MachineInstr::FrameSetup
);
117 // Change the rule for the FramePtr to be an "offset" rule.
118 unsigned DwarfFramePtr
= TRI
->getDwarfRegNum(MSP430::R4
, true);
121 MCCFIInstruction::createOffset(nullptr, DwarfFramePtr
, 2 * stackGrowth
),
122 MachineInstr::FrameSetup
);
124 // Update FP with the new base value...
125 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::MOV16rr
), MSP430::R4
)
127 .setMIFlag(MachineInstr::FrameSetup
);
129 // Mark effective beginning of when frame pointer becomes valid.
130 // Define the current CFA to use the FP register.
131 BuildCFI(MBB
, MBBI
, DL
,
132 MCCFIInstruction::createDefCfaRegister(nullptr, DwarfFramePtr
),
133 MachineInstr::FrameSetup
);
135 // Mark the FramePtr as live-in in every block except the entry.
136 for (MachineBasicBlock
&MBBJ
: llvm::drop_begin(MF
))
137 MBBJ
.addLiveIn(MSP430::R4
);
139 NumBytes
= StackSize
- MSP430FI
->getCalleeSavedFrameSize();
141 // Skip the callee-saved push instructions.
142 int StackOffset
= 2 * stackGrowth
;
143 while (MBBI
!= MBB
.end() && MBBI
->getFlag(MachineInstr::FrameSetup
) &&
144 (MBBI
->getOpcode() == MSP430::PUSH16r
)) {
148 // Mark callee-saved push instruction.
149 // Define the current CFA rule to use the provided offset.
150 assert(StackSize
&& "Expected stack frame");
151 BuildCFI(MBB
, MBBI
, DL
,
152 MCCFIInstruction::cfiDefCfaOffset(nullptr, -StackOffset
),
153 MachineInstr::FrameSetup
);
154 StackOffset
+= stackGrowth
;
158 if (MBBI
!= MBB
.end())
159 DL
= MBBI
->getDebugLoc();
161 if (NumBytes
) { // adjust stack pointer: SP -= numbytes
162 // If there is an SUB16ri of SP immediately before this instruction, merge
164 //NumBytes -= mergeSPUpdates(MBB, MBBI, true);
165 // If there is an ADD16ri or SUB16ri of SP immediately after this
166 // instruction, merge the two instructions.
167 // mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
171 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::SUB16ri
), MSP430::SP
)
174 .setMIFlag(MachineInstr::FrameSetup
);
175 // The SRW implicit def is dead.
176 MI
->getOperand(3).setIsDead();
179 // Adjust the previous CFA value if CFA was not redefined by FP
182 MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize
- stackGrowth
),
183 MachineInstr::FrameSetup
);
187 emitCalleeSavedFrameMoves(MBB
, MBBI
, DL
, true);
190 void MSP430FrameLowering::emitEpilogue(MachineFunction
&MF
,
191 MachineBasicBlock
&MBB
) const {
192 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
193 MSP430MachineFunctionInfo
*MSP430FI
= MF
.getInfo
<MSP430MachineFunctionInfo
>();
194 const MSP430InstrInfo
&TII
=
195 *static_cast<const MSP430InstrInfo
*>(MF
.getSubtarget().getInstrInfo());
197 MachineBasicBlock::iterator MBBI
= MBB
.getLastNonDebugInstr();
198 unsigned RetOpcode
= MBBI
->getOpcode();
199 DebugLoc DL
= MBBI
->getDebugLoc();
203 case MSP430::RETI
: break; // These are ok
205 llvm_unreachable("Can only insert epilog into returning blocks");
208 // Get the number of bytes to allocate from the FrameInfo
209 uint64_t StackSize
= MFI
.getStackSize();
210 unsigned CSSize
= MSP430FI
->getCalleeSavedFrameSize();
211 uint64_t NumBytes
= 0;
213 MachineBasicBlock::iterator AfterPop
= MBBI
;
215 // Calculate required stack adjustment
216 uint64_t FrameSize
= StackSize
- 2;
217 NumBytes
= FrameSize
- CSSize
;
220 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::POP16r
), MSP430::R4
)
221 .setMIFlag(MachineInstr::FrameDestroy
);
222 unsigned DwarfStackPtr
= TRI
->getDwarfRegNum(MSP430::SP
, true);
223 BuildCFI(MBB
, MBBI
, DL
,
224 MCCFIInstruction::cfiDefCfa(nullptr, DwarfStackPtr
, 2),
225 MachineInstr::FrameDestroy
);
227 if (!MBB
.succ_empty() && !MBB
.isReturnBlock()) {
228 unsigned DwarfFramePtr
= TRI
->getDwarfRegNum(MSP430::R4
, true);
229 BuildCFI(MBB
, AfterPop
, DL
,
230 MCCFIInstruction::createRestore(nullptr, DwarfFramePtr
),
231 MachineInstr::FrameDestroy
);
236 NumBytes
= StackSize
- CSSize
;
238 // Skip the callee-saved pop instructions.
239 MachineBasicBlock::iterator FirstCSPop
= MBBI
;
240 while (MBBI
!= MBB
.begin()) {
241 MachineBasicBlock::iterator PI
= std::prev(MBBI
);
242 unsigned Opc
= PI
->getOpcode();
243 if ((Opc
!= MSP430::POP16r
|| !PI
->getFlag(MachineInstr::FrameDestroy
)) &&
251 DL
= MBBI
->getDebugLoc();
253 // If there is an ADD16ri or SUB16ri of SP immediately before this
254 // instruction, merge the two instructions.
255 //if (NumBytes || MFI.hasVarSizedObjects())
256 // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
258 if (MFI
.hasVarSizedObjects()) {
259 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::MOV16rr
), MSP430::SP
)
261 .setMIFlag(MachineInstr::FrameDestroy
);
264 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::SUB16ri
), MSP430::SP
)
267 .setMIFlag(MachineInstr::FrameDestroy
);
268 // The SRW implicit def is dead.
269 MI
->getOperand(3).setIsDead();
272 // adjust stack pointer back: SP += numbytes
275 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::ADD16ri
), MSP430::SP
)
278 .setMIFlag(MachineInstr::FrameDestroy
);
279 // The SRW implicit def is dead.
280 MI
->getOperand(3).setIsDead();
283 // Adjust CFA value if it was defined by SP
284 BuildCFI(MBB
, MBBI
, DL
,
285 MCCFIInstruction::cfiDefCfaOffset(nullptr, CSSize
+ 2),
286 MachineInstr::FrameDestroy
);
293 int64_t Offset
= -(int64_t)CSSize
- 2;
294 // Mark callee-saved pop instruction.
295 // Define the current CFA rule to use the provided offset.
296 while (MBBI
!= MBB
.end()) {
297 MachineBasicBlock::iterator PI
= MBBI
;
298 unsigned Opc
= PI
->getOpcode();
300 if (Opc
== MSP430::POP16r
) {
302 BuildCFI(MBB
, MBBI
, DL
,
303 MCCFIInstruction::cfiDefCfaOffset(nullptr, -Offset
),
304 MachineInstr::FrameDestroy
);
308 emitCalleeSavedFrameMoves(MBB
, AfterPop
, DL
, false);
311 // FIXME: Can we eleminate these in favour of generic code?
312 bool MSP430FrameLowering::spillCalleeSavedRegisters(
313 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MI
,
314 ArrayRef
<CalleeSavedInfo
> CSI
, const TargetRegisterInfo
*TRI
) const {
319 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
321 MachineFunction
&MF
= *MBB
.getParent();
322 const TargetInstrInfo
&TII
= *MF
.getSubtarget().getInstrInfo();
323 MSP430MachineFunctionInfo
*MFI
= MF
.getInfo
<MSP430MachineFunctionInfo
>();
324 MFI
->setCalleeSavedFrameSize(CSI
.size() * 2);
326 for (const CalleeSavedInfo
&I
: CSI
) {
327 Register Reg
= I
.getReg();
328 // Add the callee-saved register as live-in. It's killed at the spill.
330 BuildMI(MBB
, MI
, DL
, TII
.get(MSP430::PUSH16r
))
331 .addReg(Reg
, RegState::Kill
)
332 .setMIFlag(MachineInstr::FrameSetup
);
337 bool MSP430FrameLowering::restoreCalleeSavedRegisters(
338 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MI
,
339 MutableArrayRef
<CalleeSavedInfo
> CSI
, const TargetRegisterInfo
*TRI
) const {
344 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
346 MachineFunction
&MF
= *MBB
.getParent();
347 const TargetInstrInfo
&TII
= *MF
.getSubtarget().getInstrInfo();
349 for (const CalleeSavedInfo
&I
: llvm::reverse(CSI
))
350 BuildMI(MBB
, MI
, DL
, TII
.get(MSP430::POP16r
), I
.getReg())
351 .setMIFlag(MachineInstr::FrameDestroy
);
356 MachineBasicBlock::iterator
MSP430FrameLowering::eliminateCallFramePseudoInstr(
357 MachineFunction
&MF
, MachineBasicBlock
&MBB
,
358 MachineBasicBlock::iterator I
) const {
359 const MSP430InstrInfo
&TII
=
360 *static_cast<const MSP430InstrInfo
*>(MF
.getSubtarget().getInstrInfo());
361 if (!hasReservedCallFrame(MF
)) {
362 // If the stack pointer can be changed after prologue, turn the
363 // adjcallstackup instruction into a 'sub SP, <amt>' and the
364 // adjcallstackdown instruction into 'add SP, <amt>'
365 // TODO: consider using push / pop instead of sub + store / add
366 MachineInstr
&Old
= *I
;
367 uint64_t Amount
= TII
.getFrameSize(Old
);
369 // We need to keep the stack aligned properly. To do this, we round the
370 // amount of space needed for the outgoing arguments up to the next
371 // alignment boundary.
372 Amount
= alignTo(Amount
, getStackAlign());
374 MachineInstr
*New
= nullptr;
375 if (Old
.getOpcode() == TII
.getCallFrameSetupOpcode()) {
377 BuildMI(MF
, Old
.getDebugLoc(), TII
.get(MSP430::SUB16ri
), MSP430::SP
)
381 assert(Old
.getOpcode() == TII
.getCallFrameDestroyOpcode());
382 // factor out the amount the callee already popped.
383 Amount
-= TII
.getFramePoppedByCallee(Old
);
385 New
= BuildMI(MF
, Old
.getDebugLoc(), TII
.get(MSP430::ADD16ri
),
392 // The SRW implicit def is dead.
393 New
->getOperand(3).setIsDead();
395 // Replace the pseudo instruction with a new instruction...
399 } else if (I
->getOpcode() == TII
.getCallFrameDestroyOpcode()) {
400 // If we are performing frame pointer elimination and if the callee pops
401 // something off the stack pointer, add it back.
402 if (uint64_t CalleeAmt
= TII
.getFramePoppedByCallee(*I
)) {
403 MachineInstr
&Old
= *I
;
405 BuildMI(MF
, Old
.getDebugLoc(), TII
.get(MSP430::SUB16ri
), MSP430::SP
)
409 DebugLoc DL
= I
->getDebugLoc();
411 MCCFIInstruction::createAdjustCfaOffset(nullptr, CalleeAmt
));
413 // The SRW implicit def is dead.
414 New
->getOperand(3).setIsDead();
424 MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction
&MF
,
425 RegScavenger
*) const {
426 // Create a frame entry for the FP register that must be saved.
428 int FrameIdx
= MF
.getFrameInfo().CreateFixedObject(2, -4, true);
430 assert(FrameIdx
== MF
.getFrameInfo().getObjectIndexBegin() &&
431 "Slot for FP register must be last in order to be found!");