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.
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   // 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 
164 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 
212 bool M68kRegisterInfo::requiresRegisterScavenging(
213     const MachineFunction &MF) const {
214   return true;
215 }
216 
217 bool M68kRegisterInfo::trackLivenessAfterRegAlloc(
218     const MachineFunction &MF) const {
219   return true;
220 }
221 
222 static bool CantUseSP(const MachineFrameInfo &MFI) {
223   return MFI.hasVarSizedObjects() || MFI.hasOpaqueSPAdjustment();
224 }
225 
226 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 
241 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 
260 Register M68kRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
261   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
262   return TFI->hasFP(MF) ? FramePtr : StackPtr;
263 }
264 
265 const TargetRegisterClass *M68kRegisterInfo::intRegClass(unsigned size) const {
266   return &M68k::DR32RegClass;
267 }
268