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 | |
36 | using namespace llvm; |
37 | |
38 | static 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. |
43 | void M68kRegisterInfo::anchor() {} |
44 | |
45 | M68kRegisterInfo::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 | |
59 | const MCPhysReg * |
60 | M68kRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { |
61 | return CSR_STD_SaveList; |
62 | } |
63 | |
64 | const uint32_t * |
65 | M68kRegisterInfo::getCallPreservedMask(const MachineFunction &MF, |
66 | CallingConv::ID) const { |
67 | return CSR_STD_RegMask; |
68 | } |
69 | |
70 | const TargetRegisterClass * |
71 | M68kRegisterInfo::getRegsForTailCall(const MachineFunction &MF) const { |
72 | return &M68k::XR32_TCRegClass; |
73 | } |
74 | |
75 | unsigned |
76 | M68kRegisterInfo::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 | |
84 | const TargetRegisterClass * |
85 | M68kRegisterInfo::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 | |
106 | int 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 | |
116 | int 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 | |
122 | BitVector 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 | |
165 | bool 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 | |
214 | bool M68kRegisterInfo::requiresRegisterScavenging( |
215 | const MachineFunction &MF) const { |
216 | return false; |
217 | } |
218 | |
219 | bool M68kRegisterInfo::trackLivenessAfterRegAlloc( |
220 | const MachineFunction &MF) const { |
221 | return true; |
222 | } |
223 | |
224 | static bool CantUseSP(const MachineFrameInfo &MFI) { |
225 | return MFI.hasVarSizedObjects() || MFI.hasOpaqueSPAdjustment(); |
226 | } |
227 | |
228 | bool 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 | |
243 | bool 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 | |
262 | Register M68kRegisterInfo::getFrameRegister(const MachineFunction &MF) const { |
263 | const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); |
264 | return TFI->hasFP(MF) ? FramePtr : StackPtr; |
265 | } |
266 | |
267 | const TargetRegisterClass *M68kRegisterInfo::intRegClass(unsigned size) const { |
268 | return &M68k::DR32RegClass; |
269 | } |
270 | |