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"
14#include "MCTargetDesc/MipsABIInfo.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"
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"
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
42MipsRegisterInfo::MipsRegisterInfo() : MipsGenRegisterInfo(Mips::RA) {}
43
44unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; }
45
46const TargetRegisterClass *
47MipsRegisterInfo::getPointerRegClass(const MachineFunction &MF,
48 unsigned Kind) const {
49 MipsABIInfo ABI = MF.getSubtarget<MipsSubtarget>().getABI();
50 MipsPtrClass PtrClassKind = static_cast<MipsPtrClass>(Kind);
51
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;
61 }
62
63 llvm_unreachable("Unknown pointer kind");
64}
65
66unsigned
67MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
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: {
75 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
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 *
93MipsRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
94 const MipsSubtarget &Subtarget = MF->getSubtarget<MipsSubtarget>();
95 const Function &F = MF->getFunction();
96 if (F.hasFnAttribute(Kind: "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 *
124MipsRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
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
145const uint32_t *MipsRegisterInfo::getMips16RetHelperMask() {
146 return CSR_Mips16RetHelper_RegMask;
147}
148
149BitVector MipsRegisterInfo::
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.
245bool MipsRegisterInfo::
246eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
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(i: FIOperandNum).getIndex();
256 uint64_t stackSize = MF.getFrameInfo().getStackSize();
257 int64_t spOffset = MF.getFrameInfo().getObjectOffset(ObjectIdx: 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(II: MI, OpNo: FIOperandNum, FrameIndex, StackSize: stackSize, SPOffset: spOffset);
267 return false;
268}
269
270Register MipsRegisterInfo::
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
284bool 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))
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(PhysReg: 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(PhysReg: BP);
316}
317

source code of llvm/lib/Target/Mips/MipsRegisterInfo.cpp