LLVM API Documentation

ARMRegisterInfo.cpp

Go to the documentation of this file.
00001 //===- ARMRegisterInfo.cpp - ARM Register Information -----------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the "Instituto Nokia de Tecnologia" and
00006 // is distributed under the University of Illinois Open Source
00007 // License. See LICENSE.TXT for details.
00008 //
00009 //===----------------------------------------------------------------------===//
00010 //
00011 // This file contains the ARM implementation of the MRegisterInfo class.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "ARM.h"
00016 #include "ARMRegisterInfo.h"
00017 #include "llvm/CodeGen/MachineInstrBuilder.h"
00018 #include "llvm/CodeGen/MachineFunction.h"
00019 #include "llvm/CodeGen/MachineFrameInfo.h"
00020 #include "llvm/CodeGen/MachineLocation.h"
00021 #include "llvm/Type.h"
00022 #include "llvm/ADT/STLExtras.h"
00023 #include <iostream>
00024 using namespace llvm;
00025 
00026 ARMRegisterInfo::ARMRegisterInfo()
00027   : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP) {
00028 }
00029 
00030 void ARMRegisterInfo::
00031 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00032                     unsigned SrcReg, int FI,
00033                     const TargetRegisterClass *RC) const {
00034   // On the order of operands here: think "[FI + 0] = SrcReg".
00035   assert (RC == ARM::IntRegsRegisterClass);
00036   BuildMI(MBB, I, ARM::str, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg);
00037 }
00038 
00039 void ARMRegisterInfo::
00040 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00041                      unsigned DestReg, int FI,
00042                      const TargetRegisterClass *RC) const {
00043   assert (RC == ARM::IntRegsRegisterClass);
00044   BuildMI(MBB, I, ARM::ldr, 2, DestReg).addFrameIndex(FI).addImm(0);
00045 }
00046 
00047 void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
00048                                      MachineBasicBlock::iterator I,
00049                                      unsigned DestReg, unsigned SrcReg,
00050                                      const TargetRegisterClass *RC) const {
00051   assert (RC == ARM::IntRegsRegisterClass);
00052   BuildMI(MBB, I, ARM::movrr, 1, DestReg).addReg(SrcReg);
00053 }
00054 
00055 MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
00056                                                    unsigned OpNum,
00057                                                    int FI) const {
00058   return NULL;
00059 }
00060 
00061 const unsigned* ARMRegisterInfo::getCalleeSaveRegs() const {
00062   static const unsigned CalleeSaveRegs[] = { 0 };
00063   return CalleeSaveRegs;
00064 }
00065 
00066 const TargetRegisterClass* const *
00067 ARMRegisterInfo::getCalleeSaveRegClasses() const {
00068   static const TargetRegisterClass * const CalleeSaveRegClasses[] = { 0 };
00069   return CalleeSaveRegClasses;
00070 }
00071 
00072 void ARMRegisterInfo::
00073 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
00074                               MachineBasicBlock::iterator I) const {
00075   MBB.erase(I);
00076 }
00077 
00078 void
00079 ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
00080   MachineInstr &MI = *II;
00081   MachineBasicBlock &MBB = *MI.getParent();
00082   MachineFunction &MF = *MBB.getParent();
00083 
00084   assert (MI.getOpcode() == ARM::ldr);
00085 
00086   unsigned FrameIdx = 2;
00087   unsigned OffIdx = 1;
00088 
00089   int FrameIndex = MI.getOperand(FrameIdx).getFrameIndex();
00090 
00091   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
00092   assert (MI.getOperand(OffIdx).getImmedValue() == 0);
00093 
00094   unsigned StackSize = MF.getFrameInfo()->getStackSize();
00095 
00096   Offset += StackSize;
00097 
00098   assert (Offset >= 0);
00099   if (Offset < 4096) {
00100     // Replace the FrameIndex with r13
00101     MI.getOperand(FrameIdx).ChangeToRegister(ARM::R13);
00102     // Replace the ldr offset with Offset
00103     MI.getOperand(OffIdx).ChangeToImmediate(Offset);
00104   } else {
00105     // Insert a set of r12 with the full address
00106     // r12 = r13 + offset
00107     MachineBasicBlock *MBB2 = MI.getParent();
00108     BuildMI(*MBB2, II, ARM::addri, 2, ARM::R12).addReg(ARM::R13).addImm(Offset);
00109 
00110     // Replace the FrameIndex with r12
00111     MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12);
00112   }
00113 }
00114 
00115 void ARMRegisterInfo::
00116 processFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
00117 
00118 void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
00119   MachineBasicBlock &MBB = MF.front();
00120   MachineBasicBlock::iterator MBBI = MBB.begin();
00121   MachineFrameInfo  *MFI = MF.getFrameInfo();
00122   int           NumBytes = (int) MFI->getStackSize();
00123 
00124   //hack
00125   assert(NumBytes == 0);
00126 
00127   //sub sp, sp, #4
00128   BuildMI(MBB, MBBI, ARM::subri, 2, ARM::R13).addReg(ARM::R13).addImm(4);
00129   //str lr, [sp]
00130   BuildMI(MBB, MBBI, ARM::str, 1, ARM::R14).addReg(ARM::R13);
00131 }
00132 
00133 void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
00134            MachineBasicBlock &MBB) const {
00135   MachineBasicBlock::iterator MBBI = prior(MBB.end());
00136   assert(MBBI->getOpcode() == ARM::bx &&
00137          "Can only insert epilog into returning blocks");
00138 
00139   MachineFrameInfo *MFI = MF.getFrameInfo();
00140   int          NumBytes = (int) MFI->getStackSize();
00141   //hack
00142   assert(NumBytes == 0);
00143 
00144   //ldr lr, [sp]
00145   BuildMI(MBB, MBBI, ARM::ldr, 2, ARM::R14).addImm(0).addReg(ARM::R13);
00146   //add sp, sp, #4
00147   BuildMI(MBB, MBBI, ARM::addri, 2, ARM::R13).addReg(ARM::R13).addImm(4);
00148 }
00149 
00150 unsigned ARMRegisterInfo::getRARegister() const {
00151   return ARM::R14;
00152 }
00153 
00154 unsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const {
00155   return ARM::R13;
00156 }
00157 
00158 #include "ARMGenRegisterInfo.inc"
00159