ARMRegisterInfo.cpp revision 15f17a7c4746b8533aabf7c78bde82503ad9fc9f
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 Espindolausing namespace llvm;
287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
297ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola// hasFP - Return true if the specified function should have a dedicated frame
307ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola// pointer register.  This is true if the function has variable sized allocas or
317ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola// if frame pointer elimination is disabled.
327ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola//
337ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindolastatic bool hasFP(const MachineFunction &MF) {
347ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  const MachineFrameInfo *MFI = MF.getFrameInfo();
357ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  return NoFramePointerElim || MFI->hasVarSizedObjects();
367ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola}
377ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
3815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola#define ROTATE32L(x, n) (((x) << (n)) | ((x)  >> (32 - (n))))
3915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
4015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola#define ROTATE32R(x, n) (((x) >> (n)) | ((x)  << (32 - (n))))
4115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
4215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola// finds the end position of largest sequence of zeros in binary representation
4315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola// of 'immediate'.
4415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindolastatic int findLargestZeroSequence(unsigned immediate){
4515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int max_zero_pos;
4615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int max_zero_length = 0;
4715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int zero_pos;
4815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int zero_length;
4915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int pos = 0;
5015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int end_pos;
5115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
5215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  while ((immediate & 0x3) == 0) {
5315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    immediate = ROTATE32R(immediate, 2);
5415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    pos+=2;
5515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  }
5615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  end_pos = pos+32;
5715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
5815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  while (pos<end_pos){
5915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    while ((immediate & 0x3) != 0) {
6015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      immediate = ROTATE32R(immediate, 2);
6115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      pos+=2;
6215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    }
6315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    zero_pos = pos;
6415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    while ((immediate & 0x3) == 0) {
6515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      immediate = ROTATE32R(immediate, 2);
6615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      pos+=2;
6715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    }
6815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    zero_length = pos - zero_pos;
6915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    if (zero_length > max_zero_length){
7015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      max_zero_length = zero_length;
7115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      max_zero_pos = zero_pos % 32;
7215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    }
7315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
7415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  }
7515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
7615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  return (max_zero_pos + max_zero_length) % 32;
7715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola}
7815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
7915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindolastatic void splitInstructionWithImmediate(MachineBasicBlock &BB,
8015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				       MachineBasicBlock::iterator I,
8115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				       const TargetInstrDescriptor &TID,
8215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				       unsigned DestReg,
8315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				       unsigned OrigReg,
8415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				       unsigned immediate){
8515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
8615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  if (immediate == 0){
8715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    BuildMI(BB, I, TID, DestReg).addReg(OrigReg).addImm(0)
8815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola	.addImm(0).addImm(ARMShift::LSL);
8915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    return;
9015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  }
9115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
9215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int start_pos = findLargestZeroSequence(immediate);
9315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  unsigned immediate_tmp = ROTATE32R(immediate, start_pos);
9415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
9515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int pos = 0;
9615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  while (pos < 32){
9715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    while(((immediate_tmp&0x3) == 0)&&(pos<32)){
9815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      immediate_tmp = ROTATE32R(immediate_tmp,2);
9915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      pos+=2;
10015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    }
10115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    if (pos < 32){
10215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      BuildMI(BB, I, TID, DestReg).addReg(OrigReg)
10315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola	.addImm(ROTATE32L(immediate_tmp&0xFF, (start_pos + pos) % 32 ))
10415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola	.addImm(0).addImm(ARMShift::LSL);
10515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      immediate_tmp = ROTATE32R(immediate_tmp,8);
10615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      pos+=8;
10715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    }
10815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  }
10915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
11015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola}
11115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
112c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan ChengARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii)
113c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng  : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
114c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    TII(tii) {
1157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
1187bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolastoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
1197bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                    unsigned SrcReg, int FI,
1207bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                    const TargetRegisterClass *RC) const {
1217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  assert (RC == ARM::IntRegsRegisterClass);
122c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng  BuildMI(MBB, I, TII.get(ARM::STR)).addReg(SrcReg).addFrameIndex(FI).addImm(0);
1237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1247bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
1267bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
1277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                     unsigned DestReg, int FI,
1287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                     const TargetRegisterClass *RC) const {
1297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  assert (RC == ARM::IntRegsRegisterClass);
130c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng  BuildMI(MBB, I, TII.get(ARM::LDR), DestReg).addFrameIndex(FI).addImm(0);
1317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
1347bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     MachineBasicBlock::iterator I,
1357bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     unsigned DestReg, unsigned SrcReg,
1367bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     const TargetRegisterClass *RC) const {
137199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  assert(RC == ARM::IntRegsRegisterClass ||
138199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola         RC == ARM::FPRegsRegisterClass  ||
139199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola         RC == ARM::DFPRegsRegisterClass);
140199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola
141199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  if (RC == ARM::IntRegsRegisterClass)
142c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, I, TII.get(ARM::MOV), DestReg).addReg(SrcReg).addImm(0)
143199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola      .addImm(ARMShift::LSL);
144199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  else if (RC == ARM::FPRegsRegisterClass)
145c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, I, TII.get(ARM::FCPYS), DestReg).addReg(SrcReg);
146199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  else
147c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, I, TII.get(ARM::FCPYD), DestReg).addReg(SrcReg);
1487bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1497bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1507bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaMachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
1517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                                   unsigned OpNum,
1527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                                   int FI) const {
1537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return NULL;
1547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1560f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Chengconst unsigned* ARMRegisterInfo::getCalleeSaveRegs() const {
157ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  static const unsigned CalleeSaveRegs[] = {
158ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    ARM::R4,  ARM::R5, ARM::R6,  ARM::R7,
159ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    ARM::R8,  ARM::R9, ARM::R10, ARM::R11,
160ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    ARM::R14, 0
161ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  };
1620f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng  return CalleeSaveRegs;
1630f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng}
1640f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng
1650f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Chengconst TargetRegisterClass* const *
1660f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan ChengARMRegisterInfo::getCalleeSaveRegClasses() const {
167ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  static const TargetRegisterClass * const CalleeSaveRegClasses[] = {
168ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass,
169ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass,
170ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    &ARM::IntRegsRegClass, 0
171ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  };
1720f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng  return CalleeSaveRegClasses;
1730f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng}
1740f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng
1757bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
1767bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
1777bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                              MachineBasicBlock::iterator I) const {
1787ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  if (hasFP(MF)) {
179b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola    MachineInstr *Old = I;
180b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola    unsigned Amount = Old->getOperand(0).getImmedValue();
181b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola    if (Amount != 0) {
182b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
183b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      Amount = (Amount+Align-1)/Align*Align;
184b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola
185b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      if (Old->getOpcode() == ARM::ADJCALLSTACKDOWN) {
186b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola        // sub sp, sp, amount
18715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola	splitInstructionWithImmediate(MBB, I, TII.get(ARM::SUB), ARM::R13,
18815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				   ARM::R13, Amount);
189b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      } else {
190b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola        // add sp, sp, amount
191b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola        assert(Old->getOpcode() == ARM::ADJCALLSTACKUP);
19215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola	splitInstructionWithImmediate(MBB, I, TII.get(ARM::ADD), ARM::R13,
19315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				   ARM::R13, Amount);
194b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      }
195b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola    }
1967ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  }
1977bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  MBB.erase(I);
1987bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1997bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2007bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid
2017bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
20258421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineInstr &MI = *II;
20358421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineBasicBlock &MBB = *MI.getParent();
20458421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineFunction &MF = *MBB.getParent();
20558421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
2066e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola  assert (MI.getOpcode() == ARM::LDR ||
207f819a4999aedd00368c850c1707e7ed0d59b4aceRafael Espindola          MI.getOpcode() == ARM::STR ||
208f819a4999aedd00368c850c1707e7ed0d59b4aceRafael Espindola          MI.getOpcode() == ARM::ADD);
20958421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
210f819a4999aedd00368c850c1707e7ed0d59b4aceRafael Espindola  unsigned FrameIdx = 1;
211f819a4999aedd00368c850c1707e7ed0d59b4aceRafael Espindola  unsigned   OffIdx = 2;
21258421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
21358421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  int FrameIndex = MI.getOperand(FrameIdx).getFrameIndex();
21458421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
2150d479ecbb132e324da27b674fea5b232115fe964Rafael Espindola  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
2160d479ecbb132e324da27b674fea5b232115fe964Rafael Espindola               MI.getOperand(OffIdx).getImmedValue();
21758421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
21858421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  unsigned StackSize = MF.getFrameInfo()->getStackSize();
21958421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
22058421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  Offset += StackSize;
22158421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
222a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  assert (Offset >= 0);
2237ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  unsigned BaseRegister = hasFP(MF) ? ARM::R11 : ARM::R13;
224a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  if (Offset < 4096) {
225a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the FrameIndex with r13
2267ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola    MI.getOperand(FrameIdx).ChangeToRegister(BaseRegister, false);
227a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the ldr offset with Offset
228a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    MI.getOperand(OffIdx).ChangeToImmediate(Offset);
229a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  } else {
230a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Insert a set of r12 with the full address
231a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // r12 = r13 + offset
232a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    MachineBasicBlock *MBB2 = MI.getParent();
23315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    splitInstructionWithImmediate(*MBB2, II, TII.get(ARM::ADD), ARM::R12,
23415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola			       BaseRegister, Offset);
235a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola
236a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the FrameIndex with r12
23709e460662a8d7328da1b938d5581a6ef3740b51dChris Lattner    MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
238a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  }
2397bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2407bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2417bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
2427bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaprocessFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
2437bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
245355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineBasicBlock &MBB = MF.front();
24644819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola  MachineBasicBlock::iterator MBBI = MBB.begin();
247355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineFrameInfo  *MFI = MF.getFrameInfo();
248355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  int           NumBytes = (int) MFI->getStackSize();
249355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
2507ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  bool HasFP = hasFP(MF);
2517ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
2521a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  if (MFI->hasCalls()) {
2531a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    // We reserve argument space for call sites in the function immediately on
2541a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    // entry to the current function.  This eliminates the need for add/sub
2551a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    // brackets around call sites.
2561a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    NumBytes += MFI->getMaxCallFrameSize();
2571a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  }
2581a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola
2597ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  if (HasFP)
2607ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola    // Add space for storing the FP
2617ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola    NumBytes += 4;
2627ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
2631b5076887e32f9a16a1f65f3ce9abf11c31abcd7Rafael Espindola  // Align to 8 bytes
2641b5076887e32f9a16a1f65f3ce9abf11c31abcd7Rafael Espindola  NumBytes = ((NumBytes + 7) / 8) * 8;
2651b5076887e32f9a16a1f65f3ce9abf11c31abcd7Rafael Espindola
2661a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  MFI->setStackSize(NumBytes);
2671a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola
2681a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  //sub sp, sp, #NumBytes
26915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  splitInstructionWithImmediate(MBB, MBBI, TII.get(ARM::SUB), ARM::R13,
27015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola			     ARM::R13, NumBytes);
27115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
2727ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
2737ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  if (HasFP) {
274c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(ARM::STR))
2756e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola      .addReg(ARM::R11).addReg(ARM::R13).addImm(0);
276c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(ARM::MOV), ARM::R11).addReg(ARM::R13).addImm(0).
2777ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola      addImm(ARMShift::LSL);
2787ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  }
2797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
2827bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola				   MachineBasicBlock &MBB) const {
283355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineBasicBlock::iterator MBBI = prior(MBB.end());
284355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  assert(MBBI->getOpcode() == ARM::bx &&
285355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola         "Can only insert epilog into returning blocks");
286355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
287355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineFrameInfo *MFI = MF.getFrameInfo();
288355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  int          NumBytes = (int) MFI->getStackSize();
289355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
2907ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  if (hasFP(MF)) {
291c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(ARM::MOV), ARM::R13).addReg(ARM::R11).addImm(0).
2927ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola      addImm(ARMShift::LSL);
293c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(ARM::LDR), ARM::R11).addReg(ARM::R13).addImm(0);
2947ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  }
2957ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
2961a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  //add sp, sp, #NumBytes
29715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  splitInstructionWithImmediate(MBB, MBBI, TII.get(ARM::ADD), ARM::R13,
29815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola			     ARM::R13, NumBytes);
29915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
3007bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3017bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
3027bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolaunsigned ARMRegisterInfo::getRARegister() const {
3037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return ARM::R14;
3047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3057bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
3067bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolaunsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const {
3077ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  return hasFP(MF) ? ARM::R11 : ARM::R13;
3087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3097bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
3107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenRegisterInfo.inc"
3117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
312