1 //======- Thumb1FrameLowering.cpp - Thumb1 Frame Information ---*- C++ -*-====//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Thumb1 implementation of TargetFrameLowering class.
12 //===----------------------------------------------------------------------===//
14 #include "Thumb1FrameLowering.h"
15 #include "ARMBaseInstrInfo.h"
16 #include "ARMMachineFunctionInfo.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 bool Thumb1FrameLowering::hasReservedCallFrame(const MachineFunction
&MF
) const {
25 const MachineFrameInfo
*FFI
= MF
.getFrameInfo();
26 unsigned CFSize
= FFI
->getMaxCallFrameSize();
27 // It's not always a good idea to include the call frame as part of the
28 // stack frame. ARM (especially Thumb) has small immediate offset to
29 // address the stack frame. So a large call frame can cause poor codegen
30 // and may even makes it impossible to scavenge a register.
31 if (CFSize
>= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
34 return !MF
.getFrameInfo()->hasVarSizedObjects();
38 emitSPUpdate(MachineBasicBlock
&MBB
,
39 MachineBasicBlock::iterator
&MBBI
,
40 const TargetInstrInfo
&TII
, DebugLoc dl
,
41 const Thumb1RegisterInfo
&MRI
,
42 int NumBytes
, unsigned MIFlags
= MachineInstr::NoFlags
) {
43 emitThumbRegPlusImmediate(MBB
, MBBI
, dl
, ARM::SP
, ARM::SP
, NumBytes
, TII
,
47 void Thumb1FrameLowering::emitPrologue(MachineFunction
&MF
) const {
48 MachineBasicBlock
&MBB
= MF
.front();
49 MachineBasicBlock::iterator MBBI
= MBB
.begin();
50 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
51 ARMFunctionInfo
*AFI
= MF
.getInfo
<ARMFunctionInfo
>();
52 const Thumb1RegisterInfo
*RegInfo
=
53 static_cast<const Thumb1RegisterInfo
*>(MF
.getTarget().getRegisterInfo());
54 const Thumb1InstrInfo
&TII
=
55 *static_cast<const Thumb1InstrInfo
*>(MF
.getTarget().getInstrInfo());
57 unsigned VARegSaveSize
= AFI
->getVarArgsRegSaveSize();
58 unsigned NumBytes
= MFI
->getStackSize();
59 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
->getCalleeSavedInfo();
60 DebugLoc dl
= MBBI
!= MBB
.end() ? MBBI
->getDebugLoc() : DebugLoc();
61 unsigned FramePtr
= RegInfo
->getFrameRegister(MF
);
62 unsigned BasePtr
= RegInfo
->getBaseRegister();
64 // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
65 NumBytes
= (NumBytes
+ 3) & ~3;
66 MFI
->setStackSize(NumBytes
);
68 // Determine the sizes of each callee-save spill areas and record which frame
69 // belongs to which callee-save spill areas.
70 unsigned GPRCS1Size
= 0, GPRCS2Size
= 0, DPRCSSize
= 0;
71 int FramePtrSpillFI
= 0;
74 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, -VARegSaveSize
,
75 MachineInstr::FrameSetup
);
77 if (!AFI
->hasStackFrame()) {
79 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, -NumBytes
,
80 MachineInstr::FrameSetup
);
84 for (unsigned i
= 0, e
= CSI
.size(); i
!= e
; ++i
) {
85 unsigned Reg
= CSI
[i
].getReg();
86 int FI
= CSI
[i
].getFrameIdx();
95 AFI
->addGPRCalleeSavedArea1Frame(FI
);
103 FramePtrSpillFI
= FI
;
104 if (STI
.isTargetDarwin()) {
105 AFI
->addGPRCalleeSavedArea2Frame(FI
);
108 AFI
->addGPRCalleeSavedArea1Frame(FI
);
113 AFI
->addDPRCalleeSavedAreaFrame(FI
);
118 if (MBBI
!= MBB
.end() && MBBI
->getOpcode() == ARM::tPUSH
) {
120 if (MBBI
!= MBB
.end())
121 dl
= MBBI
->getDebugLoc();
124 // Determine starting offsets of spill areas.
125 unsigned DPRCSOffset
= NumBytes
- (GPRCS1Size
+ GPRCS2Size
+ DPRCSSize
);
126 unsigned GPRCS2Offset
= DPRCSOffset
+ DPRCSSize
;
127 unsigned GPRCS1Offset
= GPRCS2Offset
+ GPRCS2Size
;
128 AFI
->setFramePtrSpillOffset(MFI
->getObjectOffset(FramePtrSpillFI
) + NumBytes
);
129 AFI
->setGPRCalleeSavedArea1Offset(GPRCS1Offset
);
130 AFI
->setGPRCalleeSavedArea2Offset(GPRCS2Offset
);
131 AFI
->setDPRCalleeSavedAreaOffset(DPRCSOffset
);
132 NumBytes
= DPRCSOffset
;
134 // Adjust FP so it point to the stack slot that contains the previous FP.
136 BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tADDrSPi
), FramePtr
)
137 .addFrameIndex(FramePtrSpillFI
).addImm(0)
138 .setMIFlags(MachineInstr::FrameSetup
);
140 // If offset is > 508 then sp cannot be adjusted in a single instruction,
141 // try restoring from fp instead.
142 AFI
->setShouldRestoreSPFromFP(true);
146 // Insert it after all the callee-save spills.
147 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, -NumBytes
,
148 MachineInstr::FrameSetup
);
150 if (STI
.isTargetELF() && hasFP(MF
))
151 MFI
->setOffsetAdjustment(MFI
->getOffsetAdjustment() -
152 AFI
->getFramePtrSpillOffset());
154 AFI
->setGPRCalleeSavedArea1Size(GPRCS1Size
);
155 AFI
->setGPRCalleeSavedArea2Size(GPRCS2Size
);
156 AFI
->setDPRCalleeSavedAreaSize(DPRCSSize
);
158 // If we need a base pointer, set it up here. It's whatever the value
159 // of the stack pointer is at this point. Any variable size objects
160 // will be allocated after this, so we can still use the base pointer
161 // to reference locals.
162 if (RegInfo
->hasBasePointer(MF
))
163 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVr
), BasePtr
)
166 // If the frame has variable sized objects then the epilogue must restore
167 // the sp from fp. We can assume there's an FP here since hasFP already
168 // checks for hasVarSizedObjects.
169 if (MFI
->hasVarSizedObjects())
170 AFI
->setShouldRestoreSPFromFP(true);
173 static bool isCalleeSavedRegister(unsigned Reg
, const unsigned *CSRegs
) {
174 for (unsigned i
= 0; CSRegs
[i
]; ++i
)
175 if (Reg
== CSRegs
[i
])
180 static bool isCSRestore(MachineInstr
*MI
, const unsigned *CSRegs
) {
181 if (MI
->getOpcode() == ARM::tLDRspi
&&
182 MI
->getOperand(1).isFI() &&
183 isCalleeSavedRegister(MI
->getOperand(0).getReg(), CSRegs
))
185 else if (MI
->getOpcode() == ARM::tPOP
) {
186 // The first two operands are predicates. The last two are
187 // imp-def and imp-use of SP. Check everything in between.
188 for (int i
= 2, e
= MI
->getNumOperands() - 2; i
!= e
; ++i
)
189 if (!isCalleeSavedRegister(MI
->getOperand(i
).getReg(), CSRegs
))
196 void Thumb1FrameLowering::emitEpilogue(MachineFunction
&MF
,
197 MachineBasicBlock
&MBB
) const {
198 MachineBasicBlock::iterator MBBI
= MBB
.getLastNonDebugInstr();
199 assert((MBBI
->getOpcode() == ARM::tBX_RET
||
200 MBBI
->getOpcode() == ARM::tPOP_RET
) &&
201 "Can only insert epilog into returning blocks");
202 DebugLoc dl
= MBBI
->getDebugLoc();
203 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
204 ARMFunctionInfo
*AFI
= MF
.getInfo
<ARMFunctionInfo
>();
205 const Thumb1RegisterInfo
*RegInfo
=
206 static_cast<const Thumb1RegisterInfo
*>(MF
.getTarget().getRegisterInfo());
207 const Thumb1InstrInfo
&TII
=
208 *static_cast<const Thumb1InstrInfo
*>(MF
.getTarget().getInstrInfo());
210 unsigned VARegSaveSize
= AFI
->getVarArgsRegSaveSize();
211 int NumBytes
= (int)MFI
->getStackSize();
212 const unsigned *CSRegs
= RegInfo
->getCalleeSavedRegs();
213 unsigned FramePtr
= RegInfo
->getFrameRegister(MF
);
215 if (!AFI
->hasStackFrame()) {
217 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, NumBytes
);
219 // Unwind MBBI to point to first LDR / VLDRD.
220 if (MBBI
!= MBB
.begin()) {
223 while (MBBI
!= MBB
.begin() && isCSRestore(MBBI
, CSRegs
));
224 if (!isCSRestore(MBBI
, CSRegs
))
228 // Move SP to start of FP callee save spill area.
229 NumBytes
-= (AFI
->getGPRCalleeSavedArea1Size() +
230 AFI
->getGPRCalleeSavedArea2Size() +
231 AFI
->getDPRCalleeSavedAreaSize());
233 if (AFI
->shouldRestoreSPFromFP()) {
234 NumBytes
= AFI
->getFramePtrSpillOffset() - NumBytes
;
235 // Reset SP based on frame pointer only if the stack frame extends beyond
236 // frame pointer stack slot, the target is ELF and the function has FP, or
237 // the target uses var sized objects.
239 assert(MF
.getRegInfo().isPhysRegUsed(ARM::R4
) &&
240 "No scratch register to restore SP from FP!");
241 emitThumbRegPlusImmediate(MBB
, MBBI
, dl
, ARM::R4
, FramePtr
, -NumBytes
,
243 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVr
),
247 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVr
),
251 if (MBBI
->getOpcode() == ARM::tBX_RET
&&
252 &MBB
.front() != MBBI
&&
253 prior(MBBI
)->getOpcode() == ARM::tPOP
) {
254 MachineBasicBlock::iterator PMBBI
= prior(MBBI
);
255 emitSPUpdate(MBB
, PMBBI
, TII
, dl
, *RegInfo
, NumBytes
);
257 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, NumBytes
);
262 // Unlike T2 and ARM mode, the T1 pop instruction cannot restore
263 // to LR, and we can't pop the value directly to the PC since
264 // we need to update the SP after popping the value. Therefore, we
265 // pop the old LR into R3 as a temporary.
267 // Move back past the callee-saved register restoration
268 while (MBBI
!= MBB
.end() && isCSRestore(MBBI
, CSRegs
))
270 // Epilogue for vararg functions: pop LR to R3 and branch off it.
271 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tPOP
)))
272 .addReg(ARM::R3
, RegState::Define
);
274 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, VARegSaveSize
);
276 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tBX_RET_vararg
))
277 .addReg(ARM::R3
, RegState::Kill
));
278 // erase the old tBX_RET instruction
283 bool Thumb1FrameLowering::
284 spillCalleeSavedRegisters(MachineBasicBlock
&MBB
,
285 MachineBasicBlock::iterator MI
,
286 const std::vector
<CalleeSavedInfo
> &CSI
,
287 const TargetRegisterInfo
*TRI
) const {
292 MachineFunction
&MF
= *MBB
.getParent();
293 const TargetInstrInfo
&TII
= *MF
.getTarget().getInstrInfo();
295 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
297 MachineInstrBuilder MIB
= BuildMI(MBB
, MI
, DL
, TII
.get(ARM::tPUSH
));
299 for (unsigned i
= CSI
.size(); i
!= 0; --i
) {
300 unsigned Reg
= CSI
[i
-1].getReg();
303 // Add the callee-saved register as live-in unless it's LR and
304 // @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress
305 // then it's already added to the function and entry block live-in sets.
306 if (Reg
== ARM::LR
) {
307 MachineFunction
&MF
= *MBB
.getParent();
308 if (MF
.getFrameInfo()->isReturnAddressTaken() &&
309 MF
.getRegInfo().isLiveIn(Reg
))
316 MIB
.addReg(Reg
, getKillRegState(isKill
));
318 MIB
.setMIFlags(MachineInstr::FrameSetup
);
322 bool Thumb1FrameLowering::
323 restoreCalleeSavedRegisters(MachineBasicBlock
&MBB
,
324 MachineBasicBlock::iterator MI
,
325 const std::vector
<CalleeSavedInfo
> &CSI
,
326 const TargetRegisterInfo
*TRI
) const {
330 MachineFunction
&MF
= *MBB
.getParent();
331 ARMFunctionInfo
*AFI
= MF
.getInfo
<ARMFunctionInfo
>();
332 const TargetInstrInfo
&TII
= *MF
.getTarget().getInstrInfo();
334 bool isVarArg
= AFI
->getVarArgsRegSaveSize() > 0;
335 DebugLoc DL
= MI
->getDebugLoc();
336 MachineInstrBuilder MIB
= BuildMI(MF
, DL
, TII
.get(ARM::tPOP
));
339 bool NumRegs
= false;
340 for (unsigned i
= CSI
.size(); i
!= 0; --i
) {
341 unsigned Reg
= CSI
[i
-1].getReg();
342 if (Reg
== ARM::LR
) {
343 // Special epilogue for vararg functions. See emitEpilogue
347 (*MIB
).setDesc(TII
.get(ARM::tPOP_RET
));
350 MIB
.addReg(Reg
, getDefRegState(true));
354 // It's illegal to emit pop instruction without operands.
356 MBB
.insert(MI
, &*MIB
);
358 MF
.DeleteMachineInstr(MIB
);