LLVM 24.0.0git
MipsRegisterInfo.cpp
Go to the documentation of this file.
1//===- MipsRegisterInfo.cpp - MIPS Register Information -------------------===//
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// This file contains the MIPS implementation of the TargetRegisterInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "MipsRegisterInfo.h"
15#include "Mips.h"
16#include "MipsMachineFunction.h"
17#include "MipsSubtarget.h"
18#include "MipsTargetMachine.h"
19#include "llvm/ADT/BitVector.h"
27#include "llvm/IR/Function.h"
28#include "llvm/IR/Module.h"
29#include "llvm/Support/Debug.h"
32#include <cstdint>
33
34using namespace llvm;
35
36#define DEBUG_TYPE "mips-reg-info"
37
38#define GET_REGINFO_TARGET_DESC
39#include "MipsGenRegisterInfo.inc"
40
42 : MipsGenRegisterInfo(Mips::RA), ArePtrs64bit(STI.getABI().ArePtrs64bit()) {
44}
45
46unsigned MipsRegisterInfo::getPICCallReg() { return Mips::R25; }
47
48unsigned
50 MachineFunction &MF) const {
51 switch (RC->getID()) {
52 default:
53 return 0;
54 case Mips::GPR32RegClassID:
55 case Mips::GPR64RegClassID:
56 case Mips::DSPRRegClassID: {
58 return 28 - TFI->hasFP(MF);
59 }
60 case Mips::FGR32RegClassID:
61 return 32;
62 case Mips::AFGR64RegClassID:
63 return 16;
64 case Mips::FGR64RegClassID:
65 return 32;
66 }
67}
68
69//===----------------------------------------------------------------------===//
70// Callee Saved Registers methods
71//===----------------------------------------------------------------------===//
72
73/// Check if the user has declared $gp/$28 as a global regiater.
75 const Module *Module = MF.getFunction().getParent();
76
77 return Module->getNamedMetadata("llvm.named.register.$28");
78}
79
80/// Mips Callee Saved Registers
81const MCPhysReg *
83 const MipsSubtarget &Subtarget = MF->getSubtarget<MipsSubtarget>();
84 const Function &F = MF->getFunction();
85 if (F.hasFnAttribute("interrupt")) {
86 if (Subtarget.hasMips64())
87 return Subtarget.hasMips64r6() ? CSR_Interrupt_64R6_SaveList
88 : CSR_Interrupt_64_SaveList;
89 else
90 return Subtarget.hasMips32r6() ? CSR_Interrupt_32R6_SaveList
91 : CSR_Interrupt_32_SaveList;
92 }
93
94 bool GPIsGlobal = isGPUsedAsGlobalRegister(*MF);
95 // N64 ABI
96 if (Subtarget.isABI_N64()) {
97 if (Subtarget.isSingleFloat())
98 return GPIsGlobal ? CSR_N64_SingleFloat_NoGP_SaveList
99 : CSR_N64_SingleFloat_SaveList;
100
101 return GPIsGlobal ? CSR_N64_NoGP_SaveList : CSR_N64_SaveList;
102 }
103
104 // N32 ABI
105 if (Subtarget.isABI_N32()) {
106 if (Subtarget.isSingleFloat())
107 return GPIsGlobal ? CSR_N32_SingleFloat_NoGP_SaveList
108 : CSR_N32_SingleFloat_SaveList;
109
110 return GPIsGlobal ? CSR_N32_NoGP_SaveList : CSR_N32_SaveList;
111 }
112
113 // O32 ABI
114 if (Subtarget.isSingleFloat())
115 return CSR_O32_SingleFloat_SaveList;
116
117 if (Subtarget.isFP64bit())
118 return CSR_O32_FP64_SaveList;
119
120 if (Subtarget.isFPXX())
121 return CSR_O32_FPXX_SaveList;
122
123 return CSR_O32_SaveList;
124}
125
126const uint32_t *
128 CallingConv::ID) const {
129 const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
130 // N64 ABI
131 if (Subtarget.isABI_N64()) {
132 if (Subtarget.isSingleFloat())
133 return CSR_N64_SingleFloat_RegMask;
134
135 return CSR_N64_RegMask;
136 }
137
138 // N32 ABI
139 if (Subtarget.isABI_N32()) {
140 if (Subtarget.isSingleFloat())
141 return CSR_N32_SingleFloat_RegMask;
142
143 return CSR_N32_RegMask;
144 }
145
146 // O32 ABI
147 if (Subtarget.isSingleFloat())
148 return CSR_O32_SingleFloat_RegMask;
149
150 if (Subtarget.isFP64bit())
151 return CSR_O32_FP64_RegMask;
152
153 if (Subtarget.isFPXX())
154 return CSR_O32_FPXX_RegMask;
155
156 return CSR_O32_RegMask;
157}
158
160 return CSR_Mips16RetHelper_RegMask;
161}
162
164getReservedRegs(const MachineFunction &MF) const {
165 static const MCPhysReg ReservedGPR32[] = {Mips::R0, Mips::R26, Mips::R27,
166 Mips::SP};
167
168 static const MCPhysReg ReservedGPR64[] = {Mips::R0_64, Mips::R26_64,
169 Mips::R27_64, Mips::SP_64};
170
171 BitVector Reserved(getNumRegs());
172 const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
173
174 for (MCPhysReg R : ReservedGPR32)
175 Reserved.set(R);
176
177 for (MCPhysReg R : ReservedGPR64)
178 Reserved.set(R);
179
180 // Static JIT code uses t9 in RuntimeDyld stubs for R_MIPS_26 relocations,
181 // including jumps within a function. Keep it out of register allocation.
182 const auto &TM = static_cast<const MipsTargetMachine &>(MF.getTarget());
183 if (TM.isJIT() && TM.getRelocationModel() == Reloc::Static)
184 markSuperRegs(Reserved, Mips::R25);
185
186 // Mark user-reserved GPRs and their 64-bit super-registers.
187 for (unsigned I = 1; I < 32; ++I)
188 if (Subtarget.isGPRReservedByUser(I))
189 markSuperRegs(Reserved, Mips::GPR32RegClass.getRegister(I));
190
191 // For mno-abicalls, GP is a program invariant!
192 bool GPIsGlobal = isGPUsedAsGlobalRegister(MF);
193 if (!Subtarget.isABICalls() || GPIsGlobal) {
194 Reserved.set(Mips::GP);
196 }
197
198 if (Subtarget.isFP64bit()) {
199 // Reserve all registers in AFGR64.
200 for (MCPhysReg Reg : Mips::AFGR64RegClass)
201 Reserved.set(Reg);
202 } else {
203 // Reserve all registers in FGR64.
204 for (MCPhysReg Reg : Mips::FGR64RegClass)
205 Reserved.set(Reg);
206 }
207 // Reserve FP if this function should have a dedicated frame pointer register.
208 if (Subtarget.getFrameLowering()->hasFP(MF)) {
209 if (Subtarget.inMips16Mode())
210 Reserved.set(Mips::R16);
211 else {
212 Reserved.set(Mips::FP);
214
215 // Reserve the base register if we need to both realign the stack and
216 // allocate variable-sized objects at runtime. This should test the
217 // same conditions as MipsFrameLowering::hasBP().
218 if (hasStackRealignment(MF) && MF.getFrameInfo().hasVarSizedObjects()) {
219 const MipsABIInfo &ABI = Subtarget.getABI();
220 Reserved.set(ABI.getSavedReg(7, false));
221 Reserved.set(ABI.getSavedReg(7, true));
222 }
223 }
224 }
225 // Reserve fp control and status register
226 Reserved.set(Mips::FCR31);
227
228 // Reserve hardware registers.
229 Reserved.set(Mips::HWR29);
230 Reserved.set(Mips::HWR2);
231
232 // Reserve DSP control register.
233 Reserved.set(Mips::DSPPos);
234 Reserved.set(Mips::DSPSCount);
235 Reserved.set(Mips::DSPCarry);
236 Reserved.set(Mips::DSPEFI);
237 Reserved.set(Mips::DSPOutFlag);
238
239 // Reserve MSA control registers.
240 for (MCPhysReg Reg : Mips::MSACtrlRegClass)
241 Reserved.set(Reg);
242
243 // Reserve RA if in mips16 mode.
244 if (Subtarget.inMips16Mode()) {
245 const MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
246 Reserved.set(Mips::RA);
248 Reserved.set(Mips::R8);
249 Reserved.set(Mips::R9);
250 if (MF.getFunction().hasFnAttribute("saveS2") || MipsFI->hasSaveS2())
251 Reserved.set(Mips::R18);
252 }
253
254 // Reserve GP if small section is used.
255 if (Subtarget.useSmallSection()) {
256 Reserved.set(Mips::GP);
258 }
259
260 return Reserved;
261}
262
263// FrameIndex represent objects inside a abstract stack.
264// We must replace FrameIndex with an stack/frame pointer
265// direct reference.
268 unsigned FIOperandNum, RegScavenger *RS) const {
269 MachineInstr &MI = *II;
270 MachineFunction &MF = *MI.getParent()->getParent();
271
272 LLVM_DEBUG(errs() << "\nFunction : " << MF.getName() << "\n";
273 errs() << "<--------->\n"
274 << MI);
275
276 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
277 uint64_t stackSize = MF.getFrameInfo().getStackSize();
278 int64_t spOffset = MF.getFrameInfo().getObjectOffset(FrameIndex);
279
280 LLVM_DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
281 << "spOffset : " << spOffset << "\n"
282 << "stackSize : " << stackSize << "\n"
283 << "alignment : "
284 << DebugStr(MF.getFrameInfo().getObjectAlign(FrameIndex))
285 << "\n");
286
287 eliminateFI(MI, FIOperandNum, FrameIndex, stackSize, spOffset);
288 return false;
289}
290
292getFrameRegister(const MachineFunction &MF) const {
293 const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
294 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
295 bool IsN64 = Subtarget.getABI().IsN64();
296
297 if (Subtarget.inMips16Mode())
298 return TFI->hasFP(MF) ? Mips::R16 : Mips::SP;
299 else
300 return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) :
301 (IsN64 ? Mips::SP_64 : Mips::SP);
302}
303
305 // Avoid realigning functions that explicitly do not want to be realigned.
306 // Normally, we should report an error when a function should be dynamically
307 // realigned but also has the attribute no-realign-stack. Unfortunately,
308 // with this attribute, MachineFrameInfo clamps each new object's alignment
309 // to that of the stack's alignment as specified by the ABI. As a result,
310 // the information of whether we have objects with larger alignment
311 // requirement than the stack's alignment is already lost at this point.
313 return false;
314
315 const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
316 unsigned FP = Subtarget.isGP32bit() ? Mips::FP : Mips::FP_64;
317 unsigned BP = Subtarget.getABI().getSavedReg(7, Subtarget.isGP64bit());
318
319 // Support dynamic stack realignment for all targets except Mips16.
320 if (Subtarget.inMips16Mode())
321 return false;
322
323 // We can't perform dynamic stack realignment if we can't reserve the
324 // frame pointer register.
325 if (!MF.getRegInfo().canReserveReg(FP))
326 return false;
327
328 // We can realign the stack if we know the maximum call frame size and we
329 // don't have variable sized objects.
330 if (Subtarget.getFrameLowering()->hasReservedCallFrame(MF))
331 return true;
332
333 // We have to reserve the base pointer register in the presence of variable
334 // sized objects.
335 return MF.getRegInfo().canReserveReg(BP);
336}
This file implements the BitVector class.
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
bool isGPUsedAsGlobalRegister(const MachineFunction &MF)
Check if the user has declared $gp/$28 as a global regiater.
uint64_t IntrinsicInst * II
SI optimize exec mask operations pre RA
#define LLVM_DEBUG(...)
Definition Debug.h:119
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:731
Module * getParent()
Get the module that this global value is contained inside of...
unsigned getID() const
getID() - Return the register class ID number.
MachineInstrBundleIterator< MachineInstr > iterator
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
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.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
bool canReserveReg(MCRegister PhysReg) const
canReserveReg - Returns true if PhysReg can be used as a reserved register.
bool IsN64() const
Definition MipsABIInfo.h:41
MCRegister getSavedReg(unsigned I, bool Is64Bit) const
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
static unsigned getPICCallReg()
Get PIC indirect call register.
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
Register getFrameRegister(const MachineFunction &MF) const override
Debug information queries.
bool eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
Stack Frame Processing Methods.
unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override
Code Generation virtual methods...
static const uint32_t * getMips16RetHelperMask()
bool canRealignStack(const MachineFunction &MF) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
MipsRegisterInfo(const MipsSubtarget &STI)
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Mips Callee Saved Registers.
bool hasMips32r6() const
bool isFP64bit() const
bool isGP32bit() const
bool hasMips64r6() const
bool inMips16Mode() const
bool hasMips64() const
bool isABICalls() const
bool isGP64bit() const
bool isSingleFloat() const
bool useSmallSection() const
const MipsABIInfo & getABI() const
bool isGPRReservedByUser(unsigned GPR) const
const TargetFrameLowering * getFrameLowering() const override
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
NamedMDNode * getNamedMetadata(StringRef Name) const
Return the first NamedMDNode in the module with the specified name.
Definition Module.cpp:301
Wrapper class representing virtual and physical registers.
Definition Register.h:20
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.
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
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
void initLLVMToCVRegMapping(MCRegisterInfo *MRI)
constexpr MCPhysReg FP_64
constexpr MCPhysReg GP_64
constexpr MCPhysReg FP
constexpr MCPhysReg GP
constexpr MCPhysReg RA_64
constexpr MCPhysReg SP
constexpr MCPhysReg SP_64
constexpr MCPhysReg RA
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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