LLVM 23.0.0git
RISCVCallingConv.cpp
Go to the documentation of this file.
1//===-- RISCVCallingConv.cpp - RISC-V Custom CC Routines ------------------===//
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// This file contains the custom routines for the RISC-V Calling Convention.
10//
11//===----------------------------------------------------------------------===//
12
13#include "RISCVCallingConv.h"
14#include "RISCVSubtarget.h"
15#include "llvm/IR/DataLayout.h"
16#include "llvm/IR/Module.h"
17#include "llvm/MC/MCRegister.h"
18
19using namespace llvm;
20
21// This does not have the regular `CCAssignFn` signature, it has an extra
22// `bool IsRet` parameter.
23static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT LocVT,
25 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,
26 CCState &State, bool IsRet);
27
28/// Used for assigning arguments with CallingConvention::GHC
30
31/// Used for assigning arguments with CallingConvention::Fast
33
34bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT,
35 CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
36 Type *OrigTy, CCState &State) {
37 if (State.getCallingConv() == CallingConv::GHC)
38 return CC_RISCV_GHC(ValNo, ValVT, LocVT, LocInfo, ArgFlags, OrigTy, State);
39
40 if (State.getCallingConv() == CallingConv::Fast)
41 return CC_RISCV_FastCC(ValNo, ValVT, LocVT, LocInfo, ArgFlags, OrigTy,
42 State);
43
44 // For all other cases, use the standard calling convention
45 return CC_RISCV_Impl(ValNo, ValVT, LocVT, LocInfo, ArgFlags, OrigTy, State,
46 /*IsRet=*/false);
47}
48
49bool llvm::RetCC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT,
50 CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
51 Type *OrigTy, CCState &State) {
52 // Always use the standard calling convention.
53 return CC_RISCV_Impl(ValNo, ValVT, LocVT, LocInfo, ArgFlags, OrigTy, State,
54 /*IsRet=*/true);
55}
56
57// Calling Convention Implementation.
58// The expectations for frontend ABI lowering vary from target to target.
59// Ideally, an LLVM frontend would be able to avoid worrying about many ABI
60// details, but this is a longer term goal. For now, we simply try to keep the
61// role of the frontend as simple and well-defined as possible. The rules can
62// be summarised as:
63// * Never split up large scalar arguments. We handle them here.
64// * If a hardfloat calling convention is being used, and the struct may be
65// passed in a pair of registers (fp+fp, int+fp), and both registers are
66// available, then pass as two separate arguments. If either the GPRs or FPRs
67// are exhausted, then pass according to the rule below.
68// * If a struct could never be passed in registers or directly in a stack
69// slot (as it is larger than 2*XLEN and the floating point rules don't
70// apply), then pass it using a pointer with the byval attribute.
71// * If a struct is less than 2*XLEN, then coerce to either a two-element
72// word-sized array or a 2*XLEN scalar (depending on alignment).
73// * The frontend can determine whether a struct is returned by reference or
74// not based on its size and fields. If it will be returned by reference, the
75// frontend must modify the prototype so a pointer with the sret annotation is
76// passed as the first argument. This is not necessary for large scalar
77// returns.
78// * Struct return values and varargs should be coerced to structs containing
79// register-size fields in the same situations they would be for fixed
80// arguments.
81
82static const MCPhysReg ArgFPR16s[] = {RISCV::F10_H, RISCV::F11_H, RISCV::F12_H,
83 RISCV::F13_H, RISCV::F14_H, RISCV::F15_H,
84 RISCV::F16_H, RISCV::F17_H};
85static const MCPhysReg ArgFPR32s[] = {RISCV::F10_F, RISCV::F11_F, RISCV::F12_F,
86 RISCV::F13_F, RISCV::F14_F, RISCV::F15_F,
87 RISCV::F16_F, RISCV::F17_F};
88static const MCPhysReg ArgFPR64s[] = {RISCV::F10_D, RISCV::F11_D, RISCV::F12_D,
89 RISCV::F13_D, RISCV::F14_D, RISCV::F15_D,
90 RISCV::F16_D, RISCV::F17_D};
91// This is an interim calling convention and it may be changed in the future.
92static const MCPhysReg ArgVRs[] = {
93 RISCV::V8, RISCV::V9, RISCV::V10, RISCV::V11, RISCV::V12, RISCV::V13,
94 RISCV::V14, RISCV::V15, RISCV::V16, RISCV::V17, RISCV::V18, RISCV::V19,
95 RISCV::V20, RISCV::V21, RISCV::V22, RISCV::V23};
96static const MCPhysReg ArgVRM2s[] = {RISCV::V8M2, RISCV::V10M2, RISCV::V12M2,
97 RISCV::V14M2, RISCV::V16M2, RISCV::V18M2,
98 RISCV::V20M2, RISCV::V22M2};
99static const MCPhysReg ArgVRM4s[] = {RISCV::V8M4, RISCV::V12M4, RISCV::V16M4,
100 RISCV::V20M4};
101static const MCPhysReg ArgVRM8s[] = {RISCV::V8M8, RISCV::V16M8};
102static const MCPhysReg ArgVRN2M1s[] = {
103 RISCV::V8_V9, RISCV::V9_V10, RISCV::V10_V11, RISCV::V11_V12,
104 RISCV::V12_V13, RISCV::V13_V14, RISCV::V14_V15, RISCV::V15_V16,
105 RISCV::V16_V17, RISCV::V17_V18, RISCV::V18_V19, RISCV::V19_V20,
106 RISCV::V20_V21, RISCV::V21_V22, RISCV::V22_V23};
107static const MCPhysReg ArgVRN3M1s[] = {
108 RISCV::V8_V9_V10, RISCV::V9_V10_V11, RISCV::V10_V11_V12,
109 RISCV::V11_V12_V13, RISCV::V12_V13_V14, RISCV::V13_V14_V15,
110 RISCV::V14_V15_V16, RISCV::V15_V16_V17, RISCV::V16_V17_V18,
111 RISCV::V17_V18_V19, RISCV::V18_V19_V20, RISCV::V19_V20_V21,
112 RISCV::V20_V21_V22, RISCV::V21_V22_V23};
113static const MCPhysReg ArgVRN4M1s[] = {
114 RISCV::V8_V9_V10_V11, RISCV::V9_V10_V11_V12, RISCV::V10_V11_V12_V13,
115 RISCV::V11_V12_V13_V14, RISCV::V12_V13_V14_V15, RISCV::V13_V14_V15_V16,
116 RISCV::V14_V15_V16_V17, RISCV::V15_V16_V17_V18, RISCV::V16_V17_V18_V19,
117 RISCV::V17_V18_V19_V20, RISCV::V18_V19_V20_V21, RISCV::V19_V20_V21_V22,
118 RISCV::V20_V21_V22_V23};
119static const MCPhysReg ArgVRN5M1s[] = {
120 RISCV::V8_V9_V10_V11_V12, RISCV::V9_V10_V11_V12_V13,
121 RISCV::V10_V11_V12_V13_V14, RISCV::V11_V12_V13_V14_V15,
122 RISCV::V12_V13_V14_V15_V16, RISCV::V13_V14_V15_V16_V17,
123 RISCV::V14_V15_V16_V17_V18, RISCV::V15_V16_V17_V18_V19,
124 RISCV::V16_V17_V18_V19_V20, RISCV::V17_V18_V19_V20_V21,
125 RISCV::V18_V19_V20_V21_V22, RISCV::V19_V20_V21_V22_V23};
126static const MCPhysReg ArgVRN6M1s[] = {
127 RISCV::V8_V9_V10_V11_V12_V13, RISCV::V9_V10_V11_V12_V13_V14,
128 RISCV::V10_V11_V12_V13_V14_V15, RISCV::V11_V12_V13_V14_V15_V16,
129 RISCV::V12_V13_V14_V15_V16_V17, RISCV::V13_V14_V15_V16_V17_V18,
130 RISCV::V14_V15_V16_V17_V18_V19, RISCV::V15_V16_V17_V18_V19_V20,
131 RISCV::V16_V17_V18_V19_V20_V21, RISCV::V17_V18_V19_V20_V21_V22,
132 RISCV::V18_V19_V20_V21_V22_V23};
133static const MCPhysReg ArgVRN7M1s[] = {
134 RISCV::V8_V9_V10_V11_V12_V13_V14, RISCV::V9_V10_V11_V12_V13_V14_V15,
135 RISCV::V10_V11_V12_V13_V14_V15_V16, RISCV::V11_V12_V13_V14_V15_V16_V17,
136 RISCV::V12_V13_V14_V15_V16_V17_V18, RISCV::V13_V14_V15_V16_V17_V18_V19,
137 RISCV::V14_V15_V16_V17_V18_V19_V20, RISCV::V15_V16_V17_V18_V19_V20_V21,
138 RISCV::V16_V17_V18_V19_V20_V21_V22, RISCV::V17_V18_V19_V20_V21_V22_V23};
139static const MCPhysReg ArgVRN8M1s[] = {RISCV::V8_V9_V10_V11_V12_V13_V14_V15,
140 RISCV::V9_V10_V11_V12_V13_V14_V15_V16,
141 RISCV::V10_V11_V12_V13_V14_V15_V16_V17,
142 RISCV::V11_V12_V13_V14_V15_V16_V17_V18,
143 RISCV::V12_V13_V14_V15_V16_V17_V18_V19,
144 RISCV::V13_V14_V15_V16_V17_V18_V19_V20,
145 RISCV::V14_V15_V16_V17_V18_V19_V20_V21,
146 RISCV::V15_V16_V17_V18_V19_V20_V21_V22,
147 RISCV::V16_V17_V18_V19_V20_V21_V22_V23};
148static const MCPhysReg ArgVRN2M2s[] = {RISCV::V8M2_V10M2, RISCV::V10M2_V12M2,
149 RISCV::V12M2_V14M2, RISCV::V14M2_V16M2,
150 RISCV::V16M2_V18M2, RISCV::V18M2_V20M2,
151 RISCV::V20M2_V22M2};
152static const MCPhysReg ArgVRN3M2s[] = {
153 RISCV::V8M2_V10M2_V12M2, RISCV::V10M2_V12M2_V14M2,
154 RISCV::V12M2_V14M2_V16M2, RISCV::V14M2_V16M2_V18M2,
155 RISCV::V16M2_V18M2_V20M2, RISCV::V18M2_V20M2_V22M2};
156static const MCPhysReg ArgVRN4M2s[] = {
157 RISCV::V8M2_V10M2_V12M2_V14M2, RISCV::V10M2_V12M2_V14M2_V16M2,
158 RISCV::V12M2_V14M2_V16M2_V18M2, RISCV::V14M2_V16M2_V18M2_V20M2,
159 RISCV::V16M2_V18M2_V20M2_V22M2};
160static const MCPhysReg ArgVRN2M4s[] = {RISCV::V8M4_V12M4, RISCV::V12M4_V16M4,
161 RISCV::V16M4_V20M4};
162
164 // The GPRs used for passing arguments in the ILP32* and LP64* ABIs, except
165 // the ILP32E ABI.
166 static const MCPhysReg ArgIGPRs[] = {RISCV::X10, RISCV::X11, RISCV::X12,
167 RISCV::X13, RISCV::X14, RISCV::X15,
168 RISCV::X16, RISCV::X17};
169 // The GPRs used for passing arguments in the ILP32E/LP64E ABI.
170 static const MCPhysReg ArgEGPRs[] = {RISCV::X10, RISCV::X11, RISCV::X12,
171 RISCV::X13, RISCV::X14, RISCV::X15};
172
173 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)
174 return ArrayRef(ArgEGPRs);
175
176 return ArrayRef(ArgIGPRs);
177}
178
180 // The GPRs used for passing arguments in the ILP32* and LP64* ABIs, except
181 // the ILP32E ABI.
182 static const MCPhysReg ArgIGPRs[] = {RISCV::X10_H, RISCV::X11_H, RISCV::X12_H,
183 RISCV::X13_H, RISCV::X14_H, RISCV::X15_H,
184 RISCV::X16_H, RISCV::X17_H};
185 // The GPRs used for passing arguments in the ILP32E/LP64E ABI.
186 static const MCPhysReg ArgEGPRs[] = {RISCV::X10_H, RISCV::X11_H,
187 RISCV::X12_H, RISCV::X13_H,
188 RISCV::X14_H, RISCV::X15_H};
189
190 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)
191 return ArrayRef(ArgEGPRs);
192
193 return ArrayRef(ArgIGPRs);
194}
195
197 // The GPRs used for passing arguments in the ILP32* and LP64* ABIs, except
198 // the ILP32E ABI.
199 static const MCPhysReg ArgIGPRs[] = {RISCV::X10_W, RISCV::X11_W, RISCV::X12_W,
200 RISCV::X13_W, RISCV::X14_W, RISCV::X15_W,
201 RISCV::X16_W, RISCV::X17_W};
202 // The GPRs used for passing arguments in the ILP32E/LP64E ABI.
203 static const MCPhysReg ArgEGPRs[] = {RISCV::X10_W, RISCV::X11_W,
204 RISCV::X12_W, RISCV::X13_W,
205 RISCV::X14_W, RISCV::X15_W};
206
207 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)
208 return ArrayRef(ArgEGPRs);
209
210 return ArrayRef(ArgIGPRs);
211}
212
214 // The GPRs used for passing arguments in the FastCC, X5 and X6 might be used
215 // for save-restore libcall, so we don't use them.
216 // Don't use X7 for fastcc, since Zicfilp uses X7 as the label register.
217 static const MCPhysReg FastCCIGPRs[] = {
218 RISCV::X10, RISCV::X11, RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15,
219 RISCV::X16, RISCV::X17, RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31};
220
221 // The GPRs used for passing arguments in the FastCC when using ILP32E/LP64E.
222 static const MCPhysReg FastCCEGPRs[] = {RISCV::X10, RISCV::X11, RISCV::X12,
223 RISCV::X13, RISCV::X14, RISCV::X15};
224
225 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)
226 return ArrayRef(FastCCEGPRs);
227
228 return ArrayRef(FastCCIGPRs);
229}
230
232 // The GPRs used for passing arguments in the FastCC, X5 and X6 might be used
233 // for save-restore libcall, so we don't use them.
234 // Don't use X7 for fastcc, since Zicfilp uses X7 as the label register.
235 static const MCPhysReg FastCCIGPRs[] = {
236 RISCV::X10_H, RISCV::X11_H, RISCV::X12_H, RISCV::X13_H,
237 RISCV::X14_H, RISCV::X15_H, RISCV::X16_H, RISCV::X17_H,
238 RISCV::X28_H, RISCV::X29_H, RISCV::X30_H, RISCV::X31_H};
239
240 // The GPRs used for passing arguments in the FastCC when using ILP32E/LP64E.
241 static const MCPhysReg FastCCEGPRs[] = {RISCV::X10_H, RISCV::X11_H,
242 RISCV::X12_H, RISCV::X13_H,
243 RISCV::X14_H, RISCV::X15_H};
244
245 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)
246 return ArrayRef(FastCCEGPRs);
247
248 return ArrayRef(FastCCIGPRs);
249}
250
252 // The GPRs used for passing arguments in the FastCC, X5 and X6 might be used
253 // for save-restore libcall, so we don't use them.
254 // Don't use X7 for fastcc, since Zicfilp uses X7 as the label register.
255 static const MCPhysReg FastCCIGPRs[] = {
256 RISCV::X10_W, RISCV::X11_W, RISCV::X12_W, RISCV::X13_W,
257 RISCV::X14_W, RISCV::X15_W, RISCV::X16_W, RISCV::X17_W,
258 RISCV::X28_W, RISCV::X29_W, RISCV::X30_W, RISCV::X31_W};
259
260 // The GPRs used for passing arguments in the FastCC when using ILP32E/LP64E.
261 static const MCPhysReg FastCCEGPRs[] = {RISCV::X10_W, RISCV::X11_W,
262 RISCV::X12_W, RISCV::X13_W,
263 RISCV::X14_W, RISCV::X15_W};
264
265 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)
266 return ArrayRef(FastCCEGPRs);
267
268 return ArrayRef(FastCCIGPRs);
269}
270
271// Pass a 2*XLEN argument that has been split into two XLEN values through
272// registers or the stack as necessary.
273static bool CC_RISCVAssign2XLen(unsigned XLen, CCState &State, CCValAssign VA1,
274 ISD::ArgFlagsTy ArgFlags1, unsigned ValNo2,
275 MVT ValVT2, MVT LocVT2,
276 ISD::ArgFlagsTy ArgFlags2, bool EABI) {
277 unsigned XLenInBytes = XLen / 8;
278 const RISCVSubtarget &STI =
279 State.getMachineFunction().getSubtarget<RISCVSubtarget>();
281
282 if (MCRegister Reg = State.AllocateReg(ArgGPRs)) {
283 // At least one half can be passed via register.
284 State.addLoc(CCValAssign::getReg(VA1.getValNo(), VA1.getValVT(), Reg,
286 } else {
287 // Both halves must be passed on the stack, with proper alignment.
288 // TODO: To be compatible with GCC's behaviors, we force them to have 4-byte
289 // alignment. This behavior may be changed when RV32E/ILP32E is ratified.
290 Align StackAlign(XLenInBytes);
291 if (!EABI || XLen != 32)
292 StackAlign = std::max(StackAlign, ArgFlags1.getNonZeroOrigAlign());
293 State.addLoc(
295 State.AllocateStack(XLenInBytes, StackAlign),
297 State.addLoc(CCValAssign::getMem(
298 ValNo2, ValVT2, State.AllocateStack(XLenInBytes, Align(XLenInBytes)),
299 LocVT2, CCValAssign::Full));
300 return false;
301 }
302
303 if (MCRegister Reg = State.AllocateReg(ArgGPRs)) {
304 // The second half can also be passed via register.
305 State.addLoc(
306 CCValAssign::getReg(ValNo2, ValVT2, Reg, LocVT2, CCValAssign::Full));
307 } else {
308 // The second half is passed via the stack, without additional alignment.
309 State.addLoc(CCValAssign::getMem(
310 ValNo2, ValVT2, State.AllocateStack(XLenInBytes, Align(XLenInBytes)),
311 LocVT2, CCValAssign::Full));
312 }
313
314 return false;
315}
316
317static MCRegister allocateRVVReg(MVT ValVT, unsigned ValNo, CCState &State,
318 const RISCVTargetLowering &TLI) {
319 const TargetRegisterClass *RC = TLI.getRegClassFor(ValVT);
320 if (RC == &RISCV::VRRegClass) {
321 // Assign the first mask argument to V0.
322 // This is an interim calling convention and it may be changed in the
323 // future.
324 if (ValVT.getVectorElementType() == MVT::i1)
325 if (MCRegister Reg = State.AllocateReg(RISCV::V0))
326 return Reg;
327 return State.AllocateReg(ArgVRs);
328 }
329 if (RC == &RISCV::VRM2RegClass)
330 return State.AllocateReg(ArgVRM2s);
331 if (RC == &RISCV::VRM4RegClass)
332 return State.AllocateReg(ArgVRM4s);
333 if (RC == &RISCV::VRM8RegClass)
334 return State.AllocateReg(ArgVRM8s);
335 if (RC == &RISCV::VRN2M1RegClass)
336 return State.AllocateReg(ArgVRN2M1s);
337 if (RC == &RISCV::VRN3M1RegClass)
338 return State.AllocateReg(ArgVRN3M1s);
339 if (RC == &RISCV::VRN4M1RegClass)
340 return State.AllocateReg(ArgVRN4M1s);
341 if (RC == &RISCV::VRN5M1RegClass)
342 return State.AllocateReg(ArgVRN5M1s);
343 if (RC == &RISCV::VRN6M1RegClass)
344 return State.AllocateReg(ArgVRN6M1s);
345 if (RC == &RISCV::VRN7M1RegClass)
346 return State.AllocateReg(ArgVRN7M1s);
347 if (RC == &RISCV::VRN8M1RegClass)
348 return State.AllocateReg(ArgVRN8M1s);
349 if (RC == &RISCV::VRN2M2RegClass)
350 return State.AllocateReg(ArgVRN2M2s);
351 if (RC == &RISCV::VRN3M2RegClass)
352 return State.AllocateReg(ArgVRN3M2s);
353 if (RC == &RISCV::VRN4M2RegClass)
354 return State.AllocateReg(ArgVRN4M2s);
355 if (RC == &RISCV::VRN2M4RegClass)
356 return State.AllocateReg(ArgVRN2M4s);
357 llvm_unreachable("Unhandled register class for ValueType");
358}
359
360// Implements the RISC-V calling convention. Returns true upon failure.
361//
362// This has a slightly different signature to CCAssignFn - it adds `bool IsRet`.
363static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT LocVT,
364 CCValAssign::LocInfo LocInfo,
365 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,
366 CCState &State, bool IsRet) {
367 const MachineFunction &MF = State.getMachineFunction();
368 const DataLayout &DL = MF.getDataLayout();
369 const RISCVSubtarget &Subtarget = MF.getSubtarget<RISCVSubtarget>();
370 const RISCVTargetLowering &TLI = *Subtarget.getTargetLowering();
371
372 unsigned XLen = Subtarget.getXLen();
373 MVT XLenVT = Subtarget.getXLenVT();
374
375 if (ArgFlags.isNest()) {
376 // Static chain parameter must not be passed in normal argument registers,
377 // so we assign t2/t3 for it as done in GCC's
378 // __builtin_call_with_static_chain
379 bool HasCFBranch =
380 Subtarget.hasStdExtZicfilp() &&
381 MF.getFunction().getParent()->getModuleFlag("cf-protection-branch");
382
383 // Normal: t2, Branch control flow protection: t3
384 const auto StaticChainReg = HasCFBranch ? RISCV::X28 : RISCV::X7;
385
386 RISCVABI::ABI ABI = Subtarget.getTargetABI();
387 if (HasCFBranch &&
388 (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E))
390 "Nested functions with control flow protection are not "
391 "usable with ILP32E or LP64E ABI.");
392 if (MCRegister Reg = State.AllocateReg(StaticChainReg)) {
393 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
394 return false;
395 }
396 }
397
398 // Any return value split in to more than two values can't be returned
399 // directly. Vectors are returned via the available vector registers.
400 if ((!LocVT.isVector() || Subtarget.isPExtPackedType(ValVT)) && IsRet &&
401 ValNo > 1)
402 return true;
403
404 // UseGPRForF16_F32 if targeting one of the soft-float ABIs, if passing a
405 // variadic argument, or if no F16/F32 argument registers are available.
406 bool UseGPRForF16_F32 = true;
407 // UseGPRForF64 if targeting soft-float ABIs or an FLEN=32 ABI, if passing a
408 // variadic argument, or if no F64 argument registers are available.
409 bool UseGPRForF64 = true;
410
411 RISCVABI::ABI ABI = Subtarget.getTargetABI();
412 switch (ABI) {
413 default:
414 llvm_unreachable("Unexpected ABI");
419 break;
422 UseGPRForF16_F32 = ArgFlags.isVarArg();
423 break;
426 UseGPRForF16_F32 = ArgFlags.isVarArg();
427 UseGPRForF64 = ArgFlags.isVarArg();
428 break;
429 }
430
431 if ((LocVT == MVT::f16 || LocVT == MVT::bf16) && !UseGPRForF16_F32) {
432 if (MCRegister Reg = State.AllocateReg(ArgFPR16s)) {
433 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
434 return false;
435 }
436 }
437
438 if (LocVT == MVT::f32 && !UseGPRForF16_F32) {
439 if (MCRegister Reg = State.AllocateReg(ArgFPR32s)) {
440 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
441 return false;
442 }
443 }
444
445 if (LocVT == MVT::f64 && !UseGPRForF64) {
446 if (MCRegister Reg = State.AllocateReg(ArgFPR64s)) {
447 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
448 return false;
449 }
450 }
451
452 if ((ValVT == MVT::f16 && Subtarget.hasStdExtZhinxmin())) {
453 if (MCRegister Reg = State.AllocateReg(getArgGPR16s(ABI))) {
454 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
455 return false;
456 }
457 }
458
459 if (ValVT == MVT::f32 && Subtarget.hasStdExtZfinx()) {
460 if (MCRegister Reg = State.AllocateReg(getArgGPR32s(ABI))) {
461 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
462 return false;
463 }
464 }
465
467
468 // Zdinx use GPR without a bitcast when possible.
469 if (LocVT == MVT::f64 && XLen == 64 && Subtarget.hasStdExtZdinx()) {
470 if (MCRegister Reg = State.AllocateReg(ArgGPRs)) {
471 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
472 return false;
473 }
474 }
475
476 // FP smaller than XLen, uses custom GPR.
477 if (LocVT == MVT::f16 || LocVT == MVT::bf16 ||
478 (LocVT == MVT::f32 && XLen == 64)) {
479 if (MCRegister Reg = State.AllocateReg(ArgGPRs)) {
480 LocVT = XLenVT;
481 State.addLoc(
482 CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
483 return false;
484 }
485 }
486
487 // Bitcast FP to GPR if we can use a GPR register.
488 if ((XLen == 32 && LocVT == MVT::f32) || (XLen == 64 && LocVT == MVT::f64)) {
489 if (MCRegister Reg = State.AllocateReg(ArgGPRs)) {
490 LocVT = XLenVT;
491 LocInfo = CCValAssign::BCvt;
492 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
493 return false;
494 }
495 }
496
497 // If this is a variadic argument, the RISC-V calling convention requires
498 // that it is assigned an 'even' or 'aligned' register if it has 8-byte
499 // alignment (RV32) or 16-byte alignment (RV64). An aligned register should
500 // be used regardless of whether the original argument was split during
501 // legalisation or not. The argument will not be passed by registers if the
502 // original type is larger than 2*XLEN, so the register alignment rule does
503 // not apply.
504 // TODO: To be compatible with GCC's behaviors, we don't align registers
505 // currently if we are using ILP32E calling convention. This behavior may be
506 // changed when RV32E/ILP32E is ratified.
507 unsigned TwoXLenInBytes = (2 * XLen) / 8;
508 if (ArgFlags.isVarArg() && ArgFlags.getNonZeroOrigAlign() == TwoXLenInBytes &&
509 DL.getTypeAllocSize(OrigTy) == TwoXLenInBytes &&
510 ABI != RISCVABI::ABI_ILP32E) {
511 unsigned RegIdx = State.getFirstUnallocated(ArgGPRs);
512 // Skip 'odd' register if necessary.
513 if (RegIdx != std::size(ArgGPRs) && RegIdx % 2 == 1)
514 State.AllocateReg(ArgGPRs);
515 }
516
517 SmallVectorImpl<CCValAssign> &PendingLocs = State.getPendingLocs();
518 SmallVectorImpl<ISD::ArgFlagsTy> &PendingArgFlags =
519 State.getPendingArgFlags();
520
521 assert(PendingLocs.size() == PendingArgFlags.size() &&
522 "PendingLocs and PendingArgFlags out of sync");
523
524 // Handle passing f64 on RV32D with a soft float ABI or when floating point
525 // registers are exhausted.
526 if (XLen == 32 && LocVT == MVT::f64) {
527 assert(PendingLocs.empty() && "Can't lower f64 if it is split");
528 // Depending on available argument GPRS, f64 may be passed in a pair of
529 // GPRs, split between a GPR and the stack, or passed completely on the
530 // stack. LowerCall/LowerFormalArguments/LowerReturn must recognise these
531 // cases.
532 MCRegister Reg = State.AllocateReg(ArgGPRs);
533 if (!Reg) {
534 int64_t StackOffset = State.AllocateStack(8, Align(8));
535 State.addLoc(
536 CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
537 return false;
538 }
539 LocVT = MVT::i32;
540 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
541 MCRegister HiReg = State.AllocateReg(ArgGPRs);
542 if (HiReg) {
543 State.addLoc(
544 CCValAssign::getCustomReg(ValNo, ValVT, HiReg, LocVT, LocInfo));
545 } else {
546 int64_t StackOffset = State.AllocateStack(4, Align(4));
547 State.addLoc(
548 CCValAssign::getCustomMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
549 }
550 return false;
551 }
552
553 // If the split argument only had two elements, it should be passed directly
554 // in registers or on the stack.
555 if ((ValVT.isScalarInteger() || Subtarget.isPExtPackedType(ValVT)) &&
556 ArgFlags.isSplitEnd() && PendingLocs.size() <= 1) {
557 assert(PendingLocs.size() == 1 && "Unexpected PendingLocs.size()");
558 // Apply the normal calling convention rules to the first half of the
559 // split argument.
560 CCValAssign VA = PendingLocs[0];
561 ISD::ArgFlagsTy AF = PendingArgFlags[0];
562 PendingLocs.clear();
563 PendingArgFlags.clear();
564 return CC_RISCVAssign2XLen(
565 XLen, State, VA, AF, ValNo, ValVT, LocVT, ArgFlags,
567 }
568
569 // Split arguments might be passed indirectly, so keep track of the pending
570 // values. Split vectors excluding P extension packed vectors(see
571 // isPExtPackedType) are passed via a mix of registers and indirectly, so
572 // treat them as we would any other argument.
573 if ((ValVT.isScalarInteger() || Subtarget.isPExtPackedType(ValVT)) &&
574 (ArgFlags.isSplit() || !PendingLocs.empty())) {
575 PendingLocs.push_back(
576 CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
577 PendingArgFlags.push_back(ArgFlags);
578 if (!ArgFlags.isSplitEnd()) {
579 return false;
580 }
581 }
582
583 // Allocate to a register if possible, or else a stack slot.
585 unsigned StoreSizeBytes = XLen / 8;
586 Align StackAlign = Align(XLen / 8);
587
588 // FIXME: If P extension and V extension are enabled at the same time,
589 // who should go first?
590 if (!Subtarget.isPExtPackedType(ValVT) &&
591 (ValVT.isVector() || ValVT.isRISCVVectorTuple())) {
592 Reg = allocateRVVReg(ValVT, ValNo, State, TLI);
593 if (Reg) {
594 // Fixed-length vectors are located in the corresponding scalable-vector
595 // container types.
596 if (ValVT.isFixedLengthVector()) {
597 LocVT = TLI.getContainerForFixedLengthVector(LocVT);
598 State.addLoc(
599 CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
600 return false;
601 }
602 } else {
603 // For return values, the vector must be passed fully via registers or
604 // via the stack.
605 if (IsRet)
606 return true;
607 // Try using a GPR to pass the address
608 if ((Reg = State.AllocateReg(ArgGPRs))) {
609 LocVT = XLenVT;
610 LocInfo = CCValAssign::Indirect;
611 } else if (ValVT.isScalableVector()) {
612 LocVT = XLenVT;
613 LocInfo = CCValAssign::Indirect;
614 } else {
615 StoreSizeBytes = ValVT.getStoreSize();
616 // Align vectors to their element sizes, being careful for vXi1
617 // vectors.
618 StackAlign = MaybeAlign(ValVT.getScalarSizeInBits() / 8).valueOrOne();
619 }
620 }
621 } else {
622 Reg = State.AllocateReg(ArgGPRs);
623 }
624
625 int64_t StackOffset =
626 Reg ? 0 : State.AllocateStack(StoreSizeBytes, StackAlign);
627
628 // If we reach this point and PendingLocs is non-empty, we must be at the
629 // end of a split argument that must be passed indirectly.
630 if (!PendingLocs.empty()) {
631 assert(ArgFlags.isSplitEnd() && "Expected ArgFlags.isSplitEnd()");
632 assert(PendingLocs.size() > 2 && "Unexpected PendingLocs.size()");
633
634 for (auto &It : PendingLocs) {
635 if (Reg)
636 State.addLoc(CCValAssign::getReg(It.getValNo(), It.getValVT(), Reg,
637 XLenVT, CCValAssign::Indirect));
638 else
639 State.addLoc(CCValAssign::getMem(It.getValNo(), It.getValVT(),
640 StackOffset, XLenVT,
642 }
643 PendingLocs.clear();
644 PendingArgFlags.clear();
645 return false;
646 }
647
648 assert(((ValVT.isFloatingPoint() && !ValVT.isVector()) || LocVT == XLenVT ||
649 Subtarget.isPExtPackedType(LocVT) ||
650 (TLI.getSubtarget().hasVInstructions() &&
651 (ValVT.isVector() || ValVT.isRISCVVectorTuple()))) &&
652 "Expected an XLenVT or vector types at this stage");
653
654 if (Reg) {
655 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
656 return false;
657 }
658
659 State.addLoc(CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
660 return false;
661}
662
663// FastCC has less than 1% performance improvement for some particular
664// benchmark. But theoretically, it may have benefit for some cases.
665static bool CC_RISCV_FastCC(unsigned ValNo, MVT ValVT, MVT LocVT,
666 CCValAssign::LocInfo LocInfo,
667 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,
668 CCState &State) {
669 const MachineFunction &MF = State.getMachineFunction();
670 const RISCVSubtarget &Subtarget = MF.getSubtarget<RISCVSubtarget>();
671 const RISCVTargetLowering &TLI = *Subtarget.getTargetLowering();
672 RISCVABI::ABI ABI = Subtarget.getTargetABI();
673
674 if ((LocVT == MVT::f16 && Subtarget.hasStdExtZfhmin()) ||
675 (LocVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin())) {
676 static const MCPhysReg FPR16List[] = {
677 RISCV::F10_H, RISCV::F11_H, RISCV::F12_H, RISCV::F13_H, RISCV::F14_H,
678 RISCV::F15_H, RISCV::F16_H, RISCV::F17_H, RISCV::F0_H, RISCV::F1_H,
679 RISCV::F2_H, RISCV::F3_H, RISCV::F4_H, RISCV::F5_H, RISCV::F6_H,
680 RISCV::F7_H, RISCV::F28_H, RISCV::F29_H, RISCV::F30_H, RISCV::F31_H};
681 if (MCRegister Reg = State.AllocateReg(FPR16List)) {
682 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
683 return false;
684 }
685 }
686
687 if (LocVT == MVT::f32 && Subtarget.hasStdExtF()) {
688 static const MCPhysReg FPR32List[] = {
689 RISCV::F10_F, RISCV::F11_F, RISCV::F12_F, RISCV::F13_F, RISCV::F14_F,
690 RISCV::F15_F, RISCV::F16_F, RISCV::F17_F, RISCV::F0_F, RISCV::F1_F,
691 RISCV::F2_F, RISCV::F3_F, RISCV::F4_F, RISCV::F5_F, RISCV::F6_F,
692 RISCV::F7_F, RISCV::F28_F, RISCV::F29_F, RISCV::F30_F, RISCV::F31_F};
693 if (MCRegister Reg = State.AllocateReg(FPR32List)) {
694 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
695 return false;
696 }
697 }
698
699 if (LocVT == MVT::f64 && Subtarget.hasStdExtD()) {
700 static const MCPhysReg FPR64List[] = {
701 RISCV::F10_D, RISCV::F11_D, RISCV::F12_D, RISCV::F13_D, RISCV::F14_D,
702 RISCV::F15_D, RISCV::F16_D, RISCV::F17_D, RISCV::F0_D, RISCV::F1_D,
703 RISCV::F2_D, RISCV::F3_D, RISCV::F4_D, RISCV::F5_D, RISCV::F6_D,
704 RISCV::F7_D, RISCV::F28_D, RISCV::F29_D, RISCV::F30_D, RISCV::F31_D};
705 if (MCRegister Reg = State.AllocateReg(FPR64List)) {
706 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
707 return false;
708 }
709 }
710
711 MVT XLenVT = Subtarget.getXLenVT();
712
713 // Check if there is an available GPRF16 before hitting the stack.
714 if ((LocVT == MVT::f16 && Subtarget.hasStdExtZhinxmin())) {
715 if (MCRegister Reg = State.AllocateReg(getFastCCArgGPRF16s(ABI))) {
716 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
717 return false;
718 }
719 }
720
721 // Check if there is an available GPRF32 before hitting the stack.
722 if (LocVT == MVT::f32 && Subtarget.hasStdExtZfinx()) {
723 if (MCRegister Reg = State.AllocateReg(getFastCCArgGPRF32s(ABI))) {
724 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
725 return false;
726 }
727 }
728
729 // Check if there is an available GPR before hitting the stack.
730 if (LocVT == MVT::f64 && Subtarget.is64Bit() && Subtarget.hasStdExtZdinx()) {
731 if (MCRegister Reg = State.AllocateReg(getFastCCArgGPRs(ABI))) {
732 if (LocVT.getSizeInBits() != Subtarget.getXLen()) {
733 LocVT = XLenVT;
734 State.addLoc(
735 CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
736 return false;
737 }
738 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
739 return false;
740 }
741 }
742
744
745 if (LocVT.isVector()) {
746 if (MCRegister Reg = allocateRVVReg(ValVT, ValNo, State, TLI)) {
747 // Fixed-length vectors are located in the corresponding scalable-vector
748 // container types.
749 if (LocVT.isFixedLengthVector()) {
750 LocVT = TLI.getContainerForFixedLengthVector(LocVT);
751 State.addLoc(
752 CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
753 return false;
754 }
755 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
756 return false;
757 }
758
759 // Pass scalable vectors indirectly. Pass fixed vectors indirectly if we
760 // have a free GPR.
761 if (LocVT.isScalableVector() ||
762 State.getFirstUnallocated(ArgGPRs) != ArgGPRs.size()) {
763 LocInfo = CCValAssign::Indirect;
764 LocVT = XLenVT;
765 }
766 }
767
768 if (LocVT == XLenVT) {
769 if (MCRegister Reg = State.AllocateReg(getFastCCArgGPRs(ABI))) {
770 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
771 return false;
772 }
773 }
774
775 if (LocVT == XLenVT || LocVT == MVT::f16 || LocVT == MVT::bf16 ||
776 LocVT == MVT::f32 || LocVT == MVT::f64 || LocVT.isFixedLengthVector()) {
777 Align StackAlign = MaybeAlign(ValVT.getScalarSizeInBits() / 8).valueOrOne();
778 int64_t Offset = State.AllocateStack(LocVT.getStoreSize(), StackAlign);
779 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
780 return false;
781 }
782
783 return true; // CC didn't match.
784}
785
786static bool CC_RISCV_GHC(unsigned ValNo, MVT ValVT, MVT LocVT,
787 CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
788 Type *OrigTy, CCState &State) {
789 if (ArgFlags.isNest()) {
791 "Attribute 'nest' is not supported in GHC calling convention");
792 }
793
794 static const MCPhysReg GPRList[] = {
795 RISCV::X9, RISCV::X18, RISCV::X19, RISCV::X20, RISCV::X21, RISCV::X22,
796 RISCV::X23, RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27};
797
798 if (LocVT == MVT::i32 || LocVT == MVT::i64) {
799 // Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, R5, R6, R7, SpLim
800 // s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11
801 if (MCRegister Reg = State.AllocateReg(GPRList)) {
802 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
803 return false;
804 }
805 }
806
807 const RISCVSubtarget &Subtarget =
808 State.getMachineFunction().getSubtarget<RISCVSubtarget>();
809
810 if (LocVT == MVT::f32 && Subtarget.hasStdExtF()) {
811 // Pass in STG registers: F1, ..., F6
812 // fs0 ... fs5
813 static const MCPhysReg FPR32List[] = {RISCV::F8_F, RISCV::F9_F,
814 RISCV::F18_F, RISCV::F19_F,
815 RISCV::F20_F, RISCV::F21_F};
816 if (MCRegister Reg = State.AllocateReg(FPR32List)) {
817 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
818 return false;
819 }
820 }
821
822 if (LocVT == MVT::f64 && Subtarget.hasStdExtD()) {
823 // Pass in STG registers: D1, ..., D6
824 // fs6 ... fs11
825 static const MCPhysReg FPR64List[] = {RISCV::F22_D, RISCV::F23_D,
826 RISCV::F24_D, RISCV::F25_D,
827 RISCV::F26_D, RISCV::F27_D};
828 if (MCRegister Reg = State.AllocateReg(FPR64List)) {
829 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
830 return false;
831 }
832 }
833
834 if (LocVT == MVT::f32 && Subtarget.hasStdExtZfinx()) {
835 static const MCPhysReg GPR32List[] = {
836 RISCV::X9_W, RISCV::X18_W, RISCV::X19_W, RISCV::X20_W,
837 RISCV::X21_W, RISCV::X22_W, RISCV::X23_W, RISCV::X24_W,
838 RISCV::X25_W, RISCV::X26_W, RISCV::X27_W};
839 if (MCRegister Reg = State.AllocateReg(GPR32List)) {
840 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
841 return false;
842 }
843 }
844
845 if (LocVT == MVT::f64 && Subtarget.hasStdExtZdinx() && Subtarget.is64Bit()) {
846 if (MCRegister Reg = State.AllocateReg(GPRList)) {
847 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
848 return false;
849 }
850 }
851
852 report_fatal_error("No registers left in GHC calling convention");
853 return true;
854}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Module.h This file contains the declarations for the Module class.
const MCPhysReg ArgFPR32s[]
const MCPhysReg ArgVRs[]
const MCPhysReg ArgFPR64s[]
const MCPhysReg ArgGPRs[]
Register Reg
static bool CC_RISCVAssign2XLen(unsigned XLen, CCState &State, CCValAssign VA1, ISD::ArgFlagsTy ArgFlags1, unsigned ValNo2, MVT ValVT2, MVT LocVT2, ISD::ArgFlagsTy ArgFlags2, bool EABI)
static const MCPhysReg ArgVRN2M2s[]
static CCAssignFn CC_RISCV_FastCC
Used for assigning arguments with CallingConvention::Fast.
static const MCPhysReg ArgVRM2s[]
static MCRegister allocateRVVReg(MVT ValVT, unsigned ValNo, CCState &State, const RISCVTargetLowering &TLI)
static CCAssignFn CC_RISCV_GHC
Used for assigning arguments with CallingConvention::GHC.
static const MCPhysReg ArgVRN3M2s[]
static const MCPhysReg ArgVRN4M1s[]
static const MCPhysReg ArgVRN6M1s[]
static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State, bool IsRet)
static ArrayRef< MCPhysReg > getFastCCArgGPRF32s(const RISCVABI::ABI ABI)
static const MCPhysReg ArgVRN4M2s[]
static const MCPhysReg ArgVRN3M1s[]
static const MCPhysReg ArgVRN7M1s[]
static const MCPhysReg ArgVRN5M1s[]
static const MCPhysReg ArgVRN2M4s[]
static ArrayRef< MCPhysReg > getFastCCArgGPRF16s(const RISCVABI::ABI ABI)
static ArrayRef< MCPhysReg > getArgGPR32s(const RISCVABI::ABI ABI)
static const MCPhysReg ArgVRN2M1s[]
static const MCPhysReg ArgVRN8M1s[]
static ArrayRef< MCPhysReg > getArgGPR16s(const RISCVABI::ABI ABI)
static ArrayRef< MCPhysReg > getFastCCArgGPRs(const RISCVABI::ABI ABI)
static const MCPhysReg ArgVRM8s[]
static const MCPhysReg ArgVRM4s[]
static const MCPhysReg ArgFPR16s[]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Module * getParent()
Get the module that this global value is contained inside of...
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Machine Value Type.
bool isRISCVVectorTuple() const
Return true if this is a RISCV vector tuple type where the runtime length is machine dependent.
uint64_t getScalarSizeInBits() const
bool isVector() const
Return true if this is a vector value type.
bool isScalableVector() const
Return true if this is a vector value type where the runtime length is machine dependent.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
bool isFixedLengthVector() const
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
MVT getVectorElementType() const
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Definition Module.cpp:358
RISCVABI::ABI getTargetABI() const
bool isPExtPackedType(MVT VT) const
unsigned getXLen() const
const RISCVTargetLowering * getTargetLowering() const override
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition CallingConv.h:50
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
ArrayRef< MCPhysReg > getArgGPRs(const RISCVABI::ABI ABI)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
CCAssignFn RetCC_RISCV
This is used for assigning return values to locations when making calls.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
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 >
EABI
Definition CodeGen.h:73
CCAssignFn CC_RISCV
This is used for assigining arguments to locations when making calls.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Align getNonZeroOrigAlign() const
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:106
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition Alignment.h:130