270 lines · cpp
1//===-- M68kRegisterInfo.cpp - CPU0 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/// \file10/// This file contains the CPU0 implementation of the TargetRegisterInfo class.11///12//===----------------------------------------------------------------------===//13 14#include "M68kRegisterInfo.h"15 16#include "M68k.h"17#include "M68kMachineFunction.h"18#include "M68kSubtarget.h"19 20#include "MCTargetDesc/M68kMCTargetDesc.h"21 22#include "llvm/CodeGen/MachineFrameInfo.h"23#include "llvm/CodeGen/MachineRegisterInfo.h"24#include "llvm/IR/Function.h"25#include "llvm/IR/Type.h"26#include "llvm/Support/CommandLine.h"27#include "llvm/Support/Debug.h"28#include "llvm/Support/ErrorHandling.h"29#include "llvm/Support/raw_ostream.h"30 31#define GET_REGINFO_TARGET_DESC32#include "M68kGenRegisterInfo.inc"33 34#define DEBUG_TYPE "m68k-reg-info"35 36using namespace llvm;37 38static cl::opt<bool> EnableBasePointer(39 "m68k-use-base-pointer", cl::Hidden, cl::init(true),40 cl::desc("Enable use of a base pointer for complex stack frames"));41 42// Pin the vtable to this file.43void M68kRegisterInfo::anchor() {}44 45M68kRegisterInfo::M68kRegisterInfo(const M68kSubtarget &ST)46 // FIXME x26 not sure it this the correct value, it expects RA, but M68k47 // passes IP anyway, how this works?48 : M68kGenRegisterInfo(M68k::A0, 0, 0, M68k::PC), Subtarget(ST) {49 StackPtr = M68k::SP;50 FramePtr = M68k::A6;51 GlobalBasePtr = M68k::A5;52 BasePtr = M68k::A4;53}54 55//===----------------------------------------------------------------------===//56// Callee Saved Registers methods57//===----------------------------------------------------------------------===//58 59const MCPhysReg *60M68kRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {61 return CSR_STD_SaveList;62}63 64const uint32_t *65M68kRegisterInfo::getCallPreservedMask(const MachineFunction &MF,66 CallingConv::ID) const {67 return CSR_STD_RegMask;68}69 70const TargetRegisterClass *71M68kRegisterInfo::getRegsForTailCall(const MachineFunction &MF) const {72 return &M68k::XR32_TCRegClass;73}74 75unsigned76M68kRegisterInfo::getMatchingMegaReg(unsigned Reg,77 const TargetRegisterClass *RC) const {78 for (MCPhysReg Super : superregs(Reg))79 if (RC->contains(Super))80 return Super;81 return 0;82}83 84const TargetRegisterClass *85M68kRegisterInfo::getMaximalPhysRegClass(unsigned reg, MVT VT) const {86 assert(Register::isPhysicalRegister(reg) &&87 "reg must be a physical register");88 89 // Pick the most sub register class of the right type that contains90 // this physreg.91 const TargetRegisterClass *BestRC = nullptr;92 for (regclass_iterator I = regclass_begin(), E = regclass_end(); I != E;93 ++I) {94 const TargetRegisterClass *RC = *I;95 if ((VT == MVT::Other || isTypeLegalForClass(*RC, VT)) &&96 RC->contains(reg) &&97 (!BestRC ||98 (BestRC->hasSubClass(RC) && RC->getNumRegs() > BestRC->getNumRegs())))99 BestRC = RC;100 }101 102 assert(BestRC && "Couldn't find the register class");103 return BestRC;104}105 106int M68kRegisterInfo::getRegisterOrder(unsigned Reg,107 const TargetRegisterClass &TRC) const {108 for (unsigned i = 0; i < TRC.getNumRegs(); ++i) {109 if (regsOverlap(Reg, TRC.getRegister(i))) {110 return i;111 }112 }113 return -1;114}115 116int M68kRegisterInfo::getSpillRegisterOrder(unsigned Reg) const {117 int Result = getRegisterOrder(Reg, *getRegClass(M68k::SPILLRegClassID));118 assert(Result >= 0 && "Can not determine spill order");119 return Result;120}121 122BitVector M68kRegisterInfo::getReservedRegs(const MachineFunction &MF) const {123 const M68kFrameLowering *TFI = getFrameLowering(MF);124 125 BitVector Reserved(getNumRegs());126 127 // Set a register's and its sub-registers and aliases as reserved.128 auto setBitVector = [&Reserved, this](unsigned Reg) {129 for (MCRegAliasIterator I(Reg, this, /* self */ true); I.isValid(); ++I) {130 Reserved.set(*I);131 }132 for (MCPhysReg I : subregs_inclusive(Reg)) {133 Reserved.set(I);134 }135 };136 137 // Registers reserved by users138 for (size_t Reg = 0, Total = getNumRegs(); Reg != Total; ++Reg) {139 if (MF.getSubtarget<M68kSubtarget>().isRegisterReservedByUser(Reg))140 setBitVector(Reg);141 }142 143 setBitVector(M68k::PC);144 setBitVector(M68k::SP);145 146 if (TFI->hasFP(MF)) {147 setBitVector(FramePtr);148 }149 150 // Set the base-pointer register and its aliases as reserved if needed.151 if (hasBasePointer(MF)) {152 CallingConv::ID CC = MF.getFunction().getCallingConv();153 const uint32_t *RegMask = getCallPreservedMask(MF, CC);154 if (MachineOperand::clobbersPhysReg(RegMask, getBaseRegister()))155 report_fatal_error("Stack realignment in presence of dynamic allocas is "156 "not supported with"157 "this calling convention.");158 159 setBitVector(getBaseRegister());160 }161 162 return Reserved;163}164 165bool M68kRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,166 int SPAdj, unsigned FIOperandNum,167 RegScavenger *RS) const {168 MachineInstr &MI = *II;169 MachineFunction &MF = *MI.getParent()->getParent();170 const M68kFrameLowering *TFI = getFrameLowering(MF);171 172 // We have either (i,An,Rn) or (i,An) EA form173 // NOTE Base contains the FI and we need to backtrace a bit to get Disp174 MachineOperand &Disp = MI.getOperand(FIOperandNum - 1);175 MachineOperand &Base = MI.getOperand(FIOperandNum);176 177 int Imm = (int)(Disp.getImm());178 int FIndex = (int)(Base.getIndex());179 180 // FIXME tail call: implement jmp from mem181 bool AfterFPPop = false;182 183 unsigned BasePtr;184 if (hasBasePointer(MF))185 BasePtr = (FIndex < 0 ? FramePtr : getBaseRegister());186 else if (hasStackRealignment(MF))187 BasePtr = (FIndex < 0 ? FramePtr : StackPtr);188 else if (AfterFPPop)189 BasePtr = StackPtr;190 else191 BasePtr = (TFI->hasFP(MF) ? FramePtr : StackPtr);192 193 Base.ChangeToRegister(BasePtr, false);194 195 // Now add the frame object offset to the offset from FP.196 int64_t FIOffset;197 Register IgnoredFrameReg;198 if (AfterFPPop) {199 // Tail call jmp happens after FP is popped.200 const MachineFrameInfo &MFI = MF.getFrameInfo();201 FIOffset = MFI.getObjectOffset(FIndex) - TFI->getOffsetOfLocalArea();202 } else {203 FIOffset =204 TFI->getFrameIndexReference(MF, FIndex, IgnoredFrameReg).getFixed();205 }206 207 if (BasePtr == StackPtr)208 FIOffset += SPAdj;209 210 Disp.ChangeToImmediate(FIOffset + Imm);211 return false;212}213 214bool M68kRegisterInfo::requiresRegisterScavenging(215 const MachineFunction &MF) const {216 return false;217}218 219bool M68kRegisterInfo::trackLivenessAfterRegAlloc(220 const MachineFunction &MF) const {221 return true;222}223 224static bool CantUseSP(const MachineFrameInfo &MFI) {225 return MFI.hasVarSizedObjects() || MFI.hasOpaqueSPAdjustment();226}227 228bool M68kRegisterInfo::hasBasePointer(const MachineFunction &MF) const {229 const MachineFrameInfo &MFI = MF.getFrameInfo();230 231 if (!EnableBasePointer)232 return false;233 234 // When we need stack realignment, we can't address the stack from the frame235 // pointer. When we have dynamic allocas or stack-adjusting inline asm, we236 // can't address variables from the stack pointer. MS inline asm can237 // reference locals while also adjusting the stack pointer. When we can't238 // use both the SP and the FP, we need a separate base pointer register.239 bool CantUseFP = hasStackRealignment(MF);240 return CantUseFP && CantUseSP(MFI);241}242 243bool M68kRegisterInfo::canRealignStack(const MachineFunction &MF) const {244 if (!TargetRegisterInfo::canRealignStack(MF))245 return false;246 247 const MachineFrameInfo &MFI = MF.getFrameInfo();248 const MachineRegisterInfo *MRI = &MF.getRegInfo();249 250 // Stack realignment requires a frame pointer. If we already started251 // register allocation with frame pointer elimination, it is too late now.252 if (!MRI->canReserveReg(FramePtr))253 return false;254 255 // If a base pointer is necessary. Check that it isn't too late to reserve it.256 if (CantUseSP(MFI))257 return MRI->canReserveReg(BasePtr);258 259 return true;260}261 262Register M68kRegisterInfo::getFrameRegister(const MachineFunction &MF) const {263 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();264 return TFI->hasFP(MF) ? FramePtr : StackPtr;265}266 267const TargetRegisterClass *M68kRegisterInfo::intRegClass(unsigned size) const {268 return &M68k::DR32RegClass;269}270