brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · 194b467 Raw
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