212 lines · cpp
1//===-- MipsMachineFunctionInfo.cpp - Private data used for Mips ----------===//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#include "MipsMachineFunction.h"10#include "MCTargetDesc/MipsABIInfo.h"11#include "MipsSubtarget.h"12#include "MipsTargetMachine.h"13#include "llvm/CodeGen/MachineFrameInfo.h"14#include "llvm/CodeGen/MachineRegisterInfo.h"15#include "llvm/CodeGen/PseudoSourceValue.h"16#include "llvm/CodeGen/PseudoSourceValueManager.h"17#include "llvm/CodeGen/TargetRegisterInfo.h"18#include "llvm/Support/CommandLine.h"19 20using namespace llvm;21 22static cl::opt<bool>23FixGlobalBaseReg("mips-fix-global-base-reg", cl::Hidden, cl::init(true),24 cl::desc("Always use $gp as the global base register."));25 26MachineFunctionInfo *27MipsFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,28 const DenseMap<MachineBasicBlock *, MachineBasicBlock *>29 &Src2DstMBB) const {30 return DestMF.cloneInfo<MipsFunctionInfo>(*this);31}32 33MipsFunctionInfo::~MipsFunctionInfo() = default;34 35bool MipsFunctionInfo::globalBaseRegSet() const {36 return GlobalBaseReg;37}38 39static const TargetRegisterClass &getGlobalBaseRegClass(MachineFunction &MF) {40 auto &STI = MF.getSubtarget<MipsSubtarget>();41 auto &TM = static_cast<const MipsTargetMachine &>(MF.getTarget());42 43 if (STI.inMips16Mode())44 return Mips::CPU16RegsRegClass;45 46 if (STI.inMicroMipsMode())47 return Mips::GPRMM16RegClass;48 49 if (TM.getABI().IsN64())50 return Mips::GPR64RegClass;51 52 return Mips::GPR32RegClass;53}54 55Register MipsFunctionInfo::getGlobalBaseReg(MachineFunction &MF) {56 if (!GlobalBaseReg)57 GlobalBaseReg =58 MF.getRegInfo().createVirtualRegister(&getGlobalBaseRegClass(MF));59 return GlobalBaseReg;60}61 62Register MipsFunctionInfo::getGlobalBaseRegForGlobalISel(MachineFunction &MF) {63 if (!GlobalBaseReg) {64 getGlobalBaseReg(MF);65 initGlobalBaseReg(MF);66 }67 return GlobalBaseReg;68}69 70void MipsFunctionInfo::initGlobalBaseReg(MachineFunction &MF) {71 if (!GlobalBaseReg)72 return;73 74 MachineBasicBlock &MBB = MF.front();75 MachineBasicBlock::iterator I = MBB.begin();76 MachineRegisterInfo &RegInfo = MF.getRegInfo();77 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();78 DebugLoc DL;79 const TargetRegisterClass *RC;80 const MipsABIInfo &ABI =81 static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI();82 RC = (ABI.IsN64()) ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;83 84 Register V0 = RegInfo.createVirtualRegister(RC);85 Register V1 = RegInfo.createVirtualRegister(RC);86 87 if (ABI.IsN64()) {88 MF.getRegInfo().addLiveIn(Mips::T9_64);89 MBB.addLiveIn(Mips::T9_64);90 91 // lui $v0, %hi(%neg(%gp_rel(fname)))92 // daddu $v1, $v0, $t993 // daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))94 const GlobalValue *FName = &MF.getFunction();95 BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)96 .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);97 BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0)98 .addReg(Mips::T9_64);99 BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)100 .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);101 return;102 }103 104 if (!MF.getTarget().isPositionIndependent()) {105 // Set global register to __gnu_local_gp.106 //107 // lui $v0, %hi(__gnu_local_gp)108 // addiu $globalbasereg, $v0, %lo(__gnu_local_gp)109 BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)110 .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);111 BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)112 .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);113 return;114 }115 116 MF.getRegInfo().addLiveIn(Mips::T9);117 MBB.addLiveIn(Mips::T9);118 119 if (ABI.IsN32()) {120 // lui $v0, %hi(%neg(%gp_rel(fname)))121 // addu $v1, $v0, $t9122 // addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))123 const GlobalValue *FName = &MF.getFunction();124 BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)125 .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);126 BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);127 BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)128 .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);129 return;130 }131 132 assert(ABI.IsO32());133 134 // For O32 ABI, the following instruction sequence is emitted to initialize135 // the global base register:136 //137 // 0. lui $2, %hi(_gp_disp)138 // 1. addiu $2, $2, %lo(_gp_disp)139 // 2. addu $globalbasereg, $2, $t9140 //141 // We emit only the last instruction here.142 //143 // GNU linker requires that the first two instructions appear at the beginning144 // of a function and no instructions be inserted before or between them.145 // The two instructions are emitted during lowering to MC layer in order to146 // avoid any reordering.147 //148 // Register $2 (Mips::V0) is added to the list of live-in registers to ensure149 // the value instruction 1 (addiu) defines is valid when instruction 2 (addu)150 // reads it.151 MF.getRegInfo().addLiveIn(Mips::V0);152 MBB.addLiveIn(Mips::V0);153 BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg)154 .addReg(Mips::V0).addReg(Mips::T9);155}156 157void MipsFunctionInfo::createEhDataRegsFI(MachineFunction &MF) {158 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();159 for (int &I : EhDataRegFI) {160 const TargetRegisterClass &RC =161 static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI().IsN64()162 ? Mips::GPR64RegClass163 : Mips::GPR32RegClass;164 165 I = MF.getFrameInfo().CreateStackObject(TRI.getSpillSize(RC),166 TRI.getSpillAlign(RC), false);167 }168}169 170void MipsFunctionInfo::createISRRegFI(MachineFunction &MF) {171 // ISRs require spill slots for Status & ErrorPC Coprocessor 0 registers.172 // The current implementation only supports Mips32r2+ not Mips64rX. Status173 // is always 32 bits, ErrorPC is 32 or 64 bits dependent on architecture,174 // however Mips32r2+ is the supported architecture.175 const TargetRegisterClass &RC = Mips::GPR32RegClass;176 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();177 178 for (int &I : ISRDataRegFI)179 I = MF.getFrameInfo().CreateStackObject(TRI.getSpillSize(RC),180 TRI.getSpillAlign(RC), false);181}182 183bool MipsFunctionInfo::isEhDataRegFI(int FI) const {184 return CallsEhReturn && (FI == EhDataRegFI[0] || FI == EhDataRegFI[1]185 || FI == EhDataRegFI[2] || FI == EhDataRegFI[3]);186}187 188bool MipsFunctionInfo::isISRRegFI(int FI) const {189 return IsISR && (FI == ISRDataRegFI[0] || FI == ISRDataRegFI[1]);190}191MachinePointerInfo MipsFunctionInfo::callPtrInfo(MachineFunction &MF,192 const char *ES) {193 return MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES));194}195 196MachinePointerInfo MipsFunctionInfo::callPtrInfo(MachineFunction &MF,197 const GlobalValue *GV) {198 return MachinePointerInfo(MF.getPSVManager().getGlobalValueCallEntry(GV));199}200 201int MipsFunctionInfo::getMoveF64ViaSpillFI(MachineFunction &MF,202 const TargetRegisterClass *RC) {203 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();204 if (MoveF64ViaSpillFI == -1) {205 MoveF64ViaSpillFI = MF.getFrameInfo().CreateStackObject(206 TRI.getSpillSize(*RC), TRI.getSpillAlign(*RC), false);207 }208 return MoveF64ViaSpillFI;209}210 211void MipsFunctionInfo::anchor() {}212