LLVM API Documentation

MipsRegisterInfo.cpp
Go to the documentation of this file.
00001 //===-- MipsRegisterInfo.cpp - MIPS Register Information -== --------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the MIPS implementation of the TargetRegisterInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "MipsRegisterInfo.h"
00015 #include "Mips.h"
00016 #include "MipsAnalyzeImmediate.h"
00017 #include "MipsInstrInfo.h"
00018 #include "MipsMachineFunction.h"
00019 #include "MipsSubtarget.h"
00020 #include "llvm/ADT/BitVector.h"
00021 #include "llvm/ADT/STLExtras.h"
00022 #include "llvm/CodeGen/MachineFrameInfo.h"
00023 #include "llvm/CodeGen/MachineFunction.h"
00024 #include "llvm/CodeGen/MachineInstrBuilder.h"
00025 #include "llvm/IR/Constants.h"
00026 #include "llvm/IR/DebugInfo.h"
00027 #include "llvm/IR/Function.h"
00028 #include "llvm/IR/Type.h"
00029 #include "llvm/Support/CommandLine.h"
00030 #include "llvm/Support/Debug.h"
00031 #include "llvm/Support/ErrorHandling.h"
00032 #include "llvm/Support/raw_ostream.h"
00033 #include "llvm/Target/TargetFrameLowering.h"
00034 #include "llvm/Target/TargetInstrInfo.h"
00035 #include "llvm/Target/TargetMachine.h"
00036 #include "llvm/Target/TargetOptions.h"
00037 
00038 using namespace llvm;
00039 
00040 #define DEBUG_TYPE "mips-reg-info"
00041 
00042 #define GET_REGINFO_TARGET_DESC
00043 #include "MipsGenRegisterInfo.inc"
00044 
00045 MipsRegisterInfo::MipsRegisterInfo(const MipsSubtarget &ST)
00046   : MipsGenRegisterInfo(Mips::RA), Subtarget(ST) {}
00047 
00048 unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; }
00049 
00050 const TargetRegisterClass *
00051 MipsRegisterInfo::getPointerRegClass(const MachineFunction &MF,
00052                                      unsigned Kind) const {
00053   return Subtarget.isABI_N64() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
00054 }
00055 
00056 unsigned
00057 MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
00058                                       MachineFunction &MF) const {
00059   switch (RC->getID()) {
00060   default:
00061     return 0;
00062   case Mips::GPR32RegClassID:
00063   case Mips::GPR64RegClassID:
00064   case Mips::DSPRRegClassID: {
00065     const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
00066     return 28 - TFI->hasFP(MF);
00067   }
00068   case Mips::FGR32RegClassID:
00069     return 32;
00070   case Mips::AFGR64RegClassID:
00071     return 16;
00072   case Mips::FGR64RegClassID:
00073     return 32;
00074   }
00075 }
00076 
00077 //===----------------------------------------------------------------------===//
00078 // Callee Saved Registers methods
00079 //===----------------------------------------------------------------------===//
00080 
00081 /// Mips Callee Saved Registers
00082 const MCPhysReg *
00083 MipsRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
00084   if (Subtarget.isSingleFloat())
00085     return CSR_SingleFloatOnly_SaveList;
00086 
00087   if (Subtarget.isABI_N64())
00088     return CSR_N64_SaveList;
00089 
00090   if (Subtarget.isABI_N32())
00091     return CSR_N32_SaveList;
00092 
00093   if (Subtarget.isFP64bit())
00094     return CSR_O32_FP64_SaveList;
00095 
00096   if (Subtarget.isFPXX())
00097     return CSR_O32_FPXX_SaveList;
00098 
00099   return CSR_O32_SaveList;
00100 }
00101 
00102 const uint32_t*
00103 MipsRegisterInfo::getCallPreservedMask(CallingConv::ID) const {
00104   if (Subtarget.isSingleFloat())
00105     return CSR_SingleFloatOnly_RegMask;
00106 
00107   if (Subtarget.isABI_N64())
00108     return CSR_N64_RegMask;
00109 
00110   if (Subtarget.isABI_N32())
00111     return CSR_N32_RegMask;
00112 
00113   if (Subtarget.isFP64bit())
00114     return CSR_O32_FP64_RegMask;
00115 
00116   if (Subtarget.isFPXX())
00117     return CSR_O32_FPXX_RegMask;
00118 
00119   return CSR_O32_RegMask;
00120 }
00121 
00122 const uint32_t *MipsRegisterInfo::getMips16RetHelperMask() {
00123   return CSR_Mips16RetHelper_RegMask;
00124 }
00125 
00126 BitVector MipsRegisterInfo::
00127 getReservedRegs(const MachineFunction &MF) const {
00128   static const MCPhysReg ReservedGPR32[] = {
00129     Mips::ZERO, Mips::K0, Mips::K1, Mips::SP
00130   };
00131 
00132   static const MCPhysReg ReservedGPR64[] = {
00133     Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64
00134   };
00135 
00136   BitVector Reserved(getNumRegs());
00137   typedef TargetRegisterClass::const_iterator RegIter;
00138 
00139   for (unsigned I = 0; I < array_lengthof(ReservedGPR32); ++I)
00140     Reserved.set(ReservedGPR32[I]);
00141 
00142   // Reserve registers for the NaCl sandbox.
00143   if (Subtarget.isTargetNaCl()) {
00144     Reserved.set(Mips::T6);   // Reserved for control flow mask.
00145     Reserved.set(Mips::T7);   // Reserved for memory access mask.
00146     Reserved.set(Mips::T8);   // Reserved for thread pointer.
00147   }
00148 
00149   for (unsigned I = 0; I < array_lengthof(ReservedGPR64); ++I)
00150     Reserved.set(ReservedGPR64[I]);
00151 
00152   // For mno-abicalls, GP is a program invariant!
00153   if (!Subtarget.isABICalls()) {
00154     Reserved.set(Mips::GP);
00155     Reserved.set(Mips::GP_64);
00156   }
00157 
00158   if (Subtarget.isFP64bit()) {
00159     // Reserve all registers in AFGR64.
00160     for (RegIter Reg = Mips::AFGR64RegClass.begin(),
00161          EReg = Mips::AFGR64RegClass.end(); Reg != EReg; ++Reg)
00162       Reserved.set(*Reg);
00163   } else {
00164     // Reserve all registers in FGR64.
00165     for (RegIter Reg = Mips::FGR64RegClass.begin(),
00166          EReg = Mips::FGR64RegClass.end(); Reg != EReg; ++Reg)
00167       Reserved.set(*Reg);
00168   }
00169   // Reserve FP if this function should have a dedicated frame pointer register.
00170   if (MF.getSubtarget().getFrameLowering()->hasFP(MF)) {
00171     if (Subtarget.inMips16Mode())
00172       Reserved.set(Mips::S0);
00173     else {
00174       Reserved.set(Mips::FP);
00175       Reserved.set(Mips::FP_64);
00176     }
00177   }
00178 
00179   // Reserve hardware registers.
00180   Reserved.set(Mips::HWR29);
00181 
00182   // Reserve DSP control register.
00183   Reserved.set(Mips::DSPPos);
00184   Reserved.set(Mips::DSPSCount);
00185   Reserved.set(Mips::DSPCarry);
00186   Reserved.set(Mips::DSPEFI);
00187   Reserved.set(Mips::DSPOutFlag);
00188 
00189   // Reserve MSA control registers.
00190   Reserved.set(Mips::MSAIR);
00191   Reserved.set(Mips::MSACSR);
00192   Reserved.set(Mips::MSAAccess);
00193   Reserved.set(Mips::MSASave);
00194   Reserved.set(Mips::MSAModify);
00195   Reserved.set(Mips::MSARequest);
00196   Reserved.set(Mips::MSAMap);
00197   Reserved.set(Mips::MSAUnmap);
00198 
00199   // Reserve RA if in mips16 mode.
00200   if (Subtarget.inMips16Mode()) {
00201     const MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
00202     Reserved.set(Mips::RA);
00203     Reserved.set(Mips::RA_64);
00204     Reserved.set(Mips::T0);
00205     Reserved.set(Mips::T1);
00206     if (MF.getFunction()->hasFnAttribute("saveS2") || MipsFI->hasSaveS2())
00207       Reserved.set(Mips::S2);
00208   }
00209 
00210   // Reserve GP if small section is used.
00211   if (Subtarget.useSmallSection()) {
00212     Reserved.set(Mips::GP);
00213     Reserved.set(Mips::GP_64);
00214   }
00215 
00216   if (Subtarget.isABI_O32() && !Subtarget.useOddSPReg()) {
00217     for (const auto &Reg : Mips::OddSPRegClass)
00218       Reserved.set(Reg);
00219   }
00220 
00221   return Reserved;
00222 }
00223 
00224 bool
00225 MipsRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
00226   return true;
00227 }
00228 
00229 bool
00230 MipsRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
00231   return true;
00232 }
00233 
00234 // FrameIndex represent objects inside a abstract stack.
00235 // We must replace FrameIndex with an stack/frame pointer
00236 // direct reference.
00237 void MipsRegisterInfo::
00238 eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
00239                     unsigned FIOperandNum, RegScavenger *RS) const {
00240   MachineInstr &MI = *II;
00241   MachineFunction &MF = *MI.getParent()->getParent();
00242 
00243   DEBUG(errs() << "\nFunction : " << MF.getName() << "\n";
00244         errs() << "<--------->\n" << MI);
00245 
00246   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
00247   uint64_t stackSize = MF.getFrameInfo()->getStackSize();
00248   int64_t spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
00249 
00250   DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
00251                << "spOffset   : " << spOffset << "\n"
00252                << "stackSize  : " << stackSize << "\n");
00253 
00254   eliminateFI(MI, FIOperandNum, FrameIndex, stackSize, spOffset);
00255 }
00256 
00257 unsigned MipsRegisterInfo::
00258 getFrameRegister(const MachineFunction &MF) const {
00259   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
00260   bool IsN64 = Subtarget.isABI_N64();
00261 
00262   if (Subtarget.inMips16Mode())
00263     return TFI->hasFP(MF) ? Mips::S0 : Mips::SP;
00264   else
00265     return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) :
00266                             (IsN64 ? Mips::SP_64 : Mips::SP);
00267 
00268 }
00269