LLVM 23.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 (const TargetRegisterClass &RC : regclasses()) {
93 if ((VT == MVT::Other || isTypeLegalForClass(RC, VT)) && RC.contains(reg) &&
94 (!BestRC ||
95 (BestRC->hasSubClass(&RC) && RC.getNumRegs() > BestRC->getNumRegs())))
96 BestRC = &RC;
97 }
98
99 assert(BestRC && "Couldn't find the register class");
100 return BestRC;
101}
102
104 const TargetRegisterClass &TRC) const {
105 for (unsigned i = 0; i < TRC.getNumRegs(); ++i) {
106 if (regsOverlap(Reg, TRC.getRegister(i))) {
107 return i;
108 }
109 }
110 return -1;
111}
112
114 int Result = getRegisterOrder(Reg, *getRegClass(M68k::SPILLRegClassID));
115 assert(Result >= 0 && "Can not determine spill order");
116 return Result;
117}
118
120 const M68kFrameLowering *TFI = getFrameLowering(MF);
121
122 BitVector Reserved(getNumRegs());
123
124 // Set a register's and its sub-registers and aliases as reserved.
125 auto setBitVector = [&Reserved, this](unsigned Reg) {
126 for (MCRegAliasIterator I(Reg, this, /* self */ true); I.isValid(); ++I) {
127 Reserved.set(*I);
128 }
129 for (MCPhysReg I : subregs_inclusive(Reg)) {
130 Reserved.set(I);
131 }
132 };
133
134 // Registers reserved by users
135 for (size_t Reg = 0, Total = getNumRegs(); Reg != Total; ++Reg) {
137 setBitVector(Reg);
138 }
139
140 setBitVector(M68k::PC);
141 setBitVector(M68k::SP);
142
143 if (TFI->hasFP(MF)) {
144 setBitVector(FramePtr);
145 }
146
147 // Set the base-pointer register and its aliases as reserved if needed.
148 if (hasBasePointer(MF)) {
150 const uint32_t *RegMask = getCallPreservedMask(MF, CC);
152 report_fatal_error("Stack realignment in presence of dynamic allocas is "
153 "not supported with"
154 "this calling convention.");
155
156 setBitVector(getBaseRegister());
157 }
158
159 return Reserved;
160}
161
163 int SPAdj, unsigned FIOperandNum,
164 RegScavenger *RS) const {
165 MachineInstr &MI = *II;
166 MachineFunction &MF = *MI.getParent()->getParent();
167 const M68kFrameLowering *TFI = getFrameLowering(MF);
168
169 // We have either (i,An,Rn) or (i,An) EA form
170 // NOTE Base contains the FI and we need to backtrace a bit to get Disp
171 MachineOperand &Disp = MI.getOperand(FIOperandNum - 1);
172 MachineOperand &Base = MI.getOperand(FIOperandNum);
173
174 int Imm = (int)(Disp.getImm());
175 int FIndex = (int)(Base.getIndex());
176
177 // FIXME tail call: implement jmp from mem
178 bool AfterFPPop = false;
179
180 unsigned BasePtr;
181 if (hasBasePointer(MF))
182 BasePtr = (FIndex < 0 ? FramePtr : getBaseRegister());
183 else if (hasStackRealignment(MF))
184 BasePtr = (FIndex < 0 ? FramePtr : StackPtr);
185 else if (AfterFPPop)
186 BasePtr = StackPtr;
187 else
188 BasePtr = (TFI->hasFP(MF) ? FramePtr : StackPtr);
189
190 Base.ChangeToRegister(BasePtr, false);
191
192 // Now add the frame object offset to the offset from FP.
193 int64_t FIOffset;
194 Register IgnoredFrameReg;
195 if (AfterFPPop) {
196 // Tail call jmp happens after FP is popped.
197 const MachineFrameInfo &MFI = MF.getFrameInfo();
198 FIOffset = MFI.getObjectOffset(FIndex) - TFI->getOffsetOfLocalArea();
199 } else {
200 FIOffset =
201 TFI->getFrameIndexReference(MF, FIndex, IgnoredFrameReg).getFixed();
202 }
203
204 if (BasePtr == StackPtr)
205 FIOffset += SPAdj;
206
207 Disp.ChangeToImmediate(FIOffset + Imm);
208 return false;
209}
210
212 const MachineFunction &MF) const {
213 return false;
214}
215
217 const MachineFunction &MF) const {
218 return true;
219}
220
221static bool CantUseSP(const MachineFrameInfo &MFI) {
222 return MFI.hasVarSizedObjects() || MFI.hasOpaqueSPAdjustment();
223}
224
226 const MachineFrameInfo &MFI = MF.getFrameInfo();
227
229 return false;
230
231 // When we need stack realignment, we can't address the stack from the frame
232 // pointer. When we have dynamic allocas or stack-adjusting inline asm, we
233 // can't address variables from the stack pointer. MS inline asm can
234 // reference locals while also adjusting the stack pointer. When we can't
235 // use both the SP and the FP, we need a separate base pointer register.
236 bool CantUseFP = hasStackRealignment(MF);
237 return CantUseFP && CantUseSP(MFI);
238}
239
242 return false;
243
244 const MachineFrameInfo &MFI = MF.getFrameInfo();
245 const MachineRegisterInfo *MRI = &MF.getRegInfo();
246
247 // Stack realignment requires a frame pointer. If we already started
248 // register allocation with frame pointer elimination, it is too late now.
249 if (!MRI->canReserveReg(FramePtr))
250 return false;
251
252 // If a base pointer is necessary. Check that it isn't too late to reserve it.
253 if (CantUseSP(MFI))
254 return MRI->canReserveReg(BasePtr);
255
256 return true;
257}
258
261 return TFI->hasFP(MF) ? FramePtr : StackPtr;
262}
263
265 return &M68k::DR32RegClass;
266}
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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:57
uint64_t IntrinsicInst * II
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:272
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.
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 M68kSubtarget & Subtarget
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 override
MCRegAliasIterator enumerates all registers aliasing Reg.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
bool hasSubClass(const MCRegisterClass *RC) const
Return true if the specified TargetRegisterClass is a proper sub-class of this TargetRegisterClass.
Machine Value Type.
MachineInstrBundleIterator< MachineInstr > iterator
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.
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
LLVM_ABI 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,...
bool canReserveReg(MCRegister PhysReg) const
canReserveReg - Returns true if PhysReg can be used as a reserved register.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
static constexpr bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition Register.h:60
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:39
Information about stack frame layout on the target.
bool hasFP(const MachineFunction &MF) const
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...
virtual bool canRealignStack(const MachineFunction &MF) const
True if the stack can be realigned for the target.
virtual const TargetFrameLowering * getFrameLowering() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
Define some predicates that are used for node matching.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58