ARMRegisterInfo.cpp revision 0d479ecbb132e324da27b674fea5b232115fe964
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"
227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/STLExtras.h"
237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <iostream>
247bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm;
257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
267bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaARMRegisterInfo::ARMRegisterInfo()
277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP) {
287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
317bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolastoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                    unsigned SrcReg, int FI,
337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                    const TargetRegisterClass *RC) const {
347bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  assert (RC == ARM::IntRegsRegisterClass);
357a53bd0890b0529c6dd95e97611dca7a8c4d6077Rafael Espindola  BuildMI(MBB, I, ARM::str, 3).addReg(SrcReg).addImm(0).addFrameIndex(FI);
367bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
397bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
407bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                     unsigned DestReg, int FI,
417bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                     const TargetRegisterClass *RC) const {
427bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  assert (RC == ARM::IntRegsRegisterClass);
437a53bd0890b0529c6dd95e97611dca7a8c4d6077Rafael Espindola  BuildMI(MBB, I, ARM::ldr, 2, DestReg).addImm(0).addFrameIndex(FI);
447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
457bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
467bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
477bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     MachineBasicBlock::iterator I,
487bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     unsigned DestReg, unsigned SrcReg,
497bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     const TargetRegisterClass *RC) const {
50199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  assert(RC == ARM::IntRegsRegisterClass ||
51199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola         RC == ARM::FPRegsRegisterClass  ||
52199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola         RC == ARM::DFPRegsRegisterClass);
53199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola
54199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  if (RC == ARM::IntRegsRegisterClass)
55199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola    BuildMI(MBB, I, ARM::MOV, 3, DestReg).addReg(SrcReg).addImm(0)
56199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola      .addImm(ARMShift::LSL);
57199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  else if (RC == ARM::FPRegsRegisterClass)
58199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola    BuildMI(MBB, I, ARM::FCPYS, 1, DestReg).addReg(SrcReg);
59199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola  else
60199dd67c50990a45876b871008cad0dad0f63b88Rafael Espindola    BuildMI(MBB, I, ARM::FCPYD, 1, DestReg).addReg(SrcReg);
617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
627bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
637bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaMachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
647bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                                   unsigned OpNum,
657bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                                   int FI) const {
667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return NULL;
677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
687bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
690f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Chengconst unsigned* ARMRegisterInfo::getCalleeSaveRegs() const {
70ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  static const unsigned CalleeSaveRegs[] = {
71ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    ARM::R4,  ARM::R5, ARM::R6,  ARM::R7,
72ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    ARM::R8,  ARM::R9, ARM::R10, ARM::R11,
73ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    ARM::R14, 0
74ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  };
750f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng  return CalleeSaveRegs;
760f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng}
770f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng
780f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Chengconst TargetRegisterClass* const *
790f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan ChengARMRegisterInfo::getCalleeSaveRegClasses() const {
80ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  static const TargetRegisterClass * const CalleeSaveRegClasses[] = {
81ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass,
82ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass,
83ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola    &ARM::IntRegsRegClass, 0
84ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola  };
850f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng  return CalleeSaveRegClasses;
860f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng}
870f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng
887bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
897bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
907bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                              MachineBasicBlock::iterator I) const {
917bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  MBB.erase(I);
927bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
937bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
947bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid
957bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
9658421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineInstr &MI = *II;
9758421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineBasicBlock &MBB = *MI.getParent();
9858421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineFunction &MF = *MBB.getParent();
9958421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
1007a53bd0890b0529c6dd95e97611dca7a8c4d6077Rafael Espindola  assert (MI.getOpcode() == ARM::ldr ||
101f3a335cedff423438789c593d58be068b124dc1eRafael Espindola	  MI.getOpcode() == ARM::str ||
102f3a335cedff423438789c593d58be068b124dc1eRafael Espindola	  MI.getOpcode() == ARM::lea_addri);
10358421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
104a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  unsigned FrameIdx = 2;
105a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  unsigned OffIdx = 1;
10658421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
10758421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  int FrameIndex = MI.getOperand(FrameIdx).getFrameIndex();
10858421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
1090d479ecbb132e324da27b674fea5b232115fe964Rafael Espindola  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
1100d479ecbb132e324da27b674fea5b232115fe964Rafael Espindola               MI.getOperand(OffIdx).getImmedValue();
11158421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
11258421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  unsigned StackSize = MF.getFrameInfo()->getStackSize();
11358421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
11458421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  Offset += StackSize;
11558421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
116a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  assert (Offset >= 0);
117a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  if (Offset < 4096) {
118a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the FrameIndex with r13
11909e460662a8d7328da1b938d5581a6ef3740b51dChris Lattner    MI.getOperand(FrameIdx).ChangeToRegister(ARM::R13, false);
120a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the ldr offset with Offset
121a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    MI.getOperand(OffIdx).ChangeToImmediate(Offset);
122a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  } else {
123a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Insert a set of r12 with the full address
124a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // r12 = r13 + offset
125a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    MachineBasicBlock *MBB2 = MI.getParent();
1263ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola    BuildMI(*MBB2, II, ARM::ADD, 4, ARM::R12).addReg(ARM::R13).addImm(Offset)
1273ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola	    .addImm(0).addImm(ARMShift::LSL);
128a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola
129a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the FrameIndex with r12
13009e460662a8d7328da1b938d5581a6ef3740b51dChris Lattner    MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
131a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  }
1327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1347bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
1357bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaprocessFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
1367bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
138355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineBasicBlock &MBB = MF.front();
13944819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola  MachineBasicBlock::iterator MBBI = MBB.begin();
140355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineFrameInfo  *MFI = MF.getFrameInfo();
141355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  int           NumBytes = (int) MFI->getStackSize();
142355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
1431a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  if (MFI->hasCalls()) {
1441a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    // We reserve argument space for call sites in the function immediately on
1451a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    // entry to the current function.  This eliminates the need for add/sub
1461a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    // brackets around call sites.
1471a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola    NumBytes += MFI->getMaxCallFrameSize();
1481a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  }
1491a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola
1501b5076887e32f9a16a1f65f3ce9abf11c31abcd7Rafael Espindola  // Align to 8 bytes
1511b5076887e32f9a16a1f65f3ce9abf11c31abcd7Rafael Espindola  NumBytes = ((NumBytes + 7) / 8) * 8;
1521b5076887e32f9a16a1f65f3ce9abf11c31abcd7Rafael Espindola
1531a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  MFI->setStackSize(NumBytes);
1541a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola
1551a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  //sub sp, sp, #NumBytes
1563ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola  BuildMI(MBB, MBBI, ARM::SUB, 4, ARM::R13).addReg(ARM::R13).addImm(NumBytes)
1573ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola	  .addImm(0).addImm(ARMShift::LSL);
1587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
1617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola				   MachineBasicBlock &MBB) const {
162355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineBasicBlock::iterator MBBI = prior(MBB.end());
163355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  assert(MBBI->getOpcode() == ARM::bx &&
164355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola         "Can only insert epilog into returning blocks");
165355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
166355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineFrameInfo *MFI = MF.getFrameInfo();
167355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  int          NumBytes = (int) MFI->getStackSize();
168355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
1691a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola  //add sp, sp, #NumBytes
1703ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola  BuildMI(MBB, MBBI, ARM::ADD, 4, ARM::R13).addReg(ARM::R13).addImm(NumBytes)
1713ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola	  .addImm(0).addImm(ARMShift::LSL);
1727bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1737bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1747bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolaunsigned ARMRegisterInfo::getRARegister() const {
1757bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return ARM::R14;
1767bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1777bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1787bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolaunsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const {
1797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return ARM::R13;
1807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1827bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenRegisterInfo.inc"
1837bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
184