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