brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.3 KiB · 1326878 Raw
256 lines · cpp
1//===-- MipsSERegisterInfo.cpp - MIPS32/64 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 MIPS32/64 implementation of the TargetRegisterInfo10// class.11//12//===----------------------------------------------------------------------===//13 14#include "MipsSERegisterInfo.h"15#include "Mips.h"16#include "MipsMachineFunction.h"17#include "MipsSEInstrInfo.h"18#include "MipsSubtarget.h"19#include "MipsTargetMachine.h"20#include "llvm/CodeGen/MachineFrameInfo.h"21#include "llvm/CodeGen/MachineFunction.h"22#include "llvm/CodeGen/MachineInstrBuilder.h"23#include "llvm/CodeGen/MachineRegisterInfo.h"24#include "llvm/CodeGen/TargetFrameLowering.h"25#include "llvm/CodeGen/TargetInstrInfo.h"26#include "llvm/IR/Function.h"27#include "llvm/IR/Type.h"28#include "llvm/Support/Debug.h"29#include "llvm/Support/raw_ostream.h"30#include "llvm/Target/TargetMachine.h"31#include "llvm/Target/TargetOptions.h"32 33using namespace llvm;34 35#define DEBUG_TYPE "mips-reg-info"36 37MipsSERegisterInfo::MipsSERegisterInfo(const MipsSubtarget &STI)38    : MipsRegisterInfo(STI) {}39 40bool MipsSERegisterInfo::41requiresRegisterScavenging(const MachineFunction &MF) const {42  return true;43}44 45bool MipsSERegisterInfo::46requiresFrameIndexScavenging(const MachineFunction &MF) const {47  return true;48}49 50const TargetRegisterClass *51MipsSERegisterInfo::intRegClass(unsigned Size) const {52  if (Size == 4)53    return &Mips::GPR32RegClass;54 55  assert(Size == 8);56  return &Mips::GPR64RegClass;57}58 59/// Get the size of the offset supported by the given load/store/inline asm.60/// The result includes the effects of any scale factors applied to the61/// instruction immediate.62static inline unsigned getLoadStoreOffsetSizeInBits(const unsigned Opcode,63                                                    MachineOperand MO) {64  switch (Opcode) {65  case Mips::LD_B:66  case Mips::ST_B:67    return 10;68  case Mips::LD_H:69  case Mips::ST_H:70    return 10 + 1 /* scale factor */;71  case Mips::LD_W:72  case Mips::ST_W:73    return 10 + 2 /* scale factor */;74  case Mips::LD_D:75  case Mips::ST_D:76    return 10 + 3 /* scale factor */;77  case Mips::LL:78  case Mips::LL64:79  case Mips::LLD:80  case Mips::LLE:81  case Mips::SC:82  case Mips::SC64:83  case Mips::SCD:84  case Mips::SCE:85    return 16;86  case Mips::LLE_MM:87  case Mips::LL_MM:88  case Mips::SCE_MM:89  case Mips::SC_MM:90    return 12;91  case Mips::LL64_R6:92  case Mips::LL_R6:93  case Mips::LLD_R6:94  case Mips::SC64_R6:95  case Mips::SCD_R6:96  case Mips::SC_R6:97  case Mips::LL_MMR6:98  case Mips::SC_MMR6:99    return 9;100  case Mips::INLINEASM: {101    const InlineAsm::Flag F(MO.getImm());102    switch (F.getMemoryConstraintID()) {103    case InlineAsm::ConstraintCode::ZC: {104      const MipsSubtarget &Subtarget = MO.getParent()105                                           ->getParent()106                                           ->getParent()107                                           ->getSubtarget<MipsSubtarget>();108      if (Subtarget.inMicroMipsMode())109        return 12;110 111      if (Subtarget.hasMips32r6())112        return 9;113 114      return 16;115    }116    default:117      return 16;118    }119  }120  default:121    return 16;122  }123}124 125/// Get the scale factor applied to the immediate in the given load/store.126static inline unsigned getLoadStoreOffsetAlign(const unsigned Opcode) {127  switch (Opcode) {128  case Mips::LD_H:129  case Mips::ST_H:130    return 2;131  case Mips::LD_W:132  case Mips::ST_W:133    return 4;134  case Mips::LD_D:135  case Mips::ST_D:136    return 8;137  default:138    return 1;139  }140}141 142void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,143                                     unsigned OpNo, int FrameIndex,144                                     uint64_t StackSize,145                                     int64_t SPOffset) const {146  MachineInstr &MI = *II;147  MachineFunction &MF = *MI.getParent()->getParent();148  MachineFrameInfo &MFI = MF.getFrameInfo();149  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();150 151  MipsABIInfo ABI =152      static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI();153  const MipsRegisterInfo *RegInfo =154    static_cast<const MipsRegisterInfo *>(MF.getSubtarget().getRegisterInfo());155 156  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();157  int MinCSFI = 0;158  int MaxCSFI = -1;159 160  if (CSI.size()) {161    MinCSFI = CSI[0].getFrameIdx();162    MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();163  }164 165  bool EhDataRegFI = MipsFI->isEhDataRegFI(FrameIndex);166  bool IsISRRegFI = MipsFI->isISRRegFI(FrameIndex);167  // The following stack frame objects are always referenced relative to $sp:168  //  1. Outgoing arguments.169  //  2. Pointer to dynamically allocated stack space.170  //  3. Locations for callee-saved registers.171  //  4. Locations for eh data registers.172  //  5. Locations for ISR saved Coprocessor 0 registers 12 & 14.173  // Everything else is referenced relative to whatever register174  // getFrameRegister() returns.175  unsigned FrameReg;176 177  if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) || EhDataRegFI ||178      IsISRRegFI)179    FrameReg = ABI.GetStackPtr();180  else if (RegInfo->hasStackRealignment(MF)) {181    if (MFI.hasVarSizedObjects() && !MFI.isFixedObjectIndex(FrameIndex))182      FrameReg = ABI.GetBasePtr();183    else if (MFI.isFixedObjectIndex(FrameIndex))184      FrameReg = getFrameRegister(MF);185    else186      FrameReg = ABI.GetStackPtr();187  } else188    FrameReg = getFrameRegister(MF);189 190  // Calculate final offset.191  // - There is no need to change the offset if the frame object is one of the192  //   following: an outgoing argument, pointer to a dynamically allocated193  //   stack space or a $gp restore location,194  // - If the frame object is any of the following, its offset must be adjusted195  //   by adding the size of the stack:196  //   incoming argument, callee-saved register location or local variable.197  bool IsKill = false;198  int64_t Offset;199 200  Offset = SPOffset + (int64_t)StackSize;201  Offset += MI.getOperand(OpNo + 1).getImm();202 203  LLVM_DEBUG(errs() << "Offset     : " << Offset << "\n"204                    << "<--------->\n");205 206  if (!MI.isDebugValue()) {207    // Make sure Offset fits within the field available.208    // For MSA instructions, this is a 10-bit signed immediate (scaled by209    // element size), otherwise it is a 16-bit signed immediate.210    unsigned OffsetBitSize =211        getLoadStoreOffsetSizeInBits(MI.getOpcode(), MI.getOperand(OpNo - 1));212    const Align OffsetAlign(getLoadStoreOffsetAlign(MI.getOpcode()));213    if (OffsetBitSize < 16 && isInt<16>(Offset) &&214        (!isIntN(OffsetBitSize, Offset) || !isAligned(OffsetAlign, Offset))) {215      // If we have an offset that needs to fit into a signed n-bit immediate216      // (where n < 16) and doesn't, but does fit into 16-bits then use an ADDiu217      MachineBasicBlock &MBB = *MI.getParent();218      DebugLoc DL = II->getDebugLoc();219      const TargetRegisterClass *PtrRC =220          ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;221      MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();222      Register Reg = RegInfo.createVirtualRegister(PtrRC);223      const MipsSEInstrInfo &TII =224          *static_cast<const MipsSEInstrInfo *>(225              MBB.getParent()->getSubtarget().getInstrInfo());226      BuildMI(MBB, II, DL, TII.get(ABI.GetPtrAddiuOp()), Reg)227          .addReg(FrameReg)228          .addImm(Offset);229 230      FrameReg = Reg;231      Offset = 0;232      IsKill = true;233    } else if (!isInt<16>(Offset)) {234      // Otherwise split the offset into 16-bit pieces and add it in multiple235      // instructions.236      MachineBasicBlock &MBB = *MI.getParent();237      DebugLoc DL = II->getDebugLoc();238      unsigned NewImm = 0;239      const MipsSEInstrInfo &TII =240          *static_cast<const MipsSEInstrInfo *>(241              MBB.getParent()->getSubtarget().getInstrInfo());242      unsigned Reg = TII.loadImmediate(Offset, MBB, II, DL,243                                       OffsetBitSize == 16 ? &NewImm : nullptr);244      BuildMI(MBB, II, DL, TII.get(ABI.GetPtrAdduOp()), Reg).addReg(FrameReg)245        .addReg(Reg, RegState::Kill);246 247      FrameReg = Reg;248      Offset = SignExtend64<16>(NewImm);249      IsKill = true;250    }251  }252 253  MI.getOperand(OpNo).ChangeToRegister(FrameReg, false, false, IsKill);254  MI.getOperand(OpNo + 1).ChangeToImmediate(Offset);255}256