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/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"
29
30 #define GET_REGINFO_TARGET_DESC
31 #include "M68kGenRegisterInfo.inc"
32
33 #define DEBUG_TYPE "m68k-reg-info"
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.
anchor()42 void M68kRegisterInfo::anchor() {}
43
M68kRegisterInfo(const M68kSubtarget & ST)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 *
getCalleeSavedRegs(const MachineFunction * MF) const59 M68kRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
60 return CSR_STD_SaveList;
61 }
62
63 const uint32_t *
getCallPreservedMask(const MachineFunction & MF,CallingConv::ID) const64 M68kRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
65 CallingConv::ID) const {
66 return CSR_STD_RegMask;
67 }
68
69 const TargetRegisterClass *
getRegsForTailCall(const MachineFunction & MF) const70 M68kRegisterInfo::getRegsForTailCall(const MachineFunction &MF) const {
71 return &M68k::XR32_TCRegClass;
72 }
73
74 unsigned
getMatchingMegaReg(unsigned Reg,const TargetRegisterClass * RC) const75 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 *
getMaximalPhysRegClass(unsigned reg,MVT VT) const84 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
getRegisterOrder(unsigned Reg,const TargetRegisterClass & TRC) const105 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
getSpillRegisterOrder(unsigned Reg) const115 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
getReservedRegs(const MachineFunction & MF) const121 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
eliminateFrameIndex(MachineBasicBlock::iterator II,int SPAdj,unsigned FIOperandNum,RegScavenger * RS) const164 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
requiresRegisterScavenging(const MachineFunction & MF) const212 bool M68kRegisterInfo::requiresRegisterScavenging(
213 const MachineFunction &MF) const {
214 return true;
215 }
216
trackLivenessAfterRegAlloc(const MachineFunction & MF) const217 bool M68kRegisterInfo::trackLivenessAfterRegAlloc(
218 const MachineFunction &MF) const {
219 return true;
220 }
221
CantUseSP(const MachineFrameInfo & MFI)222 static bool CantUseSP(const MachineFrameInfo &MFI) {
223 return MFI.hasVarSizedObjects() || MFI.hasOpaqueSPAdjustment();
224 }
225
hasBasePointer(const MachineFunction & MF) const226 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
canRealignStack(const MachineFunction & MF) const241 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
getFrameRegister(const MachineFunction & MF) const260 Register M68kRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
261 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
262 return TFI->hasFP(MF) ? FramePtr : StackPtr;
263 }
264
intRegClass(unsigned size) const265 const TargetRegisterClass *M68kRegisterInfo::intRegClass(unsigned size) const {
266 return &M68k::DR32RegClass;
267 }
268