Home | History | Annotate | Download | only in Mips
      1 //===-- MipsRegisterInfo.cpp - MIPS Register Information -== --------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains the MIPS implementation of the TargetRegisterInfo class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "MipsRegisterInfo.h"
     15 #include "Mips.h"
     16 #include "MipsInstrInfo.h"
     17 #include "MipsMachineFunction.h"
     18 #include "MipsSubtarget.h"
     19 #include "MipsTargetMachine.h"
     20 #include "llvm/ADT/BitVector.h"
     21 #include "llvm/ADT/STLExtras.h"
     22 #include "llvm/CodeGen/MachineFrameInfo.h"
     23 #include "llvm/CodeGen/MachineFunction.h"
     24 #include "llvm/CodeGen/MachineInstrBuilder.h"
     25 #include "llvm/CodeGen/MachineRegisterInfo.h"
     26 #include "llvm/IR/Constants.h"
     27 #include "llvm/IR/DebugInfo.h"
     28 #include "llvm/IR/Function.h"
     29 #include "llvm/IR/Type.h"
     30 #include "llvm/Support/Debug.h"
     31 #include "llvm/Support/ErrorHandling.h"
     32 #include "llvm/Support/raw_ostream.h"
     33 #include "llvm/Target/TargetFrameLowering.h"
     34 #include "llvm/Target/TargetInstrInfo.h"
     35 #include "llvm/Target/TargetMachine.h"
     36 #include "llvm/Target/TargetOptions.h"
     37 
     38 using namespace llvm;
     39 
     40 #define DEBUG_TYPE "mips-reg-info"
     41 
     42 #define GET_REGINFO_TARGET_DESC
     43 #include "MipsGenRegisterInfo.inc"
     44 
     45 MipsRegisterInfo::MipsRegisterInfo() : MipsGenRegisterInfo(Mips::RA) {}
     46 
     47 unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; }
     48 
     49 const TargetRegisterClass *
     50 MipsRegisterInfo::getPointerRegClass(const MachineFunction &MF,
     51                                      unsigned Kind) const {
     52   MipsABIInfo ABI = MF.getSubtarget<MipsSubtarget>().getABI();
     53   MipsPtrClass PtrClassKind = static_cast<MipsPtrClass>(Kind);
     54 
     55   switch (PtrClassKind) {
     56   case MipsPtrClass::Default:
     57     return ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
     58   case MipsPtrClass::GPR16MM:
     59     return ABI.ArePtrs64bit() ? &Mips::GPRMM16_64RegClass
     60                               : &Mips::GPRMM16RegClass;
     61   case MipsPtrClass::StackPointer:
     62     return ABI.ArePtrs64bit() ? &Mips::SP64RegClass : &Mips::SP32RegClass;
     63   case MipsPtrClass::GlobalPointer:
     64     return ABI.ArePtrs64bit() ? &Mips::GP64RegClass : &Mips::GP32RegClass;
     65   }
     66 
     67   llvm_unreachable("Unknown pointer kind");
     68 }
     69 
     70 unsigned
     71 MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
     72                                       MachineFunction &MF) const {
     73   switch (RC->getID()) {
     74   default:
     75     return 0;
     76   case Mips::GPR32RegClassID:
     77   case Mips::GPR64RegClassID:
     78   case Mips::DSPRRegClassID: {
     79     const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
     80     return 28 - TFI->hasFP(MF);
     81   }
     82   case Mips::FGR32RegClassID:
     83     return 32;
     84   case Mips::AFGR64RegClassID:
     85     return 16;
     86   case Mips::FGR64RegClassID:
     87     return 32;
     88   }
     89 }
     90 
     91 //===----------------------------------------------------------------------===//
     92 // Callee Saved Registers methods
     93 //===----------------------------------------------------------------------===//
     94 
     95 /// Mips Callee Saved Registers
     96 const MCPhysReg *
     97 MipsRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
     98   const MipsSubtarget &Subtarget = MF->getSubtarget<MipsSubtarget>();
     99   const Function *F = MF->getFunction();
    100   if (F->hasFnAttribute("interrupt")) {
    101     if (Subtarget.hasMips64())
    102       return Subtarget.hasMips64r6() ? CSR_Interrupt_64R6_SaveList
    103                                      : CSR_Interrupt_64_SaveList;
    104     else
    105       return Subtarget.hasMips32r6() ? CSR_Interrupt_32R6_SaveList
    106                                      : CSR_Interrupt_32_SaveList;
    107   }
    108 
    109   if (Subtarget.isSingleFloat())
    110     return CSR_SingleFloatOnly_SaveList;
    111 
    112   if (Subtarget.isABI_N64())
    113     return CSR_N64_SaveList;
    114 
    115   if (Subtarget.isABI_N32())
    116     return CSR_N32_SaveList;
    117 
    118   if (Subtarget.isFP64bit())
    119     return CSR_O32_FP64_SaveList;
    120 
    121   if (Subtarget.isFPXX())
    122     return CSR_O32_FPXX_SaveList;
    123 
    124   return CSR_O32_SaveList;
    125 }
    126 
    127 const uint32_t *
    128 MipsRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
    129                                        CallingConv::ID) const {
    130   const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
    131   if (Subtarget.isSingleFloat())
    132     return CSR_SingleFloatOnly_RegMask;
    133 
    134   if (Subtarget.isABI_N64())
    135     return CSR_N64_RegMask;
    136 
    137   if (Subtarget.isABI_N32())
    138     return CSR_N32_RegMask;
    139 
    140   if (Subtarget.isFP64bit())
    141     return CSR_O32_FP64_RegMask;
    142 
    143   if (Subtarget.isFPXX())
    144     return CSR_O32_FPXX_RegMask;
    145 
    146   return CSR_O32_RegMask;
    147 }
    148 
    149 const uint32_t *MipsRegisterInfo::getMips16RetHelperMask() {
    150   return CSR_Mips16RetHelper_RegMask;
    151 }
    152 
    153 BitVector MipsRegisterInfo::
    154 getReservedRegs(const MachineFunction &MF) const {
    155   static const MCPhysReg ReservedGPR32[] = {
    156     Mips::ZERO, Mips::K0, Mips::K1, Mips::SP
    157   };
    158 
    159   static const MCPhysReg ReservedGPR64[] = {
    160     Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64
    161   };
    162 
    163   BitVector Reserved(getNumRegs());
    164   const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
    165   typedef TargetRegisterClass::const_iterator RegIter;
    166 
    167   for (unsigned I = 0; I < array_lengthof(ReservedGPR32); ++I)
    168     Reserved.set(ReservedGPR32[I]);
    169 
    170   // Reserve registers for the NaCl sandbox.
    171   if (Subtarget.isTargetNaCl()) {
    172     Reserved.set(Mips::T6);   // Reserved for control flow mask.
    173     Reserved.set(Mips::T7);   // Reserved for memory access mask.
    174     Reserved.set(Mips::T8);   // Reserved for thread pointer.
    175   }
    176 
    177   for (unsigned I = 0; I < array_lengthof(ReservedGPR64); ++I)
    178     Reserved.set(ReservedGPR64[I]);
    179 
    180   // For mno-abicalls, GP is a program invariant!
    181   if (!Subtarget.isABICalls()) {
    182     Reserved.set(Mips::GP);
    183     Reserved.set(Mips::GP_64);
    184   }
    185 
    186   if (Subtarget.isFP64bit()) {
    187     // Reserve all registers in AFGR64.
    188     for (RegIter Reg = Mips::AFGR64RegClass.begin(),
    189          EReg = Mips::AFGR64RegClass.end(); Reg != EReg; ++Reg)
    190       Reserved.set(*Reg);
    191   } else {
    192     // Reserve all registers in FGR64.
    193     for (RegIter Reg = Mips::FGR64RegClass.begin(),
    194          EReg = Mips::FGR64RegClass.end(); Reg != EReg; ++Reg)
    195       Reserved.set(*Reg);
    196   }
    197   // Reserve FP if this function should have a dedicated frame pointer register.
    198   if (Subtarget.getFrameLowering()->hasFP(MF)) {
    199     if (Subtarget.inMips16Mode())
    200       Reserved.set(Mips::S0);
    201     else {
    202       Reserved.set(Mips::FP);
    203       Reserved.set(Mips::FP_64);
    204 
    205       // Reserve the base register if we need to both realign the stack and
    206       // allocate variable-sized objects at runtime. This should test the
    207       // same conditions as MipsFrameLowering::hasBP().
    208       if (needsStackRealignment(MF) &&
    209           MF.getFrameInfo()->hasVarSizedObjects()) {
    210         Reserved.set(Mips::S7);
    211         Reserved.set(Mips::S7_64);
    212       }
    213     }
    214   }
    215 
    216   // Reserve hardware registers.
    217   Reserved.set(Mips::HWR29);
    218 
    219   // Reserve DSP control register.
    220   Reserved.set(Mips::DSPPos);
    221   Reserved.set(Mips::DSPSCount);
    222   Reserved.set(Mips::DSPCarry);
    223   Reserved.set(Mips::DSPEFI);
    224   Reserved.set(Mips::DSPOutFlag);
    225 
    226   // Reserve MSA control registers.
    227   Reserved.set(Mips::MSAIR);
    228   Reserved.set(Mips::MSACSR);
    229   Reserved.set(Mips::MSAAccess);
    230   Reserved.set(Mips::MSASave);
    231   Reserved.set(Mips::MSAModify);
    232   Reserved.set(Mips::MSARequest);
    233   Reserved.set(Mips::MSAMap);
    234   Reserved.set(Mips::MSAUnmap);
    235 
    236   // Reserve RA if in mips16 mode.
    237   if (Subtarget.inMips16Mode()) {
    238     const MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
    239     Reserved.set(Mips::RA);
    240     Reserved.set(Mips::RA_64);
    241     Reserved.set(Mips::T0);
    242     Reserved.set(Mips::T1);
    243     if (MF.getFunction()->hasFnAttribute("saveS2") || MipsFI->hasSaveS2())
    244       Reserved.set(Mips::S2);
    245   }
    246 
    247   // Reserve GP if small section is used.
    248   if (Subtarget.useSmallSection()) {
    249     Reserved.set(Mips::GP);
    250     Reserved.set(Mips::GP_64);
    251   }
    252 
    253   if (Subtarget.isABI_O32() && !Subtarget.useOddSPReg()) {
    254     for (const auto &Reg : Mips::OddSPRegClass)
    255       Reserved.set(Reg);
    256   }
    257 
    258   return Reserved;
    259 }
    260 
    261 bool
    262 MipsRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
    263   return true;
    264 }
    265 
    266 bool
    267 MipsRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
    268   return true;
    269 }
    270 
    271 // FrameIndex represent objects inside a abstract stack.
    272 // We must replace FrameIndex with an stack/frame pointer
    273 // direct reference.
    274 void MipsRegisterInfo::
    275 eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
    276                     unsigned FIOperandNum, RegScavenger *RS) const {
    277   MachineInstr &MI = *II;
    278   MachineFunction &MF = *MI.getParent()->getParent();
    279 
    280   DEBUG(errs() << "\nFunction : " << MF.getName() << "\n";
    281         errs() << "<--------->\n" << MI);
    282 
    283   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
    284   uint64_t stackSize = MF.getFrameInfo()->getStackSize();
    285   int64_t spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
    286 
    287   DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
    288                << "spOffset   : " << spOffset << "\n"
    289                << "stackSize  : " << stackSize << "\n");
    290 
    291   eliminateFI(MI, FIOperandNum, FrameIndex, stackSize, spOffset);
    292 }
    293 
    294 unsigned MipsRegisterInfo::
    295 getFrameRegister(const MachineFunction &MF) const {
    296   const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
    297   const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
    298   bool IsN64 =
    299       static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI().IsN64();
    300 
    301   if (Subtarget.inMips16Mode())
    302     return TFI->hasFP(MF) ? Mips::S0 : Mips::SP;
    303   else
    304     return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) :
    305                             (IsN64 ? Mips::SP_64 : Mips::SP);
    306 }
    307 
    308 bool MipsRegisterInfo::canRealignStack(const MachineFunction &MF) const {
    309   // Avoid realigning functions that explicitly do not want to be realigned.
    310   // Normally, we should report an error when a function should be dynamically
    311   // realigned but also has the attribute no-realign-stack. Unfortunately,
    312   // with this attribute, MachineFrameInfo clamps each new object's alignment
    313   // to that of the stack's alignment as specified by the ABI. As a result,
    314   // the information of whether we have objects with larger alignment
    315   // requirement than the stack's alignment is already lost at this point.
    316   if (!TargetRegisterInfo::canRealignStack(MF))
    317     return false;
    318 
    319   const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
    320   unsigned FP = Subtarget.isGP32bit() ? Mips::FP : Mips::FP_64;
    321   unsigned BP = Subtarget.isGP32bit() ? Mips::S7 : Mips::S7_64;
    322 
    323   // Support dynamic stack realignment only for targets with standard encoding.
    324   if (!Subtarget.hasStandardEncoding())
    325     return false;
    326 
    327   // We can't perform dynamic stack realignment if we can't reserve the
    328   // frame pointer register.
    329   if (!MF.getRegInfo().canReserveReg(FP))
    330     return false;
    331 
    332   // We can realign the stack if we know the maximum call frame size and we
    333   // don't have variable sized objects.
    334   if (Subtarget.getFrameLowering()->hasReservedCallFrame(MF))
    335     return true;
    336 
    337   // We have to reserve the base pointer register in the presence of variable
    338   // sized objects.
    339   return MF.getRegInfo().canReserveReg(BP);
    340 }
    341