Lines Matching +full:xlen +full:- +full:1

1 //===- RISCV.cpp ----------------------------------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
15 //===----------------------------------------------------------------------===//
16 // RISC-V ABI Implementation
17 //===----------------------------------------------------------------------===//
23 unsigned XLen; member in __anonb4a9a46e0111::RISCVABIInfo
38 RISCVABIInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, unsigned FLen, in RISCVABIInfo() argument
40 : DefaultABIInfo(CGT), XLen(XLen), FLen(FLen), NumArgGPRs(EABI ? 6 : 8), in RISCVABIInfo()
44 // non-virtual, but computeInfo is virtual, so we overload it.
75 // be passed indirect, or if the type size is a scalar greater than 2*XLen in computeInfo()
80 if (!IsRetIndirect && RetTy->isScalarType() && in computeInfo()
81 getContext().getTypeSize(RetTy) > (2 * XLen)) { in computeInfo()
82 if (RetTy->isComplexType() && FLen) { in computeInfo()
83 QualType EltTy = RetTy->castAs<ComplexType>()->getElementType(); in computeInfo()
86 // This is a normal scalar > 2*XLen, such as fp128 on RV32. in computeInfo()
91 int ArgGPRsLeft = IsRetIndirect ? NumArgGPRs - 1 : NumArgGPRs; in computeInfo()
113 bool IsInt = Ty->isIntegralOrEnumerationType(); in detectFPCCEligibleStructHelper()
114 bool IsFloat = Ty->isRealFloatingType(); in detectFPCCEligibleStructHelper()
118 if (IsInt && Size > XLen) in detectFPCCEligibleStructHelper()
126 if (IsInt && Field1Ty && Field1Ty->isIntegerTy()) in detectFPCCEligibleStructHelper()
141 if (auto CTy = Ty->getAs<ComplexType>()) { in detectFPCCEligibleStructHelper()
144 QualType EltTy = CTy->getElementType(); in detectFPCCEligibleStructHelper()
155 uint64_t ArraySize = ATy->getZExtSize(); in detectFPCCEligibleStructHelper()
156 QualType EltTy = ATy->getElementType(); in detectFPCCEligibleStructHelper()
157 // Non-zero-length arrays of empty records make the struct ineligible for in detectFPCCEligibleStructHelper()
159 if (const auto *RTy = EltTy->getAs<RecordType>()) { in detectFPCCEligibleStructHelper()
160 if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) && in detectFPCCEligibleStructHelper()
175 if (const auto *RTy = Ty->getAs<RecordType>()) { in detectFPCCEligibleStructHelper()
176 // Structures with either a non-trivial destructor or a non-trivial in detectFPCCEligibleStructHelper()
182 const RecordDecl *RD = RTy->getDecl(); in detectFPCCEligibleStructHelper()
184 if (RD->isUnion()) in detectFPCCEligibleStructHelper()
189 for (const CXXBaseSpecifier &B : CXXRD->bases()) { in detectFPCCEligibleStructHelper()
191 cast<CXXRecordDecl>(B.getType()->castAs<RecordType>()->getDecl()); in detectFPCCEligibleStructHelper()
201 for (const FieldDecl *FD : RD->fields()) { in detectFPCCEligibleStructHelper()
202 uint64_t FieldOffInBits = Layout.getFieldOffset(FD->getFieldIndex()); in detectFPCCEligibleStructHelper()
203 QualType QTy = FD->getType(); in detectFPCCEligibleStructHelper()
204 if (FD->isBitField()) { in detectFPCCEligibleStructHelper()
205 unsigned BitWidth = FD->getBitWidthValue(getContext()); in detectFPCCEligibleStructHelper()
206 // Allow a bitfield with a type greater than XLen as long as the in detectFPCCEligibleStructHelper()
207 // bitwidth is XLen or less. in detectFPCCEligibleStructHelper()
208 if (getContext().getTypeSize(QTy) > XLen && BitWidth <= XLen) in detectFPCCEligibleStructHelper()
209 QTy = getContext().getIntTypeForBitwidth(XLen, false); in detectFPCCEligibleStructHelper()
222 // As a quirk of the ABI, zero-width bitfields aren't ignored for fp+fp in detectFPCCEligibleStructHelper()
224 // any number of zero-width bitfields. in detectFPCCEligibleStructHelper()
253 if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy()) in detectFPCCEligibleStruct()
257 if (Field1Ty && Field1Ty->isFloatingPointTy()) in detectFPCCEligibleStruct()
261 if (Field2Ty && Field2Ty->isFloatingPointTy()) in detectFPCCEligibleStruct()
268 // Call getCoerceAndExpand for the two-element flattened struct described by
297 Padding = Field2Off - Field2OffNoPadNoPack; in coerceAndExpandFPCCEligibleStruct()
299 Padding = Field2Off - Field1End; in coerceAndExpandFPCCEligibleStruct()
318 // Fixed-length RVV vectors are represented as scalable vectors in function
321 assert(Ty->isVectorType() && "expected vector type!"); in coerceVLSVector()
323 const auto *VT = Ty->castAs<VectorType>(); in coerceVLSVector()
324 assert(VT->getElementType()->isBuiltinType() && "expected builtin type!"); in coerceVLSVector()
329 unsigned NumElts = VT->getNumElements(); in coerceVLSVector()
331 if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask) { in coerceVLSVector()
335 assert(VT->getVectorKind() == VectorKind::RVVFixedLengthData && in coerceVLSVector()
337 EltType = CGT.ConvertType(VT->getElementType()); in coerceVLSVector()
345 llvm::ScalableVectorType::get(EltType, NumElts / VScale->first); in coerceVLSVector()
355 // Structures with either a non-trivial destructor or a non-trivial in classifyArgumentType()
359 ArgGPRsLeft -= 1; in classifyArgumentType()
372 if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() && in classifyArgumentType()
374 ArgFPRsLeft--; in classifyArgumentType()
380 if (IsFixed && Ty->isComplexType() && FLen && ArgFPRsLeft >= 2) { in classifyArgumentType()
381 QualType EltTy = Ty->castAs<ComplexType>()->getElementType(); in classifyArgumentType()
383 ArgFPRsLeft -= 2; in classifyArgumentType()
388 if (IsFixed && FLen && Ty->isStructureOrClassType()) { in classifyArgumentType()
400 ArgGPRsLeft -= NeededArgGPRs; in classifyArgumentType()
401 ArgFPRsLeft -= NeededArgFPRs; in classifyArgumentType()
409 // according to the ABI. 2*XLen-aligned varargs are passed in "aligned" in classifyArgumentType()
414 int NeededArgGPRs = 1; in classifyArgumentType()
415 if (!IsFixed && NeededAlign == 2 * XLen) in classifyArgumentType()
416 NeededArgGPRs = 2 + (EABI && XLen == 32 ? 0 : (ArgGPRsLeft % 2)); in classifyArgumentType()
417 else if (Size > XLen && Size <= 2 * XLen) in classifyArgumentType()
424 ArgGPRsLeft -= NeededArgGPRs; in classifyArgumentType()
426 if (!isAggregateTypeForABI(Ty) && !Ty->isVectorType()) { in classifyArgumentType()
428 if (const EnumType *EnumTy = Ty->getAs<EnumType>()) in classifyArgumentType()
429 Ty = EnumTy->getDecl()->getIntegerType(); in classifyArgumentType()
431 // All integral types are promoted to XLen width in classifyArgumentType()
432 if (Size < XLen && Ty->isIntegralOrEnumerationType()) { in classifyArgumentType()
436 if (const auto *EIT = Ty->getAs<BitIntType>()) { in classifyArgumentType()
437 if (EIT->getNumBits() < XLen) in classifyArgumentType()
439 if (EIT->getNumBits() > 128 || in classifyArgumentType()
441 EIT->getNumBits() > 64)) in classifyArgumentType()
449 Info.setCanBeFlattened(!STy->containsHomogeneousScalableVectorTypes()); in classifyArgumentType()
454 if (const VectorType *VT = Ty->getAs<VectorType>()) in classifyArgumentType()
455 if (VT->getVectorKind() == VectorKind::RVVFixedLengthData || in classifyArgumentType()
456 VT->getVectorKind() == VectorKind::RVVFixedLengthMask) in classifyArgumentType()
459 // Aggregates which are <= 2*XLen will be passed in registers if possible, in classifyArgumentType()
461 if (Size <= 2 * XLen) { in classifyArgumentType()
464 // Use a single XLen int if possible, 2*XLen if 2*XLen alignment is in classifyArgumentType()
465 // required, and a 2-element XLen array if only XLen alignment is required. in classifyArgumentType()
466 if (Size <= XLen) { in classifyArgumentType()
468 llvm::IntegerType::get(getVMContext(), XLen)); in classifyArgumentType()
469 } else if (Alignment == 2 * XLen) { in classifyArgumentType()
471 llvm::IntegerType::get(getVMContext(), 2 * XLen)); in classifyArgumentType()
474 llvm::IntegerType::get(getVMContext(), XLen), 2)); in classifyArgumentType()
481 if (RetTy->isVoidType()) in classifyReturnType()
495 CharUnits SlotSize = CharUnits::fromQuantity(XLen / 8); in EmitVAArg()
504 // 2×XLEN-bit alignment and size at most 2×XLEN bits like `long long`, in EmitVAArg()
505 // `unsigned long long` and `double` to have 4-byte alignment. This in EmitVAArg()
507 if (EABI && XLen == 32) in EmitVAArg()
510 // Arguments bigger than 2*Xlen bytes are passed indirectly. in EmitVAArg()
520 if (XLen == 64 && Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32) in extendType()
528 RISCVTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, in RISCVTargetCodeGenInfo() argument
531 std::make_unique<RISCVABIInfo>(CGT, XLen, FLen, EABI)) { in RISCVTargetCodeGenInfo()
541 const auto *Attr = FD->getAttr<RISCVInterruptAttr>(); in setTargetAttributes()
546 switch (Attr->getInterrupt()) { in setTargetAttributes()
553 Fn->addFnAttr("interrupt", Kind); in setTargetAttributes()
559 CodeGen::createRISCVTargetCodeGenInfo(CodeGenModule &CGM, unsigned XLen, in createRISCVTargetCodeGenInfo() argument
561 return std::make_unique<RISCVTargetCodeGenInfo>(CGM.getTypes(), XLen, FLen, in createRISCVTargetCodeGenInfo()