MipsRegisterInfo.cpp revision 36e91e9599c014fc0044c02030973bcfc78fbc68
1//===- MipsRegisterInfo.cpp - MIPS Register Information -== -----*- C++ -*-===//
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#define DEBUG_TYPE "mips-reg-info"
15
16#include "Mips.h"
17#include "MipsAnalyzeImmediate.h"
18#include "MipsSubtarget.h"
19#include "MipsRegisterInfo.h"
20#include "MipsMachineFunction.h"
21#include "llvm/Constants.h"
22#include "llvm/Type.h"
23#include "llvm/Function.h"
24#include "llvm/CodeGen/ValueTypes.h"
25#include "llvm/CodeGen/MachineInstrBuilder.h"
26#include "llvm/CodeGen/MachineFunction.h"
27#include "llvm/CodeGen/MachineFrameInfo.h"
28#include "llvm/Target/TargetFrameLowering.h"
29#include "llvm/Target/TargetMachine.h"
30#include "llvm/Target/TargetOptions.h"
31#include "llvm/Target/TargetInstrInfo.h"
32#include "llvm/Support/CommandLine.h"
33#include "llvm/Support/Debug.h"
34#include "llvm/Support/ErrorHandling.h"
35#include "llvm/Support/raw_ostream.h"
36#include "llvm/ADT/BitVector.h"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/Analysis/DebugInfo.h"
39
40#define GET_REGINFO_TARGET_DESC
41#include "MipsGenRegisterInfo.inc"
42
43using namespace llvm;
44
45MipsRegisterInfo::MipsRegisterInfo(const MipsSubtarget &ST,
46                                   const TargetInstrInfo &tii)
47  : MipsGenRegisterInfo(Mips::RA), Subtarget(ST), TII(tii) {}
48
49unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; }
50
51//===----------------------------------------------------------------------===//
52// Callee Saved Registers methods
53//===----------------------------------------------------------------------===//
54
55/// Mips Callee Saved Registers
56const unsigned* MipsRegisterInfo::
57getCalleeSavedRegs(const MachineFunction *MF) const
58{
59  // Mips callee-save register range is $16-$23, $f20-$f30
60  static const unsigned SingleFloatOnlyCalleeSavedRegs[] = {
61    Mips::F31, Mips::F30, Mips::F29, Mips::F28, Mips::F27, Mips::F26,
62    Mips::F25, Mips::F24, Mips::F23, Mips::F22, Mips::F21, Mips::F20,
63    Mips::RA, Mips::FP, Mips::S7, Mips::S6, Mips::S5, Mips::S4,
64    Mips::S3, Mips::S2, Mips::S1, Mips::S0, 0
65  };
66
67  static const unsigned Mips32CalleeSavedRegs[] = {
68    Mips::D15, Mips::D14, Mips::D13, Mips::D12, Mips::D11, Mips::D10,
69    Mips::RA, Mips::FP, Mips::S7, Mips::S6, Mips::S5, Mips::S4,
70    Mips::S3, Mips::S2, Mips::S1, Mips::S0, 0
71  };
72
73  static const unsigned N32CalleeSavedRegs[] = {
74    Mips::D31_64, Mips::D29_64, Mips::D27_64, Mips::D25_64, Mips::D23_64,
75    Mips::D21_64,
76    Mips::RA_64, Mips::FP_64, Mips::GP_64, Mips::S7_64, Mips::S6_64,
77    Mips::S5_64, Mips::S4_64, Mips::S3_64, Mips::S2_64, Mips::S1_64,
78    Mips::S0_64, 0
79  };
80
81  static const unsigned N64CalleeSavedRegs[] = {
82    Mips::D31_64, Mips::D30_64, Mips::D29_64, Mips::D28_64, Mips::D27_64,
83    Mips::D26_64, Mips::D25_64, Mips::D24_64,
84    Mips::RA_64, Mips::FP_64, Mips::GP_64, Mips::S7_64, Mips::S6_64,
85    Mips::S5_64, Mips::S4_64, Mips::S3_64, Mips::S2_64, Mips::S1_64,
86    Mips::S0_64, 0
87  };
88
89  if (Subtarget.isSingleFloat())
90    return SingleFloatOnlyCalleeSavedRegs;
91  else if (!Subtarget.hasMips64())
92    return Mips32CalleeSavedRegs;
93  else if (Subtarget.isABI_N32())
94    return N32CalleeSavedRegs;
95
96  assert(Subtarget.isABI_N64());
97  return N64CalleeSavedRegs;
98}
99
100BitVector MipsRegisterInfo::
101getReservedRegs(const MachineFunction &MF) const {
102  static const unsigned ReservedCPURegs[] = {
103    Mips::ZERO, Mips::AT, Mips::K0, Mips::K1,
104    Mips::GP, Mips::SP, Mips::FP, Mips::RA
105  };
106
107  static const unsigned ReservedCPU64Regs[] = {
108    Mips::ZERO_64, Mips::AT_64, Mips::K0_64, Mips::K1_64,
109    Mips::GP_64, Mips::SP_64, Mips::FP_64, Mips::RA_64
110  };
111
112  BitVector Reserved(getNumRegs());
113  typedef TargetRegisterClass::iterator RegIter;
114
115  for (unsigned I = 0; I < array_lengthof(ReservedCPURegs); ++I)
116    Reserved.set(ReservedCPURegs[I]);
117
118  if (Subtarget.hasMips64()) {
119    for (unsigned I = 0; I < array_lengthof(ReservedCPU64Regs); ++I)
120      Reserved.set(ReservedCPU64Regs[I]);
121
122    // Reserve all registers in AFGR64.
123    for (RegIter Reg = Mips::AFGR64RegisterClass->begin();
124         Reg != Mips::AFGR64RegisterClass->end(); ++Reg)
125      Reserved.set(*Reg);
126  }
127  else {
128    // Reserve all registers in CPU64Regs & FGR64.
129    for (RegIter Reg = Mips::CPU64RegsRegisterClass->begin();
130         Reg != Mips::CPU64RegsRegisterClass->end(); ++Reg)
131      Reserved.set(*Reg);
132
133    for (RegIter Reg = Mips::FGR64RegisterClass->begin();
134         Reg != Mips::FGR64RegisterClass->end(); ++Reg)
135      Reserved.set(*Reg);
136  }
137
138  return Reserved;
139}
140
141// This function eliminate ADJCALLSTACKDOWN,
142// ADJCALLSTACKUP pseudo instructions
143void MipsRegisterInfo::
144eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
145                              MachineBasicBlock::iterator I) const {
146  // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
147  MBB.erase(I);
148}
149
150// FrameIndex represent objects inside a abstract stack.
151// We must replace FrameIndex with an stack/frame pointer
152// direct reference.
153void MipsRegisterInfo::
154eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
155                    RegScavenger *RS) const {
156  MachineInstr &MI = *II;
157  MachineFunction &MF = *MI.getParent()->getParent();
158  MachineFrameInfo *MFI = MF.getFrameInfo();
159  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
160
161  unsigned i = 0;
162  while (!MI.getOperand(i).isFI()) {
163    ++i;
164    assert(i < MI.getNumOperands() &&
165           "Instr doesn't have FrameIndex operand!");
166  }
167
168  DEBUG(errs() << "\nFunction : " << MF.getFunction()->getName() << "\n";
169        errs() << "<--------->\n" << MI);
170
171  int FrameIndex = MI.getOperand(i).getIndex();
172  uint64_t stackSize = MF.getFrameInfo()->getStackSize();
173  int64_t spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
174
175  DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
176               << "spOffset   : " << spOffset << "\n"
177               << "stackSize  : " << stackSize << "\n");
178
179  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
180  int MinCSFI = 0;
181  int MaxCSFI = -1;
182
183  if (CSI.size()) {
184    MinCSFI = CSI[0].getFrameIdx();
185    MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
186  }
187
188  // The following stack frame objects are always referenced relative to $sp:
189  //  1. Outgoing arguments.
190  //  2. Pointer to dynamically allocated stack space.
191  //  3. Locations for callee-saved registers.
192  // Everything else is referenced relative to whatever register
193  // getFrameRegister() returns.
194  unsigned FrameReg;
195
196  if (MipsFI->isOutArgFI(FrameIndex) || MipsFI->isDynAllocFI(FrameIndex) ||
197      (FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI))
198    FrameReg = Subtarget.isABI_N64() ? Mips::SP_64 : Mips::SP;
199  else
200    FrameReg = getFrameRegister(MF);
201
202  // Calculate final offset.
203  // - There is no need to change the offset if the frame object is one of the
204  //   following: an outgoing argument, pointer to a dynamically allocated
205  //   stack space or a $gp restore location,
206  // - If the frame object is any of the following, its offset must be adjusted
207  //   by adding the size of the stack:
208  //   incoming argument, callee-saved register location or local variable.
209  int64_t Offset;
210
211  if (MipsFI->isOutArgFI(FrameIndex) || MipsFI->isGPFI(FrameIndex) ||
212      MipsFI->isDynAllocFI(FrameIndex))
213    Offset = spOffset;
214  else
215    Offset = spOffset + (int64_t)stackSize;
216
217  Offset    += MI.getOperand(i+1).getImm();
218
219  DEBUG(errs() << "Offset     : " << Offset << "\n" << "<--------->\n");
220
221  // If MI is not a debug value, make sure Offset fits in the 16-bit immediate
222  // field.
223  if (!MI.isDebugValue() && !isInt<16>(Offset)) {
224    MachineBasicBlock &MBB = *MI.getParent();
225    DebugLoc DL = II->getDebugLoc();
226    MipsAnalyzeImmediate AnalyzeImm;
227    unsigned Size = Subtarget.isABI_N64() ? 64 : 32;
228    unsigned LUi = Subtarget.isABI_N64() ? Mips::LUi64 : Mips::LUi;
229    unsigned ADDu = Subtarget.isABI_N64() ? Mips::DADDu : Mips::ADDu;
230    unsigned ZEROReg = Subtarget.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
231    unsigned ATReg = Subtarget.isABI_N64() ? Mips::AT_64 : Mips::AT;
232    const MipsAnalyzeImmediate::InstSeq &Seq =
233      AnalyzeImm.Analyze(Offset, Size, true /* LastInstrIsADDiu */);
234    MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
235
236    // FIXME: change this when mips goes MC".
237    BuildMI(MBB, II, DL, TII.get(Mips::NOAT));
238
239    // The first instruction can be a LUi, which is different from other
240    // instructions (ADDiu, ORI and SLL) in that it does not have a register
241    // operand.
242    if (Inst->Opc == LUi)
243      BuildMI(MBB, II, DL, TII.get(LUi), ATReg)
244        .addImm(SignExtend64<16>(Inst->ImmOpnd));
245    else
246      BuildMI(MBB, II, DL, TII.get(Inst->Opc), ATReg).addReg(ZEROReg)
247        .addImm(SignExtend64<16>(Inst->ImmOpnd));
248
249    // Build the remaining instructions in Seq except for the last one.
250    for (++Inst; Inst != Seq.end() - 1; ++Inst)
251      BuildMI(MBB, II, DL, TII.get(Inst->Opc), ATReg).addReg(ATReg)
252        .addImm(SignExtend64<16>(Inst->ImmOpnd));
253
254    BuildMI(MBB, II, DL, TII.get(ADDu), ATReg).addReg(FrameReg).addReg(ATReg);
255
256    FrameReg = ATReg;
257    Offset = SignExtend64<16>(Inst->ImmOpnd);
258    BuildMI(MBB, ++II, MI.getDebugLoc(), TII.get(Mips::ATMACRO));
259  }
260
261  MI.getOperand(i).ChangeToRegister(FrameReg, false);
262  MI.getOperand(i+1).ChangeToImmediate(Offset);
263}
264
265unsigned MipsRegisterInfo::
266getFrameRegister(const MachineFunction &MF) const {
267  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
268  bool IsN64 = Subtarget.isABI_N64();
269
270  return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) :
271                          (IsN64 ? Mips::SP_64 : Mips::SP);
272}
273
274unsigned MipsRegisterInfo::
275getEHExceptionRegister() const {
276  llvm_unreachable("What is the exception register");
277}
278
279unsigned MipsRegisterInfo::
280getEHHandlerRegister() const {
281  llvm_unreachable("What is the exception handler register");
282}
283