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 (MCPhysReg R
: ReservedGPR32
)
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 (MCPhysReg R
: ReservedGPR64
)
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 (hasStackRealignment(MF
) && MF
.getFrameInfo().hasVarSizedObjects()) {
202 Reserved
.set(Mips::S7
);
203 Reserved
.set(Mips::S7_64
);
208 // Reserve hardware registers.
209 Reserved
.set(Mips::HWR29
);
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
);
218 // Reserve MSA control registers.
219 for (MCPhysReg Reg
: Mips::MSACtrlRegClass
)
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
);
233 // Reserve GP if small section is used.
234 if (Subtarget
.useSmallSection()) {
235 Reserved
.set(Mips::GP
);
236 Reserved
.set(Mips::GP_64
);
242 // FrameIndex represent objects inside a abstract stack.
243 // We must replace FrameIndex with an stack/frame pointer
245 bool MipsRegisterInfo::
246 eliminateFrameIndex(MachineBasicBlock::iterator II
, int SPAdj
,
247 unsigned FIOperandNum
, RegScavenger
*RS
) const {
248 MachineInstr
&MI
= *II
;
249 MachineFunction
&MF
= *MI
.getParent()->getParent();
251 LLVM_DEBUG(errs() << "\nFunction : " << MF
.getName() << "\n";
252 errs() << "<--------->\n"
255 int FrameIndex
= MI
.getOperand(FIOperandNum
).getIndex();
256 uint64_t stackSize
= MF
.getFrameInfo().getStackSize();
257 int64_t spOffset
= MF
.getFrameInfo().getObjectOffset(FrameIndex
);
259 LLVM_DEBUG(errs() << "FrameIndex : " << FrameIndex
<< "\n"
260 << "spOffset : " << spOffset
<< "\n"
261 << "stackSize : " << stackSize
<< "\n"
263 << DebugStr(MF
.getFrameInfo().getObjectAlign(FrameIndex
))
266 eliminateFI(MI
, FIOperandNum
, FrameIndex
, stackSize
, spOffset
);
270 Register
MipsRegisterInfo::
271 getFrameRegister(const MachineFunction
&MF
) const {
272 const MipsSubtarget
&Subtarget
= MF
.getSubtarget
<MipsSubtarget
>();
273 const TargetFrameLowering
*TFI
= Subtarget
.getFrameLowering();
275 static_cast<const MipsTargetMachine
&>(MF
.getTarget()).getABI().IsN64();
277 if (Subtarget
.inMips16Mode())
278 return TFI
->hasFP(MF
) ? Mips::S0
: Mips::SP
;
280 return TFI
->hasFP(MF
) ? (IsN64
? Mips::FP_64
: Mips::FP
) :
281 (IsN64
? Mips::SP_64
: Mips::SP
);
284 bool MipsRegisterInfo::canRealignStack(const MachineFunction
&MF
) const {
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.
292 if (!TargetRegisterInfo::canRealignStack(MF
))
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
;
299 // Support dynamic stack realignment for all targets except Mips16.
300 if (Subtarget
.inMips16Mode())
303 // We can't perform dynamic stack realignment if we can't reserve the
304 // frame pointer register.
305 if (!MF
.getRegInfo().canReserveReg(FP
))
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
))
313 // We have to reserve the base pointer register in the presence of variable
315 return MF
.getRegInfo().canReserveReg(BP
);