1*9880d681SAndroid Build Coastguard Worker //===---- MipsABIInfo.cpp - Information about MIPS ABI's ------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "MipsABIInfo.h"
11*9880d681SAndroid Build Coastguard Worker #include "MipsRegisterInfo.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringRef.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringSwitch.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCTargetOptions.h"
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker using namespace llvm;
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker namespace {
19*9880d681SAndroid Build Coastguard Worker static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3};
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker static const MCPhysReg Mips64IntRegs[8] = {
22*9880d681SAndroid Build Coastguard Worker Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64,
23*9880d681SAndroid Build Coastguard Worker Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64};
24*9880d681SAndroid Build Coastguard Worker }
25*9880d681SAndroid Build Coastguard Worker
GetByValArgRegs() const26*9880d681SAndroid Build Coastguard Worker ArrayRef<MCPhysReg> MipsABIInfo::GetByValArgRegs() const {
27*9880d681SAndroid Build Coastguard Worker if (IsO32())
28*9880d681SAndroid Build Coastguard Worker return makeArrayRef(O32IntRegs);
29*9880d681SAndroid Build Coastguard Worker if (IsN32() || IsN64())
30*9880d681SAndroid Build Coastguard Worker return makeArrayRef(Mips64IntRegs);
31*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unhandled ABI");
32*9880d681SAndroid Build Coastguard Worker }
33*9880d681SAndroid Build Coastguard Worker
GetVarArgRegs() const34*9880d681SAndroid Build Coastguard Worker ArrayRef<MCPhysReg> MipsABIInfo::GetVarArgRegs() const {
35*9880d681SAndroid Build Coastguard Worker if (IsO32())
36*9880d681SAndroid Build Coastguard Worker return makeArrayRef(O32IntRegs);
37*9880d681SAndroid Build Coastguard Worker if (IsN32() || IsN64())
38*9880d681SAndroid Build Coastguard Worker return makeArrayRef(Mips64IntRegs);
39*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unhandled ABI");
40*9880d681SAndroid Build Coastguard Worker }
41*9880d681SAndroid Build Coastguard Worker
GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const42*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const {
43*9880d681SAndroid Build Coastguard Worker if (IsO32())
44*9880d681SAndroid Build Coastguard Worker return CC != CallingConv::Fast ? 16 : 0;
45*9880d681SAndroid Build Coastguard Worker if (IsN32() || IsN64())
46*9880d681SAndroid Build Coastguard Worker return 0;
47*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unhandled ABI");
48*9880d681SAndroid Build Coastguard Worker }
49*9880d681SAndroid Build Coastguard Worker
computeTargetABI(const Triple & TT,StringRef CPU,const MCTargetOptions & Options)50*9880d681SAndroid Build Coastguard Worker MipsABIInfo MipsABIInfo::computeTargetABI(const Triple &TT, StringRef CPU,
51*9880d681SAndroid Build Coastguard Worker const MCTargetOptions &Options) {
52*9880d681SAndroid Build Coastguard Worker if (Options.getABIName().startswith("o32"))
53*9880d681SAndroid Build Coastguard Worker return MipsABIInfo::O32();
54*9880d681SAndroid Build Coastguard Worker else if (Options.getABIName().startswith("n32"))
55*9880d681SAndroid Build Coastguard Worker return MipsABIInfo::N32();
56*9880d681SAndroid Build Coastguard Worker else if (Options.getABIName().startswith("n64"))
57*9880d681SAndroid Build Coastguard Worker return MipsABIInfo::N64();
58*9880d681SAndroid Build Coastguard Worker else if (!Options.getABIName().empty())
59*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unknown ABI option for MIPS");
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker if (TT.getArch() == Triple::mips64 || TT.getArch() == Triple::mips64el)
62*9880d681SAndroid Build Coastguard Worker return MipsABIInfo::N64();
63*9880d681SAndroid Build Coastguard Worker return MipsABIInfo::O32();
64*9880d681SAndroid Build Coastguard Worker }
65*9880d681SAndroid Build Coastguard Worker
GetStackPtr() const66*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetStackPtr() const {
67*9880d681SAndroid Build Coastguard Worker return ArePtrs64bit() ? Mips::SP_64 : Mips::SP;
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker
GetFramePtr() const70*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetFramePtr() const {
71*9880d681SAndroid Build Coastguard Worker return ArePtrs64bit() ? Mips::FP_64 : Mips::FP;
72*9880d681SAndroid Build Coastguard Worker }
73*9880d681SAndroid Build Coastguard Worker
GetBasePtr() const74*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetBasePtr() const {
75*9880d681SAndroid Build Coastguard Worker return ArePtrs64bit() ? Mips::S7_64 : Mips::S7;
76*9880d681SAndroid Build Coastguard Worker }
77*9880d681SAndroid Build Coastguard Worker
GetGlobalPtr() const78*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetGlobalPtr() const {
79*9880d681SAndroid Build Coastguard Worker return ArePtrs64bit() ? Mips::GP_64 : Mips::GP;
80*9880d681SAndroid Build Coastguard Worker }
81*9880d681SAndroid Build Coastguard Worker
GetNullPtr() const82*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetNullPtr() const {
83*9880d681SAndroid Build Coastguard Worker return ArePtrs64bit() ? Mips::ZERO_64 : Mips::ZERO;
84*9880d681SAndroid Build Coastguard Worker }
85*9880d681SAndroid Build Coastguard Worker
GetZeroReg() const86*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetZeroReg() const {
87*9880d681SAndroid Build Coastguard Worker return AreGprs64bit() ? Mips::ZERO_64 : Mips::ZERO;
88*9880d681SAndroid Build Coastguard Worker }
89*9880d681SAndroid Build Coastguard Worker
GetPtrAdduOp() const90*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetPtrAdduOp() const {
91*9880d681SAndroid Build Coastguard Worker return ArePtrs64bit() ? Mips::DADDu : Mips::ADDu;
92*9880d681SAndroid Build Coastguard Worker }
93*9880d681SAndroid Build Coastguard Worker
GetPtrAddiuOp() const94*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetPtrAddiuOp() const {
95*9880d681SAndroid Build Coastguard Worker return ArePtrs64bit() ? Mips::DADDiu : Mips::ADDiu;
96*9880d681SAndroid Build Coastguard Worker }
97*9880d681SAndroid Build Coastguard Worker
GetPtrSubuOp() const98*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetPtrSubuOp() const {
99*9880d681SAndroid Build Coastguard Worker return ArePtrs64bit() ? Mips::DSUBu : Mips::SUBu;
100*9880d681SAndroid Build Coastguard Worker }
101*9880d681SAndroid Build Coastguard Worker
GetPtrAndOp() const102*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetPtrAndOp() const {
103*9880d681SAndroid Build Coastguard Worker return ArePtrs64bit() ? Mips::AND64 : Mips::AND;
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker
GetGPRMoveOp() const106*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetGPRMoveOp() const {
107*9880d681SAndroid Build Coastguard Worker return ArePtrs64bit() ? Mips::OR64 : Mips::OR;
108*9880d681SAndroid Build Coastguard Worker }
109*9880d681SAndroid Build Coastguard Worker
GetEhDataReg(unsigned I) const110*9880d681SAndroid Build Coastguard Worker unsigned MipsABIInfo::GetEhDataReg(unsigned I) const {
111*9880d681SAndroid Build Coastguard Worker static const unsigned EhDataReg[] = {
112*9880d681SAndroid Build Coastguard Worker Mips::A0, Mips::A1, Mips::A2, Mips::A3
113*9880d681SAndroid Build Coastguard Worker };
114*9880d681SAndroid Build Coastguard Worker static const unsigned EhDataReg64[] = {
115*9880d681SAndroid Build Coastguard Worker Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64
116*9880d681SAndroid Build Coastguard Worker };
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker return IsN64() ? EhDataReg64[I] : EhDataReg[I];
119*9880d681SAndroid Build Coastguard Worker }
120*9880d681SAndroid Build Coastguard Worker
121