LLVM 19.0.0git
M68kRegisterInfo.cpp
Go to the documentation of this file.
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
21
24#include "llvm/IR/Function.h"
25#include "llvm/IR/Type.h"
27#include "llvm/Support/Debug.h"
30
31#define GET_REGINFO_TARGET_DESC
32#include "M68kGenRegisterInfo.inc"
33
34#define DEBUG_TYPE "m68k-reg-info"
35
36using namespace llvm;
37
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.
43void M68kRegisterInfo::anchor() {}
44
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
59const MCPhysReg *
61 return CSR_STD_SaveList;
62}
63
64const uint32_t *
66 CallingConv::ID) const {
67 return CSR_STD_RegMask;
68}
69
72 return &M68k::XR32_TCRegClass;
73}
74
75unsigned
77 const TargetRegisterClass *RC) const {
78 for (MCPhysReg Super : superregs(Reg))
79 if (RC->contains(Super))
80 return Super;
81 return 0;
82}
83
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
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
117 int Result = getRegisterOrder(Reg, *getRegClass(M68k::SPILLRegClassID));
118 assert(Result >= 0 && "Can not determine spill order");
119 return Result;
120}
121
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) {
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)) {
153 const uint32_t *RegMask = getCallPreservedMask(MF, CC);
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
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 return false;
212}
213
215 const MachineFunction &MF) const {
216 return false;
217}
218
220 const MachineFunction &MF) const {
221 return true;
222}
223
224static bool CantUseSP(const MachineFrameInfo &MFI) {
225 return MFI.hasVarSizedObjects() || MFI.hasOpaqueSPAdjustment();
226}
227
229 const MachineFrameInfo &MFI = MF.getFrameInfo();
230
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
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(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(BasePtr);
258
259 return true;
260}
261
264 return TFI->hasFP(MF) ? FramePtr : StackPtr;
265}
266
268 return &M68k::DR32RegClass;
269}
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
IRTranslator LLVM IR MI
This file provides M68k specific target descriptions.
This file declares the M68k specific subclass of MachineFunctionInfo.
static cl::opt< bool > EnableBasePointer("m68k-use-base-pointer", cl::Hidden, cl::init(true), cl::desc("Enable use of a base pointer for complex stack frames"))
static bool CantUseSP(const MachineFrameInfo &MFI)
This file contains the M68k implementation of the TargetRegisterInfo class.
This file declares the M68k specific subclass of TargetSubtargetInfo.
This file contains the entry points for global functions defined in the M68k target library,...
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:263
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
This method should return the base register and offset used to reference a frame index location.
bool hasFP(const MachineFunction &MF) const override
Return true if the specified function should have a dedicated frame pointer register.
unsigned getMatchingMegaReg(unsigned Reg, const TargetRegisterClass *RC) const
Return a mega-register of the specified register Reg so its sub-register of index SubIdx is Reg,...
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
const TargetRegisterClass * intRegClass(unsigned Size) const
Register getFrameRegister(const MachineFunction &MF) const override
unsigned getBaseRegister() const
M68kRegisterInfo(const M68kSubtarget &Subtarget)
bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override
int getSpillRegisterOrder(unsigned Reg) const
Return spill order index of a register, if there is none then trap.
bool requiresRegisterScavenging(const MachineFunction &MF) const override
const TargetRegisterClass * getRegsForTailCall(const MachineFunction &MF) const
Returns a register class with registers that can be used in forming tail calls.
const TargetRegisterClass * getMaximalPhysRegClass(unsigned reg, MVT VT) const
Returns the Register Class of a physical register of the given type, picking the biggest register cla...
int getRegisterOrder(unsigned Reg, const TargetRegisterClass &TRC) const
Return index of a register within a register class, otherwise return -1.
bool hasBasePointer(const MachineFunction &MF) const
bool eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
FrameIndex represent objects inside a abstract stack.
bool canRealignStack(const MachineFunction &MF) const override
True if the stack can be realigned for the target.
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
bool isRegisterReservedByUser(Register R) const
MCRegAliasIterator enumerates all registers aliasing Reg.
Machine Value Type.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool hasOpaqueSPAdjustment() const
Returns true if the function contains opaque dynamic stack adjustments.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
static constexpr bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:65
static StackOffset getFixed(int64_t Fixed)
Definition: TypeSize.h:42
Information about stack frame layout on the target.
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register.
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
unsigned getNumRegs() const
Return the number of registers in this class.
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
bool hasSubClass(const TargetRegisterClass *RC) const
Return true if the specified TargetRegisterClass is a proper sub-class of this TargetRegisterClass.
MCRegister getRegister(unsigned i) const
Return the specified register in the class.
virtual bool canRealignStack(const MachineFunction &MF) const
True if the stack can be realigned for the target.
virtual const TargetFrameLowering * getFrameLowering() const
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:450
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156