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 "Mips.h"
16 #include "MipsAnalyzeImmediate.h"
17 #include "MipsInstrInfo.h"
18 #include "MipsMachineFunction.h"
19 #include "MipsSubtarget.h"
20 #include "MipsTargetMachine.h"
21 #include "llvm/ADT/BitVector.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/CodeGen/MachineFrameInfo.h"
24 #include "llvm/CodeGen/MachineRegisterInfo.h"
25 #include "llvm/CodeGen/MachineFunction.h"
26 #include "llvm/CodeGen/MachineInstrBuilder.h"
27 #include "llvm/IR/Constants.h"
28 #include "llvm/IR/DebugInfo.h"
29 #include "llvm/IR/Function.h"
30 #include "llvm/IR/Type.h"
31 #include "llvm/Support/CommandLine.h"
32 #include "llvm/Support/Debug.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/raw_ostream.h"
35 #include "llvm/Target/TargetFrameLowering.h"
36 #include "llvm/Target/TargetInstrInfo.h"
37 #include "llvm/Target/TargetMachine.h"
38 #include "llvm/Target/TargetOptions.h"
39 
40 using namespace llvm;
41 
42 #define DEBUG_TYPE "mips-reg-info"
43 
44 #define GET_REGINFO_TARGET_DESC
45 #include "MipsGenRegisterInfo.inc"
46 
MipsRegisterInfo()47 MipsRegisterInfo::MipsRegisterInfo() : MipsGenRegisterInfo(Mips::RA) {}
48 
getPICCallReg()49 unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; }
50 
51 const TargetRegisterClass *
getPointerRegClass(const MachineFunction & MF,unsigned Kind) const52 MipsRegisterInfo::getPointerRegClass(const MachineFunction &MF,
53                                      unsigned Kind) const {
54   MipsABIInfo ABI = MF.getSubtarget<MipsSubtarget>().getABI();
55   return ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
56 }
57 
58 unsigned
getRegPressureLimit(const TargetRegisterClass * RC,MachineFunction & MF) const59 MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
60                                       MachineFunction &MF) const {
61   switch (RC->getID()) {
62   default:
63     return 0;
64   case Mips::GPR32RegClassID:
65   case Mips::GPR64RegClassID:
66   case Mips::DSPRRegClassID: {
67     const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
68     return 28 - TFI->hasFP(MF);
69   }
70   case Mips::FGR32RegClassID:
71     return 32;
72   case Mips::AFGR64RegClassID:
73     return 16;
74   case Mips::FGR64RegClassID:
75     return 32;
76   }
77 }
78 
79 //===----------------------------------------------------------------------===//
80 // Callee Saved Registers methods
81 //===----------------------------------------------------------------------===//
82 
83 /// Mips Callee Saved Registers
84 const MCPhysReg *
getCalleeSavedRegs(const MachineFunction * MF) const85 MipsRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
86   const MipsSubtarget &Subtarget = MF->getSubtarget<MipsSubtarget>();
87   const Function *F = MF->getFunction();
88   if (F->hasFnAttribute("interrupt")) {
89     if (Subtarget.hasMips64())
90       return Subtarget.hasMips64r6() ? CSR_Interrupt_64R6_SaveList
91                                      : CSR_Interrupt_64_SaveList;
92     else
93       return Subtarget.hasMips32r6() ? CSR_Interrupt_32R6_SaveList
94                                      : CSR_Interrupt_32_SaveList;
95   }
96 
97   if (Subtarget.isSingleFloat())
98     return CSR_SingleFloatOnly_SaveList;
99 
100   if (Subtarget.isABI_N64())
101     return CSR_N64_SaveList;
102 
103   if (Subtarget.isABI_N32())
104     return CSR_N32_SaveList;
105 
106   if (Subtarget.isFP64bit())
107     return CSR_O32_FP64_SaveList;
108 
109   if (Subtarget.isFPXX())
110     return CSR_O32_FPXX_SaveList;
111 
112   return CSR_O32_SaveList;
113 }
114 
115 const uint32_t *
getCallPreservedMask(const MachineFunction & MF,CallingConv::ID) const116 MipsRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
117                                        CallingConv::ID) const {
118   const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
119   if (Subtarget.isSingleFloat())
120     return CSR_SingleFloatOnly_RegMask;
121 
122   if (Subtarget.isABI_N64())
123     return CSR_N64_RegMask;
124 
125   if (Subtarget.isABI_N32())
126     return CSR_N32_RegMask;
127 
128   if (Subtarget.isFP64bit())
129     return CSR_O32_FP64_RegMask;
130 
131   if (Subtarget.isFPXX())
132     return CSR_O32_FPXX_RegMask;
133 
134   return CSR_O32_RegMask;
135 }
136 
getMips16RetHelperMask()137 const uint32_t *MipsRegisterInfo::getMips16RetHelperMask() {
138   return CSR_Mips16RetHelper_RegMask;
139 }
140 
141 BitVector MipsRegisterInfo::
getReservedRegs(const MachineFunction & MF) const142 getReservedRegs(const MachineFunction &MF) const {
143   static const MCPhysReg ReservedGPR32[] = {
144     Mips::ZERO, Mips::K0, Mips::K1, Mips::SP
145   };
146 
147   static const MCPhysReg ReservedGPR64[] = {
148     Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64
149   };
150 
151   BitVector Reserved(getNumRegs());
152   const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
153   typedef TargetRegisterClass::const_iterator RegIter;
154 
155   for (unsigned I = 0; I < array_lengthof(ReservedGPR32); ++I)
156     Reserved.set(ReservedGPR32[I]);
157 
158   // Reserve registers for the NaCl sandbox.
159   if (Subtarget.isTargetNaCl()) {
160     Reserved.set(Mips::T6);   // Reserved for control flow mask.
161     Reserved.set(Mips::T7);   // Reserved for memory access mask.
162     Reserved.set(Mips::T8);   // Reserved for thread pointer.
163   }
164 
165   for (unsigned I = 0; I < array_lengthof(ReservedGPR64); ++I)
166     Reserved.set(ReservedGPR64[I]);
167 
168   // For mno-abicalls, GP is a program invariant!
169   if (!Subtarget.isABICalls()) {
170     Reserved.set(Mips::GP);
171     Reserved.set(Mips::GP_64);
172   }
173 
174   if (Subtarget.isFP64bit()) {
175     // Reserve all registers in AFGR64.
176     for (RegIter Reg = Mips::AFGR64RegClass.begin(),
177          EReg = Mips::AFGR64RegClass.end(); Reg != EReg; ++Reg)
178       Reserved.set(*Reg);
179   } else {
180     // Reserve all registers in FGR64.
181     for (RegIter Reg = Mips::FGR64RegClass.begin(),
182          EReg = Mips::FGR64RegClass.end(); Reg != EReg; ++Reg)
183       Reserved.set(*Reg);
184   }
185   // Reserve FP if this function should have a dedicated frame pointer register.
186   if (Subtarget.getFrameLowering()->hasFP(MF)) {
187     if (Subtarget.inMips16Mode())
188       Reserved.set(Mips::S0);
189     else {
190       Reserved.set(Mips::FP);
191       Reserved.set(Mips::FP_64);
192 
193       // Reserve the base register if we need to both realign the stack and
194       // allocate variable-sized objects at runtime. This should test the
195       // same conditions as MipsFrameLowering::hasBP().
196       if (needsStackRealignment(MF) &&
197           MF.getFrameInfo()->hasVarSizedObjects()) {
198         Reserved.set(Mips::S7);
199         Reserved.set(Mips::S7_64);
200       }
201     }
202   }
203 
204   // Reserve hardware registers.
205   Reserved.set(Mips::HWR29);
206 
207   // Reserve DSP control register.
208   Reserved.set(Mips::DSPPos);
209   Reserved.set(Mips::DSPSCount);
210   Reserved.set(Mips::DSPCarry);
211   Reserved.set(Mips::DSPEFI);
212   Reserved.set(Mips::DSPOutFlag);
213 
214   // Reserve MSA control registers.
215   Reserved.set(Mips::MSAIR);
216   Reserved.set(Mips::MSACSR);
217   Reserved.set(Mips::MSAAccess);
218   Reserved.set(Mips::MSASave);
219   Reserved.set(Mips::MSAModify);
220   Reserved.set(Mips::MSARequest);
221   Reserved.set(Mips::MSAMap);
222   Reserved.set(Mips::MSAUnmap);
223 
224   // Reserve RA if in mips16 mode.
225   if (Subtarget.inMips16Mode()) {
226     const MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
227     Reserved.set(Mips::RA);
228     Reserved.set(Mips::RA_64);
229     Reserved.set(Mips::T0);
230     Reserved.set(Mips::T1);
231     if (MF.getFunction()->hasFnAttribute("saveS2") || MipsFI->hasSaveS2())
232       Reserved.set(Mips::S2);
233   }
234 
235   // Reserve GP if small section is used.
236   if (Subtarget.useSmallSection()) {
237     Reserved.set(Mips::GP);
238     Reserved.set(Mips::GP_64);
239   }
240 
241   if (Subtarget.isABI_O32() && !Subtarget.useOddSPReg()) {
242     for (const auto &Reg : Mips::OddSPRegClass)
243       Reserved.set(Reg);
244   }
245 
246   return Reserved;
247 }
248 
249 bool
requiresRegisterScavenging(const MachineFunction & MF) const250 MipsRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
251   return true;
252 }
253 
254 bool
trackLivenessAfterRegAlloc(const MachineFunction & MF) const255 MipsRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
256   return true;
257 }
258 
259 // FrameIndex represent objects inside a abstract stack.
260 // We must replace FrameIndex with an stack/frame pointer
261 // direct reference.
262 void MipsRegisterInfo::
eliminateFrameIndex(MachineBasicBlock::iterator II,int SPAdj,unsigned FIOperandNum,RegScavenger * RS) const263 eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
264                     unsigned FIOperandNum, RegScavenger *RS) const {
265   MachineInstr &MI = *II;
266   MachineFunction &MF = *MI.getParent()->getParent();
267 
268   DEBUG(errs() << "\nFunction : " << MF.getName() << "\n";
269         errs() << "<--------->\n" << MI);
270 
271   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
272   uint64_t stackSize = MF.getFrameInfo()->getStackSize();
273   int64_t spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
274 
275   DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
276                << "spOffset   : " << spOffset << "\n"
277                << "stackSize  : " << stackSize << "\n");
278 
279   eliminateFI(MI, FIOperandNum, FrameIndex, stackSize, spOffset);
280 }
281 
282 unsigned MipsRegisterInfo::
getFrameRegister(const MachineFunction & MF) const283 getFrameRegister(const MachineFunction &MF) const {
284   const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
285   const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
286   bool IsN64 =
287       static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI().IsN64();
288 
289   if (Subtarget.inMips16Mode())
290     return TFI->hasFP(MF) ? Mips::S0 : Mips::SP;
291   else
292     return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) :
293                             (IsN64 ? Mips::SP_64 : Mips::SP);
294 }
295 
canRealignStack(const MachineFunction & MF) const296 bool MipsRegisterInfo::canRealignStack(const MachineFunction &MF) const {
297   // Avoid realigning functions that explicitly do not want to be realigned.
298   // Normally, we should report an error when a function should be dynamically
299   // realigned but also has the attribute no-realign-stack. Unfortunately,
300   // with this attribute, MachineFrameInfo clamps each new object's alignment
301   // to that of the stack's alignment as specified by the ABI. As a result,
302   // the information of whether we have objects with larger alignment
303   // requirement than the stack's alignment is already lost at this point.
304   if (!TargetRegisterInfo::canRealignStack(MF))
305     return false;
306 
307   const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
308   unsigned FP = Subtarget.isGP32bit() ? Mips::FP : Mips::FP_64;
309   unsigned BP = Subtarget.isGP32bit() ? Mips::S7 : Mips::S7_64;
310 
311   // Support dynamic stack realignment only for targets with standard encoding.
312   if (!Subtarget.hasStandardEncoding())
313     return false;
314 
315   // We can't perform dynamic stack realignment if we can't reserve the
316   // frame pointer register.
317   if (!MF.getRegInfo().canReserveReg(FP))
318     return false;
319 
320   // We can realign the stack if we know the maximum call frame size and we
321   // don't have variable sized objects.
322   if (Subtarget.getFrameLowering()->hasReservedCallFrame(MF))
323     return true;
324 
325   // We have to reserve the base pointer register in the presence of variable
326   // sized objects.
327   return MF.getRegInfo().canReserveReg(BP);
328 }
329