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