1//===---- MipsABIInfo.cpp - Information about MIPS ABI's ------------------===//
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#include "MipsABIInfo.h"
11#include "MipsRegisterInfo.h"
12#include "llvm/ADT/StringRef.h"
13#include "llvm/ADT/StringSwitch.h"
14#include "llvm/MC/MCTargetOptions.h"
15
16using namespace llvm;
17
18namespace {
19static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3};
20
21static const MCPhysReg Mips64IntRegs[8] = {
22    Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64,
23    Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64};
24}
25
26ArrayRef<MCPhysReg> MipsABIInfo::GetByValArgRegs() const {
27  if (IsO32())
28    return makeArrayRef(O32IntRegs);
29  if (IsN32() || IsN64())
30    return makeArrayRef(Mips64IntRegs);
31  llvm_unreachable("Unhandled ABI");
32}
33
34ArrayRef<MCPhysReg> MipsABIInfo::GetVarArgRegs() const {
35  if (IsO32())
36    return makeArrayRef(O32IntRegs);
37  if (IsN32() || IsN64())
38    return makeArrayRef(Mips64IntRegs);
39  llvm_unreachable("Unhandled ABI");
40}
41
42unsigned MipsABIInfo::GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const {
43  if (IsO32())
44    return CC != CallingConv::Fast ? 16 : 0;
45  if (IsN32() || IsN64() || IsEABI())
46    return 0;
47  llvm_unreachable("Unhandled ABI");
48}
49
50MipsABIInfo MipsABIInfo::computeTargetABI(const Triple &TT, StringRef CPU,
51                                          const MCTargetOptions &Options) {
52  if (Options.getABIName().startswith("o32"))
53    return MipsABIInfo::O32();
54  else if (Options.getABIName().startswith("n32"))
55    return MipsABIInfo::N32();
56  else if (Options.getABIName().startswith("n64"))
57    return MipsABIInfo::N64();
58  else if (Options.getABIName().startswith("eabi"))
59    return MipsABIInfo::EABI();
60  else if (!Options.getABIName().empty())
61    llvm_unreachable("Unknown ABI option for MIPS");
62
63  // FIXME: This shares code with the selectMipsCPU routine that's
64  // used and not shared in a couple of other places. This needs unifying
65  // at some level.
66  if (CPU.empty() || CPU == "generic") {
67    if (TT.getArch() == Triple::mips || TT.getArch() == Triple::mipsel)
68      CPU = "mips32";
69    else
70      CPU = "mips64";
71  }
72
73  return StringSwitch<MipsABIInfo>(CPU)
74      .Case("mips1", MipsABIInfo::O32())
75      .Case("mips2", MipsABIInfo::O32())
76      .Case("mips32", MipsABIInfo::O32())
77      .Case("mips32r2", MipsABIInfo::O32())
78      .Case("mips32r3", MipsABIInfo::O32())
79      .Case("mips32r5", MipsABIInfo::O32())
80      .Case("mips32r6", MipsABIInfo::O32())
81      .Case("mips3", MipsABIInfo::N64())
82      .Case("mips4", MipsABIInfo::N64())
83      .Case("mips5", MipsABIInfo::N64())
84      .Case("mips64", MipsABIInfo::N64())
85      .Case("mips64r2", MipsABIInfo::N64())
86      .Case("mips64r3", MipsABIInfo::N64())
87      .Case("mips64r5", MipsABIInfo::N64())
88      .Case("mips64r6", MipsABIInfo::N64())
89      .Case("octeon", MipsABIInfo::N64())
90      .Default(MipsABIInfo::Unknown());
91}
92
93unsigned MipsABIInfo::GetStackPtr() const {
94  return ArePtrs64bit() ? Mips::SP_64 : Mips::SP;
95}
96
97unsigned MipsABIInfo::GetFramePtr() const {
98  return ArePtrs64bit() ? Mips::FP_64 : Mips::FP;
99}
100
101unsigned MipsABIInfo::GetBasePtr() const {
102  return ArePtrs64bit() ? Mips::S7_64 : Mips::S7;
103}
104
105unsigned MipsABIInfo::GetNullPtr() const {
106  return ArePtrs64bit() ? Mips::ZERO_64 : Mips::ZERO;
107}
108
109unsigned MipsABIInfo::GetZeroReg() const {
110  return AreGprs64bit() ? Mips::ZERO_64 : Mips::ZERO;
111}
112
113unsigned MipsABIInfo::GetPtrAdduOp() const {
114  return ArePtrs64bit() ? Mips::DADDu : Mips::ADDu;
115}
116
117unsigned MipsABIInfo::GetPtrAddiuOp() const {
118  return ArePtrs64bit() ? Mips::DADDiu : Mips::ADDiu;
119}
120
121unsigned MipsABIInfo::GetGPRMoveOp() const {
122  return ArePtrs64bit() ? Mips::OR64 : Mips::OR;
123}
124
125unsigned MipsABIInfo::GetEhDataReg(unsigned I) const {
126  static const unsigned EhDataReg[] = {
127    Mips::A0, Mips::A1, Mips::A2, Mips::A3
128  };
129  static const unsigned EhDataReg64[] = {
130    Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64
131  };
132
133  return IsN64() ? EhDataReg64[I] : EhDataReg[I];
134}
135
136