1234285Sdim//===-- MipsMachineFunctionInfo.cpp - Private data used for Mips ----------===//
2234285Sdim//
3234285Sdim//                     The LLVM Compiler Infrastructure
4234285Sdim//
5234285Sdim// This file is distributed under the University of Illinois Open Source
6234285Sdim// License. See LICENSE.TXT for details.
7234285Sdim//
8234285Sdim//===----------------------------------------------------------------------===//
9234285Sdim
10234285Sdim#include "MipsMachineFunction.h"
11252723Sdim#include "MCTargetDesc/MipsBaseInfo.h"
12234285Sdim#include "MipsInstrInfo.h"
13234285Sdim#include "MipsSubtarget.h"
14234285Sdim#include "llvm/CodeGen/MachineInstrBuilder.h"
15234285Sdim#include "llvm/CodeGen/MachineRegisterInfo.h"
16252723Sdim#include "llvm/IR/Function.h"
17234285Sdim#include "llvm/Support/CommandLine.h"
18263509Sdim#include "llvm/Support/raw_ostream.h"
19234285Sdim
20234285Sdimusing namespace llvm;
21234285Sdim
22234285Sdimstatic cl::opt<bool>
23234285SdimFixGlobalBaseReg("mips-fix-global-base-reg", cl::Hidden, cl::init(true),
24234285Sdim                 cl::desc("Always use $gp as the global base register."));
25234285Sdim
26263509Sdim// class MipsCallEntry.
27263509SdimMipsCallEntry::MipsCallEntry(const StringRef &N) {
28263509Sdim#ifndef NDEBUG
29263509Sdim  Name = N;
30263509Sdim  Val = 0;
31263509Sdim#endif
32263509Sdim}
33263509Sdim
34263509SdimMipsCallEntry::MipsCallEntry(const GlobalValue *V) {
35263509Sdim#ifndef NDEBUG
36263509Sdim  Val = V;
37263509Sdim#endif
38263509Sdim}
39263509Sdim
40263509Sdimbool MipsCallEntry::isConstant(const MachineFrameInfo *) const {
41263509Sdim  return false;
42263509Sdim}
43263509Sdim
44263509Sdimbool MipsCallEntry::isAliased(const MachineFrameInfo *) const {
45263509Sdim  return false;
46263509Sdim}
47263509Sdim
48263509Sdimbool MipsCallEntry::mayAlias(const MachineFrameInfo *) const {
49263509Sdim  return false;
50263509Sdim}
51263509Sdim
52263509Sdimvoid MipsCallEntry::printCustom(raw_ostream &O) const {
53263509Sdim  O << "MipsCallEntry: ";
54263509Sdim#ifndef NDEBUG
55263509Sdim  if (Val)
56263509Sdim    O << Val->getName();
57263509Sdim  else
58263509Sdim    O << Name;
59263509Sdim#endif
60263509Sdim}
61263509Sdim
62263509SdimMipsFunctionInfo::~MipsFunctionInfo() {
63263509Sdim  for (StringMap<const MipsCallEntry *>::iterator
64263509Sdim       I = ExternalCallEntries.begin(), E = ExternalCallEntries.end(); I != E;
65263509Sdim       ++I)
66263509Sdim    delete I->getValue();
67263509Sdim
68263509Sdim  for (ValueMap<const GlobalValue *, const MipsCallEntry *>::iterator
69263509Sdim       I = GlobalCallEntries.begin(), E = GlobalCallEntries.end(); I != E; ++I)
70263509Sdim    delete I->second;
71263509Sdim}
72263509Sdim
73234285Sdimbool MipsFunctionInfo::globalBaseRegSet() const {
74234285Sdim  return GlobalBaseReg;
75234285Sdim}
76234285Sdim
77234285Sdimunsigned MipsFunctionInfo::getGlobalBaseReg() {
78234285Sdim  // Return if it has already been initialized.
79234285Sdim  if (GlobalBaseReg)
80234285Sdim    return GlobalBaseReg;
81234285Sdim
82234285Sdim  const MipsSubtarget &ST = MF.getTarget().getSubtarget<MipsSubtarget>();
83234285Sdim
84234285Sdim  const TargetRegisterClass *RC;
85245431Sdim  if (ST.inMips16Mode())
86245431Sdim    RC=(const TargetRegisterClass*)&Mips::CPU16RegsRegClass;
87245431Sdim  else
88245431Sdim    RC = ST.isABI_N64() ?
89263509Sdim      (const TargetRegisterClass*)&Mips::GPR64RegClass :
90263509Sdim      (const TargetRegisterClass*)&Mips::GPR32RegClass;
91234285Sdim  return GlobalBaseReg = MF.getRegInfo().createVirtualRegister(RC);
92234285Sdim}
93234285Sdim
94245431Sdimbool MipsFunctionInfo::mips16SPAliasRegSet() const {
95245431Sdim  return Mips16SPAliasReg;
96245431Sdim}
97245431Sdimunsigned MipsFunctionInfo::getMips16SPAliasReg() {
98245431Sdim  // Return if it has already been initialized.
99245431Sdim  if (Mips16SPAliasReg)
100245431Sdim    return Mips16SPAliasReg;
101245431Sdim
102245431Sdim  const TargetRegisterClass *RC;
103245431Sdim  RC=(const TargetRegisterClass*)&Mips::CPU16RegsRegClass;
104245431Sdim  return Mips16SPAliasReg = MF.getRegInfo().createVirtualRegister(RC);
105245431Sdim}
106245431Sdim
107252723Sdimvoid MipsFunctionInfo::createEhDataRegsFI() {
108252723Sdim  for (int I = 0; I < 4; ++I) {
109252723Sdim    const MipsSubtarget &ST = MF.getTarget().getSubtarget<MipsSubtarget>();
110252723Sdim    const TargetRegisterClass *RC = ST.isABI_N64() ?
111263509Sdim        &Mips::GPR64RegClass : &Mips::GPR32RegClass;
112252723Sdim
113252723Sdim    EhDataRegFI[I] = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
114252723Sdim        RC->getAlignment(), false);
115252723Sdim  }
116252723Sdim}
117252723Sdim
118252723Sdimbool MipsFunctionInfo::isEhDataRegFI(int FI) const {
119252723Sdim  return CallsEhReturn && (FI == EhDataRegFI[0] || FI == EhDataRegFI[1]
120252723Sdim                        || FI == EhDataRegFI[2] || FI == EhDataRegFI[3]);
121252723Sdim}
122252723Sdim
123263509SdimMachinePointerInfo MipsFunctionInfo::callPtrInfo(const StringRef &Name) {
124263509Sdim  const MipsCallEntry *&E = ExternalCallEntries[Name];
125263509Sdim
126263509Sdim  if (!E)
127263509Sdim    E = new MipsCallEntry(Name);
128263509Sdim
129263509Sdim  return MachinePointerInfo(E);
130263509Sdim}
131263509Sdim
132263509SdimMachinePointerInfo MipsFunctionInfo::callPtrInfo(const GlobalValue *Val) {
133263509Sdim  const MipsCallEntry *&E = GlobalCallEntries[Val];
134263509Sdim
135263509Sdim  if (!E)
136263509Sdim    E = new MipsCallEntry(Val);
137263509Sdim
138263509Sdim  return MachinePointerInfo(E);
139263509Sdim}
140263509Sdim
141234285Sdimvoid MipsFunctionInfo::anchor() { }
142