LLVM 24.0.0git
MipsABIInfo.cpp
Go to the documentation of this file.
1//===---- MipsABIInfo.cpp - Information about MIPS ABI's ------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "MipsABIInfo.h"
10#include "Mips.h"
11#include "llvm/ADT/StringRef.h"
14
15using namespace llvm;
16
17// Note: this option is defined here to be visible from libLLVMMipsAsmParser
18// and libLLVMMipsCodeGen
20EmitJalrReloc("mips-jalr-reloc", cl::Hidden,
21 cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"),
22 cl::init(true));
24 NoZeroDivCheck("mno-check-zero-division", cl::Hidden,
25 cl::desc("MIPS: Don't trap on integer division by zero."),
26 cl::init(false));
27
28namespace {
29static constexpr MCPhysReg O32IntRegs[] = {Mips::A0, Mips::A1, Mips::A2,
30 Mips::A3};
31static constexpr MCPhysReg NABIIntRegs[] = {Mips::A0, Mips::A1, Mips::A2,
32 Mips::A3, Mips::T0, Mips::T1,
33 Mips::T2, Mips::T3};
34static constexpr MCPhysReg Mips64IntRegs[] = {
35 Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64,
36 Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64};
37
38struct GPR {
39 MCPhysReg Reg32;
40 MCPhysReg Reg64;
41};
42
43static constexpr GPR OABITempRegs[] = {
44 {Mips::T0, Mips::T0_64}, {Mips::T1, Mips::T1_64}, {Mips::T2, Mips::T2_64},
45 {Mips::T3, Mips::T3_64}, {Mips::T4, Mips::T4_64}, {Mips::T5, Mips::T5_64},
46 {Mips::T6, Mips::T6_64}, {Mips::T7, Mips::T7_64}, {Mips::T8, Mips::T8_64},
47 {Mips::T9, Mips::T9_64},
48};
49
50static constexpr GPR NABITempRegs[] = {
51 {Mips::T4, Mips::T4_64},
52 {Mips::T5, Mips::T5_64},
53 {Mips::T6, Mips::T6_64},
54 {Mips::T7, Mips::T7_64},
55 {Mips::NoRegister, Mips::NoRegister},
56 {Mips::NoRegister, Mips::NoRegister},
57 {Mips::NoRegister, Mips::NoRegister},
58 {Mips::NoRegister, Mips::NoRegister},
59 {Mips::T8, Mips::T8_64},
60 {Mips::T9, Mips::T9_64},
61};
62
63static constexpr GPR PABITempRegs[] = {
64 {Mips::T4, Mips::T4_64},
65 {Mips::T5, Mips::T5_64},
66 {Mips::T6, Mips::T6_64},
67 {Mips::T7, Mips::T7_64},
68 {Mips::V0, Mips::V0_64},
69 {Mips::V1, Mips::V1_64},
70 {Mips::NoRegister, Mips::NoRegister},
71 {Mips::NoRegister, Mips::NoRegister},
72 {Mips::T8, Mips::T8_64},
73 {Mips::T9, Mips::T9_64},
74};
75
76static constexpr GPR SavedRegs[] = {
77 {Mips::S0, Mips::S0_64}, {Mips::S1, Mips::S1_64}, {Mips::S2, Mips::S2_64},
78 {Mips::S3, Mips::S3_64}, {Mips::S4, Mips::S4_64}, {Mips::S5, Mips::S5_64},
79 {Mips::S6, Mips::S6_64}, {Mips::S7, Mips::S7_64},
80};
81
82static constexpr GPR ReturnRegs[] = {
83 {Mips::V0, Mips::V0_64},
84 {Mips::V1, Mips::V1_64},
85};
86
87MCRegister getReg(ArrayRef<GPR> Regs, unsigned I, bool Is64Bit) {
88 assert(I < Regs.size() && "Invalid ABI register index");
89 MCRegister Reg = Is64Bit ? Regs[I].Reg64 : Regs[I].Reg32;
90 assert(Reg && "Register name is not defined by this ABI");
91 return Reg;
92}
93} // namespace
94
96 assert(IsKnown() && "Unknown ABI");
97 if (Is64Bit)
98 return ArrayRef(Mips64IntRegs).take_front(IsO32() ? 4 : 8);
99 return IsO32() ? ArrayRef(O32IntRegs) : ArrayRef(NABIIntRegs);
100}
101
105
107 switch (ThisABI) {
108 case ABI::O32:
109 return Mips::OABIRegAltName;
110 case ABI::N32:
111 case ABI::N64:
112 return Mips::NABIRegAltName;
113 case ABI::Unknown:
114 llvm_unreachable("Unknown ABI");
115 }
116 llvm_unreachable("Unhandled ABI");
117}
118
119MCRegister MipsABIInfo::getArgReg(unsigned I, bool Is64Bit) const {
120 ArrayRef<MCPhysReg> Regs = getArgRegs(Is64Bit);
121 assert(I < Regs.size() && "Invalid argument register");
122 return Regs[I];
123}
124
125MCRegister MipsABIInfo::getTempReg(unsigned I, bool Is64Bit) const {
126 switch (getRegAltNameIndex()) {
127 case Mips::OABIRegAltName:
128 return getReg(OABITempRegs, I, Is64Bit);
129 case Mips::NABIRegAltName:
130 return getReg(NABITempRegs, I, Is64Bit);
131 case Mips::PABIRegAltName:
132 return getReg(PABITempRegs, I, Is64Bit);
133 default:
134 llvm_unreachable("Unknown register naming convention");
135 }
136}
137
138MCRegister MipsABIInfo::getSavedReg(unsigned I, bool Is64Bit) const {
139 assert(IsKnown() && "Unknown ABI");
140 return getReg(SavedRegs, I, Is64Bit);
141}
142
143MCRegister MipsABIInfo::getReturnReg(unsigned I, bool Is64Bit) const {
144 switch (ThisABI) {
145 case ABI::O32:
146 case ABI::N32:
147 case ABI::N64:
148 return getReg(ReturnRegs, I, Is64Bit);
149 case ABI::Unknown:
150 llvm_unreachable("Unknown ABI");
151 }
152 llvm_unreachable("Unhandled ABI");
153}
154
156 if (IsO32()) {
157 if (isGP64bit)
158 return ArrayRef(Mips64IntRegs);
159 else
160 return ArrayRef(O32IntRegs);
161 }
162 if (IsN32() || IsN64())
163 return ArrayRef(Mips64IntRegs);
164 llvm_unreachable("Unhandled ABI");
165}
166
168 if (IsO32())
169 return CC != CallingConv::Fast ? 16 : 0;
170 if (IsN32() || IsN64())
171 return 0;
172 llvm_unreachable("Unhandled ABI");
173}
174
176 if (ABIName.starts_with("o32"))
177 return MipsABIInfo::O32();
178 if (ABIName.starts_with("n32"))
179 return MipsABIInfo::N32();
180 if (ABIName.starts_with("n64"))
181 return MipsABIInfo::N64();
182 if (TT.isABIN32())
183 return MipsABIInfo::N32();
184 assert(ABIName.empty() && "Unknown ABI option for MIPS");
185
186 if (TT.isMIPS64())
187 return MipsABIInfo::N64();
188 return MipsABIInfo::O32();
189}
190
191unsigned MipsABIInfo::GetStackPtr() const {
192 return ArePtrs64bit() ? Mips::SP_64 : Mips::SP;
193}
194
195unsigned MipsABIInfo::GetFramePtr() const {
196 return ArePtrs64bit() ? Mips::FP_64 : Mips::FP;
197}
198
199unsigned MipsABIInfo::GetBasePtr() const { return getSavedRegPtr(7); }
200
202 return ArePtrs64bit() ? Mips::GP_64 : Mips::GP;
203}
204
205unsigned MipsABIInfo::GetNullPtr() const {
206 return ArePtrs64bit() ? Mips::ZERO_64 : Mips::ZERO;
207}
208
209unsigned MipsABIInfo::GetZeroReg() const {
210 return AreGprs64bit() ? Mips::ZERO_64 : Mips::ZERO;
211}
212
214 return ArePtrs64bit() ? Mips::DADDu : Mips::ADDu;
215}
216
218 return ArePtrs64bit() ? Mips::DADDiu : Mips::ADDiu;
219}
220
222 return ArePtrs64bit() ? Mips::DSUBu : Mips::SUBu;
223}
224
225unsigned MipsABIInfo::GetPtrAndOp() const {
226 return ArePtrs64bit() ? Mips::AND64 : Mips::AND;
227}
228
230 return ArePtrs64bit() ? Mips::OR64 : Mips::OR;
231}
232
233unsigned MipsABIInfo::GetEhDataReg(unsigned I) const {
234 assert(I < 4 && "Invalid EH data register");
235 return getArgRegPtr(I);
236}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
cl::opt< bool > EmitJalrReloc("mips-jalr-reloc", cl::Hidden, cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"), cl::init(true))
cl::opt< bool > NoZeroDivCheck("mno-check-zero-division", cl::Hidden, cl::desc("MIPS: Don't trap on integer division by zero."), cl::init(false))
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
bool AreGprs64bit() const
bool IsN64() const
Definition MipsABIInfo.h:41
unsigned GetGlobalPtr() const
static MipsABIInfo O32()
Definition MipsABIInfo.h:33
MipsABIInfo(ABI ThisABI)
Definition MipsABIInfo.h:30
unsigned GetEhDataReg(unsigned I) const
bool ArePtrs64bit() const
unsigned GetGPRMoveOp() const
MCRegister getArgReg(unsigned I, bool Is64Bit) const
ABI register accessors default to the ABI's GPR width.
unsigned GetStackPtr() const
static MipsABIInfo N32()
Definition MipsABIInfo.h:34
unsigned GetZeroReg() const
unsigned GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const
Obtain the size of the area allocated by the callee for arguments.
static MipsABIInfo N64()
Definition MipsABIInfo.h:35
unsigned GetPtrAddiuOp() const
unsigned GetPtrAndOp() const
unsigned GetFramePtr() const
unsigned getRegAltNameIndex() const
Register naming convention for this ABI.
static MipsABIInfo computeTargetABI(const Triple &TT, StringRef ABIName)
ArrayRef< MCPhysReg > GetByValArgRegs() const
The registers to use for byval arguments.
unsigned GetNullPtr() const
ArrayRef< MCPhysReg > getVarArgRegs(bool isGP64bit) const
The registers to use for the variable argument list.
unsigned GetPtrAdduOp() const
bool IsKnown() const
Definition MipsABIInfo.h:38
bool IsN32() const
Definition MipsABIInfo.h:40
MCRegister getReturnReg(unsigned I, bool Is64Bit) const
Integer return-value registers.
MCRegister getSavedReg(unsigned I, bool Is64Bit) const
unsigned GetBasePtr() const
unsigned GetPtrSubuOp() const
MCRegister getSavedRegPtr(unsigned I) const
Definition MipsABIInfo.h:72
bool IsO32() const
Definition MipsABIInfo.h:39
MCRegister getTempReg(unsigned I, bool Is64Bit) const
I is the suffix in tI (NABI has t0-t3 and t8-t9).
ArrayRef< MCPhysReg > getArgRegs(bool Is64Bit) const
Integer argument registers in calling-convention order.
MCRegister getArgRegPtr(unsigned I) const
Definition MipsABIInfo.h:57
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
ArrayRef(const T &OneElt) -> ArrayRef< T >