1 //===- XtensaFrameLowering.cpp - Xtensa 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 Xtensa implementation of TargetFrameLowering class.
11 //===----------------------------------------------------------------------===//
13 #include "XtensaFrameLowering.h"
14 #include "XtensaInstrInfo.h"
15 #include "XtensaMachineFunctionInfo.h"
16 #include "XtensaSubtarget.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineModuleInfo.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/CodeGen/RegisterScavenging.h"
22 #include "llvm/IR/Function.h"
26 XtensaFrameLowering::XtensaFrameLowering(const XtensaSubtarget
&STI
)
27 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown
, Align(4), 0,
29 TII(*STI
.getInstrInfo()), TRI(STI
.getRegisterInfo()) {}
31 bool XtensaFrameLowering::hasFPImpl(const MachineFunction
&MF
) const {
32 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
33 return MF
.getTarget().Options
.DisableFramePointerElim(MF
) ||
34 MFI
.hasVarSizedObjects();
37 void XtensaFrameLowering::emitPrologue(MachineFunction
&MF
,
38 MachineBasicBlock
&MBB
) const {
39 assert(&MBB
== &MF
.front() && "Shrink-wrapping not yet implemented");
40 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
41 MachineBasicBlock::iterator MBBI
= MBB
.begin();
42 DebugLoc DL
= MBBI
!= MBB
.end() ? MBBI
->getDebugLoc() : DebugLoc();
43 MCRegister SP
= Xtensa::SP
;
44 MCRegister FP
= TRI
->getFrameRegister(MF
);
45 const MCRegisterInfo
*MRI
= MF
.getContext().getRegisterInfo();
47 // First, compute final stack size.
48 uint64_t StackSize
= MFI
.getStackSize();
49 uint64_t PrevStackSize
= StackSize
;
51 // Round up StackSize to 16*N
52 StackSize
+= (16 - StackSize
) & 0xf;
54 // No need to allocate space on the stack.
55 if (StackSize
== 0 && !MFI
.adjustsStack())
59 TII
.adjustStackPtr(SP
, -StackSize
, MBB
, MBBI
);
61 // emit ".cfi_def_cfa_offset StackSize"
63 MF
.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize
));
64 BuildMI(MBB
, MBBI
, DL
, TII
.get(TargetOpcode::CFI_INSTRUCTION
))
65 .addCFIIndex(CFIIndex
);
67 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
.getCalleeSavedInfo();
70 // Find the instruction past the last instruction that saves a
71 // callee-saved register to the stack. The callee-saved store
72 // instructions are placed at the begin of basic block, so
73 // iterate over instruction sequence and check that
74 // save instructions are placed correctly.
75 for (unsigned i
= 0, e
= CSI
.size(); i
< e
; ++i
) {
77 const CalleeSavedInfo
&Info
= CSI
[i
];
78 int FI
= Info
.getFrameIdx();
81 // Checking that the instruction is exactly as expected
82 bool IsStoreInst
= false;
83 if (MBBI
->getOpcode() == TargetOpcode::COPY
&& Info
.isSpilledToReg()) {
84 Register DstReg
= MBBI
->getOperand(0).getReg();
85 Register Reg
= MBBI
->getOperand(1).getReg();
86 IsStoreInst
= (Info
.getDstReg() == DstReg
) && (Info
.getReg() == Reg
);
88 Register Reg
= TII
.isStoreToStackSlot(*MBBI
, StoreFI
);
89 IsStoreInst
= (Reg
== Info
.getReg()) && (StoreFI
== FI
);
92 "Unexpected callee-saved register store instruction");
97 // Iterate over list of callee-saved registers and emit .cfi_offset
99 for (const auto &I
: CSI
) {
100 int64_t Offset
= MFI
.getObjectOffset(I
.getFrameIdx());
101 Register Reg
= I
.getReg();
103 unsigned CFIIndex
= MF
.addFrameInst(MCCFIInstruction::createOffset(
104 nullptr, MRI
->getDwarfRegNum(Reg
, 1), Offset
));
105 BuildMI(MBB
, MBBI
, DL
, TII
.get(TargetOpcode::CFI_INSTRUCTION
))
106 .addCFIIndex(CFIIndex
);
110 // if framepointer enabled, set it to point to the stack pointer.
112 // Insert instruction "move $fp, $sp" at this location.
113 BuildMI(MBB
, MBBI
, DL
, TII
.get(Xtensa::OR
), FP
)
116 .setMIFlag(MachineInstr::FrameSetup
);
118 // emit ".cfi_def_cfa_register $fp"
119 unsigned CFIIndex
= MF
.addFrameInst(MCCFIInstruction::createDefCfaRegister(
120 nullptr, MRI
->getDwarfRegNum(FP
, true)));
121 BuildMI(MBB
, MBBI
, DL
, TII
.get(TargetOpcode::CFI_INSTRUCTION
))
122 .addCFIIndex(CFIIndex
);
125 if (StackSize
!= PrevStackSize
) {
126 MFI
.setStackSize(StackSize
);
128 for (int i
= MFI
.getObjectIndexBegin(); i
< MFI
.getObjectIndexEnd(); i
++) {
129 if (!MFI
.isDeadObjectIndex(i
)) {
130 int64_t SPOffset
= MFI
.getObjectOffset(i
);
133 MFI
.setObjectOffset(i
, SPOffset
- StackSize
+ PrevStackSize
);
139 void XtensaFrameLowering::emitEpilogue(MachineFunction
&MF
,
140 MachineBasicBlock
&MBB
) const {
141 MachineBasicBlock::iterator MBBI
= MBB
.getLastNonDebugInstr();
142 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
143 DebugLoc DL
= MBBI
->getDebugLoc();
144 MCRegister SP
= Xtensa::SP
;
145 MCRegister FP
= TRI
->getFrameRegister(MF
);
147 // if framepointer enabled, restore the stack pointer.
149 // We should place restore stack pointer instruction just before
150 // sequence of instructions which restores callee-saved registers.
151 // This sequence is placed at the end of the basic block,
152 // so we should find first instruction of the sequence.
153 MachineBasicBlock::iterator I
= MBBI
;
155 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
.getCalleeSavedInfo();
157 // Find the first instruction at the end that restores a callee-saved
159 for (unsigned i
= 0, e
= CSI
.size(); i
< e
; ++i
) {
162 const CalleeSavedInfo
&Info
= CSI
[i
];
163 int FI
= Info
.getFrameIdx();
166 // Checking that the instruction is exactly as expected
167 bool IsRestoreInst
= false;
168 if (I
->getOpcode() == TargetOpcode::COPY
&& Info
.isSpilledToReg()) {
169 Register Reg
= I
->getOperand(0).getReg();
170 Register DstReg
= I
->getOperand(1).getReg();
171 IsRestoreInst
= (Info
.getDstReg() == DstReg
) && (Info
.getReg() == Reg
);
173 Register Reg
= TII
.isLoadFromStackSlot(*I
, LoadFI
);
174 IsRestoreInst
= (Info
.getReg() == Reg
) && (LoadFI
== FI
);
176 assert(IsRestoreInst
&&
177 "Unexpected callee-saved register restore instruction");
181 BuildMI(MBB
, I
, DL
, TII
.get(Xtensa::OR
), SP
).addReg(FP
).addReg(FP
);
184 // Get the number of bytes from FrameInfo
185 uint64_t StackSize
= MFI
.getStackSize();
191 TII
.adjustStackPtr(SP
, StackSize
, MBB
, MBBI
);
194 bool XtensaFrameLowering::spillCalleeSavedRegisters(
195 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MI
,
196 ArrayRef
<CalleeSavedInfo
> CSI
, const TargetRegisterInfo
*TRI
) const {
197 MachineFunction
*MF
= MBB
.getParent();
198 MachineBasicBlock
&EntryBlock
= *(MF
->begin());
200 for (unsigned i
= 0, e
= CSI
.size(); i
!= e
; ++i
) {
201 // Add the callee-saved register as live-in. Do not add if the register is
202 // A0 and return address is taken, because it will be implemented in
203 // method XtensaTargetLowering::LowerRETURNADDR.
204 // It's killed at the spill, unless the register is RA and return address
206 Register Reg
= CSI
[i
].getReg();
207 bool IsA0AndRetAddrIsTaken
=
208 (Reg
== Xtensa::A0
) && MF
->getFrameInfo().isReturnAddressTaken();
209 if (!IsA0AndRetAddrIsTaken
)
210 EntryBlock
.addLiveIn(Reg
);
212 // Insert the spill to the stack frame.
213 bool IsKill
= !IsA0AndRetAddrIsTaken
;
214 const TargetRegisterClass
*RC
= TRI
->getMinimalPhysRegClass(Reg
);
215 TII
.storeRegToStackSlot(EntryBlock
, MI
, Reg
, IsKill
, CSI
[i
].getFrameIdx(),
216 RC
, TRI
, Register());
222 bool XtensaFrameLowering::restoreCalleeSavedRegisters(
223 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MI
,
224 MutableArrayRef
<CalleeSavedInfo
> CSI
, const TargetRegisterInfo
*TRI
) const {
225 return TargetFrameLowering::restoreCalleeSavedRegisters(MBB
, MI
, CSI
, TRI
);
228 // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
229 MachineBasicBlock::iterator
XtensaFrameLowering::eliminateCallFramePseudoInstr(
230 MachineFunction
&MF
, MachineBasicBlock
&MBB
,
231 MachineBasicBlock::iterator I
) const {
232 const XtensaInstrInfo
&TII
=
233 *static_cast<const XtensaInstrInfo
*>(MF
.getSubtarget().getInstrInfo());
235 if (!hasReservedCallFrame(MF
)) {
236 int64_t Amount
= I
->getOperand(0).getImm();
238 if (I
->getOpcode() == Xtensa::ADJCALLSTACKDOWN
)
241 TII
.adjustStackPtr(Xtensa::SP
, Amount
, MBB
, I
);
247 void XtensaFrameLowering::determineCalleeSaves(MachineFunction
&MF
,
248 BitVector
&SavedRegs
,
249 RegScavenger
*RS
) const {
250 unsigned FP
= TRI
->getFrameRegister(MF
);
252 TargetFrameLowering::determineCalleeSaves(MF
, SavedRegs
, RS
);
254 // Mark $fp as used if function has dedicated frame pointer.
259 void XtensaFrameLowering::processFunctionBeforeFrameFinalized(
260 MachineFunction
&MF
, RegScavenger
*RS
) const {
261 // Set scavenging frame index if necessary.
262 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
263 uint64_t MaxSPOffset
= MFI
.estimateStackSize(MF
);
264 auto *XtensaFI
= MF
.getInfo
<XtensaMachineFunctionInfo
>();
265 unsigned ScavSlotsNum
= 0;
267 if (!isInt
<12>(MaxSPOffset
))
270 // Far branches over 18-bit offset require a spill slot for scratch register.
271 bool IsLargeFunction
= !isInt
<18>(MF
.estimateFunctionSizeInBytes());
273 ScavSlotsNum
= std::max(ScavSlotsNum
, 1u);
275 const TargetRegisterClass
&RC
= Xtensa::ARRegClass
;
276 unsigned Size
= TRI
->getSpillSize(RC
);
277 Align Alignment
= TRI
->getSpillAlign(RC
);
278 for (unsigned I
= 0; I
< ScavSlotsNum
; I
++) {
279 int FI
= MFI
.CreateStackObject(Size
, Alignment
, false);
280 RS
->addScavengingFrameIndex(FI
);
282 if (IsLargeFunction
&&
283 XtensaFI
->getBranchRelaxationScratchFrameIndex() == -1)
284 XtensaFI
->setBranchRelaxationScratchFrameIndex(FI
);