LLVM 24.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"
26#include "llvm/Support/Debug.h"
29
30#define GET_REGINFO_TARGET_DESC
31#include "M68kGenRegisterInfo.inc"
32
33#define DEBUG_TYPE "m68k-reg-info"
34
35using namespace llvm;
36
37// Pin the vtable to this file.
38void M68kRegisterInfo::anchor() {}
39
41 // FIXME x26 not sure it this the correct value, it expects RA, but M68k
42 // passes IP anyway, how this works?
43 : M68kGenRegisterInfo(M68k::A0, 0, 0, M68k::PC), Subtarget(ST) {
44 StackPtr = M68k::SP;
45 FramePtr = M68k::A6;
46 GlobalBasePtr = M68k::A5;
47 BasePtr = M68k::A4;
48}
49
50//===----------------------------------------------------------------------===//
51// Callee Saved Registers methods
52//===----------------------------------------------------------------------===//
53
54const MCPhysReg *
56 return CSR_STD_SaveList;
57}
58
59const uint32_t *
61 CallingConv::ID) const {
62 return CSR_STD_RegMask;
63}
64
67 return &M68k::XR32_TCRegClass;
68}
69
70unsigned
72 const TargetRegisterClass *RC) const {
73 for (MCPhysReg Super : superregs(Reg))
74 if (RC->contains(Super))
75 return Super;
76 return 0;
77}
78
82 "reg must be a physical register");
83
84 // Pick the most sub register class of the right type that contains
85 // this physreg.
86 const TargetRegisterClass *BestRC = nullptr;
87 for (const TargetRegisterClass &RC : regclasses()) {
88 if ((VT == MVT::Other || isTypeLegalForClass(RC, VT)) && RC.contains(reg) &&
89 (!BestRC ||
90 (BestRC->hasSubClass(&RC) && RC.getNumRegs() > BestRC->getNumRegs())))
91 BestRC = &RC;
92 }
93
94 assert(BestRC && "Couldn't find the register class");
95 return BestRC;
96}
97
99 const TargetRegisterClass &TRC) const {
100 for (unsigned i = 0; i < TRC.getNumRegs(); ++i) {
101 if (regsOverlap(Reg, TRC.getRegister(i))) {
102 return i;
103 }
104 }
105 return -1;
106}
107
109 int Result = getRegisterOrder(Reg, *getRegClass(M68k::SPILLRegClassID));
110 assert(Result >= 0 && "Can not determine spill order");
111 return Result;
112}
113
115 const M68kFrameLowering *TFI = getFrameLowering(MF);
116
117 BitVector Reserved(getNumRegs());
118
119 // Set a register's and its sub-registers and aliases as reserved.
120 auto setBitVector = [&Reserved, this](unsigned Reg) {
121 for (MCRegAliasIterator I(Reg, this, /* self */ true); I.isValid(); ++I) {
122 Reserved.set(*I);
123 }
124 for (MCPhysReg I : subregs_inclusive(Reg)) {
125 Reserved.set(I);
126 }
127 };
128
129 // Registers reserved by users
130 for (size_t Reg = 0, Total = getNumRegs(); Reg != Total; ++Reg) {
132 setBitVector(Reg);
133 }
134
135 setBitVector(M68k::PC);
136 setBitVector(M68k::SP);
137
138 if (TFI->hasFP(MF)) {
139 setBitVector(FramePtr);
140 }
141
142 // Set the base-pointer register and its aliases as reserved if needed.
143 if (hasBasePointer(MF)) {
145 const uint32_t *RegMask = getCallPreservedMask(MF, CC);
147 report_fatal_error("Stack realignment in presence of dynamic allocas is "
148 "not supported with"
149 "this calling convention.");
150
151 setBitVector(getBaseRegister());
152 }
153
154 return Reserved;
155}
156
158 int SPAdj, unsigned FIOperandNum,
159 RegScavenger *RS) const {
160 MachineInstr &MI = *II;
161 MachineFunction &MF = *MI.getParent()->getParent();
162 const M68kFrameLowering *TFI = getFrameLowering(MF);
163
164 // We have either (i,An,Rn) or (i,An) EA form
165 // NOTE Base contains the FI and we need to backtrace a bit to get Disp
166 MachineOperand &Disp = MI.getOperand(FIOperandNum - 1);
167 MachineOperand &Base = MI.getOperand(FIOperandNum);
168
169 int Imm = (int)(Disp.getImm());
170 int FIndex = (int)(Base.getIndex());
171
172 // FIXME tail call: implement jmp from mem
173 bool AfterFPPop = false;
174
175 unsigned BasePtr;
176 if (hasBasePointer(MF))
177 BasePtr = (FIndex < 0 ? FramePtr : getBaseRegister());
178 else if (hasStackRealignment(MF))
179 BasePtr = (FIndex < 0 ? FramePtr : StackPtr);
180 else if (AfterFPPop)
181 BasePtr = StackPtr;
182 else
183 BasePtr = (TFI->hasFP(MF) ? FramePtr : StackPtr);
184
185 Base.ChangeToRegister(BasePtr, false);
186
187 // Now add the frame object offset to the offset from FP.
188 int64_t FIOffset;
189 Register IgnoredFrameReg;
190 if (AfterFPPop) {
191 // Tail call jmp happens after FP is popped.
192 const MachineFrameInfo &MFI = MF.getFrameInfo();
193 FIOffset = MFI.getObjectOffset(FIndex) - TFI->getOffsetOfLocalArea();
194 } else {
195 FIOffset =
196 TFI->getFrameIndexReference(MF, FIndex, IgnoredFrameReg).getFixed();
197 }
198
199 if (BasePtr == StackPtr)
200 FIOffset += SPAdj;
201
202 Disp.ChangeToImmediate(FIOffset + Imm);
203 return false;
204}
205
207 const MachineFunction &MF) const {
208 return false;
209}
210
212 const MachineFunction &MF) const {
213 return true;
214}
215
216static bool CantUseSP(const MachineFrameInfo &MFI) {
217 return MFI.hasVarSizedObjects() || MFI.hasOpaqueSPAdjustment();
218}
219
221 const MachineFrameInfo &MFI = MF.getFrameInfo();
222
223 if (!Subtarget.getCLOpts().use_base_pointer)
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
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
256 return TFI->hasFP(MF) ? FramePtr : StackPtr;
257}
258
260 return &M68k::DR32RegClass;
261}
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t Imm
IRTranslator LLVM IR MI
This file provides M68k specific target descriptions.
This file declares the M68k specific subclass of MachineFunctionInfo.
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
RISCVCC::CondCode CC
MachineRegisterInfo & MRI
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:273
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,...
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:40
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.
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:1685
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