1227825Stheraven//===-- MipsRegisterInfo.cpp - MIPS Register Information -== --------------===// 2227825Stheraven// 3227825Stheraven// The LLVM Compiler Infrastructure 4227825Stheraven// 5227825Stheraven// This file is distributed under the University of Illinois Open Source 6227825Stheraven// License. See LICENSE.TXT for details. 7227825Stheraven// 8227825Stheraven//===----------------------------------------------------------------------===// 9227825Stheraven// 10262801Sdim// This file contains the MIPS implementation of the TargetRegisterInfo class. 11227825Stheraven// 12227825Stheraven//===----------------------------------------------------------------------===// 13262801Sdim 14227825Stheraven#define DEBUG_TYPE "mips-reg-info" 15241903Sdim 16241903Sdim#include "MipsRegisterInfo.h" 17241903Sdim#include "Mips.h" 18241903Sdim#include "MipsAnalyzeImmediate.h" 19278724Sdim#include "MipsInstrInfo.h" 20227825Stheraven#include "MipsMachineFunction.h" 21232950Stheraven#include "MipsSubtarget.h" 22227825Stheraven#include "llvm/ADT/BitVector.h" 23227825Stheraven#include "llvm/ADT/STLExtras.h" 24232950Stheraven#include "llvm/CodeGen/MachineFrameInfo.h" 25232950Stheraven#include "llvm/CodeGen/MachineFunction.h" 26232950Stheraven#include "llvm/CodeGen/MachineInstrBuilder.h" 27262801Sdim#include "llvm/CodeGen/ValueTypes.h" 28232950Stheraven#include "llvm/DebugInfo.h" 29232950Stheraven#include "llvm/IR/Constants.h" 30232950Stheraven#include "llvm/IR/Type.h" 31232950Stheraven#include "llvm/Support/CommandLine.h" 32241903Sdim#include "llvm/Support/Debug.h" 33227825Stheraven#include "llvm/Support/ErrorHandling.h" 34227825Stheraven#include "llvm/Support/raw_ostream.h" 35241903Sdim#include "llvm/Target/TargetFrameLowering.h" 36241903Sdim#include "llvm/Target/TargetInstrInfo.h" 37241903Sdim#include "llvm/Target/TargetMachine.h" 38246487Stheraven#include "llvm/Target/TargetOptions.h" 39227825Stheraven 40227825Stheraven#define GET_REGINFO_TARGET_DESC 41241903Sdim#include "MipsGenRegisterInfo.inc" 42227825Stheraven 43232950Stheravenusing namespace llvm; 44232950Stheraven 45232950StheravenMipsRegisterInfo::MipsRegisterInfo(const MipsSubtarget &ST) 46246487Stheraven : MipsGenRegisterInfo(Mips::RA), Subtarget(ST) {} 47232950Stheraven 48227825Stheravenunsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; } 49232950Stheraven 50232950Stheravenconst TargetRegisterClass * 51227825StheravenMipsRegisterInfo::getPointerRegClass(const MachineFunction &MF, 52227825Stheraven unsigned Kind) const { 53227825Stheraven return Subtarget.isABI_N64() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass; 54227825Stheraven} 55232950Stheraven 56232950Stheravenunsigned 57227825StheravenMipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, 58232950Stheraven MachineFunction &MF) const { 59227825Stheraven switch (RC->getID()) { 60227825Stheraven default: 61241903Sdim return 0; 62227825Stheraven case Mips::GPR32RegClassID: 63232950Stheraven case Mips::GPR64RegClassID: 64227825Stheraven case Mips::DSPRRegClassID: { 65232950Stheraven const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 66227825Stheraven return 28 - TFI->hasFP(MF); 67232950Stheraven } 68227825Stheraven case Mips::FGR32RegClassID: 69227825Stheraven return 32; 70232950Stheraven case Mips::AFGR64RegClassID: 71232950Stheraven return 16; 72227825Stheraven case Mips::FGR64RegClassID: 73227825Stheraven return 32; 74227825Stheraven } 75227825Stheraven} 76232950Stheraven 77232950Stheraven//===----------------------------------------------------------------------===// 78227825Stheraven// Callee Saved Registers methods 79232950Stheraven//===----------------------------------------------------------------------===// 80227825Stheraven 81227825Stheraven/// Mips Callee Saved Registers 82262801Sdimconst uint16_t* MipsRegisterInfo:: 83241903SdimgetCalleeSavedRegs(const MachineFunction *MF) const { 84227825Stheraven if (Subtarget.isSingleFloat()) 85232950Stheraven return CSR_SingleFloatOnly_SaveList; 86227825Stheraven 87227825Stheraven if (Subtarget.isABI_N64()) 88227825Stheraven return CSR_N64_SaveList; 89227825Stheraven 90227825Stheraven if (Subtarget.isABI_N32()) 91232950Stheraven return CSR_N32_SaveList; 92227825Stheraven 93262801Sdim if (Subtarget.isFP64bit()) 94262801Sdim return CSR_O32_FP64_SaveList; 95227825Stheraven 96227825Stheraven return CSR_O32_SaveList; 97227825Stheraven} 98227825Stheraven 99227825Stheravenconst uint32_t* 100262801SdimMipsRegisterInfo::getCallPreservedMask(CallingConv::ID) const { 101262801Sdim if (Subtarget.isSingleFloat()) 102227825Stheraven return CSR_SingleFloatOnly_RegMask; 103227825Stheraven 104227825Stheraven if (Subtarget.isABI_N64()) 105262801Sdim return CSR_N64_RegMask; 106232950Stheraven 107227825Stheraven if (Subtarget.isABI_N32()) 108262801Sdim return CSR_N32_RegMask; 109232950Stheraven 110227825Stheraven if (Subtarget.isFP64bit()) 111249998Sdim return CSR_O32_FP64_RegMask; 112227825Stheraven 113232950Stheraven return CSR_O32_RegMask; 114227825Stheraven} 115262801Sdim 116262801Sdimconst uint32_t *MipsRegisterInfo::getMips16RetHelperMask() { 117262801Sdim return CSR_Mips16RetHelper_RegMask; 118262801Sdim} 119262801Sdim 120262801SdimBitVector MipsRegisterInfo:: 121227825StheravengetReservedRegs(const MachineFunction &MF) const { 122227825Stheraven static const uint16_t ReservedGPR32[] = { 123227825Stheraven Mips::ZERO, Mips::K0, Mips::K1, Mips::SP 124227825Stheraven }; 125262801Sdim 126232950Stheraven static const uint16_t ReservedGPR64[] = { 127227825Stheraven Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64 128227825Stheraven }; 129227825Stheraven 130227825Stheraven BitVector Reserved(getNumRegs()); 131227825Stheraven typedef TargetRegisterClass::const_iterator RegIter; 132232972Stheraven 133227825Stheraven for (unsigned I = 0; I < array_lengthof(ReservedGPR32); ++I) 134232972Stheraven Reserved.set(ReservedGPR32[I]); 135227825Stheraven 136227825Stheraven for (unsigned I = 0; I < array_lengthof(ReservedGPR64); ++I) 137232972Stheraven Reserved.set(ReservedGPR64[I]); 138232972Stheraven 139246487Stheraven if (Subtarget.isFP64bit()) { 140232972Stheraven // Reserve all registers in AFGR64. 141232972Stheraven for (RegIter Reg = Mips::AFGR64RegClass.begin(), 142227825Stheraven EReg = Mips::AFGR64RegClass.end(); Reg != EReg; ++Reg) 143227825Stheraven Reserved.set(*Reg); 144227825Stheraven } else { 145227825Stheraven // Reserve all registers in FGR64. 146227825Stheraven for (RegIter Reg = Mips::FGR64RegClass.begin(), 147227825Stheraven EReg = Mips::FGR64RegClass.end(); Reg != EReg; ++Reg) 148227825Stheraven Reserved.set(*Reg); 149227825Stheraven } 150232972Stheraven // Reserve FP if this function should have a dedicated frame pointer register. 151232950Stheraven if (MF.getTarget().getFrameLowering()->hasFP(MF)) { 152262801Sdim if (Subtarget.inMips16Mode()) 153232972Stheraven Reserved.set(Mips::S0); 154262801Sdim else { 155262801Sdim Reserved.set(Mips::FP); 156262801Sdim Reserved.set(Mips::FP_64); 157262801Sdim } 158262801Sdim } 159262801Sdim 160262801Sdim // Reserve hardware registers. 161262801Sdim Reserved.set(Mips::HWR29); 162262801Sdim 163262801Sdim // Reserve DSP control register. 164262801Sdim Reserved.set(Mips::DSPPos); 165262801Sdim Reserved.set(Mips::DSPSCount); 166262801Sdim Reserved.set(Mips::DSPCarry); 167262801Sdim Reserved.set(Mips::DSPEFI); 168262801Sdim Reserved.set(Mips::DSPOutFlag); 169262801Sdim 170262801Sdim // Reserve MSA control registers. 171262801Sdim Reserved.set(Mips::MSAIR); 172262801Sdim Reserved.set(Mips::MSACSR); 173262801Sdim Reserved.set(Mips::MSAAccess); 174262801Sdim Reserved.set(Mips::MSASave); 175262801Sdim Reserved.set(Mips::MSAModify); 176262801Sdim Reserved.set(Mips::MSARequest); 177262801Sdim Reserved.set(Mips::MSAMap); 178262801Sdim Reserved.set(Mips::MSAUnmap); 179262801Sdim 180262801Sdim // Reserve RA if in mips16 mode. 181227825Stheraven if (Subtarget.inMips16Mode()) { 182227825Stheraven Reserved.set(Mips::RA); 183227825Stheraven Reserved.set(Mips::RA_64); 184227825Stheraven Reserved.set(Mips::T0); 185262801Sdim Reserved.set(Mips::T1); 186262801Sdim } 187227825Stheraven 188262801Sdim // Reserve GP if small section is used. 189262801Sdim if (Subtarget.useSmallSection()) { 190262801Sdim Reserved.set(Mips::GP); 191262801Sdim Reserved.set(Mips::GP_64); 192262801Sdim } 193262801Sdim 194227825Stheraven return Reserved; 195262801Sdim} 196227825Stheraven 197227825Stheravenbool 198227825StheravenMipsRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { 199227825Stheraven return true; 200227825Stheraven} 201227825Stheraven 202227825Stheravenbool 203262801SdimMipsRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const { 204262801Sdim return true; 205262801Sdim} 206227825Stheraven 207262801Sdim// FrameIndex represent objects inside a abstract stack. 208262801Sdim// We must replace FrameIndex with an stack/frame pointer 209262801Sdim// direct reference. 210262801Sdimvoid MipsRegisterInfo:: 211262801SdimeliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, 212262801Sdim unsigned FIOperandNum, RegScavenger *RS) const { 213227825Stheraven MachineInstr &MI = *II; 214262801Sdim MachineFunction &MF = *MI.getParent()->getParent(); 215227825Stheraven 216227825Stheraven DEBUG(errs() << "\nFunction : " << MF.getName() << "\n"; 217227825Stheraven errs() << "<--------->\n" << MI); 218227825Stheraven 219227825Stheraven int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 220227825Stheraven uint64_t stackSize = MF.getFrameInfo()->getStackSize(); 221227825Stheraven int64_t spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 222227825Stheraven 223227825Stheraven DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n" 224227825Stheraven << "spOffset : " << spOffset << "\n" 225227825Stheraven << "stackSize : " << stackSize << "\n"); 226227825Stheraven 227262801Sdim eliminateFI(MI, FIOperandNum, FrameIndex, stackSize, spOffset); 228262801Sdim} 229262801Sdim 230262801Sdimunsigned MipsRegisterInfo:: 231262801SdimgetFrameRegister(const MachineFunction &MF) const { 232262801Sdim const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 233262801Sdim bool IsN64 = Subtarget.isABI_N64(); 234262801Sdim 235262801Sdim if (Subtarget.inMips16Mode()) 236262801Sdim return TFI->hasFP(MF) ? Mips::S0 : Mips::SP; 237262801Sdim else 238227825Stheraven return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) : 239262801Sdim (IsN64 ? Mips::SP_64 : Mips::SP); 240227825Stheraven 241227825Stheraven} 242227825Stheraven 243227825Stheraven