brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.9 KiB · 6ca587b Raw
320 lines · cpp
1//===- MipsRegisterInfo.cpp - MIPS Register Information -------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the MIPS implementation of the TargetRegisterInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "MipsRegisterInfo.h"14#include "MCTargetDesc/MipsABIInfo.h"15#include "Mips.h"16#include "MipsMachineFunction.h"17#include "MipsSubtarget.h"18#include "MipsTargetMachine.h"19#include "llvm/ADT/BitVector.h"20#include "llvm/CodeGen/MachineFrameInfo.h"21#include "llvm/CodeGen/MachineFunction.h"22#include "llvm/CodeGen/MachineInstr.h"23#include "llvm/CodeGen/MachineRegisterInfo.h"24#include "llvm/CodeGen/TargetFrameLowering.h"25#include "llvm/CodeGen/TargetRegisterInfo.h"26#include "llvm/CodeGen/TargetSubtargetInfo.h"27#include "llvm/IR/Function.h"28#include "llvm/Support/Debug.h"29#include "llvm/Support/ErrorHandling.h"30#include "llvm/Support/raw_ostream.h"31#include <cstdint>32 33using namespace llvm;34 35#define DEBUG_TYPE "mips-reg-info"36 37#define GET_REGINFO_TARGET_DESC38#include "MipsGenRegisterInfo.inc"39 40MipsRegisterInfo::MipsRegisterInfo(const MipsSubtarget &STI)41    : MipsGenRegisterInfo(Mips::RA), ArePtrs64bit(STI.getABI().ArePtrs64bit()) {42  MIPS_MC::initLLVMToCVRegMapping(this);43}44 45unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; }46 47const TargetRegisterClass *48MipsRegisterInfo::getPointerRegClass(unsigned Kind) const {49  assert(Kind == 0 && "this should only be used for default case");50  return ArePtrs64bit ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;51}52 53unsigned54MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,55                                      MachineFunction &MF) const {56  switch (RC->getID()) {57  default:58    return 0;59  case Mips::GPR32RegClassID:60  case Mips::GPR64RegClassID:61  case Mips::DSPRRegClassID: {62    const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();63    return 28 - TFI->hasFP(MF);64  }65  case Mips::FGR32RegClassID:66    return 32;67  case Mips::AFGR64RegClassID:68    return 16;69  case Mips::FGR64RegClassID:70    return 32;71  }72}73 74//===----------------------------------------------------------------------===//75// Callee Saved Registers methods76//===----------------------------------------------------------------------===//77 78/// Mips Callee Saved Registers79const MCPhysReg *80MipsRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {81  const MipsSubtarget &Subtarget = MF->getSubtarget<MipsSubtarget>();82  const Function &F = MF->getFunction();83  if (F.hasFnAttribute("interrupt")) {84    if (Subtarget.hasMips64())85      return Subtarget.hasMips64r6() ? CSR_Interrupt_64R6_SaveList86                                     : CSR_Interrupt_64_SaveList;87    else88      return Subtarget.hasMips32r6() ? CSR_Interrupt_32R6_SaveList89                                     : CSR_Interrupt_32_SaveList;90  }91 92  // N64 ABI93  if (Subtarget.isABI_N64()) {94    if (Subtarget.isSingleFloat())95      return CSR_N64_SingleFloat_SaveList;96 97    return CSR_N64_SaveList;98  }99 100  // N32 ABI101  if (Subtarget.isABI_N32()) {102    if (Subtarget.isSingleFloat())103      return CSR_N32_SingleFloat_SaveList;104 105    return CSR_N32_SaveList;106  }107 108  // O32 ABI109  if (Subtarget.isSingleFloat())110    return CSR_O32_SingleFloat_SaveList;111 112  if (Subtarget.isFP64bit())113    return CSR_O32_FP64_SaveList;114 115  if (Subtarget.isFPXX())116    return CSR_O32_FPXX_SaveList;117 118  return CSR_O32_SaveList;119}120 121const uint32_t *122MipsRegisterInfo::getCallPreservedMask(const MachineFunction &MF,123                                       CallingConv::ID) const {124  const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();125  // N64 ABI126  if (Subtarget.isABI_N64()) {127    if (Subtarget.isSingleFloat())128      return CSR_N64_SingleFloat_RegMask;129 130    return CSR_N64_RegMask;131  }132 133  // N32 ABI134  if (Subtarget.isABI_N32()) {135    if (Subtarget.isSingleFloat())136      return CSR_N32_SingleFloat_RegMask;137 138    return CSR_N32_RegMask;139  }140 141  // O32 ABI142  if (Subtarget.isSingleFloat())143    return CSR_O32_SingleFloat_RegMask;144 145  if (Subtarget.isFP64bit())146    return CSR_O32_FP64_RegMask;147 148  if (Subtarget.isFPXX())149    return CSR_O32_FPXX_RegMask;150 151  return CSR_O32_RegMask;152}153 154const uint32_t *MipsRegisterInfo::getMips16RetHelperMask() {155  return CSR_Mips16RetHelper_RegMask;156}157 158BitVector MipsRegisterInfo::159getReservedRegs(const MachineFunction &MF) const {160  static const MCPhysReg ReservedGPR32[] = {161    Mips::ZERO, Mips::K0, Mips::K1, Mips::SP162  };163 164  static const MCPhysReg ReservedGPR64[] = {165    Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64166  };167 168  BitVector Reserved(getNumRegs());169  const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();170 171  for (MCPhysReg R : ReservedGPR32)172    Reserved.set(R);173 174  for (MCPhysReg R : ReservedGPR64)175    Reserved.set(R);176 177  // For mno-abicalls, GP is a program invariant!178  if (!Subtarget.isABICalls()) {179    Reserved.set(Mips::GP);180    Reserved.set(Mips::GP_64);181  }182 183  if (Subtarget.isFP64bit()) {184    // Reserve all registers in AFGR64.185    for (MCPhysReg Reg : Mips::AFGR64RegClass)186      Reserved.set(Reg);187  } else {188    // Reserve all registers in FGR64.189    for (MCPhysReg Reg : Mips::FGR64RegClass)190      Reserved.set(Reg);191  }192  // Reserve FP if this function should have a dedicated frame pointer register.193  if (Subtarget.getFrameLowering()->hasFP(MF)) {194    if (Subtarget.inMips16Mode())195      Reserved.set(Mips::S0);196    else {197      Reserved.set(Mips::FP);198      Reserved.set(Mips::FP_64);199 200      // Reserve the base register if we need to both realign the stack and201      // allocate variable-sized objects at runtime. This should test the202      // same conditions as MipsFrameLowering::hasBP().203      if (hasStackRealignment(MF) && MF.getFrameInfo().hasVarSizedObjects()) {204        Reserved.set(Mips::S7);205        Reserved.set(Mips::S7_64);206      }207    }208  }209 210  // Reserve hardware registers.211  Reserved.set(Mips::HWR29);212  Reserved.set(Mips::HWR2);213 214  // Reserve DSP control register.215  Reserved.set(Mips::DSPPos);216  Reserved.set(Mips::DSPSCount);217  Reserved.set(Mips::DSPCarry);218  Reserved.set(Mips::DSPEFI);219  Reserved.set(Mips::DSPOutFlag);220 221  // Reserve MSA control registers.222  for (MCPhysReg Reg : Mips::MSACtrlRegClass)223    Reserved.set(Reg);224 225  // Reserve RA if in mips16 mode.226  if (Subtarget.inMips16Mode()) {227    const MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();228    Reserved.set(Mips::RA);229    Reserved.set(Mips::RA_64);230    Reserved.set(Mips::T0);231    Reserved.set(Mips::T1);232    if (MF.getFunction().hasFnAttribute("saveS2") || MipsFI->hasSaveS2())233      Reserved.set(Mips::S2);234  }235 236  // Reserve GP if small section is used.237  if (Subtarget.useSmallSection()) {238    Reserved.set(Mips::GP);239    Reserved.set(Mips::GP_64);240  }241 242  return Reserved;243}244 245// FrameIndex represent objects inside a abstract stack.246// We must replace FrameIndex with an stack/frame pointer247// direct reference.248bool MipsRegisterInfo::249eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,250                    unsigned FIOperandNum, RegScavenger *RS) const {251  MachineInstr &MI = *II;252  MachineFunction &MF = *MI.getParent()->getParent();253 254  LLVM_DEBUG(errs() << "\nFunction : " << MF.getName() << "\n";255             errs() << "<--------->\n"256                    << MI);257 258  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();259  uint64_t stackSize = MF.getFrameInfo().getStackSize();260  int64_t spOffset = MF.getFrameInfo().getObjectOffset(FrameIndex);261 262  LLVM_DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"263                    << "spOffset   : " << spOffset << "\n"264                    << "stackSize  : " << stackSize << "\n"265                    << "alignment  : "266                    << DebugStr(MF.getFrameInfo().getObjectAlign(FrameIndex))267                    << "\n");268 269  eliminateFI(MI, FIOperandNum, FrameIndex, stackSize, spOffset);270  return false;271}272 273Register MipsRegisterInfo::274getFrameRegister(const MachineFunction &MF) const {275  const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();276  const TargetFrameLowering *TFI = Subtarget.getFrameLowering();277  bool IsN64 =278      static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI().IsN64();279 280  if (Subtarget.inMips16Mode())281    return TFI->hasFP(MF) ? Mips::S0 : Mips::SP;282  else283    return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) :284                            (IsN64 ? Mips::SP_64 : Mips::SP);285}286 287bool MipsRegisterInfo::canRealignStack(const MachineFunction &MF) const {288  // Avoid realigning functions that explicitly do not want to be realigned.289  // Normally, we should report an error when a function should be dynamically290  // realigned but also has the attribute no-realign-stack. Unfortunately,291  // with this attribute, MachineFrameInfo clamps each new object's alignment292  // to that of the stack's alignment as specified by the ABI. As a result,293  // the information of whether we have objects with larger alignment294  // requirement than the stack's alignment is already lost at this point.295  if (!TargetRegisterInfo::canRealignStack(MF))296    return false;297 298  const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();299  unsigned FP = Subtarget.isGP32bit() ? Mips::FP : Mips::FP_64;300  unsigned BP = Subtarget.isGP32bit() ? Mips::S7 : Mips::S7_64;301 302  // Support dynamic stack realignment for all targets except Mips16.303  if (Subtarget.inMips16Mode())304    return false;305 306  // We can't perform dynamic stack realignment if we can't reserve the307  // frame pointer register.308  if (!MF.getRegInfo().canReserveReg(FP))309    return false;310 311  // We can realign the stack if we know the maximum call frame size and we312  // don't have variable sized objects.313  if (Subtarget.getFrameLowering()->hasReservedCallFrame(MF))314    return true;315 316  // We have to reserve the base pointer register in the presence of variable317  // sized objects.318  return MF.getRegInfo().canReserveReg(BP);319}320