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