xref: /aosp_15_r20/external/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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