Mips16RegisterInfo.cpp revision 0fd831325006d3d3f73022b4908ceacfbf7aa262
1ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//===-- Mips16RegisterInfo.cpp - MIPS16 Register Information -== ----------===//
2ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//
3ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//                     The LLVM Compiler Infrastructure
4ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//
5ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// This file is distributed under the University of Illinois Open Source
6ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// License. See LICENSE.TXT for details.
7ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//
8ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//===----------------------------------------------------------------------===//
9ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//
10ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// This file contains the MIPS16 implementation of the TargetRegisterInfo class.
11ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//
12ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//===----------------------------------------------------------------------===//
13ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek
14ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "Mips16RegisterInfo.h"
15ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "Mips.h"
16ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "Mips16InstrInfo.h"
17ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "MipsAnalyzeImmediate.h"
18686775deca8b8685eb90801495880e3abdd844c2Chris Lattner#include "MipsInstrInfo.h"
19a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek#include "MipsMachineFunction.h"
20f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "MipsSubtarget.h"
219c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko#include "llvm/ADT/BitVector.h"
22ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "llvm/ADT/STLExtras.h"
23ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "llvm/CodeGen/MachineFrameInfo.h"
24ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "llvm/CodeGen/MachineFunction.h"
259c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko#include "llvm/CodeGen/MachineInstrBuilder.h"
269c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko#include "llvm/CodeGen/ValueTypes.h"
27ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "llvm/Constants.h"
28dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko#include "llvm/DebugInfo.h"
29dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko#include "llvm/Function.h"
30dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko#include "llvm/Support/CommandLine.h"
31ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "llvm/Support/Debug.h"
32ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "llvm/Support/ErrorHandling.h"
33ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "llvm/Support/raw_ostream.h"
34a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek#include "llvm/Target/TargetFrameLowering.h"
35686775deca8b8685eb90801495880e3abdd844c2Chris Lattner#include "llvm/Target/TargetInstrInfo.h"
36a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek#include "llvm/Target/TargetMachine.h"
37a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek#include "llvm/Target/TargetOptions.h"
38a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek#include "llvm/Type.h"
39a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek
409c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenkousing namespace llvm;
419c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko
429c48d16a11872624410ab3a5944edcba0f32818cDmitri GribenkoMips16RegisterInfo::Mips16RegisterInfo(const MipsSubtarget &ST,
439c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko    const Mips16InstrInfo &I)
449c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko  : MipsRegisterInfo(ST), TII(I) {}
459c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko
469c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenkobool Mips16RegisterInfo::requiresRegisterScavenging
479c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko  (const MachineFunction &MF) const {
489c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko  return true;
499c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko}
509c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenkobool Mips16RegisterInfo::requiresFrameIndexScavenging
519c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko  (const MachineFunction &MF) const {
529c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko  return true;
539c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko}
549c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko
559c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenkobool Mips16RegisterInfo::useFPForScavengingIndex
569c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko  (const MachineFunction &MF) const {
579c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko  return false;
589c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko}
599c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko
609c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenkobool Mips16RegisterInfo::saveScavengerRegister
619c48d16a11872624410ab3a5944edcba0f32818cDmitri Gribenko  (MachineBasicBlock &MBB,
62a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek   MachineBasicBlock::iterator I,
63a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek   MachineBasicBlock::iterator &UseMI,
64ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek   const TargetRegisterClass *RC,
65baf82b0fdf5c23dff80660add40bb92bd850bba0Ted Kremenek   unsigned Reg) const {
66baf82b0fdf5c23dff80660add40bb92bd850bba0Ted Kremenek  DebugLoc DL;
67baf82b0fdf5c23dff80660add40bb92bd850bba0Ted Kremenek  TII.copyPhysReg(MBB, I, DL, Mips::T0, Reg, true);
68ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek  TII.copyPhysReg(MBB, UseMI, DL, Reg, Mips::T0, true);
69ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek  return true;
70ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek}
71ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek
72ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// This function eliminate ADJCALLSTACKDOWN,
73// ADJCALLSTACKUP pseudo instructions
74void Mips16RegisterInfo::
75eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
76                              MachineBasicBlock::iterator I) const {
77  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
78
79  if (!TFI->hasReservedCallFrame(MF)) {
80    int64_t Amount = I->getOperand(0).getImm();
81
82    if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
83      Amount = -Amount;
84
85    const Mips16InstrInfo *II = static_cast<const Mips16InstrInfo*>(&TII);
86
87    II->adjustStackPtr(Mips::SP, Amount, MBB, I);
88  }
89
90  MBB.erase(I);
91}
92
93void Mips16RegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
94                                     unsigned OpNo, int FrameIndex,
95                                     uint64_t StackSize,
96                                     int64_t SPOffset) const {
97  MachineInstr &MI = *II;
98  MachineFunction &MF = *MI.getParent()->getParent();
99  MachineFrameInfo *MFI = MF.getFrameInfo();
100
101  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
102  int MinCSFI = 0;
103  int MaxCSFI = -1;
104
105  if (CSI.size()) {
106    MinCSFI = CSI[0].getFrameIdx();
107    MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
108  }
109
110  // The following stack frame objects are always
111  // referenced relative to $sp:
112  //  1. Outgoing arguments.
113  //  2. Pointer to dynamically allocated stack space.
114  //  3. Locations for callee-saved registers.
115  // Everything else is referenced relative to whatever register
116  // getFrameRegister() returns.
117  unsigned FrameReg;
118
119  if (FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI)
120    FrameReg = Mips::SP;
121  else {
122    const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
123    if (TFI->hasFP(MF)) {
124      FrameReg = Mips::S0;
125    }
126    else {
127      if ((MI.getNumOperands()> OpNo+2) && MI.getOperand(OpNo+2).isReg())
128        FrameReg = MI.getOperand(OpNo+2).getReg();
129      else
130        FrameReg = Mips::SP;
131    }
132  }
133  // Calculate final offset.
134  // - There is no need to change the offset if the frame object
135  //   is one of the
136  //   following: an outgoing argument, pointer to a dynamically allocated
137  //   stack space or a $gp restore location,
138  // - If the frame object is any of the following,
139  //   its offset must be adjusted
140  //   by adding the size of the stack:
141  //   incoming argument, callee-saved register location or local variable.
142  int64_t Offset;
143  Offset = SPOffset + (int64_t)StackSize;
144  Offset += MI.getOperand(OpNo + 1).getImm();
145
146
147  DEBUG(errs() << "Offset     : " << Offset << "\n" << "<--------->\n");
148
149  if (!MI.isDebugValue() && ( ((FrameReg != Mips::SP) && !isInt<16>(Offset)) ||
150      ((FrameReg == Mips::SP) && !isInt<15>(Offset)) )) {
151    assert(false && "frame offset does not fit in instruction");
152  }
153  MI.getOperand(OpNo).ChangeToRegister(FrameReg, false);
154  MI.getOperand(OpNo + 1).ChangeToImmediate(Offset);
155
156
157}
158