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