MipsRegisterInfo.cpp revision e62f97c094dba44e4c259d20135167fa91912eea
1//===- MipsRegisterInfo.cpp - MIPS Register Information -== -----*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file was developed by Bruno Cardoso Lopes and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the MIPS implementation of the MRegisterInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "mips-reg-info"
15
16#include "Mips.h"
17#include "MipsRegisterInfo.h"
18#include "MipsMachineFunction.h"
19#include "llvm/Constants.h"
20#include "llvm/Type.h"
21#include "llvm/Function.h"
22#include "llvm/CodeGen/ValueTypes.h"
23#include "llvm/CodeGen/MachineInstrBuilder.h"
24#include "llvm/CodeGen/MachineFunction.h"
25#include "llvm/CodeGen/MachineFrameInfo.h"
26#include "llvm/CodeGen/MachineLocation.h"
27#include "llvm/Target/TargetFrameInfo.h"
28#include "llvm/Target/TargetMachine.h"
29#include "llvm/Target/TargetOptions.h"
30#include "llvm/Target/TargetInstrInfo.h"
31#include "llvm/Support/CommandLine.h"
32#include "llvm/Support/Debug.h"
33#include "llvm/ADT/BitVector.h"
34#include "llvm/ADT/STLExtras.h"
35//#include "MipsSubtarget.h"
36
37using namespace llvm;
38
39// TODO: add subtarget support
40MipsRegisterInfo::MipsRegisterInfo(const TargetInstrInfo &tii)
41  : MipsGenRegisterInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP),
42  TII(tii) {}
43
44/// getRegisterNumbering - Given the enum value for some register, e.g.
45/// Mips::RA, return the number that it corresponds to (e.g. 31).
46unsigned MipsRegisterInfo::
47getRegisterNumbering(unsigned RegEnum)
48{
49  switch (RegEnum) {
50    case Mips::ZERO : return 0;
51    case Mips::AT   : return 1;
52    case Mips::V0   : return 2;
53    case Mips::V1   : return 3;
54    case Mips::A0   : return 4;
55    case Mips::A1   : return 5;
56    case Mips::A2   : return 6;
57    case Mips::A3   : return 7;
58    case Mips::T0   : return 8;
59    case Mips::T1   : return 9;
60    case Mips::T2   : return 10;
61    case Mips::T3   : return 11;
62    case Mips::T4   : return 12;
63    case Mips::T5   : return 13;
64    case Mips::T6   : return 14;
65    case Mips::T7   : return 15;
66    case Mips::T8   : return 16;
67    case Mips::T9   : return 17;
68    case Mips::S0   : return 18;
69    case Mips::S1   : return 19;
70    case Mips::S2   : return 20;
71    case Mips::S3   : return 21;
72    case Mips::S4   : return 22;
73    case Mips::S5   : return 23;
74    case Mips::S6   : return 24;
75    case Mips::S7   : return 25;
76    case Mips::K0   : return 26;
77    case Mips::K1   : return 27;
78    case Mips::GP   : return 28;
79    case Mips::SP   : return 29;
80    case Mips::FP   : return 30;
81    case Mips::RA   : return 31;
82    default: assert(0 && "Unknown register number!");
83  }
84}
85
86void MipsRegisterInfo::
87storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
88          unsigned SrcReg, int FI,
89          const TargetRegisterClass *RC) const
90{
91  if (RC == Mips::CPURegsRegisterClass)
92    BuildMI(MBB, I, TII.get(Mips::SW)).addReg(SrcReg, false, false, true)
93          .addImm(0).addFrameIndex(FI);
94  else
95    assert(0 && "Can't store this register to stack slot");
96}
97
98void MipsRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
99                                      SmallVectorImpl<MachineOperand> &Addr,
100                                      const TargetRegisterClass *RC,
101                                 SmallVectorImpl<MachineInstr*> &NewMIs) const {
102  if (RC != Mips::CPURegsRegisterClass)
103    assert(0 && "Can't store this register");
104  MachineInstrBuilder MIB = BuildMI(TII.get(Mips::SW))
105    .addReg(SrcReg, false, false, true);
106  for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
107    MachineOperand &MO = Addr[i];
108    if (MO.isRegister())
109      MIB.addReg(MO.getReg());
110    else if (MO.isImmediate())
111      MIB.addImm(MO.getImmedValue());
112    else
113      MIB.addFrameIndex(MO.getFrameIndex());
114  }
115  NewMIs.push_back(MIB);
116  return;
117}
118
119void MipsRegisterInfo::
120loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
121                     unsigned DestReg, int FI,
122                     const TargetRegisterClass *RC) const
123{
124  if (RC == Mips::CPURegsRegisterClass)
125    BuildMI(MBB, I, TII.get(Mips::LW), DestReg).addImm(0).addFrameIndex(FI);
126  else
127    assert(0 && "Can't load this register from stack slot");
128}
129
130void MipsRegisterInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
131                                       SmallVectorImpl<MachineOperand> &Addr,
132                                       const TargetRegisterClass *RC,
133                                 SmallVectorImpl<MachineInstr*> &NewMIs) const {
134  if (RC != Mips::CPURegsRegisterClass)
135    assert(0 && "Can't load this register");
136  MachineInstrBuilder MIB = BuildMI(TII.get(Mips::LW), DestReg);
137  for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
138    MachineOperand &MO = Addr[i];
139    if (MO.isRegister())
140      MIB.addReg(MO.getReg());
141    else if (MO.isImmediate())
142      MIB.addImm(MO.getImmedValue());
143    else
144      MIB.addFrameIndex(MO.getFrameIndex());
145  }
146  NewMIs.push_back(MIB);
147  return;
148}
149
150void MipsRegisterInfo::
151copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
152             unsigned DestReg, unsigned SrcReg,
153             const TargetRegisterClass *DestRC,
154             const TargetRegisterClass *SrcRC) const
155{
156  if (DestRC != SrcRC) {
157    cerr << "Not yet supported!";
158    abort();
159  }
160
161  if (DestRC == Mips::CPURegsRegisterClass)
162    BuildMI(MBB, I, TII.get(Mips::ADDu), DestReg).addReg(Mips::ZERO)
163      .addReg(SrcReg);
164  else
165    assert (0 && "Can't copy this register");
166}
167
168void MipsRegisterInfo::reMaterialize(MachineBasicBlock &MBB,
169                                      MachineBasicBlock::iterator I,
170                                      unsigned DestReg,
171                                      const MachineInstr *Orig) const
172{
173    MachineInstr *MI = Orig->clone();
174    MI->getOperand(0).setReg(DestReg);
175    MBB.insert(I, MI);
176}
177
178MachineInstr *MipsRegisterInfo::
179foldMemoryOperand(MachineInstr* MI, unsigned OpNum, int FI) const
180{
181  MachineInstr *NewMI = NULL;
182
183  switch (MI->getOpcode())
184  {
185    case Mips::ADDu:
186      if ((MI->getOperand(0).isRegister()) &&
187        (MI->getOperand(1).isRegister()) &&
188        (MI->getOperand(1).getReg() == Mips::ZERO) &&
189        (MI->getOperand(2).isRegister()))
190      {
191        if (OpNum == 0)    // COPY -> STORE
192          NewMI = BuildMI(TII.get(Mips::SW)).addFrameIndex(FI)
193                  .addImm(0).addReg(MI->getOperand(2).getReg());
194        else               // COPY -> LOAD
195          NewMI = BuildMI(TII.get(Mips::LW), MI->getOperand(0)
196                  .getReg()).addImm(0).addFrameIndex(FI);
197      }
198      break;
199  }
200
201  if (NewMI)
202    NewMI->copyKillDeadInfo(MI);
203  return NewMI;
204}
205
206//===----------------------------------------------------------------------===//
207//
208// Callee Saved Registers methods
209//
210//===----------------------------------------------------------------------===//
211
212/// Mips Callee Saved Registers
213const unsigned* MipsRegisterInfo::
214getCalleeSavedRegs(const MachineFunction *MF) const
215{
216  // Mips calle-save register range is $16-$26(s0-s7)
217  static const unsigned CalleeSavedRegs[] = {
218    Mips::S0, Mips::S1, Mips::S2, Mips::S3,
219    Mips::S4, Mips::S5, Mips::S6, Mips::S7, 0
220  };
221  return CalleeSavedRegs;
222}
223
224/// Mips Callee Saved Register Classes
225const TargetRegisterClass* const*
226MipsRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const
227{
228  static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
229    &Mips::CPURegsRegClass, &Mips::CPURegsRegClass,
230    &Mips::CPURegsRegClass, &Mips::CPURegsRegClass,
231    &Mips::CPURegsRegClass, &Mips::CPURegsRegClass,
232    &Mips::CPURegsRegClass, &Mips::CPURegsRegClass, 0
233  };
234  return CalleeSavedRegClasses;
235}
236
237BitVector MipsRegisterInfo::
238getReservedRegs(const MachineFunction &MF) const
239{
240  BitVector Reserved(getNumRegs());
241  Reserved.set(Mips::ZERO);
242  Reserved.set(Mips::AT);
243  Reserved.set(Mips::K0);
244  Reserved.set(Mips::K1);
245  Reserved.set(Mips::GP);
246  Reserved.set(Mips::SP);
247  Reserved.set(Mips::FP);
248  Reserved.set(Mips::RA);
249  return Reserved;
250}
251
252//===----------------------------------------------------------------------===//
253//
254// Stack Frame Processing methods
255// +----------------------------+
256//
257// The stack is allocated decrementing the stack pointer on
258// the first instruction of a function prologue. Once decremented,
259// all stack referencesare are done thought a positive offset
260// from the stack/frame pointer, so the stack is considering
261// to grow up! Otherwise terrible hacks would have to be made
262// to get this stack ABI compliant :)
263//
264//  The stack frame required by the ABI:
265//  Offset
266//
267//  0                 ----------
268//  4                 Args to pass
269//  .                 saved $GP  (used in PIC - not supported yet)
270//  .                 Local Area
271//  .                 saved "Callee Saved" Registers
272//  .                 saved FP
273//  .                 saved RA
274//  StackSize         -----------
275//
276// Offset - offset from sp after stack allocation on function prologue
277//
278// The sp is the stack pointer subtracted/added from the stack size
279// at the Prologue/Epilogue
280//
281// References to the previous stack (to obtain arguments) are done
282// with offsets that exceeds the stack size: (stacksize+(4*(num_arg-1))
283//
284// Examples:
285// - reference to the actual stack frame
286//   for any local area var there is smt like : FI >= 0, StackOffset: 4
287//     sw REGX, 4(SP)
288//
289// - reference to previous stack frame
290//   suppose there's a load to the 5th arguments : FI < 0, StackOffset: 16.
291//   The emitted instruction will be something like:
292//     lw REGX, 16+StackSize(SP)
293//
294// Since the total stack size is unknown on LowerFORMAL_ARGUMENTS, all
295// stack references (ObjectOffset) created to reference the function
296// arguments, are negative numbers. This way, on eliminateFrameIndex it's
297// possible to detect those references and the offsets are adjusted to
298// their real location.
299//
300//
301//
302//===----------------------------------------------------------------------===//
303
304// hasFP - Return true if the specified function should have a dedicated frame
305// pointer register.  This is true if the function has variable sized allocas or
306// if frame pointer elimination is disabled.
307bool MipsRegisterInfo::
308hasFP(const MachineFunction &MF) const {
309  return (NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects());
310}
311
312// This function eliminate ADJCALLSTACKDOWN,
313// ADJCALLSTACKUP pseudo instructions
314void MipsRegisterInfo::
315eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
316                              MachineBasicBlock::iterator I) const {
317  // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
318  MBB.erase(I);
319}
320
321// FrameIndex represent objects inside a abstract stack.
322// We must replace FrameIndex with an stack/frame pointer
323// direct reference.
324void MipsRegisterInfo::
325eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
326                    RegScavenger *RS) const
327{
328  MachineInstr &MI = *II;
329  MachineFunction &MF = *MI.getParent()->getParent();
330
331  unsigned i = 0;
332  while (!MI.getOperand(i).isFrameIndex()) {
333    ++i;
334    assert(i < MI.getNumOperands() &&
335           "Instr doesn't have FrameIndex operand!");
336  }
337
338  int FrameIndex = MI.getOperand(i).getFrameIndex();
339  int stackSize  = MF.getFrameInfo()->getStackSize();
340  int spOffset   = MF.getFrameInfo()->getObjectOffset(FrameIndex);
341
342  #ifndef NDEBUG
343  DOUT << "\nFunction : " << MF.getFunction()->getName() << "\n";
344  DOUT << "<--------->\n";
345  MI.print(DOUT);
346  DOUT << "FrameIndex : " << FrameIndex << "\n";
347  DOUT << "spOffset   : " << spOffset << "\n";
348  DOUT << "stackSize  : " << stackSize << "\n";
349  #endif
350
351  // as explained on LowerFORMAL_ARGUMENTS, detect negative offsets
352  // and adjust SPOffsets considering the final stack size.
353  int Offset = ((spOffset < 0) ? (stackSize + (-(spOffset+4))) : (spOffset));
354  Offset    += MI.getOperand(i-1).getImm();
355
356  #ifndef NDEBUG
357  DOUT << "Offset     : " << Offset << "\n";
358  DOUT << "<--------->\n";
359  #endif
360
361  MI.getOperand(i-1).ChangeToImmediate(Offset);
362  MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
363}
364
365void MipsRegisterInfo::
366emitPrologue(MachineFunction &MF) const
367{
368  MachineBasicBlock &MBB   = MF.front();
369  MachineFrameInfo *MFI    = MF.getFrameInfo();
370  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
371  MachineBasicBlock::iterator MBBI = MBB.begin();
372  bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_);
373
374  // Replace the dummy '0' SPOffset by the negative
375  // offsets, as explained on LowerFORMAL_ARGUMENTS
376  MipsFI->adjustLoadArgsFI(MFI);
377  MipsFI->adjustStoreVarArgsFI(MFI);
378
379  // Get the number of bytes to allocate from the FrameInfo.
380  int NumBytes = (int) MFI->getStackSize();
381
382  #ifndef NDEBUG
383  DOUT << "\n<--- EMIT PROLOGUE --->\n";
384  DOUT << "Actual Stack size :" << NumBytes << "\n";
385  #endif
386
387  // No need to allocate space on the stack.
388  if (NumBytes == 0) return;
389
390  int FPOffset, RAOffset;
391
392  // Allocate space for saved RA and FP when needed
393  if ((hasFP(MF)) && (MFI->hasCalls())) {
394    FPOffset = NumBytes;
395    RAOffset = (NumBytes+4);
396    NumBytes += 8;
397  } else if ((!hasFP(MF)) && (MFI->hasCalls())) {
398    FPOffset = 0;
399    RAOffset = NumBytes;
400    NumBytes += 4;
401  } else if ((hasFP(MF)) && (!MFI->hasCalls())) {
402    FPOffset = NumBytes;
403    RAOffset = 0;
404    NumBytes += 4;
405  }
406
407  MFI->setObjectOffset(MFI->CreateStackObject(4,4), FPOffset);
408  MFI->setObjectOffset(MFI->CreateStackObject(4,4), RAOffset);
409  MipsFI->setFPStackOffset(FPOffset);
410  MipsFI->setRAStackOffset(RAOffset);
411
412  // Align stack.
413  unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
414  NumBytes = ((NumBytes+Align-1)/Align*Align);
415
416  #ifndef NDEBUG
417  DOUT << "FPOffset :" << FPOffset << "\n";
418  DOUT << "RAOffset :" << RAOffset << "\n";
419  DOUT << "New stack size :" << NumBytes << "\n\n";
420  #endif
421
422  // Update frame info
423  MFI->setStackSize(NumBytes);
424
425  // PIC speficic function prologue
426  if (isPIC)
427    BuildMI(MBB, MBBI, TII.get(Mips::CPLOAD)).addReg(Mips::T9);
428
429  // Adjust stack : addi sp, sp, (-imm)
430  BuildMI(MBB, MBBI, TII.get(Mips::ADDiu), Mips::SP)
431      .addReg(Mips::SP).addImm(-NumBytes);
432
433  // Save the return address only if the function isnt a leaf one.
434  // sw  $ra, stack_loc($sp)
435  if (MFI->hasCalls()) {
436    BuildMI(MBB, MBBI, TII.get(Mips::SW))
437        .addReg(Mips::RA).addImm(RAOffset).addReg(Mips::SP);
438  }
439
440  // if framepointer enabled, save it and set it
441  // to point to the stack pointer
442  if (hasFP(MF)) {
443    // sw  $fp,stack_loc($sp)
444    BuildMI(MBB, MBBI, TII.get(Mips::SW))
445      .addReg(Mips::FP).addImm(FPOffset).addReg(Mips::SP);
446
447    // move $fp, $sp
448    BuildMI(MBB, MBBI, TII.get(Mips::ADDu), Mips::FP)
449      .addReg(Mips::SP).addReg(Mips::ZERO);
450  }
451
452  // PIC speficic function prologue
453  if ((isPIC) && (MFI->hasCalls()))
454    BuildMI(MBB, MBBI, TII.get(Mips::CPRESTORE))
455      .addImm(MipsFI->getGPStackOffset());
456}
457
458void MipsRegisterInfo::
459emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const
460{
461  MachineBasicBlock::iterator MBBI = prior(MBB.end());
462  MachineFrameInfo *MFI            = MF.getFrameInfo();
463  MipsFunctionInfo *MipsFI         = MF.getInfo<MipsFunctionInfo>();
464
465  // Get the number of bytes from FrameInfo
466  int NumBytes = (int) MFI->getStackSize();
467
468  // Get the FI's where RA and FP are saved.
469  int FPOffset = MipsFI->getFPStackOffset();
470  int RAOffset = MipsFI->getRAStackOffset();
471
472  // if framepointer enabled, restore it and restore the
473  // stack pointer
474  if (hasFP(MF)) {
475    // move $sp, $fp
476    BuildMI(MBB, MBBI, TII.get(Mips::ADDu), Mips::SP)
477      .addReg(Mips::FP).addReg(Mips::ZERO);
478
479    // lw  $fp,stack_loc($sp)
480    BuildMI(MBB, MBBI, TII.get(Mips::LW))
481      .addReg(Mips::FP).addImm(FPOffset).addReg(Mips::SP);
482  }
483
484  // Restore the return address only if the function isnt a leaf one.
485  // lw  $ra, stack_loc($sp)
486  if (MFI->hasCalls()) {
487    BuildMI(MBB, MBBI, TII.get(Mips::LW))
488        .addReg(Mips::RA).addImm(RAOffset).addReg(Mips::SP);
489  }
490
491  // adjust stack  : insert addi sp, sp, (imm)
492  if (NumBytes) {
493    BuildMI(MBB, MBBI, TII.get(Mips::ADDiu), Mips::SP)
494      .addReg(Mips::SP).addImm(NumBytes);
495  }
496}
497
498void MipsRegisterInfo::
499processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
500  // Set the SPOffset on the FI where GP must be saved/loaded.
501  MachineFrameInfo *MFI = MF.getFrameInfo();
502  if (MFI->hasCalls()) {
503    MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
504    #ifndef NDEBUG
505    DOUT << "processFunctionBeforeFrameFinalized\n";
506    DOUT << "GPOffset :" << MipsFI->getGPStackOffset() << "\n";
507    DOUT << "FI :" << MipsFI->getGPFI() << "\n";
508    #endif
509    MFI->setObjectOffset(MipsFI->getGPFI(), MipsFI->getGPStackOffset());
510  }
511}
512
513unsigned MipsRegisterInfo::
514getRARegister() const {
515  return Mips::RA;
516}
517
518unsigned MipsRegisterInfo::
519getFrameRegister(MachineFunction &MF) const {
520  return hasFP(MF) ? Mips::FP : Mips::SP;
521}
522
523unsigned MipsRegisterInfo::
524getEHExceptionRegister() const {
525  assert(0 && "What is the exception register");
526  return 0;
527}
528
529unsigned MipsRegisterInfo::
530getEHHandlerRegister() const {
531  assert(0 && "What is the exception handler register");
532  return 0;
533}
534
535int MipsRegisterInfo::
536getDwarfRegNum(unsigned RegNum, bool isEH) const {
537  assert(0 && "What is the dwarf register number");
538  return -1;
539}
540
541#include "MipsGenRegisterInfo.inc"
542
543