Mips16RegisterInfo.cpp revision 9441125d636dee246acf9cb6c8f264edda92c335
1//===-- Mips16RegisterInfo.cpp - MIPS16 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 MIPS16 implementation of the TargetRegisterInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Mips16RegisterInfo.h"
15#include "Mips16InstrInfo.h"
16#include "Mips.h"
17#include "MipsAnalyzeImmediate.h"
18#include "MipsInstrInfo.h"
19#include "MipsSubtarget.h"
20#include "MipsMachineFunction.h"
21#include "llvm/Constants.h"
22#include "llvm/DebugInfo.h"
23#include "llvm/Type.h"
24#include "llvm/Function.h"
25#include "llvm/CodeGen/ValueTypes.h"
26#include "llvm/CodeGen/MachineInstrBuilder.h"
27#include "llvm/CodeGen/MachineFunction.h"
28#include "llvm/CodeGen/MachineFrameInfo.h"
29#include "llvm/Target/TargetFrameLowering.h"
30#include "llvm/Target/TargetMachine.h"
31#include "llvm/Target/TargetOptions.h"
32#include "llvm/Target/TargetInstrInfo.h"
33#include "llvm/Support/CommandLine.h"
34#include "llvm/Support/Debug.h"
35#include "llvm/Support/ErrorHandling.h"
36#include "llvm/Support/raw_ostream.h"
37#include "llvm/ADT/BitVector.h"
38#include "llvm/ADT/STLExtras.h"
39
40using namespace llvm;
41
42Mips16RegisterInfo::Mips16RegisterInfo(const MipsSubtarget &ST,
43    const Mips16InstrInfo &I)
44  : MipsRegisterInfo(ST), TII(I) {}
45
46// This function eliminate ADJCALLSTACKDOWN,
47// ADJCALLSTACKUP pseudo instructions
48void Mips16RegisterInfo::
49eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
50                              MachineBasicBlock::iterator I) const {
51  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
52
53  if (!TFI->hasReservedCallFrame(MF)) {
54    int64_t Amount = I->getOperand(0).getImm();
55
56    if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
57      Amount = -Amount;
58
59    const Mips16InstrInfo *II = static_cast<const Mips16InstrInfo*>(&TII);
60
61    II->adjustStackPtr(Mips::SP, Amount, MBB, I);
62  }
63
64  MBB.erase(I);
65}
66
67void Mips16RegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
68                                     unsigned OpNo, int FrameIndex,
69                                     uint64_t StackSize,
70                                     int64_t SPOffset) const {
71  MachineInstr &MI = *II;
72  MachineFunction &MF = *MI.getParent()->getParent();
73  MachineFrameInfo *MFI = MF.getFrameInfo();
74
75  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
76  int MinCSFI = 0;
77  int MaxCSFI = -1;
78
79  if (CSI.size()) {
80    MinCSFI = CSI[0].getFrameIdx();
81    MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
82  }
83
84  // The following stack frame objects are always
85  // referenced relative to $sp:
86  //  1. Outgoing arguments.
87  //  2. Pointer to dynamically allocated stack space.
88  //  3. Locations for callee-saved registers.
89  // Everything else is referenced relative to whatever register
90  // getFrameRegister() returns.
91  unsigned FrameReg;
92
93  if (FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI)
94    FrameReg = Mips::SP;
95  else {
96    const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
97    if (TFI->hasFP(MF)) {
98      FrameReg = Mips::S0;
99    }
100    else {
101      if ((MI.getNumOperands()> OpNo+2) && MI.getOperand(OpNo+2).isReg())
102        FrameReg = MI.getOperand(OpNo+2).getReg();
103      else
104        FrameReg = Mips::SP;
105    }
106  }
107  // Calculate final offset.
108  // - There is no need to change the offset if the frame object
109  //   is one of the
110  //   following: an outgoing argument, pointer to a dynamically allocated
111  //   stack space or a $gp restore location,
112  // - If the frame object is any of the following,
113  //   its offset must be adjusted
114  //   by adding the size of the stack:
115  //   incoming argument, callee-saved register location or local variable.
116  int64_t Offset;
117  Offset = SPOffset + (int64_t)StackSize;
118  Offset += MI.getOperand(OpNo + 1).getImm();
119
120
121  DEBUG(errs() << "Offset     : " << Offset << "\n" << "<--------->\n");
122
123  MI.getOperand(OpNo).ChangeToRegister(FrameReg, false);
124  MI.getOperand(OpNo + 1).ChangeToImmediate(Offset);
125
126
127}
128