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 | |
13 | using namespace clang; |
14 | using namespace clang::CodeGen; |
15 | |
16 | //===----------------------------------------------------------------------===// |
17 | // RISC-V ABI Implementation |
18 | //===----------------------------------------------------------------------===// |
19 | |
20 | namespace { |
21 | class RISCVABIInfo : public DefaultABIInfo { |
22 | private: |
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 | |
41 | public: |
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 | |
79 | void RISCVABIInfo::appendAttributeMangling(TargetClonesAttr *Attr, |
80 | unsigned Index, |
81 | raw_ostream &Out) const { |
82 | appendAttributeMangling(AttrStr: Attr->getFeatureStr(Index), Out); |
83 | } |
84 | |
85 | void 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 | |
117 | void 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. |
179 | bool 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. |
309 | bool 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. |
342 | ABIArgInfo 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 | |
389 | bool 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 | // Struct of 1 fixed-length vector is passed as a scalable vector. |
445 | // Struct of >1 fixed-length vectors are passed as vector tuple. |
446 | // Struct of 1 array of fixed-length vectors is passed as a scalable vector. |
447 | // Otherwise, pass the struct indirectly. |
448 | |
449 | if (llvm::StructType *STy = dyn_cast<llvm::StructType>(Val: CGT.ConvertType(T: Ty))) { |
450 | unsigned NumElts = STy->getStructNumElements(); |
451 | if (NumElts > 8) |
452 | return false; |
453 | |
454 | auto *FirstEltTy = STy->getElementType(N: 0); |
455 | if (!STy->containsHomogeneousTypes()) |
456 | return false; |
457 | |
458 | // Check structure of fixed-length vectors and turn them into vector tuple |
459 | // type if legal. |
460 | if (auto *FixedVecTy = dyn_cast<llvm::FixedVectorType>(Val: FirstEltTy)) { |
461 | if (NumElts == 1) { |
462 | // Handle single fixed-length vector. |
463 | VLSType = llvm::ScalableVectorType::get( |
464 | ElementType: FixedVecTy->getElementType(), |
465 | MinNumElts: llvm::divideCeil(Numerator: FixedVecTy->getNumElements() * |
466 | llvm::RISCV::RVVBitsPerBlock, |
467 | Denominator: ABIVLen)); |
468 | // Check registers needed <= 8. |
469 | return llvm::divideCeil( |
470 | Numerator: FixedVecTy->getNumElements() * |
471 | FixedVecTy->getElementType()->getScalarSizeInBits(), |
472 | Denominator: ABIVLen) <= 8; |
473 | } |
474 | // LMUL |
475 | // = fixed-length vector size / ABIVLen |
476 | // = 8 * I8EltCount / RVVBitsPerBlock |
477 | // => |
478 | // I8EltCount |
479 | // = (fixed-length vector size * RVVBitsPerBlock) / (ABIVLen * 8) |
480 | unsigned I8EltCount = llvm::divideCeil( |
481 | Numerator: FixedVecTy->getNumElements() * |
482 | FixedVecTy->getElementType()->getScalarSizeInBits() * |
483 | llvm::RISCV::RVVBitsPerBlock, |
484 | Denominator: ABIVLen * 8); |
485 | VLSType = llvm::TargetExtType::get( |
486 | Context&: getVMContext(), Name: "riscv.vector.tuple" , |
487 | Types: llvm::ScalableVectorType::get(ElementType: llvm::Type::getInt8Ty(C&: getVMContext()), |
488 | MinNumElts: I8EltCount), |
489 | Ints: NumElts); |
490 | // Check registers needed <= 8. |
491 | return NumElts * |
492 | llvm::divideCeil( |
493 | Numerator: FixedVecTy->getNumElements() * |
494 | FixedVecTy->getElementType()->getScalarSizeInBits(), |
495 | Denominator: ABIVLen) <= |
496 | 8; |
497 | } |
498 | |
499 | // If elements are not fixed-length vectors, it should be an array. |
500 | if (NumElts != 1) |
501 | return false; |
502 | |
503 | // Check array of fixed-length vector and turn it into scalable vector type |
504 | // if legal. |
505 | if (auto *ArrTy = dyn_cast<llvm::ArrayType>(Val: FirstEltTy)) { |
506 | unsigned NumArrElt = ArrTy->getNumElements(); |
507 | if (NumArrElt > 8) |
508 | return false; |
509 | |
510 | auto *ArrEltTy = dyn_cast<llvm::FixedVectorType>(Val: ArrTy->getElementType()); |
511 | if (!ArrEltTy) |
512 | return false; |
513 | |
514 | // LMUL |
515 | // = NumArrElt * fixed-length vector size / ABIVLen |
516 | // = fixed-length vector elt size * ScalVecNumElts / RVVBitsPerBlock |
517 | // => |
518 | // ScalVecNumElts |
519 | // = (NumArrElt * fixed-length vector size * RVVBitsPerBlock) / |
520 | // (ABIVLen * fixed-length vector elt size) |
521 | // = NumArrElt * num fixed-length vector elt * RVVBitsPerBlock / |
522 | // ABIVLen |
523 | unsigned ScalVecNumElts = llvm::divideCeil( |
524 | Numerator: NumArrElt * ArrEltTy->getNumElements() * llvm::RISCV::RVVBitsPerBlock, |
525 | Denominator: ABIVLen); |
526 | VLSType = llvm::ScalableVectorType::get(ElementType: ArrEltTy->getElementType(), |
527 | MinNumElts: ScalVecNumElts); |
528 | // Check registers needed <= 8. |
529 | return llvm::divideCeil( |
530 | Numerator: ScalVecNumElts * |
531 | ArrEltTy->getElementType()->getScalarSizeInBits(), |
532 | Denominator: llvm::RISCV::RVVBitsPerBlock) <= 8; |
533 | } |
534 | } |
535 | return false; |
536 | } |
537 | |
538 | // Fixed-length RVV vectors are represented as scalable vectors in function |
539 | // args/return and must be coerced from fixed vectors. |
540 | ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty, unsigned ABIVLen) const { |
541 | assert(Ty->isVectorType() && "expected vector type!" ); |
542 | |
543 | const auto *VT = Ty->castAs<VectorType>(); |
544 | assert(VT->getElementType()->isBuiltinType() && "expected builtin type!" ); |
545 | |
546 | auto VScale = getContext().getTargetInfo().getVScaleRange( |
547 | LangOpts: getContext().getLangOpts(), Mode: TargetInfo::ArmStreamingKind::NotStreaming); |
548 | |
549 | unsigned NumElts = VT->getNumElements(); |
550 | llvm::Type *EltType = llvm::Type::getInt1Ty(C&: getVMContext()); |
551 | switch (VT->getVectorKind()) { |
552 | case VectorKind::RVVFixedLengthMask_1: |
553 | break; |
554 | case VectorKind::RVVFixedLengthMask_2: |
555 | NumElts *= 2; |
556 | break; |
557 | case VectorKind::RVVFixedLengthMask_4: |
558 | NumElts *= 4; |
559 | break; |
560 | case VectorKind::RVVFixedLengthMask: |
561 | NumElts *= 8; |
562 | break; |
563 | default: |
564 | assert((VT->getVectorKind() == VectorKind::Generic || |
565 | VT->getVectorKind() == VectorKind::RVVFixedLengthData) && |
566 | "Unexpected vector kind" ); |
567 | EltType = CGT.ConvertType(T: VT->getElementType()); |
568 | } |
569 | |
570 | llvm::ScalableVectorType *ResType; |
571 | |
572 | if (ABIVLen == 0) { |
573 | // The MinNumElts is simplified from equation: |
574 | // NumElts / VScale = |
575 | // (EltSize * NumElts / (VScale * RVVBitsPerBlock)) |
576 | // * (RVVBitsPerBlock / EltSize) |
577 | ResType = llvm::ScalableVectorType::get(ElementType: EltType, MinNumElts: NumElts / VScale->first); |
578 | } else { |
579 | // Check registers needed <= 8. |
580 | if ((EltType->getScalarSizeInBits() * NumElts / ABIVLen) > 8) |
581 | return getNaturalAlignIndirect( |
582 | Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(), |
583 | /*ByVal=*/false); |
584 | |
585 | // Generic vector |
586 | // The number of elements needs to be at least 1. |
587 | ResType = llvm::ScalableVectorType::get( |
588 | ElementType: EltType, |
589 | MinNumElts: llvm::divideCeil(Numerator: NumElts * llvm::RISCV::RVVBitsPerBlock, Denominator: ABIVLen)); |
590 | |
591 | // If the corresponding extension is not supported, just make it an i8 |
592 | // vector with same LMUL. |
593 | const TargetInfo &TI = getContext().getTargetInfo(); |
594 | if ((EltType->isHalfTy() && !TI.hasFeature(Feature: "zvfhmin" )) || |
595 | (EltType->isBFloatTy() && !TI.hasFeature(Feature: "zvfbfmin" )) || |
596 | (EltType->isFloatTy() && !TI.hasFeature(Feature: "zve32f" )) || |
597 | (EltType->isDoubleTy() && !TI.hasFeature(Feature: "zve64d" )) || |
598 | (EltType->isIntegerTy(Bitwidth: 64) && !TI.hasFeature(Feature: "zve64x" )) || |
599 | EltType->isIntegerTy(Bitwidth: 128)) { |
600 | // The number of elements needs to be at least 1. |
601 | ResType = llvm::ScalableVectorType::get( |
602 | ElementType: llvm::Type::getInt8Ty(C&: getVMContext()), |
603 | MinNumElts: llvm::divideCeil(Numerator: EltType->getScalarSizeInBits() * NumElts * |
604 | llvm::RISCV::RVVBitsPerBlock, |
605 | Denominator: 8 * ABIVLen)); |
606 | } |
607 | } |
608 | |
609 | return ABIArgInfo::getDirect(T: ResType); |
610 | } |
611 | |
612 | ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, |
613 | int &ArgGPRsLeft, |
614 | int &ArgFPRsLeft, |
615 | unsigned ABIVLen) const { |
616 | assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow" ); |
617 | Ty = useFirstFieldIfTransparentUnion(Ty); |
618 | |
619 | // Structures with either a non-trivial destructor or a non-trivial |
620 | // copy constructor are always passed indirectly. |
621 | if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(T: Ty, CXXABI&: getCXXABI())) { |
622 | if (ArgGPRsLeft) |
623 | ArgGPRsLeft -= 1; |
624 | return getNaturalAlignIndirect( |
625 | Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(), |
626 | /*ByVal=*/RAA == CGCXXABI::RAA_DirectInMemory); |
627 | } |
628 | |
629 | uint64_t Size = getContext().getTypeSize(T: Ty); |
630 | |
631 | // Ignore empty structs/unions whose size is zero. According to the calling |
632 | // convention empty structs/unions are required to be sized types in C++. |
633 | if (isEmptyRecord(Context&: getContext(), T: Ty, AllowArrays: true) && Size == 0) |
634 | return ABIArgInfo::getIgnore(); |
635 | |
636 | // Pass floating point values via FPRs if possible. |
637 | if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() && |
638 | FLen >= Size && ArgFPRsLeft) { |
639 | ArgFPRsLeft--; |
640 | return ABIArgInfo::getDirect(); |
641 | } |
642 | |
643 | // Complex types for the hard float ABI must be passed direct rather than |
644 | // using CoerceAndExpand. |
645 | if (IsFixed && Ty->isComplexType() && FLen && ArgFPRsLeft >= 2) { |
646 | QualType EltTy = Ty->castAs<ComplexType>()->getElementType(); |
647 | if (getContext().getTypeSize(T: EltTy) <= FLen) { |
648 | ArgFPRsLeft -= 2; |
649 | return ABIArgInfo::getDirect(); |
650 | } |
651 | } |
652 | |
653 | if (IsFixed && FLen && Ty->isStructureOrClassType()) { |
654 | llvm::Type *Field1Ty = nullptr; |
655 | llvm::Type *Field2Ty = nullptr; |
656 | CharUnits Field1Off = CharUnits::Zero(); |
657 | CharUnits Field2Off = CharUnits::Zero(); |
658 | int NeededArgGPRs = 0; |
659 | int NeededArgFPRs = 0; |
660 | bool IsCandidate = |
661 | detectFPCCEligibleStruct(Ty, Field1Ty, Field1Off, Field2Ty, Field2Off, |
662 | NeededArgGPRs, NeededArgFPRs); |
663 | if (IsCandidate && NeededArgGPRs <= ArgGPRsLeft && |
664 | NeededArgFPRs <= ArgFPRsLeft) { |
665 | ArgGPRsLeft -= NeededArgGPRs; |
666 | ArgFPRsLeft -= NeededArgFPRs; |
667 | return coerceAndExpandFPCCEligibleStruct(Field1Ty, Field1Off, Field2Ty, |
668 | Field2Off); |
669 | } |
670 | } |
671 | |
672 | if (IsFixed && Ty->isStructureOrClassType()) { |
673 | llvm::Type *VLSType = nullptr; |
674 | if (detectVLSCCEligibleStruct(Ty, ABIVLen, VLSType)) |
675 | return ABIArgInfo::getDirect(T: VLSType); |
676 | } |
677 | |
678 | uint64_t NeededAlign = getContext().getTypeAlign(T: Ty); |
679 | // Determine the number of GPRs needed to pass the current argument |
680 | // according to the ABI. 2*XLen-aligned varargs are passed in "aligned" |
681 | // register pairs, so may consume 3 registers. |
682 | // TODO: To be compatible with GCC's behaviors, we don't align registers |
683 | // currently if we are using ILP32E calling convention. This behavior may be |
684 | // changed when RV32E/ILP32E is ratified. |
685 | int NeededArgGPRs = 1; |
686 | if (!IsFixed && NeededAlign == 2 * XLen) |
687 | NeededArgGPRs = 2 + (EABI && XLen == 32 ? 0 : (ArgGPRsLeft % 2)); |
688 | else if (Size > XLen && Size <= 2 * XLen) |
689 | NeededArgGPRs = 2; |
690 | |
691 | if (NeededArgGPRs > ArgGPRsLeft) { |
692 | NeededArgGPRs = ArgGPRsLeft; |
693 | } |
694 | |
695 | ArgGPRsLeft -= NeededArgGPRs; |
696 | |
697 | if (!isAggregateTypeForABI(T: Ty) && !Ty->isVectorType()) { |
698 | // Treat an enum type as its underlying type. |
699 | if (const EnumType *EnumTy = Ty->getAs<EnumType>()) |
700 | Ty = EnumTy->getDecl()->getIntegerType(); |
701 | |
702 | // All integral types are promoted to XLen width |
703 | if (Size < XLen && Ty->isIntegralOrEnumerationType()) { |
704 | return extendType(Ty, CoerceTy: CGT.ConvertType(T: Ty)); |
705 | } |
706 | |
707 | if (const auto *EIT = Ty->getAs<BitIntType>()) { |
708 | if (EIT->getNumBits() < XLen) |
709 | return extendType(Ty, CoerceTy: CGT.ConvertType(T: Ty)); |
710 | if (EIT->getNumBits() > 128 || |
711 | (!getContext().getTargetInfo().hasInt128Type() && |
712 | EIT->getNumBits() > 64)) |
713 | return getNaturalAlignIndirect( |
714 | Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(), |
715 | /*ByVal=*/false); |
716 | } |
717 | |
718 | return ABIArgInfo::getDirect(); |
719 | } |
720 | |
721 | // TODO: _BitInt is not handled yet in VLS calling convention since _BitInt |
722 | // ABI is also not merged yet in RISC-V: |
723 | // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/419 |
724 | if (const VectorType *VT = Ty->getAs<VectorType>(); |
725 | VT && !VT->getElementType()->isBitIntType()) { |
726 | if (VT->getVectorKind() == VectorKind::RVVFixedLengthData || |
727 | VT->getVectorKind() == VectorKind::RVVFixedLengthMask || |
728 | VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1 || |
729 | VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2 || |
730 | VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4) |
731 | return coerceVLSVector(Ty); |
732 | if (VT->getVectorKind() == VectorKind::Generic && ABIVLen != 0) |
733 | // Generic vector without riscv_vls_cc should fall through and pass by |
734 | // reference. |
735 | return coerceVLSVector(Ty, ABIVLen); |
736 | } |
737 | |
738 | // Aggregates which are <= 2*XLen will be passed in registers if possible, |
739 | // so coerce to integers. |
740 | if (Size <= 2 * XLen) { |
741 | unsigned Alignment = getContext().getTypeAlign(T: Ty); |
742 | |
743 | // Use a single XLen int if possible, 2*XLen if 2*XLen alignment is |
744 | // required, and a 2-element XLen array if only XLen alignment is required. |
745 | if (Size <= XLen) { |
746 | return ABIArgInfo::getDirect( |
747 | T: llvm::IntegerType::get(C&: getVMContext(), NumBits: XLen)); |
748 | } else if (Alignment == 2 * XLen) { |
749 | return ABIArgInfo::getDirect( |
750 | T: llvm::IntegerType::get(C&: getVMContext(), NumBits: 2 * XLen)); |
751 | } else { |
752 | return ABIArgInfo::getDirect(T: llvm::ArrayType::get( |
753 | ElementType: llvm::IntegerType::get(C&: getVMContext(), NumBits: XLen), NumElements: 2)); |
754 | } |
755 | } |
756 | return getNaturalAlignIndirect( |
757 | Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(), |
758 | /*ByVal=*/false); |
759 | } |
760 | |
761 | ABIArgInfo RISCVABIInfo::classifyReturnType(QualType RetTy, |
762 | unsigned ABIVLen) const { |
763 | if (RetTy->isVoidType()) |
764 | return ABIArgInfo::getIgnore(); |
765 | |
766 | int ArgGPRsLeft = 2; |
767 | int ArgFPRsLeft = FLen ? 2 : 0; |
768 | |
769 | // The rules for return and argument types are the same, so defer to |
770 | // classifyArgumentType. |
771 | return classifyArgumentType(Ty: RetTy, /*IsFixed=*/true, ArgGPRsLeft, ArgFPRsLeft, |
772 | ABIVLen); |
773 | } |
774 | |
775 | RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, |
776 | QualType Ty, AggValueSlot Slot) const { |
777 | CharUnits SlotSize = CharUnits::fromQuantity(Quantity: XLen / 8); |
778 | |
779 | // Empty records are ignored for parameter passing purposes. |
780 | if (isEmptyRecord(Context&: getContext(), T: Ty, AllowArrays: true)) |
781 | return Slot.asRValue(); |
782 | |
783 | auto TInfo = getContext().getTypeInfoInChars(T: Ty); |
784 | |
785 | // TODO: To be compatible with GCC's behaviors, we force arguments with |
786 | // 2×XLEN-bit alignment and size at most 2×XLEN bits like `long long`, |
787 | // `unsigned long long` and `double` to have 4-byte alignment. This |
788 | // behavior may be changed when RV32E/ILP32E is ratified. |
789 | if (EABI && XLen == 32) |
790 | TInfo.Align = std::min(a: TInfo.Align, b: CharUnits::fromQuantity(Quantity: 4)); |
791 | |
792 | // Arguments bigger than 2*Xlen bytes are passed indirectly. |
793 | bool IsIndirect = TInfo.Width > 2 * SlotSize; |
794 | |
795 | return emitVoidPtrVAArg(CGF, VAListAddr, ValueTy: Ty, IsIndirect, ValueInfo: TInfo, SlotSizeAndAlign: SlotSize, |
796 | /*AllowHigherAlign=*/true, Slot); |
797 | } |
798 | |
799 | ABIArgInfo RISCVABIInfo::extendType(QualType Ty, llvm::Type *CoerceTy) const { |
800 | int TySize = getContext().getTypeSize(T: Ty); |
801 | // RV64 ABI requires unsigned 32 bit integers to be sign extended. |
802 | if (XLen == 64 && Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32) |
803 | return ABIArgInfo::getSignExtend(Ty, T: CoerceTy); |
804 | return ABIArgInfo::getExtend(Ty, T: CoerceTy); |
805 | } |
806 | |
807 | namespace { |
808 | class RISCVTargetCodeGenInfo : public TargetCodeGenInfo { |
809 | public: |
810 | RISCVTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, |
811 | unsigned FLen, bool EABI) |
812 | : TargetCodeGenInfo( |
813 | std::make_unique<RISCVABIInfo>(args&: CGT, args&: XLen, args&: FLen, args&: EABI)) { |
814 | SwiftInfo = |
815 | std::make_unique<SwiftABIInfo>(args&: CGT, /*SwiftErrorInRegister=*/args: false); |
816 | } |
817 | |
818 | void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, |
819 | CodeGen::CodeGenModule &CGM) const override { |
820 | const auto *FD = dyn_cast_or_null<FunctionDecl>(Val: D); |
821 | if (!FD) return; |
822 | |
823 | auto *Fn = cast<llvm::Function>(Val: GV); |
824 | |
825 | if (CGM.getCodeGenOpts().CFProtectionReturn) |
826 | Fn->addFnAttr(Kind: "hw-shadow-stack" ); |
827 | |
828 | const auto *Attr = FD->getAttr<RISCVInterruptAttr>(); |
829 | if (!Attr) |
830 | return; |
831 | |
832 | StringRef Kind = "machine" ; |
833 | bool HasSiFiveCLICPreemptible = false; |
834 | bool HasSiFiveCLICStackSwap = false; |
835 | for (RISCVInterruptAttr::InterruptType type : Attr->interrupt()) { |
836 | switch (type) { |
837 | case RISCVInterruptAttr::machine: |
838 | // Do not update `Kind` because `Kind` is already "machine", or the |
839 | // kinds also contains SiFive types which need to be applied. |
840 | break; |
841 | case RISCVInterruptAttr::supervisor: |
842 | Kind = "supervisor" ; |
843 | break; |
844 | case RISCVInterruptAttr::qcinest: |
845 | Kind = "qci-nest" ; |
846 | break; |
847 | case RISCVInterruptAttr::qcinonest: |
848 | Kind = "qci-nonest" ; |
849 | break; |
850 | // There are three different LLVM IR attribute values for SiFive CLIC |
851 | // interrupt kinds, one for each kind and one extra for their combination. |
852 | case RISCVInterruptAttr::SiFiveCLICPreemptible: { |
853 | HasSiFiveCLICPreemptible = true; |
854 | Kind = HasSiFiveCLICStackSwap ? "SiFive-CLIC-preemptible-stack-swap" |
855 | : "SiFive-CLIC-preemptible" ; |
856 | break; |
857 | } |
858 | case RISCVInterruptAttr::SiFiveCLICStackSwap: { |
859 | HasSiFiveCLICStackSwap = true; |
860 | Kind = HasSiFiveCLICPreemptible ? "SiFive-CLIC-preemptible-stack-swap" |
861 | : "SiFive-CLIC-stack-swap" ; |
862 | break; |
863 | } |
864 | } |
865 | } |
866 | |
867 | Fn->addFnAttr(Kind: "interrupt" , Val: Kind); |
868 | } |
869 | }; |
870 | } // namespace |
871 | |
872 | std::unique_ptr<TargetCodeGenInfo> |
873 | CodeGen::createRISCVTargetCodeGenInfo(CodeGenModule &CGM, unsigned XLen, |
874 | unsigned FLen, bool EABI) { |
875 | return std::make_unique<RISCVTargetCodeGenInfo>(args&: CGM.getTypes(), args&: XLen, args&: FLen, |
876 | args&: EABI); |
877 | } |
878 | |