/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- MipsRegisterInfo.cpp - MIPS Register Information -------------------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file contains the MIPS implementation of the TargetRegisterInfo class. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "MipsRegisterInfo.h" |
15 | | #include "MCTargetDesc/MipsABIInfo.h" |
16 | | #include "Mips.h" |
17 | | #include "MipsMachineFunction.h" |
18 | | #include "MipsSubtarget.h" |
19 | | #include "MipsTargetMachine.h" |
20 | | #include "llvm/ADT/BitVector.h" |
21 | | #include "llvm/ADT/STLExtras.h" |
22 | | #include "llvm/CodeGen/MachineFrameInfo.h" |
23 | | #include "llvm/CodeGen/MachineFunction.h" |
24 | | #include "llvm/CodeGen/MachineInstr.h" |
25 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
26 | | #include "llvm/IR/Function.h" |
27 | | #include "llvm/MC/MCRegisterInfo.h" |
28 | | #include "llvm/Support/Debug.h" |
29 | | #include "llvm/Support/ErrorHandling.h" |
30 | | #include "llvm/Support/raw_ostream.h" |
31 | | #include "llvm/Target/TargetFrameLowering.h" |
32 | | #include "llvm/Target/TargetRegisterInfo.h" |
33 | | #include "llvm/Target/TargetSubtargetInfo.h" |
34 | | #include <cstdint> |
35 | | |
36 | | using namespace llvm; |
37 | | |
38 | | #define DEBUG_TYPE "mips-reg-info" |
39 | | |
40 | | #define GET_REGINFO_TARGET_DESC |
41 | | #include "MipsGenRegisterInfo.inc" |
42 | | |
43 | 8.96k | MipsRegisterInfo::MipsRegisterInfo() : MipsGenRegisterInfo(Mips::RA) {} |
44 | | |
45 | 0 | unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; } |
46 | | |
47 | | const TargetRegisterClass * |
48 | | MipsRegisterInfo::getPointerRegClass(const MachineFunction &MF, |
49 | 90.2k | unsigned Kind) const { |
50 | 90.2k | MipsABIInfo ABI = MF.getSubtarget<MipsSubtarget>().getABI(); |
51 | 90.2k | MipsPtrClass PtrClassKind = static_cast<MipsPtrClass>(Kind); |
52 | 90.2k | |
53 | 90.2k | switch (PtrClassKind) { |
54 | 89.6k | case MipsPtrClass::Default: |
55 | 89.6k | return ABI.ArePtrs64bit() ? &Mips::GPR64RegClass27.7k : &Mips::GPR32RegClass61.8k ; |
56 | 489 | case MipsPtrClass::GPR16MM: |
57 | 14 | return ABI.ArePtrs64bit() ? &Mips::GPRMM16_64RegClass |
58 | 475 | : &Mips::GPRMM16RegClass; |
59 | 190 | case MipsPtrClass::StackPointer: |
60 | 190 | return ABI.ArePtrs64bit() ? &Mips::SP64RegClass0 : &Mips::SP32RegClass190 ; |
61 | 0 | case MipsPtrClass::GlobalPointer: |
62 | 0 | return ABI.ArePtrs64bit() ? &Mips::GP64RegClass0 : &Mips::GP32RegClass0 ; |
63 | 0 | } |
64 | 0 |
|
65 | 0 | llvm_unreachable0 ("Unknown pointer kind"); |
66 | 0 | } |
67 | | |
68 | | unsigned |
69 | | MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, |
70 | 971k | MachineFunction &MF) const { |
71 | 971k | switch (RC->getID()) { |
72 | 891k | default: |
73 | 891k | return 0; |
74 | 39.9k | case Mips::GPR32RegClassID: |
75 | 39.9k | case Mips::GPR64RegClassID: |
76 | 39.9k | case Mips::DSPRRegClassID: { |
77 | 39.9k | const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); |
78 | 39.9k | return 28 - TFI->hasFP(MF); |
79 | 39.9k | } |
80 | 13.3k | case Mips::FGR32RegClassID: |
81 | 13.3k | return 32; |
82 | 13.3k | case Mips::AFGR64RegClassID: |
83 | 13.3k | return 16; |
84 | 13.3k | case Mips::FGR64RegClassID: |
85 | 13.3k | return 32; |
86 | 0 | } |
87 | 0 | } |
88 | | |
89 | | //===----------------------------------------------------------------------===// |
90 | | // Callee Saved Registers methods |
91 | | //===----------------------------------------------------------------------===// |
92 | | |
93 | | /// Mips Callee Saved Registers |
94 | | const MCPhysReg * |
95 | 103k | MipsRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { |
96 | 103k | const MipsSubtarget &Subtarget = MF->getSubtarget<MipsSubtarget>(); |
97 | 103k | const Function *F = MF->getFunction(); |
98 | 103k | if (F->hasFnAttribute("interrupt")103k ) { |
99 | 75 | if (Subtarget.hasMips64()) |
100 | 6 | return Subtarget.hasMips64r6() ? 6 CSR_Interrupt_64R6_SaveList6 |
101 | 0 | : CSR_Interrupt_64_SaveList; |
102 | 75 | else |
103 | 69 | return Subtarget.hasMips32r6() ? 69 CSR_Interrupt_32R6_SaveList0 |
104 | 69 | : CSR_Interrupt_32_SaveList; |
105 | 103k | } |
106 | 103k | |
107 | 103k | if (103k Subtarget.isSingleFloat()103k ) |
108 | 56 | return CSR_SingleFloatOnly_SaveList; |
109 | 103k | |
110 | 103k | if (103k Subtarget.isABI_N64()103k ) |
111 | 35.6k | return CSR_N64_SaveList; |
112 | 67.9k | |
113 | 67.9k | if (67.9k Subtarget.isABI_N32()67.9k ) |
114 | 4.86k | return CSR_N32_SaveList; |
115 | 63.0k | |
116 | 63.0k | if (63.0k Subtarget.isFP64bit()63.0k ) |
117 | 29.6k | return CSR_O32_FP64_SaveList; |
118 | 33.4k | |
119 | 33.4k | if (33.4k Subtarget.isFPXX()33.4k ) |
120 | 162 | return CSR_O32_FPXX_SaveList; |
121 | 33.2k | |
122 | 33.2k | return CSR_O32_SaveList; |
123 | 33.2k | } |
124 | | |
125 | | const uint32_t * |
126 | | MipsRegisterInfo::getCallPreservedMask(const MachineFunction &MF, |
127 | 2.97k | CallingConv::ID) const { |
128 | 2.97k | const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>(); |
129 | 2.97k | if (Subtarget.isSingleFloat()) |
130 | 7 | return CSR_SingleFloatOnly_RegMask; |
131 | 2.96k | |
132 | 2.96k | if (2.96k Subtarget.isABI_N64()2.96k ) |
133 | 793 | return CSR_N64_RegMask; |
134 | 2.17k | |
135 | 2.17k | if (2.17k Subtarget.isABI_N32()2.17k ) |
136 | 83 | return CSR_N32_RegMask; |
137 | 2.08k | |
138 | 2.08k | if (2.08k Subtarget.isFP64bit()2.08k ) |
139 | 291 | return CSR_O32_FP64_RegMask; |
140 | 1.79k | |
141 | 1.79k | if (1.79k Subtarget.isFPXX()1.79k ) |
142 | 8 | return CSR_O32_FPXX_RegMask; |
143 | 1.78k | |
144 | 1.78k | return CSR_O32_RegMask; |
145 | 1.78k | } |
146 | | |
147 | 30 | const uint32_t *MipsRegisterInfo::getMips16RetHelperMask() { |
148 | 30 | return CSR_Mips16RetHelper_RegMask; |
149 | 30 | } |
150 | | |
151 | | BitVector MipsRegisterInfo:: |
152 | 25.5k | getReservedRegs(const MachineFunction &MF) const { |
153 | 25.5k | static const MCPhysReg ReservedGPR32[] = { |
154 | 25.5k | Mips::ZERO, Mips::K0, Mips::K1, Mips::SP |
155 | 25.5k | }; |
156 | 25.5k | |
157 | 25.5k | static const MCPhysReg ReservedGPR64[] = { |
158 | 25.5k | Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64 |
159 | 25.5k | }; |
160 | 25.5k | |
161 | 25.5k | BitVector Reserved(getNumRegs()); |
162 | 25.5k | const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>(); |
163 | 25.5k | |
164 | 25.5k | using RegIter = TargetRegisterClass::const_iterator; |
165 | 25.5k | |
166 | 127k | for (unsigned I = 0; I < array_lengthof(ReservedGPR32)127k ; ++I102k ) |
167 | 102k | Reserved.set(ReservedGPR32[I]); |
168 | 25.5k | |
169 | 25.5k | // Reserve registers for the NaCl sandbox. |
170 | 25.5k | if (Subtarget.isTargetNaCl()25.5k ) { |
171 | 50 | Reserved.set(Mips::T6); // Reserved for control flow mask. |
172 | 50 | Reserved.set(Mips::T7); // Reserved for memory access mask. |
173 | 50 | Reserved.set(Mips::T8); // Reserved for thread pointer. |
174 | 50 | } |
175 | 25.5k | |
176 | 127k | for (unsigned I = 0; I < array_lengthof(ReservedGPR64)127k ; ++I102k ) |
177 | 102k | Reserved.set(ReservedGPR64[I]); |
178 | 25.5k | |
179 | 25.5k | // For mno-abicalls, GP is a program invariant! |
180 | 25.5k | if (!Subtarget.isABICalls()25.5k ) { |
181 | 4.57k | Reserved.set(Mips::GP); |
182 | 4.57k | Reserved.set(Mips::GP_64); |
183 | 4.57k | } |
184 | 25.5k | |
185 | 25.5k | if (Subtarget.isFP64bit()25.5k ) { |
186 | 16.6k | // Reserve all registers in AFGR64. |
187 | 16.6k | for (RegIter Reg = Mips::AFGR64RegClass.begin(), |
188 | 283k | EReg = Mips::AFGR64RegClass.end(); Reg != EReg283k ; ++Reg266k ) |
189 | 266k | Reserved.set(*Reg); |
190 | 25.5k | } else { |
191 | 8.85k | // Reserve all registers in FGR64. |
192 | 8.85k | for (RegIter Reg = Mips::FGR64RegClass.begin(), |
193 | 292k | EReg = Mips::FGR64RegClass.end(); Reg != EReg292k ; ++Reg283k ) |
194 | 283k | Reserved.set(*Reg); |
195 | 8.85k | } |
196 | 25.5k | // Reserve FP if this function should have a dedicated frame pointer register. |
197 | 25.5k | if (Subtarget.getFrameLowering()->hasFP(MF)25.5k ) { |
198 | 1.22k | if (Subtarget.inMips16Mode()) |
199 | 599 | Reserved.set(Mips::S0); |
200 | 622 | else { |
201 | 622 | Reserved.set(Mips::FP); |
202 | 622 | Reserved.set(Mips::FP_64); |
203 | 622 | |
204 | 622 | // Reserve the base register if we need to both realign the stack and |
205 | 622 | // allocate variable-sized objects at runtime. This should test the |
206 | 622 | // same conditions as MipsFrameLowering::hasBP(). |
207 | 622 | if (needsStackRealignment(MF) && |
208 | 622 | MF.getFrameInfo().hasVarSizedObjects()366 ) { |
209 | 74 | Reserved.set(Mips::S7); |
210 | 74 | Reserved.set(Mips::S7_64); |
211 | 74 | } |
212 | 622 | } |
213 | 1.22k | } |
214 | 25.5k | |
215 | 25.5k | // Reserve hardware registers. |
216 | 25.5k | Reserved.set(Mips::HWR29); |
217 | 25.5k | |
218 | 25.5k | // Reserve DSP control register. |
219 | 25.5k | Reserved.set(Mips::DSPPos); |
220 | 25.5k | Reserved.set(Mips::DSPSCount); |
221 | 25.5k | Reserved.set(Mips::DSPCarry); |
222 | 25.5k | Reserved.set(Mips::DSPEFI); |
223 | 25.5k | Reserved.set(Mips::DSPOutFlag); |
224 | 25.5k | |
225 | 25.5k | // Reserve MSA control registers. |
226 | 25.5k | Reserved.set(Mips::MSAIR); |
227 | 25.5k | Reserved.set(Mips::MSACSR); |
228 | 25.5k | Reserved.set(Mips::MSAAccess); |
229 | 25.5k | Reserved.set(Mips::MSASave); |
230 | 25.5k | Reserved.set(Mips::MSAModify); |
231 | 25.5k | Reserved.set(Mips::MSARequest); |
232 | 25.5k | Reserved.set(Mips::MSAMap); |
233 | 25.5k | Reserved.set(Mips::MSAUnmap); |
234 | 25.5k | |
235 | 25.5k | // Reserve RA if in mips16 mode. |
236 | 25.5k | if (Subtarget.inMips16Mode()25.5k ) { |
237 | 1.62k | const MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); |
238 | 1.62k | Reserved.set(Mips::RA); |
239 | 1.62k | Reserved.set(Mips::RA_64); |
240 | 1.62k | Reserved.set(Mips::T0); |
241 | 1.62k | Reserved.set(Mips::T1); |
242 | 1.62k | if (MF.getFunction()->hasFnAttribute("saveS2") || 1.62k MipsFI->hasSaveS2()1.37k ) |
243 | 346 | Reserved.set(Mips::S2); |
244 | 1.62k | } |
245 | 25.5k | |
246 | 25.5k | // Reserve GP if small section is used. |
247 | 25.5k | if (Subtarget.useSmallSection()25.5k ) { |
248 | 28 | Reserved.set(Mips::GP); |
249 | 28 | Reserved.set(Mips::GP_64); |
250 | 28 | } |
251 | 25.5k | |
252 | 25.5k | if (Subtarget.isABI_O32() && 25.5k !Subtarget.useOddSPReg()16.2k ) { |
253 | 130 | for (const auto &Reg : Mips::OddSPRegClass) |
254 | 7.28k | Reserved.set(Reg); |
255 | 130 | } |
256 | 25.5k | |
257 | 25.5k | return Reserved; |
258 | 25.5k | } |
259 | | |
260 | | bool |
261 | 0 | MipsRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { |
262 | 0 | return true; |
263 | 0 | } |
264 | | |
265 | | bool |
266 | 11.9k | MipsRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const { |
267 | 11.9k | return true; |
268 | 11.9k | } |
269 | | |
270 | | // FrameIndex represent objects inside a abstract stack. |
271 | | // We must replace FrameIndex with an stack/frame pointer |
272 | | // direct reference. |
273 | | void MipsRegisterInfo:: |
274 | | eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, |
275 | 13.9k | unsigned FIOperandNum, RegScavenger *RS) const { |
276 | 13.9k | MachineInstr &MI = *II; |
277 | 13.9k | MachineFunction &MF = *MI.getParent()->getParent(); |
278 | 13.9k | |
279 | 13.9k | DEBUG(errs() << "\nFunction : " << MF.getName() << "\n"; |
280 | 13.9k | errs() << "<--------->\n" << MI); |
281 | 13.9k | |
282 | 13.9k | int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); |
283 | 13.9k | uint64_t stackSize = MF.getFrameInfo().getStackSize(); |
284 | 13.9k | int64_t spOffset = MF.getFrameInfo().getObjectOffset(FrameIndex); |
285 | 13.9k | |
286 | 13.9k | DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n" |
287 | 13.9k | << "spOffset : " << spOffset << "\n" |
288 | 13.9k | << "stackSize : " << stackSize << "\n" |
289 | 13.9k | << "alignment : " |
290 | 13.9k | << MF.getFrameInfo().getObjectAlignment(FrameIndex) << "\n"); |
291 | 13.9k | |
292 | 13.9k | eliminateFI(MI, FIOperandNum, FrameIndex, stackSize, spOffset); |
293 | 13.9k | } |
294 | | |
295 | | unsigned MipsRegisterInfo:: |
296 | 17.5k | getFrameRegister(const MachineFunction &MF) const { |
297 | 17.5k | const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>(); |
298 | 17.5k | const TargetFrameLowering *TFI = Subtarget.getFrameLowering(); |
299 | 17.5k | bool IsN64 = |
300 | 17.5k | static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI().IsN64(); |
301 | 17.5k | |
302 | 17.5k | if (Subtarget.inMips16Mode()) |
303 | 416 | return TFI->hasFP(MF) ? 416 Mips::S0126 : Mips::SP290 ; |
304 | 17.5k | else |
305 | 17.0k | return TFI->hasFP(MF) ? 17.0k (IsN64 ? 693 Mips::FP_64367 : Mips::FP326 ) : |
306 | 17.0k | (IsN64 ? 16.3k Mips::SP_645.47k : Mips::SP10.9k ); |
307 | 0 | } |
308 | | |
309 | 3.77k | bool MipsRegisterInfo::canRealignStack(const MachineFunction &MF) const { |
310 | 3.77k | // Avoid realigning functions that explicitly do not want to be realigned. |
311 | 3.77k | // Normally, we should report an error when a function should be dynamically |
312 | 3.77k | // realigned but also has the attribute no-realign-stack. Unfortunately, |
313 | 3.77k | // with this attribute, MachineFrameInfo clamps each new object's alignment |
314 | 3.77k | // to that of the stack's alignment as specified by the ABI. As a result, |
315 | 3.77k | // the information of whether we have objects with larger alignment |
316 | 3.77k | // requirement than the stack's alignment is already lost at this point. |
317 | 3.77k | if (!TargetRegisterInfo::canRealignStack(MF)) |
318 | 0 | return false; |
319 | 3.77k | |
320 | 3.77k | const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>(); |
321 | 3.77k | unsigned FP = Subtarget.isGP32bit() ? Mips::FP3.26k : Mips::FP_64510 ; |
322 | 3.77k | unsigned BP = Subtarget.isGP32bit() ? Mips::S73.26k : Mips::S7_64510 ; |
323 | 3.77k | |
324 | 3.77k | // Support dynamic stack realignment only for targets with standard encoding. |
325 | 3.77k | if (!Subtarget.hasStandardEncoding()) |
326 | 0 | return false; |
327 | 3.77k | |
328 | 3.77k | // We can't perform dynamic stack realignment if we can't reserve the |
329 | 3.77k | // frame pointer register. |
330 | 3.77k | if (3.77k !MF.getRegInfo().canReserveReg(FP)3.77k ) |
331 | 154 | return false; |
332 | 3.62k | |
333 | 3.62k | // We can realign the stack if we know the maximum call frame size and we |
334 | 3.62k | // don't have variable sized objects. |
335 | 3.62k | if (3.62k Subtarget.getFrameLowering()->hasReservedCallFrame(MF)3.62k ) |
336 | 3.35k | return true; |
337 | 264 | |
338 | 264 | // We have to reserve the base pointer register in the presence of variable |
339 | 264 | // sized objects. |
340 | 264 | return MF.getRegInfo().canReserveReg(BP); |
341 | 264 | } |