1277323Sdim//===---- MipsABIInfo.cpp - Information about MIPS ABI's ------------------===// 2277323Sdim// 3277323Sdim// The LLVM Compiler Infrastructure 4277323Sdim// 5277323Sdim// This file is distributed under the University of Illinois Open Source 6277323Sdim// License. See LICENSE.TXT for details. 7277323Sdim// 8277323Sdim//===----------------------------------------------------------------------===// 9277323Sdim 10277323Sdim#include "MipsABIInfo.h" 11277323Sdim#include "MipsRegisterInfo.h" 12288943Sdim#include "llvm/ADT/StringRef.h" 13288943Sdim#include "llvm/ADT/StringSwitch.h" 14288943Sdim#include "llvm/MC/MCTargetOptions.h" 15277323Sdim 16277323Sdimusing namespace llvm; 17277323Sdim 18277323Sdimnamespace { 19277323Sdimstatic const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3}; 20277323Sdim 21277323Sdimstatic const MCPhysReg Mips64IntRegs[8] = { 22277323Sdim Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64, 23277323Sdim Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64}; 24277323Sdim} 25277323Sdim 26296417SdimArrayRef<MCPhysReg> MipsABIInfo::GetByValArgRegs() const { 27277323Sdim if (IsO32()) 28277323Sdim return makeArrayRef(O32IntRegs); 29277323Sdim if (IsN32() || IsN64()) 30277323Sdim return makeArrayRef(Mips64IntRegs); 31277323Sdim llvm_unreachable("Unhandled ABI"); 32277323Sdim} 33277323Sdim 34296417SdimArrayRef<MCPhysReg> MipsABIInfo::GetVarArgRegs() const { 35277323Sdim if (IsO32()) 36277323Sdim return makeArrayRef(O32IntRegs); 37277323Sdim if (IsN32() || IsN64()) 38277323Sdim return makeArrayRef(Mips64IntRegs); 39277323Sdim llvm_unreachable("Unhandled ABI"); 40277323Sdim} 41277323Sdim 42277323Sdimunsigned MipsABIInfo::GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const { 43277323Sdim if (IsO32()) 44277323Sdim return CC != CallingConv::Fast ? 16 : 0; 45277323Sdim if (IsN32() || IsN64() || IsEABI()) 46277323Sdim return 0; 47277323Sdim llvm_unreachable("Unhandled ABI"); 48277323Sdim} 49288943Sdim 50288943SdimMipsABIInfo MipsABIInfo::computeTargetABI(const Triple &TT, StringRef CPU, 51288943Sdim const MCTargetOptions &Options) { 52288943Sdim if (Options.getABIName().startswith("o32")) 53288943Sdim return MipsABIInfo::O32(); 54288943Sdim else if (Options.getABIName().startswith("n32")) 55288943Sdim return MipsABIInfo::N32(); 56288943Sdim else if (Options.getABIName().startswith("n64")) 57288943Sdim return MipsABIInfo::N64(); 58288943Sdim else if (Options.getABIName().startswith("eabi")) 59288943Sdim return MipsABIInfo::EABI(); 60288943Sdim else if (!Options.getABIName().empty()) 61288943Sdim llvm_unreachable("Unknown ABI option for MIPS"); 62288943Sdim 63288943Sdim // FIXME: This shares code with the selectMipsCPU routine that's 64288943Sdim // used and not shared in a couple of other places. This needs unifying 65288943Sdim // at some level. 66288943Sdim if (CPU.empty() || CPU == "generic") { 67288943Sdim if (TT.getArch() == Triple::mips || TT.getArch() == Triple::mipsel) 68288943Sdim CPU = "mips32"; 69288943Sdim else 70288943Sdim CPU = "mips64"; 71288943Sdim } 72288943Sdim 73288943Sdim return StringSwitch<MipsABIInfo>(CPU) 74288943Sdim .Case("mips1", MipsABIInfo::O32()) 75288943Sdim .Case("mips2", MipsABIInfo::O32()) 76288943Sdim .Case("mips32", MipsABIInfo::O32()) 77288943Sdim .Case("mips32r2", MipsABIInfo::O32()) 78288943Sdim .Case("mips32r3", MipsABIInfo::O32()) 79288943Sdim .Case("mips32r5", MipsABIInfo::O32()) 80288943Sdim .Case("mips32r6", MipsABIInfo::O32()) 81288943Sdim .Case("mips3", MipsABIInfo::N64()) 82288943Sdim .Case("mips4", MipsABIInfo::N64()) 83288943Sdim .Case("mips5", MipsABIInfo::N64()) 84288943Sdim .Case("mips64", MipsABIInfo::N64()) 85288943Sdim .Case("mips64r2", MipsABIInfo::N64()) 86288943Sdim .Case("mips64r3", MipsABIInfo::N64()) 87288943Sdim .Case("mips64r5", MipsABIInfo::N64()) 88288943Sdim .Case("mips64r6", MipsABIInfo::N64()) 89288943Sdim .Case("octeon", MipsABIInfo::N64()) 90288943Sdim .Default(MipsABIInfo::Unknown()); 91288943Sdim} 92288943Sdim 93288943Sdimunsigned MipsABIInfo::GetStackPtr() const { 94288943Sdim return ArePtrs64bit() ? Mips::SP_64 : Mips::SP; 95288943Sdim} 96288943Sdim 97288943Sdimunsigned MipsABIInfo::GetFramePtr() const { 98288943Sdim return ArePtrs64bit() ? Mips::FP_64 : Mips::FP; 99288943Sdim} 100288943Sdim 101288943Sdimunsigned MipsABIInfo::GetBasePtr() const { 102288943Sdim return ArePtrs64bit() ? Mips::S7_64 : Mips::S7; 103288943Sdim} 104288943Sdim 105288943Sdimunsigned MipsABIInfo::GetNullPtr() const { 106288943Sdim return ArePtrs64bit() ? Mips::ZERO_64 : Mips::ZERO; 107288943Sdim} 108288943Sdim 109296417Sdimunsigned MipsABIInfo::GetZeroReg() const { 110296417Sdim return AreGprs64bit() ? Mips::ZERO_64 : Mips::ZERO; 111296417Sdim} 112296417Sdim 113288943Sdimunsigned MipsABIInfo::GetPtrAdduOp() const { 114288943Sdim return ArePtrs64bit() ? Mips::DADDu : Mips::ADDu; 115288943Sdim} 116288943Sdim 117288943Sdimunsigned MipsABIInfo::GetPtrAddiuOp() const { 118288943Sdim return ArePtrs64bit() ? Mips::DADDiu : Mips::ADDiu; 119288943Sdim} 120288943Sdim 121296417Sdimunsigned MipsABIInfo::GetGPRMoveOp() const { 122296417Sdim return ArePtrs64bit() ? Mips::OR64 : Mips::OR; 123296417Sdim} 124296417Sdim 125288943Sdimunsigned MipsABIInfo::GetEhDataReg(unsigned I) const { 126288943Sdim static const unsigned EhDataReg[] = { 127288943Sdim Mips::A0, Mips::A1, Mips::A2, Mips::A3 128288943Sdim }; 129288943Sdim static const unsigned EhDataReg64[] = { 130288943Sdim Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64 131288943Sdim }; 132288943Sdim 133288943Sdim return IsN64() ? EhDataReg64[I] : EhDataReg[I]; 134288943Sdim} 135288943Sdim 136