clang 20.0.0git
RISCV.cpp
Go to the documentation of this file.
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
12using namespace clang;
13using namespace clang::CodeGen;
14
15//===----------------------------------------------------------------------===//
16// RISC-V ABI Implementation
17//===----------------------------------------------------------------------===//
18
19namespace {
20class RISCVABIInfo : public DefaultABIInfo {
21private:
22 // Size of the integer ('x') registers in bits.
23 unsigned XLen;
24 // Size of the floating point ('f') registers in bits. Note that the target
25 // ISA might have a wider FLen than the selected ABI (e.g. an RV32IF target
26 // with soft float ABI has FLen==0).
27 unsigned FLen;
28 const int NumArgGPRs;
29 const int NumArgFPRs;
30 const bool EABI;
31 bool detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
32 llvm::Type *&Field1Ty,
33 CharUnits &Field1Off,
34 llvm::Type *&Field2Ty,
35 CharUnits &Field2Off) const;
36
37public:
38 RISCVABIInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, unsigned FLen,
39 bool EABI)
40 : DefaultABIInfo(CGT), XLen(XLen), FLen(FLen), NumArgGPRs(EABI ? 6 : 8),
41 NumArgFPRs(FLen != 0 ? 8 : 0), EABI(EABI) {}
42
43 // DefaultABIInfo's classifyReturnType and classifyArgumentType are
44 // non-virtual, but computeInfo is virtual, so we overload it.
45 void computeInfo(CGFunctionInfo &FI) const override;
46
47 ABIArgInfo classifyArgumentType(QualType Ty, bool IsFixed, int &ArgGPRsLeft,
48 int &ArgFPRsLeft) const;
50
51 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
52 AggValueSlot Slot) const override;
53
54 ABIArgInfo extendType(QualType Ty) const;
55
56 bool detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
57 CharUnits &Field1Off, llvm::Type *&Field2Ty,
58 CharUnits &Field2Off, int &NeededArgGPRs,
59 int &NeededArgFPRs) const;
60 ABIArgInfo coerceAndExpandFPCCEligibleStruct(llvm::Type *Field1Ty,
61 CharUnits Field1Off,
62 llvm::Type *Field2Ty,
63 CharUnits Field2Off) const;
64
65 ABIArgInfo coerceVLSVector(QualType Ty) const;
66};
67} // end anonymous namespace
68
69void RISCVABIInfo::computeInfo(CGFunctionInfo &FI) const {
70 QualType RetTy = FI.getReturnType();
71 if (!getCXXABI().classifyReturnType(FI))
73
74 // IsRetIndirect is true if classifyArgumentType indicated the value should
75 // be passed indirect, or if the type size is a scalar greater than 2*XLen
76 // and not a complex type with elements <= FLen. e.g. fp128 is passed direct
77 // in LLVM IR, relying on the backend lowering code to rewrite the argument
78 // list and pass indirectly on RV32.
79 bool IsRetIndirect = FI.getReturnInfo().getKind() == ABIArgInfo::Indirect;
80 if (!IsRetIndirect && RetTy->isScalarType() &&
81 getContext().getTypeSize(RetTy) > (2 * XLen)) {
82 if (RetTy->isComplexType() && FLen) {
83 QualType EltTy = RetTy->castAs<ComplexType>()->getElementType();
84 IsRetIndirect = getContext().getTypeSize(EltTy) > FLen;
85 } else {
86 // This is a normal scalar > 2*XLen, such as fp128 on RV32.
87 IsRetIndirect = true;
88 }
89 }
90
91 int ArgGPRsLeft = IsRetIndirect ? NumArgGPRs - 1 : NumArgGPRs;
92 int ArgFPRsLeft = NumArgFPRs;
93 int NumFixedArgs = FI.getNumRequiredArgs();
94
95 int ArgNum = 0;
96 for (auto &ArgInfo : FI.arguments()) {
97 bool IsFixed = ArgNum < NumFixedArgs;
98 ArgInfo.info =
99 classifyArgumentType(ArgInfo.type, IsFixed, ArgGPRsLeft, ArgFPRsLeft);
100 ArgNum++;
101 }
102}
103
104// Returns true if the struct is a potential candidate for the floating point
105// calling convention. If this function returns true, the caller is
106// responsible for checking that if there is only a single field then that
107// field is a float.
108bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
109 llvm::Type *&Field1Ty,
110 CharUnits &Field1Off,
111 llvm::Type *&Field2Ty,
112 CharUnits &Field2Off) const {
113 bool IsInt = Ty->isIntegralOrEnumerationType();
114 bool IsFloat = Ty->isRealFloatingType();
115
116 if (IsInt || IsFloat) {
117 uint64_t Size = getContext().getTypeSize(Ty);
118 if (IsInt && Size > XLen)
119 return false;
120 // Can't be eligible if larger than the FP registers. Handling of half
121 // precision values has been specified in the ABI, so don't block those.
122 if (IsFloat && Size > FLen)
123 return false;
124 // Can't be eligible if an integer type was already found (int+int pairs
125 // are not eligible).
126 if (IsInt && Field1Ty && Field1Ty->isIntegerTy())
127 return false;
128 if (!Field1Ty) {
129 Field1Ty = CGT.ConvertType(Ty);
130 Field1Off = CurOff;
131 return true;
132 }
133 if (!Field2Ty) {
134 Field2Ty = CGT.ConvertType(Ty);
135 Field2Off = CurOff;
136 return true;
137 }
138 return false;
139 }
140
141 if (auto CTy = Ty->getAs<ComplexType>()) {
142 if (Field1Ty)
143 return false;
144 QualType EltTy = CTy->getElementType();
145 if (getContext().getTypeSize(EltTy) > FLen)
146 return false;
147 Field1Ty = CGT.ConvertType(EltTy);
148 Field1Off = CurOff;
149 Field2Ty = Field1Ty;
150 Field2Off = Field1Off + getContext().getTypeSizeInChars(EltTy);
151 return true;
152 }
153
154 if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) {
155 uint64_t ArraySize = ATy->getZExtSize();
156 QualType EltTy = ATy->getElementType();
157 // Non-zero-length arrays of empty records make the struct ineligible for
158 // the FP calling convention in C++.
159 if (const auto *RTy = EltTy->getAs<RecordType>()) {
160 if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) &&
161 isEmptyRecord(getContext(), EltTy, true, true))
162 return false;
163 }
164 CharUnits EltSize = getContext().getTypeSizeInChars(EltTy);
165 for (uint64_t i = 0; i < ArraySize; ++i) {
166 bool Ret = detectFPCCEligibleStructHelper(EltTy, CurOff, Field1Ty,
167 Field1Off, Field2Ty, Field2Off);
168 if (!Ret)
169 return false;
170 CurOff += EltSize;
171 }
172 return true;
173 }
174
175 if (const auto *RTy = Ty->getAs<RecordType>()) {
176 // Structures with either a non-trivial destructor or a non-trivial
177 // copy constructor are not eligible for the FP calling convention.
178 if (getRecordArgABI(Ty, CGT.getCXXABI()))
179 return false;
180 if (isEmptyRecord(getContext(), Ty, true, true))
181 return true;
182 const RecordDecl *RD = RTy->getDecl();
183 // Unions aren't eligible unless they're empty (which is caught above).
184 if (RD->isUnion())
185 return false;
186 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
187 // If this is a C++ record, check the bases first.
188 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
189 for (const CXXBaseSpecifier &B : CXXRD->bases()) {
190 const auto *BDecl =
191 cast<CXXRecordDecl>(B.getType()->castAs<RecordType>()->getDecl());
192 CharUnits BaseOff = Layout.getBaseClassOffset(BDecl);
193 bool Ret = detectFPCCEligibleStructHelper(B.getType(), CurOff + BaseOff,
194 Field1Ty, Field1Off, Field2Ty,
195 Field2Off);
196 if (!Ret)
197 return false;
198 }
199 }
200 int ZeroWidthBitFieldCount = 0;
201 for (const FieldDecl *FD : RD->fields()) {
202 uint64_t FieldOffInBits = Layout.getFieldOffset(FD->getFieldIndex());
203 QualType QTy = FD->getType();
204 if (FD->isBitField()) {
205 unsigned BitWidth = FD->getBitWidthValue(getContext());
206 // Allow a bitfield with a type greater than XLen as long as the
207 // bitwidth is XLen or less.
208 if (getContext().getTypeSize(QTy) > XLen && BitWidth <= XLen)
209 QTy = getContext().getIntTypeForBitwidth(XLen, false);
210 if (BitWidth == 0) {
211 ZeroWidthBitFieldCount++;
212 continue;
213 }
214 }
215
216 bool Ret = detectFPCCEligibleStructHelper(
217 QTy, CurOff + getContext().toCharUnitsFromBits(FieldOffInBits),
218 Field1Ty, Field1Off, Field2Ty, Field2Off);
219 if (!Ret)
220 return false;
221
222 // As a quirk of the ABI, zero-width bitfields aren't ignored for fp+fp
223 // or int+fp structs, but are ignored for a struct with an fp field and
224 // any number of zero-width bitfields.
225 if (Field2Ty && ZeroWidthBitFieldCount > 0)
226 return false;
227 }
228 return Field1Ty != nullptr;
229 }
230
231 return false;
232}
233
234// Determine if a struct is eligible for passing according to the floating
235// point calling convention (i.e., when flattened it contains a single fp
236// value, fp+fp, or int+fp of appropriate size). If so, NeededArgFPRs and
237// NeededArgGPRs are incremented appropriately.
238bool RISCVABIInfo::detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
239 CharUnits &Field1Off,
240 llvm::Type *&Field2Ty,
241 CharUnits &Field2Off,
242 int &NeededArgGPRs,
243 int &NeededArgFPRs) const {
244 Field1Ty = nullptr;
245 Field2Ty = nullptr;
246 NeededArgGPRs = 0;
247 NeededArgFPRs = 0;
248 bool IsCandidate = detectFPCCEligibleStructHelper(
249 Ty, CharUnits::Zero(), Field1Ty, Field1Off, Field2Ty, Field2Off);
250 if (!Field1Ty)
251 return false;
252 // Not really a candidate if we have a single int but no float.
253 if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy())
254 return false;
255 if (!IsCandidate)
256 return false;
257 if (Field1Ty && Field1Ty->isFloatingPointTy())
258 NeededArgFPRs++;
259 else if (Field1Ty)
260 NeededArgGPRs++;
261 if (Field2Ty && Field2Ty->isFloatingPointTy())
262 NeededArgFPRs++;
263 else if (Field2Ty)
264 NeededArgGPRs++;
265 return true;
266}
267
268// Call getCoerceAndExpand for the two-element flattened struct described by
269// Field1Ty, Field1Off, Field2Ty, Field2Off. This method will create an
270// appropriate coerceToType and unpaddedCoerceToType.
271ABIArgInfo RISCVABIInfo::coerceAndExpandFPCCEligibleStruct(
272 llvm::Type *Field1Ty, CharUnits Field1Off, llvm::Type *Field2Ty,
273 CharUnits Field2Off) const {
275 SmallVector<llvm::Type *, 2> UnpaddedCoerceElts;
276 if (!Field1Off.isZero())
277 CoerceElts.push_back(llvm::ArrayType::get(
278 llvm::Type::getInt8Ty(getVMContext()), Field1Off.getQuantity()));
279
280 CoerceElts.push_back(Field1Ty);
281 UnpaddedCoerceElts.push_back(Field1Ty);
282
283 if (!Field2Ty) {
285 llvm::StructType::get(getVMContext(), CoerceElts, !Field1Off.isZero()),
286 UnpaddedCoerceElts[0]);
287 }
288
289 CharUnits Field2Align =
290 CharUnits::fromQuantity(getDataLayout().getABITypeAlign(Field2Ty));
291 CharUnits Field1End = Field1Off +
292 CharUnits::fromQuantity(getDataLayout().getTypeStoreSize(Field1Ty));
293 CharUnits Field2OffNoPadNoPack = Field1End.alignTo(Field2Align);
294
295 CharUnits Padding = CharUnits::Zero();
296 if (Field2Off > Field2OffNoPadNoPack)
297 Padding = Field2Off - Field2OffNoPadNoPack;
298 else if (Field2Off != Field2Align && Field2Off > Field1End)
299 Padding = Field2Off - Field1End;
300
301 bool IsPacked = !Field2Off.isMultipleOf(Field2Align);
302
303 if (!Padding.isZero())
304 CoerceElts.push_back(llvm::ArrayType::get(
305 llvm::Type::getInt8Ty(getVMContext()), Padding.getQuantity()));
306
307 CoerceElts.push_back(Field2Ty);
308 UnpaddedCoerceElts.push_back(Field2Ty);
309
310 auto CoerceToType =
311 llvm::StructType::get(getVMContext(), CoerceElts, IsPacked);
312 auto UnpaddedCoerceToType =
313 llvm::StructType::get(getVMContext(), UnpaddedCoerceElts, IsPacked);
314
315 return ABIArgInfo::getCoerceAndExpand(CoerceToType, UnpaddedCoerceToType);
316}
317
318// Fixed-length RVV vectors are represented as scalable vectors in function
319// args/return and must be coerced from fixed vectors.
320ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty) const {
321 assert(Ty->isVectorType() && "expected vector type!");
322
323 const auto *VT = Ty->castAs<VectorType>();
324 assert(VT->getElementType()->isBuiltinType() && "expected builtin type!");
325
326 auto VScale =
327 getContext().getTargetInfo().getVScaleRange(getContext().getLangOpts());
328
329 unsigned NumElts = VT->getNumElements();
330 llvm::Type *EltType = llvm::Type::getInt1Ty(getVMContext());
331 switch (VT->getVectorKind()) {
332 case VectorKind::RVVFixedLengthMask_1:
333 break;
334 case VectorKind::RVVFixedLengthMask_2:
335 NumElts *= 2;
336 break;
337 case VectorKind::RVVFixedLengthMask_4:
338 NumElts *= 4;
339 break;
340 case VectorKind::RVVFixedLengthMask:
341 NumElts *= 8;
342 break;
343 default:
344 assert(VT->getVectorKind() == VectorKind::RVVFixedLengthData &&
345 "Unexpected vector kind");
346 EltType = CGT.ConvertType(VT->getElementType());
347 }
348
349 // The MinNumElts is simplified from equation:
350 // NumElts / VScale =
351 // (EltSize * NumElts / (VScale * RVVBitsPerBlock))
352 // * (RVVBitsPerBlock / EltSize)
353 llvm::ScalableVectorType *ResType =
354 llvm::ScalableVectorType::get(EltType, NumElts / VScale->first);
355 return ABIArgInfo::getDirect(ResType);
356}
357
358ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
359 int &ArgGPRsLeft,
360 int &ArgFPRsLeft) const {
361 assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
363
364 // Structures with either a non-trivial destructor or a non-trivial
365 // copy constructor are always passed indirectly.
366 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
367 if (ArgGPRsLeft)
368 ArgGPRsLeft -= 1;
369 return getNaturalAlignIndirect(Ty, /*ByVal=*/RAA ==
371 }
372
373 uint64_t Size = getContext().getTypeSize(Ty);
374
375 // Ignore empty structs/unions whose size is zero. According to the calling
376 // convention empty structs/unions are required to be sized types in C++.
377 if (isEmptyRecord(getContext(), Ty, true) && Size == 0)
378 return ABIArgInfo::getIgnore();
379
380 // Pass floating point values via FPRs if possible.
381 if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
382 FLen >= Size && ArgFPRsLeft) {
383 ArgFPRsLeft--;
384 return ABIArgInfo::getDirect();
385 }
386
387 // Complex types for the hard float ABI must be passed direct rather than
388 // using CoerceAndExpand.
389 if (IsFixed && Ty->isComplexType() && FLen && ArgFPRsLeft >= 2) {
390 QualType EltTy = Ty->castAs<ComplexType>()->getElementType();
391 if (getContext().getTypeSize(EltTy) <= FLen) {
392 ArgFPRsLeft -= 2;
393 return ABIArgInfo::getDirect();
394 }
395 }
396
397 if (IsFixed && FLen && Ty->isStructureOrClassType()) {
398 llvm::Type *Field1Ty = nullptr;
399 llvm::Type *Field2Ty = nullptr;
400 CharUnits Field1Off = CharUnits::Zero();
401 CharUnits Field2Off = CharUnits::Zero();
402 int NeededArgGPRs = 0;
403 int NeededArgFPRs = 0;
404 bool IsCandidate =
405 detectFPCCEligibleStruct(Ty, Field1Ty, Field1Off, Field2Ty, Field2Off,
406 NeededArgGPRs, NeededArgFPRs);
407 if (IsCandidate && NeededArgGPRs <= ArgGPRsLeft &&
408 NeededArgFPRs <= ArgFPRsLeft) {
409 ArgGPRsLeft -= NeededArgGPRs;
410 ArgFPRsLeft -= NeededArgFPRs;
411 return coerceAndExpandFPCCEligibleStruct(Field1Ty, Field1Off, Field2Ty,
412 Field2Off);
413 }
414 }
415
416 uint64_t NeededAlign = getContext().getTypeAlign(Ty);
417 // Determine the number of GPRs needed to pass the current argument
418 // according to the ABI. 2*XLen-aligned varargs are passed in "aligned"
419 // register pairs, so may consume 3 registers.
420 // TODO: To be compatible with GCC's behaviors, we don't align registers
421 // currently if we are using ILP32E calling convention. This behavior may be
422 // changed when RV32E/ILP32E is ratified.
423 int NeededArgGPRs = 1;
424 if (!IsFixed && NeededAlign == 2 * XLen)
425 NeededArgGPRs = 2 + (EABI && XLen == 32 ? 0 : (ArgGPRsLeft % 2));
426 else if (Size > XLen && Size <= 2 * XLen)
427 NeededArgGPRs = 2;
428
429 if (NeededArgGPRs > ArgGPRsLeft) {
430 NeededArgGPRs = ArgGPRsLeft;
431 }
432
433 ArgGPRsLeft -= NeededArgGPRs;
434
435 if (!isAggregateTypeForABI(Ty) && !Ty->isVectorType()) {
436 // Treat an enum type as its underlying type.
437 if (const EnumType *EnumTy = Ty->getAs<EnumType>())
438 Ty = EnumTy->getDecl()->getIntegerType();
439
440 // All integral types are promoted to XLen width
441 if (Size < XLen && Ty->isIntegralOrEnumerationType()) {
442 return extendType(Ty);
443 }
444
445 if (const auto *EIT = Ty->getAs<BitIntType>()) {
446 if (EIT->getNumBits() < XLen)
447 return extendType(Ty);
448 if (EIT->getNumBits() > 128 ||
449 (!getContext().getTargetInfo().hasInt128Type() &&
450 EIT->getNumBits() > 64))
451 return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
452 }
453
455
456 // If it is tuple type, it can't be flattened.
457 if (llvm::StructType *STy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty)))
458 Info.setCanBeFlattened(!STy->containsHomogeneousScalableVectorTypes());
459
460 return Info;
461 }
462
463 if (const VectorType *VT = Ty->getAs<VectorType>())
464 if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||
465 VT->getVectorKind() == VectorKind::RVVFixedLengthMask ||
466 VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1 ||
467 VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2 ||
468 VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4)
469 return coerceVLSVector(Ty);
470
471 // Aggregates which are <= 2*XLen will be passed in registers if possible,
472 // so coerce to integers.
473 if (Size <= 2 * XLen) {
474 unsigned Alignment = getContext().getTypeAlign(Ty);
475
476 // Use a single XLen int if possible, 2*XLen if 2*XLen alignment is
477 // required, and a 2-element XLen array if only XLen alignment is required.
478 if (Size <= XLen) {
480 llvm::IntegerType::get(getVMContext(), XLen));
481 } else if (Alignment == 2 * XLen) {
483 llvm::IntegerType::get(getVMContext(), 2 * XLen));
484 } else {
485 return ABIArgInfo::getDirect(llvm::ArrayType::get(
486 llvm::IntegerType::get(getVMContext(), XLen), 2));
487 }
488 }
489 return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
490}
491
492ABIArgInfo RISCVABIInfo::classifyReturnType(QualType RetTy) const {
493 if (RetTy->isVoidType())
494 return ABIArgInfo::getIgnore();
495
496 int ArgGPRsLeft = 2;
497 int ArgFPRsLeft = FLen ? 2 : 0;
498
499 // The rules for return and argument types are the same, so defer to
500 // classifyArgumentType.
501 return classifyArgumentType(RetTy, /*IsFixed=*/true, ArgGPRsLeft,
502 ArgFPRsLeft);
503}
504
505RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
506 QualType Ty, AggValueSlot Slot) const {
507 CharUnits SlotSize = CharUnits::fromQuantity(XLen / 8);
508
509 // Empty records are ignored for parameter passing purposes.
510 if (isEmptyRecord(getContext(), Ty, true))
511 return Slot.asRValue();
512
513 auto TInfo = getContext().getTypeInfoInChars(Ty);
514
515 // TODO: To be compatible with GCC's behaviors, we force arguments with
516 // 2×XLEN-bit alignment and size at most 2×XLEN bits like `long long`,
517 // `unsigned long long` and `double` to have 4-byte alignment. This
518 // behavior may be changed when RV32E/ILP32E is ratified.
519 if (EABI && XLen == 32)
520 TInfo.Align = std::min(TInfo.Align, CharUnits::fromQuantity(4));
521
522 // Arguments bigger than 2*Xlen bytes are passed indirectly.
523 bool IsIndirect = TInfo.Width > 2 * SlotSize;
524
525 return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TInfo, SlotSize,
526 /*AllowHigherAlign=*/true, Slot);
527}
528
529ABIArgInfo RISCVABIInfo::extendType(QualType Ty) const {
530 int TySize = getContext().getTypeSize(Ty);
531 // RV64 ABI requires unsigned 32 bit integers to be sign extended.
532 if (XLen == 64 && Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32)
533 return ABIArgInfo::getSignExtend(Ty);
534 return ABIArgInfo::getExtend(Ty);
535}
536
537namespace {
538class RISCVTargetCodeGenInfo : public TargetCodeGenInfo {
539public:
540 RISCVTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen,
541 unsigned FLen, bool EABI)
543 std::make_unique<RISCVABIInfo>(CGT, XLen, FLen, EABI)) {
544 SwiftInfo =
545 std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
546 }
547
548 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
549 CodeGen::CodeGenModule &CGM) const override {
550 const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
551 if (!FD) return;
552
553 const auto *Attr = FD->getAttr<RISCVInterruptAttr>();
554 if (!Attr)
555 return;
556
557 const char *Kind;
558 switch (Attr->getInterrupt()) {
559 case RISCVInterruptAttr::supervisor: Kind = "supervisor"; break;
560 case RISCVInterruptAttr::machine: Kind = "machine"; break;
561 }
562
563 auto *Fn = cast<llvm::Function>(GV);
564
565 Fn->addFnAttr("interrupt", Kind);
566 }
567};
568} // namespace
569
570std::unique_ptr<TargetCodeGenInfo>
572 unsigned FLen, bool EABI) {
573 return std::make_unique<RISCVTargetCodeGenInfo>(CGM.getTypes(), XLen, FLen,
574 EABI);
575}
const Decl * D
static CharUnits getTypeStoreSize(CodeGenModule &CGM, llvm::Type *type)
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Definition: RecordLayout.h:38
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
Definition: RecordLayout.h:200
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Definition: RecordLayout.h:249
Attr - This represents one attribute.
Definition: Attr.h:42
A fixed int type of a specified bitwidth.
Definition: Type.h:7638
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition: CharUnits.h:122
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
bool isMultipleOf(CharUnits N) const
Test whether this is a multiple of the other value.
Definition: CharUnits.h:143
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
Definition: CharUnits.h:201
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Definition: CharUnits.h:53
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
static ABIArgInfo getIgnore()
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType, llvm::Type *unpaddedCoerceToType)
void setCanBeFlattened(bool Flatten)
static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T=nullptr)
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Definition: Address.h:128
An aggregate value slot.
Definition: CGValue.h:504
RValue asRValue() const
Definition: CGValue.h:666
RecordArgABI
Specify how one should pass an argument of a record type.
Definition: CGCXXABI.h:150
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
Definition: CGCXXABI.h:158
CGFunctionInfo - Class to encapsulate the information about a function definition.
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
unsigned getNumRequiredArgs() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
This class organizes the cross-function state that is used while generating LLVM code.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
Definition: CodeGenTypes.h:54
DefaultABIInfo - The default implementation for ABI specific details.
Definition: ABIInfoImpl.h:21
ABIArgInfo classifyArgumentType(QualType RetTy) const
Definition: ABIInfoImpl.cpp:17
RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, AggValueSlot Slot) const override
EmitVAArg - Emit the target dependent code to load a value of.
Definition: ABIInfoImpl.cpp:75
ABIArgInfo classifyReturnType(QualType RetTy) const
Definition: ABIInfoImpl.cpp:46
void computeInfo(CGFunctionInfo &FI) const override
Definition: ABIInfoImpl.cpp:68
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
Definition: CGValue.h:42
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
Definition: TargetInfo.h:47
virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const
setTargetAttributes - Provides a convenient hook to handle extra target-specific attributes for the g...
Definition: TargetInfo.h:76
Complex values, per C99 6.2.5p11.
Definition: Type.h:3139
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3609
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:5996
Represents a member of a struct/union/class.
Definition: Decl.h:3030
A (possibly-)qualified type.
Definition: Type.h:941
Represents a struct/union/class.
Definition: Decl.h:4145
field_range fields() const
Definition: Decl.h:4351
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5970
RecordDecl * getDecl() const
Definition: Type.h:5980
bool isUnion() const
Definition: Decl.h:3767
bool isVoidType() const
Definition: Type.h:8324
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
Definition: Type.cpp:677
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
Definition: Type.cpp:2217
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8612
bool isScalarType() const
Definition: Type.h:8423
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:8439
bool isStructureOrClassType() const
Definition: Type.cpp:657
bool isVectorType() const
Definition: Type.h:8120
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:2266
bool isFloatingType() const
Definition: Type.cpp:2249
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8545
Represents a GCC generic vector type.
Definition: Type.h:4026
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, AggValueSlot Slot, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
bool isAggregateTypeForABI(QualType T)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
std::unique_ptr< TargetCodeGenInfo > createRISCVTargetCodeGenInfo(CodeGenModule &CGM, unsigned XLen, unsigned FLen, bool EABI)
Definition: RISCV.cpp:571
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
Definition: Interp.h:276
The JSON file list parser is used to communicate input to InstallAPI.
unsigned long uint64_t