1 //===- MipsRegisterInfo.cpp - MIPS Register Information -------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the MIPS implementation of the TargetRegisterInfo class.
11 //===----------------------------------------------------------------------===//
13 #include "MipsRegisterInfo.h"
14 #include "MCTargetDesc/MipsABIInfo.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"
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineInstr.h"
24 #include "llvm/CodeGen/MachineRegisterInfo.h"
25 #include "llvm/CodeGen/TargetFrameLowering.h"
26 #include "llvm/CodeGen/TargetRegisterInfo.h"
27 #include "llvm/CodeGen/TargetSubtargetInfo.h"
28 #include "llvm/IR/Function.h"
29 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mips-reg-info"
39 #define GET_REGINFO_TARGET_DESC
40 #include "MipsGenRegisterInfo.inc"
42 MipsRegisterInfo::MipsRegisterInfo() : MipsGenRegisterInfo(Mips::RA
) {}
44 unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9
; }
46 const TargetRegisterClass
*
47 MipsRegisterInfo::getPointerRegClass(const MachineFunction
&MF
,
48 unsigned Kind
) const {
49 MipsABIInfo ABI
= MF
.getSubtarget
<MipsSubtarget
>().getABI();
50 MipsPtrClass PtrClassKind
= static_cast<MipsPtrClass
>(Kind
);
52 switch (PtrClassKind
) {
53 case MipsPtrClass::Default
:
54 return ABI
.ArePtrs64bit() ? &Mips::GPR64RegClass
: &Mips::GPR32RegClass
;
55 case MipsPtrClass::GPR16MM
:
56 return &Mips::GPRMM16RegClass
;
57 case MipsPtrClass::StackPointer
:
58 return ABI
.ArePtrs64bit() ? &Mips::SP64RegClass
: &Mips::SP32RegClass
;
59 case MipsPtrClass::GlobalPointer
:
60 return ABI
.ArePtrs64bit() ? &Mips::GP64RegClass
: &Mips::GP32RegClass
;
63 llvm_unreachable("Unknown pointer kind");
67 MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass
*RC
,
68 MachineFunction
&MF
) const {
69 switch (RC
->getID()) {
72 case Mips::GPR32RegClassID
:
73 case Mips::GPR64RegClassID
:
74 case Mips::DSPRRegClassID
: {
75 const TargetFrameLowering
*TFI
= MF
.getSubtarget().getFrameLowering();
76 return 28 - TFI
->hasFP(MF
);
78 case Mips::FGR32RegClassID
:
80 case Mips::AFGR64RegClassID
:
82 case Mips::FGR64RegClassID
:
87 //===----------------------------------------------------------------------===//
88 // Callee Saved Registers methods
89 //===----------------------------------------------------------------------===//
91 /// Mips Callee Saved Registers
93 MipsRegisterInfo::getCalleeSavedRegs(const MachineFunction
*MF
) const {
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
;
101 return Subtarget
.hasMips32r6() ? CSR_Interrupt_32R6_SaveList
102 : CSR_Interrupt_32_SaveList
;
105 if (Subtarget
.isSingleFloat())
106 return CSR_SingleFloatOnly_SaveList
;
108 if (Subtarget
.isABI_N64())
109 return CSR_N64_SaveList
;
111 if (Subtarget
.isABI_N32())
112 return CSR_N32_SaveList
;
114 if (Subtarget
.isFP64bit())
115 return CSR_O32_FP64_SaveList
;
117 if (Subtarget
.isFPXX())
118 return CSR_O32_FPXX_SaveList
;
120 return CSR_O32_SaveList
;
124 MipsRegisterInfo::getCallPreservedMask(const MachineFunction
&MF
,
125 CallingConv::ID
) const {
126 const MipsSubtarget
&Subtarget
= MF
.getSubtarget
<MipsSubtarget
>();
127 if (Subtarget
.isSingleFloat())
128 return CSR_SingleFloatOnly_RegMask
;
130 if (Subtarget
.isABI_N64())
131 return CSR_N64_RegMask
;
133 if (Subtarget
.isABI_N32())
134 return CSR_N32_RegMask
;
136 if (Subtarget
.isFP64bit())
137 return CSR_O32_FP64_RegMask
;
139 if (Subtarget
.isFPXX())
140 return CSR_O32_FPXX_RegMask
;
142 return CSR_O32_RegMask
;
145 const uint32_t *MipsRegisterInfo::getMips16RetHelperMask() {
146 return CSR_Mips16RetHelper_RegMask
;
149 BitVector
MipsRegisterInfo::
150 getReservedRegs(const MachineFunction
&MF
) const {
151 static const MCPhysReg ReservedGPR32
[] = {
152 Mips::ZERO
, Mips::K0
, Mips::K1
, Mips::SP
155 static const MCPhysReg ReservedGPR64
[] = {
156 Mips::ZERO_64
, Mips::K0_64
, Mips::K1_64
, Mips::SP_64
159 BitVector
Reserved(getNumRegs());
160 const MipsSubtarget
&Subtarget
= MF
.getSubtarget
<MipsSubtarget
>();
162 for (unsigned I
= 0; I
< array_lengthof(ReservedGPR32
); ++I
)
163 Reserved
.set(ReservedGPR32
[I
]);
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.
172 for (unsigned I
= 0; I
< array_lengthof(ReservedGPR64
); ++I
)
173 Reserved
.set(ReservedGPR64
[I
]);
175 // For mno-abicalls, GP is a program invariant!
176 if (!Subtarget
.isABICalls()) {
177 Reserved
.set(Mips::GP
);
178 Reserved
.set(Mips::GP_64
);
181 if (Subtarget
.isFP64bit()) {
182 // Reserve all registers in AFGR64.
183 for (MCPhysReg Reg
: Mips::AFGR64RegClass
)
186 // Reserve all registers in FGR64.
187 for (MCPhysReg Reg
: Mips::FGR64RegClass
)
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
);
195 Reserved
.set(Mips::FP
);
196 Reserved
.set(Mips::FP_64
);
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 (needsStackRealignment(MF
) &&
202 MF
.getFrameInfo().hasVarSizedObjects()) {
203 Reserved
.set(Mips::S7
);
204 Reserved
.set(Mips::S7_64
);
209 // Reserve hardware registers.
210 Reserved
.set(Mips::HWR29
);
212 // Reserve DSP control register.
213 Reserved
.set(Mips::DSPPos
);
214 Reserved
.set(Mips::DSPSCount
);
215 Reserved
.set(Mips::DSPCarry
);
216 Reserved
.set(Mips::DSPEFI
);
217 Reserved
.set(Mips::DSPOutFlag
);
219 // Reserve MSA control registers.
220 for (MCPhysReg Reg
: Mips::MSACtrlRegClass
)
223 // Reserve RA if in mips16 mode.
224 if (Subtarget
.inMips16Mode()) {
225 const MipsFunctionInfo
*MipsFI
= MF
.getInfo
<MipsFunctionInfo
>();
226 Reserved
.set(Mips::RA
);
227 Reserved
.set(Mips::RA_64
);
228 Reserved
.set(Mips::T0
);
229 Reserved
.set(Mips::T1
);
230 if (MF
.getFunction().hasFnAttribute("saveS2") || MipsFI
->hasSaveS2())
231 Reserved
.set(Mips::S2
);
234 // Reserve GP if small section is used.
235 if (Subtarget
.useSmallSection()) {
236 Reserved
.set(Mips::GP
);
237 Reserved
.set(Mips::GP_64
);
244 MipsRegisterInfo::requiresRegisterScavenging(const MachineFunction
&MF
) const {
249 MipsRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction
&MF
) const {
253 // FrameIndex represent objects inside a abstract stack.
254 // We must replace FrameIndex with an stack/frame pointer
256 void MipsRegisterInfo::
257 eliminateFrameIndex(MachineBasicBlock::iterator II
, int SPAdj
,
258 unsigned FIOperandNum
, RegScavenger
*RS
) const {
259 MachineInstr
&MI
= *II
;
260 MachineFunction
&MF
= *MI
.getParent()->getParent();
262 LLVM_DEBUG(errs() << "\nFunction : " << MF
.getName() << "\n";
263 errs() << "<--------->\n"
266 int FrameIndex
= MI
.getOperand(FIOperandNum
).getIndex();
267 uint64_t stackSize
= MF
.getFrameInfo().getStackSize();
268 int64_t spOffset
= MF
.getFrameInfo().getObjectOffset(FrameIndex
);
270 LLVM_DEBUG(errs() << "FrameIndex : " << FrameIndex
<< "\n"
271 << "spOffset : " << spOffset
<< "\n"
272 << "stackSize : " << stackSize
<< "\n"
274 << MF
.getFrameInfo().getObjectAlignment(FrameIndex
)
277 eliminateFI(MI
, FIOperandNum
, FrameIndex
, stackSize
, spOffset
);
280 Register
MipsRegisterInfo::
281 getFrameRegister(const MachineFunction
&MF
) const {
282 const MipsSubtarget
&Subtarget
= MF
.getSubtarget
<MipsSubtarget
>();
283 const TargetFrameLowering
*TFI
= Subtarget
.getFrameLowering();
285 static_cast<const MipsTargetMachine
&>(MF
.getTarget()).getABI().IsN64();
287 if (Subtarget
.inMips16Mode())
288 return TFI
->hasFP(MF
) ? Mips::S0
: Mips::SP
;
290 return TFI
->hasFP(MF
) ? (IsN64
? Mips::FP_64
: Mips::FP
) :
291 (IsN64
? Mips::SP_64
: Mips::SP
);
294 bool MipsRegisterInfo::canRealignStack(const MachineFunction
&MF
) const {
295 // Avoid realigning functions that explicitly do not want to be realigned.
296 // Normally, we should report an error when a function should be dynamically
297 // realigned but also has the attribute no-realign-stack. Unfortunately,
298 // with this attribute, MachineFrameInfo clamps each new object's alignment
299 // to that of the stack's alignment as specified by the ABI. As a result,
300 // the information of whether we have objects with larger alignment
301 // requirement than the stack's alignment is already lost at this point.
302 if (!TargetRegisterInfo::canRealignStack(MF
))
305 const MipsSubtarget
&Subtarget
= MF
.getSubtarget
<MipsSubtarget
>();
306 unsigned FP
= Subtarget
.isGP32bit() ? Mips::FP
: Mips::FP_64
;
307 unsigned BP
= Subtarget
.isGP32bit() ? Mips::S7
: Mips::S7_64
;
309 // Support dynamic stack realignment for all targets except Mips16.
310 if (Subtarget
.inMips16Mode())
313 // We can't perform dynamic stack realignment if we can't reserve the
314 // frame pointer register.
315 if (!MF
.getRegInfo().canReserveReg(FP
))
318 // We can realign the stack if we know the maximum call frame size and we
319 // don't have variable sized objects.
320 if (Subtarget
.getFrameLowering()->hasReservedCallFrame(MF
))
323 // We have to reserve the base pointer register in the presence of variable
325 return MF
.getRegInfo().canReserveReg(BP
);