]>
git.proxmox.com Git - rustc.git/blob - src/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
1 //===-- Thumb1FrameLowering.cpp - Thumb1 Frame Information ----------------===//
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 "ARMMachineFunctionInfo.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineModuleInfo.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 Thumb1FrameLowering::Thumb1FrameLowering(const ARMSubtarget
&sti
)
25 : ARMFrameLowering(sti
) {}
27 bool Thumb1FrameLowering::hasReservedCallFrame(const MachineFunction
&MF
) const{
28 const MachineFrameInfo
*FFI
= MF
.getFrameInfo();
29 unsigned CFSize
= FFI
->getMaxCallFrameSize();
30 // It's not always a good idea to include the call frame as part of the
31 // stack frame. ARM (especially Thumb) has small immediate offset to
32 // address the stack frame. So a large call frame can cause poor codegen
33 // and may even makes it impossible to scavenge a register.
34 if (CFSize
>= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
37 return !MF
.getFrameInfo()->hasVarSizedObjects();
41 emitSPUpdate(MachineBasicBlock
&MBB
,
42 MachineBasicBlock::iterator
&MBBI
,
43 const TargetInstrInfo
&TII
, DebugLoc dl
,
44 const Thumb1RegisterInfo
&MRI
,
45 int NumBytes
, unsigned MIFlags
= MachineInstr::NoFlags
) {
46 emitThumbRegPlusImmediate(MBB
, MBBI
, dl
, ARM::SP
, ARM::SP
, NumBytes
, TII
,
51 void Thumb1FrameLowering::
52 eliminateCallFramePseudoInstr(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
53 MachineBasicBlock::iterator I
) const {
54 const Thumb1InstrInfo
&TII
=
55 *static_cast<const Thumb1InstrInfo
*>(MF
.getSubtarget().getInstrInfo());
56 const Thumb1RegisterInfo
*RegInfo
= static_cast<const Thumb1RegisterInfo
*>(
57 MF
.getSubtarget().getRegisterInfo());
58 if (!hasReservedCallFrame(MF
)) {
59 // If we have alloca, convert as follows:
60 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
61 // ADJCALLSTACKUP -> add, sp, sp, amount
62 MachineInstr
*Old
= I
;
63 DebugLoc dl
= Old
->getDebugLoc();
64 unsigned Amount
= Old
->getOperand(0).getImm();
66 // We need to keep the stack aligned properly. To do this, we round the
67 // amount of space needed for the outgoing arguments up to the next
68 // alignment boundary.
69 unsigned Align
= getStackAlignment();
70 Amount
= (Amount
+Align
-1)/Align
*Align
;
72 // Replace the pseudo instruction with a new instruction...
73 unsigned Opc
= Old
->getOpcode();
74 if (Opc
== ARM::ADJCALLSTACKDOWN
|| Opc
== ARM::tADJCALLSTACKDOWN
) {
75 emitSPUpdate(MBB
, I
, TII
, dl
, *RegInfo
, -Amount
);
77 assert(Opc
== ARM::ADJCALLSTACKUP
|| Opc
== ARM::tADJCALLSTACKUP
);
78 emitSPUpdate(MBB
, I
, TII
, dl
, *RegInfo
, Amount
);
85 void Thumb1FrameLowering::emitPrologue(MachineFunction
&MF
) const {
86 MachineBasicBlock
&MBB
= MF
.front();
87 MachineBasicBlock::iterator MBBI
= MBB
.begin();
88 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
89 ARMFunctionInfo
*AFI
= MF
.getInfo
<ARMFunctionInfo
>();
90 MachineModuleInfo
&MMI
= MF
.getMMI();
91 const MCRegisterInfo
*MRI
= MMI
.getContext().getRegisterInfo();
92 const Thumb1RegisterInfo
*RegInfo
= static_cast<const Thumb1RegisterInfo
*>(
93 MF
.getSubtarget().getRegisterInfo());
94 const Thumb1InstrInfo
&TII
=
95 *static_cast<const Thumb1InstrInfo
*>(MF
.getSubtarget().getInstrInfo());
97 unsigned Align
= MF
.getTarget()
100 ->getStackAlignment();
101 unsigned ArgRegsSaveSize
= AFI
->getArgRegsSaveSize(Align
);
102 unsigned NumBytes
= MFI
->getStackSize();
103 assert(NumBytes
>= ArgRegsSaveSize
&&
104 "ArgRegsSaveSize is included in NumBytes");
105 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
->getCalleeSavedInfo();
106 DebugLoc dl
= MBBI
!= MBB
.end() ? MBBI
->getDebugLoc() : DebugLoc();
107 unsigned FramePtr
= RegInfo
->getFrameRegister(MF
);
108 unsigned BasePtr
= RegInfo
->getBaseRegister();
111 // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
112 NumBytes
= (NumBytes
+ 3) & ~3;
113 MFI
->setStackSize(NumBytes
);
115 // Determine the sizes of each callee-save spill areas and record which frame
116 // belongs to which callee-save spill areas.
117 unsigned GPRCS1Size
= 0, GPRCS2Size
= 0, DPRCSSize
= 0;
118 int FramePtrSpillFI
= 0;
120 if (ArgRegsSaveSize
) {
121 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, -ArgRegsSaveSize
,
122 MachineInstr::FrameSetup
);
123 CFAOffset
-= ArgRegsSaveSize
;
124 unsigned CFIIndex
= MMI
.addFrameInst(
125 MCCFIInstruction::createDefCfaOffset(nullptr, CFAOffset
));
126 BuildMI(MBB
, MBBI
, dl
, TII
.get(TargetOpcode::CFI_INSTRUCTION
))
127 .addCFIIndex(CFIIndex
)
128 .setMIFlags(MachineInstr::FrameSetup
);
131 if (!AFI
->hasStackFrame()) {
132 if (NumBytes
- ArgRegsSaveSize
!= 0) {
133 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, -(NumBytes
- ArgRegsSaveSize
),
134 MachineInstr::FrameSetup
);
135 CFAOffset
-= NumBytes
- ArgRegsSaveSize
;
136 unsigned CFIIndex
= MMI
.addFrameInst(
137 MCCFIInstruction::createDefCfaOffset(nullptr, CFAOffset
));
138 BuildMI(MBB
, MBBI
, dl
, TII
.get(TargetOpcode::CFI_INSTRUCTION
))
139 .addCFIIndex(CFIIndex
)
140 .setMIFlags(MachineInstr::FrameSetup
);
145 for (unsigned i
= 0, e
= CSI
.size(); i
!= e
; ++i
) {
146 unsigned Reg
= CSI
[i
].getReg();
147 int FI
= CSI
[i
].getFrameIdx();
153 if (STI
.isTargetMachO()) {
164 FramePtrSpillFI
= FI
;
172 if (MBBI
!= MBB
.end() && MBBI
->getOpcode() == ARM::tPUSH
) {
174 if (MBBI
!= MBB
.end())
175 dl
= MBBI
->getDebugLoc();
178 // Determine starting offsets of spill areas.
179 unsigned DPRCSOffset
= NumBytes
- ArgRegsSaveSize
- (GPRCS1Size
+ GPRCS2Size
+ DPRCSSize
);
180 unsigned GPRCS2Offset
= DPRCSOffset
+ DPRCSSize
;
181 unsigned GPRCS1Offset
= GPRCS2Offset
+ GPRCS2Size
;
182 bool HasFP
= hasFP(MF
);
184 AFI
->setFramePtrSpillOffset(MFI
->getObjectOffset(FramePtrSpillFI
) +
186 AFI
->setGPRCalleeSavedArea1Offset(GPRCS1Offset
);
187 AFI
->setGPRCalleeSavedArea2Offset(GPRCS2Offset
);
188 AFI
->setDPRCalleeSavedAreaOffset(DPRCSOffset
);
189 NumBytes
= DPRCSOffset
;
191 int FramePtrOffsetInBlock
= 0;
192 unsigned adjustedGPRCS1Size
= GPRCS1Size
;
193 if (tryFoldSPUpdateIntoPushPop(STI
, MF
, std::prev(MBBI
), NumBytes
)) {
194 FramePtrOffsetInBlock
= NumBytes
;
195 adjustedGPRCS1Size
+= NumBytes
;
199 if (adjustedGPRCS1Size
) {
200 CFAOffset
-= adjustedGPRCS1Size
;
201 unsigned CFIIndex
= MMI
.addFrameInst(
202 MCCFIInstruction::createDefCfaOffset(nullptr, CFAOffset
));
203 BuildMI(MBB
, MBBI
, dl
, TII
.get(TargetOpcode::CFI_INSTRUCTION
))
204 .addCFIIndex(CFIIndex
)
205 .setMIFlags(MachineInstr::FrameSetup
);
207 for (std::vector
<CalleeSavedInfo
>::const_iterator I
= CSI
.begin(),
208 E
= CSI
.end(); I
!= E
; ++I
) {
209 unsigned Reg
= I
->getReg();
210 int FI
= I
->getFrameIdx();
217 if (STI
.isTargetMachO())
229 unsigned CFIIndex
= MMI
.addFrameInst(MCCFIInstruction::createOffset(
230 nullptr, MRI
->getDwarfRegNum(Reg
, true), MFI
->getObjectOffset(FI
)));
231 BuildMI(MBB
, MBBI
, dl
, TII
.get(TargetOpcode::CFI_INSTRUCTION
))
232 .addCFIIndex(CFIIndex
)
233 .setMIFlags(MachineInstr::FrameSetup
);
239 // Adjust FP so it point to the stack slot that contains the previous FP.
241 FramePtrOffsetInBlock
+= MFI
->getObjectOffset(FramePtrSpillFI
)
242 + GPRCS1Size
+ ArgRegsSaveSize
;
243 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tADDrSPi
), FramePtr
)
244 .addReg(ARM::SP
).addImm(FramePtrOffsetInBlock
/ 4)
245 .setMIFlags(MachineInstr::FrameSetup
));
246 if(FramePtrOffsetInBlock
) {
247 CFAOffset
+= FramePtrOffsetInBlock
;
248 unsigned CFIIndex
= MMI
.addFrameInst(MCCFIInstruction::createDefCfa(
249 nullptr, MRI
->getDwarfRegNum(FramePtr
, true), CFAOffset
));
250 BuildMI(MBB
, MBBI
, dl
, TII
.get(TargetOpcode::CFI_INSTRUCTION
))
251 .addCFIIndex(CFIIndex
)
252 .setMIFlags(MachineInstr::FrameSetup
);
255 MMI
.addFrameInst(MCCFIInstruction::createDefCfaRegister(
256 nullptr, MRI
->getDwarfRegNum(FramePtr
, true)));
257 BuildMI(MBB
, MBBI
, dl
, TII
.get(TargetOpcode::CFI_INSTRUCTION
))
258 .addCFIIndex(CFIIndex
)
259 .setMIFlags(MachineInstr::FrameSetup
);
262 // If offset is > 508 then sp cannot be adjusted in a single instruction,
263 // try restoring from fp instead.
264 AFI
->setShouldRestoreSPFromFP(true);
268 // Insert it after all the callee-save spills.
269 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, -NumBytes
,
270 MachineInstr::FrameSetup
);
272 CFAOffset
-= NumBytes
;
273 unsigned CFIIndex
= MMI
.addFrameInst(
274 MCCFIInstruction::createDefCfaOffset(nullptr, CFAOffset
));
275 BuildMI(MBB
, MBBI
, dl
, TII
.get(TargetOpcode::CFI_INSTRUCTION
))
276 .addCFIIndex(CFIIndex
)
277 .setMIFlags(MachineInstr::FrameSetup
);
281 if (STI
.isTargetELF() && HasFP
)
282 MFI
->setOffsetAdjustment(MFI
->getOffsetAdjustment() -
283 AFI
->getFramePtrSpillOffset());
285 AFI
->setGPRCalleeSavedArea1Size(GPRCS1Size
);
286 AFI
->setGPRCalleeSavedArea2Size(GPRCS2Size
);
287 AFI
->setDPRCalleeSavedAreaSize(DPRCSSize
);
289 // Thumb1 does not currently support dynamic stack realignment. Report a
290 // fatal error rather then silently generate bad code.
291 if (RegInfo
->needsStackRealignment(MF
))
292 report_fatal_error("Dynamic stack realignment not supported for thumb1.");
294 // If we need a base pointer, set it up here. It's whatever the value
295 // of the stack pointer is at this point. Any variable size objects
296 // will be allocated after this, so we can still use the base pointer
297 // to reference locals.
298 if (RegInfo
->hasBasePointer(MF
))
299 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVr
), BasePtr
)
302 // If the frame has variable sized objects then the epilogue must restore
303 // the sp from fp. We can assume there's an FP here since hasFP already
304 // checks for hasVarSizedObjects.
305 if (MFI
->hasVarSizedObjects())
306 AFI
->setShouldRestoreSPFromFP(true);
309 static bool isCSRestore(MachineInstr
*MI
, const MCPhysReg
*CSRegs
) {
310 if (MI
->getOpcode() == ARM::tLDRspi
&&
311 MI
->getOperand(1).isFI() &&
312 isCalleeSavedRegister(MI
->getOperand(0).getReg(), CSRegs
))
314 else if (MI
->getOpcode() == ARM::tPOP
) {
315 // The first two operands are predicates. The last two are
316 // imp-def and imp-use of SP. Check everything in between.
317 for (int i
= 2, e
= MI
->getNumOperands() - 2; i
!= e
; ++i
)
318 if (!isCalleeSavedRegister(MI
->getOperand(i
).getReg(), CSRegs
))
325 void Thumb1FrameLowering::emitEpilogue(MachineFunction
&MF
,
326 MachineBasicBlock
&MBB
) const {
327 MachineBasicBlock::iterator MBBI
= MBB
.getLastNonDebugInstr();
328 assert((MBBI
->getOpcode() == ARM::tBX_RET
||
329 MBBI
->getOpcode() == ARM::tPOP_RET
) &&
330 "Can only insert epilog into returning blocks");
331 DebugLoc dl
= MBBI
->getDebugLoc();
332 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
333 ARMFunctionInfo
*AFI
= MF
.getInfo
<ARMFunctionInfo
>();
334 const Thumb1RegisterInfo
*RegInfo
= static_cast<const Thumb1RegisterInfo
*>(
335 MF
.getSubtarget().getRegisterInfo());
336 const Thumb1InstrInfo
&TII
=
337 *static_cast<const Thumb1InstrInfo
*>(MF
.getSubtarget().getInstrInfo());
339 unsigned Align
= MF
.getTarget()
342 ->getStackAlignment();
343 unsigned ArgRegsSaveSize
= AFI
->getArgRegsSaveSize(Align
);
344 int NumBytes
= (int)MFI
->getStackSize();
345 assert((unsigned)NumBytes
>= ArgRegsSaveSize
&&
346 "ArgRegsSaveSize is included in NumBytes");
347 const MCPhysReg
*CSRegs
= RegInfo
->getCalleeSavedRegs();
348 unsigned FramePtr
= RegInfo
->getFrameRegister(MF
);
350 if (!AFI
->hasStackFrame()) {
351 if (NumBytes
- ArgRegsSaveSize
!= 0)
352 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, NumBytes
- ArgRegsSaveSize
);
354 // Unwind MBBI to point to first LDR / VLDRD.
355 if (MBBI
!= MBB
.begin()) {
358 while (MBBI
!= MBB
.begin() && isCSRestore(MBBI
, CSRegs
));
359 if (!isCSRestore(MBBI
, CSRegs
))
363 // Move SP to start of FP callee save spill area.
364 NumBytes
-= (AFI
->getGPRCalleeSavedArea1Size() +
365 AFI
->getGPRCalleeSavedArea2Size() +
366 AFI
->getDPRCalleeSavedAreaSize() +
369 if (AFI
->shouldRestoreSPFromFP()) {
370 NumBytes
= AFI
->getFramePtrSpillOffset() - NumBytes
;
371 // Reset SP based on frame pointer only if the stack frame extends beyond
372 // frame pointer stack slot, the target is ELF and the function has FP, or
373 // the target uses var sized objects.
375 assert(MF
.getRegInfo().isPhysRegUsed(ARM::R4
) &&
376 "No scratch register to restore SP from FP!");
377 emitThumbRegPlusImmediate(MBB
, MBBI
, dl
, ARM::R4
, FramePtr
, -NumBytes
,
379 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVr
),
383 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVr
),
387 if (MBBI
->getOpcode() == ARM::tBX_RET
&&
388 &MBB
.front() != MBBI
&&
389 std::prev(MBBI
)->getOpcode() == ARM::tPOP
) {
390 MachineBasicBlock::iterator PMBBI
= std::prev(MBBI
);
391 if (!tryFoldSPUpdateIntoPushPop(STI
, MF
, PMBBI
, NumBytes
))
392 emitSPUpdate(MBB
, PMBBI
, TII
, dl
, *RegInfo
, NumBytes
);
393 } else if (!tryFoldSPUpdateIntoPushPop(STI
, MF
, MBBI
, NumBytes
))
394 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, NumBytes
);
398 bool IsV4PopReturn
= false;
399 for (const CalleeSavedInfo
&CSI
: MFI
->getCalleeSavedInfo())
400 if (CSI
.getReg() == ARM::LR
)
401 IsV4PopReturn
= true;
402 IsV4PopReturn
&= STI
.hasV4TOps() && !STI
.hasV5TOps();
404 // Unlike T2 and ARM mode, the T1 pop instruction cannot restore
405 // to LR, and we can't pop the value directly to the PC since
406 // we need to update the SP after popping the value. So instead
411 // If this would clobber a return value, then generate this sequence instead:
418 if (ArgRegsSaveSize
|| IsV4PopReturn
) {
419 // Get the last instruction, tBX_RET
420 MBBI
= MBB
.getLastNonDebugInstr();
421 assert (MBBI
->getOpcode() == ARM::tBX_RET
);
422 DebugLoc dl
= MBBI
->getDebugLoc();
424 if (AFI
->getReturnRegsCount() <= 3) {
425 // Epilogue: pop saved LR to R3 and branch off it.
426 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tPOP
)))
427 .addReg(ARM::R3
, RegState::Define
);
429 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, ArgRegsSaveSize
);
431 MachineInstrBuilder MIB
=
432 BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tBX
))
433 .addReg(ARM::R3
, RegState::Kill
);
435 MIB
.copyImplicitOps(&*MBBI
);
436 // erase the old tBX_RET instruction
439 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVr
))
440 .addReg(ARM::R12
, RegState::Define
)
441 .addReg(ARM::R3
, RegState::Kill
));
443 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tPOP
)))
444 .addReg(ARM::R3
, RegState::Define
);
446 emitSPUpdate(MBB
, MBBI
, TII
, dl
, *RegInfo
, ArgRegsSaveSize
);
448 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVr
))
449 .addReg(ARM::LR
, RegState::Define
)
450 .addReg(ARM::R3
, RegState::Kill
));
452 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVr
))
453 .addReg(ARM::R3
, RegState::Define
)
454 .addReg(ARM::R12
, RegState::Kill
));
455 // Keep the tBX_RET instruction
460 bool Thumb1FrameLowering::
461 spillCalleeSavedRegisters(MachineBasicBlock
&MBB
,
462 MachineBasicBlock::iterator MI
,
463 const std::vector
<CalleeSavedInfo
> &CSI
,
464 const TargetRegisterInfo
*TRI
) const {
469 MachineFunction
&MF
= *MBB
.getParent();
470 const TargetInstrInfo
&TII
= *MF
.getSubtarget().getInstrInfo();
472 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
474 MachineInstrBuilder MIB
= BuildMI(MBB
, MI
, DL
, TII
.get(ARM::tPUSH
));
476 for (unsigned i
= CSI
.size(); i
!= 0; --i
) {
477 unsigned Reg
= CSI
[i
-1].getReg();
480 // Add the callee-saved register as live-in unless it's LR and
481 // @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress
482 // then it's already added to the function and entry block live-in sets.
483 if (Reg
== ARM::LR
) {
484 MachineFunction
&MF
= *MBB
.getParent();
485 if (MF
.getFrameInfo()->isReturnAddressTaken() &&
486 MF
.getRegInfo().isLiveIn(Reg
))
493 MIB
.addReg(Reg
, getKillRegState(isKill
));
495 MIB
.setMIFlags(MachineInstr::FrameSetup
);
499 bool Thumb1FrameLowering::
500 restoreCalleeSavedRegisters(MachineBasicBlock
&MBB
,
501 MachineBasicBlock::iterator MI
,
502 const std::vector
<CalleeSavedInfo
> &CSI
,
503 const TargetRegisterInfo
*TRI
) const {
507 MachineFunction
&MF
= *MBB
.getParent();
508 ARMFunctionInfo
*AFI
= MF
.getInfo
<ARMFunctionInfo
>();
509 const TargetInstrInfo
&TII
= *MF
.getSubtarget().getInstrInfo();
511 bool isVarArg
= AFI
->getArgRegsSaveSize() > 0;
512 DebugLoc DL
= MI
->getDebugLoc();
513 MachineInstrBuilder MIB
= BuildMI(MF
, DL
, TII
.get(ARM::tPOP
));
516 bool NumRegs
= false;
517 for (unsigned i
= CSI
.size(); i
!= 0; --i
) {
518 unsigned Reg
= CSI
[i
-1].getReg();
519 if (Reg
== ARM::LR
) {
520 // Special epilogue for vararg functions. See emitEpilogue
523 // ARMv4T requires BX, see emitEpilogue
524 if (STI
.hasV4TOps() && !STI
.hasV5TOps())
527 (*MIB
).setDesc(TII
.get(ARM::tPOP_RET
));
528 MIB
.copyImplicitOps(&*MI
);
531 MIB
.addReg(Reg
, getDefRegState(true));
535 // It's illegal to emit pop instruction without operands.
537 MBB
.insert(MI
, &*MIB
);
539 MF
.DeleteMachineInstr(MIB
);