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"
13
14using namespace llvm;
15
16namespace {
17static constexpr MCPhysReg O32IntRegs[] = {Mips::A0, Mips::A1, Mips::A2,
18 Mips::A3};
19static constexpr MCPhysReg NABIIntRegs[] = {Mips::A0, Mips::A1, Mips::A2,
20 Mips::A3, Mips::T0, Mips::T1,
21 Mips::T2, Mips::T3};
22static constexpr MCPhysReg Mips64IntRegs[] = {
23 Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64,
24 Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64};
25
26struct GPR {
27 MCPhysReg Reg32;
28 MCPhysReg Reg64;
29};
30
31static constexpr GPR OABITempRegs[] = {
32 {Mips::T0, Mips::T0_64}, {Mips::T1, Mips::T1_64}, {Mips::T2, Mips::T2_64},
33 {Mips::T3, Mips::T3_64}, {Mips::T4, Mips::T4_64}, {Mips::T5, Mips::T5_64},
34 {Mips::T6, Mips::T6_64}, {Mips::T7, Mips::T7_64}, {Mips::T8, Mips::T8_64},
35 {Mips::T9, Mips::T9_64},
36};
37
38static constexpr GPR NABITempRegs[] = {
39 {Mips::T4, Mips::T4_64},
40 {Mips::T5, Mips::T5_64},
41 {Mips::T6, Mips::T6_64},
42 {Mips::T7, Mips::T7_64},
43 {Mips::NoRegister, Mips::NoRegister},
44 {Mips::NoRegister, Mips::NoRegister},
45 {Mips::NoRegister, Mips::NoRegister},
46 {Mips::NoRegister, Mips::NoRegister},
47 {Mips::T8, Mips::T8_64},
48 {Mips::T9, Mips::T9_64},
49};
50
51static constexpr GPR PABITempRegs[] = {
52 {Mips::T4, Mips::T4_64},
53 {Mips::T5, Mips::T5_64},
54 {Mips::T6, Mips::T6_64},
55 {Mips::T7, Mips::T7_64},
56 {Mips::V0, Mips::V0_64},
57 {Mips::V1, Mips::V1_64},
58 {Mips::NoRegister, Mips::NoRegister},
59 {Mips::NoRegister, Mips::NoRegister},
60 {Mips::T8, Mips::T8_64},
61 {Mips::T9, Mips::T9_64},
62};
63
64static constexpr GPR SavedRegs[] = {
65 {Mips::S0, Mips::S0_64}, {Mips::S1, Mips::S1_64}, {Mips::S2, Mips::S2_64},
66 {Mips::S3, Mips::S3_64}, {Mips::S4, Mips::S4_64}, {Mips::S5, Mips::S5_64},
67 {Mips::S6, Mips::S6_64}, {Mips::S7, Mips::S7_64},
68};
69
70static constexpr GPR ReturnRegs[] = {
71 {Mips::V0, Mips::V0_64},
72 {Mips::V1, Mips::V1_64},
73};
74
75MCRegister getReg(ArrayRef<GPR> Regs, unsigned I, bool Is64Bit) {
76 assert(I < Regs.size() && "Invalid ABI register index");
77 MCRegister Reg = Is64Bit ? Regs[I].Reg64 : Regs[I].Reg32;
78 assert(Reg && "Register name is not defined by this ABI");
79 return Reg;
80}
81} // namespace
82
84 assert(IsKnown() && "Unknown ABI");
85 if (Is64Bit)
86 return ArrayRef(Mips64IntRegs).take_front(IsO32() ? 4 : 8);
87 return IsO32() ? ArrayRef(O32IntRegs) : ArrayRef(NABIIntRegs);
88}
89
93
95 switch (ThisABI) {
96 case ABI::O32:
97 return Mips::OABIRegAltName;
98 case ABI::N32:
99 case ABI::N64:
100 return Mips::NABIRegAltName;
101 case ABI::Unknown:
102 llvm_unreachable("Unknown ABI");
103 }
104 llvm_unreachable("Unhandled ABI");
105}
106
107MCRegister MipsABIInfo::getArgReg(unsigned I, bool Is64Bit) const {
108 ArrayRef<MCPhysReg> Regs = getArgRegs(Is64Bit);
109 assert(I < Regs.size() && "Invalid argument register");
110 return Regs[I];
111}
112
113MCRegister MipsABIInfo::getTempReg(unsigned I, bool Is64Bit) const {
114 switch (getRegAltNameIndex()) {
115 case Mips::OABIRegAltName:
116 return getReg(OABITempRegs, I, Is64Bit);
117 case Mips::NABIRegAltName:
118 return getReg(NABITempRegs, I, Is64Bit);
119 case Mips::PABIRegAltName:
120 return getReg(PABITempRegs, I, Is64Bit);
121 default:
122 llvm_unreachable("Unknown register naming convention");
123 }
124}
125
126MCRegister MipsABIInfo::getSavedReg(unsigned I, bool Is64Bit) const {
127 assert(IsKnown() && "Unknown ABI");
128 return getReg(SavedRegs, I, Is64Bit);
129}
130
131MCRegister MipsABIInfo::getReturnReg(unsigned I, bool Is64Bit) const {
132 switch (ThisABI) {
133 case ABI::O32:
134 case ABI::N32:
135 case ABI::N64:
136 return getReg(ReturnRegs, I, Is64Bit);
137 case ABI::Unknown:
138 llvm_unreachable("Unknown ABI");
139 }
140 llvm_unreachable("Unhandled ABI");
141}
142
144 if (IsO32()) {
145 if (isGP64bit)
146 return ArrayRef(Mips64IntRegs);
147 else
148 return ArrayRef(O32IntRegs);
149 }
150 if (IsN32() || IsN64())
151 return ArrayRef(Mips64IntRegs);
152 llvm_unreachable("Unhandled ABI");
153}
154
156 if (IsO32())
157 return CC != CallingConv::Fast ? 16 : 0;
158 if (IsN32() || IsN64())
159 return 0;
160 llvm_unreachable("Unhandled ABI");
161}
162
164 if (ABIName.starts_with("o32"))
165 return MipsABIInfo::O32();
166 if (ABIName.starts_with("n32"))
167 return MipsABIInfo::N32();
168 if (ABIName.starts_with("n64"))
169 return MipsABIInfo::N64();
170 if (TT.isABIN32())
171 return MipsABIInfo::N32();
172 assert(ABIName.empty() && "Unknown ABI option for MIPS");
173
174 if (TT.isMIPS64())
175 return MipsABIInfo::N64();
176 return MipsABIInfo::O32();
177}
178
179unsigned MipsABIInfo::GetStackPtr() const {
180 return ArePtrs64bit() ? Mips::SP_64 : Mips::SP;
181}
182
183unsigned MipsABIInfo::GetFramePtr() const {
184 return ArePtrs64bit() ? Mips::FP_64 : Mips::FP;
185}
186
187unsigned MipsABIInfo::GetBasePtr() const { return getSavedRegPtr(7); }
188
190 return ArePtrs64bit() ? Mips::GP_64 : Mips::GP;
191}
192
193unsigned MipsABIInfo::GetNullPtr() const {
194 return ArePtrs64bit() ? Mips::ZERO_64 : Mips::ZERO;
195}
196
197unsigned MipsABIInfo::GetZeroReg() const {
198 return AreGprs64bit() ? Mips::ZERO_64 : Mips::ZERO;
199}
200
202 return ArePtrs64bit() ? Mips::DADDu : Mips::ADDu;
203}
204
206 return ArePtrs64bit() ? Mips::DADDiu : Mips::ADDiu;
207}
208
210 return ArePtrs64bit() ? Mips::DSUBu : Mips::SUBu;
211}
212
213unsigned MipsABIInfo::GetPtrAndOp() const {
214 return ArePtrs64bit() ? Mips::AND64 : Mips::AND;
215}
216
218 return ArePtrs64bit() ? Mips::OR64 : Mips::OR;
219}
220
221unsigned MipsABIInfo::GetEhDataReg(unsigned I) const {
222 assert(I < 4 && "Invalid EH data register");
223 return getArgRegPtr(I);
224}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
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
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 >