LLVM 19.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"
20#include "llvm/ADT/STLExtras.h"
28#include "llvm/IR/Function.h"
30#include "llvm/Support/Debug.h"
33#include <cstdint>
34
35using namespace llvm;
36
37#define DEBUG_TYPE "mips-reg-info"
38
39#define GET_REGINFO_TARGET_DESC
40#include "MipsGenRegisterInfo.inc"
41
43
44unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; }
45
48 unsigned Kind) const {
49 MipsABIInfo ABI = MF.getSubtarget<MipsSubtarget>().getABI();
50 MipsPtrClass PtrClassKind = static_cast<MipsPtrClass>(Kind);
51
52 switch (PtrClassKind) {
54 return ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
56 return &Mips::GPRMM16RegClass;
58 return ABI.ArePtrs64bit() ? &Mips::SP64RegClass : &Mips::SP32RegClass;
60 return ABI.ArePtrs64bit() ? &Mips::GP64RegClass : &Mips::GP32RegClass;
61 }
62
63 llvm_unreachable("Unknown pointer kind");
64}
65
66unsigned
68 MachineFunction &MF) const {
69 switch (RC->getID()) {
70 default:
71 return 0;
72 case Mips::GPR32RegClassID:
73 case Mips::GPR64RegClassID:
74 case Mips::DSPRRegClassID: {
76 return 28 - TFI->hasFP(MF);
77 }
78 case Mips::FGR32RegClassID:
79 return 32;
80 case Mips::AFGR64RegClassID:
81 return 16;
82 case Mips::FGR64RegClassID:
83 return 32;
84 }
85}
86
87//===----------------------------------------------------------------------===//
88// Callee Saved Registers methods
89//===----------------------------------------------------------------------===//
90
91/// Mips Callee Saved Registers
92const MCPhysReg *
94 const MipsSubtarget &Subtarget = MF->getSubtarget<MipsSubtarget>();
95 const Function &F = MF->getFunction();
96 if (F.hasFnAttribute("interrupt")) {
97 if (Subtarget.hasMips64())
98 return Subtarget.hasMips64r6() ? CSR_Interrupt_64R6_SaveList
99 : CSR_Interrupt_64_SaveList;
100 else
101 return Subtarget.hasMips32r6() ? CSR_Interrupt_32R6_SaveList
102 : CSR_Interrupt_32_SaveList;
103 }
104
105 if (Subtarget.isSingleFloat())
106 return CSR_SingleFloatOnly_SaveList;
107
108 if (Subtarget.isABI_N64())
109 return CSR_N64_SaveList;
110
111 if (Subtarget.isABI_N32())
112 return CSR_N32_SaveList;
113
114 if (Subtarget.isFP64bit())
115 return CSR_O32_FP64_SaveList;
116
117 if (Subtarget.isFPXX())
118 return CSR_O32_FPXX_SaveList;
119
120 return CSR_O32_SaveList;
121}
122
123const uint32_t *
125 CallingConv::ID) const {
126 const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
127 if (Subtarget.isSingleFloat())
128 return CSR_SingleFloatOnly_RegMask;
129
130 if (Subtarget.isABI_N64())
131 return CSR_N64_RegMask;
132
133 if (Subtarget.isABI_N32())
134 return CSR_N32_RegMask;
135
136 if (Subtarget.isFP64bit())
137 return CSR_O32_FP64_RegMask;
138
139 if (Subtarget.isFPXX())
140 return CSR_O32_FPXX_RegMask;
141
142 return CSR_O32_RegMask;
143}
144
146 return CSR_Mips16RetHelper_RegMask;
147}
148
150getReservedRegs(const MachineFunction &MF) const {
151 static const MCPhysReg ReservedGPR32[] = {
152 Mips::ZERO, Mips::K0, Mips::K1, Mips::SP
153 };
154
155 static const MCPhysReg ReservedGPR64[] = {
156 Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64
157 };
158
159 BitVector Reserved(getNumRegs());
160 const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
161
162 for (MCPhysReg R : ReservedGPR32)
163 Reserved.set(R);
164
165 // Reserve registers for the NaCl sandbox.
166 if (Subtarget.isTargetNaCl()) {
167 Reserved.set(Mips::T6); // Reserved for control flow mask.
168 Reserved.set(Mips::T7); // Reserved for memory access mask.
169 Reserved.set(Mips::T8); // Reserved for thread pointer.
170 }
171
172 for (MCPhysReg R : ReservedGPR64)
173 Reserved.set(R);
174
175 // For mno-abicalls, GP is a program invariant!
176 if (!Subtarget.isABICalls()) {
177 Reserved.set(Mips::GP);
178 Reserved.set(Mips::GP_64);
179 }
180
181 if (Subtarget.isFP64bit()) {
182 // Reserve all registers in AFGR64.
183 for (MCPhysReg Reg : Mips::AFGR64RegClass)
184 Reserved.set(Reg);
185 } else {
186 // Reserve all registers in FGR64.
187 for (MCPhysReg Reg : Mips::FGR64RegClass)
188 Reserved.set(Reg);
189 }
190 // Reserve FP if this function should have a dedicated frame pointer register.
191 if (Subtarget.getFrameLowering()->hasFP(MF)) {
192 if (Subtarget.inMips16Mode())
193 Reserved.set(Mips::S0);
194 else {
195 Reserved.set(Mips::FP);
196 Reserved.set(Mips::FP_64);
197
198 // Reserve the base register if we need to both realign the stack and
199 // allocate variable-sized objects at runtime. This should test the
200 // same conditions as MipsFrameLowering::hasBP().
201 if (hasStackRealignment(MF) && MF.getFrameInfo().hasVarSizedObjects()) {
202 Reserved.set(Mips::S7);
203 Reserved.set(Mips::S7_64);
204 }
205 }
206 }
207
208 // Reserve hardware registers.
209 Reserved.set(Mips::HWR29);
210
211 // Reserve DSP control register.
212 Reserved.set(Mips::DSPPos);
213 Reserved.set(Mips::DSPSCount);
214 Reserved.set(Mips::DSPCarry);
215 Reserved.set(Mips::DSPEFI);
216 Reserved.set(Mips::DSPOutFlag);
217
218 // Reserve MSA control registers.
219 for (MCPhysReg Reg : Mips::MSACtrlRegClass)
220 Reserved.set(Reg);
221
222 // Reserve RA if in mips16 mode.
223 if (Subtarget.inMips16Mode()) {
224 const MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
225 Reserved.set(Mips::RA);
226 Reserved.set(Mips::RA_64);
227 Reserved.set(Mips::T0);
228 Reserved.set(Mips::T1);
229 if (MF.getFunction().hasFnAttribute("saveS2") || MipsFI->hasSaveS2())
230 Reserved.set(Mips::S2);
231 }
232
233 // Reserve GP if small section is used.
234 if (Subtarget.useSmallSection()) {
235 Reserved.set(Mips::GP);
236 Reserved.set(Mips::GP_64);
237 }
238
239 return Reserved;
240}
241
242// FrameIndex represent objects inside a abstract stack.
243// We must replace FrameIndex with an stack/frame pointer
244// direct reference.
247 unsigned FIOperandNum, RegScavenger *RS) const {
248 MachineInstr &MI = *II;
249 MachineFunction &MF = *MI.getParent()->getParent();
250
251 LLVM_DEBUG(errs() << "\nFunction : " << MF.getName() << "\n";
252 errs() << "<--------->\n"
253 << MI);
254
255 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
256 uint64_t stackSize = MF.getFrameInfo().getStackSize();
257 int64_t spOffset = MF.getFrameInfo().getObjectOffset(FrameIndex);
258
259 LLVM_DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
260 << "spOffset : " << spOffset << "\n"
261 << "stackSize : " << stackSize << "\n"
262 << "alignment : "
263 << DebugStr(MF.getFrameInfo().getObjectAlign(FrameIndex))
264 << "\n");
265
266 eliminateFI(MI, FIOperandNum, FrameIndex, stackSize, spOffset);
267 return false;
268}
269
271getFrameRegister(const MachineFunction &MF) const {
272 const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
273 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
274 bool IsN64 =
275 static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI().IsN64();
276
277 if (Subtarget.inMips16Mode())
278 return TFI->hasFP(MF) ? Mips::S0 : Mips::SP;
279 else
280 return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) :
281 (IsN64 ? Mips::SP_64 : Mips::SP);
282}
283
285 // Avoid realigning functions that explicitly do not want to be realigned.
286 // Normally, we should report an error when a function should be dynamically
287 // realigned but also has the attribute no-realign-stack. Unfortunately,
288 // with this attribute, MachineFrameInfo clamps each new object's alignment
289 // to that of the stack's alignment as specified by the ABI. As a result,
290 // the information of whether we have objects with larger alignment
291 // requirement than the stack's alignment is already lost at this point.
293 return false;
294
295 const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
296 unsigned FP = Subtarget.isGP32bit() ? Mips::FP : Mips::FP_64;
297 unsigned BP = Subtarget.isGP32bit() ? Mips::S7 : Mips::S7_64;
298
299 // Support dynamic stack realignment for all targets except Mips16.
300 if (Subtarget.inMips16Mode())
301 return false;
302
303 // We can't perform dynamic stack realignment if we can't reserve the
304 // frame pointer register.
305 if (!MF.getRegInfo().canReserveReg(FP))
306 return false;
307
308 // We can realign the stack if we know the maximum call frame size and we
309 // don't have variable sized objects.
310 if (Subtarget.getFrameLowering()->hasReservedCallFrame(MF))
311 return true;
312
313 // We have to reserve the base pointer register in the presence of variable
314 // sized objects.
315 return MF.getRegInfo().canReserveReg(BP);
316}
This file implements the BitVector class.
#define LLVM_DEBUG(X)
Definition: Debug.h:101
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
SI optimize exec mask operations pre RA
This file contains some templates that are useful if you are working with the STL at all.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:675
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.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
Definition: MachineInstr.h:69
bool canReserveReg(MCRegister PhysReg) const
canReserveReg - Returns true if PhysReg can be used as a reserved register.
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
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind) const override
Code Generation virtual methods...
@ StackPointer
The stack pointer only.
@ Default
The default register class for integer values.
@ GlobalPointer
The global pointer only.
@ GPR16MM
The subset of registers permitted in certain microMIPS instructions such as lw16.
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Mips Callee Saved Registers.
bool hasMips32r6() const
bool isFP64bit() const
bool isGP32bit() const
bool isABI_N64() const
bool hasMips64r6() const
bool inMips16Mode() const
bool hasMips64() const
bool isABICalls() const
bool isSingleFloat() const
bool isABI_N32() const
bool useSmallSection() const
bool isTargetNaCl() const
bool isFPXX() const
const TargetFrameLowering * getFrameLowering() const override
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Information about stack frame layout on the target.
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register.
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
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.