BlackfinRegisterInfo.cpp revision d0c38176690e9602a93a20a43f1bd084564a8116
1d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen//===- BlackfinRegisterInfo.cpp - Blackfin Register Information -*- C++ -*-===// 2d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// 3d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// The LLVM Compiler Infrastructure 4d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// 5d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// This file is distributed under the University of Illinois Open Source 6d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// License. See LICENSE.TXT for details. 7d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// 8d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen//===----------------------------------------------------------------------===// 9d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// 10d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// This file contains the Blackfin implementation of the TargetRegisterInfo 11d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// class. 12d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// 13d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen//===----------------------------------------------------------------------===// 14d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 15d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "Blackfin.h" 16d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "BlackfinRegisterInfo.h" 17d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "BlackfinSubtarget.h" 18d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Support/Debug.h" 19d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Support/ErrorHandling.h" 20d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/CodeGen/MachineInstrBuilder.h" 21d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/CodeGen/MachineFunction.h" 22d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/CodeGen/MachineFrameInfo.h" 23d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/CodeGen/MachineLocation.h" 24d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/CodeGen/RegisterScavenging.h" 25d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Target/TargetFrameInfo.h" 26d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Target/TargetMachine.h" 27d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Target/TargetOptions.h" 28d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Target/TargetInstrInfo.h" 29d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/Type.h" 30d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/ADT/BitVector.h" 31d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "llvm/ADT/STLExtras.h" 32d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenusing namespace llvm; 33d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 34d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OlesenBlackfinRegisterInfo::BlackfinRegisterInfo(BlackfinSubtarget &st, 35d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen const TargetInstrInfo &tii) 36d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen : BlackfinGenRegisterInfo(BF::ADJCALLSTACKDOWN, BF::ADJCALLSTACKUP), 37d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen Subtarget(st), 38d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen TII(tii) {} 39d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 40d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenconst unsigned* 41d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OlesenBlackfinRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 42d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen using namespace BF; 43d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen static const unsigned CalleeSavedRegs[] = { 44d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen FP, 45d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen R4, R5, R6, R7, 46d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen P3, P4, P5, 47d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 0 }; 48d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return CalleeSavedRegs; 49d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 50d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 51d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OlesenBitVector 52d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OlesenBlackfinRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 53d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); 54d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 55d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen using namespace BF; 56d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BitVector Reserved(getNumRegs()); 5771d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen Reserved.set(AZ); 5871d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen Reserved.set(AN); 5971d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen Reserved.set(AQ); 6071d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen Reserved.set(AC0); 6171d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen Reserved.set(AC1); 6271d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen Reserved.set(AV0); 6371d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen Reserved.set(AV0S); 6471d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen Reserved.set(AV1); 6571d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen Reserved.set(AV1S); 6671d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen Reserved.set(V); 6771d342e8546e8bb7b57bd161651d08912a32465fJakob Stoklund Olesen Reserved.set(VS); 6846151de6a0d08184c1bfc90bb39657ff1e21729eJakob Stoklund Olesen Reserved.set(CYCLES).set(CYCLES2); 69d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen Reserved.set(L0); 70d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen Reserved.set(L1); 71d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen Reserved.set(L2); 72d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen Reserved.set(L3); 73d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen Reserved.set(SP); 74d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen Reserved.set(RETS); 75d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (TFI->hasFP(MF)) 76d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen Reserved.set(FP); 77d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return Reserved; 78d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 79d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 80d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenbool BlackfinRegisterInfo:: 81d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OlesenrequiresRegisterScavenging(const MachineFunction &MF) const { 82d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return true; 83d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 84d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 85d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// Emit instructions to add delta to D/P register. ScratchReg must be of the 86d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// same class as Reg (P). 87d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenvoid BlackfinRegisterInfo::adjustRegister(MachineBasicBlock &MBB, 88d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MachineBasicBlock::iterator I, 89d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen DebugLoc DL, 90d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen unsigned Reg, 91d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen unsigned ScratchReg, 92d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen int delta) const { 93d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen if (!delta) 94d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return; 95d6eb635d1a1317fc3d218056ec77ec242c2413cbJakob Stoklund Olesen if (isInt<7>(delta)) { 96d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, I, DL, TII.get(BF::ADDpp_imm7), Reg) 97d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(Reg) // No kill on two-addr operand 98d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addImm(delta); 99d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return; 100d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 101d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 102d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // We must load delta into ScratchReg and add that. 103d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen loadConstant(MBB, I, DL, ScratchReg, delta); 104d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen if (BF::PRegClass.contains(Reg)) { 105ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(BF::PRegClass.contains(ScratchReg) && 106ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen "ScratchReg must be a P register"); 107d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, I, DL, TII.get(BF::ADDpp), Reg) 108d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(Reg, RegState::Kill) 109d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(ScratchReg, RegState::Kill); 110d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } else { 111ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(BF::DRegClass.contains(Reg) && "Reg must be a D or P register"); 112ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(BF::DRegClass.contains(ScratchReg) && 113ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen "ScratchReg must be a D register"); 114d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, I, DL, TII.get(BF::ADD), Reg) 115d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(Reg, RegState::Kill) 116d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(ScratchReg, RegState::Kill); 117d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 118d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 119d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 120d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen// Emit instructions to load a constant into D/P register 121d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenvoid BlackfinRegisterInfo::loadConstant(MachineBasicBlock &MBB, 122d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MachineBasicBlock::iterator I, 123d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen DebugLoc DL, 124d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen unsigned Reg, 125d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen int value) const { 126d6eb635d1a1317fc3d218056ec77ec242c2413cbJakob Stoklund Olesen if (isInt<7>(value)) { 127d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, I, DL, TII.get(BF::LOADimm7), Reg).addImm(value); 128d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return; 129d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 130d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 13134247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer if (isUInt<16>(value)) { 132d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, I, DL, TII.get(BF::LOADuimm16), Reg).addImm(value); 133d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return; 134d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 135d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 136d6eb635d1a1317fc3d218056ec77ec242c2413cbJakob Stoklund Olesen if (isInt<16>(value)) { 137d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, I, DL, TII.get(BF::LOADimm16), Reg).addImm(value); 138d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return; 139d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 140d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 141d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // We must split into halves 142d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, I, DL, 14373ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen TII.get(BF::LOAD16i), getSubReg(Reg, BF::hi16)) 144d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addImm((value >> 16) & 0xffff) 145d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(Reg, RegState::ImplicitDefine); 146d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, I, DL, 14773ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen TII.get(BF::LOAD16i), getSubReg(Reg, BF::lo16)) 148d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addImm(value & 0xffff) 149d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(Reg, RegState::ImplicitKill) 150d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(Reg, RegState::ImplicitDefine); 151d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 152d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 153d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenvoid BlackfinRegisterInfo:: 154d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OleseneliminateCallFramePseudoInstr(MachineFunction &MF, 155d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MachineBasicBlock &MBB, 156d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MachineBasicBlock::iterator I) const { 157d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); 158d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 159d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (!TFI->hasReservedCallFrame(MF)) { 160d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen int64_t Amount = I->getOperand(0).getImm(); 161d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen if (Amount != 0) { 162ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(Amount%4 == 0 && "Unaligned call frame size"); 163d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen if (I->getOpcode() == BF::ADJCALLSTACKDOWN) { 164d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, -Amount); 165d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } else { 166ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(I->getOpcode() == BF::ADJCALLSTACKUP && 167ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen "Unknown call frame pseudo instruction"); 168d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, Amount); 169d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 170d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 171d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 172d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MBB.erase(I); 173d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 174d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 175d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen/// findScratchRegister - Find a 'free' register. Try for a call-clobbered 176d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen/// register first and then a spilled callee-saved register if that fails. 177d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenstatic unsigned findScratchRegister(MachineBasicBlock::iterator II, 178d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen RegScavenger *RS, 179d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen const TargetRegisterClass *RC, 180d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen int SPAdj) { 181d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen assert(RS && "Register scavenging must be on"); 182c0823fe7c679ca8f7d1667a310c2fca97b9402d5Jakob Stoklund Olesen unsigned Reg = RS->FindUnusedReg(RC); 183d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen if (Reg == 0) 184d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen Reg = RS->scavengeRegister(RC, II, SPAdj); 185d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return Reg; 186d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 187d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 188fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbachvoid 189b58f498f7502e7e1833decbbbb4df771367c7341Jim GrosbachBlackfinRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 190fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach int SPAdj, RegScavenger *RS) const { 191d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MachineInstr &MI = *II; 192d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MachineBasicBlock &MBB = *MI.getParent(); 193d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MachineFunction &MF = *MBB.getParent(); 194d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); 195d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen DebugLoc DL = MI.getDebugLoc(); 196d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 197ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen unsigned FIPos; 198ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen for (FIPos=0; !MI.getOperand(FIPos).isFI(); ++FIPos) { 199ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(FIPos < MI.getNumOperands() && 200ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen "Instr doesn't have FrameIndex operand!"); 201d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 202ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen int FrameIndex = MI.getOperand(FIPos).getIndex(); 203ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(FIPos+1 < MI.getNumOperands() && MI.getOperand(FIPos+1).isImm()); 204d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) 205ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen + MI.getOperand(FIPos+1).getImm(); 206d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen unsigned BaseReg = BF::FP; 207d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (TFI->hasFP(MF)) { 208ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(SPAdj==0 && "Unexpected SP adjust in function with frame pointer"); 209d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } else { 210d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BaseReg = BF::SP; 211d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen Offset += MF.getFrameInfo()->getStackSize() + SPAdj; 212d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 213d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 214d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen bool isStore = false; 215d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 216d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen switch (MI.getOpcode()) { 217d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen case BF::STORE32fi: 218d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen isStore = true; 219d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen case BF::LOAD32fi: { 220ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(Offset%4 == 0 && "Unaligned i32 stack access"); 221ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(FIPos==1 && "Bad frame index operand"); 222ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen MI.getOperand(FIPos).ChangeToRegister(BaseReg, false); 223ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen MI.getOperand(FIPos+1).setImm(Offset); 22434247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer if (isUInt<6>(Offset)) { 225d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.setDesc(TII.get(isStore 226d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen ? BF::STORE32p_uimm6m4 227d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen : BF::LOAD32p_uimm6m4)); 228fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach return; 229d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 23034247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer if (BaseReg == BF::FP && isUInt<7>(-Offset)) { 231d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.setDesc(TII.get(isStore 232d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen ? BF::STORE32fp_nimm7m4 233d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen : BF::LOAD32fp_nimm7m4)); 234ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen MI.getOperand(FIPos+1).setImm(-Offset); 235fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach return; 236d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 237d6eb635d1a1317fc3d218056ec77ec242c2413cbJakob Stoklund Olesen if (isInt<18>(Offset)) { 238d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.setDesc(TII.get(isStore 239d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen ? BF::STORE32p_imm18m4 240d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen : BF::LOAD32p_imm18m4)); 241fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach return; 242d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 243d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // Use RegScavenger to calculate proper offset... 244d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.dump(); 245d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen llvm_unreachable("Stack frame offset too big"); 246d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen break; 247d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 248d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen case BF::ADDpp: { 249ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(MI.getOperand(0).isReg() && "ADD instruction needs a register"); 250d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen unsigned DestReg = MI.getOperand(0).getReg(); 251d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // We need to produce a stack offset in a P register. We emit: 252d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // P0 = offset; 253d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // P0 = BR + P0; 254ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(FIPos==1 && "Bad frame index operand"); 255d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen loadConstant(MBB, II, DL, DestReg, Offset); 256d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.getOperand(1).ChangeToRegister(DestReg, false, false, true); 257d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.getOperand(2).ChangeToRegister(BaseReg, false); 258d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen break; 259d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 260d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen case BF::STORE16fi: 261d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen isStore = true; 262d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen case BF::LOAD16fi: { 263ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(Offset%2 == 0 && "Unaligned i16 stack access"); 264ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(FIPos==1 && "Bad frame index operand"); 265d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // We need a P register to use as an address 266d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen unsigned ScratchReg = findScratchRegister(II, RS, &BF::PRegClass, SPAdj); 267ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(ScratchReg && "Could not scavenge register"); 268d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen loadConstant(MBB, II, DL, ScratchReg, Offset); 269d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, II, DL, TII.get(BF::ADDpp), ScratchReg) 270d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(ScratchReg, RegState::Kill) 271d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(BaseReg); 272d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.setDesc(TII.get(isStore ? BF::STORE16pi : BF::LOAD16pi)); 273d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.getOperand(1).ChangeToRegister(ScratchReg, false, false, true); 274d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.RemoveOperand(2); 275d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen break; 276d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 277d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen case BF::STORE8fi: { 278d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // This is an AnyCC spill, we need a scratch register. 279ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(FIPos==1 && "Bad frame index operand"); 280d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MachineOperand SpillReg = MI.getOperand(0); 281d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj); 282ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(ScratchReg && "Could not scavenge register"); 283d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen if (SpillReg.getReg()==BF::NCC) { 284d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, II, DL, TII.get(BF::MOVENCC_z), ScratchReg) 285d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addOperand(SpillReg); 286d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, II, DL, TII.get(BF::BITTGL), ScratchReg) 287d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(ScratchReg).addImm(0); 288d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } else { 289d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, II, DL, TII.get(BF::MOVECC_zext), ScratchReg) 290d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addOperand(SpillReg); 291d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 292d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // STORE D 293d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.setDesc(TII.get(BF::STORE8p_imm16)); 294d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.getOperand(0).ChangeToRegister(ScratchReg, false, false, true); 295ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen MI.getOperand(FIPos).ChangeToRegister(BaseReg, false); 296ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen MI.getOperand(FIPos+1).setImm(Offset); 297d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen break; 298d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 299d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen case BF::LOAD8fi: { 300d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // This is an restore, we need a scratch register. 301ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(FIPos==1 && "Bad frame index operand"); 302d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MachineOperand SpillReg = MI.getOperand(0); 303d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj); 304ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen assert(ScratchReg && "Could not scavenge register"); 305d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.setDesc(TII.get(BF::LOAD32p_imm16_8z)); 306d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MI.getOperand(0).ChangeToRegister(ScratchReg, true); 307ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen MI.getOperand(FIPos).ChangeToRegister(BaseReg, false); 308ea1c9b7bacb6d58b4fef08fb32b1a7ccef856c1eJakob Stoklund Olesen MI.getOperand(FIPos+1).setImm(Offset); 309d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen ++II; 310d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen if (SpillReg.getReg()==BF::CC) { 311d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // CC = D 312d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, II, DL, TII.get(BF::MOVECC_nz), BF::CC) 313d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(ScratchReg, RegState::Kill); 314d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } else { 315d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // Restore NCC (CC = D==0) 316d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen BuildMI(MBB, II, DL, TII.get(BF::SETEQri_not), BF::NCC) 317d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addReg(ScratchReg, RegState::Kill) 318d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen .addImm(0); 319d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 320d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen break; 321d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 322d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen default: 323d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen llvm_unreachable("Cannot eliminate frame index"); 324d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen break; 325d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 326d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 327d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 328d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenvoid BlackfinRegisterInfo:: 329d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund OlesenprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF, 330d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen RegScavenger *RS) const { 331d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen MachineFrameInfo *MFI = MF.getFrameInfo(); 332d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen const TargetRegisterClass *RC = BF::DPRegisterClass; 333d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen if (requiresRegisterScavenging(MF)) { 334d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen // Reserve a slot close to SP or frame pointer. 335d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 3363f2bf85d14759cc4b28a86805f566ac805a54d00David Greene RC->getAlignment(), 3373f2bf85d14759cc4b28a86805f566ac805a54d00David Greene false)); 338d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen } 339d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 340d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 341d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenunsigned BlackfinRegisterInfo::getRARegister() const { 342d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return BF::RETS; 343d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 344d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 3453f2bf85d14759cc4b28a86805f566ac805a54d00David Greeneunsigned 3463f2bf85d14759cc4b28a86805f566ac805a54d00David GreeneBlackfinRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 347d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); 348d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 349d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return TFI->hasFP(MF) ? BF::FP : BF::SP; 350d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 351d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 352d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenunsigned BlackfinRegisterInfo::getEHExceptionRegister() const { 353d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen llvm_unreachable("What is the exception register"); 354d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return 0; 355d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 356d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 357d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenunsigned BlackfinRegisterInfo::getEHHandlerRegister() const { 358d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen llvm_unreachable("What is the exception handler register"); 359d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return 0; 360d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 361d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 362d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesenint BlackfinRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { 363d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen llvm_unreachable("What is the dwarf register number"); 364d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen return -1; 365d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen} 366d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 367d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen#include "BlackfinGenRegisterInfo.inc" 368d950941e138455ebcd7a5f55805dcb977892e3e3Jakob Stoklund Olesen 369