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#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_DESC
32#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 M68k
47 // 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 methods
57//===----------------------------------------------------------------------===//
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
75unsigned
76M68kRegisterInfo::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 contains
90 // 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, TRC: *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 users
138 for (size_t Reg = 0, Total = getNumRegs(); Reg != Total; ++Reg) {
139 if (MF.getSubtarget<M68kSubtarget>().isRegisterReservedByUser(R: 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, PhysReg: getBaseRegister()))
155 report_fatal_error(reason: "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 form
173 // NOTE Base contains the FI and we need to backtrace a bit to get Disp
174 MachineOperand &Disp = MI.getOperand(i: FIOperandNum - 1);
175 MachineOperand &Base = MI.getOperand(i: FIOperandNum);
176
177 int Imm = (int)(Disp.getImm());
178 int FIndex = (int)(Base.getIndex());
179
180 // FIXME tail call: implement jmp from mem
181 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 else
191 BasePtr = (TFI->hasFP(MF) ? FramePtr : StackPtr);
192
193 Base.ChangeToRegister(Reg: BasePtr, isDef: 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(ObjectIdx: FIndex) - TFI->getOffsetOfLocalArea();
202 } else {
203 FIOffset =
204 TFI->getFrameIndexReference(MF, FI: FIndex, FrameReg&: IgnoredFrameReg).getFixed();
205 }
206
207 if (BasePtr == StackPtr)
208 FIOffset += SPAdj;
209
210 Disp.ChangeToImmediate(ImmVal: 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 frame
235 // pointer. When we have dynamic allocas or stack-adjusting inline asm, we
236 // can't address variables from the stack pointer. MS inline asm can
237 // reference locals while also adjusting the stack pointer. When we can't
238 // 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 started
251 // register allocation with frame pointer elimination, it is too late now.
252 if (!MRI->canReserveReg(PhysReg: 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(PhysReg: 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

source code of llvm/lib/Target/M68k/M68kRegisterInfo.cpp