1227825Stheraven//===-- MipsRegisterInfo.cpp - MIPS Register Information -== --------------===//
2227825Stheraven//
3227825Stheraven//                     The LLVM Compiler Infrastructure
4227825Stheraven//
5227825Stheraven// This file is distributed under the University of Illinois Open Source
6227825Stheraven// License. See LICENSE.TXT for details.
7227825Stheraven//
8227825Stheraven//===----------------------------------------------------------------------===//
9227825Stheraven//
10262801Sdim// This file contains the MIPS implementation of the TargetRegisterInfo class.
11227825Stheraven//
12227825Stheraven//===----------------------------------------------------------------------===//
13262801Sdim
14227825Stheraven#define DEBUG_TYPE "mips-reg-info"
15241903Sdim
16241903Sdim#include "MipsRegisterInfo.h"
17241903Sdim#include "Mips.h"
18241903Sdim#include "MipsAnalyzeImmediate.h"
19278724Sdim#include "MipsInstrInfo.h"
20227825Stheraven#include "MipsMachineFunction.h"
21232950Stheraven#include "MipsSubtarget.h"
22227825Stheraven#include "llvm/ADT/BitVector.h"
23227825Stheraven#include "llvm/ADT/STLExtras.h"
24232950Stheraven#include "llvm/CodeGen/MachineFrameInfo.h"
25232950Stheraven#include "llvm/CodeGen/MachineFunction.h"
26232950Stheraven#include "llvm/CodeGen/MachineInstrBuilder.h"
27262801Sdim#include "llvm/CodeGen/ValueTypes.h"
28232950Stheraven#include "llvm/DebugInfo.h"
29232950Stheraven#include "llvm/IR/Constants.h"
30232950Stheraven#include "llvm/IR/Type.h"
31232950Stheraven#include "llvm/Support/CommandLine.h"
32241903Sdim#include "llvm/Support/Debug.h"
33227825Stheraven#include "llvm/Support/ErrorHandling.h"
34227825Stheraven#include "llvm/Support/raw_ostream.h"
35241903Sdim#include "llvm/Target/TargetFrameLowering.h"
36241903Sdim#include "llvm/Target/TargetInstrInfo.h"
37241903Sdim#include "llvm/Target/TargetMachine.h"
38246487Stheraven#include "llvm/Target/TargetOptions.h"
39227825Stheraven
40227825Stheraven#define GET_REGINFO_TARGET_DESC
41241903Sdim#include "MipsGenRegisterInfo.inc"
42227825Stheraven
43232950Stheravenusing namespace llvm;
44232950Stheraven
45232950StheravenMipsRegisterInfo::MipsRegisterInfo(const MipsSubtarget &ST)
46246487Stheraven  : MipsGenRegisterInfo(Mips::RA), Subtarget(ST) {}
47232950Stheraven
48227825Stheravenunsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; }
49232950Stheraven
50232950Stheravenconst TargetRegisterClass *
51227825StheravenMipsRegisterInfo::getPointerRegClass(const MachineFunction &MF,
52227825Stheraven                                     unsigned Kind) const {
53227825Stheraven  return Subtarget.isABI_N64() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
54227825Stheraven}
55232950Stheraven
56232950Stheravenunsigned
57227825StheravenMipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
58232950Stheraven                                      MachineFunction &MF) const {
59227825Stheraven  switch (RC->getID()) {
60227825Stheraven  default:
61241903Sdim    return 0;
62227825Stheraven  case Mips::GPR32RegClassID:
63232950Stheraven  case Mips::GPR64RegClassID:
64227825Stheraven  case Mips::DSPRRegClassID: {
65232950Stheraven    const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
66227825Stheraven    return 28 - TFI->hasFP(MF);
67232950Stheraven  }
68227825Stheraven  case Mips::FGR32RegClassID:
69227825Stheraven    return 32;
70232950Stheraven  case Mips::AFGR64RegClassID:
71232950Stheraven    return 16;
72227825Stheraven  case Mips::FGR64RegClassID:
73227825Stheraven    return 32;
74227825Stheraven  }
75227825Stheraven}
76232950Stheraven
77232950Stheraven//===----------------------------------------------------------------------===//
78227825Stheraven// Callee Saved Registers methods
79232950Stheraven//===----------------------------------------------------------------------===//
80227825Stheraven
81227825Stheraven/// Mips Callee Saved Registers
82262801Sdimconst uint16_t* MipsRegisterInfo::
83241903SdimgetCalleeSavedRegs(const MachineFunction *MF) const {
84227825Stheraven  if (Subtarget.isSingleFloat())
85232950Stheraven    return CSR_SingleFloatOnly_SaveList;
86227825Stheraven
87227825Stheraven  if (Subtarget.isABI_N64())
88227825Stheraven    return CSR_N64_SaveList;
89227825Stheraven
90227825Stheraven  if (Subtarget.isABI_N32())
91232950Stheraven    return CSR_N32_SaveList;
92227825Stheraven
93262801Sdim  if (Subtarget.isFP64bit())
94262801Sdim    return CSR_O32_FP64_SaveList;
95227825Stheraven
96227825Stheraven  return CSR_O32_SaveList;
97227825Stheraven}
98227825Stheraven
99227825Stheravenconst uint32_t*
100262801SdimMipsRegisterInfo::getCallPreservedMask(CallingConv::ID) const {
101262801Sdim  if (Subtarget.isSingleFloat())
102227825Stheraven    return CSR_SingleFloatOnly_RegMask;
103227825Stheraven
104227825Stheraven  if (Subtarget.isABI_N64())
105262801Sdim    return CSR_N64_RegMask;
106232950Stheraven
107227825Stheraven  if (Subtarget.isABI_N32())
108262801Sdim    return CSR_N32_RegMask;
109232950Stheraven
110227825Stheraven  if (Subtarget.isFP64bit())
111249998Sdim    return CSR_O32_FP64_RegMask;
112227825Stheraven
113232950Stheraven  return CSR_O32_RegMask;
114227825Stheraven}
115262801Sdim
116262801Sdimconst uint32_t *MipsRegisterInfo::getMips16RetHelperMask() {
117262801Sdim  return CSR_Mips16RetHelper_RegMask;
118262801Sdim}
119262801Sdim
120262801SdimBitVector MipsRegisterInfo::
121227825StheravengetReservedRegs(const MachineFunction &MF) const {
122227825Stheraven  static const uint16_t ReservedGPR32[] = {
123227825Stheraven    Mips::ZERO, Mips::K0, Mips::K1, Mips::SP
124227825Stheraven  };
125262801Sdim
126232950Stheraven  static const uint16_t ReservedGPR64[] = {
127227825Stheraven    Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64
128227825Stheraven  };
129227825Stheraven
130227825Stheraven  BitVector Reserved(getNumRegs());
131227825Stheraven  typedef TargetRegisterClass::const_iterator RegIter;
132232972Stheraven
133227825Stheraven  for (unsigned I = 0; I < array_lengthof(ReservedGPR32); ++I)
134232972Stheraven    Reserved.set(ReservedGPR32[I]);
135227825Stheraven
136227825Stheraven  for (unsigned I = 0; I < array_lengthof(ReservedGPR64); ++I)
137232972Stheraven    Reserved.set(ReservedGPR64[I]);
138232972Stheraven
139246487Stheraven  if (Subtarget.isFP64bit()) {
140232972Stheraven    // Reserve all registers in AFGR64.
141232972Stheraven    for (RegIter Reg = Mips::AFGR64RegClass.begin(),
142227825Stheraven         EReg = Mips::AFGR64RegClass.end(); Reg != EReg; ++Reg)
143227825Stheraven      Reserved.set(*Reg);
144227825Stheraven  } else {
145227825Stheraven    // Reserve all registers in FGR64.
146227825Stheraven    for (RegIter Reg = Mips::FGR64RegClass.begin(),
147227825Stheraven         EReg = Mips::FGR64RegClass.end(); Reg != EReg; ++Reg)
148227825Stheraven      Reserved.set(*Reg);
149227825Stheraven  }
150232972Stheraven  // Reserve FP if this function should have a dedicated frame pointer register.
151232950Stheraven  if (MF.getTarget().getFrameLowering()->hasFP(MF)) {
152262801Sdim    if (Subtarget.inMips16Mode())
153232972Stheraven      Reserved.set(Mips::S0);
154262801Sdim    else {
155262801Sdim      Reserved.set(Mips::FP);
156262801Sdim      Reserved.set(Mips::FP_64);
157262801Sdim    }
158262801Sdim  }
159262801Sdim
160262801Sdim  // Reserve hardware registers.
161262801Sdim  Reserved.set(Mips::HWR29);
162262801Sdim
163262801Sdim  // Reserve DSP control register.
164262801Sdim  Reserved.set(Mips::DSPPos);
165262801Sdim  Reserved.set(Mips::DSPSCount);
166262801Sdim  Reserved.set(Mips::DSPCarry);
167262801Sdim  Reserved.set(Mips::DSPEFI);
168262801Sdim  Reserved.set(Mips::DSPOutFlag);
169262801Sdim
170262801Sdim  // Reserve MSA control registers.
171262801Sdim  Reserved.set(Mips::MSAIR);
172262801Sdim  Reserved.set(Mips::MSACSR);
173262801Sdim  Reserved.set(Mips::MSAAccess);
174262801Sdim  Reserved.set(Mips::MSASave);
175262801Sdim  Reserved.set(Mips::MSAModify);
176262801Sdim  Reserved.set(Mips::MSARequest);
177262801Sdim  Reserved.set(Mips::MSAMap);
178262801Sdim  Reserved.set(Mips::MSAUnmap);
179262801Sdim
180262801Sdim  // Reserve RA if in mips16 mode.
181227825Stheraven  if (Subtarget.inMips16Mode()) {
182227825Stheraven    Reserved.set(Mips::RA);
183227825Stheraven    Reserved.set(Mips::RA_64);
184227825Stheraven    Reserved.set(Mips::T0);
185262801Sdim    Reserved.set(Mips::T1);
186262801Sdim  }
187227825Stheraven
188262801Sdim  // Reserve GP if small section is used.
189262801Sdim  if (Subtarget.useSmallSection()) {
190262801Sdim    Reserved.set(Mips::GP);
191262801Sdim    Reserved.set(Mips::GP_64);
192262801Sdim  }
193262801Sdim
194227825Stheraven  return Reserved;
195262801Sdim}
196227825Stheraven
197227825Stheravenbool
198227825StheravenMipsRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
199227825Stheraven  return true;
200227825Stheraven}
201227825Stheraven
202227825Stheravenbool
203262801SdimMipsRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
204262801Sdim  return true;
205262801Sdim}
206227825Stheraven
207262801Sdim// FrameIndex represent objects inside a abstract stack.
208262801Sdim// We must replace FrameIndex with an stack/frame pointer
209262801Sdim// direct reference.
210262801Sdimvoid MipsRegisterInfo::
211262801SdimeliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
212262801Sdim                    unsigned FIOperandNum, RegScavenger *RS) const {
213227825Stheraven  MachineInstr &MI = *II;
214262801Sdim  MachineFunction &MF = *MI.getParent()->getParent();
215227825Stheraven
216227825Stheraven  DEBUG(errs() << "\nFunction : " << MF.getName() << "\n";
217227825Stheraven        errs() << "<--------->\n" << MI);
218227825Stheraven
219227825Stheraven  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
220227825Stheraven  uint64_t stackSize = MF.getFrameInfo()->getStackSize();
221227825Stheraven  int64_t spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
222227825Stheraven
223227825Stheraven  DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
224227825Stheraven               << "spOffset   : " << spOffset << "\n"
225227825Stheraven               << "stackSize  : " << stackSize << "\n");
226227825Stheraven
227262801Sdim  eliminateFI(MI, FIOperandNum, FrameIndex, stackSize, spOffset);
228262801Sdim}
229262801Sdim
230262801Sdimunsigned MipsRegisterInfo::
231262801SdimgetFrameRegister(const MachineFunction &MF) const {
232262801Sdim  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
233262801Sdim  bool IsN64 = Subtarget.isABI_N64();
234262801Sdim
235262801Sdim  if (Subtarget.inMips16Mode())
236262801Sdim    return TFI->hasFP(MF) ? Mips::S0 : Mips::SP;
237262801Sdim  else
238227825Stheraven    return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) :
239262801Sdim                            (IsN64 ? Mips::SP_64 : Mips::SP);
240227825Stheraven
241227825Stheraven}
242227825Stheraven
243227825Stheraven