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 "llvm/ADT/BitVector.h"
26#include "llvm/IR/Function.h"
27#include "llvm/IR/Module.h"
28#include "llvm/Support/Debug.h"
31#include <cstdint>
32
33using namespace llvm;
34
35#define DEBUG_TYPE "mips-reg-info"
36
37#define GET_REGINFO_TARGET_DESC
38#include "MipsGenRegisterInfo.inc"
39
41 : MipsGenRegisterInfo(Mips::RA), ArePtrs64bit(STI.getABI().ArePtrs64bit()) {
43}
44
45unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; }
46
47unsigned
49 MachineFunction &MF) const {
50 switch (RC->getID()) {
51 default:
52 return 0;
53 case Mips::GPR32RegClassID:
54 case Mips::GPR64RegClassID:
55 case Mips::DSPRRegClassID: {
57 return 28 - TFI->hasFP(MF);
58 }
59 case Mips::FGR32RegClassID:
60 return 32;
61 case Mips::AFGR64RegClassID:
62 return 16;
63 case Mips::FGR64RegClassID:
64 return 32;
65 }
66}
67
68//===----------------------------------------------------------------------===//
69// Callee Saved Registers methods
70//===----------------------------------------------------------------------===//
71
72/// Check if the user has declared $gp/$28 as a global regiater.
74 const Module *Module = MF.getFunction().getParent();
75
76 return Module->getNamedMetadata("llvm.named.register.$28");
77}
78
79/// Mips Callee Saved Registers
80const MCPhysReg *
82 const MipsSubtarget &Subtarget = MF->getSubtarget<MipsSubtarget>();
83 const Function &F = MF->getFunction();
84 if (F.hasFnAttribute("interrupt")) {
85 if (Subtarget.hasMips64())
86 return Subtarget.hasMips64r6() ? CSR_Interrupt_64R6_SaveList
87 : CSR_Interrupt_64_SaveList;
88 else
89 return Subtarget.hasMips32r6() ? CSR_Interrupt_32R6_SaveList
90 : CSR_Interrupt_32_SaveList;
91 }
92
93 bool GPIsGlobal = isGPUsedAsGlobalRegister(*MF);
94 // N64 ABI
95 if (Subtarget.isABI_N64()) {
96 if (Subtarget.isSingleFloat())
97 return GPIsGlobal ? CSR_N64_SingleFloat_NoGP_SaveList
98 : CSR_N64_SingleFloat_SaveList;
99
100 return GPIsGlobal ? CSR_N64_NoGP_SaveList : CSR_N64_SaveList;
101 }
102
103 // N32 ABI
104 if (Subtarget.isABI_N32()) {
105 if (Subtarget.isSingleFloat())
106 return GPIsGlobal ? CSR_N32_SingleFloat_NoGP_SaveList
107 : CSR_N32_SingleFloat_SaveList;
108
109 return GPIsGlobal ? CSR_N32_NoGP_SaveList : CSR_N32_SaveList;
110 }
111
112 // O32 ABI
113 if (Subtarget.isSingleFloat())
114 return CSR_O32_SingleFloat_SaveList;
115
116 if (Subtarget.isFP64bit())
117 return CSR_O32_FP64_SaveList;
118
119 if (Subtarget.isFPXX())
120 return CSR_O32_FPXX_SaveList;
121
122 return CSR_O32_SaveList;
123}
124
125const uint32_t *
127 CallingConv::ID) const {
128 const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
129 // N64 ABI
130 if (Subtarget.isABI_N64()) {
131 if (Subtarget.isSingleFloat())
132 return CSR_N64_SingleFloat_RegMask;
133
134 return CSR_N64_RegMask;
135 }
136
137 // N32 ABI
138 if (Subtarget.isABI_N32()) {
139 if (Subtarget.isSingleFloat())
140 return CSR_N32_SingleFloat_RegMask;
141
142 return CSR_N32_RegMask;
143 }
144
145 // O32 ABI
146 if (Subtarget.isSingleFloat())
147 return CSR_O32_SingleFloat_RegMask;
148
149 if (Subtarget.isFP64bit())
150 return CSR_O32_FP64_RegMask;
151
152 if (Subtarget.isFPXX())
153 return CSR_O32_FPXX_RegMask;
154
155 return CSR_O32_RegMask;
156}
157
159 return CSR_Mips16RetHelper_RegMask;
160}
161
163getReservedRegs(const MachineFunction &MF) const {
164 static const MCPhysReg ReservedGPR32[] = {
165 Mips::ZERO, Mips::K0, Mips::K1, Mips::SP
166 };
167
168 static const MCPhysReg ReservedGPR64[] = {
169 Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64
170 };
171
172 BitVector Reserved(getNumRegs());
173 const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
174
175 for (MCPhysReg R : ReservedGPR32)
176 Reserved.set(R);
177
178 for (MCPhysReg R : ReservedGPR64)
179 Reserved.set(R);
180
181 // Mark user-reserved GPRs and their 64-bit super-registers.
182 for (unsigned I = 1; I < 32; ++I)
183 if (Subtarget.isGPRReservedByUser(I))
184 markSuperRegs(Reserved, Mips::GPR32RegClass.getRegister(I));
185
186 // For mno-abicalls, GP is a program invariant!
187 bool GPIsGlobal = isGPUsedAsGlobalRegister(MF);
188 if (!Subtarget.isABICalls() || GPIsGlobal) {
189 Reserved.set(Mips::GP);
190 Reserved.set(Mips::GP_64);
191 }
192
193 if (Subtarget.isFP64bit()) {
194 // Reserve all registers in AFGR64.
195 for (MCPhysReg Reg : Mips::AFGR64RegClass)
196 Reserved.set(Reg);
197 } else {
198 // Reserve all registers in FGR64.
199 for (MCPhysReg Reg : Mips::FGR64RegClass)
200 Reserved.set(Reg);
201 }
202 // Reserve FP if this function should have a dedicated frame pointer register.
203 if (Subtarget.getFrameLowering()->hasFP(MF)) {
204 if (Subtarget.inMips16Mode())
205 Reserved.set(Mips::S0);
206 else {
207 Reserved.set(Mips::FP);
208 Reserved.set(Mips::FP_64);
209
210 // Reserve the base register if we need to both realign the stack and
211 // allocate variable-sized objects at runtime. This should test the
212 // same conditions as MipsFrameLowering::hasBP().
213 if (hasStackRealignment(MF) && MF.getFrameInfo().hasVarSizedObjects()) {
214 Reserved.set(Mips::S7);
215 Reserved.set(Mips::S7_64);
216 }
217 }
218 }
219 // Reserve fp control and status register
220 Reserved.set(Mips::FCR31);
221
222 // Reserve hardware registers.
223 Reserved.set(Mips::HWR29);
224 Reserved.set(Mips::HWR2);
225
226 // Reserve DSP control register.
227 Reserved.set(Mips::DSPPos);
228 Reserved.set(Mips::DSPSCount);
229 Reserved.set(Mips::DSPCarry);
230 Reserved.set(Mips::DSPEFI);
231 Reserved.set(Mips::DSPOutFlag);
232
233 // Reserve MSA control registers.
234 for (MCPhysReg Reg : Mips::MSACtrlRegClass)
235 Reserved.set(Reg);
236
237 // Reserve RA if in mips16 mode.
238 if (Subtarget.inMips16Mode()) {
239 const MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
240 Reserved.set(Mips::RA);
241 Reserved.set(Mips::RA_64);
242 Reserved.set(Mips::T0);
243 Reserved.set(Mips::T1);
244 if (MF.getFunction().hasFnAttribute("saveS2") || MipsFI->hasSaveS2())
245 Reserved.set(Mips::S2);
246 }
247
248 // Reserve GP if small section is used.
249 if (Subtarget.useSmallSection()) {
250 Reserved.set(Mips::GP);
251 Reserved.set(Mips::GP_64);
252 }
253
254 return Reserved;
255}
256
257// FrameIndex represent objects inside a abstract stack.
258// We must replace FrameIndex with an stack/frame pointer
259// direct reference.
262 unsigned FIOperandNum, RegScavenger *RS) const {
263 MachineInstr &MI = *II;
264 MachineFunction &MF = *MI.getParent()->getParent();
265
266 LLVM_DEBUG(errs() << "\nFunction : " << MF.getName() << "\n";
267 errs() << "<--------->\n"
268 << MI);
269
270 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
271 uint64_t stackSize = MF.getFrameInfo().getStackSize();
272 int64_t spOffset = MF.getFrameInfo().getObjectOffset(FrameIndex);
273
274 LLVM_DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
275 << "spOffset : " << spOffset << "\n"
276 << "stackSize : " << stackSize << "\n"
277 << "alignment : "
278 << DebugStr(MF.getFrameInfo().getObjectAlign(FrameIndex))
279 << "\n");
280
281 eliminateFI(MI, FIOperandNum, FrameIndex, stackSize, spOffset);
282 return false;
283}
284
286getFrameRegister(const MachineFunction &MF) const {
287 const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
288 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
289 bool IsN64 = Subtarget.getABI().IsN64();
290
291 if (Subtarget.inMips16Mode())
292 return TFI->hasFP(MF) ? Mips::S0 : Mips::SP;
293 else
294 return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) :
295 (IsN64 ? Mips::SP_64 : Mips::SP);
296}
297
299 // Avoid realigning functions that explicitly do not want to be realigned.
300 // Normally, we should report an error when a function should be dynamically
301 // realigned but also has the attribute no-realign-stack. Unfortunately,
302 // with this attribute, MachineFrameInfo clamps each new object's alignment
303 // to that of the stack's alignment as specified by the ABI. As a result,
304 // the information of whether we have objects with larger alignment
305 // requirement than the stack's alignment is already lost at this point.
307 return false;
308
309 const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
310 unsigned FP = Subtarget.isGP32bit() ? Mips::FP : Mips::FP_64;
311 unsigned BP = Subtarget.getABI().getSavedReg(7, Subtarget.isGP64bit());
312
313 // Support dynamic stack realignment for all targets except Mips16.
314 if (Subtarget.inMips16Mode())
315 return false;
316
317 // We can't perform dynamic stack realignment if we can't reserve the
318 // frame pointer register.
319 if (!MF.getRegInfo().canReserveReg(FP))
320 return false;
321
322 // We can realign the stack if we know the maximum call frame size and we
323 // don't have variable sized objects.
324 if (Subtarget.getFrameLowering()->hasReservedCallFrame(MF))
325 return true;
326
327 // We have to reserve the base pointer register in the presence of variable
328 // sized objects.
329 return MF.getRegInfo().canReserveReg(BP);
330}
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:730
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...
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)
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