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 (MCSuperRegIterator Super(Reg, this); Super.isValid(); ++Super)
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, *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 (MCSubRegIterator I(Reg, this, /* self */ true); I.isValid(); ++I) {
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(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, getBaseRegister()))
155       report_fatal_error("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 void 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(FIOperandNum - 1);
175   MachineOperand &Base = MI.getOperand(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(BasePtr, 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(FIndex) - TFI->getOffsetOfLocalArea();
202   } else {
203     FIOffset =
204         TFI->getFrameIndexReference(MF, FIndex, IgnoredFrameReg).getFixed();
205   }
206 
207   if (BasePtr == StackPtr)
208     FIOffset += SPAdj;
209 
210   Disp.ChangeToImmediate(FIOffset + Imm);
211 }
212 
213 bool M68kRegisterInfo::requiresRegisterScavenging(
214     const MachineFunction &MF) const {
215   return true;
216 }
217 
218 bool M68kRegisterInfo::trackLivenessAfterRegAlloc(
219     const MachineFunction &MF) const {
220   return true;
221 }
222 
223 static bool CantUseSP(const MachineFrameInfo &MFI) {
224   return MFI.hasVarSizedObjects() || MFI.hasOpaqueSPAdjustment();
225 }
226 
227 bool M68kRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
228   const MachineFrameInfo &MFI = MF.getFrameInfo();
229 
230   if (!EnableBasePointer)
231     return false;
232 
233   // When we need stack realignment, we can't address the stack from the frame
234   // pointer.  When we have dynamic allocas or stack-adjusting inline asm, we
235   // can't address variables from the stack pointer.  MS inline asm can
236   // reference locals while also adjusting the stack pointer.  When we can't
237   // use both the SP and the FP, we need a separate base pointer register.
238   bool CantUseFP = hasStackRealignment(MF);
239   return CantUseFP && CantUseSP(MFI);
240 }
241 
242 bool M68kRegisterInfo::canRealignStack(const MachineFunction &MF) const {
243   if (!TargetRegisterInfo::canRealignStack(MF))
244     return false;
245 
246   const MachineFrameInfo &MFI = MF.getFrameInfo();
247   const MachineRegisterInfo *MRI = &MF.getRegInfo();
248 
249   // Stack realignment requires a frame pointer.  If we already started
250   // register allocation with frame pointer elimination, it is too late now.
251   if (!MRI->canReserveReg(FramePtr))
252     return false;
253 
254   // If a base pointer is necessary. Check that it isn't too late to reserve it.
255   if (CantUseSP(MFI))
256     return MRI->canReserveReg(BasePtr);
257 
258   return true;
259 }
260 
261 Register M68kRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
262   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
263   return TFI->hasFP(MF) ? FramePtr : StackPtr;
264 }
265 
266 const TargetRegisterClass *M68kRegisterInfo::intRegClass(unsigned size) const {
267   return &M68k::DR32RegClass;
268 }
269