LLVM API Documentation
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