1//===- RISCV.cpp ----------------------------------------------------------===//
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 "ABIInfoImpl.h"
10#include "TargetInfo.h"
11#include "llvm/TargetParser/RISCVTargetParser.h"
12
13using namespace clang;
14using namespace clang::CodeGen;
15
16//===----------------------------------------------------------------------===//
17// RISC-V ABI Implementation
18//===----------------------------------------------------------------------===//
19
20namespace {
21class RISCVABIInfo : public DefaultABIInfo {
22private:
23 // Size of the integer ('x') registers in bits.
24 unsigned XLen;
25 // Size of the floating point ('f') registers in bits. Note that the target
26 // ISA might have a wider FLen than the selected ABI (e.g. an RV32IF target
27 // with soft float ABI has FLen==0).
28 unsigned FLen;
29 const int NumArgGPRs;
30 const int NumArgFPRs;
31 const bool EABI;
32 bool detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
33 llvm::Type *&Field1Ty,
34 CharUnits &Field1Off,
35 llvm::Type *&Field2Ty,
36 CharUnits &Field2Off) const;
37
38 bool detectVLSCCEligibleStruct(QualType Ty, unsigned ABIVLen,
39 llvm::Type *&VLSType) const;
40
41public:
42 RISCVABIInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, unsigned FLen,
43 bool EABI)
44 : DefaultABIInfo(CGT), XLen(XLen), FLen(FLen), NumArgGPRs(EABI ? 6 : 8),
45 NumArgFPRs(FLen != 0 ? 8 : 0), EABI(EABI) {}
46
47 // DefaultABIInfo's classifyReturnType and classifyArgumentType are
48 // non-virtual, but computeInfo is virtual, so we overload it.
49 void computeInfo(CGFunctionInfo &FI) const override;
50
51 ABIArgInfo classifyArgumentType(QualType Ty, bool IsFixed, int &ArgGPRsLeft,
52 int &ArgFPRsLeft, unsigned ABIVLen) const;
53 ABIArgInfo classifyReturnType(QualType RetTy, unsigned ABIVLen) const;
54
55 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
56 AggValueSlot Slot) const override;
57
58 ABIArgInfo extendType(QualType Ty, llvm::Type *CoerceTy = nullptr) const;
59
60 bool detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
61 CharUnits &Field1Off, llvm::Type *&Field2Ty,
62 CharUnits &Field2Off, int &NeededArgGPRs,
63 int &NeededArgFPRs) const;
64 ABIArgInfo coerceAndExpandFPCCEligibleStruct(llvm::Type *Field1Ty,
65 CharUnits Field1Off,
66 llvm::Type *Field2Ty,
67 CharUnits Field2Off) const;
68
69 ABIArgInfo coerceVLSVector(QualType Ty, unsigned ABIVLen = 0) const;
70
71 using ABIInfo::appendAttributeMangling;
72 void appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
73 raw_ostream &Out) const override;
74 void appendAttributeMangling(StringRef AttrStr,
75 raw_ostream &Out) const override;
76};
77} // end anonymous namespace
78
79void RISCVABIInfo::appendAttributeMangling(TargetClonesAttr *Attr,
80 unsigned Index,
81 raw_ostream &Out) const {
82 appendAttributeMangling(AttrStr: Attr->getFeatureStr(Index), Out);
83}
84
85void RISCVABIInfo::appendAttributeMangling(StringRef AttrStr,
86 raw_ostream &Out) const {
87 if (AttrStr == "default") {
88 Out << ".default";
89 return;
90 }
91
92 Out << '.';
93
94 SmallVector<StringRef, 8> Attrs;
95 AttrStr.split(A&: Attrs, Separator: ';');
96
97 // Only consider the arch string.
98 StringRef ArchStr;
99 for (auto &Attr : Attrs) {
100 if (Attr.starts_with(Prefix: "arch="))
101 ArchStr = Attr;
102 }
103
104 // Extract features string.
105 SmallVector<StringRef, 8> Features;
106 ArchStr.consume_front(Prefix: "arch=");
107 ArchStr.split(A&: Features, Separator: ',');
108
109 llvm::stable_sort(Range&: Features);
110
111 for (auto Feat : Features) {
112 Feat.consume_front(Prefix: "+");
113 Out << "_" << Feat;
114 }
115}
116
117void RISCVABIInfo::computeInfo(CGFunctionInfo &FI) const {
118 unsigned ABIVLen;
119 switch (FI.getExtInfo().getCC()) {
120 default:
121 ABIVLen = 0;
122 break;
123#define CC_VLS_CASE(ABI_VLEN) \
124 case CallingConv::CC_RISCVVLSCall_##ABI_VLEN: \
125 ABIVLen = ABI_VLEN; \
126 break;
127 CC_VLS_CASE(32)
128 CC_VLS_CASE(64)
129 CC_VLS_CASE(128)
130 CC_VLS_CASE(256)
131 CC_VLS_CASE(512)
132 CC_VLS_CASE(1024)
133 CC_VLS_CASE(2048)
134 CC_VLS_CASE(4096)
135 CC_VLS_CASE(8192)
136 CC_VLS_CASE(16384)
137 CC_VLS_CASE(32768)
138 CC_VLS_CASE(65536)
139#undef CC_VLS_CASE
140 }
141 QualType RetTy = FI.getReturnType();
142 if (!getCXXABI().classifyReturnType(FI))
143 FI.getReturnInfo() = classifyReturnType(RetTy, ABIVLen);
144
145 // IsRetIndirect is true if classifyArgumentType indicated the value should
146 // be passed indirect, or if the type size is a scalar greater than 2*XLen
147 // and not a complex type with elements <= FLen. e.g. fp128 is passed direct
148 // in LLVM IR, relying on the backend lowering code to rewrite the argument
149 // list and pass indirectly on RV32.
150 bool IsRetIndirect = FI.getReturnInfo().getKind() == ABIArgInfo::Indirect;
151 if (!IsRetIndirect && RetTy->isScalarType() &&
152 getContext().getTypeSize(T: RetTy) > (2 * XLen)) {
153 if (RetTy->isComplexType() && FLen) {
154 QualType EltTy = RetTy->castAs<ComplexType>()->getElementType();
155 IsRetIndirect = getContext().getTypeSize(T: EltTy) > FLen;
156 } else {
157 // This is a normal scalar > 2*XLen, such as fp128 on RV32.
158 IsRetIndirect = true;
159 }
160 }
161
162 int ArgGPRsLeft = IsRetIndirect ? NumArgGPRs - 1 : NumArgGPRs;
163 int ArgFPRsLeft = NumArgFPRs;
164 int NumFixedArgs = FI.getNumRequiredArgs();
165
166 int ArgNum = 0;
167 for (auto &ArgInfo : FI.arguments()) {
168 bool IsFixed = ArgNum < NumFixedArgs;
169 ArgInfo.info = classifyArgumentType(Ty: ArgInfo.type, IsFixed, ArgGPRsLeft,
170 ArgFPRsLeft, ABIVLen);
171 ArgNum++;
172 }
173}
174
175// Returns true if the struct is a potential candidate for the floating point
176// calling convention. If this function returns true, the caller is
177// responsible for checking that if there is only a single field then that
178// field is a float.
179bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
180 llvm::Type *&Field1Ty,
181 CharUnits &Field1Off,
182 llvm::Type *&Field2Ty,
183 CharUnits &Field2Off) const {
184 bool IsInt = Ty->isIntegralOrEnumerationType();
185 bool IsFloat = Ty->isRealFloatingType();
186
187 if (IsInt || IsFloat) {
188 uint64_t Size = getContext().getTypeSize(T: Ty);
189 if (IsInt && Size > XLen)
190 return false;
191 // Can't be eligible if larger than the FP registers. Handling of half
192 // precision values has been specified in the ABI, so don't block those.
193 if (IsFloat && Size > FLen)
194 return false;
195 // Can't be eligible if an integer type was already found (int+int pairs
196 // are not eligible).
197 if (IsInt && Field1Ty && Field1Ty->isIntegerTy())
198 return false;
199 if (!Field1Ty) {
200 Field1Ty = CGT.ConvertType(T: Ty);
201 Field1Off = CurOff;
202 return true;
203 }
204 if (!Field2Ty) {
205 Field2Ty = CGT.ConvertType(T: Ty);
206 Field2Off = CurOff;
207 return true;
208 }
209 return false;
210 }
211
212 if (auto CTy = Ty->getAs<ComplexType>()) {
213 if (Field1Ty)
214 return false;
215 QualType EltTy = CTy->getElementType();
216 if (getContext().getTypeSize(T: EltTy) > FLen)
217 return false;
218 Field1Ty = CGT.ConvertType(T: EltTy);
219 Field1Off = CurOff;
220 Field2Ty = Field1Ty;
221 Field2Off = Field1Off + getContext().getTypeSizeInChars(T: EltTy);
222 return true;
223 }
224
225 if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(T: Ty)) {
226 uint64_t ArraySize = ATy->getZExtSize();
227 QualType EltTy = ATy->getElementType();
228 // Non-zero-length arrays of empty records make the struct ineligible for
229 // the FP calling convention in C++.
230 if (const auto *RTy = EltTy->getAs<RecordType>()) {
231 if (ArraySize != 0 && isa<CXXRecordDecl>(Val: RTy->getDecl()) &&
232 isEmptyRecord(Context&: getContext(), T: EltTy, AllowArrays: true, AsIfNoUniqueAddr: true))
233 return false;
234 }
235 CharUnits EltSize = getContext().getTypeSizeInChars(T: EltTy);
236 for (uint64_t i = 0; i < ArraySize; ++i) {
237 bool Ret = detectFPCCEligibleStructHelper(Ty: EltTy, CurOff, Field1Ty,
238 Field1Off, Field2Ty, Field2Off);
239 if (!Ret)
240 return false;
241 CurOff += EltSize;
242 }
243 return true;
244 }
245
246 if (const auto *RTy = Ty->getAs<RecordType>()) {
247 // Structures with either a non-trivial destructor or a non-trivial
248 // copy constructor are not eligible for the FP calling convention.
249 if (getRecordArgABI(T: Ty, CXXABI&: CGT.getCXXABI()))
250 return false;
251 if (isEmptyRecord(Context&: getContext(), T: Ty, AllowArrays: true, AsIfNoUniqueAddr: true))
252 return true;
253 const RecordDecl *RD = RTy->getDecl();
254 // Unions aren't eligible unless they're empty (which is caught above).
255 if (RD->isUnion())
256 return false;
257 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(D: RD);
258 // If this is a C++ record, check the bases first.
259 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(Val: RD)) {
260 for (const CXXBaseSpecifier &B : CXXRD->bases()) {
261 const auto *BDecl =
262 cast<CXXRecordDecl>(Val: B.getType()->castAs<RecordType>()->getDecl());
263 CharUnits BaseOff = Layout.getBaseClassOffset(Base: BDecl);
264 bool Ret = detectFPCCEligibleStructHelper(Ty: B.getType(), CurOff: CurOff + BaseOff,
265 Field1Ty, Field1Off, Field2Ty,
266 Field2Off);
267 if (!Ret)
268 return false;
269 }
270 }
271 int ZeroWidthBitFieldCount = 0;
272 for (const FieldDecl *FD : RD->fields()) {
273 uint64_t FieldOffInBits = Layout.getFieldOffset(FieldNo: FD->getFieldIndex());
274 QualType QTy = FD->getType();
275 if (FD->isBitField()) {
276 unsigned BitWidth = FD->getBitWidthValue();
277 // Allow a bitfield with a type greater than XLen as long as the
278 // bitwidth is XLen or less.
279 if (getContext().getTypeSize(T: QTy) > XLen && BitWidth <= XLen)
280 QTy = getContext().getIntTypeForBitwidth(DestWidth: XLen, Signed: false);
281 if (BitWidth == 0) {
282 ZeroWidthBitFieldCount++;
283 continue;
284 }
285 }
286
287 bool Ret = detectFPCCEligibleStructHelper(
288 Ty: QTy, CurOff: CurOff + getContext().toCharUnitsFromBits(BitSize: FieldOffInBits),
289 Field1Ty, Field1Off, Field2Ty, Field2Off);
290 if (!Ret)
291 return false;
292
293 // As a quirk of the ABI, zero-width bitfields aren't ignored for fp+fp
294 // or int+fp structs, but are ignored for a struct with an fp field and
295 // any number of zero-width bitfields.
296 if (Field2Ty && ZeroWidthBitFieldCount > 0)
297 return false;
298 }
299 return Field1Ty != nullptr;
300 }
301
302 return false;
303}
304
305// Determine if a struct is eligible for passing according to the floating
306// point calling convention (i.e., when flattened it contains a single fp
307// value, fp+fp, or int+fp of appropriate size). If so, NeededArgFPRs and
308// NeededArgGPRs are incremented appropriately.
309bool RISCVABIInfo::detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
310 CharUnits &Field1Off,
311 llvm::Type *&Field2Ty,
312 CharUnits &Field2Off,
313 int &NeededArgGPRs,
314 int &NeededArgFPRs) const {
315 Field1Ty = nullptr;
316 Field2Ty = nullptr;
317 NeededArgGPRs = 0;
318 NeededArgFPRs = 0;
319 bool IsCandidate = detectFPCCEligibleStructHelper(
320 Ty, CurOff: CharUnits::Zero(), Field1Ty, Field1Off, Field2Ty, Field2Off);
321 if (!Field1Ty)
322 return false;
323 // Not really a candidate if we have a single int but no float.
324 if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy())
325 return false;
326 if (!IsCandidate)
327 return false;
328 if (Field1Ty && Field1Ty->isFloatingPointTy())
329 NeededArgFPRs++;
330 else if (Field1Ty)
331 NeededArgGPRs++;
332 if (Field2Ty && Field2Ty->isFloatingPointTy())
333 NeededArgFPRs++;
334 else if (Field2Ty)
335 NeededArgGPRs++;
336 return true;
337}
338
339// Call getCoerceAndExpand for the two-element flattened struct described by
340// Field1Ty, Field1Off, Field2Ty, Field2Off. This method will create an
341// appropriate coerceToType and unpaddedCoerceToType.
342ABIArgInfo RISCVABIInfo::coerceAndExpandFPCCEligibleStruct(
343 llvm::Type *Field1Ty, CharUnits Field1Off, llvm::Type *Field2Ty,
344 CharUnits Field2Off) const {
345 SmallVector<llvm::Type *, 3> CoerceElts;
346 SmallVector<llvm::Type *, 2> UnpaddedCoerceElts;
347 if (!Field1Off.isZero())
348 CoerceElts.push_back(Elt: llvm::ArrayType::get(
349 ElementType: llvm::Type::getInt8Ty(C&: getVMContext()), NumElements: Field1Off.getQuantity()));
350
351 CoerceElts.push_back(Elt: Field1Ty);
352 UnpaddedCoerceElts.push_back(Elt: Field1Ty);
353
354 if (!Field2Ty) {
355 return ABIArgInfo::getCoerceAndExpand(
356 coerceToType: llvm::StructType::get(Context&: getVMContext(), Elements: CoerceElts, isPacked: !Field1Off.isZero()),
357 unpaddedCoerceToType: UnpaddedCoerceElts[0]);
358 }
359
360 CharUnits Field2Align =
361 CharUnits::fromQuantity(Quantity: getDataLayout().getABITypeAlign(Ty: Field2Ty));
362 CharUnits Field1End = Field1Off +
363 CharUnits::fromQuantity(Quantity: getDataLayout().getTypeStoreSize(Ty: Field1Ty));
364 CharUnits Field2OffNoPadNoPack = Field1End.alignTo(Align: Field2Align);
365
366 CharUnits Padding = CharUnits::Zero();
367 if (Field2Off > Field2OffNoPadNoPack)
368 Padding = Field2Off - Field2OffNoPadNoPack;
369 else if (Field2Off != Field2Align && Field2Off > Field1End)
370 Padding = Field2Off - Field1End;
371
372 bool IsPacked = !Field2Off.isMultipleOf(N: Field2Align);
373
374 if (!Padding.isZero())
375 CoerceElts.push_back(Elt: llvm::ArrayType::get(
376 ElementType: llvm::Type::getInt8Ty(C&: getVMContext()), NumElements: Padding.getQuantity()));
377
378 CoerceElts.push_back(Elt: Field2Ty);
379 UnpaddedCoerceElts.push_back(Elt: Field2Ty);
380
381 auto CoerceToType =
382 llvm::StructType::get(Context&: getVMContext(), Elements: CoerceElts, isPacked: IsPacked);
383 auto UnpaddedCoerceToType =
384 llvm::StructType::get(Context&: getVMContext(), Elements: UnpaddedCoerceElts, isPacked: IsPacked);
385
386 return ABIArgInfo::getCoerceAndExpand(coerceToType: CoerceToType, unpaddedCoerceToType: UnpaddedCoerceToType);
387}
388
389bool RISCVABIInfo::detectVLSCCEligibleStruct(QualType Ty, unsigned ABIVLen,
390 llvm::Type *&VLSType) const {
391 // No riscv_vls_cc attribute.
392 if (ABIVLen == 0)
393 return false;
394
395 // Legal struct for VLS calling convention should fulfill following rules:
396 // 1. Struct element should be either "homogeneous fixed-length vectors" or "a
397 // fixed-length vector array".
398 // 2. Number of struct elements or array elements should be greater or equal
399 // to 1 and less or equal to 8
400 // 3. Total number of vector registers needed should not exceed 8.
401 //
402 // Examples: Assume ABI_VLEN = 128.
403 // These are legal structs:
404 // a. Structs with 1~8 "same" fixed-length vectors, e.g.
405 // struct {
406 // __attribute__((vector_size(16))) int a;
407 // __attribute__((vector_size(16))) int b;
408 // }
409 //
410 // b. Structs with "single" fixed-length vector array with lengh 1~8, e.g.
411 // struct {
412 // __attribute__((vector_size(16))) int a[3];
413 // }
414 // These are illegal structs:
415 // a. Structs with 9 fixed-length vectors, e.g.
416 // struct {
417 // __attribute__((vector_size(16))) int a;
418 // __attribute__((vector_size(16))) int b;
419 // __attribute__((vector_size(16))) int c;
420 // __attribute__((vector_size(16))) int d;
421 // __attribute__((vector_size(16))) int e;
422 // __attribute__((vector_size(16))) int f;
423 // __attribute__((vector_size(16))) int g;
424 // __attribute__((vector_size(16))) int h;
425 // __attribute__((vector_size(16))) int i;
426 // }
427 //
428 // b. Structs with "multiple" fixed-length vector array, e.g.
429 // struct {
430 // __attribute__((vector_size(16))) int a[2];
431 // __attribute__((vector_size(16))) int b[2];
432 // }
433 //
434 // c. Vector registers needed exceeds 8, e.g.
435 // struct {
436 // // Registers needed for single fixed-length element:
437 // // 64 * 8 / ABI_VLEN = 4
438 // __attribute__((vector_size(64))) int a;
439 // __attribute__((vector_size(64))) int b;
440 // __attribute__((vector_size(64))) int c;
441 // __attribute__((vector_size(64))) int d;
442 // }
443 //
444 // 1. Struct of 1 fixed-length vector is passed as a scalable vector.
445 // 2. Struct of >1 fixed-length vectors are passed as vector tuple.
446 // 3. Struct of an array with 1 element of fixed-length vectors is passed as a
447 // scalable vector.
448 // 4. Struct of an array with >1 elements of fixed-length vectors is passed as
449 // vector tuple.
450 // 5. Otherwise, pass the struct indirectly.
451
452 llvm::StructType *STy = dyn_cast<llvm::StructType>(Val: CGT.ConvertType(T: Ty));
453 if (!STy)
454 return false;
455
456 unsigned NumElts = STy->getStructNumElements();
457 if (NumElts > 8)
458 return false;
459
460 auto *FirstEltTy = STy->getElementType(N: 0);
461 if (!STy->containsHomogeneousTypes())
462 return false;
463
464 if (auto *ArrayTy = dyn_cast<llvm::ArrayType>(Val: FirstEltTy)) {
465 // Only struct of single array is accepted
466 if (NumElts != 1)
467 return false;
468 FirstEltTy = ArrayTy->getArrayElementType();
469 NumElts = ArrayTy->getNumElements();
470 }
471
472 auto *FixedVecTy = dyn_cast<llvm::FixedVectorType>(Val: FirstEltTy);
473 if (!FixedVecTy)
474 return false;
475
476 // Check registers needed <= 8.
477 if (NumElts * llvm::divideCeil(
478 Numerator: FixedVecTy->getNumElements() *
479 FixedVecTy->getElementType()->getScalarSizeInBits(),
480 Denominator: ABIVLen) >
481 8)
482 return false;
483
484 // Turn them into scalable vector type or vector tuple type if legal.
485 if (NumElts == 1) {
486 // Handle single fixed-length vector.
487 VLSType = llvm::ScalableVectorType::get(
488 ElementType: FixedVecTy->getElementType(),
489 MinNumElts: llvm::divideCeil(Numerator: FixedVecTy->getNumElements() *
490 llvm::RISCV::RVVBitsPerBlock,
491 Denominator: ABIVLen));
492 return true;
493 }
494
495 // LMUL
496 // = fixed-length vector size / ABIVLen
497 // = 8 * I8EltCount / RVVBitsPerBlock
498 // =>
499 // I8EltCount
500 // = (fixed-length vector size * RVVBitsPerBlock) / (ABIVLen * 8)
501 unsigned I8EltCount =
502 llvm::divideCeil(Numerator: FixedVecTy->getNumElements() *
503 FixedVecTy->getElementType()->getScalarSizeInBits() *
504 llvm::RISCV::RVVBitsPerBlock,
505 Denominator: ABIVLen * 8);
506 VLSType = llvm::TargetExtType::get(
507 Context&: getVMContext(), Name: "riscv.vector.tuple",
508 Types: llvm::ScalableVectorType::get(ElementType: llvm::Type::getInt8Ty(C&: getVMContext()),
509 MinNumElts: I8EltCount),
510 Ints: NumElts);
511 return true;
512}
513
514// Fixed-length RVV vectors are represented as scalable vectors in function
515// args/return and must be coerced from fixed vectors.
516ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty, unsigned ABIVLen) const {
517 assert(Ty->isVectorType() && "expected vector type!");
518
519 const auto *VT = Ty->castAs<VectorType>();
520 assert(VT->getElementType()->isBuiltinType() && "expected builtin type!");
521
522 auto VScale = getContext().getTargetInfo().getVScaleRange(
523 LangOpts: getContext().getLangOpts(), Mode: TargetInfo::ArmStreamingKind::NotStreaming);
524
525 unsigned NumElts = VT->getNumElements();
526 llvm::Type *EltType = llvm::Type::getInt1Ty(C&: getVMContext());
527 switch (VT->getVectorKind()) {
528 case VectorKind::RVVFixedLengthMask_1:
529 break;
530 case VectorKind::RVVFixedLengthMask_2:
531 NumElts *= 2;
532 break;
533 case VectorKind::RVVFixedLengthMask_4:
534 NumElts *= 4;
535 break;
536 case VectorKind::RVVFixedLengthMask:
537 NumElts *= 8;
538 break;
539 default:
540 assert((VT->getVectorKind() == VectorKind::Generic ||
541 VT->getVectorKind() == VectorKind::RVVFixedLengthData) &&
542 "Unexpected vector kind");
543 EltType = CGT.ConvertType(T: VT->getElementType());
544 }
545
546 llvm::ScalableVectorType *ResType;
547
548 if (ABIVLen == 0) {
549 // The MinNumElts is simplified from equation:
550 // NumElts / VScale =
551 // (EltSize * NumElts / (VScale * RVVBitsPerBlock))
552 // * (RVVBitsPerBlock / EltSize)
553 ResType = llvm::ScalableVectorType::get(ElementType: EltType, MinNumElts: NumElts / VScale->first);
554 } else {
555 // Check registers needed <= 8.
556 if ((EltType->getScalarSizeInBits() * NumElts / ABIVLen) > 8)
557 return getNaturalAlignIndirect(
558 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
559 /*ByVal=*/false);
560
561 // Generic vector
562 // The number of elements needs to be at least 1.
563 ResType = llvm::ScalableVectorType::get(
564 ElementType: EltType,
565 MinNumElts: llvm::divideCeil(Numerator: NumElts * llvm::RISCV::RVVBitsPerBlock, Denominator: ABIVLen));
566
567 // If the corresponding extension is not supported, just make it an i8
568 // vector with same LMUL.
569 const TargetInfo &TI = getContext().getTargetInfo();
570 if ((EltType->isHalfTy() && !TI.hasFeature(Feature: "zvfhmin")) ||
571 (EltType->isBFloatTy() && !TI.hasFeature(Feature: "zvfbfmin")) ||
572 (EltType->isFloatTy() && !TI.hasFeature(Feature: "zve32f")) ||
573 (EltType->isDoubleTy() && !TI.hasFeature(Feature: "zve64d")) ||
574 (EltType->isIntegerTy(Bitwidth: 64) && !TI.hasFeature(Feature: "zve64x")) ||
575 EltType->isIntegerTy(Bitwidth: 128)) {
576 // The number of elements needs to be at least 1.
577 ResType = llvm::ScalableVectorType::get(
578 ElementType: llvm::Type::getInt8Ty(C&: getVMContext()),
579 MinNumElts: llvm::divideCeil(Numerator: EltType->getScalarSizeInBits() * NumElts *
580 llvm::RISCV::RVVBitsPerBlock,
581 Denominator: 8 * ABIVLen));
582 }
583 }
584
585 return ABIArgInfo::getDirect(T: ResType);
586}
587
588ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
589 int &ArgGPRsLeft,
590 int &ArgFPRsLeft,
591 unsigned ABIVLen) const {
592 assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
593 Ty = useFirstFieldIfTransparentUnion(Ty);
594
595 // Structures with either a non-trivial destructor or a non-trivial
596 // copy constructor are always passed indirectly.
597 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(T: Ty, CXXABI&: getCXXABI())) {
598 if (ArgGPRsLeft)
599 ArgGPRsLeft -= 1;
600 return getNaturalAlignIndirect(
601 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
602 /*ByVal=*/RAA == CGCXXABI::RAA_DirectInMemory);
603 }
604
605 uint64_t Size = getContext().getTypeSize(T: Ty);
606
607 // Ignore empty structs/unions whose size is zero. According to the calling
608 // convention empty structs/unions are required to be sized types in C++.
609 if (isEmptyRecord(Context&: getContext(), T: Ty, AllowArrays: true) && Size == 0)
610 return ABIArgInfo::getIgnore();
611
612 // Pass floating point values via FPRs if possible.
613 if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
614 FLen >= Size && ArgFPRsLeft) {
615 ArgFPRsLeft--;
616 return ABIArgInfo::getDirect();
617 }
618
619 // Complex types for the hard float ABI must be passed direct rather than
620 // using CoerceAndExpand.
621 if (IsFixed && Ty->isComplexType() && FLen && ArgFPRsLeft >= 2) {
622 QualType EltTy = Ty->castAs<ComplexType>()->getElementType();
623 if (getContext().getTypeSize(T: EltTy) <= FLen) {
624 ArgFPRsLeft -= 2;
625 return ABIArgInfo::getDirect();
626 }
627 }
628
629 if (IsFixed && FLen && Ty->isStructureOrClassType()) {
630 llvm::Type *Field1Ty = nullptr;
631 llvm::Type *Field2Ty = nullptr;
632 CharUnits Field1Off = CharUnits::Zero();
633 CharUnits Field2Off = CharUnits::Zero();
634 int NeededArgGPRs = 0;
635 int NeededArgFPRs = 0;
636 bool IsCandidate =
637 detectFPCCEligibleStruct(Ty, Field1Ty, Field1Off, Field2Ty, Field2Off,
638 NeededArgGPRs, NeededArgFPRs);
639 if (IsCandidate && NeededArgGPRs <= ArgGPRsLeft &&
640 NeededArgFPRs <= ArgFPRsLeft) {
641 ArgGPRsLeft -= NeededArgGPRs;
642 ArgFPRsLeft -= NeededArgFPRs;
643 return coerceAndExpandFPCCEligibleStruct(Field1Ty, Field1Off, Field2Ty,
644 Field2Off);
645 }
646 }
647
648 if (IsFixed && Ty->isStructureOrClassType()) {
649 llvm::Type *VLSType = nullptr;
650 if (detectVLSCCEligibleStruct(Ty, ABIVLen, VLSType))
651 return ABIArgInfo::getDirect(T: VLSType);
652 }
653
654 uint64_t NeededAlign = getContext().getTypeAlign(T: Ty);
655 // Determine the number of GPRs needed to pass the current argument
656 // according to the ABI. 2*XLen-aligned varargs are passed in "aligned"
657 // register pairs, so may consume 3 registers.
658 // TODO: To be compatible with GCC's behaviors, we don't align registers
659 // currently if we are using ILP32E calling convention. This behavior may be
660 // changed when RV32E/ILP32E is ratified.
661 int NeededArgGPRs = 1;
662 if (!IsFixed && NeededAlign == 2 * XLen)
663 NeededArgGPRs = 2 + (EABI && XLen == 32 ? 0 : (ArgGPRsLeft % 2));
664 else if (Size > XLen && Size <= 2 * XLen)
665 NeededArgGPRs = 2;
666
667 if (NeededArgGPRs > ArgGPRsLeft) {
668 NeededArgGPRs = ArgGPRsLeft;
669 }
670
671 ArgGPRsLeft -= NeededArgGPRs;
672
673 if (!isAggregateTypeForABI(T: Ty) && !Ty->isVectorType()) {
674 // Treat an enum type as its underlying type.
675 if (const EnumType *EnumTy = Ty->getAs<EnumType>())
676 Ty = EnumTy->getDecl()->getIntegerType();
677
678 // All integral types are promoted to XLen width
679 if (Size < XLen && Ty->isIntegralOrEnumerationType()) {
680 return extendType(Ty, CoerceTy: CGT.ConvertType(T: Ty));
681 }
682
683 if (const auto *EIT = Ty->getAs<BitIntType>()) {
684 if (EIT->getNumBits() < XLen)
685 return extendType(Ty, CoerceTy: CGT.ConvertType(T: Ty));
686 if (EIT->getNumBits() > 128 ||
687 (!getContext().getTargetInfo().hasInt128Type() &&
688 EIT->getNumBits() > 64))
689 return getNaturalAlignIndirect(
690 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
691 /*ByVal=*/false);
692 }
693
694 return ABIArgInfo::getDirect();
695 }
696
697 // TODO: _BitInt is not handled yet in VLS calling convention since _BitInt
698 // ABI is also not merged yet in RISC-V:
699 // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/419
700 if (const VectorType *VT = Ty->getAs<VectorType>();
701 VT && !VT->getElementType()->isBitIntType()) {
702 if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||
703 VT->getVectorKind() == VectorKind::RVVFixedLengthMask ||
704 VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1 ||
705 VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2 ||
706 VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4)
707 return coerceVLSVector(Ty);
708 if (VT->getVectorKind() == VectorKind::Generic && ABIVLen != 0)
709 // Generic vector without riscv_vls_cc should fall through and pass by
710 // reference.
711 return coerceVLSVector(Ty, ABIVLen);
712 }
713
714 // Aggregates which are <= 2*XLen will be passed in registers if possible,
715 // so coerce to integers.
716 if (Size <= 2 * XLen) {
717 unsigned Alignment = getContext().getTypeAlign(T: Ty);
718
719 // Use a single XLen int if possible, 2*XLen if 2*XLen alignment is
720 // required, and a 2-element XLen array if only XLen alignment is required.
721 if (Size <= XLen) {
722 return ABIArgInfo::getDirect(
723 T: llvm::IntegerType::get(C&: getVMContext(), NumBits: XLen));
724 } else if (Alignment == 2 * XLen) {
725 return ABIArgInfo::getDirect(
726 T: llvm::IntegerType::get(C&: getVMContext(), NumBits: 2 * XLen));
727 } else {
728 return ABIArgInfo::getDirect(T: llvm::ArrayType::get(
729 ElementType: llvm::IntegerType::get(C&: getVMContext(), NumBits: XLen), NumElements: 2));
730 }
731 }
732 return getNaturalAlignIndirect(
733 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
734 /*ByVal=*/false);
735}
736
737ABIArgInfo RISCVABIInfo::classifyReturnType(QualType RetTy,
738 unsigned ABIVLen) const {
739 if (RetTy->isVoidType())
740 return ABIArgInfo::getIgnore();
741
742 int ArgGPRsLeft = 2;
743 int ArgFPRsLeft = FLen ? 2 : 0;
744
745 // The rules for return and argument types are the same, so defer to
746 // classifyArgumentType.
747 return classifyArgumentType(Ty: RetTy, /*IsFixed=*/true, ArgGPRsLeft, ArgFPRsLeft,
748 ABIVLen);
749}
750
751RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
752 QualType Ty, AggValueSlot Slot) const {
753 CharUnits SlotSize = CharUnits::fromQuantity(Quantity: XLen / 8);
754
755 // Empty records are ignored for parameter passing purposes.
756 if (isEmptyRecord(Context&: getContext(), T: Ty, AllowArrays: true))
757 return Slot.asRValue();
758
759 auto TInfo = getContext().getTypeInfoInChars(T: Ty);
760
761 // TODO: To be compatible with GCC's behaviors, we force arguments with
762 // 2×XLEN-bit alignment and size at most 2×XLEN bits like `long long`,
763 // `unsigned long long` and `double` to have 4-byte alignment. This
764 // behavior may be changed when RV32E/ILP32E is ratified.
765 if (EABI && XLen == 32)
766 TInfo.Align = std::min(a: TInfo.Align, b: CharUnits::fromQuantity(Quantity: 4));
767
768 // Arguments bigger than 2*Xlen bytes are passed indirectly.
769 bool IsIndirect = TInfo.Width > 2 * SlotSize;
770
771 return emitVoidPtrVAArg(CGF, VAListAddr, ValueTy: Ty, IsIndirect, ValueInfo: TInfo, SlotSizeAndAlign: SlotSize,
772 /*AllowHigherAlign=*/true, Slot);
773}
774
775ABIArgInfo RISCVABIInfo::extendType(QualType Ty, llvm::Type *CoerceTy) const {
776 int TySize = getContext().getTypeSize(T: Ty);
777 // RV64 ABI requires unsigned 32 bit integers to be sign extended.
778 if (XLen == 64 && Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32)
779 return ABIArgInfo::getSignExtend(Ty, T: CoerceTy);
780 return ABIArgInfo::getExtend(Ty, T: CoerceTy);
781}
782
783namespace {
784class RISCVTargetCodeGenInfo : public TargetCodeGenInfo {
785public:
786 RISCVTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen,
787 unsigned FLen, bool EABI)
788 : TargetCodeGenInfo(
789 std::make_unique<RISCVABIInfo>(args&: CGT, args&: XLen, args&: FLen, args&: EABI)) {
790 SwiftInfo =
791 std::make_unique<SwiftABIInfo>(args&: CGT, /*SwiftErrorInRegister=*/args: false);
792 }
793
794 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
795 CodeGen::CodeGenModule &CGM) const override {
796 const auto *FD = dyn_cast_or_null<FunctionDecl>(Val: D);
797 if (!FD) return;
798
799 auto *Fn = cast<llvm::Function>(Val: GV);
800
801 if (CGM.getCodeGenOpts().CFProtectionReturn)
802 Fn->addFnAttr(Kind: "hw-shadow-stack");
803
804 const auto *Attr = FD->getAttr<RISCVInterruptAttr>();
805 if (!Attr)
806 return;
807
808 StringRef Kind = "machine";
809 bool HasSiFiveCLICPreemptible = false;
810 bool HasSiFiveCLICStackSwap = false;
811 for (RISCVInterruptAttr::InterruptType type : Attr->interrupt()) {
812 switch (type) {
813 case RISCVInterruptAttr::machine:
814 // Do not update `Kind` because `Kind` is already "machine", or the
815 // kinds also contains SiFive types which need to be applied.
816 break;
817 case RISCVInterruptAttr::supervisor:
818 Kind = "supervisor";
819 break;
820 case RISCVInterruptAttr::qcinest:
821 Kind = "qci-nest";
822 break;
823 case RISCVInterruptAttr::qcinonest:
824 Kind = "qci-nonest";
825 break;
826 // There are three different LLVM IR attribute values for SiFive CLIC
827 // interrupt kinds, one for each kind and one extra for their combination.
828 case RISCVInterruptAttr::SiFiveCLICPreemptible: {
829 HasSiFiveCLICPreemptible = true;
830 Kind = HasSiFiveCLICStackSwap ? "SiFive-CLIC-preemptible-stack-swap"
831 : "SiFive-CLIC-preemptible";
832 break;
833 }
834 case RISCVInterruptAttr::SiFiveCLICStackSwap: {
835 HasSiFiveCLICStackSwap = true;
836 Kind = HasSiFiveCLICPreemptible ? "SiFive-CLIC-preemptible-stack-swap"
837 : "SiFive-CLIC-stack-swap";
838 break;
839 }
840 }
841 }
842
843 Fn->addFnAttr(Kind: "interrupt", Val: Kind);
844 }
845};
846} // namespace
847
848std::unique_ptr<TargetCodeGenInfo>
849CodeGen::createRISCVTargetCodeGenInfo(CodeGenModule &CGM, unsigned XLen,
850 unsigned FLen, bool EABI) {
851 return std::make_unique<RISCVTargetCodeGenInfo>(args&: CGM.getTypes(), args&: XLen, args&: FLen,
852 args&: EABI);
853}
854

source code of clang/lib/CodeGen/Targets/RISCV.cpp