10#include "TargetInfo.h"
32 llvm::Type *&Field1Ty,
34 llvm::Type *&Field2Ty,
40 :
DefaultABIInfo(CGT), XLen(XLen), FLen(FLen), NumArgGPRs(EABI ? 6 : 8),
41 NumArgFPRs(FLen != 0 ? 8 : 0), EABI(EABI) {}
48 int &ArgFPRsLeft)
const;
56 bool detectFPCCEligibleStruct(
QualType Ty, llvm::Type *&Field1Ty,
57 CharUnits &Field1Off, llvm::Type *&Field2Ty,
59 int &NeededArgFPRs)
const;
60 ABIArgInfo coerceAndExpandFPCCEligibleStruct(llvm::Type *Field1Ty,
81 getContext().getTypeSize(RetTy) > (2 * XLen)) {
84 IsRetIndirect = getContext().getTypeSize(EltTy) > FLen;
91 int ArgGPRsLeft = IsRetIndirect ? NumArgGPRs - 1 : NumArgGPRs;
92 int ArgFPRsLeft = NumArgFPRs;
97 bool IsFixed = ArgNum < NumFixedArgs;
109 llvm::Type *&Field1Ty,
111 llvm::Type *&Field2Ty,
116 if (IsInt || IsFloat) {
118 if (IsInt && Size > XLen)
122 if (IsFloat && Size > FLen)
126 if (IsInt && Field1Ty && Field1Ty->isIntegerTy())
129 Field1Ty = CGT.ConvertType(Ty);
134 Field2Ty = CGT.ConvertType(Ty);
144 QualType EltTy = CTy->getElementType();
145 if (getContext().getTypeSize(EltTy) > FLen)
147 Field1Ty = CGT.ConvertType(EltTy);
150 Field2Off = Field1Off + getContext().getTypeSizeInChars(EltTy);
155 uint64_t ArraySize = ATy->getZExtSize();
156 QualType EltTy = ATy->getElementType();
160 if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) &&
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);
188 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
193 bool Ret = detectFPCCEligibleStructHelper(B.getType(), CurOff + BaseOff,
194 Field1Ty, Field1Off, Field2Ty,
200 int ZeroWidthBitFieldCount = 0;
204 if (FD->isBitField()) {
205 unsigned BitWidth = FD->getBitWidthValue(getContext());
208 if (getContext().getTypeSize(QTy) > XLen && BitWidth <= XLen)
209 QTy = getContext().getIntTypeForBitwidth(XLen,
false);
211 ZeroWidthBitFieldCount++;
216 bool Ret = detectFPCCEligibleStructHelper(
217 QTy, CurOff + getContext().toCharUnitsFromBits(FieldOffInBits),
218 Field1Ty, Field1Off, Field2Ty, Field2Off);
225 if (Field2Ty && ZeroWidthBitFieldCount > 0)
228 return Field1Ty !=
nullptr;
238bool RISCVABIInfo::detectFPCCEligibleStruct(
QualType Ty, llvm::Type *&Field1Ty,
240 llvm::Type *&Field2Ty,
243 int &NeededArgFPRs)
const {
248 bool IsCandidate = detectFPCCEligibleStructHelper(
253 if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy())
257 if (Field1Ty && Field1Ty->isFloatingPointTy())
261 if (Field2Ty && Field2Ty->isFloatingPointTy())
271ABIArgInfo RISCVABIInfo::coerceAndExpandFPCCEligibleStruct(
272 llvm::Type *Field1Ty,
CharUnits Field1Off, llvm::Type *Field2Ty,
277 CoerceElts.push_back(llvm::ArrayType::get(
278 llvm::Type::getInt8Ty(getVMContext()), Field1Off.
getQuantity()));
280 CoerceElts.push_back(Field1Ty);
281 UnpaddedCoerceElts.push_back(Field1Ty);
285 llvm::StructType::get(getVMContext(), CoerceElts, !Field1Off.
isZero()),
286 UnpaddedCoerceElts[0]);
296 if (Field2Off > Field2OffNoPadNoPack)
297 Padding = Field2Off - Field2OffNoPadNoPack;
298 else if (Field2Off != Field2Align && Field2Off > Field1End)
299 Padding = Field2Off - Field1End;
304 CoerceElts.push_back(llvm::ArrayType::get(
305 llvm::Type::getInt8Ty(getVMContext()), Padding.
getQuantity()));
307 CoerceElts.push_back(Field2Ty);
308 UnpaddedCoerceElts.push_back(Field2Ty);
311 llvm::StructType::get(getVMContext(), CoerceElts, IsPacked);
312 auto UnpaddedCoerceToType =
313 llvm::StructType::get(getVMContext(), UnpaddedCoerceElts, IsPacked);
324 assert(VT->getElementType()->isBuiltinType() &&
"expected builtin type!");
327 getContext().getTargetInfo().getVScaleRange(getContext().getLangOpts());
329 unsigned NumElts = VT->getNumElements();
331 if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask) {
333 EltType = llvm::Type::getInt1Ty(getVMContext());
335 assert(VT->getVectorKind() == VectorKind::RVVFixedLengthData &&
336 "Unexpected vector kind");
337 EltType = CGT.ConvertType(VT->getElementType());
344 llvm::ScalableVectorType *ResType =
345 llvm::ScalableVectorType::get(EltType, NumElts / VScale->first);
351 int &ArgFPRsLeft)
const {
352 assert(ArgGPRsLeft <= NumArgGPRs &&
"Arg GPR tracking underflow");
360 return getNaturalAlignIndirect(Ty, RAA ==
372 FLen >= Size && ArgFPRsLeft) {
379 if (IsFixed && Ty->
isComplexType() && FLen && ArgFPRsLeft >= 2) {
381 if (getContext().getTypeSize(EltTy) <= FLen) {
388 llvm::Type *Field1Ty =
nullptr;
389 llvm::Type *Field2Ty =
nullptr;
392 int NeededArgGPRs = 0;
393 int NeededArgFPRs = 0;
395 detectFPCCEligibleStruct(Ty, Field1Ty, Field1Off, Field2Ty, Field2Off,
396 NeededArgGPRs, NeededArgFPRs);
397 if (IsCandidate && NeededArgGPRs <= ArgGPRsLeft &&
398 NeededArgFPRs <= ArgFPRsLeft) {
399 ArgGPRsLeft -= NeededArgGPRs;
400 ArgFPRsLeft -= NeededArgFPRs;
401 return coerceAndExpandFPCCEligibleStruct(Field1Ty, Field1Off, Field2Ty,
406 uint64_t NeededAlign = getContext().getTypeAlign(Ty);
413 int NeededArgGPRs = 1;
414 if (!IsFixed && NeededAlign == 2 * XLen)
415 NeededArgGPRs = 2 + (EABI && XLen == 32 ? 0 : (ArgGPRsLeft % 2));
416 else if (Size > XLen && Size <= 2 * XLen)
419 if (NeededArgGPRs > ArgGPRsLeft) {
420 NeededArgGPRs = ArgGPRsLeft;
423 ArgGPRsLeft -= NeededArgGPRs;
428 Ty = EnumTy->getDecl()->getIntegerType();
431 if (Size < XLen && Ty->isIntegralOrEnumerationType()) {
432 return extendType(Ty);
436 if (EIT->getNumBits() < XLen)
437 return extendType(Ty);
438 if (EIT->getNumBits() > 128 ||
439 (!getContext().getTargetInfo().hasInt128Type() &&
440 EIT->getNumBits() > 64))
441 return getNaturalAlignIndirect(Ty,
false);
447 if (llvm::StructType *STy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty)))
454 if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||
455 VT->getVectorKind() == VectorKind::RVVFixedLengthMask)
456 return coerceVLSVector(Ty);
460 if (Size <= 2 * XLen) {
461 unsigned Alignment = getContext().getTypeAlign(Ty);
467 llvm::IntegerType::get(getVMContext(), XLen));
468 }
else if (Alignment == 2 * XLen) {
470 llvm::IntegerType::get(getVMContext(), 2 * XLen));
473 llvm::IntegerType::get(getVMContext(), XLen), 2));
476 return getNaturalAlignIndirect(Ty,
false);
484 int ArgFPRsLeft = FLen ? 2 : 0;
502 auto TInfo = getContext().getTypeInfoInChars(Ty);
508 if (EABI && XLen == 32)
512 bool IsIndirect = TInfo.Width > 2 * SlotSize;
519 int TySize = getContext().getTypeSize(Ty);
530 unsigned FLen,
bool EABI)
532 std::make_unique<RISCVABIInfo>(CGT, XLen, FLen, EABI)) {
534 std::make_unique<SwiftABIInfo>(CGT,
false);
539 const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
542 const auto *
Attr = FD->getAttr<RISCVInterruptAttr>();
547 switch (
Attr->getInterrupt()) {
548 case RISCVInterruptAttr::supervisor:
Kind =
"supervisor";
break;
549 case RISCVInterruptAttr::machine:
Kind =
"machine";
break;
552 auto *Fn = cast<llvm::Function>(GV);
554 Fn->addFnAttr(
"interrupt", Kind);
559std::unique_ptr<TargetCodeGenInfo>
561 unsigned FLen,
bool EABI) {
562 return std::make_unique<RISCVTargetCodeGenInfo>(CGM.
getTypes(), XLen, FLen,
static CharUnits getTypeStoreSize(CodeGenModule &CGM, llvm::Type *type)
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Attr - This represents one attribute.
A fixed int type of a specified bitwidth.
Represents a base class of a C++ class.
Represents a C++ struct/union/class.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isMultipleOf(CharUnits N) const
Test whether this is a multiple of the other value.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
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 ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
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 ...
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
RecordArgABI
Specify how one should pass an argument of a record type.
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
CGFunctionInfo - Class to encapsulate the information about a function definition.
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
unsigned getNumRequiredArgs() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertTypeForMem(QualType T)
This class organizes the cross-function state that is used while generating LLVM code.
CodeGenTypes & getTypes()
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
DefaultABIInfo - The default implementation for ABI specific details.
ABIArgInfo classifyArgumentType(QualType RetTy) const
ABIArgInfo classifyReturnType(QualType RetTy) const
void computeInfo(CGFunctionInfo &FI) const override
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const override
EmitVAArg - Emit the target dependent code to load a value of.
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
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...
Complex values, per C99 6.2.5p11.
Represents the canonical version of C arrays with a specified constant size.
Decl - This represents one declaration (or definition), e.g.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Represents a member of a struct/union/class.
A (possibly-)qualified type.
Represents a struct/union/class.
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
const T * castAs() const
Member-template castAs<specific type>.
bool isScalarType() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isStructureOrClassType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a GCC generic vector type.
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)
Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, 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)
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)
The JSON file list parser is used to communicate input to InstallAPI.