1*9880d681SAndroid Build Coastguard Worker //===-- Thumb1FrameLowering.cpp - Thumb1 Frame Information ----------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the Thumb1 implementation of TargetFrameLowering class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "Thumb1FrameLowering.h"
15*9880d681SAndroid Build Coastguard Worker #include "ARMMachineFunctionInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LivePhysRegs.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker using namespace llvm;
24*9880d681SAndroid Build Coastguard Worker
Thumb1FrameLowering(const ARMSubtarget & sti)25*9880d681SAndroid Build Coastguard Worker Thumb1FrameLowering::Thumb1FrameLowering(const ARMSubtarget &sti)
26*9880d681SAndroid Build Coastguard Worker : ARMFrameLowering(sti) {}
27*9880d681SAndroid Build Coastguard Worker
hasReservedCallFrame(const MachineFunction & MF) const28*9880d681SAndroid Build Coastguard Worker bool Thumb1FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const{
29*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *FFI = MF.getFrameInfo();
30*9880d681SAndroid Build Coastguard Worker unsigned CFSize = FFI->getMaxCallFrameSize();
31*9880d681SAndroid Build Coastguard Worker // It's not always a good idea to include the call frame as part of the
32*9880d681SAndroid Build Coastguard Worker // stack frame. ARM (especially Thumb) has small immediate offset to
33*9880d681SAndroid Build Coastguard Worker // address the stack frame. So a large call frame can cause poor codegen
34*9880d681SAndroid Build Coastguard Worker // and may even makes it impossible to scavenge a register.
35*9880d681SAndroid Build Coastguard Worker if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
36*9880d681SAndroid Build Coastguard Worker return false;
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker return !MF.getFrameInfo()->hasVarSizedObjects();
39*9880d681SAndroid Build Coastguard Worker }
40*9880d681SAndroid Build Coastguard Worker
emitSPUpdate(MachineBasicBlock & MBB,MachineBasicBlock::iterator & MBBI,const TargetInstrInfo & TII,const DebugLoc & dl,const ThumbRegisterInfo & MRI,int NumBytes,unsigned MIFlags=MachineInstr::NoFlags)41*9880d681SAndroid Build Coastguard Worker static void emitSPUpdate(MachineBasicBlock &MBB,
42*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator &MBBI,
43*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo &TII, const DebugLoc &dl,
44*9880d681SAndroid Build Coastguard Worker const ThumbRegisterInfo &MRI, int NumBytes,
45*9880d681SAndroid Build Coastguard Worker unsigned MIFlags = MachineInstr::NoFlags) {
46*9880d681SAndroid Build Coastguard Worker emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII,
47*9880d681SAndroid Build Coastguard Worker MRI, MIFlags);
48*9880d681SAndroid Build Coastguard Worker }
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator Thumb1FrameLowering::
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const52*9880d681SAndroid Build Coastguard Worker eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
53*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I) const {
54*9880d681SAndroid Build Coastguard Worker const Thumb1InstrInfo &TII =
55*9880d681SAndroid Build Coastguard Worker *static_cast<const Thumb1InstrInfo *>(STI.getInstrInfo());
56*9880d681SAndroid Build Coastguard Worker const ThumbRegisterInfo *RegInfo =
57*9880d681SAndroid Build Coastguard Worker static_cast<const ThumbRegisterInfo *>(STI.getRegisterInfo());
58*9880d681SAndroid Build Coastguard Worker if (!hasReservedCallFrame(MF)) {
59*9880d681SAndroid Build Coastguard Worker // If we have alloca, convert as follows:
60*9880d681SAndroid Build Coastguard Worker // ADJCALLSTACKDOWN -> sub, sp, sp, amount
61*9880d681SAndroid Build Coastguard Worker // ADJCALLSTACKUP -> add, sp, sp, amount
62*9880d681SAndroid Build Coastguard Worker MachineInstr &Old = *I;
63*9880d681SAndroid Build Coastguard Worker DebugLoc dl = Old.getDebugLoc();
64*9880d681SAndroid Build Coastguard Worker unsigned Amount = Old.getOperand(0).getImm();
65*9880d681SAndroid Build Coastguard Worker if (Amount != 0) {
66*9880d681SAndroid Build Coastguard Worker // We need to keep the stack aligned properly. To do this, we round the
67*9880d681SAndroid Build Coastguard Worker // amount of space needed for the outgoing arguments up to the next
68*9880d681SAndroid Build Coastguard Worker // alignment boundary.
69*9880d681SAndroid Build Coastguard Worker unsigned Align = getStackAlignment();
70*9880d681SAndroid Build Coastguard Worker Amount = (Amount+Align-1)/Align*Align;
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker // Replace the pseudo instruction with a new instruction...
73*9880d681SAndroid Build Coastguard Worker unsigned Opc = Old.getOpcode();
74*9880d681SAndroid Build Coastguard Worker if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
75*9880d681SAndroid Build Coastguard Worker emitSPUpdate(MBB, I, TII, dl, *RegInfo, -Amount);
76*9880d681SAndroid Build Coastguard Worker } else {
77*9880d681SAndroid Build Coastguard Worker assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
78*9880d681SAndroid Build Coastguard Worker emitSPUpdate(MBB, I, TII, dl, *RegInfo, Amount);
79*9880d681SAndroid Build Coastguard Worker }
80*9880d681SAndroid Build Coastguard Worker }
81*9880d681SAndroid Build Coastguard Worker }
82*9880d681SAndroid Build Coastguard Worker return MBB.erase(I);
83*9880d681SAndroid Build Coastguard Worker }
84*9880d681SAndroid Build Coastguard Worker
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const85*9880d681SAndroid Build Coastguard Worker void Thumb1FrameLowering::emitPrologue(MachineFunction &MF,
86*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB) const {
87*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI = MBB.begin();
88*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF.getFrameInfo();
89*9880d681SAndroid Build Coastguard Worker ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
90*9880d681SAndroid Build Coastguard Worker MachineModuleInfo &MMI = MF.getMMI();
91*9880d681SAndroid Build Coastguard Worker const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
92*9880d681SAndroid Build Coastguard Worker const ThumbRegisterInfo *RegInfo =
93*9880d681SAndroid Build Coastguard Worker static_cast<const ThumbRegisterInfo *>(STI.getRegisterInfo());
94*9880d681SAndroid Build Coastguard Worker const Thumb1InstrInfo &TII =
95*9880d681SAndroid Build Coastguard Worker *static_cast<const Thumb1InstrInfo *>(STI.getInstrInfo());
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize();
98*9880d681SAndroid Build Coastguard Worker unsigned NumBytes = MFI->getStackSize();
99*9880d681SAndroid Build Coastguard Worker assert(NumBytes >= ArgRegsSaveSize &&
100*9880d681SAndroid Build Coastguard Worker "ArgRegsSaveSize is included in NumBytes");
101*9880d681SAndroid Build Coastguard Worker const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker // Debug location must be unknown since the first debug location is used
104*9880d681SAndroid Build Coastguard Worker // to determine the end of the prologue.
105*9880d681SAndroid Build Coastguard Worker DebugLoc dl;
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker unsigned FramePtr = RegInfo->getFrameRegister(MF);
108*9880d681SAndroid Build Coastguard Worker unsigned BasePtr = RegInfo->getBaseRegister();
109*9880d681SAndroid Build Coastguard Worker int CFAOffset = 0;
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
112*9880d681SAndroid Build Coastguard Worker NumBytes = (NumBytes + 3) & ~3;
113*9880d681SAndroid Build Coastguard Worker MFI->setStackSize(NumBytes);
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker // Determine the sizes of each callee-save spill areas and record which frame
116*9880d681SAndroid Build Coastguard Worker // belongs to which callee-save spill areas.
117*9880d681SAndroid Build Coastguard Worker unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
118*9880d681SAndroid Build Coastguard Worker int FramePtrSpillFI = 0;
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Worker if (ArgRegsSaveSize) {
121*9880d681SAndroid Build Coastguard Worker emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -ArgRegsSaveSize,
122*9880d681SAndroid Build Coastguard Worker MachineInstr::FrameSetup);
123*9880d681SAndroid Build Coastguard Worker CFAOffset -= ArgRegsSaveSize;
124*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(
125*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createDefCfaOffset(nullptr, CFAOffset));
126*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
127*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex)
128*9880d681SAndroid Build Coastguard Worker .setMIFlags(MachineInstr::FrameSetup);
129*9880d681SAndroid Build Coastguard Worker }
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker if (!AFI->hasStackFrame()) {
132*9880d681SAndroid Build Coastguard Worker if (NumBytes - ArgRegsSaveSize != 0) {
133*9880d681SAndroid Build Coastguard Worker emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -(NumBytes - ArgRegsSaveSize),
134*9880d681SAndroid Build Coastguard Worker MachineInstr::FrameSetup);
135*9880d681SAndroid Build Coastguard Worker CFAOffset -= NumBytes - ArgRegsSaveSize;
136*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(
137*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createDefCfaOffset(nullptr, CFAOffset));
138*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
139*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex)
140*9880d681SAndroid Build Coastguard Worker .setMIFlags(MachineInstr::FrameSetup);
141*9880d681SAndroid Build Coastguard Worker }
142*9880d681SAndroid Build Coastguard Worker return;
143*9880d681SAndroid Build Coastguard Worker }
144*9880d681SAndroid Build Coastguard Worker
145*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
146*9880d681SAndroid Build Coastguard Worker unsigned Reg = CSI[i].getReg();
147*9880d681SAndroid Build Coastguard Worker int FI = CSI[i].getFrameIdx();
148*9880d681SAndroid Build Coastguard Worker switch (Reg) {
149*9880d681SAndroid Build Coastguard Worker case ARM::R8:
150*9880d681SAndroid Build Coastguard Worker case ARM::R9:
151*9880d681SAndroid Build Coastguard Worker case ARM::R10:
152*9880d681SAndroid Build Coastguard Worker case ARM::R11:
153*9880d681SAndroid Build Coastguard Worker if (STI.splitFramePushPop()) {
154*9880d681SAndroid Build Coastguard Worker GPRCS2Size += 4;
155*9880d681SAndroid Build Coastguard Worker break;
156*9880d681SAndroid Build Coastguard Worker }
157*9880d681SAndroid Build Coastguard Worker // fallthrough
158*9880d681SAndroid Build Coastguard Worker case ARM::R4:
159*9880d681SAndroid Build Coastguard Worker case ARM::R5:
160*9880d681SAndroid Build Coastguard Worker case ARM::R6:
161*9880d681SAndroid Build Coastguard Worker case ARM::R7:
162*9880d681SAndroid Build Coastguard Worker case ARM::LR:
163*9880d681SAndroid Build Coastguard Worker if (Reg == FramePtr)
164*9880d681SAndroid Build Coastguard Worker FramePtrSpillFI = FI;
165*9880d681SAndroid Build Coastguard Worker GPRCS1Size += 4;
166*9880d681SAndroid Build Coastguard Worker break;
167*9880d681SAndroid Build Coastguard Worker default:
168*9880d681SAndroid Build Coastguard Worker DPRCSSize += 8;
169*9880d681SAndroid Build Coastguard Worker }
170*9880d681SAndroid Build Coastguard Worker }
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) {
173*9880d681SAndroid Build Coastguard Worker ++MBBI;
174*9880d681SAndroid Build Coastguard Worker }
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker // Determine starting offsets of spill areas.
177*9880d681SAndroid Build Coastguard Worker unsigned DPRCSOffset = NumBytes - ArgRegsSaveSize - (GPRCS1Size + GPRCS2Size + DPRCSSize);
178*9880d681SAndroid Build Coastguard Worker unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
179*9880d681SAndroid Build Coastguard Worker unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
180*9880d681SAndroid Build Coastguard Worker bool HasFP = hasFP(MF);
181*9880d681SAndroid Build Coastguard Worker if (HasFP)
182*9880d681SAndroid Build Coastguard Worker AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) +
183*9880d681SAndroid Build Coastguard Worker NumBytes);
184*9880d681SAndroid Build Coastguard Worker AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
185*9880d681SAndroid Build Coastguard Worker AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
186*9880d681SAndroid Build Coastguard Worker AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
187*9880d681SAndroid Build Coastguard Worker NumBytes = DPRCSOffset;
188*9880d681SAndroid Build Coastguard Worker
189*9880d681SAndroid Build Coastguard Worker int FramePtrOffsetInBlock = 0;
190*9880d681SAndroid Build Coastguard Worker unsigned adjustedGPRCS1Size = GPRCS1Size;
191*9880d681SAndroid Build Coastguard Worker if (tryFoldSPUpdateIntoPushPop(STI, MF, &*std::prev(MBBI), NumBytes)) {
192*9880d681SAndroid Build Coastguard Worker FramePtrOffsetInBlock = NumBytes;
193*9880d681SAndroid Build Coastguard Worker adjustedGPRCS1Size += NumBytes;
194*9880d681SAndroid Build Coastguard Worker NumBytes = 0;
195*9880d681SAndroid Build Coastguard Worker }
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Worker if (adjustedGPRCS1Size) {
198*9880d681SAndroid Build Coastguard Worker CFAOffset -= adjustedGPRCS1Size;
199*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(
200*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createDefCfaOffset(nullptr, CFAOffset));
201*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
202*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex)
203*9880d681SAndroid Build Coastguard Worker .setMIFlags(MachineInstr::FrameSetup);
204*9880d681SAndroid Build Coastguard Worker }
205*9880d681SAndroid Build Coastguard Worker for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
206*9880d681SAndroid Build Coastguard Worker E = CSI.end(); I != E; ++I) {
207*9880d681SAndroid Build Coastguard Worker unsigned Reg = I->getReg();
208*9880d681SAndroid Build Coastguard Worker int FI = I->getFrameIdx();
209*9880d681SAndroid Build Coastguard Worker switch (Reg) {
210*9880d681SAndroid Build Coastguard Worker case ARM::R8:
211*9880d681SAndroid Build Coastguard Worker case ARM::R9:
212*9880d681SAndroid Build Coastguard Worker case ARM::R10:
213*9880d681SAndroid Build Coastguard Worker case ARM::R11:
214*9880d681SAndroid Build Coastguard Worker case ARM::R12:
215*9880d681SAndroid Build Coastguard Worker if (STI.splitFramePushPop())
216*9880d681SAndroid Build Coastguard Worker break;
217*9880d681SAndroid Build Coastguard Worker // fallthough
218*9880d681SAndroid Build Coastguard Worker case ARM::R0:
219*9880d681SAndroid Build Coastguard Worker case ARM::R1:
220*9880d681SAndroid Build Coastguard Worker case ARM::R2:
221*9880d681SAndroid Build Coastguard Worker case ARM::R3:
222*9880d681SAndroid Build Coastguard Worker case ARM::R4:
223*9880d681SAndroid Build Coastguard Worker case ARM::R5:
224*9880d681SAndroid Build Coastguard Worker case ARM::R6:
225*9880d681SAndroid Build Coastguard Worker case ARM::R7:
226*9880d681SAndroid Build Coastguard Worker case ARM::LR:
227*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset(
228*9880d681SAndroid Build Coastguard Worker nullptr, MRI->getDwarfRegNum(Reg, true), MFI->getObjectOffset(FI)));
229*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
230*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex)
231*9880d681SAndroid Build Coastguard Worker .setMIFlags(MachineInstr::FrameSetup);
232*9880d681SAndroid Build Coastguard Worker break;
233*9880d681SAndroid Build Coastguard Worker }
234*9880d681SAndroid Build Coastguard Worker }
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker // Adjust FP so it point to the stack slot that contains the previous FP.
237*9880d681SAndroid Build Coastguard Worker if (HasFP) {
238*9880d681SAndroid Build Coastguard Worker FramePtrOffsetInBlock +=
239*9880d681SAndroid Build Coastguard Worker MFI->getObjectOffset(FramePtrSpillFI) + GPRCS1Size + ArgRegsSaveSize;
240*9880d681SAndroid Build Coastguard Worker AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
241*9880d681SAndroid Build Coastguard Worker .addReg(ARM::SP).addImm(FramePtrOffsetInBlock / 4)
242*9880d681SAndroid Build Coastguard Worker .setMIFlags(MachineInstr::FrameSetup));
243*9880d681SAndroid Build Coastguard Worker if(FramePtrOffsetInBlock) {
244*9880d681SAndroid Build Coastguard Worker CFAOffset += FramePtrOffsetInBlock;
245*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createDefCfa(
246*9880d681SAndroid Build Coastguard Worker nullptr, MRI->getDwarfRegNum(FramePtr, true), CFAOffset));
247*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
248*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex)
249*9880d681SAndroid Build Coastguard Worker .setMIFlags(MachineInstr::FrameSetup);
250*9880d681SAndroid Build Coastguard Worker } else {
251*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex =
252*9880d681SAndroid Build Coastguard Worker MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(
253*9880d681SAndroid Build Coastguard Worker nullptr, MRI->getDwarfRegNum(FramePtr, true)));
254*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
255*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex)
256*9880d681SAndroid Build Coastguard Worker .setMIFlags(MachineInstr::FrameSetup);
257*9880d681SAndroid Build Coastguard Worker }
258*9880d681SAndroid Build Coastguard Worker if (NumBytes > 508)
259*9880d681SAndroid Build Coastguard Worker // If offset is > 508 then sp cannot be adjusted in a single instruction,
260*9880d681SAndroid Build Coastguard Worker // try restoring from fp instead.
261*9880d681SAndroid Build Coastguard Worker AFI->setShouldRestoreSPFromFP(true);
262*9880d681SAndroid Build Coastguard Worker }
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Worker if (NumBytes) {
265*9880d681SAndroid Build Coastguard Worker // Insert it after all the callee-save spills.
266*9880d681SAndroid Build Coastguard Worker emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes,
267*9880d681SAndroid Build Coastguard Worker MachineInstr::FrameSetup);
268*9880d681SAndroid Build Coastguard Worker if (!HasFP) {
269*9880d681SAndroid Build Coastguard Worker CFAOffset -= NumBytes;
270*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(
271*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createDefCfaOffset(nullptr, CFAOffset));
272*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
273*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex)
274*9880d681SAndroid Build Coastguard Worker .setMIFlags(MachineInstr::FrameSetup);
275*9880d681SAndroid Build Coastguard Worker }
276*9880d681SAndroid Build Coastguard Worker }
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker if (STI.isTargetELF() && HasFP)
279*9880d681SAndroid Build Coastguard Worker MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
280*9880d681SAndroid Build Coastguard Worker AFI->getFramePtrSpillOffset());
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Worker AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
283*9880d681SAndroid Build Coastguard Worker AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
284*9880d681SAndroid Build Coastguard Worker AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
285*9880d681SAndroid Build Coastguard Worker
286*9880d681SAndroid Build Coastguard Worker // Thumb1 does not currently support dynamic stack realignment. Report a
287*9880d681SAndroid Build Coastguard Worker // fatal error rather then silently generate bad code.
288*9880d681SAndroid Build Coastguard Worker if (RegInfo->needsStackRealignment(MF))
289*9880d681SAndroid Build Coastguard Worker report_fatal_error("Dynamic stack realignment not supported for thumb1.");
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Worker // If we need a base pointer, set it up here. It's whatever the value
292*9880d681SAndroid Build Coastguard Worker // of the stack pointer is at this point. Any variable size objects
293*9880d681SAndroid Build Coastguard Worker // will be allocated after this, so we can still use the base pointer
294*9880d681SAndroid Build Coastguard Worker // to reference locals.
295*9880d681SAndroid Build Coastguard Worker if (RegInfo->hasBasePointer(MF))
296*9880d681SAndroid Build Coastguard Worker AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), BasePtr)
297*9880d681SAndroid Build Coastguard Worker .addReg(ARM::SP));
298*9880d681SAndroid Build Coastguard Worker
299*9880d681SAndroid Build Coastguard Worker // If the frame has variable sized objects then the epilogue must restore
300*9880d681SAndroid Build Coastguard Worker // the sp from fp. We can assume there's an FP here since hasFP already
301*9880d681SAndroid Build Coastguard Worker // checks for hasVarSizedObjects.
302*9880d681SAndroid Build Coastguard Worker if (MFI->hasVarSizedObjects())
303*9880d681SAndroid Build Coastguard Worker AFI->setShouldRestoreSPFromFP(true);
304*9880d681SAndroid Build Coastguard Worker }
305*9880d681SAndroid Build Coastguard Worker
isCSRestore(MachineInstr & MI,const MCPhysReg * CSRegs)306*9880d681SAndroid Build Coastguard Worker static bool isCSRestore(MachineInstr &MI, const MCPhysReg *CSRegs) {
307*9880d681SAndroid Build Coastguard Worker if (MI.getOpcode() == ARM::tLDRspi && MI.getOperand(1).isFI() &&
308*9880d681SAndroid Build Coastguard Worker isCalleeSavedRegister(MI.getOperand(0).getReg(), CSRegs))
309*9880d681SAndroid Build Coastguard Worker return true;
310*9880d681SAndroid Build Coastguard Worker else if (MI.getOpcode() == ARM::tPOP) {
311*9880d681SAndroid Build Coastguard Worker // The first two operands are predicates. The last two are
312*9880d681SAndroid Build Coastguard Worker // imp-def and imp-use of SP. Check everything in between.
313*9880d681SAndroid Build Coastguard Worker for (int i = 2, e = MI.getNumOperands() - 2; i != e; ++i)
314*9880d681SAndroid Build Coastguard Worker if (!isCalleeSavedRegister(MI.getOperand(i).getReg(), CSRegs))
315*9880d681SAndroid Build Coastguard Worker return false;
316*9880d681SAndroid Build Coastguard Worker return true;
317*9880d681SAndroid Build Coastguard Worker }
318*9880d681SAndroid Build Coastguard Worker return false;
319*9880d681SAndroid Build Coastguard Worker }
320*9880d681SAndroid Build Coastguard Worker
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const321*9880d681SAndroid Build Coastguard Worker void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF,
322*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB) const {
323*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
324*9880d681SAndroid Build Coastguard Worker DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
325*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF.getFrameInfo();
326*9880d681SAndroid Build Coastguard Worker ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
327*9880d681SAndroid Build Coastguard Worker const ThumbRegisterInfo *RegInfo =
328*9880d681SAndroid Build Coastguard Worker static_cast<const ThumbRegisterInfo *>(STI.getRegisterInfo());
329*9880d681SAndroid Build Coastguard Worker const Thumb1InstrInfo &TII =
330*9880d681SAndroid Build Coastguard Worker *static_cast<const Thumb1InstrInfo *>(STI.getInstrInfo());
331*9880d681SAndroid Build Coastguard Worker
332*9880d681SAndroid Build Coastguard Worker unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize();
333*9880d681SAndroid Build Coastguard Worker int NumBytes = (int)MFI->getStackSize();
334*9880d681SAndroid Build Coastguard Worker assert((unsigned)NumBytes >= ArgRegsSaveSize &&
335*9880d681SAndroid Build Coastguard Worker "ArgRegsSaveSize is included in NumBytes");
336*9880d681SAndroid Build Coastguard Worker const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
337*9880d681SAndroid Build Coastguard Worker unsigned FramePtr = RegInfo->getFrameRegister(MF);
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Worker if (!AFI->hasStackFrame()) {
340*9880d681SAndroid Build Coastguard Worker if (NumBytes - ArgRegsSaveSize != 0)
341*9880d681SAndroid Build Coastguard Worker emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes - ArgRegsSaveSize);
342*9880d681SAndroid Build Coastguard Worker } else {
343*9880d681SAndroid Build Coastguard Worker // Unwind MBBI to point to first LDR / VLDRD.
344*9880d681SAndroid Build Coastguard Worker if (MBBI != MBB.begin()) {
345*9880d681SAndroid Build Coastguard Worker do
346*9880d681SAndroid Build Coastguard Worker --MBBI;
347*9880d681SAndroid Build Coastguard Worker while (MBBI != MBB.begin() && isCSRestore(*MBBI, CSRegs));
348*9880d681SAndroid Build Coastguard Worker if (!isCSRestore(*MBBI, CSRegs))
349*9880d681SAndroid Build Coastguard Worker ++MBBI;
350*9880d681SAndroid Build Coastguard Worker }
351*9880d681SAndroid Build Coastguard Worker
352*9880d681SAndroid Build Coastguard Worker // Move SP to start of FP callee save spill area.
353*9880d681SAndroid Build Coastguard Worker NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
354*9880d681SAndroid Build Coastguard Worker AFI->getGPRCalleeSavedArea2Size() +
355*9880d681SAndroid Build Coastguard Worker AFI->getDPRCalleeSavedAreaSize() +
356*9880d681SAndroid Build Coastguard Worker ArgRegsSaveSize);
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Worker if (AFI->shouldRestoreSPFromFP()) {
359*9880d681SAndroid Build Coastguard Worker NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
360*9880d681SAndroid Build Coastguard Worker // Reset SP based on frame pointer only if the stack frame extends beyond
361*9880d681SAndroid Build Coastguard Worker // frame pointer stack slot, the target is ELF and the function has FP, or
362*9880d681SAndroid Build Coastguard Worker // the target uses var sized objects.
363*9880d681SAndroid Build Coastguard Worker if (NumBytes) {
364*9880d681SAndroid Build Coastguard Worker assert(!MFI->getPristineRegs(MF).test(ARM::R4) &&
365*9880d681SAndroid Build Coastguard Worker "No scratch register to restore SP from FP!");
366*9880d681SAndroid Build Coastguard Worker emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes,
367*9880d681SAndroid Build Coastguard Worker TII, *RegInfo);
368*9880d681SAndroid Build Coastguard Worker AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),
369*9880d681SAndroid Build Coastguard Worker ARM::SP)
370*9880d681SAndroid Build Coastguard Worker .addReg(ARM::R4));
371*9880d681SAndroid Build Coastguard Worker } else
372*9880d681SAndroid Build Coastguard Worker AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),
373*9880d681SAndroid Build Coastguard Worker ARM::SP)
374*9880d681SAndroid Build Coastguard Worker .addReg(FramePtr));
375*9880d681SAndroid Build Coastguard Worker } else {
376*9880d681SAndroid Build Coastguard Worker if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tBX_RET &&
377*9880d681SAndroid Build Coastguard Worker &MBB.front() != &*MBBI && std::prev(MBBI)->getOpcode() == ARM::tPOP) {
378*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator PMBBI = std::prev(MBBI);
379*9880d681SAndroid Build Coastguard Worker if (!tryFoldSPUpdateIntoPushPop(STI, MF, &*PMBBI, NumBytes))
380*9880d681SAndroid Build Coastguard Worker emitSPUpdate(MBB, PMBBI, TII, dl, *RegInfo, NumBytes);
381*9880d681SAndroid Build Coastguard Worker } else if (!tryFoldSPUpdateIntoPushPop(STI, MF, &*MBBI, NumBytes))
382*9880d681SAndroid Build Coastguard Worker emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes);
383*9880d681SAndroid Build Coastguard Worker }
384*9880d681SAndroid Build Coastguard Worker }
385*9880d681SAndroid Build Coastguard Worker
386*9880d681SAndroid Build Coastguard Worker if (needPopSpecialFixUp(MF)) {
387*9880d681SAndroid Build Coastguard Worker bool Done = emitPopSpecialFixUp(MBB, /* DoIt */ true);
388*9880d681SAndroid Build Coastguard Worker (void)Done;
389*9880d681SAndroid Build Coastguard Worker assert(Done && "Emission of the special fixup failed!?");
390*9880d681SAndroid Build Coastguard Worker }
391*9880d681SAndroid Build Coastguard Worker }
392*9880d681SAndroid Build Coastguard Worker
canUseAsEpilogue(const MachineBasicBlock & MBB) const393*9880d681SAndroid Build Coastguard Worker bool Thumb1FrameLowering::canUseAsEpilogue(const MachineBasicBlock &MBB) const {
394*9880d681SAndroid Build Coastguard Worker if (!needPopSpecialFixUp(*MBB.getParent()))
395*9880d681SAndroid Build Coastguard Worker return true;
396*9880d681SAndroid Build Coastguard Worker
397*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
398*9880d681SAndroid Build Coastguard Worker return emitPopSpecialFixUp(*TmpMBB, /* DoIt */ false);
399*9880d681SAndroid Build Coastguard Worker }
400*9880d681SAndroid Build Coastguard Worker
needPopSpecialFixUp(const MachineFunction & MF) const401*9880d681SAndroid Build Coastguard Worker bool Thumb1FrameLowering::needPopSpecialFixUp(const MachineFunction &MF) const {
402*9880d681SAndroid Build Coastguard Worker ARMFunctionInfo *AFI =
403*9880d681SAndroid Build Coastguard Worker const_cast<MachineFunction *>(&MF)->getInfo<ARMFunctionInfo>();
404*9880d681SAndroid Build Coastguard Worker if (AFI->getArgRegsSaveSize())
405*9880d681SAndroid Build Coastguard Worker return true;
406*9880d681SAndroid Build Coastguard Worker
407*9880d681SAndroid Build Coastguard Worker // LR cannot be encoded with Thumb1, i.e., it requires a special fix-up.
408*9880d681SAndroid Build Coastguard Worker for (const CalleeSavedInfo &CSI : MF.getFrameInfo()->getCalleeSavedInfo())
409*9880d681SAndroid Build Coastguard Worker if (CSI.getReg() == ARM::LR)
410*9880d681SAndroid Build Coastguard Worker return true;
411*9880d681SAndroid Build Coastguard Worker
412*9880d681SAndroid Build Coastguard Worker return false;
413*9880d681SAndroid Build Coastguard Worker }
414*9880d681SAndroid Build Coastguard Worker
emitPopSpecialFixUp(MachineBasicBlock & MBB,bool DoIt) const415*9880d681SAndroid Build Coastguard Worker bool Thumb1FrameLowering::emitPopSpecialFixUp(MachineBasicBlock &MBB,
416*9880d681SAndroid Build Coastguard Worker bool DoIt) const {
417*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = *MBB.getParent();
418*9880d681SAndroid Build Coastguard Worker ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
419*9880d681SAndroid Build Coastguard Worker unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize();
420*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo &TII = *STI.getInstrInfo();
421*9880d681SAndroid Build Coastguard Worker const ThumbRegisterInfo *RegInfo =
422*9880d681SAndroid Build Coastguard Worker static_cast<const ThumbRegisterInfo *>(STI.getRegisterInfo());
423*9880d681SAndroid Build Coastguard Worker
424*9880d681SAndroid Build Coastguard Worker // If MBBI is a return instruction, or is a tPOP followed by a return
425*9880d681SAndroid Build Coastguard Worker // instruction in the successor BB, we may be able to directly restore
426*9880d681SAndroid Build Coastguard Worker // LR in the PC.
427*9880d681SAndroid Build Coastguard Worker // This is only possible with v5T ops (v4T can't change the Thumb bit via
428*9880d681SAndroid Build Coastguard Worker // a POP PC instruction), and only if we do not need to emit any SP update.
429*9880d681SAndroid Build Coastguard Worker // Otherwise, we need a temporary register to pop the value
430*9880d681SAndroid Build Coastguard Worker // and copy that value into LR.
431*9880d681SAndroid Build Coastguard Worker auto MBBI = MBB.getFirstTerminator();
432*9880d681SAndroid Build Coastguard Worker bool CanRestoreDirectly = STI.hasV5TOps() && !ArgRegsSaveSize;
433*9880d681SAndroid Build Coastguard Worker if (CanRestoreDirectly) {
434*9880d681SAndroid Build Coastguard Worker if (MBBI != MBB.end() && MBBI->getOpcode() != ARM::tB)
435*9880d681SAndroid Build Coastguard Worker CanRestoreDirectly = (MBBI->getOpcode() == ARM::tBX_RET ||
436*9880d681SAndroid Build Coastguard Worker MBBI->getOpcode() == ARM::tPOP_RET);
437*9880d681SAndroid Build Coastguard Worker else {
438*9880d681SAndroid Build Coastguard Worker auto MBBI_prev = MBBI;
439*9880d681SAndroid Build Coastguard Worker MBBI_prev--;
440*9880d681SAndroid Build Coastguard Worker assert(MBBI_prev->getOpcode() == ARM::tPOP);
441*9880d681SAndroid Build Coastguard Worker assert(MBB.succ_size() == 1);
442*9880d681SAndroid Build Coastguard Worker if ((*MBB.succ_begin())->begin()->getOpcode() == ARM::tBX_RET)
443*9880d681SAndroid Build Coastguard Worker MBBI = MBBI_prev; // Replace the final tPOP with a tPOP_RET.
444*9880d681SAndroid Build Coastguard Worker else
445*9880d681SAndroid Build Coastguard Worker CanRestoreDirectly = false;
446*9880d681SAndroid Build Coastguard Worker }
447*9880d681SAndroid Build Coastguard Worker }
448*9880d681SAndroid Build Coastguard Worker
449*9880d681SAndroid Build Coastguard Worker if (CanRestoreDirectly) {
450*9880d681SAndroid Build Coastguard Worker if (!DoIt || MBBI->getOpcode() == ARM::tPOP_RET)
451*9880d681SAndroid Build Coastguard Worker return true;
452*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB =
453*9880d681SAndroid Build Coastguard Worker AddDefaultPred(
454*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII.get(ARM::tPOP_RET)));
455*9880d681SAndroid Build Coastguard Worker // Copy implicit ops and popped registers, if any.
456*9880d681SAndroid Build Coastguard Worker for (auto MO: MBBI->operands())
457*9880d681SAndroid Build Coastguard Worker if (MO.isReg() && (MO.isImplicit() || MO.isDef()))
458*9880d681SAndroid Build Coastguard Worker MIB.addOperand(MO);
459*9880d681SAndroid Build Coastguard Worker MIB.addReg(ARM::PC, RegState::Define);
460*9880d681SAndroid Build Coastguard Worker // Erase the old instruction (tBX_RET or tPOP).
461*9880d681SAndroid Build Coastguard Worker MBB.erase(MBBI);
462*9880d681SAndroid Build Coastguard Worker return true;
463*9880d681SAndroid Build Coastguard Worker }
464*9880d681SAndroid Build Coastguard Worker
465*9880d681SAndroid Build Coastguard Worker // Look for a temporary register to use.
466*9880d681SAndroid Build Coastguard Worker // First, compute the liveness information.
467*9880d681SAndroid Build Coastguard Worker LivePhysRegs UsedRegs(STI.getRegisterInfo());
468*9880d681SAndroid Build Coastguard Worker UsedRegs.addLiveOuts(MBB);
469*9880d681SAndroid Build Coastguard Worker // The semantic of pristines changed recently and now,
470*9880d681SAndroid Build Coastguard Worker // the callee-saved registers that are touched in the function
471*9880d681SAndroid Build Coastguard Worker // are not part of the pristines set anymore.
472*9880d681SAndroid Build Coastguard Worker // Add those callee-saved now.
473*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI = STI.getRegisterInfo();
474*9880d681SAndroid Build Coastguard Worker const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF);
475*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; CSRegs[i]; ++i)
476*9880d681SAndroid Build Coastguard Worker UsedRegs.addReg(CSRegs[i]);
477*9880d681SAndroid Build Coastguard Worker
478*9880d681SAndroid Build Coastguard Worker DebugLoc dl = DebugLoc();
479*9880d681SAndroid Build Coastguard Worker if (MBBI != MBB.end()) {
480*9880d681SAndroid Build Coastguard Worker dl = MBBI->getDebugLoc();
481*9880d681SAndroid Build Coastguard Worker auto InstUpToMBBI = MBB.end();
482*9880d681SAndroid Build Coastguard Worker while (InstUpToMBBI != MBBI)
483*9880d681SAndroid Build Coastguard Worker // The pre-decrement is on purpose here.
484*9880d681SAndroid Build Coastguard Worker // We want to have the liveness right before MBBI.
485*9880d681SAndroid Build Coastguard Worker UsedRegs.stepBackward(*--InstUpToMBBI);
486*9880d681SAndroid Build Coastguard Worker }
487*9880d681SAndroid Build Coastguard Worker
488*9880d681SAndroid Build Coastguard Worker // Look for a register that can be directly use in the POP.
489*9880d681SAndroid Build Coastguard Worker unsigned PopReg = 0;
490*9880d681SAndroid Build Coastguard Worker // And some temporary register, just in case.
491*9880d681SAndroid Build Coastguard Worker unsigned TemporaryReg = 0;
492*9880d681SAndroid Build Coastguard Worker BitVector PopFriendly =
493*9880d681SAndroid Build Coastguard Worker TRI->getAllocatableSet(MF, TRI->getRegClass(ARM::tGPRRegClassID));
494*9880d681SAndroid Build Coastguard Worker assert(PopFriendly.any() && "No allocatable pop-friendly register?!");
495*9880d681SAndroid Build Coastguard Worker // Rebuild the GPRs from the high registers because they are removed
496*9880d681SAndroid Build Coastguard Worker // form the GPR reg class for thumb1.
497*9880d681SAndroid Build Coastguard Worker BitVector GPRsNoLRSP =
498*9880d681SAndroid Build Coastguard Worker TRI->getAllocatableSet(MF, TRI->getRegClass(ARM::hGPRRegClassID));
499*9880d681SAndroid Build Coastguard Worker GPRsNoLRSP |= PopFriendly;
500*9880d681SAndroid Build Coastguard Worker GPRsNoLRSP.reset(ARM::LR);
501*9880d681SAndroid Build Coastguard Worker GPRsNoLRSP.reset(ARM::SP);
502*9880d681SAndroid Build Coastguard Worker GPRsNoLRSP.reset(ARM::PC);
503*9880d681SAndroid Build Coastguard Worker for (int Register = GPRsNoLRSP.find_first(); Register != -1;
504*9880d681SAndroid Build Coastguard Worker Register = GPRsNoLRSP.find_next(Register)) {
505*9880d681SAndroid Build Coastguard Worker if (!UsedRegs.contains(Register)) {
506*9880d681SAndroid Build Coastguard Worker // Remember the first pop-friendly register and exit.
507*9880d681SAndroid Build Coastguard Worker if (PopFriendly.test(Register)) {
508*9880d681SAndroid Build Coastguard Worker PopReg = Register;
509*9880d681SAndroid Build Coastguard Worker TemporaryReg = 0;
510*9880d681SAndroid Build Coastguard Worker break;
511*9880d681SAndroid Build Coastguard Worker }
512*9880d681SAndroid Build Coastguard Worker // Otherwise, remember that the register will be available to
513*9880d681SAndroid Build Coastguard Worker // save a pop-friendly register.
514*9880d681SAndroid Build Coastguard Worker TemporaryReg = Register;
515*9880d681SAndroid Build Coastguard Worker }
516*9880d681SAndroid Build Coastguard Worker }
517*9880d681SAndroid Build Coastguard Worker
518*9880d681SAndroid Build Coastguard Worker if (!DoIt && !PopReg && !TemporaryReg)
519*9880d681SAndroid Build Coastguard Worker return false;
520*9880d681SAndroid Build Coastguard Worker
521*9880d681SAndroid Build Coastguard Worker assert((PopReg || TemporaryReg) && "Cannot get LR");
522*9880d681SAndroid Build Coastguard Worker
523*9880d681SAndroid Build Coastguard Worker if (TemporaryReg) {
524*9880d681SAndroid Build Coastguard Worker assert(!PopReg && "Unnecessary MOV is about to be inserted");
525*9880d681SAndroid Build Coastguard Worker PopReg = PopFriendly.find_first();
526*9880d681SAndroid Build Coastguard Worker AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr))
527*9880d681SAndroid Build Coastguard Worker .addReg(TemporaryReg, RegState::Define)
528*9880d681SAndroid Build Coastguard Worker .addReg(PopReg, RegState::Kill));
529*9880d681SAndroid Build Coastguard Worker }
530*9880d681SAndroid Build Coastguard Worker
531*9880d681SAndroid Build Coastguard Worker if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPOP_RET) {
532*9880d681SAndroid Build Coastguard Worker // We couldn't use the direct restoration above, so
533*9880d681SAndroid Build Coastguard Worker // perform the opposite conversion: tPOP_RET to tPOP.
534*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB =
535*9880d681SAndroid Build Coastguard Worker AddDefaultPred(
536*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII.get(ARM::tPOP)));
537*9880d681SAndroid Build Coastguard Worker bool Popped = false;
538*9880d681SAndroid Build Coastguard Worker for (auto MO: MBBI->operands())
539*9880d681SAndroid Build Coastguard Worker if (MO.isReg() && (MO.isImplicit() || MO.isDef()) &&
540*9880d681SAndroid Build Coastguard Worker MO.getReg() != ARM::PC) {
541*9880d681SAndroid Build Coastguard Worker MIB.addOperand(MO);
542*9880d681SAndroid Build Coastguard Worker if (!MO.isImplicit())
543*9880d681SAndroid Build Coastguard Worker Popped = true;
544*9880d681SAndroid Build Coastguard Worker }
545*9880d681SAndroid Build Coastguard Worker // Is there anything left to pop?
546*9880d681SAndroid Build Coastguard Worker if (!Popped)
547*9880d681SAndroid Build Coastguard Worker MBB.erase(MIB.getInstr());
548*9880d681SAndroid Build Coastguard Worker // Erase the old instruction.
549*9880d681SAndroid Build Coastguard Worker MBB.erase(MBBI);
550*9880d681SAndroid Build Coastguard Worker MBBI = AddDefaultPred(BuildMI(MBB, MBB.end(), dl, TII.get(ARM::tBX_RET)));
551*9880d681SAndroid Build Coastguard Worker }
552*9880d681SAndroid Build Coastguard Worker
553*9880d681SAndroid Build Coastguard Worker assert(PopReg && "Do not know how to get LR");
554*9880d681SAndroid Build Coastguard Worker AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
555*9880d681SAndroid Build Coastguard Worker .addReg(PopReg, RegState::Define);
556*9880d681SAndroid Build Coastguard Worker
557*9880d681SAndroid Build Coastguard Worker emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, ArgRegsSaveSize);
558*9880d681SAndroid Build Coastguard Worker
559*9880d681SAndroid Build Coastguard Worker AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr))
560*9880d681SAndroid Build Coastguard Worker .addReg(ARM::LR, RegState::Define)
561*9880d681SAndroid Build Coastguard Worker .addReg(PopReg, RegState::Kill));
562*9880d681SAndroid Build Coastguard Worker
563*9880d681SAndroid Build Coastguard Worker if (TemporaryReg)
564*9880d681SAndroid Build Coastguard Worker AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr))
565*9880d681SAndroid Build Coastguard Worker .addReg(PopReg, RegState::Define)
566*9880d681SAndroid Build Coastguard Worker .addReg(TemporaryReg, RegState::Kill));
567*9880d681SAndroid Build Coastguard Worker
568*9880d681SAndroid Build Coastguard Worker return true;
569*9880d681SAndroid Build Coastguard Worker }
570*9880d681SAndroid Build Coastguard Worker
571*9880d681SAndroid Build Coastguard Worker bool Thumb1FrameLowering::
spillCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const std::vector<CalleeSavedInfo> & CSI,const TargetRegisterInfo * TRI) const572*9880d681SAndroid Build Coastguard Worker spillCalleeSavedRegisters(MachineBasicBlock &MBB,
573*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MI,
574*9880d681SAndroid Build Coastguard Worker const std::vector<CalleeSavedInfo> &CSI,
575*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) const {
576*9880d681SAndroid Build Coastguard Worker if (CSI.empty())
577*9880d681SAndroid Build Coastguard Worker return false;
578*9880d681SAndroid Build Coastguard Worker
579*9880d681SAndroid Build Coastguard Worker DebugLoc DL;
580*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo &TII = *STI.getInstrInfo();
581*9880d681SAndroid Build Coastguard Worker
582*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(ARM::tPUSH));
583*9880d681SAndroid Build Coastguard Worker AddDefaultPred(MIB);
584*9880d681SAndroid Build Coastguard Worker for (unsigned i = CSI.size(); i != 0; --i) {
585*9880d681SAndroid Build Coastguard Worker unsigned Reg = CSI[i-1].getReg();
586*9880d681SAndroid Build Coastguard Worker bool isKill = true;
587*9880d681SAndroid Build Coastguard Worker
588*9880d681SAndroid Build Coastguard Worker // Add the callee-saved register as live-in unless it's LR and
589*9880d681SAndroid Build Coastguard Worker // @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress
590*9880d681SAndroid Build Coastguard Worker // then it's already added to the function and entry block live-in sets.
591*9880d681SAndroid Build Coastguard Worker if (Reg == ARM::LR) {
592*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = *MBB.getParent();
593*9880d681SAndroid Build Coastguard Worker if (MF.getFrameInfo()->isReturnAddressTaken() &&
594*9880d681SAndroid Build Coastguard Worker MF.getRegInfo().isLiveIn(Reg))
595*9880d681SAndroid Build Coastguard Worker isKill = false;
596*9880d681SAndroid Build Coastguard Worker }
597*9880d681SAndroid Build Coastguard Worker
598*9880d681SAndroid Build Coastguard Worker if (isKill)
599*9880d681SAndroid Build Coastguard Worker MBB.addLiveIn(Reg);
600*9880d681SAndroid Build Coastguard Worker
601*9880d681SAndroid Build Coastguard Worker MIB.addReg(Reg, getKillRegState(isKill));
602*9880d681SAndroid Build Coastguard Worker }
603*9880d681SAndroid Build Coastguard Worker MIB.setMIFlags(MachineInstr::FrameSetup);
604*9880d681SAndroid Build Coastguard Worker return true;
605*9880d681SAndroid Build Coastguard Worker }
606*9880d681SAndroid Build Coastguard Worker
607*9880d681SAndroid Build Coastguard Worker bool Thumb1FrameLowering::
restoreCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const std::vector<CalleeSavedInfo> & CSI,const TargetRegisterInfo * TRI) const608*9880d681SAndroid Build Coastguard Worker restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
609*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MI,
610*9880d681SAndroid Build Coastguard Worker const std::vector<CalleeSavedInfo> &CSI,
611*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) const {
612*9880d681SAndroid Build Coastguard Worker if (CSI.empty())
613*9880d681SAndroid Build Coastguard Worker return false;
614*9880d681SAndroid Build Coastguard Worker
615*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = *MBB.getParent();
616*9880d681SAndroid Build Coastguard Worker ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
617*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo &TII = *STI.getInstrInfo();
618*9880d681SAndroid Build Coastguard Worker
619*9880d681SAndroid Build Coastguard Worker bool isVarArg = AFI->getArgRegsSaveSize() > 0;
620*9880d681SAndroid Build Coastguard Worker DebugLoc DL = MI != MBB.end() ? MI->getDebugLoc() : DebugLoc();
621*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB = BuildMI(MF, DL, TII.get(ARM::tPOP));
622*9880d681SAndroid Build Coastguard Worker AddDefaultPred(MIB);
623*9880d681SAndroid Build Coastguard Worker
624*9880d681SAndroid Build Coastguard Worker bool NeedsPop = false;
625*9880d681SAndroid Build Coastguard Worker for (unsigned i = CSI.size(); i != 0; --i) {
626*9880d681SAndroid Build Coastguard Worker unsigned Reg = CSI[i-1].getReg();
627*9880d681SAndroid Build Coastguard Worker if (Reg == ARM::LR) {
628*9880d681SAndroid Build Coastguard Worker if (MBB.succ_empty()) {
629*9880d681SAndroid Build Coastguard Worker // Special epilogue for vararg functions. See emitEpilogue
630*9880d681SAndroid Build Coastguard Worker if (isVarArg)
631*9880d681SAndroid Build Coastguard Worker continue;
632*9880d681SAndroid Build Coastguard Worker // ARMv4T requires BX, see emitEpilogue
633*9880d681SAndroid Build Coastguard Worker if (!STI.hasV5TOps())
634*9880d681SAndroid Build Coastguard Worker continue;
635*9880d681SAndroid Build Coastguard Worker Reg = ARM::PC;
636*9880d681SAndroid Build Coastguard Worker (*MIB).setDesc(TII.get(ARM::tPOP_RET));
637*9880d681SAndroid Build Coastguard Worker if (MI != MBB.end())
638*9880d681SAndroid Build Coastguard Worker MIB.copyImplicitOps(*MI);
639*9880d681SAndroid Build Coastguard Worker MI = MBB.erase(MI);
640*9880d681SAndroid Build Coastguard Worker } else
641*9880d681SAndroid Build Coastguard Worker // LR may only be popped into PC, as part of return sequence.
642*9880d681SAndroid Build Coastguard Worker // If this isn't the return sequence, we'll need emitPopSpecialFixUp
643*9880d681SAndroid Build Coastguard Worker // to restore LR the hard way.
644*9880d681SAndroid Build Coastguard Worker continue;
645*9880d681SAndroid Build Coastguard Worker }
646*9880d681SAndroid Build Coastguard Worker MIB.addReg(Reg, getDefRegState(true));
647*9880d681SAndroid Build Coastguard Worker NeedsPop = true;
648*9880d681SAndroid Build Coastguard Worker }
649*9880d681SAndroid Build Coastguard Worker
650*9880d681SAndroid Build Coastguard Worker // It's illegal to emit pop instruction without operands.
651*9880d681SAndroid Build Coastguard Worker if (NeedsPop)
652*9880d681SAndroid Build Coastguard Worker MBB.insert(MI, &*MIB);
653*9880d681SAndroid Build Coastguard Worker else
654*9880d681SAndroid Build Coastguard Worker MF.DeleteMachineInstr(MIB);
655*9880d681SAndroid Build Coastguard Worker
656*9880d681SAndroid Build Coastguard Worker return true;
657*9880d681SAndroid Build Coastguard Worker }
658