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 setBitVector(M68k::PC); 137 setBitVector(M68k::SP); 138 139 if (TFI->hasFP(MF)) { 140 setBitVector(FramePtr); 141 } 142 143 // Set the base-pointer register and its aliases as reserved if needed. 144 if (hasBasePointer(MF)) { 145 CallingConv::ID CC = MF.getFunction().getCallingConv(); 146 const uint32_t *RegMask = getCallPreservedMask(MF, CC); 147 if (MachineOperand::clobbersPhysReg(RegMask, getBaseRegister())) 148 report_fatal_error("Stack realignment in presence of dynamic allocas is " 149 "not supported with" 150 "this calling convention."); 151 152 setBitVector(getBaseRegister()); 153 } 154 155 return Reserved; 156 } 157 158 void M68kRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 159 int SPAdj, unsigned FIOperandNum, 160 RegScavenger *RS) const { 161 MachineInstr &MI = *II; 162 MachineFunction &MF = *MI.getParent()->getParent(); 163 const M68kFrameLowering *TFI = getFrameLowering(MF); 164 165 // We have either (i,An,Rn) or (i,An) EA form 166 // NOTE Base contains the FI and we need to backtrace a bit to get Disp 167 MachineOperand &Disp = MI.getOperand(FIOperandNum - 1); 168 MachineOperand &Base = MI.getOperand(FIOperandNum); 169 170 int Imm = (int)(Disp.getImm()); 171 int FIndex = (int)(Base.getIndex()); 172 173 // FIXME tail call: implement jmp from mem 174 bool AfterFPPop = false; 175 176 unsigned BasePtr; 177 if (hasBasePointer(MF)) 178 BasePtr = (FIndex < 0 ? FramePtr : getBaseRegister()); 179 else if (hasStackRealignment(MF)) 180 BasePtr = (FIndex < 0 ? FramePtr : StackPtr); 181 else if (AfterFPPop) 182 BasePtr = StackPtr; 183 else 184 BasePtr = (TFI->hasFP(MF) ? FramePtr : StackPtr); 185 186 Base.ChangeToRegister(BasePtr, false); 187 188 // Now add the frame object offset to the offset from FP. 189 int64_t FIOffset; 190 Register IgnoredFrameReg; 191 if (AfterFPPop) { 192 // Tail call jmp happens after FP is popped. 193 const MachineFrameInfo &MFI = MF.getFrameInfo(); 194 FIOffset = MFI.getObjectOffset(FIndex) - TFI->getOffsetOfLocalArea(); 195 } else { 196 FIOffset = 197 TFI->getFrameIndexReference(MF, FIndex, IgnoredFrameReg).getFixed(); 198 } 199 200 if (BasePtr == StackPtr) 201 FIOffset += SPAdj; 202 203 Disp.ChangeToImmediate(FIOffset + Imm); 204 } 205 206 bool M68kRegisterInfo::requiresRegisterScavenging( 207 const MachineFunction &MF) const { 208 return true; 209 } 210 211 bool M68kRegisterInfo::trackLivenessAfterRegAlloc( 212 const MachineFunction &MF) const { 213 return true; 214 } 215 216 static bool CantUseSP(const MachineFrameInfo &MFI) { 217 return MFI.hasVarSizedObjects() || MFI.hasOpaqueSPAdjustment(); 218 } 219 220 bool M68kRegisterInfo::hasBasePointer(const MachineFunction &MF) const { 221 const MachineFrameInfo &MFI = MF.getFrameInfo(); 222 223 if (!EnableBasePointer) 224 return false; 225 226 // When we need stack realignment, we can't address the stack from the frame 227 // pointer. When we have dynamic allocas or stack-adjusting inline asm, we 228 // can't address variables from the stack pointer. MS inline asm can 229 // reference locals while also adjusting the stack pointer. When we can't 230 // use both the SP and the FP, we need a separate base pointer register. 231 bool CantUseFP = hasStackRealignment(MF); 232 return CantUseFP && CantUseSP(MFI); 233 } 234 235 bool M68kRegisterInfo::canRealignStack(const MachineFunction &MF) const { 236 if (!TargetRegisterInfo::canRealignStack(MF)) 237 return false; 238 239 const MachineFrameInfo &MFI = MF.getFrameInfo(); 240 const MachineRegisterInfo *MRI = &MF.getRegInfo(); 241 242 // Stack realignment requires a frame pointer. If we already started 243 // register allocation with frame pointer elimination, it is too late now. 244 if (!MRI->canReserveReg(FramePtr)) 245 return false; 246 247 // If a base pointer is necessary. Check that it isn't too late to reserve it. 248 if (CantUseSP(MFI)) 249 return MRI->canReserveReg(BasePtr); 250 251 return true; 252 } 253 254 Register M68kRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 255 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 256 return TFI->hasFP(MF) ? FramePtr : StackPtr; 257 } 258 259 const TargetRegisterClass *M68kRegisterInfo::intRegClass(unsigned size) const { 260 return &M68k::DR32RegClass; 261 } 262