ARMRegisterInfo.cpp revision c0f64ffab93d11fb27a3b8a0707b77400918a20e
17bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===- ARMRegisterInfo.cpp - ARM Register Information -----------*- C++ -*-===//
27bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
37bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//                     The LLVM Compiler Infrastructure
47bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
57bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file was developed by the "Instituto Nokia de Tecnologia" and
67bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// is distributed under the University of Illinois Open Source
77bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// License. See LICENSE.TXT for details.
87bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
97bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===//
107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file contains the ARM implementation of the MRegisterInfo class.
127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===//
147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARM.h"
167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMRegisterInfo.h"
177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineInstrBuilder.h"
187bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunction.h"
197bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFrameInfo.h"
207bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineLocation.h"
217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Type.h"
22b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola#include "llvm/Target/TargetFrameInfo.h"
23b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola#include "llvm/Target/TargetMachine.h"
247ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola#include "llvm/Target/TargetOptions.h"
25c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng#include "llvm/Target/TargetInstrInfo.h"
267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/STLExtras.h"
277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <iostream>
287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm;
297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
307ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola// hasFP - Return true if the specified function should have a dedicated frame
317ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola// pointer register.  This is true if the function has variable sized allocas or
327ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola// if frame pointer elimination is disabled.
337ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola//
347ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindolastatic bool hasFP(const MachineFunction &MF) {
357ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  const MachineFrameInfo *MFI = MF.getFrameInfo();
367ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  return NoFramePointerElim || MFI->hasVarSizedObjects();
377ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola}
387ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
39c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan ChengARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii)
40c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng  : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
41c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    TII(tii) {
427bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
437bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
457bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolastoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
467bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                    unsigned SrcReg, int FI,
477bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                    const TargetRegisterClass *RC) const {
487bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  assert (RC == ARM::IntRegsRegisterClass);
49c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng  BuildMI(MBB, I, TII.get(ARM::STR)).addReg(SrcReg).addFrameIndex(FI).addImm(0);
507bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
537bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                     unsigned DestReg, int FI,
557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                     const TargetRegisterClass *RC) const {
567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  assert (RC == ARM::IntRegsRegisterClass);
57c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng  BuildMI(MBB, I, TII.get(ARM::LDR), DestReg).addFrameIndex(FI).addImm(0);
587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     MachineBasicBlock::iterator I,
627bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     unsigned DestReg, unsigned SrcReg,
637bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     const TargetRegisterClass *RC) const {
64199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  assert(RC == ARM::IntRegsRegisterClass ||
65199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola         RC == ARM::FPRegsRegisterClass  ||
66199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola         RC == ARM::DFPRegsRegisterClass);
67199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola
68199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  if (RC == ARM::IntRegsRegisterClass)
69c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, I, TII.get(ARM::MOV), DestReg).addReg(SrcReg).addImm(0)
70199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola      .addImm(ARMShift::LSL);
71199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  else if (RC == ARM::FPRegsRegisterClass)
72c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, I, TII.get(ARM::FCPYS), DestReg).addReg(SrcReg);
73199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  else
74c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, I, TII.get(ARM::FCPYD), DestReg).addReg(SrcReg);
757bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
767bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
777bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaMachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
787bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                                   unsigned OpNum,
797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                                   int FI) const {
807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return NULL;
817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
827bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
830f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Chengconst unsigned* ARMRegisterInfo::getCalleeSaveRegs() const {
84ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  static const unsigned CalleeSaveRegs[] = {
85ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    ARM::R4,  ARM::R5, ARM::R6,  ARM::R7,
86ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    ARM::R8,  ARM::R9, ARM::R10, ARM::R11,
87ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    ARM::R14, 0
88ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  };
890f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng  return CalleeSaveRegs;
900f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng}
910f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng
920f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Chengconst TargetRegisterClass* const *
930f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan ChengARMRegisterInfo::getCalleeSaveRegClasses() const {
94ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  static const TargetRegisterClass * const CalleeSaveRegClasses[] = {
95ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass,
96ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass,
97ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    &ARM::IntRegsRegClass, 0
98ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  };
990f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng  return CalleeSaveRegClasses;
1000f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng}
1010f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng
1027bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
1037bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
1047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                              MachineBasicBlock::iterator I) const {
1057ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  if (hasFP(MF)) {
106b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola    MachineInstr *Old = I;
107b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola    unsigned Amount = Old->getOperand(0).getImmedValue();
108b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola    if (Amount != 0) {
109b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
110b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      Amount = (Amount+Align-1)/Align*Align;
111b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola
112b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      if (Old->getOpcode() == ARM::ADJCALLSTACKDOWN) {
113b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola        // sub sp, sp, amount
114c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng        BuildMI(MBB, I, TII.get(ARM::SUB), ARM::R13).addReg(ARM::R13).addImm(Amount)
115b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola          .addImm(0).addImm(ARMShift::LSL);
116b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      } else {
117b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola        // add sp, sp, amount
118b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola        assert(Old->getOpcode() == ARM::ADJCALLSTACKUP);
119c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng        BuildMI(MBB, I, TII.get(ARM::ADD), ARM::R13).addReg(ARM::R13).addImm(Amount)
120b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola          .addImm(0).addImm(ARMShift::LSL);
121b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      }
122b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola    }
1237ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  }
1247bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  MBB.erase(I);
1257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid
1287bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
12958421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineInstr &MI = *II;
13058421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineBasicBlock &MBB = *MI.getParent();
13158421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineFunction &MF = *MBB.getParent();
13258421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
1336e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola  assert (MI.getOpcode() == ARM::LDR ||
134f819a4999aedd00368c850c1707e7ed0d59b4aceRafael Espindola          MI.getOpcode() == ARM::STR ||
135f819a4999aedd00368c850c1707e7ed0d59b4aceRafael Espindola          MI.getOpcode() == ARM::ADD);
13658421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
137f819a4999aedd00368c850c1707e7ed0d59b4aceRafael Espindola  unsigned FrameIdx = 1;
138f819a4999aedd00368c850c1707e7ed0d59b4aceRafael Espindola  unsigned   OffIdx = 2;
13958421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
14058421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  int FrameIndex = MI.getOperand(FrameIdx).getFrameIndex();
14158421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
1420d479ecbb132e324da27b674fea5b232115fe964Rafael Espindola  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
1430d479ecbb132e324da27b674fea5b232115fe964Rafael Espindola               MI.getOperand(OffIdx).getImmedValue();
14458421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
14558421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  unsigned StackSize = MF.getFrameInfo()->getStackSize();
14658421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
14758421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  Offset += StackSize;
14858421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
149a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  assert (Offset >= 0);
1507ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  unsigned BaseRegister = hasFP(MF) ? ARM::R11 : ARM::R13;
151a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  if (Offset < 4096) {
152a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the FrameIndex with r13
1537ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola    MI.getOperand(FrameIdx).ChangeToRegister(BaseRegister, false);
154a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the ldr offset with Offset
155a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    MI.getOperand(OffIdx).ChangeToImmediate(Offset);
156a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  } else {
157a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Insert a set of r12 with the full address
158a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // r12 = r13 + offset
159a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    MachineBasicBlock *MBB2 = MI.getParent();
160c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(*MBB2, II, TII.get(ARM::ADD), ARM::R12).addReg(BaseRegister)
1617ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola      .addImm(Offset).addImm(0).addImm(ARMShift::LSL);
162a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola
163a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the FrameIndex with r12
16409e460662a8d7328da1b938d5581a6ef3740b51dChris Lattner    MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
165a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  }
1667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1687bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
1697bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaprocessFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
1707bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1717bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
172355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineBasicBlock &MBB = MF.front();
17344819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola  MachineBasicBlock::iterator MBBI = MBB.begin();
174355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineFrameInfo  *MFI = MF.getFrameInfo();
175355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  int           NumBytes = (int) MFI->getStackSize();
176355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
1777ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  bool HasFP = hasFP(MF);
1787ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
1791a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  if (MFI->hasCalls()) {
1801a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    // We reserve argument space for call sites in the function immediately on
1811a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    // entry to the current function.  This eliminates the need for add/sub
1821a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    // brackets around call sites.
1831a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    NumBytes += MFI->getMaxCallFrameSize();
1841a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  }
1851a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola
1867ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  if (HasFP)
1877ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola    // Add space for storing the FP
1887ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola    NumBytes += 4;
1897ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
1901b5076887e32f9a16a1f65f3ce9abf11c31abcd7Rafael Espindola  // Align to 8 bytes
1911b5076887e32f9a16a1f65f3ce9abf11c31abcd7Rafael Espindola  NumBytes = ((NumBytes + 7) / 8) * 8;
1921b5076887e32f9a16a1f65f3ce9abf11c31abcd7Rafael Espindola
1931a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  MFI->setStackSize(NumBytes);
1941a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola
1951a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  //sub sp, sp, #NumBytes
196c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng  BuildMI(MBB, MBBI, TII.get(ARM::SUB), ARM::R13).addReg(ARM::R13).addImm(NumBytes)
1973ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola	  .addImm(0).addImm(ARMShift::LSL);
1987ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
1997ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  if (HasFP) {
200c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(ARM::STR))
2016e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola      .addReg(ARM::R11).addReg(ARM::R13).addImm(0);
202c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(ARM::MOV), ARM::R11).addReg(ARM::R13).addImm(0).
2037ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola      addImm(ARMShift::LSL);
2047ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  }
2057bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2067bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2077bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
2087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola				   MachineBasicBlock &MBB) const {
209355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineBasicBlock::iterator MBBI = prior(MBB.end());
210355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  assert(MBBI->getOpcode() == ARM::bx &&
211355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola         "Can only insert epilog into returning blocks");
212355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
213355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineFrameInfo *MFI = MF.getFrameInfo();
214355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  int          NumBytes = (int) MFI->getStackSize();
215355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
2167ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  if (hasFP(MF)) {
217c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(ARM::MOV), ARM::R13).addReg(ARM::R11).addImm(0).
2187ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola      addImm(ARMShift::LSL);
219c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(ARM::LDR), ARM::R11).addReg(ARM::R13).addImm(0);
2207ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  }
2217ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
2221a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  //add sp, sp, #NumBytes
223c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng  BuildMI(MBB, MBBI, TII.get(ARM::ADD), ARM::R13).addReg(ARM::R13).addImm(NumBytes)
2243ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola	  .addImm(0).addImm(ARMShift::LSL);
2257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolaunsigned ARMRegisterInfo::getRARegister() const {
2287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return ARM::R14;
2297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolaunsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const {
2327ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  return hasFP(MF) ? ARM::R11 : ARM::R13;
2337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2347bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2357bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenRegisterInfo.inc"
2367bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
237