Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/M68kRegisterInfo.cpp
96353 views
//===-- M68kRegisterInfo.cpp - CPU0 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/// \file9/// This file contains the CPU0 implementation of the TargetRegisterInfo class.10///11//===----------------------------------------------------------------------===//1213#include "M68kRegisterInfo.h"1415#include "M68k.h"16#include "M68kMachineFunction.h"17#include "M68kSubtarget.h"1819#include "MCTargetDesc/M68kMCTargetDesc.h"2021#include "llvm/CodeGen/MachineFrameInfo.h"22#include "llvm/CodeGen/MachineRegisterInfo.h"23#include "llvm/IR/Function.h"24#include "llvm/IR/Type.h"25#include "llvm/Support/CommandLine.h"26#include "llvm/Support/Debug.h"27#include "llvm/Support/ErrorHandling.h"28#include "llvm/Support/raw_ostream.h"2930#define GET_REGINFO_TARGET_DESC31#include "M68kGenRegisterInfo.inc"3233#define DEBUG_TYPE "m68k-reg-info"3435using namespace llvm;3637static cl::opt<bool> EnableBasePointer(38"m68k-use-base-pointer", cl::Hidden, cl::init(true),39cl::desc("Enable use of a base pointer for complex stack frames"));4041// Pin the vtable to this file.42void M68kRegisterInfo::anchor() {}4344M68kRegisterInfo::M68kRegisterInfo(const M68kSubtarget &ST)45// FIXME x26 not sure it this the correct value, it expects RA, but M68k46// passes IP anyway, how this works?47: M68kGenRegisterInfo(M68k::A0, 0, 0, M68k::PC), Subtarget(ST) {48StackPtr = M68k::SP;49FramePtr = M68k::A6;50GlobalBasePtr = M68k::A5;51BasePtr = M68k::A4;52}5354//===----------------------------------------------------------------------===//55// Callee Saved Registers methods56//===----------------------------------------------------------------------===//5758const MCPhysReg *59M68kRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {60return CSR_STD_SaveList;61}6263const uint32_t *64M68kRegisterInfo::getCallPreservedMask(const MachineFunction &MF,65CallingConv::ID) const {66return CSR_STD_RegMask;67}6869const TargetRegisterClass *70M68kRegisterInfo::getRegsForTailCall(const MachineFunction &MF) const {71return &M68k::XR32_TCRegClass;72}7374unsigned75M68kRegisterInfo::getMatchingMegaReg(unsigned Reg,76const TargetRegisterClass *RC) const {77for (MCPhysReg Super : superregs(Reg))78if (RC->contains(Super))79return Super;80return 0;81}8283const TargetRegisterClass *84M68kRegisterInfo::getMaximalPhysRegClass(unsigned reg, MVT VT) const {85assert(Register::isPhysicalRegister(reg) &&86"reg must be a physical register");8788// Pick the most sub register class of the right type that contains89// this physreg.90const TargetRegisterClass *BestRC = nullptr;91for (regclass_iterator I = regclass_begin(), E = regclass_end(); I != E;92++I) {93const TargetRegisterClass *RC = *I;94if ((VT == MVT::Other || isTypeLegalForClass(*RC, VT)) &&95RC->contains(reg) &&96(!BestRC ||97(BestRC->hasSubClass(RC) && RC->getNumRegs() > BestRC->getNumRegs())))98BestRC = RC;99}100101assert(BestRC && "Couldn't find the register class");102return BestRC;103}104105int M68kRegisterInfo::getRegisterOrder(unsigned Reg,106const TargetRegisterClass &TRC) const {107for (unsigned i = 0; i < TRC.getNumRegs(); ++i) {108if (regsOverlap(Reg, TRC.getRegister(i))) {109return i;110}111}112return -1;113}114115int M68kRegisterInfo::getSpillRegisterOrder(unsigned Reg) const {116int Result = getRegisterOrder(Reg, *getRegClass(M68k::SPILLRegClassID));117assert(Result >= 0 && "Can not determine spill order");118return Result;119}120121BitVector M68kRegisterInfo::getReservedRegs(const MachineFunction &MF) const {122const M68kFrameLowering *TFI = getFrameLowering(MF);123124BitVector Reserved(getNumRegs());125126// Set a register's and its sub-registers and aliases as reserved.127auto setBitVector = [&Reserved, this](unsigned Reg) {128for (MCRegAliasIterator I(Reg, this, /* self */ true); I.isValid(); ++I) {129Reserved.set(*I);130}131for (MCPhysReg I : subregs_inclusive(Reg)) {132Reserved.set(I);133}134};135136// Registers reserved by users137for (size_t Reg = 0, Total = getNumRegs(); Reg != Total; ++Reg) {138if (MF.getSubtarget<M68kSubtarget>().isRegisterReservedByUser(Reg))139setBitVector(Reg);140}141142setBitVector(M68k::PC);143setBitVector(M68k::SP);144145if (TFI->hasFP(MF)) {146setBitVector(FramePtr);147}148149// Set the base-pointer register and its aliases as reserved if needed.150if (hasBasePointer(MF)) {151CallingConv::ID CC = MF.getFunction().getCallingConv();152const uint32_t *RegMask = getCallPreservedMask(MF, CC);153if (MachineOperand::clobbersPhysReg(RegMask, getBaseRegister()))154report_fatal_error("Stack realignment in presence of dynamic allocas is "155"not supported with"156"this calling convention.");157158setBitVector(getBaseRegister());159}160161return Reserved;162}163164bool M68kRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,165int SPAdj, unsigned FIOperandNum,166RegScavenger *RS) const {167MachineInstr &MI = *II;168MachineFunction &MF = *MI.getParent()->getParent();169const M68kFrameLowering *TFI = getFrameLowering(MF);170171// We have either (i,An,Rn) or (i,An) EA form172// NOTE Base contains the FI and we need to backtrace a bit to get Disp173MachineOperand &Disp = MI.getOperand(FIOperandNum - 1);174MachineOperand &Base = MI.getOperand(FIOperandNum);175176int Imm = (int)(Disp.getImm());177int FIndex = (int)(Base.getIndex());178179// FIXME tail call: implement jmp from mem180bool AfterFPPop = false;181182unsigned BasePtr;183if (hasBasePointer(MF))184BasePtr = (FIndex < 0 ? FramePtr : getBaseRegister());185else if (hasStackRealignment(MF))186BasePtr = (FIndex < 0 ? FramePtr : StackPtr);187else if (AfterFPPop)188BasePtr = StackPtr;189else190BasePtr = (TFI->hasFP(MF) ? FramePtr : StackPtr);191192Base.ChangeToRegister(BasePtr, false);193194// Now add the frame object offset to the offset from FP.195int64_t FIOffset;196Register IgnoredFrameReg;197if (AfterFPPop) {198// Tail call jmp happens after FP is popped.199const MachineFrameInfo &MFI = MF.getFrameInfo();200FIOffset = MFI.getObjectOffset(FIndex) - TFI->getOffsetOfLocalArea();201} else {202FIOffset =203TFI->getFrameIndexReference(MF, FIndex, IgnoredFrameReg).getFixed();204}205206if (BasePtr == StackPtr)207FIOffset += SPAdj;208209Disp.ChangeToImmediate(FIOffset + Imm);210return false;211}212213bool M68kRegisterInfo::requiresRegisterScavenging(214const MachineFunction &MF) const {215return false;216}217218bool M68kRegisterInfo::trackLivenessAfterRegAlloc(219const MachineFunction &MF) const {220return true;221}222223static bool CantUseSP(const MachineFrameInfo &MFI) {224return MFI.hasVarSizedObjects() || MFI.hasOpaqueSPAdjustment();225}226227bool M68kRegisterInfo::hasBasePointer(const MachineFunction &MF) const {228const MachineFrameInfo &MFI = MF.getFrameInfo();229230if (!EnableBasePointer)231return false;232233// When we need stack realignment, we can't address the stack from the frame234// pointer. When we have dynamic allocas or stack-adjusting inline asm, we235// can't address variables from the stack pointer. MS inline asm can236// reference locals while also adjusting the stack pointer. When we can't237// use both the SP and the FP, we need a separate base pointer register.238bool CantUseFP = hasStackRealignment(MF);239return CantUseFP && CantUseSP(MFI);240}241242bool M68kRegisterInfo::canRealignStack(const MachineFunction &MF) const {243if (!TargetRegisterInfo::canRealignStack(MF))244return false;245246const MachineFrameInfo &MFI = MF.getFrameInfo();247const MachineRegisterInfo *MRI = &MF.getRegInfo();248249// Stack realignment requires a frame pointer. If we already started250// register allocation with frame pointer elimination, it is too late now.251if (!MRI->canReserveReg(FramePtr))252return false;253254// If a base pointer is necessary. Check that it isn't too late to reserve it.255if (CantUseSP(MFI))256return MRI->canReserveReg(BasePtr);257258return true;259}260261Register M68kRegisterInfo::getFrameRegister(const MachineFunction &MF) const {262const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();263return TFI->hasFP(MF) ? FramePtr : StackPtr;264}265266const TargetRegisterClass *M68kRegisterInfo::intRegClass(unsigned size) const {267return &M68k::DR32RegClass;268}269270271