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 MSP430FrameLowering::MSP430FrameLowering(const MSP430Subtarget
&STI
)
29 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown
, Align(2), -2,
31 STI(STI
), TII(*STI
.getInstrInfo()), TRI(STI
.getRegisterInfo()) {}
33 bool MSP430FrameLowering::hasFP(const MachineFunction
&MF
) const {
34 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
36 return (MF
.getTarget().Options
.DisableFramePointerElim(MF
) ||
37 MF
.getFrameInfo().hasVarSizedObjects() ||
38 MFI
.isFrameAddressTaken());
41 bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction
&MF
) const {
42 return !MF
.getFrameInfo().hasVarSizedObjects();
45 void MSP430FrameLowering::BuildCFI(MachineBasicBlock
&MBB
,
46 MachineBasicBlock::iterator MBBI
,
48 const MCCFIInstruction
&CFIInst
,
49 MachineInstr::MIFlag Flag
) const {
50 MachineFunction
&MF
= *MBB
.getParent();
51 unsigned CFIIndex
= MF
.addFrameInst(CFIInst
);
52 BuildMI(MBB
, MBBI
, DL
, TII
.get(TargetOpcode::CFI_INSTRUCTION
))
53 .addCFIIndex(CFIIndex
)
57 void MSP430FrameLowering::emitCalleeSavedFrameMoves(
58 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
59 const DebugLoc
&DL
, bool IsPrologue
) const {
60 MachineFunction
&MF
= *MBB
.getParent();
61 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
62 MachineModuleInfo
&MMI
= MF
.getMMI();
63 const MCRegisterInfo
*MRI
= MMI
.getContext().getRegisterInfo();
65 // Add callee saved registers to move list.
66 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
.getCalleeSavedInfo();
69 for (const CalleeSavedInfo
&I
: CSI
) {
70 int64_t Offset
= MFI
.getObjectOffset(I
.getFrameIdx());
71 Register Reg
= I
.getReg();
72 unsigned DwarfReg
= MRI
->getDwarfRegNum(Reg
, true);
75 BuildCFI(MBB
, MBBI
, DL
,
76 MCCFIInstruction::createOffset(nullptr, DwarfReg
, Offset
));
78 BuildCFI(MBB
, MBBI
, DL
,
79 MCCFIInstruction::createRestore(nullptr, DwarfReg
));
84 void MSP430FrameLowering::emitPrologue(MachineFunction
&MF
,
85 MachineBasicBlock
&MBB
) const {
86 assert(&MF
.front() == &MBB
&& "Shrink-wrapping not yet supported");
87 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
88 MSP430MachineFunctionInfo
*MSP430FI
= MF
.getInfo
<MSP430MachineFunctionInfo
>();
89 const MSP430InstrInfo
&TII
=
90 *static_cast<const MSP430InstrInfo
*>(MF
.getSubtarget().getInstrInfo());
92 MachineBasicBlock::iterator MBBI
= MBB
.begin();
93 DebugLoc DL
= MBBI
!= MBB
.end() ? MBBI
->getDebugLoc() : DebugLoc();
95 // Get the number of bytes to allocate from the FrameInfo.
96 uint64_t StackSize
= MFI
.getStackSize();
99 uint64_t NumBytes
= 0;
101 // Calculate required stack adjustment
102 uint64_t FrameSize
= StackSize
- 2;
103 NumBytes
= FrameSize
- MSP430FI
->getCalleeSavedFrameSize();
105 // Get the offset of the stack slot for the EBP register... which is
106 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
107 // Update the frame offset adjustment.
108 MFI
.setOffsetAdjustment(-NumBytes
);
110 // Save FP into the appropriate stack slot...
111 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::PUSH16r
))
112 .addReg(MSP430::R4
, RegState::Kill
)
113 .setMIFlag(MachineInstr::FrameSetup
);
115 // Mark the place where FP was saved.
116 // Define the current CFA rule to use the provided offset.
117 BuildCFI(MBB
, MBBI
, DL
,
118 MCCFIInstruction::cfiDefCfaOffset(nullptr, -2 * stackGrowth
),
119 MachineInstr::FrameSetup
);
121 // Change the rule for the FramePtr to be an "offset" rule.
122 unsigned DwarfFramePtr
= TRI
->getDwarfRegNum(MSP430::R4
, true);
125 MCCFIInstruction::createOffset(nullptr, DwarfFramePtr
, 2 * stackGrowth
),
126 MachineInstr::FrameSetup
);
128 // Update FP with the new base value...
129 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::MOV16rr
), MSP430::R4
)
131 .setMIFlag(MachineInstr::FrameSetup
);
133 // Mark effective beginning of when frame pointer becomes valid.
134 // Define the current CFA to use the FP register.
135 BuildCFI(MBB
, MBBI
, DL
,
136 MCCFIInstruction::createDefCfaRegister(nullptr, DwarfFramePtr
),
137 MachineInstr::FrameSetup
);
139 // Mark the FramePtr as live-in in every block except the entry.
140 for (MachineBasicBlock
&MBBJ
: llvm::drop_begin(MF
))
141 MBBJ
.addLiveIn(MSP430::R4
);
143 NumBytes
= StackSize
- MSP430FI
->getCalleeSavedFrameSize();
145 // Skip the callee-saved push instructions.
146 int StackOffset
= 2 * stackGrowth
;
147 while (MBBI
!= MBB
.end() && MBBI
->getFlag(MachineInstr::FrameSetup
) &&
148 (MBBI
->getOpcode() == MSP430::PUSH16r
)) {
152 // Mark callee-saved push instruction.
153 // Define the current CFA rule to use the provided offset.
154 assert(StackSize
&& "Expected stack frame");
155 BuildCFI(MBB
, MBBI
, DL
,
156 MCCFIInstruction::cfiDefCfaOffset(nullptr, -StackOffset
),
157 MachineInstr::FrameSetup
);
158 StackOffset
+= stackGrowth
;
162 if (MBBI
!= MBB
.end())
163 DL
= MBBI
->getDebugLoc();
165 if (NumBytes
) { // adjust stack pointer: SP -= numbytes
166 // If there is an SUB16ri of SP immediately before this instruction, merge
168 //NumBytes -= mergeSPUpdates(MBB, MBBI, true);
169 // If there is an ADD16ri or SUB16ri of SP immediately after this
170 // instruction, merge the two instructions.
171 // mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
175 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::SUB16ri
), MSP430::SP
)
178 .setMIFlag(MachineInstr::FrameSetup
);
179 // The SRW implicit def is dead.
180 MI
->getOperand(3).setIsDead();
183 // Adjust the previous CFA value if CFA was not redefined by FP
186 MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize
- stackGrowth
),
187 MachineInstr::FrameSetup
);
191 emitCalleeSavedFrameMoves(MBB
, MBBI
, DL
, true);
194 void MSP430FrameLowering::emitEpilogue(MachineFunction
&MF
,
195 MachineBasicBlock
&MBB
) const {
196 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
197 MSP430MachineFunctionInfo
*MSP430FI
= MF
.getInfo
<MSP430MachineFunctionInfo
>();
198 const MSP430InstrInfo
&TII
=
199 *static_cast<const MSP430InstrInfo
*>(MF
.getSubtarget().getInstrInfo());
201 MachineBasicBlock::iterator MBBI
= MBB
.getLastNonDebugInstr();
202 unsigned RetOpcode
= MBBI
->getOpcode();
203 DebugLoc DL
= MBBI
->getDebugLoc();
207 case MSP430::RETI
: break; // These are ok
209 llvm_unreachable("Can only insert epilog into returning blocks");
212 // Get the number of bytes to allocate from the FrameInfo
213 uint64_t StackSize
= MFI
.getStackSize();
214 unsigned CSSize
= MSP430FI
->getCalleeSavedFrameSize();
215 uint64_t NumBytes
= 0;
217 MachineBasicBlock::iterator AfterPop
= MBBI
;
219 // Calculate required stack adjustment
220 uint64_t FrameSize
= StackSize
- 2;
221 NumBytes
= FrameSize
- CSSize
;
224 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::POP16r
), MSP430::R4
)
225 .setMIFlag(MachineInstr::FrameDestroy
);
226 unsigned DwarfStackPtr
= TRI
->getDwarfRegNum(MSP430::SP
, true);
227 BuildCFI(MBB
, MBBI
, DL
,
228 MCCFIInstruction::cfiDefCfa(nullptr, DwarfStackPtr
, 2),
229 MachineInstr::FrameDestroy
);
231 if (!MBB
.succ_empty() && !MBB
.isReturnBlock()) {
232 unsigned DwarfFramePtr
= TRI
->getDwarfRegNum(MSP430::R4
, true);
233 BuildCFI(MBB
, AfterPop
, DL
,
234 MCCFIInstruction::createRestore(nullptr, DwarfFramePtr
),
235 MachineInstr::FrameDestroy
);
240 NumBytes
= StackSize
- CSSize
;
242 // Skip the callee-saved pop instructions.
243 MachineBasicBlock::iterator FirstCSPop
= MBBI
;
244 while (MBBI
!= MBB
.begin()) {
245 MachineBasicBlock::iterator PI
= std::prev(MBBI
);
246 unsigned Opc
= PI
->getOpcode();
247 if ((Opc
!= MSP430::POP16r
|| !PI
->getFlag(MachineInstr::FrameDestroy
)) &&
255 DL
= MBBI
->getDebugLoc();
257 // If there is an ADD16ri or SUB16ri of SP immediately before this
258 // instruction, merge the two instructions.
259 //if (NumBytes || MFI.hasVarSizedObjects())
260 // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
262 if (MFI
.hasVarSizedObjects()) {
263 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::MOV16rr
), MSP430::SP
)
265 .setMIFlag(MachineInstr::FrameDestroy
);
268 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::SUB16ri
), MSP430::SP
)
271 .setMIFlag(MachineInstr::FrameDestroy
);
272 // The SRW implicit def is dead.
273 MI
->getOperand(3).setIsDead();
276 // adjust stack pointer back: SP += numbytes
279 BuildMI(MBB
, MBBI
, DL
, TII
.get(MSP430::ADD16ri
), MSP430::SP
)
282 .setMIFlag(MachineInstr::FrameDestroy
);
283 // The SRW implicit def is dead.
284 MI
->getOperand(3).setIsDead();
287 // Adjust CFA value if it was defined by SP
288 BuildCFI(MBB
, MBBI
, DL
,
289 MCCFIInstruction::cfiDefCfaOffset(nullptr, CSSize
+ 2),
290 MachineInstr::FrameDestroy
);
297 int64_t Offset
= -CSSize
- 2;
298 // Mark callee-saved pop instruction.
299 // Define the current CFA rule to use the provided offset.
300 while (MBBI
!= MBB
.end()) {
301 MachineBasicBlock::iterator PI
= MBBI
;
302 unsigned Opc
= PI
->getOpcode();
304 if (Opc
== MSP430::POP16r
) {
306 BuildCFI(MBB
, MBBI
, DL
,
307 MCCFIInstruction::cfiDefCfaOffset(nullptr, -Offset
),
308 MachineInstr::FrameDestroy
);
312 emitCalleeSavedFrameMoves(MBB
, AfterPop
, DL
, false);
315 // FIXME: Can we eleminate these in favour of generic code?
316 bool MSP430FrameLowering::spillCalleeSavedRegisters(
317 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MI
,
318 ArrayRef
<CalleeSavedInfo
> CSI
, const TargetRegisterInfo
*TRI
) const {
323 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
325 MachineFunction
&MF
= *MBB
.getParent();
326 const TargetInstrInfo
&TII
= *MF
.getSubtarget().getInstrInfo();
327 MSP430MachineFunctionInfo
*MFI
= MF
.getInfo
<MSP430MachineFunctionInfo
>();
328 MFI
->setCalleeSavedFrameSize(CSI
.size() * 2);
330 for (const CalleeSavedInfo
&I
: CSI
) {
331 Register Reg
= I
.getReg();
332 // Add the callee-saved register as live-in. It's killed at the spill.
334 BuildMI(MBB
, MI
, DL
, TII
.get(MSP430::PUSH16r
))
335 .addReg(Reg
, RegState::Kill
)
336 .setMIFlag(MachineInstr::FrameSetup
);
341 bool MSP430FrameLowering::restoreCalleeSavedRegisters(
342 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MI
,
343 MutableArrayRef
<CalleeSavedInfo
> CSI
, const TargetRegisterInfo
*TRI
) const {
348 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
350 MachineFunction
&MF
= *MBB
.getParent();
351 const TargetInstrInfo
&TII
= *MF
.getSubtarget().getInstrInfo();
353 for (const CalleeSavedInfo
&I
: llvm::reverse(CSI
))
354 BuildMI(MBB
, MI
, DL
, TII
.get(MSP430::POP16r
), I
.getReg())
355 .setMIFlag(MachineInstr::FrameDestroy
);
360 MachineBasicBlock::iterator
MSP430FrameLowering::eliminateCallFramePseudoInstr(
361 MachineFunction
&MF
, MachineBasicBlock
&MBB
,
362 MachineBasicBlock::iterator I
) const {
363 const MSP430InstrInfo
&TII
=
364 *static_cast<const MSP430InstrInfo
*>(MF
.getSubtarget().getInstrInfo());
365 if (!hasReservedCallFrame(MF
)) {
366 // If the stack pointer can be changed after prologue, turn the
367 // adjcallstackup instruction into a 'sub SP, <amt>' and the
368 // adjcallstackdown instruction into 'add SP, <amt>'
369 // TODO: consider using push / pop instead of sub + store / add
370 MachineInstr
&Old
= *I
;
371 uint64_t Amount
= TII
.getFrameSize(Old
);
373 // We need to keep the stack aligned properly. To do this, we round the
374 // amount of space needed for the outgoing arguments up to the next
375 // alignment boundary.
376 Amount
= alignTo(Amount
, getStackAlign());
378 MachineInstr
*New
= nullptr;
379 if (Old
.getOpcode() == TII
.getCallFrameSetupOpcode()) {
381 BuildMI(MF
, Old
.getDebugLoc(), TII
.get(MSP430::SUB16ri
), MSP430::SP
)
385 assert(Old
.getOpcode() == TII
.getCallFrameDestroyOpcode());
386 // factor out the amount the callee already popped.
387 Amount
-= TII
.getFramePoppedByCallee(Old
);
389 New
= BuildMI(MF
, Old
.getDebugLoc(), TII
.get(MSP430::ADD16ri
),
396 // The SRW implicit def is dead.
397 New
->getOperand(3).setIsDead();
399 // Replace the pseudo instruction with a new instruction...
403 } else if (I
->getOpcode() == TII
.getCallFrameDestroyOpcode()) {
404 // If we are performing frame pointer elimination and if the callee pops
405 // something off the stack pointer, add it back.
406 if (uint64_t CalleeAmt
= TII
.getFramePoppedByCallee(*I
)) {
407 MachineInstr
&Old
= *I
;
409 BuildMI(MF
, Old
.getDebugLoc(), TII
.get(MSP430::SUB16ri
), MSP430::SP
)
413 DebugLoc DL
= I
->getDebugLoc();
415 MCCFIInstruction::createAdjustCfaOffset(nullptr, CalleeAmt
));
417 // The SRW implicit def is dead.
418 New
->getOperand(3).setIsDead();
428 MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction
&MF
,
429 RegScavenger
*) const {
430 // Create a frame entry for the FP register that must be saved.
432 int FrameIdx
= MF
.getFrameInfo().CreateFixedObject(2, -4, true);
434 assert(FrameIdx
== MF
.getFrameInfo().getObjectIndexBegin() &&
435 "Slot for FP register must be last in order to be found!");