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