10#include "TargetInfo.h"
28 static const int NumGARs = 8;
30 static const int NumFARs = 8;
32 llvm::Type *&Field1Ty,
34 llvm::Type *&Field2Ty,
52 bool detectFARsEligibleStruct(
QualType Ty, llvm::Type *&Field1Ty,
53 CharUnits &Field1Off, llvm::Type *&Field2Ty,
55 int &NeededArgFPRs)
const;
56 ABIArgInfo coerceAndExpandFARsEligibleStruct(llvm::Type *Field1Ty,
75 getContext().getTypeSize(RetTy) > (2 * GRLen)) {
78 IsRetIndirect = getContext().getTypeSize(EltTy) > FRLen;
88 int GARsLeft = IsRetIndirect ? NumGARs - 1 : NumGARs;
89 int FARsLeft = FRLen ? NumFARs : 0;
95 ArgInfo.type, ArgNum < NumFixedArgs, GARsLeft, FARsLeft);
103bool LoongArchABIInfo::detectFARsEligibleStructHelper(
105 llvm::Type *&Field2Ty,
CharUnits &Field2Off)
const {
109 if (IsInt || IsFloat) {
111 if (IsInt && Size > GRLen)
116 if (IsFloat && (Size > FRLen || Size < 32))
120 if (IsInt && Field1Ty && Field1Ty->isIntegerTy())
123 Field1Ty = CGT.ConvertType(Ty);
128 Field2Ty = CGT.ConvertType(Ty);
138 QualType EltTy = CTy->getElementType();
139 if (getContext().getTypeSize(EltTy) > FRLen)
141 Field1Ty = CGT.ConvertType(EltTy);
144 Field2Off = Field1Off + getContext().getTypeSizeInChars(EltTy);
149 uint64_t ArraySize = ATy->getZExtSize();
150 QualType EltTy = ATy->getElementType();
154 if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) &&
158 CharUnits EltSize = getContext().getTypeSizeInChars(EltTy);
159 for (uint64_t i = 0; i < ArraySize; ++i) {
160 if (!detectFARsEligibleStructHelper(EltTy, CurOff, Field1Ty, Field1Off,
161 Field2Ty, Field2Off))
175 (!RD->
isUnion() || !isa<CXXRecordDecl>(RD)))
182 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
186 if (!detectFARsEligibleStructHelper(
188 Field1Ty, Field1Off, Field2Ty, Field2Off))
194 if (FD->isBitField()) {
195 unsigned BitWidth = FD->getBitWidthValue(getContext());
201 if (getContext().getTypeSize(QTy) > GRLen && BitWidth <= GRLen) {
202 QTy = getContext().getIntTypeForBitwidth(GRLen,
false);
206 if (!detectFARsEligibleStructHelper(
208 CurOff + getContext().toCharUnitsFromBits(
210 Field1Ty, Field1Off, Field2Ty, Field2Off))
213 return Field1Ty !=
nullptr;
222bool LoongArchABIInfo::detectFARsEligibleStruct(
224 llvm::Type *&Field2Ty,
CharUnits &Field2Off,
int &NeededGARs,
225 int &NeededFARs)
const {
231 Field1Off, Field2Ty, Field2Off))
236 if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy())
238 if (Field1Ty && Field1Ty->isFloatingPointTy())
242 if (Field2Ty && Field2Ty->isFloatingPointTy())
252ABIArgInfo LoongArchABIInfo::coerceAndExpandFARsEligibleStruct(
253 llvm::Type *Field1Ty,
CharUnits Field1Off, llvm::Type *Field2Ty,
258 CoerceElts.push_back(llvm::ArrayType::get(
259 llvm::Type::getInt8Ty(getVMContext()), Field1Off.
getQuantity()));
261 CoerceElts.push_back(Field1Ty);
262 UnpaddedCoerceElts.push_back(Field1Ty);
266 llvm::StructType::get(getVMContext(), CoerceElts, !Field1Off.
isZero()),
267 UnpaddedCoerceElts[0]);
278 if (Field2Off > Field2OffNoPadNoPack)
279 Padding = Field2Off - Field2OffNoPadNoPack;
280 else if (Field2Off != Field2Align && Field2Off > Field1End)
281 Padding = Field2Off - Field1End;
286 CoerceElts.push_back(llvm::ArrayType::get(
287 llvm::Type::getInt8Ty(getVMContext()), Padding.
getQuantity()));
289 CoerceElts.push_back(Field2Ty);
290 UnpaddedCoerceElts.push_back(Field2Ty);
293 llvm::StructType::get(getVMContext(), CoerceElts, IsPacked),
294 llvm::StructType::get(getVMContext(), UnpaddedCoerceElts, IsPacked));
299 int &FARsLeft)
const {
300 assert(GARsLeft <= NumGARs &&
"GAR tracking underflow");
308 return getNaturalAlignIndirect(Ty, RAA ==
322 FRLen >= Size && FARsLeft) {
329 if (IsFixed && Ty->
isComplexType() && FRLen && FARsLeft >= 2) {
331 if (getContext().getTypeSize(EltTy) <= FRLen) {
338 llvm::Type *Field1Ty =
nullptr;
339 llvm::Type *Field2Ty =
nullptr;
344 bool IsCandidate = detectFARsEligibleStruct(
345 Ty, Field1Ty, Field1Off, Field2Ty, Field2Off, NeededGARs, NeededFARs);
346 if (IsCandidate && NeededGARs <= GARsLeft && NeededFARs <= FARsLeft) {
347 GARsLeft -= NeededGARs;
348 FARsLeft -= NeededFARs;
349 return coerceAndExpandFARsEligibleStruct(Field1Ty, Field1Off, Field2Ty,
354 uint64_t NeededAlign = getContext().getTypeAlign(Ty);
359 if (!IsFixed && NeededAlign == 2 * GRLen)
360 NeededGARs = 2 + (GARsLeft % 2);
361 else if (Size > GRLen && Size <= 2 * GRLen)
364 if (NeededGARs > GARsLeft)
365 NeededGARs = GARsLeft;
367 GARsLeft -= NeededGARs;
372 Ty = EnumTy->getDecl()->getIntegerType();
375 if (Size < GRLen && Ty->isIntegralOrEnumerationType())
376 return extendType(Ty);
379 if (EIT->getNumBits() < GRLen)
380 return extendType(Ty);
381 if (EIT->getNumBits() > 128 ||
382 (!getContext().getTargetInfo().hasInt128Type() &&
383 EIT->getNumBits() > 64))
384 return getNaturalAlignIndirect(Ty,
false);
392 if (Size <= 2 * GRLen) {
398 llvm::IntegerType::get(getVMContext(), GRLen));
400 if (getContext().getTypeAlign(Ty) == 2 * GRLen) {
402 llvm::IntegerType::get(getVMContext(), 2 * GRLen));
405 llvm::ArrayType::get(llvm::IntegerType::get(getVMContext(), GRLen), 2));
407 return getNaturalAlignIndirect(Ty,
false);
416 int FARsLeft = FRLen ? 2 : 0;
428 auto TInfo = getContext().getTypeInfoInChars(Ty);
432 TInfo.Width > 2 * SlotSize, TInfo,
438 int TySize = getContext().getTypeSize(Ty);
451 std::make_unique<LoongArchABIInfo>(CGT, GRLen, FRLen)) {}
455std::unique_ptr<TargetCodeGenInfo>
458 return std::make_unique<LoongArchTargetCodeGenInfo>(CGM.
getTypes(), GRLen,
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.
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)
static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T=nullptr)
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
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...
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
RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, AggValueSlot Slot) const override
EmitVAArg - Emit the target dependent code to load a value of.
ABIArgInfo classifyReturnType(QualType RetTy) const
void computeInfo(CGFunctionInfo &FI) const override
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
Complex values, per C99 6.2.5p11.
Represents the canonical version of C arrays with a specified constant size.
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>'.
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.
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
std::unique_ptr< TargetCodeGenInfo > createLoongArchTargetCodeGenInfo(CodeGenModule &CGM, unsigned GRLen, unsigned FLen)
The JSON file list parser is used to communicate input to InstallAPI.