ARMRegisterInfo.cpp revision 44819cb20ab8e84fc14ea1e6fc69fb797c70a50d
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  // On the order of operands here: think "[FI + 0] = SrcReg".
357bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  assert (RC == ARM::IntRegsRegisterClass);
367bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  BuildMI(MBB, I, ARM::str, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg);
377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
397bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
407bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
417bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                     unsigned DestReg, int FI,
427bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                     const TargetRegisterClass *RC) const {
437bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  assert (RC == ARM::IntRegsRegisterClass);
447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  BuildMI(MBB, I, ARM::ldr, 2, DestReg).addFrameIndex(FI).addImm(0);
457bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
467bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
477bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
487bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     MachineBasicBlock::iterator I,
497bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     unsigned DestReg, unsigned SrcReg,
507bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                     const TargetRegisterClass *RC) const {
517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  assert (RC == ARM::IntRegsRegisterClass);
52dc124a234a02ea6fc1061a51ade1bb7b817ddb61Rafael Espindola  BuildMI(MBB, I, ARM::movrr, 1, DestReg).addReg(SrcReg);
537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
557bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaMachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                                   unsigned OpNum,
577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                                   int FI) const {
587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return NULL;
597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
610f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Chengconst unsigned* ARMRegisterInfo::getCalleeSaveRegs() const {
620f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng  static const unsigned CalleeSaveRegs[] = { 0 };
630f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng  return CalleeSaveRegs;
640f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng}
650f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng
660f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Chengconst TargetRegisterClass* const *
670f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan ChengARMRegisterInfo::getCalleeSaveRegClasses() const {
680f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng  static const TargetRegisterClass * const CalleeSaveRegClasses[] = { 0 };
690f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng  return CalleeSaveRegClasses;
700f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng}
710f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng
727bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
737bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
747bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                              MachineBasicBlock::iterator I) const {
757bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  MBB.erase(I);
767bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
777bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
787bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid
797bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
8058421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineInstr &MI = *II;
8158421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineBasicBlock &MBB = *MI.getParent();
8258421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  MachineFunction &MF = *MBB.getParent();
8358421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
84aefe14299a05621864e6372639f372173a96bf38Rafael Espindola  assert (MI.getOpcode() == ARM::ldr);
8558421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
86a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  unsigned FrameIdx = 2;
87a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  unsigned OffIdx = 1;
8858421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
8958421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  int FrameIndex = MI.getOperand(FrameIdx).getFrameIndex();
9058421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
9158421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
92a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  assert (MI.getOperand(OffIdx).getImmedValue() == 0);
9358421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
9458421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  unsigned StackSize = MF.getFrameInfo()->getStackSize();
9558421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
9658421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola  Offset += StackSize;
9758421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola
98a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  assert (Offset >= 0);
99a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  if (Offset < 4096) {
100a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the FrameIndex with r13
101a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    MI.getOperand(FrameIdx).ChangeToRegister(ARM::R13);
102a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the ldr offset with Offset
103a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    MI.getOperand(OffIdx).ChangeToImmediate(Offset);
104a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  } else {
105a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Insert a set of r12 with the full address
106a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // r12 = r13 + offset
107a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    MachineBasicBlock *MBB2 = MI.getParent();
108a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    BuildMI(*MBB2, II, ARM::addri, 2, ARM::R12).addReg(ARM::R13).addImm(Offset);
109a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola
110a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    // Replace the FrameIndex with r12
111a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12);
112a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola  }
1137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::
1167bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaprocessFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
1177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1187bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
119355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineBasicBlock &MBB = MF.front();
12044819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola  MachineBasicBlock::iterator MBBI = MBB.begin();
121355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineFrameInfo  *MFI = MF.getFrameInfo();
122355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  int           NumBytes = (int) MFI->getStackSize();
123355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
124355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  //hack
125355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  assert(NumBytes == 0);
126355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
12744819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola  //sub sp, sp, #4
12844819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola  BuildMI(MBB, MBBI, ARM::subri, 2, ARM::R13).addReg(ARM::R13).addImm(4);
12944819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola  //str lr, [sp]
13044819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola  BuildMI(MBB, MBBI, ARM::str, 1, ARM::R14).addReg(ARM::R13);
1317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
1347bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola				   MachineBasicBlock &MBB) const {
135355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineBasicBlock::iterator MBBI = prior(MBB.end());
136355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  assert(MBBI->getOpcode() == ARM::bx &&
137355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola         "Can only insert epilog into returning blocks");
138355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
139355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  MachineFrameInfo *MFI = MF.getFrameInfo();
140355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  int          NumBytes = (int) MFI->getStackSize();
141355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  //hack
142355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  assert(NumBytes == 0);
143355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola
14444819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola  //ldr lr, [sp]
145355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola  BuildMI(MBB, MBBI, ARM::ldr, 2, ARM::R14).addImm(0).addReg(ARM::R13);
14644819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola  //add sp, sp, #4
14744819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola  BuildMI(MBB, MBBI, ARM::addri, 2, ARM::R13).addReg(ARM::R13).addImm(4);
1487bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1497bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1507bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolaunsigned ARMRegisterInfo::getRARegister() const {
1517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return ARM::R14;
1527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolaunsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const {
1557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return ARM::R13;
1567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenRegisterInfo.inc"
1597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
160