ARMFrameLowering.cpp revision 28f08c93e75d291695ea89b9004145103292e85b
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com//===-- ARMFrameLowering.cpp - ARM Frame Information ----------------------===//
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com//                     The LLVM Compiler Infrastructure
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// This file is distributed under the University of Illinois Open Source
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// License. See LICENSE.TXT for details.
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//===----------------------------------------------------------------------===//
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com//
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// This file contains the ARM implementation of TargetFrameLowering class.
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//===----------------------------------------------------------------------===//
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ARMFrameLowering.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ARMBaseInstrInfo.h"
1656c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#include "ARMBaseRegisterInfo.h"
17f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#include "ARMMachineFunctionInfo.h"
18f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#include "MCTargetDesc/ARMAddressingModes.h"
19f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#include "llvm/Function.h"
20f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#include "llvm/CodeGen/MachineFrameInfo.h"
21f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#include "llvm/CodeGen/MachineFunction.h"
22f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#include "llvm/CodeGen/MachineInstrBuilder.h"
23f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#include "llvm/CodeGen/MachineRegisterInfo.h"
24739456585a0cc52b335cd1c0a9fc6b01782a7f89reed@google.com#include "llvm/CodeGen/RegisterScavenging.h"
25739456585a0cc52b335cd1c0a9fc6b01782a7f89reed@google.com#include "llvm/Target/TargetOptions.h"
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "llvm/Support/CommandLine.h"
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing namespace llvm;
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic cl::opt<bool>
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSpillAlignedNEONRegs("align-neon-spills", cl::Hidden, cl::init(true),
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                     cl::desc("Align ARM NEON spills in prolog and epilog"));
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
347ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgstatic MachineBasicBlock::iterator
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comskipAlignedDPRCS2Spills(MachineBasicBlock::iterator MI,
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        unsigned NumAlignedDPRCS2Regs);
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// hasFP - Return true if the specified function should have a dedicated frame
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// pointer register.  This is true if the function has variable sized allocas
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// or if frame pointer elimination is disabled.
41b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.orgbool ARMFrameLowering::hasFP(const MachineFunction &MF) const {
423abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com  const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
433abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
443abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com  // iOS requires FP not to be clobbered for backtracing purpose.
453abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com  if (STI.isTargetIOS())
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return true;
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  const MachineFrameInfo *MFI = MF.getFrameInfo();
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // Always eliminate non-leaf frame pointers.
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  return ((MF.getTarget().Options.DisableFramePointerElim(MF) &&
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com           MFI->hasCalls()) ||
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          RegInfo->needsStackRealignment(MF) ||
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          MFI->hasVarSizedObjects() ||
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          MFI->isFrameAddressTaken());
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// not required, we reserve argument space for call sites in the function
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// immediately on entry to the current function.  This eliminates the need for
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// add/sub sp brackets around call sites.  Returns true if the call frame is
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// included as part of the stack frame.
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool ARMFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  const MachineFrameInfo *FFI = MF.getFrameInfo();
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  unsigned CFSize = FFI->getMaxCallFrameSize();
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // It's not always a good idea to include the call frame as part of the
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // stack frame. ARM (especially Thumb) has small immediate offset to
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // address the stack frame. So a large call frame can cause poor codegen
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // and may even makes it impossible to scavenge a register.
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  if (CFSize >= ((1 << 12) - 1) / 2)  // Half of imm12
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return false;
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  return !MF.getFrameInfo()->hasVarSizedObjects();
73b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org}
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// canSimplifyCallFramePseudos - If there is a reserved call frame, the
76f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com/// call frame pseudos can be simplified.  Unlike most targets, having a FP
77f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com/// is not sufficient here since we still may reference some objects via SP
78f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com/// even when FP is available in Thumb2 mode.
79f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.combool
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comARMFrameLowering::canSimplifyCallFramePseudos(const MachineFunction &MF) const {
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  return hasReservedCallFrame(MF) || MF.getFrameInfo()->hasVarSizedObjects();
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
84b54455e440e66e0b1c30954d226226f49aac26d6reed@google.comstatic bool isCalleeSavedRegister(unsigned Reg, const uint16_t *CSRegs) {
85b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com  for (unsigned i = 0; CSRegs[i]; ++i)
86b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    if (Reg == CSRegs[i])
87b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com      return true;
88f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com  return false;
89f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com}
90f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com
91f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.comstatic bool isCSRestore(MachineInstr *MI,
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        const ARMBaseInstrInfo &TII,
9304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com                        const uint16_t *CSRegs) {
9404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  // Integer spill area is handled with "pop".
9504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  if (MI->getOpcode() == ARM::LDMIA_RET ||
9604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com      MI->getOpcode() == ARM::t2LDMIA_RET ||
9704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com      MI->getOpcode() == ARM::LDMIA_UPD ||
9804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com      MI->getOpcode() == ARM::t2LDMIA_UPD ||
9904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com      MI->getOpcode() == ARM::VLDMDIA_UPD) {
100b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    // The first two operands are predicates. The last two are
101b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    // imp-def and imp-use of SP. Check everything in between.
102b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    for (int i = 5, e = MI->getNumOperands(); i != e; ++i)
103b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com      if (!isCalleeSavedRegister(MI->getOperand(i).getReg(), CSRegs))
104b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com        return false;
105b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    return true;
106b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com  }
107b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com  if ((MI->getOpcode() == ARM::LDR_POST_IMM ||
108b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com       MI->getOpcode() == ARM::LDR_POST_REG ||
109b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com       MI->getOpcode() == ARM::t2LDR_POST) &&
110b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com      isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs) &&
111b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com      MI->getOperand(1).getReg() == ARM::SP)
112b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    return true;
113b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com
114b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com  return false;
115b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com}
11604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
117b54455e440e66e0b1c30954d226226f49aac26d6reed@google.comstatic void
11804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.comemitSPUpdate(bool isARM,
11904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com             MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
12004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com             DebugLoc dl, const ARMBaseInstrInfo &TII,
12104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com             int NumBytes, unsigned MIFlags = MachineInstr::NoFlags) {
12204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  if (isARM)
123b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
124b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com                            ARMCC::AL, 0, TII, MIFlags);
125b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com  else
126b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
12704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com                           ARMCC::AL, 0, TII, MIFlags);
12804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com}
12904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
13004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.comvoid ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
13104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  MachineBasicBlock &MBB = MF.front();
13204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  MachineBasicBlock::iterator MBBI = MBB.begin();
13304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  MachineFrameInfo  *MFI = MF.getFrameInfo();
134b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
135b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com  const ARMBaseRegisterInfo *RegInfo =
13604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    static_cast<const ARMBaseRegisterInfo*>(MF.getTarget().getRegisterInfo());
137b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com  const ARMBaseInstrInfo &TII =
138b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    *static_cast<const ARMBaseInstrInfo*>(MF.getTarget().getInstrInfo());
13904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  assert(!AFI->isThumb1OnlyFunction() &&
14004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com         "This emitPrologue does not support Thumb1!");
1416b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com  bool isARM = !AFI->isThumbFunction();
14204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
1436b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com  unsigned NumBytes = MFI->getStackSize();
14404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
14504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
14604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  unsigned FramePtr = RegInfo->getFrameRegister(MF);
14704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
14804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  // Determine the sizes of each callee-save spill areas and record which frame
14904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  // belongs to which callee-save spill areas.
15004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
15104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  int FramePtrSpillFI = 0;
15204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  int D8SpillFI = 0;
15304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
15404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  // Allocate the vararg register save area. This is not counted in NumBytes.
15504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com  if (VARegSaveSize)
15604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    emitSPUpdate(isARM, MBB, MBBI, dl, TII, -VARegSaveSize,
15704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com                 MachineInstr::FrameSetup);
15804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
1596b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com  if (!AFI->hasStackFrame()) {
160f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com    if (NumBytes != 0)
16104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com      emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes,
162f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com                   MachineInstr::FrameSetup);
1636b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    return;
1646aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com  }
1656aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
1666aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
1676aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    unsigned Reg = CSI[i].getReg();
1686aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    int FI = CSI[i].getFrameIdx();
1696aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    switch (Reg) {
1706aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    case ARM::R4:
1716aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    case ARM::R5:
1726aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    case ARM::R6:
1736aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    case ARM::R7:
1746aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    case ARM::LR:
1756aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com      if (Reg == FramePtr)
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        FramePtrSpillFI = FI;
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      AFI->addGPRCalleeSavedArea1Frame(FI);
1786b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com      GPRCS1Size += 4;
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      break;
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    case ARM::R8:
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    case ARM::R9:
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    case ARM::R10:
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    case ARM::R11:
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (Reg == FramePtr)
1856b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        FramePtrSpillFI = FI;
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (STI.isTargetIOS()) {
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        AFI->addGPRCalleeSavedArea2Frame(FI);
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        GPRCS2Size += 4;
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      } else {
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        AFI->addGPRCalleeSavedArea1Frame(FI);
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        GPRCS1Size += 4;
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      }
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      break;
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    default:
1954da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org      // This is a DPR. Exclude the aligned DPRCS2 spills.
1964da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org      if (Reg == ARM::D8)
1974da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org        D8SpillFI = FI;
1984da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org      if (Reg < ARM::D8 || Reg >= ARM::D8 + AFI->getNumAlignedDPRCS2Regs()) {
1994da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org        AFI->addDPRCalleeSavedAreaFrame(FI);
20094fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com        DPRCSSize += 8;
2014da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org      }
2024da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    }
2034da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org  }
2044da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
2054da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org  // Move past area 1.
2064da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org  if (GPRCS1Size > 0) MBBI++;
2074da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
2084da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org  // Set FP to point to the stack slot that contains the previous FP.
20994fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com  // For iOS, FP is R7, which has now been stored in spill area 1.
21094fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com  // Otherwise, if this is not iOS, all the callee-saved registers go
2114da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org  // into spill area 1, including the FP in R11.  In either case, it is
2124da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org  // now safe to emit this assignment.
2134da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org  bool HasFP = hasFP(MF);
2144da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org  if (HasFP) {
2154da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : ARM::t2ADDri;
2164da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    MachineInstrBuilder MIB =
2174da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org      BuildMI(MBB, MBBI, dl, TII.get(ADDriOpc), FramePtr)
2184da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org      .addFrameIndex(FramePtrSpillFI).addImm(0)
21994fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com      .setMIFlag(MachineInstr::FrameSetup);
22094fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com    AddDefaultCC(AddDefaultPred(MIB));
22194fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com  }
2224da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
2234da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org  // Move past area 2.
2247e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com  if (GPRCS2Size > 0) MBBI++;
2257e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
2267e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com  // Determine starting offsets of spill areas.
2277e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com  unsigned DPRCSOffset  = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
2287e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com  unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
2297e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com  unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
2307e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com  if (HasFP)
2317e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) +
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                NumBytes);
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // Move past area 3.
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  if (DPRCSSize > 0) {
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    MBBI++;
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // Since vpush register list cannot have gaps, there may be multiple vpush
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // instructions in the prologue.
242d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com    while (MBBI->getOpcode() == ARM::VSTMDDB_UPD)
243d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com      MBBI++;
244d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com  }
245d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com
246d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com  // Move past the aligned DPRCS2 area.
247d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com  if (AFI->getNumAlignedDPRCS2Regs() > 0) {
248d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com    MBBI = skipAlignedDPRCS2Spills(MBBI, AFI->getNumAlignedDPRCS2Regs());
249d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com    // The code inserted by emitAlignedDPRCS2Spills realigns the stack, and
250d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com    // leaves the stack pointer pointing to the DPRCS2 area.
251d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com    //
252d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com    // Adjust NumBytes to represent the stack slots below the DPRCS2 area.
253d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com    NumBytes += MFI->getObjectOffset(D8SpillFI);
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  } else
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    NumBytes = DPRCSOffset;
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  if (NumBytes) {
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // Adjust SP after all the callee-save spills.
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes,
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                 MachineInstr::FrameSetup);
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (HasFP && isARM)
262df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com      // Restore from fp only in ARM mode: e.g. sub sp, r7, #24
263df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com      // Note it's not safe to do this in Thumb2 mode because it would have
264df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com      // taken two instructions:
265df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com      // mov sp, r7
266df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com      // sub sp, #24
267df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com      // If an interrupt is taken between the two instructions, then sp is in
268df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com      // an inconsistent state (pointing to the middle of callee-saved area).
269df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com      // The interrupt handler can end up clobbering the registers.
270df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com      AFI->setShouldRestoreSPFromFP(true);
271df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com  }
272df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com
273df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com  if (STI.isTargetELF() && hasFP(MF))
274df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
275df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com                             AFI->getFramePtrSpillOffset());
276df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com
2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
280d252db03d9650013b545ef9781fe993c07f8f314reed@android.com
281d252db03d9650013b545ef9781fe993c07f8f314reed@android.com  // If we need dynamic stack realignment, do it here. Be paranoid and make
282d252db03d9650013b545ef9781fe993c07f8f314reed@android.com  // sure if we also have VLAs, we have a base pointer for frame access.
283d252db03d9650013b545ef9781fe993c07f8f314reed@android.com  // If aligned NEON registers were spilled, the stack has already been
284d252db03d9650013b545ef9781fe993c07f8f314reed@android.com  // realigned.
285d252db03d9650013b545ef9781fe993c07f8f314reed@android.com  if (!AFI->getNumAlignedDPRCS2Regs() && RegInfo->needsStackRealignment(MF)) {
286d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    unsigned MaxAlign = MFI->getMaxAlignment();
287d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    assert (!AFI->isThumb1OnlyFunction());
288d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    if (!AFI->isThumbFunction()) {
289d252db03d9650013b545ef9781fe993c07f8f314reed@android.com      // Emit bic sp, sp, MaxAlign
290d252db03d9650013b545ef9781fe993c07f8f314reed@android.com      AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl,
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                          TII.get(ARM::BICri), ARM::SP)
2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                  .addReg(ARM::SP, RegState::Kill)
293d252db03d9650013b545ef9781fe993c07f8f314reed@android.com                                  .addImm(MaxAlign-1)));
2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // We cannot use sp as source/dest register here, thus we're emitting the
296d252db03d9650013b545ef9781fe993c07f8f314reed@android.com      // following sequence:
297d252db03d9650013b545ef9781fe993c07f8f314reed@android.com      // mov r4, sp
298d252db03d9650013b545ef9781fe993c07f8f314reed@android.com      // bic r4, r4, MaxAlign
299d252db03d9650013b545ef9781fe993c07f8f314reed@android.com      // mov sp, r4
300d252db03d9650013b545ef9781fe993c07f8f314reed@android.com      // FIXME: It will be better just to find spare register here.
3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::R4)
3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        .addReg(ARM::SP, RegState::Kill));
3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl,
3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                          TII.get(ARM::t2BICri), ARM::R4)
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                  .addReg(ARM::R4, RegState::Kill)
3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                  .addImm(MaxAlign-1)));
3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::SP)
3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        .addReg(ARM::R4, RegState::Kill));
3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    AFI->setShouldRestoreSPFromFP(true);
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // If we need a base pointer, set it up here. It's whatever the value
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // of the stack pointer is at this point. Any variable size objects
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // will be allocated after this, so we can still use the base pointer
3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // to reference locals.
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // FIXME: Clarify FrameSetup flags here.
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  if (RegInfo->hasBasePointer(MF)) {
3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (isARM)
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      BuildMI(MBB, MBBI, dl,
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com              TII.get(ARM::MOVr), RegInfo->getBaseRegister())
3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        .addReg(ARM::SP)
3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    else
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                             RegInfo->getBaseRegister())
3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        .addReg(ARM::SP));
3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // If the frame has variable sized objects then the epilogue must restore
3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // the sp from fp. We can assume there's an FP here since hasFP already
3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // checks for hasVarSizedObjects.
3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  if (MFI->hasVarSizedObjects())
3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    AFI->setShouldRestoreSPFromFP(true);
3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid ARMFrameLowering::emitEpilogue(MachineFunction &MF,
3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    MachineBasicBlock &MBB) const {
3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  assert(MBBI->isReturn() && "Can only insert epilog into returning blocks");
3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  unsigned RetOpcode = MBBI->getOpcode();
3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  DebugLoc dl = MBBI->getDebugLoc();
3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  MachineFrameInfo *MFI = MF.getFrameInfo();
3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  const ARMBaseInstrInfo &TII =
3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *static_cast<const ARMBaseInstrInfo*>(MF.getTarget().getInstrInfo());
3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  assert(!AFI->isThumb1OnlyFunction() &&
3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com         "This emitEpilogue does not support Thumb1!");
3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  bool isARM = !AFI->isThumbFunction();
3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  int NumBytes = (int)MFI->getStackSize();
3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  unsigned FramePtr = RegInfo->getFrameRegister(MF);
3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  if (!AFI->hasStackFrame()) {
3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (NumBytes != 0)
3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  } else {
3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // Unwind MBBI to point to first LDR / VLDRD.
3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs();
3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (MBBI != MBB.begin()) {
3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      do
3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        --MBBI;
3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      while (MBBI != MBB.begin() && isCSRestore(MBBI, TII, CSRegs));
3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (!isCSRestore(MBBI, TII, CSRegs))
3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        ++MBBI;
3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // Move SP to start of FP callee save spill area.
3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                 AFI->getGPRCalleeSavedArea2Size() +
3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                 AFI->getDPRCalleeSavedAreaSize());
3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // Reset SP based on frame pointer only if the stack frame extends beyond
3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // frame pointer stack slot or target is ELF and the function has FP.
3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (AFI->shouldRestoreSPFromFP()) {
3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (NumBytes) {
3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (isARM)
3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, FramePtr, -NumBytes,
3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                  ARMCC::AL, 0, TII);
3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        else {
3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          // It's not possible to restore SP from FP in a single instruction.
3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          // For iOS, this looks like:
3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          // mov sp, r7
3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          // sub sp, #24
3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          // This is bad, if an interrupt is taken after the mov, sp is in an
3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          // inconsistent state.
3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          // Use the first callee-saved register as a scratch register.
3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          assert(MF.getRegInfo().isPhysRegUsed(ARM::R4) &&
3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                 "No scratch register to restore SP from FP!");
3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes,
3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                 ARMCC::AL, 0, TII);
3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),
3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                 ARM::SP)
3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            .addReg(ARM::R4));
3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      } else {
4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // Thumb2 or ARM.
4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (isARM)
4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP)
4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            .addReg(FramePtr).addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        else
4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),
4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                 ARM::SP)
4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            .addReg(FramePtr));
4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      }
4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else if (NumBytes)
4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // Increment past our save areas.
4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (AFI->getDPRCalleeSavedAreaSize()) {
4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      MBBI++;
4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // Since vpop register list cannot have gaps, there may be multiple vpop
4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // instructions in the epilogue.
4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      while (MBBI->getOpcode() == ARM::VLDMDIA_UPD)
4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        MBBI++;
4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (AFI->getGPRCalleeSavedArea2Size()) MBBI++;
4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (AFI->getGPRCalleeSavedArea1Size()) MBBI++;
4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  if (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNdiND ||
4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      RetOpcode == ARM::TCRETURNri || RetOpcode == ARM::TCRETURNriND) {
4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // Tail call return: adjust the stack pointer and jump to callee.
4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    MBBI = MBB.getLastNonDebugInstr();
4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    MachineOperand &JumpTarget = MBBI->getOperand(0);
4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // Jump to label or value in register.
4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNdiND) {
4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      unsigned TCOpcode = (RetOpcode == ARM::TCRETURNdi)
4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        ? (STI.isThumb() ? ARM::tTAILJMPd : ARM::TAILJMPd)
4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : (STI.isThumb() ? ARM::tTAILJMPdND : ARM::TAILJMPdND);
4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(TCOpcode));
4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (JumpTarget.isGlobal())
4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                             JumpTarget.getTargetFlags());
4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      else {
4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        assert(JumpTarget.isSymbol());
4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        MIB.addExternalSymbol(JumpTarget.getSymbolName(),
4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                              JumpTarget.getTargetFlags());
4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      }
4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // Add the default predicate in Thumb mode.
4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (STI.isThumb()) MIB.addImm(ARMCC::AL).addReg(0);
4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else if (RetOpcode == ARM::TCRETURNri) {
4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      BuildMI(MBB, MBBI, dl,
4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com              TII.get(STI.isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr)).
4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        addReg(JumpTarget.getReg(), RegState::Kill);
4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else if (RetOpcode == ARM::TCRETURNriND) {
4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      BuildMI(MBB, MBBI, dl,
4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com              TII.get(STI.isThumb() ? ARM::tTAILJMPrND : ARM::TAILJMPrND)).
4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        addReg(JumpTarget.getReg(), RegState::Kill);
4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    MachineInstr *NewMI = prior(MBBI);
4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (unsigned i = 1, e = MBBI->getNumOperands(); i != e; ++i)
4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      NewMI->addOperand(MBBI->getOperand(i));
4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // Delete the pseudo instruction TCRETURN.
4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    MBB.erase(MBBI);
4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    MBBI = NewMI;
4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  if (VARegSaveSize)
4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    emitSPUpdate(isARM, MBB, MBBI, dl, TII, VARegSaveSize);
4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// getFrameIndexReference - Provide a base+offset reference to an FI slot for
4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// debug info.  It's the same as what we use for resolving the code-gen
4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// references for now.  FIXME: This can go wrong when references are
4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// SP-relative and simple call frames aren't used.
4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint
4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comARMFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                         unsigned &FrameReg) const {
4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  return ResolveFrameIndexReference(MF, FI, FrameReg, 0);
4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint
4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comARMFrameLowering::ResolveFrameIndexReference(const MachineFunction &MF,
4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                             int FI, unsigned &FrameReg,
4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                             int SPAdj) const {
4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  const MachineFrameInfo *MFI = MF.getFrameInfo();
4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  const ARMBaseRegisterInfo *RegInfo =
4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static_cast<const ARMBaseRegisterInfo*>(MF.getTarget().getRegisterInfo());
4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  int Offset = MFI->getObjectOffset(FI) + MFI->getStackSize();
4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  int FPOffset = Offset - AFI->getFramePtrSpillOffset();
49169a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com  bool isFixed = MFI->isFixedObjectIndex(FI);
49269a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com
49369a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com  FrameReg = ARM::SP;
49469a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com  Offset += SPAdj;
49569a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com  if (AFI->isGPRCalleeSavedArea1Frame(FI))
49669a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com    return Offset - AFI->getGPRCalleeSavedArea1Offset();
49769a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com  else if (AFI->isGPRCalleeSavedArea2Frame(FI))
49869a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com    return Offset - AFI->getGPRCalleeSavedArea2Offset();
49969a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com  else if (AFI->isDPRCalleeSavedAreaFrame(FI))
50069a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com    return Offset - AFI->getDPRCalleeSavedAreaOffset();
50169a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com
50269a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com  // SP can move around if there are allocas.  We may also lose track of SP
50369a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com  // when emergency spilling inside a non-reserved call frame setup.
50469a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com  bool hasMovingSP = MFI->hasVarSizedObjects() || !hasReservedCallFrame(MF);
50569a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com
50669a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com  // When dynamically realigning the stack, use the frame pointer for
50769a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com  // parameters, and the stack/base pointer for locals.
50869a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com  if (RegInfo->needsStackRealignment(MF)) {
5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    assert (hasFP(MF) && "dynamic stack realignment without a FP!");
5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (isFixed) {
5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      FrameReg = RegInfo->getFrameRegister(MF);
5128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      Offset = FPOffset;
5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else if (hasMovingSP) {
5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      assert(RegInfo->hasBasePointer(MF) &&
5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com             "VLAs and dynamic stack alignment, but missing base pointer!");
5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      FrameReg = RegInfo->getBaseRegister();
5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return Offset;
5198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // If there is a frame pointer, use it when we can.
5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  if (hasFP(MF) && AFI->hasStackFrame()) {
5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // Use frame pointer to reference fixed objects. Use it for locals if
5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // there are VLAs (and thus the SP isn't reliable as a base).
5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (isFixed || (hasMovingSP && !RegInfo->hasBasePointer(MF))) {
5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      FrameReg = RegInfo->getFrameRegister(MF);
5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      return FPOffset;
5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else if (hasMovingSP) {
5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      assert(RegInfo->hasBasePointer(MF) && "missing base pointer!");
5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (AFI->isThumb2Function()) {
5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // Try to use the frame pointer if we can, else use the base pointer
5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // since it's available. This is handy for the emergency spill slot, in
5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // particular.
5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (FPOffset >= -255 && FPOffset < 0) {
5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          FrameReg = RegInfo->getFrameRegister(MF);
5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          return FPOffset;
5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      }
5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else if (AFI->isThumb2Function()) {
5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // Use  add <rd>, sp, #<imm8>
5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      //      ldr <rd>, [sp, #<imm8>]
5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // if at all possible to save space.
5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (Offset >= 0 && (Offset & 3) == 0 && Offset <= 1020)
5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return Offset;
5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // In Thumb2 mode, the negative offset is very limited. Try to avoid
5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // out of range references. ldr <rt>,[<rn>, #-<imm8>]
5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (FPOffset >= -255 && FPOffset < 0) {
5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        FrameReg = RegInfo->getFrameRegister(MF);
5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return FPOffset;
5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      }
5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else if (Offset > (FPOffset < 0 ? -FPOffset : FPOffset)) {
5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // Otherwise, use SP or FP, whichever is closer to the stack slot.
5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      FrameReg = RegInfo->getFrameRegister(MF);
5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      return FPOffset;
5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // Use the base pointer if we have one.
5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  if (RegInfo->hasBasePointer(MF))
5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    FrameReg = RegInfo->getBaseRegister();
5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  return Offset;
5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint ARMFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                          int FI) const {
5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  unsigned FrameReg;
5668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  return getFrameIndexReference(MF, FI, FrameReg);
5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
5708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    MachineBasicBlock::iterator MI,
5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    const std::vector<CalleeSavedInfo> &CSI,
5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    unsigned StmOpc, unsigned StrOpc,
5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    bool NoGap,
5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    bool(*Func)(unsigned, bool),
5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    unsigned NumAlignedDPRCS2Regs,
5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    unsigned MIFlags) const {
577744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com  MachineFunction &MF = *MBB.getParent();
578744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
579744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com
580744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com  DebugLoc DL;
581744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com  if (MI != MBB.end()) DL = MI->getDebugLoc();
582744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com
583744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com  SmallVector<std::pair<unsigned,bool>, 4> Regs;
584744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com  unsigned i = CSI.size();
585744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com  while (i != 0) {
586744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    unsigned LastReg = 0;
587744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    for (; i != 0; --i) {
588744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com      unsigned Reg = CSI[i-1].getReg();
589744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com      if (!(Func)(Reg, STI.isTargetIOS())) continue;
5908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // D-registers in the aligned area DPRCS2 are NOT spilled here.
5928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
5938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        continue;
5948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
59563d73749fbe36491403ea521005fd298dc70a94creed@google.com      // Add the callee-saved register as live-in unless it's LR and
5968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // @llvm.returnaddress is called. If LR is returned for
5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // @llvm.returnaddress then it's already added to the function and
5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // entry block live-in sets.
5998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      bool isKill = true;
6008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (Reg == ARM::LR) {
6018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (MF.getFrameInfo()->isReturnAddressTaken() &&
6028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            MF.getRegInfo().isLiveIn(Reg))
6038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          isKill = false;
6048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      }
6058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (isKill)
6078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        MBB.addLiveIn(Reg);
6088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // If NoGap is true, push consecutive registers and then leave the rest
61063d73749fbe36491403ea521005fd298dc70a94creed@google.com      // for other instructions. e.g.
61163d73749fbe36491403ea521005fd298dc70a94creed@google.com      // vpush {d8, d10, d11} -> vpush {d8}, vpush {d10, d11}
61263d73749fbe36491403ea521005fd298dc70a94creed@google.com      if (NoGap && LastReg && LastReg != Reg-1)
61363d73749fbe36491403ea521005fd298dc70a94creed@google.com        break;
61463d73749fbe36491403ea521005fd298dc70a94creed@google.com      LastReg = Reg;
6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      Regs.push_back(std::make_pair(Reg, isKill));
6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (Regs.empty())
6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      continue;
6208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (Regs.size() > 1 || StrOpc== 0) {
6218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      MachineInstrBuilder MIB =
6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(StmOpc), ARM::SP)
6238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                       .addReg(ARM::SP).setMIFlags(MIFlags));
6248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      for (unsigned i = 0, e = Regs.size(); i < e; ++i)
6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        MIB.addReg(Regs[i].first, getKillRegState(Regs[i].second));
6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else if (Regs.size() == 1) {
6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc),
6288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                        ARM::SP)
6298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        .addReg(Regs[0].first, getKillRegState(Regs[0].second))
6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        .addReg(ARM::SP).setMIFlags(MIFlags)
6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        .addImm(-4);
6328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      AddDefaultPred(MIB);
6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Regs.clear();
6358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
6368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                   MachineBasicBlock::iterator MI,
6408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                   const std::vector<CalleeSavedInfo> &CSI,
6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                   unsigned LdmOpc, unsigned LdrOpc,
6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                   bool isVarArg, bool NoGap,
6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                   bool(*Func)(unsigned, bool),
6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                   unsigned NumAlignedDPRCS2Regs) const {
6458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  MachineFunction &MF = *MBB.getParent();
6468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  DebugLoc DL = MI->getDebugLoc();
649294dd7b3d7b55ba38881cd4cabb6636abda23eb9reed@google.com  unsigned RetOpcode = MI->getOpcode();
650294dd7b3d7b55ba38881cd4cabb6636abda23eb9reed@google.com  bool isTailCall = (RetOpcode == ARM::TCRETURNdi ||
6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                     RetOpcode == ARM::TCRETURNdiND ||
6528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                     RetOpcode == ARM::TCRETURNri ||
6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                     RetOpcode == ARM::TCRETURNriND);
654294dd7b3d7b55ba38881cd4cabb6636abda23eb9reed@google.com
6558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  SmallVector<unsigned, 4> Regs;
6568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  unsigned i = CSI.size();
6578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  while (i != 0) {
6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned LastReg = 0;
6598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool DeleteRet = false;
6608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (; i != 0; --i) {
6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      unsigned Reg = CSI[i-1].getReg();
6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (!(Func)(Reg, STI.isTargetIOS())) continue;
6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // The aligned reloads from area DPRCS2 are not inserted here.
6658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        continue;
6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (Reg == ARM::LR && !isTailCall && !isVarArg && STI.hasV5TOps()) {
6698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Reg = ARM::PC;
6708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
6718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // Fold the return instruction into the LDM.
6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        DeleteRet = true;
67310296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com      }
67410296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com
67510296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com      // If NoGap is true, pop consecutive registers and then leave the rest
67610296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com      // for other instructions. e.g.
67710296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com      // vpop {d8, d10, d11} -> vpop {d8}, vpop {d10, d11}
67810296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com      if (NoGap && LastReg && LastReg != Reg-1)
67910296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com        break;
68010296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com
68110296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com      LastReg = Reg;
68210296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com      Regs.push_back(Reg);
68310296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    }
68410296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com
68510296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    if (Regs.empty())
6868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      continue;
6878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (Regs.size() > 1 || LdrOpc == 0) {
6888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      MachineInstrBuilder MIB =
6898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(LdmOpc), ARM::SP)
6908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                       .addReg(ARM::SP));
691b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com      for (unsigned i = 0, e = Regs.size(); i < e; ++i)
6928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        MIB.addReg(Regs[i], getDefRegState(true));
6938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (DeleteRet) {
6948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        MIB->copyImplicitOps(&*MI);
6958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        MI->eraseFromParent();
6968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      }
69772785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org      MI = MIB;
69872785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org    } else if (Regs.size() == 1) {
69972785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org      // If we adjusted the reg to PC from LR above, switch it back here. We
70072785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org      // only do that for LDM.
70172785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org      if (Regs[0] == ARM::PC)
70272785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org        Regs[0] = ARM::LR;
7038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      MachineInstrBuilder MIB =
7047ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.org        BuildMI(MBB, MI, DL, TII.get(LdrOpc), Regs[0])
7058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com          .addReg(ARM::SP, RegState::Define)
70672785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org          .addReg(ARM::SP);
70772785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org      // ARM mode needs an extra reg0 here due to addrmode2. Will go away once
7088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      // that refactoring is complete (eventually).
7098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      if (LdrOpc == ARM::LDR_POST_REG || LdrOpc == ARM::LDR_POST_IMM) {
7108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        MIB.addReg(0);
7118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        MIB.addImm(ARM_AM::getAM2Opc(ARM_AM::add, 4, ARM_AM::no_shift));
7128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      } else
713b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org        MIB.addImm(4);
7148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      AddDefaultPred(MIB);
7154a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com    }
7164a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com    Regs.clear();
7178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
7188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7194a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com
7204a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com/// Emit aligned spill instructions for NumAlignedDPRCS2Regs D-registers
7214a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com/// starting from d8.  Also insert stack realignment code and leave the stack
7224a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com/// pointer pointing to the d8 spill slot.
7234a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.comstatic void emitAlignedDPRCS2Spills(MachineBasicBlock &MBB,
7244a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com                                    MachineBasicBlock::iterator MI,
7258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    unsigned NumAlignedDPRCS2Regs,
7268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    const std::vector<CalleeSavedInfo> &CSI,
7278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    const TargetRegisterInfo *TRI) {
7288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  MachineFunction &MF = *MBB.getParent();
7298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
730b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org  DebugLoc DL = MI->getDebugLoc();
7318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
7328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  MachineFrameInfo &MFI = *MF.getFrameInfo();
7338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // Mark the D-register spill slots as properly aligned.  Since MFI computes
735b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org  // stack slot layout backwards, this can actually mean that the d-reg stack
7368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // slot offsets can be wrong. The offset for d8 will always be correct.
7378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
7388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned DNum = CSI[i].getReg() - ARM::D8;
7398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (DNum >= 8)
7408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      continue;
7418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int FI = CSI[i].getFrameIdx();
7428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // The even-numbered registers will be 16-byte aligned, the odd-numbered
7438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // registers will be 8-byte aligned.
7448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    MFI.setObjectAlignment(FI, DNum % 2 ? 8 : 16);
7458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // The stack slot for D8 needs to be maximally aligned because this is
7478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // actually the point where we align the stack pointer.  MachineFrameInfo
7488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // computes all offsets relative to the incoming stack pointer which is a
7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // bit weird when realigning the stack.  Any extra padding for this
750b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org    // over-alignment is not realized because the code inserted below adjusts
7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // the stack pointer by numregs * 8 before aligning the stack pointer.
7529e25dbf589539dd44244bc2581590bd7591e17a2reed@google.com    if (DNum == 0)
7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com      MFI.setObjectAlignment(FI, MFI.getMaxAlignment());
7544da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org  }
7554a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com
7568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // Move the stack pointer to the d8 spill slot, and align it at the same
7578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // time. Leave the stack slot address in the scratch register r4.
7586630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  //
7596630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  //   sub r4, sp, #numregs * 8
7606630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  //   bic r4, r4, #align - 1
7616630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  //   mov sp, r4
7626630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  //
7636630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  bool isThumb = AFI->isThumbFunction();
7646630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  assert(!AFI->isThumb1OnlyFunction() && "Can't realign stack for thumb1");
7656630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  AFI->setShouldRestoreSPFromFP(true);
7666630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
7676630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  // sub r4, sp, #numregs * 8
7686630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  // The immediate is <= 64, so it doesn't need any special encoding.
7696630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  unsigned Opc = isThumb ? ARM::t2SUBri : ARM::SUBri;
7706630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  AddDefaultCC(AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(Opc), ARM::R4)
771f6d3c5aa5f93e4c3cc7a7aebf014e960cf837783bsalomon@google.com                              .addReg(ARM::SP)
7726630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                              .addImm(8 * NumAlignedDPRCS2Regs)));
7736630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
7746630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  // bic r4, r4, #align-1
7756630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  Opc = isThumb ? ARM::t2BICri : ARM::BICri;
7766630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  unsigned MaxAlign = MF.getFrameInfo()->getMaxAlignment();
7776630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  AddDefaultCC(AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(Opc), ARM::R4)
7786630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                              .addReg(ARM::R4, RegState::Kill)
7796630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                              .addImm(MaxAlign - 1)));
7806630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
7816630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  // mov sp, r4
7826630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  // The stack pointer must be adjusted before spilling anything, otherwise
7836630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org  // the stack slots could be clobbered by an interrupt handler.
7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // Leave r4 live, it is used below.
785e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com  Opc = isThumb ? ARM::tMOVr : ARM::MOVr;
7868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(Opc), ARM::SP)
78794e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com                            .addReg(ARM::R4);
78894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com  MIB = AddDefaultPred(MIB);
78994e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com  if (!isThumb)
79094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    AddDefaultCC(MIB);
79194e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com
79294e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com  // Now spill NumAlignedDPRCS2Regs registers starting from d8.
79394e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com  // r4 holds the stack slot address.
79494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com  unsigned NextReg = ARM::D8;
79594e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com
79694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com  // 16-byte aligned vst1.64 with 4 d-regs and address writeback.
7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // The writeback is only needed when emitting two vst1.64 instructions.
79856c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com  if (NumAlignedDPRCS2Regs >= 6) {
799f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com    unsigned SupReg = TRI->getMatchingSuperReg(NextReg, ARM::dsub_0,
800e63793a2c8d2871bf7d95195be7b93ff669688d7djsollen@google.com                                               ARM::QQPRRegisterClass);
801e63793a2c8d2871bf7d95195be7b93ff669688d7djsollen@google.com    MBB.addLiveIn(SupReg);
802f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com    AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(ARM::VST1d64Qwb_fixed),
803f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com                           ARM::R4)
8048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                   .addReg(ARM::R4, RegState::Kill).addImm(16)
8058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                   .addReg(NextReg)
8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                   .addReg(SupReg, RegState::ImplicitKill));
8078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    NextReg += 4;
8088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    NumAlignedDPRCS2Regs -= 4;
809d252db03d9650013b545ef9781fe993c07f8f314reed@android.com  }
810d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com
8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // We won't modify r4 beyond this point.  It currently points to the next
81210296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com  // register to be spilled.
81310296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com  unsigned R4BaseReg = NextReg;
814b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com
8156aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com  // 16-byte aligned vst1.64 with 4 d-regs, no writeback.
8166aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com  if (NumAlignedDPRCS2Regs >= 4) {
81756c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com    unsigned SupReg = TRI->getMatchingSuperReg(NextReg, ARM::dsub_0,
818f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com                                               ARM::QQPRRegisterClass);
819e63793a2c8d2871bf7d95195be7b93ff669688d7djsollen@google.com    MBB.addLiveIn(SupReg);
820f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com    AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(ARM::VST1d64Q))
8218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                   .addReg(ARM::R4).addImm(16).addReg(NextReg)
822d252db03d9650013b545ef9781fe993c07f8f314reed@android.com                   .addReg(SupReg, RegState::ImplicitKill));
823d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    NextReg += 4;
824d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    NumAlignedDPRCS2Regs -= 4;
8258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
8268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // 16-byte aligned vst1.64 with 2 d-regs.
8288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  if (NumAlignedDPRCS2Regs >= 2) {
8298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned SupReg = TRI->getMatchingSuperReg(NextReg, ARM::dsub_0,
8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                               ARM::QPRRegisterClass);
8318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    MBB.addLiveIn(SupReg);
8328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(ARM::VST1q64))
8338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                   .addReg(ARM::R4).addImm(16).addReg(SupReg));
8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    NextReg += 2;
8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    NumAlignedDPRCS2Regs -= 2;
8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  }
8378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  // Finally, use a vanilla vstr.64 for the odd last register.
8398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  if (NumAlignedDPRCS2Regs) {
840d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    MBB.addLiveIn(NextReg);
841d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    // vstr.64 uses addrmode5 which has an offset scale of 4.
842d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(ARM::VSTRD))
843d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com                   .addReg(NextReg)
844d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com                   .addReg(ARM::R4).addImm((NextReg-R4BaseReg)*2));
845d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com  }
846d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com
847d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com  // The last spill instruction inserted should kill the scratch register r4.
8486aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com  llvm::prior(MI)->addRegisterKilled(ARM::R4, TRI);
8496aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
8508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8516aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com/// Skip past the code inserted by emitAlignedDPRCS2Spills, and return an
8528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/// iterator to the following instruction.
8538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic MachineBasicBlock::iterator
8548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comskipAlignedDPRCS2Spills(MachineBasicBlock::iterator MI,
855                        unsigned NumAlignedDPRCS2Regs) {
856  //   sub r4, sp, #numregs * 8
857  //   bic r4, r4, #align - 1
858  //   mov sp, r4
859  ++MI; ++MI; ++MI;
860  assert(MI->mayStore() && "Expecting spill instruction");
861
862  // These switches all fall through.
863  switch(NumAlignedDPRCS2Regs) {
864  case 7:
865    ++MI;
866    assert(MI->mayStore() && "Expecting spill instruction");
867  default:
868    ++MI;
869    assert(MI->mayStore() && "Expecting spill instruction");
870  case 1:
871  case 2:
872  case 4:
873    assert(MI->killsRegister(ARM::R4) && "Missed kill flag");
874    ++MI;
875  }
876  return MI;
877}
878
879/// Emit aligned reload instructions for NumAlignedDPRCS2Regs D-registers
880/// starting from d8.  These instructions are assumed to execute while the
881/// stack is still aligned, unlike the code inserted by emitPopInst.
882static void emitAlignedDPRCS2Restores(MachineBasicBlock &MBB,
883                                      MachineBasicBlock::iterator MI,
884                                      unsigned NumAlignedDPRCS2Regs,
885                                      const std::vector<CalleeSavedInfo> &CSI,
886                                      const TargetRegisterInfo *TRI) {
887  MachineFunction &MF = *MBB.getParent();
888  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
889  DebugLoc DL = MI->getDebugLoc();
890  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
891
892  // Find the frame index assigned to d8.
893  int D8SpillFI = 0;
894  for (unsigned i = 0, e = CSI.size(); i != e; ++i)
895    if (CSI[i].getReg() == ARM::D8) {
896      D8SpillFI = CSI[i].getFrameIdx();
897      break;
898    }
899
900  // Materialize the address of the d8 spill slot into the scratch register r4.
901  // This can be fairly complicated if the stack frame is large, so just use
902  // the normal frame index elimination mechanism to do it.  This code runs as
903  // the initial part of the epilog where the stack and base pointers haven't
904  // been changed yet.
905  bool isThumb = AFI->isThumbFunction();
906  assert(!AFI->isThumb1OnlyFunction() && "Can't realign stack for thumb1");
907
908  unsigned Opc = isThumb ? ARM::t2ADDri : ARM::ADDri;
909  AddDefaultCC(AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(Opc), ARM::R4)
910                              .addFrameIndex(D8SpillFI).addImm(0)));
911
912  // Now restore NumAlignedDPRCS2Regs registers starting from d8.
913  unsigned NextReg = ARM::D8;
914
915  // 16-byte aligned vld1.64 with 4 d-regs and writeback.
916  if (NumAlignedDPRCS2Regs >= 6) {
917    unsigned SupReg = TRI->getMatchingSuperReg(NextReg, ARM::dsub_0,
918                                               ARM::QQPRRegisterClass);
919    AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(ARM::VLD1d64Qwb_fixed), NextReg)
920                   .addReg(ARM::R4, RegState::Define)
921                   .addReg(ARM::R4, RegState::Kill).addImm(16)
922                   .addReg(SupReg, RegState::ImplicitDefine));
923    NextReg += 4;
924    NumAlignedDPRCS2Regs -= 4;
925  }
926
927  // We won't modify r4 beyond this point.  It currently points to the next
928  // register to be spilled.
929  unsigned R4BaseReg = NextReg;
930
931  // 16-byte aligned vld1.64 with 4 d-regs, no writeback.
932  if (NumAlignedDPRCS2Regs >= 4) {
933    unsigned SupReg = TRI->getMatchingSuperReg(NextReg, ARM::dsub_0,
934                                               ARM::QQPRRegisterClass);
935    AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(ARM::VLD1d64Q), NextReg)
936                   .addReg(ARM::R4).addImm(16)
937                   .addReg(SupReg, RegState::ImplicitDefine));
938    NextReg += 4;
939    NumAlignedDPRCS2Regs -= 4;
940  }
941
942  // 16-byte aligned vld1.64 with 2 d-regs.
943  if (NumAlignedDPRCS2Regs >= 2) {
944    unsigned SupReg = TRI->getMatchingSuperReg(NextReg, ARM::dsub_0,
945                                               ARM::QPRRegisterClass);
946    AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(ARM::VLD1q64), SupReg)
947                   .addReg(ARM::R4).addImm(16));
948    NextReg += 2;
949    NumAlignedDPRCS2Regs -= 2;
950  }
951
952  // Finally, use a vanilla vldr.64 for the remaining odd register.
953  if (NumAlignedDPRCS2Regs)
954    AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(ARM::VLDRD), NextReg)
955                   .addReg(ARM::R4).addImm(2*(NextReg-R4BaseReg)));
956
957  // Last store kills r4.
958  llvm::prior(MI)->addRegisterKilled(ARM::R4, TRI);
959}
960
961bool ARMFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
962                                        MachineBasicBlock::iterator MI,
963                                        const std::vector<CalleeSavedInfo> &CSI,
964                                        const TargetRegisterInfo *TRI) const {
965  if (CSI.empty())
966    return false;
967
968  MachineFunction &MF = *MBB.getParent();
969  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
970
971  unsigned PushOpc = AFI->isThumbFunction() ? ARM::t2STMDB_UPD : ARM::STMDB_UPD;
972  unsigned PushOneOpc = AFI->isThumbFunction() ?
973    ARM::t2STR_PRE : ARM::STR_PRE_IMM;
974  unsigned FltOpc = ARM::VSTMDDB_UPD;
975  unsigned NumAlignedDPRCS2Regs = AFI->getNumAlignedDPRCS2Regs();
976  emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea1Register, 0,
977               MachineInstr::FrameSetup);
978  emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea2Register, 0,
979               MachineInstr::FrameSetup);
980  emitPushInst(MBB, MI, CSI, FltOpc, 0, true, &isARMArea3Register,
981               NumAlignedDPRCS2Regs, MachineInstr::FrameSetup);
982
983  // The code above does not insert spill code for the aligned DPRCS2 registers.
984  // The stack realignment code will be inserted between the push instructions
985  // and these spills.
986  if (NumAlignedDPRCS2Regs)
987    emitAlignedDPRCS2Spills(MBB, MI, NumAlignedDPRCS2Regs, CSI, TRI);
988
989  return true;
990}
991
992bool ARMFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
993                                        MachineBasicBlock::iterator MI,
994                                        const std::vector<CalleeSavedInfo> &CSI,
995                                        const TargetRegisterInfo *TRI) const {
996  if (CSI.empty())
997    return false;
998
999  MachineFunction &MF = *MBB.getParent();
1000  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1001  bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
1002  unsigned NumAlignedDPRCS2Regs = AFI->getNumAlignedDPRCS2Regs();
1003
1004  // The emitPopInst calls below do not insert reloads for the aligned DPRCS2
1005  // registers. Do that here instead.
1006  if (NumAlignedDPRCS2Regs)
1007    emitAlignedDPRCS2Restores(MBB, MI, NumAlignedDPRCS2Regs, CSI, TRI);
1008
1009  unsigned PopOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD;
1010  unsigned LdrOpc = AFI->isThumbFunction() ? ARM::t2LDR_POST :ARM::LDR_POST_IMM;
1011  unsigned FltOpc = ARM::VLDMDIA_UPD;
1012  emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, &isARMArea3Register,
1013              NumAlignedDPRCS2Regs);
1014  emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false,
1015              &isARMArea2Register, 0);
1016  emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false,
1017              &isARMArea1Register, 0);
1018
1019  return true;
1020}
1021
1022// FIXME: Make generic?
1023static unsigned GetFunctionSizeInBytes(const MachineFunction &MF,
1024                                       const ARMBaseInstrInfo &TII) {
1025  unsigned FnSize = 0;
1026  for (MachineFunction::const_iterator MBBI = MF.begin(), E = MF.end();
1027       MBBI != E; ++MBBI) {
1028    const MachineBasicBlock &MBB = *MBBI;
1029    for (MachineBasicBlock::const_iterator I = MBB.begin(),E = MBB.end();
1030         I != E; ++I)
1031      FnSize += TII.GetInstSizeInBytes(I);
1032  }
1033  return FnSize;
1034}
1035
1036/// estimateStackSize - Estimate and return the size of the frame.
1037/// FIXME: Make generic?
1038static unsigned estimateStackSize(MachineFunction &MF) {
1039  const MachineFrameInfo *MFI = MF.getFrameInfo();
1040  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
1041  const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
1042  unsigned MaxAlign = MFI->getMaxAlignment();
1043  int Offset = 0;
1044
1045  // This code is very, very similar to PEI::calculateFrameObjectOffsets().
1046  // It really should be refactored to share code. Until then, changes
1047  // should keep in mind that there's tight coupling between the two.
1048
1049  for (int i = MFI->getObjectIndexBegin(); i != 0; ++i) {
1050    int FixedOff = -MFI->getObjectOffset(i);
1051    if (FixedOff > Offset) Offset = FixedOff;
1052  }
1053  for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
1054    if (MFI->isDeadObjectIndex(i))
1055      continue;
1056    Offset += MFI->getObjectSize(i);
1057    unsigned Align = MFI->getObjectAlignment(i);
1058    // Adjust to alignment boundary
1059    Offset = (Offset+Align-1)/Align*Align;
1060
1061    MaxAlign = std::max(Align, MaxAlign);
1062  }
1063
1064  if (MFI->adjustsStack() && TFI->hasReservedCallFrame(MF))
1065    Offset += MFI->getMaxCallFrameSize();
1066
1067  // Round up the size to a multiple of the alignment.  If the function has
1068  // any calls or alloca's, align to the target's StackAlignment value to
1069  // ensure that the callee's frame or the alloca data is suitably aligned;
1070  // otherwise, for leaf functions, align to the TransientStackAlignment
1071  // value.
1072  unsigned StackAlign;
1073  if (MFI->adjustsStack() || MFI->hasVarSizedObjects() ||
1074      (RegInfo->needsStackRealignment(MF) && MFI->getObjectIndexEnd() != 0))
1075    StackAlign = TFI->getStackAlignment();
1076  else
1077    StackAlign = TFI->getTransientStackAlignment();
1078
1079  // If the frame pointer is eliminated, all frame offsets will be relative to
1080  // SP not FP. Align to MaxAlign so this works.
1081  StackAlign = std::max(StackAlign, MaxAlign);
1082  unsigned AlignMask = StackAlign - 1;
1083  Offset = (Offset + AlignMask) & ~uint64_t(AlignMask);
1084
1085  return (unsigned)Offset;
1086}
1087
1088/// estimateRSStackSizeLimit - Look at each instruction that references stack
1089/// frames and return the stack size limit beyond which some of these
1090/// instructions will require a scratch register during their expansion later.
1091// FIXME: Move to TII?
1092static unsigned estimateRSStackSizeLimit(MachineFunction &MF,
1093                                         const TargetFrameLowering *TFI) {
1094  const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1095  unsigned Limit = (1 << 12) - 1;
1096  for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
1097    for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
1098         I != E; ++I) {
1099      for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
1100        if (!I->getOperand(i).isFI()) continue;
1101
1102        // When using ADDri to get the address of a stack object, 255 is the
1103        // largest offset guaranteed to fit in the immediate offset.
1104        if (I->getOpcode() == ARM::ADDri) {
1105          Limit = std::min(Limit, (1U << 8) - 1);
1106          break;
1107        }
1108
1109        // Otherwise check the addressing mode.
1110        switch (I->getDesc().TSFlags & ARMII::AddrModeMask) {
1111        case ARMII::AddrMode3:
1112        case ARMII::AddrModeT2_i8:
1113          Limit = std::min(Limit, (1U << 8) - 1);
1114          break;
1115        case ARMII::AddrMode5:
1116        case ARMII::AddrModeT2_i8s4:
1117          Limit = std::min(Limit, ((1U << 8) - 1) * 4);
1118          break;
1119        case ARMII::AddrModeT2_i12:
1120          // i12 supports only positive offset so these will be converted to
1121          // i8 opcodes. See llvm::rewriteT2FrameIndex.
1122          if (TFI->hasFP(MF) && AFI->hasStackFrame())
1123            Limit = std::min(Limit, (1U << 8) - 1);
1124          break;
1125        case ARMII::AddrMode4:
1126        case ARMII::AddrMode6:
1127          // Addressing modes 4 & 6 (load/store) instructions can't encode an
1128          // immediate offset for stack references.
1129          return 0;
1130        default:
1131          break;
1132        }
1133        break; // At most one FI per instruction
1134      }
1135    }
1136  }
1137
1138  return Limit;
1139}
1140
1141// In functions that realign the stack, it can be an advantage to spill the
1142// callee-saved vector registers after realigning the stack. The vst1 and vld1
1143// instructions take alignment hints that can improve performance.
1144//
1145static void checkNumAlignedDPRCS2Regs(MachineFunction &MF) {
1146  MF.getInfo<ARMFunctionInfo>()->setNumAlignedDPRCS2Regs(0);
1147  if (!SpillAlignedNEONRegs)
1148    return;
1149
1150  // Naked functions don't spill callee-saved registers.
1151  if (MF.getFunction()->hasFnAttr(Attribute::Naked))
1152    return;
1153
1154  // We are planning to use NEON instructions vst1 / vld1.
1155  if (!MF.getTarget().getSubtarget<ARMSubtarget>().hasNEON())
1156    return;
1157
1158  // Don't bother if the default stack alignment is sufficiently high.
1159  if (MF.getTarget().getFrameLowering()->getStackAlignment() >= 8)
1160    return;
1161
1162  // Aligned spills require stack realignment.
1163  const ARMBaseRegisterInfo *RegInfo =
1164    static_cast<const ARMBaseRegisterInfo*>(MF.getTarget().getRegisterInfo());
1165  if (!RegInfo->canRealignStack(MF))
1166    return;
1167
1168  // We always spill contiguous d-registers starting from d8. Count how many
1169  // needs spilling.  The register allocator will almost always use the
1170  // callee-saved registers in order, but it can happen that there are holes in
1171  // the range.  Registers above the hole will be spilled to the standard DPRCS
1172  // area.
1173  MachineRegisterInfo &MRI = MF.getRegInfo();
1174  unsigned NumSpills = 0;
1175  for (; NumSpills < 8; ++NumSpills)
1176    if (!MRI.isPhysRegOrOverlapUsed(ARM::D8 + NumSpills))
1177      break;
1178
1179  // Don't do this for just one d-register. It's not worth it.
1180  if (NumSpills < 2)
1181    return;
1182
1183  // Spill the first NumSpills D-registers after realigning the stack.
1184  MF.getInfo<ARMFunctionInfo>()->setNumAlignedDPRCS2Regs(NumSpills);
1185
1186  // A scratch register is required for the vst1 / vld1 instructions.
1187  MF.getRegInfo().setPhysRegUsed(ARM::R4);
1188}
1189
1190void
1191ARMFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
1192                                                       RegScavenger *RS) const {
1193  // This tells PEI to spill the FP as if it is any other callee-save register
1194  // to take advantage the eliminateFrameIndex machinery. This also ensures it
1195  // is spilled in the order specified by getCalleeSavedRegs() to make it easier
1196  // to combine multiple loads / stores.
1197  bool CanEliminateFrame = true;
1198  bool CS1Spilled = false;
1199  bool LRSpilled = false;
1200  unsigned NumGPRSpills = 0;
1201  SmallVector<unsigned, 4> UnspilledCS1GPRs;
1202  SmallVector<unsigned, 4> UnspilledCS2GPRs;
1203  const ARMBaseRegisterInfo *RegInfo =
1204    static_cast<const ARMBaseRegisterInfo*>(MF.getTarget().getRegisterInfo());
1205  const ARMBaseInstrInfo &TII =
1206    *static_cast<const ARMBaseInstrInfo*>(MF.getTarget().getInstrInfo());
1207  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1208  MachineFrameInfo *MFI = MF.getFrameInfo();
1209  unsigned FramePtr = RegInfo->getFrameRegister(MF);
1210
1211  // Spill R4 if Thumb2 function requires stack realignment - it will be used as
1212  // scratch register. Also spill R4 if Thumb2 function has varsized objects,
1213  // since it's not always possible to restore sp from fp in a single
1214  // instruction.
1215  // FIXME: It will be better just to find spare register here.
1216  if (AFI->isThumb2Function() &&
1217      (MFI->hasVarSizedObjects() || RegInfo->needsStackRealignment(MF)))
1218    MF.getRegInfo().setPhysRegUsed(ARM::R4);
1219
1220  if (AFI->isThumb1OnlyFunction()) {
1221    // Spill LR if Thumb1 function uses variable length argument lists.
1222    if (AFI->getVarArgsRegSaveSize() > 0)
1223      MF.getRegInfo().setPhysRegUsed(ARM::LR);
1224
1225    // Spill R4 if Thumb1 epilogue has to restore SP from FP. We don't know
1226    // for sure what the stack size will be, but for this, an estimate is good
1227    // enough. If there anything changes it, it'll be a spill, which implies
1228    // we've used all the registers and so R4 is already used, so not marking
1229    // it here will be OK.
1230    // FIXME: It will be better just to find spare register here.
1231    unsigned StackSize = estimateStackSize(MF);
1232    if (MFI->hasVarSizedObjects() || StackSize > 508)
1233      MF.getRegInfo().setPhysRegUsed(ARM::R4);
1234  }
1235
1236  // See if we can spill vector registers to aligned stack.
1237  checkNumAlignedDPRCS2Regs(MF);
1238
1239  // Spill the BasePtr if it's used.
1240  if (RegInfo->hasBasePointer(MF))
1241    MF.getRegInfo().setPhysRegUsed(RegInfo->getBaseRegister());
1242
1243  // Don't spill FP if the frame can be eliminated. This is determined
1244  // by scanning the callee-save registers to see if any is used.
1245  const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs();
1246  for (unsigned i = 0; CSRegs[i]; ++i) {
1247    unsigned Reg = CSRegs[i];
1248    bool Spilled = false;
1249    if (MF.getRegInfo().isPhysRegOrOverlapUsed(Reg)) {
1250      Spilled = true;
1251      CanEliminateFrame = false;
1252    }
1253
1254    if (!ARM::GPRRegisterClass->contains(Reg))
1255      continue;
1256
1257    if (Spilled) {
1258      NumGPRSpills++;
1259
1260      if (!STI.isTargetIOS()) {
1261        if (Reg == ARM::LR)
1262          LRSpilled = true;
1263        CS1Spilled = true;
1264        continue;
1265      }
1266
1267      // Keep track if LR and any of R4, R5, R6, and R7 is spilled.
1268      switch (Reg) {
1269      case ARM::LR:
1270        LRSpilled = true;
1271        // Fallthrough
1272      case ARM::R4: case ARM::R5:
1273      case ARM::R6: case ARM::R7:
1274        CS1Spilled = true;
1275        break;
1276      default:
1277        break;
1278      }
1279    } else {
1280      if (!STI.isTargetIOS()) {
1281        UnspilledCS1GPRs.push_back(Reg);
1282        continue;
1283      }
1284
1285      switch (Reg) {
1286      case ARM::R4: case ARM::R5:
1287      case ARM::R6: case ARM::R7:
1288      case ARM::LR:
1289        UnspilledCS1GPRs.push_back(Reg);
1290        break;
1291      default:
1292        UnspilledCS2GPRs.push_back(Reg);
1293        break;
1294      }
1295    }
1296  }
1297
1298  bool ForceLRSpill = false;
1299  if (!LRSpilled && AFI->isThumb1OnlyFunction()) {
1300    unsigned FnSize = GetFunctionSizeInBytes(MF, TII);
1301    // Force LR to be spilled if the Thumb function size is > 2048. This enables
1302    // use of BL to implement far jump. If it turns out that it's not needed
1303    // then the branch fix up path will undo it.
1304    if (FnSize >= (1 << 11)) {
1305      CanEliminateFrame = false;
1306      ForceLRSpill = true;
1307    }
1308  }
1309
1310  // If any of the stack slot references may be out of range of an immediate
1311  // offset, make sure a register (or a spill slot) is available for the
1312  // register scavenger. Note that if we're indexing off the frame pointer, the
1313  // effective stack size is 4 bytes larger since the FP points to the stack
1314  // slot of the previous FP. Also, if we have variable sized objects in the
1315  // function, stack slot references will often be negative, and some of
1316  // our instructions are positive-offset only, so conservatively consider
1317  // that case to want a spill slot (or register) as well. Similarly, if
1318  // the function adjusts the stack pointer during execution and the
1319  // adjustments aren't already part of our stack size estimate, our offset
1320  // calculations may be off, so be conservative.
1321  // FIXME: We could add logic to be more precise about negative offsets
1322  //        and which instructions will need a scratch register for them. Is it
1323  //        worth the effort and added fragility?
1324  bool BigStack =
1325    (RS &&
1326     (estimateStackSize(MF) + ((hasFP(MF) && AFI->hasStackFrame()) ? 4:0) >=
1327      estimateRSStackSizeLimit(MF, this)))
1328    || MFI->hasVarSizedObjects()
1329    || (MFI->adjustsStack() && !canSimplifyCallFramePseudos(MF));
1330
1331  bool ExtraCSSpill = false;
1332  if (BigStack || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF)) {
1333    AFI->setHasStackFrame(true);
1334
1335    // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
1336    // Spill LR as well so we can fold BX_RET to the registers restore (LDM).
1337    if (!LRSpilled && CS1Spilled) {
1338      MF.getRegInfo().setPhysRegUsed(ARM::LR);
1339      NumGPRSpills++;
1340      UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(),
1341                                    UnspilledCS1GPRs.end(), (unsigned)ARM::LR));
1342      ForceLRSpill = false;
1343      ExtraCSSpill = true;
1344    }
1345
1346    if (hasFP(MF)) {
1347      MF.getRegInfo().setPhysRegUsed(FramePtr);
1348      NumGPRSpills++;
1349    }
1350
1351    // If stack and double are 8-byte aligned and we are spilling an odd number
1352    // of GPRs, spill one extra callee save GPR so we won't have to pad between
1353    // the integer and double callee save areas.
1354    unsigned TargetAlign = getStackAlignment();
1355    if (TargetAlign == 8 && (NumGPRSpills & 1)) {
1356      if (CS1Spilled && !UnspilledCS1GPRs.empty()) {
1357        for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) {
1358          unsigned Reg = UnspilledCS1GPRs[i];
1359          // Don't spill high register if the function is thumb1
1360          if (!AFI->isThumb1OnlyFunction() ||
1361              isARMLowRegister(Reg) || Reg == ARM::LR) {
1362            MF.getRegInfo().setPhysRegUsed(Reg);
1363            if (!RegInfo->isReservedReg(MF, Reg))
1364              ExtraCSSpill = true;
1365            break;
1366          }
1367        }
1368      } else if (!UnspilledCS2GPRs.empty() && !AFI->isThumb1OnlyFunction()) {
1369        unsigned Reg = UnspilledCS2GPRs.front();
1370        MF.getRegInfo().setPhysRegUsed(Reg);
1371        if (!RegInfo->isReservedReg(MF, Reg))
1372          ExtraCSSpill = true;
1373      }
1374    }
1375
1376    // Estimate if we might need to scavenge a register at some point in order
1377    // to materialize a stack offset. If so, either spill one additional
1378    // callee-saved register or reserve a special spill slot to facilitate
1379    // register scavenging. Thumb1 needs a spill slot for stack pointer
1380    // adjustments also, even when the frame itself is small.
1381    if (BigStack && !ExtraCSSpill) {
1382      // If any non-reserved CS register isn't spilled, just spill one or two
1383      // extra. That should take care of it!
1384      unsigned NumExtras = TargetAlign / 4;
1385      SmallVector<unsigned, 2> Extras;
1386      while (NumExtras && !UnspilledCS1GPRs.empty()) {
1387        unsigned Reg = UnspilledCS1GPRs.back();
1388        UnspilledCS1GPRs.pop_back();
1389        if (!RegInfo->isReservedReg(MF, Reg) &&
1390            (!AFI->isThumb1OnlyFunction() || isARMLowRegister(Reg) ||
1391             Reg == ARM::LR)) {
1392          Extras.push_back(Reg);
1393          NumExtras--;
1394        }
1395      }
1396      // For non-Thumb1 functions, also check for hi-reg CS registers
1397      if (!AFI->isThumb1OnlyFunction()) {
1398        while (NumExtras && !UnspilledCS2GPRs.empty()) {
1399          unsigned Reg = UnspilledCS2GPRs.back();
1400          UnspilledCS2GPRs.pop_back();
1401          if (!RegInfo->isReservedReg(MF, Reg)) {
1402            Extras.push_back(Reg);
1403            NumExtras--;
1404          }
1405        }
1406      }
1407      if (Extras.size() && NumExtras == 0) {
1408        for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
1409          MF.getRegInfo().setPhysRegUsed(Extras[i]);
1410        }
1411      } else if (!AFI->isThumb1OnlyFunction()) {
1412        // note: Thumb1 functions spill to R12, not the stack.  Reserve a slot
1413        // closest to SP or frame pointer.
1414        const TargetRegisterClass *RC = ARM::GPRRegisterClass;
1415        RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
1416                                                           RC->getAlignment(),
1417                                                           false));
1418      }
1419    }
1420  }
1421
1422  if (ForceLRSpill) {
1423    MF.getRegInfo().setPhysRegUsed(ARM::LR);
1424    AFI->setLRIsSpilledForFarJump(true);
1425  }
1426}
1427