================
@@ -544,9 +544,402 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const
Type *Ty,
return false;
}
+//===----------------------------------------------------------------------===//
+// z/OS XPLINK ABI Implementation
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class ZOSXPLinkABIInfo : public ABIInfo {
+ const unsigned GPRBits = 64;
+ bool HasVector;
+
+public:
+ ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) : ABIInfo(CGT), HasVector(HV) {}
+
+ bool isPromotableIntegerTypeForABI(QualType Ty) const;
+ bool isCompoundType(QualType Ty) const;
+ bool isVectorArgumentType(QualType Ty) const;
+ QualType getSingleElementType(QualType Ty) const;
+ unsigned getMaxAlignFromTypeDefs(QualType Ty) const;
+ std::optional<QualType> getFPTypeOfComplexLikeType(QualType Ty) const;
+
+ ABIArgInfo classifyReturnType(QualType RetTy,
+ unsigned functionCallConv) const;
+ ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg,
+ unsigned functionCallConv) const;
+
+ void computeInfo(CGFunctionInfo &FI) const override {
+ if (!getCXXABI().classifyReturnType(FI))
+ FI.getReturnInfo() =
+ classifyReturnType(FI.getReturnType(), FI.getCallingConvention());
+
+ unsigned NumRequiredArgs = FI.getNumRequiredArgs();
+ unsigned ArgNo = 0;
+
+ for (auto &I : FI.arguments()) {
+ bool IsNamedArg = ArgNo < NumRequiredArgs;
+ I.info =
+ classifyArgumentType(I.type, IsNamedArg, FI.getCallingConvention());
+ ++ArgNo;
+ }
+ }
+
+ RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
+ AggValueSlot Slot) const override;
+};
+
+class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+ ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector)
+ : TargetCodeGenInfo(std::make_unique<ZOSXPLinkABIInfo>(CGT, HasVector)) {
+ SwiftInfo =
+ std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
+ }
+};
+
+} // namespace
+
+// Return true if the ABI requires Ty to be passed sign- or zero-
+// extended to 64 bits.
+bool ZOSXPLinkABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
+ // Treat an enum type as its underlying type.
+ if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+ Ty = EnumTy->getDecl()->getIntegerType();
+
+ // Promotable integer types are required to be promoted by the ABI.
+ if (ABIInfo::isPromotableIntegerTypeForABI(Ty))
+ return true;
+
+ if (const auto *EIT = Ty->getAs<BitIntType>())
+ if (EIT->getNumBits() < 64)
+ return true;
+
+ // In addition to the usual promotable integer types, we also need to
+ // extend all 32-bit types, since the ABI requires promotion to 64 bits.
+ if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
+ switch (BT->getKind()) {
+ case BuiltinType::Int:
+ case BuiltinType::UInt:
+ case BuiltinType::ULong:
+ case BuiltinType::Long:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool ZOSXPLinkABIInfo::isCompoundType(QualType Ty) const {
+ return (Ty->isAnyComplexType() || Ty->isVectorType() ||
+ isAggregateTypeForABI(Ty));
+}
+
+bool ZOSXPLinkABIInfo::isVectorArgumentType(QualType Ty) const {
+ return (HasVector && Ty->isVectorType() &&
+ getContext().getTypeSize(Ty) <= 128);
+}
+
+QualType ZOSXPLinkABIInfo::getSingleElementType(QualType Ty) const {
+ // Unions just containing a floating point type, e.g. union { float f1, f2;
};
+ // are treated as a single floating point number. Check if the union only
+ // consists of a single type (handling embedded unions recursively), and
+ // return that type.
+ if (const RecordType *RT = Ty->getAsUnionType()) {
+ QualType Found;
+ // Check the fields.
+ const RecordDecl *RD = RT->getDecl();
+ for (const auto *FD : RD->fields()) {
+ if (Found.isNull())
+ Found = getSingleElementType(FD->getType());
+ else if (Found != getSingleElementType(FD->getType()))
+ return Ty;
+ }
+ return Found.isNull() ? Ty : Found;
+ }
+
+ if (const RecordType *RT = Ty->getAsStructureType()) {
+ const RecordDecl *RD = RT->getDecl();
+ QualType Found;
+
+ // If this is a C++ class/struct, inspect its base classes first.
+ if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+ for (const auto &I : CXXRD->bases()) {
+ QualType Base = I.getType();
+
+ // Skip empty base classes, they cannot contribute a data member.
+ if (isEmptyRecord(getContext(), Base, true))
+ continue;
+
+ // A candidate base type was already found; encountering another
+ // non-empty base means the choice is no longer unique. Return the type
+ // from the first candidate.
+ if (!Found.isNull())
+ return Ty;
+ Found = getSingleElementType(Base);
+ }
+
+ // Inspect the record's fields. A struct qualifies as single-element if it
+ // has exactly one non-empty field. Empty fields (zero-size structs,
arrays,
+ // bitfields, or [[no_unique_address]] members) don't affect this
+ // classification. Validated by zos-abi.cpp tests.
+ for (const auto *FD : RD->fields()) {
+ if (!Found.isNull())
+ return Ty; // Multiple non-empty fields found
+ Found = getSingleElementType(FD->getType());
+ }
+ return Found.isNull() ? Ty : Found;
+ }
+ return Ty; // not record/union, unchanged
+}
+
+unsigned ZOSXPLinkABIInfo::getMaxAlignFromTypeDefs(QualType Ty) const {
----------------
uweigand wrote:
This function is no longer called anywhere.
https://github.com/llvm/llvm-project/pull/188501
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits