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