xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===---- MipsABIInfo.cpp - Information about MIPS ABI's ------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "MipsABIInfo.h"
105f757f3fSDimitry Andric #include "Mips.h"
110b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
12*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/LowLevelType.h"
130b57cec5SDimitry Andric #include "llvm/MC/MCTargetOptions.h"
14480093f4SDimitry Andric #include "llvm/Support/CommandLine.h"
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric using namespace llvm;
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric // Note: this option is defined here to be visible from libLLVMMipsAsmParser
190b57cec5SDimitry Andric //       and libLLVMMipsCodeGen
200b57cec5SDimitry Andric cl::opt<bool>
210b57cec5SDimitry Andric EmitJalrReloc("mips-jalr-reloc", cl::Hidden,
220b57cec5SDimitry Andric               cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"),
230b57cec5SDimitry Andric               cl::init(true));
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric namespace {
260b57cec5SDimitry Andric static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3};
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric static const MCPhysReg Mips64IntRegs[8] = {
290b57cec5SDimitry Andric     Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64,
300b57cec5SDimitry Andric     Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64};
310b57cec5SDimitry Andric }
320b57cec5SDimitry Andric 
GetByValArgRegs() const330b57cec5SDimitry Andric ArrayRef<MCPhysReg> MipsABIInfo::GetByValArgRegs() const {
340b57cec5SDimitry Andric   if (IsO32())
35bdd1243dSDimitry Andric     return ArrayRef(O32IntRegs);
360b57cec5SDimitry Andric   if (IsN32() || IsN64())
37bdd1243dSDimitry Andric     return ArrayRef(Mips64IntRegs);
380b57cec5SDimitry Andric   llvm_unreachable("Unhandled ABI");
390b57cec5SDimitry Andric }
400b57cec5SDimitry Andric 
GetVarArgRegs() const410b57cec5SDimitry Andric ArrayRef<MCPhysReg> MipsABIInfo::GetVarArgRegs() const {
420b57cec5SDimitry Andric   if (IsO32())
43bdd1243dSDimitry Andric     return ArrayRef(O32IntRegs);
440b57cec5SDimitry Andric   if (IsN32() || IsN64())
45bdd1243dSDimitry Andric     return ArrayRef(Mips64IntRegs);
460b57cec5SDimitry Andric   llvm_unreachable("Unhandled ABI");
470b57cec5SDimitry Andric }
480b57cec5SDimitry Andric 
GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const490b57cec5SDimitry Andric unsigned MipsABIInfo::GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const {
500b57cec5SDimitry Andric   if (IsO32())
510b57cec5SDimitry Andric     return CC != CallingConv::Fast ? 16 : 0;
520b57cec5SDimitry Andric   if (IsN32() || IsN64())
530b57cec5SDimitry Andric     return 0;
540b57cec5SDimitry Andric   llvm_unreachable("Unhandled ABI");
550b57cec5SDimitry Andric }
560b57cec5SDimitry Andric 
computeTargetABI(const Triple & TT,StringRef CPU,const MCTargetOptions & Options)570b57cec5SDimitry Andric MipsABIInfo MipsABIInfo::computeTargetABI(const Triple &TT, StringRef CPU,
580b57cec5SDimitry Andric                                           const MCTargetOptions &Options) {
595f757f3fSDimitry Andric   if (Options.getABIName().starts_with("o32"))
600b57cec5SDimitry Andric     return MipsABIInfo::O32();
615f757f3fSDimitry Andric   if (Options.getABIName().starts_with("n32"))
620b57cec5SDimitry Andric     return MipsABIInfo::N32();
635f757f3fSDimitry Andric   if (Options.getABIName().starts_with("n64"))
640b57cec5SDimitry Andric     return MipsABIInfo::N64();
650b57cec5SDimitry Andric   if (TT.getEnvironment() == llvm::Triple::GNUABIN32)
660b57cec5SDimitry Andric     return MipsABIInfo::N32();
670b57cec5SDimitry Andric   assert(Options.getABIName().empty() && "Unknown ABI option for MIPS");
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   if (TT.isMIPS64())
700b57cec5SDimitry Andric     return MipsABIInfo::N64();
710b57cec5SDimitry Andric   return MipsABIInfo::O32();
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric 
GetStackPtr() const740b57cec5SDimitry Andric unsigned MipsABIInfo::GetStackPtr() const {
750b57cec5SDimitry Andric   return ArePtrs64bit() ? Mips::SP_64 : Mips::SP;
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric 
GetFramePtr() const780b57cec5SDimitry Andric unsigned MipsABIInfo::GetFramePtr() const {
790b57cec5SDimitry Andric   return ArePtrs64bit() ? Mips::FP_64 : Mips::FP;
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric 
GetBasePtr() const820b57cec5SDimitry Andric unsigned MipsABIInfo::GetBasePtr() const {
830b57cec5SDimitry Andric   return ArePtrs64bit() ? Mips::S7_64 : Mips::S7;
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric 
GetGlobalPtr() const860b57cec5SDimitry Andric unsigned MipsABIInfo::GetGlobalPtr() const {
870b57cec5SDimitry Andric   return ArePtrs64bit() ? Mips::GP_64 : Mips::GP;
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric 
GetNullPtr() const900b57cec5SDimitry Andric unsigned MipsABIInfo::GetNullPtr() const {
910b57cec5SDimitry Andric   return ArePtrs64bit() ? Mips::ZERO_64 : Mips::ZERO;
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric 
GetZeroReg() const940b57cec5SDimitry Andric unsigned MipsABIInfo::GetZeroReg() const {
950b57cec5SDimitry Andric   return AreGprs64bit() ? Mips::ZERO_64 : Mips::ZERO;
960b57cec5SDimitry Andric }
970b57cec5SDimitry Andric 
GetPtrAdduOp() const980b57cec5SDimitry Andric unsigned MipsABIInfo::GetPtrAdduOp() const {
990b57cec5SDimitry Andric   return ArePtrs64bit() ? Mips::DADDu : Mips::ADDu;
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
GetPtrAddiuOp() const1020b57cec5SDimitry Andric unsigned MipsABIInfo::GetPtrAddiuOp() const {
1030b57cec5SDimitry Andric   return ArePtrs64bit() ? Mips::DADDiu : Mips::ADDiu;
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
GetPtrSubuOp() const1060b57cec5SDimitry Andric unsigned MipsABIInfo::GetPtrSubuOp() const {
1070b57cec5SDimitry Andric   return ArePtrs64bit() ? Mips::DSUBu : Mips::SUBu;
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric 
GetPtrAndOp() const1100b57cec5SDimitry Andric unsigned MipsABIInfo::GetPtrAndOp() const {
1110b57cec5SDimitry Andric   return ArePtrs64bit() ? Mips::AND64 : Mips::AND;
1120b57cec5SDimitry Andric }
1130b57cec5SDimitry Andric 
GetGPRMoveOp() const1140b57cec5SDimitry Andric unsigned MipsABIInfo::GetGPRMoveOp() const {
1150b57cec5SDimitry Andric   return ArePtrs64bit() ? Mips::OR64 : Mips::OR;
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
GetEhDataReg(unsigned I) const1180b57cec5SDimitry Andric unsigned MipsABIInfo::GetEhDataReg(unsigned I) const {
1190b57cec5SDimitry Andric   static const unsigned EhDataReg[] = {
1200b57cec5SDimitry Andric     Mips::A0, Mips::A1, Mips::A2, Mips::A3
1210b57cec5SDimitry Andric   };
1220b57cec5SDimitry Andric   static const unsigned EhDataReg64[] = {
1230b57cec5SDimitry Andric     Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64
1240b57cec5SDimitry Andric   };
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric   return IsN64() ? EhDataReg64[I] : EhDataReg[I];
1270b57cec5SDimitry Andric }
1280b57cec5SDimitry Andric 
129