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