ARMRegisterInfo.cpp revision c2b861da18c54a4252fecba866341e1513fa18cc
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
383ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindolastatic inline unsigned rotateL(unsigned x, unsigned n){
393ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindola  return ((x << n) | (x  >> (32 - n)));
403ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindola}
4115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
423ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindolastatic inline unsigned rotateR(unsigned x, unsigned n){
433ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindola  return ((x >> n) | (x  << (32 - n)));
443ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindola}
4515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
4615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola// finds the end position of largest sequence of zeros in binary representation
4715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola// of 'immediate'.
4815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindolastatic int findLargestZeroSequence(unsigned immediate){
4915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int max_zero_pos;
5015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int max_zero_length = 0;
5115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int zero_pos;
5215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int zero_length;
5315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int pos = 0;
5415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int end_pos;
5515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
5615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  while ((immediate & 0x3) == 0) {
573ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindola    immediate = rotateR(immediate, 2);
5815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    pos+=2;
5915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  }
6015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  end_pos = pos+32;
6115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
6215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  while (pos<end_pos){
6315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    while ((immediate & 0x3) != 0) {
643ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindola      immediate = rotateR(immediate, 2);
6515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      pos+=2;
6615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    }
6715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    zero_pos = pos;
6815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    while ((immediate & 0x3) == 0) {
693ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindola      immediate = rotateR(immediate, 2);
7015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      pos+=2;
7115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    }
7215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    zero_length = pos - zero_pos;
7315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    if (zero_length > max_zero_length){
7415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      max_zero_length = zero_length;
7515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      max_zero_pos = zero_pos % 32;
7615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    }
7715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
7815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  }
7915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
8015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  return (max_zero_pos + max_zero_length) % 32;
8115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola}
8215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
8315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindolastatic void splitInstructionWithImmediate(MachineBasicBlock &BB,
8415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				       MachineBasicBlock::iterator I,
8515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				       const TargetInstrDescriptor &TID,
8615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				       unsigned DestReg,
8715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				       unsigned OrigReg,
8815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				       unsigned immediate){
8915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
9015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  if (immediate == 0){
9115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    BuildMI(BB, I, TID, DestReg).addReg(OrigReg).addImm(0)
9215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola	.addImm(0).addImm(ARMShift::LSL);
9315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    return;
9415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  }
9515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
9615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int start_pos = findLargestZeroSequence(immediate);
973ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindola  unsigned immediate_tmp = rotateR(immediate, start_pos);
9815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
9915f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  int pos = 0;
10015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  while (pos < 32){
10115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    while(((immediate_tmp&0x3) == 0)&&(pos<32)){
1023ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindola      immediate_tmp = rotateR(immediate_tmp,2);
10315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      pos+=2;
10415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    }
10515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    if (pos < 32){
10615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      BuildMI(BB, I, TID, DestReg).addReg(OrigReg)
1073ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindola	.addImm(rotateL(immediate_tmp&0xFF, (start_pos + pos) % 32 ))
10815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola	.addImm(0).addImm(ARMShift::LSL);
1093ef39ca6a119caced345e35204e170ee3ad9aa29Rafael Espindola      immediate_tmp = rotateR(immediate_tmp,8);
11015f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola      pos+=8;
11115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    }
11215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  }
11315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
11415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola}
11515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
116c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan ChengARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii)
117c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng  : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
118c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    TII(tii) {
1197bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1207bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
1227bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolastoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
1237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                    unsigned SrcReg, int FI,
1247bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                    const TargetRegisterClass *RC) const {
1257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  assert (RC == ARM::IntRegsRegisterClass);
126c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng  BuildMI(MBB, I, TII.get(ARM::STR)).addReg(SrcReg).addFrameIndex(FI).addImm(0);
1277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
1307bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
1317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                     unsigned DestReg, int FI,
1327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                     const TargetRegisterClass *RC) const {
1337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  assert (RC == ARM::IntRegsRegisterClass);
134c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng  BuildMI(MBB, I, TII.get(ARM::LDR), DestReg).addFrameIndex(FI).addImm(0);
1357bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1367bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
1387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     MachineBasicBlock::iterator I,
1397bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     unsigned DestReg, unsigned SrcReg,
1407bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     const TargetRegisterClass *RC) const {
141199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  assert(RC == ARM::IntRegsRegisterClass ||
142199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola         RC == ARM::FPRegsRegisterClass  ||
143199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola         RC == ARM::DFPRegsRegisterClass);
144199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola
145199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  if (RC == ARM::IntRegsRegisterClass)
146c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, I, TII.get(ARM::MOV), DestReg).addReg(SrcReg).addImm(0)
147199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola      .addImm(ARMShift::LSL);
148199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  else if (RC == ARM::FPRegsRegisterClass)
149c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, I, TII.get(ARM::FCPYS), DestReg).addReg(SrcReg);
150199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  else
151c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, I, TII.get(ARM::FCPYD), DestReg).addReg(SrcReg);
1527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1547bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaMachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
1557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                                   unsigned OpNum,
1567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                                   int FI) const {
1577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return NULL;
1587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
160c2b861da18c54a4252fecba866341e1513fa18ccEvan Chengconst unsigned* ARMRegisterInfo::getCalleeSavedRegs() const {
161c2b861da18c54a4252fecba866341e1513fa18ccEvan Cheng  static const unsigned CalleeSavedRegs[] = {
162ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    ARM::R4,  ARM::R5, ARM::R6,  ARM::R7,
163ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    ARM::R8,  ARM::R9, ARM::R10, ARM::R11,
164ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    ARM::R14, 0
165ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  };
166c2b861da18c54a4252fecba866341e1513fa18ccEvan Cheng  return CalleeSavedRegs;
1670f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng}
1680f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng
1690f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Chengconst TargetRegisterClass* const *
170c2b861da18c54a4252fecba866341e1513fa18ccEvan ChengARMRegisterInfo::getCalleeSavedRegClasses() const {
171c2b861da18c54a4252fecba866341e1513fa18ccEvan Cheng  static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
172ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass,
173ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass,
174ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    &ARM::IntRegsRegClass, 0
175ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  };
176c2b861da18c54a4252fecba866341e1513fa18ccEvan Cheng  return CalleeSavedRegClasses;
1770f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng}
1780f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng
1797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
1807bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
1817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                              MachineBasicBlock::iterator I) const {
1827ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  if (hasFP(MF)) {
183b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola    MachineInstr *Old = I;
184b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola    unsigned Amount = Old->getOperand(0).getImmedValue();
185b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola    if (Amount != 0) {
186b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
187b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      Amount = (Amount+Align-1)/Align*Align;
188b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola
189b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      if (Old->getOpcode() == ARM::ADJCALLSTACKDOWN) {
190b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola        // sub sp, sp, amount
19115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola	splitInstructionWithImmediate(MBB, I, TII.get(ARM::SUB), ARM::R13,
19215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				   ARM::R13, Amount);
193b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      } else {
194b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola        // add sp, sp, amount
195b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola        assert(Old->getOpcode() == ARM::ADJCALLSTACKUP);
19615f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola	splitInstructionWithImmediate(MBB, I, TII.get(ARM::ADD), ARM::R13,
19715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola				   ARM::R13, Amount);
198b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola      }
199b191e0ab51174cfb86502308f520f139daa9e4a0Rafael Espindola    }
2007ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  }
2017bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  MBB.erase(I);
2027bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid
2057bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
20658421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineInstr &MI = *II;
20758421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineBasicBlock &MBB = *MI.getParent();
20858421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineFunction &MF = *MBB.getParent();
20958421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
2106e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola  assert (MI.getOpcode() == ARM::LDR ||
211f819a4999aedd00368c850c1707e7ed0d59b4aceRafael Espindola          MI.getOpcode() == ARM::STR ||
212f819a4999aedd00368c850c1707e7ed0d59b4aceRafael Espindola          MI.getOpcode() == ARM::ADD);
21358421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
214f819a4999aedd00368c850c1707e7ed0d59b4aceRafael Espindola  unsigned FrameIdx = 1;
215f819a4999aedd00368c850c1707e7ed0d59b4aceRafael Espindola  unsigned   OffIdx = 2;
21658421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
21758421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  int FrameIndex = MI.getOperand(FrameIdx).getFrameIndex();
21858421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
2190d479ecbb132e324da27b674fea5b232115fe964Rafael Espindola  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
2200d479ecbb132e324da27b674fea5b232115fe964Rafael Espindola               MI.getOperand(OffIdx).getImmedValue();
22158421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
22258421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  unsigned StackSize = MF.getFrameInfo()->getStackSize();
22358421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
22458421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  Offset += StackSize;
22558421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
226a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  assert (Offset >= 0);
2277ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  unsigned BaseRegister = hasFP(MF) ? ARM::R11 : ARM::R13;
228a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  if (Offset < 4096) {
229a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the FrameIndex with r13
2307ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola    MI.getOperand(FrameIdx).ChangeToRegister(BaseRegister, false);
231a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the ldr offset with Offset
232a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    MI.getOperand(OffIdx).ChangeToImmediate(Offset);
233a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  } else {
234a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Insert a set of r12 with the full address
235a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // r12 = r13 + offset
236a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    MachineBasicBlock *MBB2 = MI.getParent();
23715f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola    splitInstructionWithImmediate(*MBB2, II, TII.get(ARM::ADD), ARM::R12,
23815f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola			       BaseRegister, Offset);
239a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola
240a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the FrameIndex with r12
24109e460662a8d7328da1b938d5581a6ef3740b51dChris Lattner    MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
242a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  }
2437bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2457bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
2467bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaprocessFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
2477bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2487bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
249355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineBasicBlock &MBB = MF.front();
25044819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola  MachineBasicBlock::iterator MBBI = MBB.begin();
251355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineFrameInfo  *MFI = MF.getFrameInfo();
252355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  int           NumBytes = (int) MFI->getStackSize();
253355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
2547ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  bool HasFP = hasFP(MF);
2557ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
2561a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  if (MFI->hasCalls()) {
2571a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    // We reserve argument space for call sites in the function immediately on
2581a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    // entry to the current function.  This eliminates the need for add/sub
2591a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    // brackets around call sites.
2601a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    NumBytes += MFI->getMaxCallFrameSize();
2611a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  }
2621a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola
2637ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  if (HasFP)
2647ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola    // Add space for storing the FP
2657ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola    NumBytes += 4;
2667ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
2671b5076887e32f9a16a1f65f3ce9abf11c31abcd7Rafael Espindola  // Align to 8 bytes
2681b5076887e32f9a16a1f65f3ce9abf11c31abcd7Rafael Espindola  NumBytes = ((NumBytes + 7) / 8) * 8;
2691b5076887e32f9a16a1f65f3ce9abf11c31abcd7Rafael Espindola
2701a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  MFI->setStackSize(NumBytes);
2711a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola
2721a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  //sub sp, sp, #NumBytes
27315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  splitInstructionWithImmediate(MBB, MBBI, TII.get(ARM::SUB), ARM::R13,
27415f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola			     ARM::R13, NumBytes);
27515f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
2767ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
2777ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  if (HasFP) {
278c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(ARM::STR))
2796e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola      .addReg(ARM::R11).addReg(ARM::R13).addImm(0);
280c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(ARM::MOV), ARM::R11).addReg(ARM::R13).addImm(0).
2817ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola      addImm(ARMShift::LSL);
2827ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  }
2837bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2847bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2857bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
2867bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola				   MachineBasicBlock &MBB) const {
287355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineBasicBlock::iterator MBBI = prior(MBB.end());
288355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  assert(MBBI->getOpcode() == ARM::bx &&
289355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola         "Can only insert epilog into returning blocks");
290355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
291355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineFrameInfo *MFI = MF.getFrameInfo();
292355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  int          NumBytes = (int) MFI->getStackSize();
293355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
2947ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  if (hasFP(MF)) {
295c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(ARM::MOV), ARM::R13).addReg(ARM::R11).addImm(0).
2967ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola      addImm(ARMShift::LSL);
297c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(ARM::LDR), ARM::R11).addReg(ARM::R13).addImm(0);
2987ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  }
2997ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola
3001a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  //add sp, sp, #NumBytes
30115f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola  splitInstructionWithImmediate(MBB, MBBI, TII.get(ARM::ADD), ARM::R13,
30215f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola			     ARM::R13, NumBytes);
30315f17a7c4746b8533aabf7c78bde82503ad9fc9fRafael Espindola
3047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3057bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
3067bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolaunsigned ARMRegisterInfo::getRARegister() const {
3077bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return ARM::R14;
3087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3097bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
3107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolaunsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const {
3117ae68ab3bccb6ef2d0e4c489f0648dc5d37ae362Rafael Espindola  return hasFP(MF) ? ARM::R11 : ARM::R13;
3127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
3147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenRegisterInfo.inc"
3157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
316