1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===- BlackfinRegisterInfo.cpp - Blackfin Register Information -*- C++ -*-===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file contains the Blackfin implementation of the TargetRegisterInfo 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// class. 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Blackfin.h" 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "BlackfinRegisterInfo.h" 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "BlackfinSubtarget.h" 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineInstrBuilder.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFunction.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFrameInfo.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/RegisterScavenging.h" 2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetFrameLowering.h" 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetMachine.h" 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetOptions.h" 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetInstrInfo.h" 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Type.h" 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/BitVector.h" 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/STLExtras.h" 3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define GET_REGINFO_TARGET_DESC 3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "BlackfinGenRegisterInfo.inc" 3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanBlackfinRegisterInfo::BlackfinRegisterInfo(BlackfinSubtarget &st, 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetInstrInfo &tii) 3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman : BlackfinGenRegisterInfo(BF::RETS), Subtarget(st), TII(tii) {} 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanconst unsigned* 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanBlackfinRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman using namespace BF; 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static const unsigned CalleeSavedRegs[] = { 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FP, 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman R4, R5, R6, R7, 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman P3, P4, P5, 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 0 }; 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CalleeSavedRegs; 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanBitVector 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanBlackfinRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman using namespace BF; 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BitVector Reserved(getNumRegs()); 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(AZ); 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(AN); 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(AQ); 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(AC0); 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(AC1); 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(AV0); 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(AV0S); 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(AV1); 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(AV1S); 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(V); 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(VS); 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(CYCLES).set(CYCLES2); 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(L0); 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(L1); 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(L2); 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(L3); 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(SP); 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(RETS); 7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TFI->hasFP(MF)) 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reserved.set(FP); 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Reserved; 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool BlackfinRegisterInfo:: 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanrequiresRegisterScavenging(const MachineFunction &MF) const { 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Emit instructions to add delta to D/P register. ScratchReg must be of the 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// same class as Reg (P). 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid BlackfinRegisterInfo::adjustRegister(MachineBasicBlock &MBB, 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator I, 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc DL, 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Reg, 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ScratchReg, 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int delta) const { 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!delta) 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isInt<7>(delta)) { 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, I, DL, TII.get(BF::ADDpp_imm7), Reg) 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(Reg) // No kill on two-addr operand 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addImm(delta); 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We must load delta into ScratchReg and add that. 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loadConstant(MBB, I, DL, ScratchReg, delta); 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BF::PRegClass.contains(Reg)) { 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(BF::PRegClass.contains(ScratchReg) && 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "ScratchReg must be a P register"); 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, I, DL, TII.get(BF::ADDpp), Reg) 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(Reg, RegState::Kill) 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(ScratchReg, RegState::Kill); 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(BF::DRegClass.contains(Reg) && "Reg must be a D or P register"); 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(BF::DRegClass.contains(ScratchReg) && 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "ScratchReg must be a D register"); 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, I, DL, TII.get(BF::ADD), Reg) 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(Reg, RegState::Kill) 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(ScratchReg, RegState::Kill); 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Emit instructions to load a constant into D/P register 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid BlackfinRegisterInfo::loadConstant(MachineBasicBlock &MBB, 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator I, 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc DL, 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Reg, 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int value) const { 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isInt<7>(value)) { 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, I, DL, TII.get(BF::LOADimm7), Reg).addImm(value); 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isUInt<16>(value)) { 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, I, DL, TII.get(BF::LOADuimm16), Reg).addImm(value); 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isInt<16>(value)) { 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, I, DL, TII.get(BF::LOADimm16), Reg).addImm(value); 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We must split into halves 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, I, DL, 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TII.get(BF::LOAD16i), getSubReg(Reg, BF::hi16)) 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addImm((value >> 16) & 0xffff) 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(Reg, RegState::ImplicitDefine); 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, I, DL, 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TII.get(BF::LOAD16i), getSubReg(Reg, BF::lo16)) 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addImm(value & 0xffff) 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(Reg, RegState::ImplicitKill) 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(Reg, RegState::ImplicitDefine); 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid BlackfinRegisterInfo:: 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumaneliminateCallFramePseudoInstr(MachineFunction &MF, 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock &MBB, 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator I) const { 15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!TFI->hasReservedCallFrame(MF)) { 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int64_t Amount = I->getOperand(0).getImm(); 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Amount != 0) { 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Amount%4 == 0 && "Unaligned call frame size"); 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I->getOpcode() == BF::ADJCALLSTACKDOWN) { 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, -Amount); 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(I->getOpcode() == BF::ADJCALLSTACKUP && 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Unknown call frame pseudo instruction"); 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, Amount); 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MBB.erase(I); 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// findScratchRegister - Find a 'free' register. Try for a call-clobbered 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// register first and then a spilled callee-saved register if that fails. 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic unsigned findScratchRegister(MachineBasicBlock::iterator II, 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RegScavenger *RS, 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterClass *RC, 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int SPAdj) { 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(RS && "Register scavenging must be on"); 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Reg = RS->FindUnusedReg(RC); 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Reg == 0) 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Reg = RS->scavengeRegister(RC, II, SPAdj); 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Reg; 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanBlackfinRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int SPAdj, RegScavenger *RS) const { 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineInstr &MI = *II; 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock &MBB = *MI.getParent(); 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineFunction &MF = *MBB.getParent(); 19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc DL = MI.getDebugLoc(); 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned FIPos; 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (FIPos=0; !MI.getOperand(FIPos).isFI(); ++FIPos) { 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(FIPos < MI.getNumOperands() && 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Instr doesn't have FrameIndex operand!"); 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int FrameIndex = MI.getOperand(FIPos).getIndex(); 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(FIPos+1 < MI.getNumOperands() && MI.getOperand(FIPos+1).isImm()); 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman + MI.getOperand(FIPos+1).getImm(); 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned BaseReg = BF::FP; 20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TFI->hasFP(MF)) { 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(SPAdj==0 && "Unexpected SP adjust in function with frame pointer"); 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BaseReg = BF::SP; 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset += MF.getFrameInfo()->getStackSize() + SPAdj; 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isStore = false; 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (MI.getOpcode()) { 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BF::STORE32fi: 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isStore = true; 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BF::LOAD32fi: { 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Offset%4 == 0 && "Unaligned i32 stack access"); 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(FIPos==1 && "Bad frame index operand"); 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.getOperand(FIPos).ChangeToRegister(BaseReg, false); 224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.getOperand(FIPos+1).setImm(Offset); 225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isUInt<6>(Offset)) { 226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.setDesc(TII.get(isStore 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ? BF::STORE32p_uimm6m4 228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : BF::LOAD32p_uimm6m4)); 22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BaseReg == BF::FP && isUInt<7>(-Offset)) { 232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.setDesc(TII.get(isStore 233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ? BF::STORE32fp_nimm7m4 234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : BF::LOAD32fp_nimm7m4)); 235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.getOperand(FIPos+1).setImm(-Offset); 23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isInt<18>(Offset)) { 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.setDesc(TII.get(isStore 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ? BF::STORE32p_imm18m4 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : BF::LOAD32p_imm18m4)); 24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Use RegScavenger to calculate proper offset... 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.dump(); 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("Stack frame offset too big"); 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BF::ADDpp: { 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(MI.getOperand(0).isReg() && "ADD instruction needs a register"); 251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned DestReg = MI.getOperand(0).getReg(); 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We need to produce a stack offset in a P register. We emit: 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // P0 = offset; 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // P0 = BR + P0; 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(FIPos==1 && "Bad frame index operand"); 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loadConstant(MBB, II, DL, DestReg, Offset); 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.getOperand(1).ChangeToRegister(DestReg, false, false, true); 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.getOperand(2).ChangeToRegister(BaseReg, false); 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BF::STORE16fi: 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isStore = true; 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BF::LOAD16fi: { 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Offset%2 == 0 && "Unaligned i16 stack access"); 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(FIPos==1 && "Bad frame index operand"); 266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We need a P register to use as an address 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ScratchReg = findScratchRegister(II, RS, &BF::PRegClass, SPAdj); 268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(ScratchReg && "Could not scavenge register"); 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loadConstant(MBB, II, DL, ScratchReg, Offset); 270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, II, DL, TII.get(BF::ADDpp), ScratchReg) 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(ScratchReg, RegState::Kill) 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(BaseReg); 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.setDesc(TII.get(isStore ? BF::STORE16pi : BF::LOAD16pi)); 274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.getOperand(1).ChangeToRegister(ScratchReg, false, false, true); 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.RemoveOperand(2); 276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BF::STORE8fi: { 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This is an AnyCC spill, we need a scratch register. 280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(FIPos==1 && "Bad frame index operand"); 281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineOperand SpillReg = MI.getOperand(0); 282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj); 283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(ScratchReg && "Could not scavenge register"); 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SpillReg.getReg()==BF::NCC) { 285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, II, DL, TII.get(BF::MOVENCC_z), ScratchReg) 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addOperand(SpillReg); 287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, II, DL, TII.get(BF::BITTGL), ScratchReg) 288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(ScratchReg).addImm(0); 289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, II, DL, TII.get(BF::MOVECC_zext), ScratchReg) 291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addOperand(SpillReg); 292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // STORE D 294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.setDesc(TII.get(BF::STORE8p_imm16)); 295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.getOperand(0).ChangeToRegister(ScratchReg, false, false, true); 296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.getOperand(FIPos).ChangeToRegister(BaseReg, false); 297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.getOperand(FIPos+1).setImm(Offset); 298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BF::LOAD8fi: { 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This is an restore, we need a scratch register. 302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(FIPos==1 && "Bad frame index operand"); 303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineOperand SpillReg = MI.getOperand(0); 304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj); 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(ScratchReg && "Could not scavenge register"); 306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.setDesc(TII.get(BF::LOAD32p_imm16_8z)); 307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.getOperand(0).ChangeToRegister(ScratchReg, true); 308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.getOperand(FIPos).ChangeToRegister(BaseReg, false); 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI.getOperand(FIPos+1).setImm(Offset); 310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++II; 311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SpillReg.getReg()==BF::CC) { 312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // CC = D 313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, II, DL, TII.get(BF::MOVECC_nz), BF::CC) 314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(ScratchReg, RegState::Kill); 315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Restore NCC (CC = D==0) 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, II, DL, TII.get(BF::SETEQri_not), BF::NCC) 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(ScratchReg, RegState::Kill) 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addImm(0); 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("Cannot eliminate frame index"); 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanBlackfinRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return TFI->hasFP(MF) ? BF::FP : BF::SP; 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned BlackfinRegisterInfo::getEHExceptionRegister() const { 337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("What is the exception register"); 338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned BlackfinRegisterInfo::getEHHandlerRegister() const { 342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("What is the exception handler register"); 343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 345