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 #define DEBUG_TYPE "m68k-reg-info"
15 
16 #include "M68kRegisterInfo.h"
17 
18 #include "M68k.h"
19 #include "M68kMachineFunction.h"
20 #include "M68kSubtarget.h"
21 
22 #include "MCTargetDesc/M68kMCTargetDesc.h"
23 
24 #include "llvm/CodeGen/MachineRegisterInfo.h"
25 #include "llvm/IR/Function.h"
26 #include "llvm/IR/Type.h"
27 #include "llvm/Support/CommandLine.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/ErrorHandling.h"
30 #include "llvm/Support/raw_ostream.h"
31 
32 #define GET_REGINFO_TARGET_DESC
33 #include "M68kGenRegisterInfo.inc"
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   setBitVector(M68k::PC);
137   setBitVector(M68k::SP);
138 
139   if (TFI->hasFP(MF)) {
140     setBitVector(FramePtr);
141   }
142 
143   // Set the base-pointer register and its aliases as reserved if needed.
144   if (hasBasePointer(MF)) {
145     CallingConv::ID CC = MF.getFunction().getCallingConv();
146     const uint32_t *RegMask = getCallPreservedMask(MF, CC);
147     if (MachineOperand::clobbersPhysReg(RegMask, getBaseRegister()))
148       report_fatal_error("Stack realignment in presence of dynamic allocas is "
149                          "not supported with"
150                          "this calling convention.");
151 
152     setBitVector(getBaseRegister());
153   }
154 
155   return Reserved;
156 }
157 
158 void M68kRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
159                                            int SPAdj, unsigned FIOperandNum,
160                                            RegScavenger *RS) const {
161   MachineInstr &MI = *II;
162   MachineFunction &MF = *MI.getParent()->getParent();
163   const M68kFrameLowering *TFI = getFrameLowering(MF);
164 
165   // We have either (i,An,Rn) or (i,An) EA form
166   // NOTE Base contains the FI and we need to backtrace a bit to get Disp
167   MachineOperand &Disp = MI.getOperand(FIOperandNum - 1);
168   MachineOperand &Base = MI.getOperand(FIOperandNum);
169 
170   int Imm = (int)(Disp.getImm());
171   int FIndex = (int)(Base.getIndex());
172 
173   // FIXME tail call: implement jmp from mem
174   bool AfterFPPop = false;
175 
176   unsigned BasePtr;
177   if (hasBasePointer(MF))
178     BasePtr = (FIndex < 0 ? FramePtr : getBaseRegister());
179   else if (hasStackRealignment(MF))
180     BasePtr = (FIndex < 0 ? FramePtr : StackPtr);
181   else if (AfterFPPop)
182     BasePtr = StackPtr;
183   else
184     BasePtr = (TFI->hasFP(MF) ? FramePtr : StackPtr);
185 
186   Base.ChangeToRegister(BasePtr, false);
187 
188   // Now add the frame object offset to the offset from FP.
189   int64_t FIOffset;
190   Register IgnoredFrameReg;
191   if (AfterFPPop) {
192     // Tail call jmp happens after FP is popped.
193     const MachineFrameInfo &MFI = MF.getFrameInfo();
194     FIOffset = MFI.getObjectOffset(FIndex) - TFI->getOffsetOfLocalArea();
195   } else {
196     FIOffset =
197         TFI->getFrameIndexReference(MF, FIndex, IgnoredFrameReg).getFixed();
198   }
199 
200   if (BasePtr == StackPtr)
201     FIOffset += SPAdj;
202 
203   Disp.ChangeToImmediate(FIOffset + Imm);
204 }
205 
206 bool M68kRegisterInfo::requiresRegisterScavenging(
207     const MachineFunction &MF) const {
208   return true;
209 }
210 
211 bool M68kRegisterInfo::trackLivenessAfterRegAlloc(
212     const MachineFunction &MF) const {
213   return true;
214 }
215 
216 static bool CantUseSP(const MachineFrameInfo &MFI) {
217   return MFI.hasVarSizedObjects() || MFI.hasOpaqueSPAdjustment();
218 }
219 
220 bool M68kRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
221   const MachineFrameInfo &MFI = MF.getFrameInfo();
222 
223   if (!EnableBasePointer)
224     return false;
225 
226   // When we need stack realignment, we can't address the stack from the frame
227   // pointer.  When we have dynamic allocas or stack-adjusting inline asm, we
228   // can't address variables from the stack pointer.  MS inline asm can
229   // reference locals while also adjusting the stack pointer.  When we can't
230   // use both the SP and the FP, we need a separate base pointer register.
231   bool CantUseFP = hasStackRealignment(MF);
232   return CantUseFP && CantUseSP(MFI);
233 }
234 
235 bool M68kRegisterInfo::canRealignStack(const MachineFunction &MF) const {
236   if (!TargetRegisterInfo::canRealignStack(MF))
237     return false;
238 
239   const MachineFrameInfo &MFI = MF.getFrameInfo();
240   const MachineRegisterInfo *MRI = &MF.getRegInfo();
241 
242   // Stack realignment requires a frame pointer.  If we already started
243   // register allocation with frame pointer elimination, it is too late now.
244   if (!MRI->canReserveReg(FramePtr))
245     return false;
246 
247   // If a base pointer is necessary. Check that it isn't too late to reserve it.
248   if (CantUseSP(MFI))
249     return MRI->canReserveReg(BasePtr);
250 
251   return true;
252 }
253 
254 Register M68kRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
255   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
256   return TFI->hasFP(MF) ? FramePtr : StackPtr;
257 }
258 
259 const TargetRegisterClass *M68kRegisterInfo::intRegClass(unsigned size) const {
260   return &M68k::DR32RegClass;
261 }
262