Path: blob/main/contrib/llvm-project/llvm/lib/Target/ARC/ARCRegisterInfo.cpp
96353 views
//===- ARCRegisterInfo.cpp - ARC Register Information -----------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains the ARC implementation of the MRegisterInfo class.9//10//===----------------------------------------------------------------------===//1112#include "ARCRegisterInfo.h"13#include "ARC.h"14#include "ARCInstrInfo.h"15#include "ARCMachineFunctionInfo.h"16#include "ARCSubtarget.h"17#include "llvm/ADT/BitVector.h"18#include "llvm/CodeGen/MachineFrameInfo.h"19#include "llvm/CodeGen/MachineFunction.h"20#include "llvm/CodeGen/MachineInstrBuilder.h"21#include "llvm/CodeGen/MachineModuleInfo.h"22#include "llvm/CodeGen/MachineRegisterInfo.h"23#include "llvm/CodeGen/RegisterScavenging.h"24#include "llvm/CodeGen/TargetFrameLowering.h"25#include "llvm/IR/Function.h"26#include "llvm/Support/Debug.h"27#include "llvm/Target/TargetMachine.h"28#include "llvm/Target/TargetOptions.h"2930using namespace llvm;3132#define DEBUG_TYPE "arc-reg-info"3334#define GET_REGINFO_TARGET_DESC35#include "ARCGenRegisterInfo.inc"3637static void replaceFrameIndex(MachineBasicBlock::iterator II,38const ARCInstrInfo &TII, unsigned Reg,39unsigned FrameReg, int Offset, int StackSize,40int ObjSize, RegScavenger *RS, int SPAdj) {41assert(RS && "Need register scavenger.");42MachineInstr &MI = *II;43MachineBasicBlock &MBB = *MI.getParent();44DebugLoc DL = MI.getDebugLoc();45unsigned BaseReg = FrameReg;46unsigned KillState = 0;47if (MI.getOpcode() == ARC::LD_rs9 && (Offset >= 256 || Offset < -256)) {48// Loads can always be reached with LD_rlimm.49BuildMI(MBB, II, DL, TII.get(ARC::LD_rlimm), Reg)50.addReg(BaseReg)51.addImm(Offset)52.addMemOperand(*MI.memoperands_begin());53MBB.erase(II);54return;55}5657if (MI.getOpcode() != ARC::GETFI && (Offset >= 256 || Offset < -256)) {58// We need to use a scratch register to reach the far-away frame indexes.59BaseReg = RS->FindUnusedReg(&ARC::GPR32RegClass);60if (!BaseReg) {61// We can be sure that the scavenged-register slot is within the range62// of the load offset.63const TargetRegisterInfo *TRI =64MBB.getParent()->getSubtarget().getRegisterInfo();65BaseReg =66RS->scavengeRegisterBackwards(ARC::GPR32RegClass, II, false, SPAdj);67assert(BaseReg && "Register scavenging failed.");68LLVM_DEBUG(dbgs() << "Scavenged register " << printReg(BaseReg, TRI)69<< " for FrameReg=" << printReg(FrameReg, TRI)70<< "+Offset=" << Offset << "\n");71(void)TRI;72RS->setRegUsed(BaseReg);73}74unsigned AddOpc = isUInt<6>(Offset) ? ARC::ADD_rru6 : ARC::ADD_rrlimm;75BuildMI(MBB, II, DL, TII.get(AddOpc))76.addReg(BaseReg, RegState::Define)77.addReg(FrameReg)78.addImm(Offset);79Offset = 0;80KillState = RegState::Kill;81}82switch (MI.getOpcode()) {83case ARC::LD_rs9:84assert((Offset % 4 == 0) && "LD needs 4 byte alignment.");85[[fallthrough]];86case ARC::LDH_rs9:87case ARC::LDH_X_rs9:88assert((Offset % 2 == 0) && "LDH needs 2 byte alignment.");89[[fallthrough]];90case ARC::LDB_rs9:91case ARC::LDB_X_rs9:92LLVM_DEBUG(dbgs() << "Building LDFI\n");93BuildMI(MBB, II, DL, TII.get(MI.getOpcode()), Reg)94.addReg(BaseReg, KillState)95.addImm(Offset)96.addMemOperand(*MI.memoperands_begin());97break;98case ARC::ST_rs9:99assert((Offset % 4 == 0) && "ST needs 4 byte alignment.");100[[fallthrough]];101case ARC::STH_rs9:102assert((Offset % 2 == 0) && "STH needs 2 byte alignment.");103[[fallthrough]];104case ARC::STB_rs9:105LLVM_DEBUG(dbgs() << "Building STFI\n");106BuildMI(MBB, II, DL, TII.get(MI.getOpcode()))107.addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))108.addReg(BaseReg, KillState)109.addImm(Offset)110.addMemOperand(*MI.memoperands_begin());111break;112case ARC::GETFI:113LLVM_DEBUG(dbgs() << "Building GETFI\n");114BuildMI(MBB, II, DL,115TII.get(isUInt<6>(Offset) ? ARC::ADD_rru6 : ARC::ADD_rrlimm))116.addReg(Reg, RegState::Define)117.addReg(FrameReg)118.addImm(Offset);119break;120default:121llvm_unreachable("Unhandled opcode.");122}123124// Erase old instruction.125MBB.erase(II);126}127128ARCRegisterInfo::ARCRegisterInfo(const ARCSubtarget &ST)129: ARCGenRegisterInfo(ARC::BLINK), ST(ST) {}130131bool ARCRegisterInfo::needsFrameMoves(const MachineFunction &MF) {132return MF.needsFrameMoves();133}134135const MCPhysReg *136ARCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {137return CSR_ARC_SaveList;138}139140BitVector ARCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {141BitVector Reserved(getNumRegs());142143Reserved.set(ARC::ILINK);144Reserved.set(ARC::SP);145Reserved.set(ARC::GP);146Reserved.set(ARC::R25);147Reserved.set(ARC::BLINK);148Reserved.set(ARC::FP);149150return Reserved;151}152153bool ARCRegisterInfo::requiresRegisterScavenging(154const MachineFunction &MF) const {155return true;156}157158bool ARCRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {159return true;160}161162bool ARCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,163int SPAdj, unsigned FIOperandNum,164RegScavenger *RS) const {165assert(SPAdj == 0 && "Unexpected");166MachineInstr &MI = *II;167MachineOperand &FrameOp = MI.getOperand(FIOperandNum);168int FrameIndex = FrameOp.getIndex();169170MachineFunction &MF = *MI.getParent()->getParent();171const ARCInstrInfo &TII = *MF.getSubtarget<ARCSubtarget>().getInstrInfo();172const ARCFrameLowering *TFI = getFrameLowering(MF);173int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);174int ObjSize = MF.getFrameInfo().getObjectSize(FrameIndex);175int StackSize = MF.getFrameInfo().getStackSize();176int LocalFrameSize = MF.getFrameInfo().getLocalFrameSize();177178LLVM_DEBUG(dbgs() << "\nFunction : " << MF.getName() << "\n");179LLVM_DEBUG(dbgs() << "<--------->\n");180LLVM_DEBUG(dbgs() << MI << "\n");181LLVM_DEBUG(dbgs() << "FrameIndex : " << FrameIndex << "\n");182LLVM_DEBUG(dbgs() << "ObjSize : " << ObjSize << "\n");183LLVM_DEBUG(dbgs() << "FrameOffset : " << Offset << "\n");184LLVM_DEBUG(dbgs() << "StackSize : " << StackSize << "\n");185LLVM_DEBUG(dbgs() << "LocalFrameSize : " << LocalFrameSize << "\n");186(void)LocalFrameSize;187188// Special handling of DBG_VALUE instructions.189if (MI.isDebugValue()) {190Register FrameReg = getFrameRegister(MF);191MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);192MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);193return false;194}195196// fold constant into offset.197Offset += MI.getOperand(FIOperandNum + 1).getImm();198199// TODO: assert based on the load type:200// ldb needs no alignment,201// ldh needs 2 byte alignment202// ld needs 4 byte alignment203LLVM_DEBUG(dbgs() << "Offset : " << Offset << "\n"204<< "<--------->\n");205206Register Reg = MI.getOperand(0).getReg();207assert(ARC::GPR32RegClass.contains(Reg) && "Unexpected register operand");208209if (!TFI->hasFP(MF)) {210Offset = StackSize + Offset;211if (FrameIndex >= 0)212assert((Offset >= 0 && Offset < StackSize) && "SP Offset not in bounds.");213} else {214if (FrameIndex >= 0) {215assert((Offset < 0 && -Offset <= StackSize) &&216"FP Offset not in bounds.");217}218}219replaceFrameIndex(II, TII, Reg, getFrameRegister(MF), Offset, StackSize,220ObjSize, RS, SPAdj);221return true;222}223224Register ARCRegisterInfo::getFrameRegister(const MachineFunction &MF) const {225const ARCFrameLowering *TFI = getFrameLowering(MF);226return TFI->hasFP(MF) ? ARC::FP : ARC::SP;227}228229const uint32_t *230ARCRegisterInfo::getCallPreservedMask(const MachineFunction &MF,231CallingConv::ID CC) const {232return CSR_ARC_RegMask;233}234235236