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