ARMRegisterInfo.cpp revision ec46ea34dcc615558294e9e0dbd0dd0f2894f574
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 { 507bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola assert (RC == ARM::IntRegsRegisterClass); 51dc124a234a02ea6fc1061a51ade1bb7b817ddb61Rafael Espindola BuildMI(MBB, I, ARM::movrr, 1, DestReg).addReg(SrcReg); 527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 547bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaMachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI, 557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola unsigned OpNum, 567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola int FI) const { 577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return NULL; 587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 600f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Chengconst unsigned* ARMRegisterInfo::getCalleeSaveRegs() const { 61ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola static const unsigned CalleeSaveRegs[] = { 62ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola ARM::R4, ARM::R5, ARM::R6, ARM::R7, 63ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola ARM::R8, ARM::R9, ARM::R10, ARM::R11, 64ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola ARM::R14, 0 65ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola }; 660f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng return CalleeSaveRegs; 670f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng} 680f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng 690f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Chengconst TargetRegisterClass* const * 700f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan ChengARMRegisterInfo::getCalleeSaveRegClasses() const { 71ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola static const TargetRegisterClass * const CalleeSaveRegClasses[] = { 72ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, 73ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, 74ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola &ARM::IntRegsRegClass, 0 75ec46ea34dcc615558294e9e0dbd0dd0f2894f574Rafael Espindola }; 760f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng return CalleeSaveRegClasses; 770f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng} 780f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng 797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo:: 807bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola MachineBasicBlock::iterator I) const { 827bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola MBB.erase(I); 837bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 847bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 857bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid 867bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { 8758421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola MachineInstr &MI = *II; 8858421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola MachineBasicBlock &MBB = *MI.getParent(); 8958421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola MachineFunction &MF = *MBB.getParent(); 9058421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola 917a53bd0890b0529c6dd95e97611dca7a8c4d6077Rafael Espindola assert (MI.getOpcode() == ARM::ldr || 927a53bd0890b0529c6dd95e97611dca7a8c4d6077Rafael Espindola MI.getOpcode() == ARM::str); 9358421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola 94a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola unsigned FrameIdx = 2; 95a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola unsigned OffIdx = 1; 9658421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola 9758421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola int FrameIndex = MI.getOperand(FrameIdx).getFrameIndex(); 9858421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola 9958421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 100a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola assert (MI.getOperand(OffIdx).getImmedValue() == 0); 10158421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola 10258421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola unsigned StackSize = MF.getFrameInfo()->getStackSize(); 10358421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola 10458421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola Offset += StackSize; 10558421d7d0847bbb5f4cc95c647726d55c45582c0Rafael Espindola 106a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola assert (Offset >= 0); 107a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola if (Offset < 4096) { 108a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola // Replace the FrameIndex with r13 109a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola MI.getOperand(FrameIdx).ChangeToRegister(ARM::R13); 110a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola // Replace the ldr offset with Offset 111a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola MI.getOperand(OffIdx).ChangeToImmediate(Offset); 112a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola } else { 113a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola // Insert a set of r12 with the full address 114a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola // r12 = r13 + offset 115a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola MachineBasicBlock *MBB2 = MI.getParent(); 116a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola BuildMI(*MBB2, II, ARM::addri, 2, ARM::R12).addReg(ARM::R13).addImm(Offset); 117a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola 118a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola // Replace the FrameIndex with r12 119a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12); 120a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola } 1217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 1227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo:: 1247bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaprocessFunctionBeforeFrameFinalized(MachineFunction &MF) const {} 1257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { 127355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola MachineBasicBlock &MBB = MF.front(); 12844819cb20ab8e84fc14ea1e6fc69fb797c70a50dRafael Espindola MachineBasicBlock::iterator MBBI = MBB.begin(); 129355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola MachineFrameInfo *MFI = MF.getFrameInfo(); 130355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola int NumBytes = (int) MFI->getStackSize(); 131355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola 1321a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola if (MFI->hasCalls()) { 1331a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola // We reserve argument space for call sites in the function immediately on 1341a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola // entry to the current function. This eliminates the need for add/sub 1351a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola // brackets around call sites. 1361a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola NumBytes += MFI->getMaxCallFrameSize(); 1371a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola } 1381a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola 1391a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola MFI->setStackSize(NumBytes); 1401a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola 1411a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola //sub sp, sp, #NumBytes 1421a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola BuildMI(MBB, MBBI, ARM::subri, 2, ARM::R13).addReg(ARM::R13).addImm(NumBytes); 1437bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 1447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1457bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMRegisterInfo::emitEpilogue(MachineFunction &MF, 1467bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola MachineBasicBlock &MBB) const { 147355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola MachineBasicBlock::iterator MBBI = prior(MBB.end()); 148355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola assert(MBBI->getOpcode() == ARM::bx && 149355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola "Can only insert epilog into returning blocks"); 150355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola 151355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola MachineFrameInfo *MFI = MF.getFrameInfo(); 152355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola int NumBytes = (int) MFI->getStackSize(); 153355746359ebca83ccb5accab0f3ffd20f0374a35Rafael Espindola 1541a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola //add sp, sp, #NumBytes 1551a009468175a6e123cc3f1e847c10e3e126a44dbRafael Espindola BuildMI(MBB, MBBI, ARM::addri, 2, ARM::R13).addReg(ARM::R13).addImm(NumBytes); 1567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 1577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolaunsigned ARMRegisterInfo::getRARegister() const { 1597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return ARM::R14; 1607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 1617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1627bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolaunsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const { 1637bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return ARM::R13; 1647bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 1657bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenRegisterInfo.inc" 1677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 168