1251662Sdim//===-- Mips16RegisterInfo.cpp - MIPS16 Register Information --------------===//
2239310Sdim//
3239310Sdim//                     The LLVM Compiler Infrastructure
4239310Sdim//
5239310Sdim// This file is distributed under the University of Illinois Open Source
6239310Sdim// License. See LICENSE.TXT for details.
7239310Sdim//
8239310Sdim//===----------------------------------------------------------------------===//
9239310Sdim//
10239310Sdim// This file contains the MIPS16 implementation of the TargetRegisterInfo class.
11239310Sdim//
12239310Sdim//===----------------------------------------------------------------------===//
13239310Sdim
14239310Sdim#include "Mips16RegisterInfo.h"
15243830Sdim#include "Mips16InstrInfo.h"
16239310Sdim#include "Mips.h"
17249423Sdim#include "Mips16InstrInfo.h"
18239310Sdim#include "MipsAnalyzeImmediate.h"
19239310Sdim#include "MipsInstrInfo.h"
20249423Sdim#include "MipsMachineFunction.h"
21239310Sdim#include "MipsSubtarget.h"
22249423Sdim#include "llvm/ADT/BitVector.h"
23249423Sdim#include "llvm/ADT/STLExtras.h"
24249423Sdim#include "llvm/CodeGen/MachineFrameInfo.h"
25249423Sdim#include "llvm/CodeGen/MachineFunction.h"
26249423Sdim#include "llvm/CodeGen/MachineInstrBuilder.h"
27249423Sdim#include "llvm/CodeGen/MachineRegisterInfo.h"
28249423Sdim#include "llvm/CodeGen/ValueTypes.h"
29239310Sdim#include "llvm/DebugInfo.h"
30249423Sdim#include "llvm/IR/Constants.h"
31249423Sdim#include "llvm/IR/Function.h"
32249423Sdim#include "llvm/IR/Type.h"
33239310Sdim#include "llvm/Support/CommandLine.h"
34239310Sdim#include "llvm/Support/Debug.h"
35239310Sdim#include "llvm/Support/ErrorHandling.h"
36239310Sdim#include "llvm/Support/raw_ostream.h"
37249423Sdim#include "llvm/Target/TargetFrameLowering.h"
38249423Sdim#include "llvm/Target/TargetInstrInfo.h"
39249423Sdim#include "llvm/Target/TargetMachine.h"
40249423Sdim#include "llvm/Target/TargetOptions.h"
41239310Sdim
42239310Sdimusing namespace llvm;
43239310Sdim
44263508SdimMips16RegisterInfo::Mips16RegisterInfo(const MipsSubtarget &ST)
45263508Sdim  : MipsRegisterInfo(ST) {}
46239310Sdim
47249423Sdimbool Mips16RegisterInfo::requiresRegisterScavenging
48249423Sdim  (const MachineFunction &MF) const {
49263508Sdim  return false;
50249423Sdim}
51249423Sdimbool Mips16RegisterInfo::requiresFrameIndexScavenging
52249423Sdim  (const MachineFunction &MF) const {
53263508Sdim  return false;
54249423Sdim}
55243830Sdim
56249423Sdimbool Mips16RegisterInfo::useFPForScavengingIndex
57249423Sdim  (const MachineFunction &MF) const {
58249423Sdim  return false;
59249423Sdim}
60243830Sdim
61249423Sdimbool Mips16RegisterInfo::saveScavengerRegister
62249423Sdim  (MachineBasicBlock &MBB,
63249423Sdim   MachineBasicBlock::iterator I,
64249423Sdim   MachineBasicBlock::iterator &UseMI,
65249423Sdim   const TargetRegisterClass *RC,
66249423Sdim   unsigned Reg) const {
67249423Sdim  DebugLoc DL;
68263508Sdim  const TargetInstrInfo &TII = *MBB.getParent()->getTarget().getInstrInfo();
69249423Sdim  TII.copyPhysReg(MBB, I, DL, Mips::T0, Reg, true);
70249423Sdim  TII.copyPhysReg(MBB, UseMI, DL, Reg, Mips::T0, true);
71249423Sdim  return true;
72249423Sdim}
73243830Sdim
74249423Sdimconst TargetRegisterClass *
75249423SdimMips16RegisterInfo::intRegClass(unsigned Size) const {
76249423Sdim  assert(Size == 4);
77249423Sdim  return &Mips::CPU16RegsRegClass;
78239310Sdim}
79239310Sdim
80239310Sdimvoid Mips16RegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
81239310Sdim                                     unsigned OpNo, int FrameIndex,
82239310Sdim                                     uint64_t StackSize,
83239310Sdim                                     int64_t SPOffset) const {
84243830Sdim  MachineInstr &MI = *II;
85243830Sdim  MachineFunction &MF = *MI.getParent()->getParent();
86243830Sdim  MachineFrameInfo *MFI = MF.getFrameInfo();
87239310Sdim
88243830Sdim  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
89243830Sdim  int MinCSFI = 0;
90243830Sdim  int MaxCSFI = -1;
91239310Sdim
92243830Sdim  if (CSI.size()) {
93243830Sdim    MinCSFI = CSI[0].getFrameIdx();
94243830Sdim    MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
95243830Sdim  }
96239310Sdim
97243830Sdim  // The following stack frame objects are always
98243830Sdim  // referenced relative to $sp:
99243830Sdim  //  1. Outgoing arguments.
100243830Sdim  //  2. Pointer to dynamically allocated stack space.
101243830Sdim  //  3. Locations for callee-saved registers.
102243830Sdim  // Everything else is referenced relative to whatever register
103243830Sdim  // getFrameRegister() returns.
104243830Sdim  unsigned FrameReg;
105239310Sdim
106243830Sdim  if (FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI)
107243830Sdim    FrameReg = Mips::SP;
108243830Sdim  else {
109243830Sdim    const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
110243830Sdim    if (TFI->hasFP(MF)) {
111243830Sdim      FrameReg = Mips::S0;
112243830Sdim    }
113243830Sdim    else {
114243830Sdim      if ((MI.getNumOperands()> OpNo+2) && MI.getOperand(OpNo+2).isReg())
115243830Sdim        FrameReg = MI.getOperand(OpNo+2).getReg();
116239310Sdim      else
117243830Sdim        FrameReg = Mips::SP;
118243830Sdim    }
119243830Sdim  }
120243830Sdim  // Calculate final offset.
121243830Sdim  // - There is no need to change the offset if the frame object
122243830Sdim  //   is one of the
123243830Sdim  //   following: an outgoing argument, pointer to a dynamically allocated
124243830Sdim  //   stack space or a $gp restore location,
125243830Sdim  // - If the frame object is any of the following,
126243830Sdim  //   its offset must be adjusted
127243830Sdim  //   by adding the size of the stack:
128243830Sdim  //   incoming argument, callee-saved register location or local variable.
129243830Sdim  int64_t Offset;
130249423Sdim  bool IsKill = false;
131243830Sdim  Offset = SPOffset + (int64_t)StackSize;
132243830Sdim  Offset += MI.getOperand(OpNo + 1).getImm();
133239310Sdim
134239310Sdim
135243830Sdim  DEBUG(errs() << "Offset     : " << Offset << "\n" << "<--------->\n");
136239310Sdim
137263508Sdim  if (!MI.isDebugValue() &&
138263508Sdim      !Mips16InstrInfo::validImmediate(MI.getOpcode(), FrameReg, Offset)) {
139249423Sdim    MachineBasicBlock &MBB = *MI.getParent();
140249423Sdim    DebugLoc DL = II->getDebugLoc();
141249423Sdim    unsigned NewImm;
142263508Sdim    const Mips16InstrInfo &TII =
143263508Sdim      *static_cast<const Mips16InstrInfo*>(
144263508Sdim        MBB.getParent()->getTarget().getInstrInfo());
145249423Sdim    FrameReg = TII.loadImmediate(FrameReg, Offset, MBB, II, DL, NewImm);
146249423Sdim    Offset = SignExtend64<16>(NewImm);
147249423Sdim    IsKill = true;
148249423Sdim  }
149249423Sdim  MI.getOperand(OpNo).ChangeToRegister(FrameReg, false, false, IsKill);
150243830Sdim  MI.getOperand(OpNo + 1).ChangeToImmediate(Offset);
151239310Sdim
152239310Sdim
153239310Sdim}
154