MipsRegisterInfo.cpp revision 5e93d1c61553628a9104ac19ce5edf165a7229b2
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 "MipsSubtarget.h"
18#include "MipsRegisterInfo.h"
19#include "MipsMachineFunction.h"
20#include "llvm/Constants.h"
21#include "llvm/Type.h"
22#include "llvm/Function.h"
23#include "llvm/CodeGen/ValueTypes.h"
24#include "llvm/CodeGen/MachineInstrBuilder.h"
25#include "llvm/CodeGen/MachineFunction.h"
26#include "llvm/CodeGen/MachineFrameInfo.h"
27#include "llvm/CodeGen/MachineLocation.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
39using namespace llvm;
40
41MipsRegisterInfo::MipsRegisterInfo(const MipsSubtarget &ST,
42                                   const TargetInstrInfo &tii)
43  : MipsGenRegisterInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP),
44    Subtarget(ST), TII(tii) {}
45
46/// getRegisterNumbering - Given the enum value for some register, e.g.
47/// Mips::RA, return the number that it corresponds to (e.g. 31).
48unsigned MipsRegisterInfo::
49getRegisterNumbering(unsigned RegEnum)
50{
51  switch (RegEnum) {
52    case Mips::ZERO : case Mips::F0 : case Mips::D0 : return 0;
53    case Mips::AT   : case Mips::F1 : return 1;
54    case Mips::V0   : case Mips::F2 : case Mips::D1 : return 2;
55    case Mips::V1   : case Mips::F3 : return 3;
56    case Mips::A0   : case Mips::F4 : case Mips::D2 : return 4;
57    case Mips::A1   : case Mips::F5 : return 5;
58    case Mips::A2   : case Mips::F6 : case Mips::D3 : return 6;
59    case Mips::A3   : case Mips::F7 : return 7;
60    case Mips::T0   : case Mips::F8 : case Mips::D4 : return 8;
61    case Mips::T1   : case Mips::F9 : return 9;
62    case Mips::T2   : case Mips::F10: case Mips::D5: return 10;
63    case Mips::T3   : case Mips::F11: return 11;
64    case Mips::T4   : case Mips::F12: case Mips::D6: return 12;
65    case Mips::T5   : case Mips::F13: return 13;
66    case Mips::T6   : case Mips::F14: case Mips::D7: return 14;
67    case Mips::T7   : case Mips::F15: return 15;
68    case Mips::S0   : case Mips::F16: case Mips::D8: return 16;
69    case Mips::S1   : case Mips::F17: return 17;
70    case Mips::S2   : case Mips::F18: case Mips::D9: return 18;
71    case Mips::S3   : case Mips::F19: return 19;
72    case Mips::S4   : case Mips::F20: case Mips::D10: return 20;
73    case Mips::S5   : case Mips::F21: return 21;
74    case Mips::S6   : case Mips::F22: case Mips::D11: return 22;
75    case Mips::S7   : case Mips::F23: return 23;
76    case Mips::T8   : case Mips::F24: case Mips::D12: return 24;
77    case Mips::T9   : case Mips::F25: return 25;
78    case Mips::K0   : case Mips::F26: case Mips::D13: return 26;
79    case Mips::K1   : case Mips::F27: return 27;
80    case Mips::GP   : case Mips::F28: case Mips::D14: return 28;
81    case Mips::SP   : case Mips::F29: return 29;
82    case Mips::FP   : case Mips::F30: case Mips::D15: return 30;
83    case Mips::RA   : case Mips::F31: return 31;
84    default: llvm_unreachable("Unknown register number!");
85  }
86  return 0; // Not reached
87}
88
89unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; }
90
91//===----------------------------------------------------------------------===//
92// Callee Saved Registers methods
93//===----------------------------------------------------------------------===//
94
95/// Mips Callee Saved Registers
96const unsigned* MipsRegisterInfo::
97getCalleeSavedRegs(const MachineFunction *MF) const
98{
99  // Mips callee-save register range is $16-$23, $f20-$f30
100  static const unsigned SingleFloatOnlyCalleeSavedRegs[] = {
101    Mips::F30, Mips::F29, Mips::F28, Mips::F27, Mips::F26,
102    Mips::F25, Mips::F24, Mips::F23, Mips::F22, Mips::F21, Mips::F20,
103    Mips::RA, Mips::FP, Mips::S7, Mips::S6, Mips::S5, Mips::S4,
104    Mips::S3, Mips::S2, Mips::S1, Mips::S0, 0
105  };
106
107  static const unsigned Mips32CalleeSavedRegs[] = {
108    Mips::D15, Mips::D14, Mips::D13, Mips::D12, Mips::D11, Mips::D10,
109    Mips::RA, Mips::FP, Mips::S7, Mips::S6, Mips::S5, Mips::S4,
110    Mips::S3, Mips::S2, Mips::S1, Mips::S0, 0
111  };
112
113  if (Subtarget.isSingleFloat())
114    return SingleFloatOnlyCalleeSavedRegs;
115  else
116    return Mips32CalleeSavedRegs;
117}
118
119BitVector MipsRegisterInfo::
120getReservedRegs(const MachineFunction &MF) const {
121  BitVector Reserved(getNumRegs());
122  Reserved.set(Mips::ZERO);
123  Reserved.set(Mips::AT);
124  Reserved.set(Mips::K0);
125  Reserved.set(Mips::K1);
126  Reserved.set(Mips::GP);
127  Reserved.set(Mips::SP);
128  Reserved.set(Mips::FP);
129  Reserved.set(Mips::RA);
130
131  // SRV4 requires that odd register can't be used.
132  if (!Subtarget.isSingleFloat() && !Subtarget.isMips32())
133    for (unsigned FReg=(Mips::F0)+1; FReg < Mips::F30; FReg+=2)
134      Reserved.set(FReg);
135
136  return Reserved;
137}
138
139// This function eliminate ADJCALLSTACKDOWN,
140// ADJCALLSTACKUP pseudo instructions
141void MipsRegisterInfo::
142eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
143                              MachineBasicBlock::iterator I) const {
144  // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
145  MBB.erase(I);
146}
147
148// FrameIndex represent objects inside a abstract stack.
149// We must replace FrameIndex with an stack/frame pointer
150// direct reference.
151void MipsRegisterInfo::
152eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
153                    RegScavenger *RS) const {
154  MachineInstr &MI = *II;
155  MachineFunction &MF = *MI.getParent()->getParent();
156  MachineFrameInfo *MFI = MF.getFrameInfo();
157  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
158
159  unsigned i = 0;
160  while (!MI.getOperand(i).isFI()) {
161    ++i;
162    assert(i < MI.getNumOperands() &&
163           "Instr doesn't have FrameIndex operand!");
164  }
165
166  DEBUG(errs() << "\nFunction : " << MF.getFunction()->getName() << "\n";
167        errs() << "<--------->\n" << MI);
168
169  int FrameIndex = MI.getOperand(i).getIndex();
170  int stackSize  = MF.getFrameInfo()->getStackSize();
171  int spOffset   = MF.getFrameInfo()->getObjectOffset(FrameIndex);
172
173  DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
174               << "spOffset   : " << spOffset << "\n"
175               << "stackSize  : " << stackSize << "\n");
176
177  int Offset;
178
179  // Calculate final offset.
180  // - There is no need to change the offset if the frame object is an outgoing
181  //   argument or a $gp restore location,
182  // - If the frame object is any of the following, its offset must be adjusted
183  //   by adding the size of the stack:
184  //   incoming argument, callee-saved register location or local variable.
185  if (MipsFI->isOutArgFI(FrameIndex) || MipsFI->isGPFI(FrameIndex))
186    Offset = spOffset;
187  else
188    Offset = spOffset + stackSize;
189
190  Offset    += MI.getOperand(i-1).getImm();
191
192  DEBUG(errs() << "Offset     : " << Offset << "\n" << "<--------->\n");
193
194  unsigned NewReg = 0;
195  int NewImm = 0;
196  MachineBasicBlock &MBB = *MI.getParent();
197  bool ATUsed;
198  unsigned FrameReg;
199  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
200  int MinCSFI = 0;
201  int MaxCSFI = -1;
202
203  if (CSI.size()) {
204    MinCSFI = CSI[0].getFrameIdx();
205    MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
206  }
207
208  // The following stack frame objects are always referenced relative to $sp:
209  //  1. Outgoing arguments.
210  //  2. Pointer to dynamically allocated stack space.
211  //  3. Locations for callee-saved registers.
212  // Everything else is referenced relative to whatever register
213  // getFrameRegister() returns.
214  if (MipsFI->isOutArgFI(FrameIndex) ||
215      (FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI))
216    FrameReg = Mips::SP;
217  else
218    FrameReg = getFrameRegister(MF);
219
220  // Offset fits in the 16-bit field
221  if (Offset < 0x8000 && Offset >= -0x8000) {
222    NewReg = FrameReg;
223    NewImm = Offset;
224    ATUsed = false;
225  }
226  else {
227    const TargetInstrInfo *TII = MF.getTarget().getInstrInfo();
228    DebugLoc DL = II->getDebugLoc();
229    int ImmLo = (short)(Offset & 0xffff);
230    int ImmHi = (((unsigned)Offset & 0xffff0000) >> 16) +
231                ((Offset & 0x8000) != 0);
232
233    // FIXME: change this when mips goes MC".
234    BuildMI(MBB, II, DL, TII->get(Mips::NOAT));
235    BuildMI(MBB, II, DL, TII->get(Mips::LUi), Mips::AT).addImm(ImmHi);
236    BuildMI(MBB, II, DL, TII->get(Mips::ADDu), Mips::AT).addReg(FrameReg)
237                                                        .addReg(Mips::AT);
238    NewReg = Mips::AT;
239    NewImm = ImmLo;
240
241    ATUsed = true;
242  }
243
244  // FIXME: change this when mips goes MC".
245  if (ATUsed)
246    BuildMI(MBB, ++II, MI.getDebugLoc(), TII.get(Mips::ATMACRO));
247
248  MI.getOperand(i).ChangeToRegister(NewReg, false);
249  MI.getOperand(i-1).ChangeToImmediate(NewImm);
250}
251
252unsigned MipsRegisterInfo::
253getRARegister() const {
254  return Mips::RA;
255}
256
257unsigned MipsRegisterInfo::
258getFrameRegister(const MachineFunction &MF) const {
259  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
260
261  return TFI->hasFP(MF) ? Mips::FP : Mips::SP;
262}
263
264unsigned MipsRegisterInfo::
265getEHExceptionRegister() const {
266  llvm_unreachable("What is the exception register");
267  return 0;
268}
269
270unsigned MipsRegisterInfo::
271getEHHandlerRegister() const {
272  llvm_unreachable("What is the exception handler register");
273  return 0;
274}
275
276int MipsRegisterInfo::
277getDwarfRegNum(unsigned RegNum, bool isEH) const {
278  return MipsGenRegisterInfo::getDwarfRegNumFull(RegNum, 0);
279}
280
281#include "MipsGenRegisterInfo.inc"
282