brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.1 KiB · 28dca4f Raw
235 lines · cpp
1//===- ARCRegisterInfo.cpp - ARC Register Information -----------*- C++ -*-===//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 ARC implementation of the MRegisterInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "ARCRegisterInfo.h"14#include "ARC.h"15#include "ARCInstrInfo.h"16#include "ARCMachineFunctionInfo.h"17#include "ARCSubtarget.h"18#include "llvm/ADT/BitVector.h"19#include "llvm/CodeGen/MachineFrameInfo.h"20#include "llvm/CodeGen/MachineFunction.h"21#include "llvm/CodeGen/MachineInstrBuilder.h"22#include "llvm/CodeGen/MachineModuleInfo.h"23#include "llvm/CodeGen/MachineRegisterInfo.h"24#include "llvm/CodeGen/RegisterScavenging.h"25#include "llvm/CodeGen/TargetFrameLowering.h"26#include "llvm/IR/Function.h"27#include "llvm/Support/Debug.h"28#include "llvm/Target/TargetMachine.h"29#include "llvm/Target/TargetOptions.h"30 31using namespace llvm;32 33#define DEBUG_TYPE "arc-reg-info"34 35#define GET_REGINFO_TARGET_DESC36#include "ARCGenRegisterInfo.inc"37 38static void replaceFrameIndex(MachineBasicBlock::iterator II,39                              const ARCInstrInfo &TII, unsigned Reg,40                              unsigned FrameReg, int Offset, int StackSize,41                              int ObjSize, RegScavenger *RS, int SPAdj) {42  assert(RS && "Need register scavenger.");43  MachineInstr &MI = *II;44  MachineBasicBlock &MBB = *MI.getParent();45  DebugLoc DL = MI.getDebugLoc();46  unsigned BaseReg = FrameReg;47  unsigned KillState = 0;48  if (MI.getOpcode() == ARC::LD_rs9 && (Offset >= 256 || Offset < -256)) {49    // Loads can always be reached with LD_rlimm.50    BuildMI(MBB, II, DL, TII.get(ARC::LD_rlimm), Reg)51        .addReg(BaseReg)52        .addImm(Offset)53        .addMemOperand(*MI.memoperands_begin());54    MBB.erase(II);55    return;56  }57 58  if (MI.getOpcode() != ARC::GETFI && (Offset >= 256 || Offset < -256)) {59    // We need to use a scratch register to reach the far-away frame indexes.60    BaseReg = RS->FindUnusedReg(&ARC::GPR32RegClass);61    if (!BaseReg) {62      // We can be sure that the scavenged-register slot is within the range63      // of the load offset.64      const TargetRegisterInfo *TRI =65          MBB.getParent()->getSubtarget().getRegisterInfo();66      BaseReg =67          RS->scavengeRegisterBackwards(ARC::GPR32RegClass, II, false, SPAdj);68      assert(BaseReg && "Register scavenging failed.");69      LLVM_DEBUG(dbgs() << "Scavenged register " << printReg(BaseReg, TRI)70                        << " for FrameReg=" << printReg(FrameReg, TRI)71                        << "+Offset=" << Offset << "\n");72      (void)TRI;73      RS->setRegUsed(BaseReg);74    }75    unsigned AddOpc = isUInt<6>(Offset) ? ARC::ADD_rru6 : ARC::ADD_rrlimm;76    BuildMI(MBB, II, DL, TII.get(AddOpc))77        .addReg(BaseReg, RegState::Define)78        .addReg(FrameReg)79        .addImm(Offset);80    Offset = 0;81    KillState = RegState::Kill;82  }83  switch (MI.getOpcode()) {84  case ARC::LD_rs9:85    assert((Offset % 4 == 0) && "LD needs 4 byte alignment.");86    [[fallthrough]];87  case ARC::LDH_rs9:88  case ARC::LDH_X_rs9:89    assert((Offset % 2 == 0) && "LDH needs 2 byte alignment.");90    [[fallthrough]];91  case ARC::LDB_rs9:92  case ARC::LDB_X_rs9:93    LLVM_DEBUG(dbgs() << "Building LDFI\n");94    BuildMI(MBB, II, DL, TII.get(MI.getOpcode()), Reg)95        .addReg(BaseReg, KillState)96        .addImm(Offset)97        .addMemOperand(*MI.memoperands_begin());98    break;99  case ARC::ST_rs9:100    assert((Offset % 4 == 0) && "ST needs 4 byte alignment.");101    [[fallthrough]];102  case ARC::STH_rs9:103    assert((Offset % 2 == 0) && "STH needs 2 byte alignment.");104    [[fallthrough]];105  case ARC::STB_rs9:106    LLVM_DEBUG(dbgs() << "Building STFI\n");107    BuildMI(MBB, II, DL, TII.get(MI.getOpcode()))108        .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))109        .addReg(BaseReg, KillState)110        .addImm(Offset)111        .addMemOperand(*MI.memoperands_begin());112    break;113  case ARC::GETFI:114    LLVM_DEBUG(dbgs() << "Building GETFI\n");115    BuildMI(MBB, II, DL,116            TII.get(isUInt<6>(Offset) ? ARC::ADD_rru6 : ARC::ADD_rrlimm))117        .addReg(Reg, RegState::Define)118        .addReg(FrameReg)119        .addImm(Offset);120    break;121  default:122    llvm_unreachable("Unhandled opcode.");123  }124 125  // Erase old instruction.126  MBB.erase(II);127}128 129ARCRegisterInfo::ARCRegisterInfo(const ARCSubtarget &ST)130    : ARCGenRegisterInfo(ARC::BLINK), ST(ST) {}131 132bool ARCRegisterInfo::needsFrameMoves(const MachineFunction &MF) {133  return MF.needsFrameMoves();134}135 136const MCPhysReg *137ARCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {138  return CSR_ARC_SaveList;139}140 141BitVector ARCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {142  BitVector Reserved(getNumRegs());143 144  Reserved.set(ARC::ILINK);145  Reserved.set(ARC::SP);146  Reserved.set(ARC::GP);147  Reserved.set(ARC::R25);148  Reserved.set(ARC::BLINK);149  Reserved.set(ARC::FP);150 151  return Reserved;152}153 154bool ARCRegisterInfo::requiresRegisterScavenging(155    const MachineFunction &MF) const {156  return true;157}158 159bool ARCRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {160  return true;161}162 163bool ARCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,164                                          int SPAdj, unsigned FIOperandNum,165                                          RegScavenger *RS) const {166  assert(SPAdj == 0 && "Unexpected");167  MachineInstr &MI = *II;168  MachineOperand &FrameOp = MI.getOperand(FIOperandNum);169  int FrameIndex = FrameOp.getIndex();170 171  MachineFunction &MF = *MI.getParent()->getParent();172  const ARCInstrInfo &TII = *MF.getSubtarget<ARCSubtarget>().getInstrInfo();173  const ARCFrameLowering *TFI = getFrameLowering(MF);174  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);175  int ObjSize = MF.getFrameInfo().getObjectSize(FrameIndex);176  int StackSize = MF.getFrameInfo().getStackSize();177  int LocalFrameSize = MF.getFrameInfo().getLocalFrameSize();178 179  LLVM_DEBUG(dbgs() << "\nFunction         : " << MF.getName() << "\n");180  LLVM_DEBUG(dbgs() << "<--------->\n");181  LLVM_DEBUG(dbgs() << MI << "\n");182  LLVM_DEBUG(dbgs() << "FrameIndex         : " << FrameIndex << "\n");183  LLVM_DEBUG(dbgs() << "ObjSize            : " << ObjSize << "\n");184  LLVM_DEBUG(dbgs() << "FrameOffset        : " << Offset << "\n");185  LLVM_DEBUG(dbgs() << "StackSize          : " << StackSize << "\n");186  LLVM_DEBUG(dbgs() << "LocalFrameSize     : " << LocalFrameSize << "\n");187  (void)LocalFrameSize;188 189  // Special handling of DBG_VALUE instructions.190  if (MI.isDebugValue()) {191    Register FrameReg = getFrameRegister(MF);192    MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);193    MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);194    return false;195  }196 197  // fold constant into offset.198  Offset += MI.getOperand(FIOperandNum + 1).getImm();199 200  // TODO: assert based on the load type:201  // ldb needs no alignment,202  // ldh needs 2 byte alignment203  // ld needs 4 byte alignment204  LLVM_DEBUG(dbgs() << "Offset             : " << Offset << "\n"205                    << "<--------->\n");206 207  Register Reg = MI.getOperand(0).getReg();208  assert(ARC::GPR32RegClass.contains(Reg) && "Unexpected register operand");209 210  if (!TFI->hasFP(MF)) {211    Offset = StackSize + Offset;212    if (FrameIndex >= 0)213      assert((Offset >= 0 && Offset < StackSize) && "SP Offset not in bounds.");214  } else {215    if (FrameIndex >= 0) {216      assert((Offset < 0 && -Offset <= StackSize) &&217             "FP Offset not in bounds.");218    }219  }220  replaceFrameIndex(II, TII, Reg, getFrameRegister(MF), Offset, StackSize,221                    ObjSize, RS, SPAdj);222  return true;                  223}224 225Register ARCRegisterInfo::getFrameRegister(const MachineFunction &MF) const {226  const ARCFrameLowering *TFI = getFrameLowering(MF);227  return TFI->hasFP(MF) ? ARC::FP : ARC::SP;228}229 230const uint32_t *231ARCRegisterInfo::getCallPreservedMask(const MachineFunction &MF,232                                      CallingConv::ID CC) const {233  return CSR_ARC_RegMask;234}235