[clang] [llvm] [SystemZ][z/OS] __ptr32 support for z/OS in Clang (PR #96063)
fanbo-meng wrote: Transferring this to @abhina-sree https://github.com/llvm/llvm-project/pull/96063 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ][z/OS] __ptr32 support for z/OS in Clang (PR #96063)
https://github.com/fanbo-meng closed https://github.com/llvm/llvm-project/pull/96063 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng closed https://github.com/llvm/llvm-project/pull/91384 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From aff8d6092d638092235712ca809eb0afd84d1ad6 Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 01/14] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 71192cb0e8c4a..f11d35501667f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index 0925609cc74aa..bbbee74c634ca 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -536,6 +536,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index 4d61f51379346..a81bb252143b0 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -532,9 +533,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From aff8d6092d638092235712ca809eb0afd84d1ad6 Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 01/13] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 71192cb0e8c4a..f11d35501667f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index 0925609cc74aa..bbbee74c634ca 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -536,6 +536,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index 4d61f51379346..a81bb252143b0 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -532,9 +533,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 84e5ca4d8987d071d20b9dcba673b0c856762487 Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 01/12] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 60ef28a0effaa..ffdce2417c67c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
@@ -529,9 +530,355 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + std::optional getFPTypeOfComplexLikeType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const; + + void computeInfo(CGFunctionInfo &FI) const override { +if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + +unsigned NumRequiredArgs = FI.getNumRequiredArgs(); +unsigned ArgNo = 0; + +for (auto &I : FI.arguments()) { + bool IsNamedArg = ArgNo < NumRequiredArgs; + I.info = classifyArgumentType(I.type, IsNamedArg); + ++ArgNo; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +return true; + + if (const auto *EIT = Ty->getAs()) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + return true; +default: + break; +} + + return false; +} + +bool ZOSXPLinkABIInfo::isVectorArgumentType(QualType Ty) const { + return (HasVector && Ty->isVectorType() && + getContext().getTypeSize(Ty) <= 128); +} + +bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const { + if (const BuiltinType *BT = Ty->getAs()) +switch (BT->getKind()) { +case BuiltinType::Float: +case BuiltinType::Double: +case BuiltinType::LongDouble: + return true; +default: + return false; +} + + return false; +} + +QualType ZOSXPLinkABIInfo::getSingleElementType(QualType Ty) const { + const RecordType *RT = Ty->getAs(); + + if (RT && RT->isStructureOrClassType()) { +const RecordDecl *RD = RT->getDecl(); +QualType Found; + +// If this is a C++ record, check the bases first. +if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) + if (CXXRD->hasDefinition()) +for (const auto &I : CXXRD->bases()) { + QualType Base = I.getType(); + + // Empty bases don't affect things either way. + if (isEmptyRecord(getContext(), Base, true)) +continue; + + if (!Found.isNull()) +return Ty; + Found = getSingleElementType(Base); +} + +// Check the fields. +for (const auto *FD : RD->fields()) { + QualType FT = FD->getType(); + + // Ignore empty fields. + if (isEmptyField(getContext(), FD, true)) +continue; + + if (!Found.isNull()) +return Ty; + + // Treat single element arrays as the element. + while (const ConstantArrayType *AT = + getContext().getAsConstantArrayType(FT)) { +if (AT->getZExtSize() != 1) + break; +FT = AT->getElementType(); + } + + Found = getSingleElementType(FT); +} + +// Unlike isSingleElementStruct(), trailing padding is allowed. +if (!Found.isNull()) + return Found; + } + + return Ty; +} + +std::optional +ZOSXPLinkABIInfo::getFPTypeOfComplexLikeType(QualType Ty) const { + if (const RecordType *RT = Ty->getAsStructureType()) { +const RecordDecl *RD = RT->getDecl(); + +// Check for non-empty base classes. +if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) + if (CXXRD->hasDefinition()) +for (const auto &I : CXXRD->bases()) { + QualType Base = I.getType(); +
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 84e5ca4d8987d071d20b9dcba673b0c856762487 Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 01/11] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 60ef28a0effaa..ffdce2417c67c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
fanbo-meng wrote: @uweigand can you review again pls? https://github.com/llvm/llvm-project/pull/91384 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ][z/OS] __ptr32 support for z/OS in Clang (PR #96063)
fanbo-meng wrote: code-formatter is complaining about the entire enum table. To be less pervasive, I'll not address that. https://github.com/llvm/llvm-project/pull/96063 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ][z/OS] __ptr32 support for z/OS in Clang (PR #96063)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/96063 >From 8852cfa1c035246d970f037866c2a6b290e27d43 Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Sat, 21 Mar 2020 10:45:04 -0400 Subject: [PATCH 1/2] __ptr32 support for z/OS Enabling __ptr32 support for z/OS in Clang. --- clang/include/clang/Basic/LangOptions.def | 1 + clang/include/clang/Basic/TokenKinds.def | 3 +- clang/include/clang/Driver/Options.td | 4 + clang/lib/AST/ItaniumMangle.cpp | 8 +- clang/lib/Basic/IdentifierTable.cpp | 16 +- clang/lib/Basic/Targets/SystemZ.h | 43 ++- clang/lib/Frontend/CompilerInvocation.cpp | 11 + clang/lib/Sema/SemaType.cpp | 11 +- clang/test/CodeGen/target-data.c | 2 +- .../CodeGen/zos-mixed-ptr-sizes-definitions.c | 53 .../test/CodeGen/zos-mixed-ptr-sizes-malloc.c | 84 + .../test/CodeGen/zos-mixed-ptr-sizes-sizeof.c | 94 ++ clang/test/CodeGen/zos-mixed-ptr-sizes.c | 298 ++ .../zos-mangle-ptr-size-address-space.cpp | 17 + clang/test/Sema/ZOSExtensions.cpp | 119 +++ clang/test/Sema/attr-print-zos.c | 31 ++ .../Target/SystemZ/SystemZTargetMachine.cpp | 8 + 17 files changed, 792 insertions(+), 11 deletions(-) create mode 100644 clang/test/CodeGen/zos-mixed-ptr-sizes-definitions.c create mode 100644 clang/test/CodeGen/zos-mixed-ptr-sizes-malloc.c create mode 100644 clang/test/CodeGen/zos-mixed-ptr-sizes-sizeof.c create mode 100644 clang/test/CodeGen/zos-mixed-ptr-sizes.c create mode 100644 clang/test/CodeGenCXX/zos-mangle-ptr-size-address-space.cpp create mode 100644 clang/test/Sema/ZOSExtensions.cpp create mode 100644 clang/test/Sema/attr-print-zos.c diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 2dea3cd4d795b..9f303b2f549bf 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -90,6 +90,7 @@ LANGOPT(C23 , 1, 0, "C23") LANGOPT(MSVCCompat, 1, 0, "Microsoft Visual C++ full compatibility mode") LANGOPT(Kernel, 1, 0, "Kernel mode") LANGOPT(MicrosoftExt , 1, 0, "Microsoft C++ extensions") +LANGOPT(ZOSExt, 1, 0, "z/OS extensions") LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks") LANGOPT(Borland , 1, 0, "Borland extensions") LANGOPT(CPlusPlus , 1, 0, "C++") diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 9c4b17465e18a..9717ecd6d7d66 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -286,6 +286,7 @@ PUNCTUATOR(caretcaret,"^^") // CHAR8SUPPORT - This is a keyword if 'char8_t' is a built-in type // KEYFIXEDPOINT - This is a keyword according to the N1169 fixed point // extension. +// KEYZOS - This is a keyword in C/C++ on z/OS // KEYWORD(auto, KEYALL) KEYWORD(break , KEYALL) @@ -708,7 +709,7 @@ KEYWORD(__funcref , KEYALL) // Microsoft extensions which should be disabled in strict conformance mode KEYWORD(__ptr64 , KEYMS) -KEYWORD(__ptr32 , KEYMS) +KEYWORD(__ptr32 , KEYMS | KEYZOS) KEYWORD(__sptr, KEYMS) KEYWORD(__uptr, KEYMS) KEYWORD(__w64 , KEYMS) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d44faa55c456f..e0ae29f881d9e 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3038,6 +3038,10 @@ dll version.}]>; def fms_omit_default_lib : Joined<["-"], "fms-omit-default-lib">, Group, Flags<[]>, Visibility<[ClangOption, CLOption]>; +def fzos_extensions : Flag<["-"], "fzos-extensions">, Group, Visibility<[ClangOption, CC1Option]>, + HelpText<"Accept some non-standard constructs supported by the z/OS compiler">; +def fno_zos_extensions : Flag<["-"], "fno-zos-extensions">, Group, Visibility<[ClangOption, CC1Option]>, + HelpText<"Do not accept non-standard constructs supported by the z/OS compiler">; defm delayed_template_parsing : BoolFOption<"delayed-template-parsing", LangOpts<"DelayedTemplateParsing">, DefaultFalse, PosFlag ::= U //::= U +llvm::Triple Triple = getASTContext().getTargetInfo().getTriple(); + SmallString<64> ASString; LangAS AS = Quals.getAddressSpace(); @@ -2796,7 +2798,11 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp ASString = "ptr32_sptr"; break; case LangAS::ptr32_uptr: -ASString = "ptr32_uptr"; +// For z/OS, there are no special mangling rules applied to the ptr32 +// qualifier. Ex: void foo(in
[clang] [llvm] [SystemZ][z/OS] __ptr32 support for z/OS in Clang (PR #96063)
https://github.com/fanbo-meng created https://github.com/llvm/llvm-project/pull/96063 Enabling __ptr32 keyword to support in Clang for z/OS. It is represented by addrspace(1) in LLVM IR. Unlike existing implementation, __ptr32 is not mangled into symbol names for z/OS. >From 8852cfa1c035246d970f037866c2a6b290e27d43 Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Sat, 21 Mar 2020 10:45:04 -0400 Subject: [PATCH] __ptr32 support for z/OS Enabling __ptr32 support for z/OS in Clang. --- clang/include/clang/Basic/LangOptions.def | 1 + clang/include/clang/Basic/TokenKinds.def | 3 +- clang/include/clang/Driver/Options.td | 4 + clang/lib/AST/ItaniumMangle.cpp | 8 +- clang/lib/Basic/IdentifierTable.cpp | 16 +- clang/lib/Basic/Targets/SystemZ.h | 43 ++- clang/lib/Frontend/CompilerInvocation.cpp | 11 + clang/lib/Sema/SemaType.cpp | 11 +- clang/test/CodeGen/target-data.c | 2 +- .../CodeGen/zos-mixed-ptr-sizes-definitions.c | 53 .../test/CodeGen/zos-mixed-ptr-sizes-malloc.c | 84 + .../test/CodeGen/zos-mixed-ptr-sizes-sizeof.c | 94 ++ clang/test/CodeGen/zos-mixed-ptr-sizes.c | 298 ++ .../zos-mangle-ptr-size-address-space.cpp | 17 + clang/test/Sema/ZOSExtensions.cpp | 119 +++ clang/test/Sema/attr-print-zos.c | 31 ++ .../Target/SystemZ/SystemZTargetMachine.cpp | 8 + 17 files changed, 792 insertions(+), 11 deletions(-) create mode 100644 clang/test/CodeGen/zos-mixed-ptr-sizes-definitions.c create mode 100644 clang/test/CodeGen/zos-mixed-ptr-sizes-malloc.c create mode 100644 clang/test/CodeGen/zos-mixed-ptr-sizes-sizeof.c create mode 100644 clang/test/CodeGen/zos-mixed-ptr-sizes.c create mode 100644 clang/test/CodeGenCXX/zos-mangle-ptr-size-address-space.cpp create mode 100644 clang/test/Sema/ZOSExtensions.cpp create mode 100644 clang/test/Sema/attr-print-zos.c diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 2dea3cd4d795b..9f303b2f549bf 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -90,6 +90,7 @@ LANGOPT(C23 , 1, 0, "C23") LANGOPT(MSVCCompat, 1, 0, "Microsoft Visual C++ full compatibility mode") LANGOPT(Kernel, 1, 0, "Kernel mode") LANGOPT(MicrosoftExt , 1, 0, "Microsoft C++ extensions") +LANGOPT(ZOSExt, 1, 0, "z/OS extensions") LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks") LANGOPT(Borland , 1, 0, "Borland extensions") LANGOPT(CPlusPlus , 1, 0, "C++") diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 9c4b17465e18a..9717ecd6d7d66 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -286,6 +286,7 @@ PUNCTUATOR(caretcaret,"^^") // CHAR8SUPPORT - This is a keyword if 'char8_t' is a built-in type // KEYFIXEDPOINT - This is a keyword according to the N1169 fixed point // extension. +// KEYZOS - This is a keyword in C/C++ on z/OS // KEYWORD(auto, KEYALL) KEYWORD(break , KEYALL) @@ -708,7 +709,7 @@ KEYWORD(__funcref , KEYALL) // Microsoft extensions which should be disabled in strict conformance mode KEYWORD(__ptr64 , KEYMS) -KEYWORD(__ptr32 , KEYMS) +KEYWORD(__ptr32 , KEYMS | KEYZOS) KEYWORD(__sptr, KEYMS) KEYWORD(__uptr, KEYMS) KEYWORD(__w64 , KEYMS) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d44faa55c456f..e0ae29f881d9e 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3038,6 +3038,10 @@ dll version.}]>; def fms_omit_default_lib : Joined<["-"], "fms-omit-default-lib">, Group, Flags<[]>, Visibility<[ClangOption, CLOption]>; +def fzos_extensions : Flag<["-"], "fzos-extensions">, Group, Visibility<[ClangOption, CC1Option]>, + HelpText<"Accept some non-standard constructs supported by the z/OS compiler">; +def fno_zos_extensions : Flag<["-"], "fno-zos-extensions">, Group, Visibility<[ClangOption, CC1Option]>, + HelpText<"Do not accept non-standard constructs supported by the z/OS compiler">; defm delayed_template_parsing : BoolFOption<"delayed-template-parsing", LangOpts<"DelayedTemplateParsing">, DefaultFalse, PosFlag ::= U //::= U +llvm::Triple Triple = getASTContext().getTargetInfo().getTriple(); + SmallString<64> ASString; LangAS AS = Quals.getAddressSpace(); @@ -2796,7 +2798,11 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp ASString = "ptr32_sptr"; break;
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
fanbo-meng wrote: @uweigand can you review again pls? thanks https://github.com/llvm/llvm-project/pull/91384 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 84e5ca4d8987d071d20b9dcba673b0c856762487 Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 01/10] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 60ef28a0effaa..ffdce2417c67c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 84e5ca4d8987d071d20b9dcba673b0c856762487 Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/9] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 60ef28a0effaa..ffdce2417c67c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 84e5ca4d8987d071d20b9dcba673b0c856762487 Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/8] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 60ef28a0effaa..ffdce2417c67c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
fanbo-meng wrote: @uweigand ping for review :) https://github.com/llvm/llvm-project/pull/91384 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 84e5ca4d8987d071d20b9dcba673b0c856762487 Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/7] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 60ef28a0effaa..ffdce2417c67c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 6428b9603044031aa5c58b2d75a0e9310bc3af6a Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/7] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 489c08a4d4819..c7305dede7123 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 6428b9603044031aa5c58b2d75a0e9310bc3af6a Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/7] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 489c08a4d4819..c7305dede7123 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
@@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +return true; + + if (const auto *EIT = Ty->getAs()) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + 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); +} + +bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const { + if (const BuiltinType *BT = Ty->getAs()) +switch (BT->getKind()) { +case BuiltinType::Float: +case BuiltinType::Double: +case BuiltinType::LongDouble: + return true; +default: + return false; +} + + return false; +} + +QualType ZOSXPLinkABIInfo::getSingleElementType(QualType Ty) const { + if (const RecordType *RT = Ty->getAsStructureType()) { +const RecordDecl *RD = RT->getDecl(); +QualType Found; + +// If this is a C++ record, check the bases first. +if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) + for (const auto &I : CXXRD->bases()) { +QualType Base = I.getType(); + +// Empty bases don't affect things either way. +if (isEmptyRecord(getContext(), Base, true)) + continue; + +if (!Found.isNull()) + return Ty; +Found = getSingleElementType(Base); + } + +// Check the fields. +for (const auto *FD : RD->fields()) { + // Unlike isSingleElementStruct(), empty structure and array fields + // do count. So do anonymous bitfields that aren't zero-sized. + if (getContext().getLangOpts().CPlusPlus && + FD->isZeroLengthBitField(getContext())) +continue; + + // Unlike isSingleElementStruct(), arrays do not count. + // Nested structures still do though. + if (!Found.isNull()) +return Ty; + Found = getSingleElementType(FD->getType()); +} + +// Unlike isSingleElementStruct(), trailing padding is allowed. +if (!Found.isNull()) + return Found; + } + + return Ty; +} + +unsigned ZOSXPLinkABIInfo::getMaxAlignFr
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 6428b9603044031aa5c58b2d75a0e9310bc3af6a Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/6] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 489c08a4d4819..c7305dede7123 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
@@ -0,0 +1,137 @@ +// RUN: %clang_cc1 -triple s390x-ibm-zos \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-feature +vector \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-cpu z13 \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-cpu arch11 \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-cpu z14 \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-cpu arch12 \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-cpu z15 \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-cpu arch13 \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s + +// Scalar types + +char pass_char(char arg) { return arg; } +// CHECK-LABEL: define signext i8 @pass_char(i8 signext %{{.*}}) + +short pass_short(short arg) { return arg; } +// CHECK-LABEL: define signext i16 @pass_short(i16 signext %{{.*}}) + +int pass_int(int arg) { return arg; } +// CHECK-LABEL: define signext i32 @pass_int(i32 signext %{{.*}}) + +long pass_long(long arg) { return arg; } +// CHECK-LABEL: define i64 @pass_long(i64 %{{.*}}) + +long long pass_longlong(long long arg) { return arg; } +// CHECK-LABEL: define i64 @pass_longlong(i64 %{{.*}}) + +float pass_float(float arg) { return arg; } +// CHECK-LABEL: define float @pass_float(float %{{.*}}) + +double pass_double(double arg) { return arg; } +// CHECK-LABEL: define double @pass_double(double %{{.*}}) + +long double pass_longdouble(long double arg) { return arg; } +// CHECK-LABEL: define fp128 @pass_longdouble(fp128 %{{.*}}) + +enum Color { Red, Blue }; +enum Color pass_enum(enum Color arg) { return arg; } +// CHECK-LABEL: define zeroext i32 @pass_enum(i32 zeroext %{{.*}}) + +// Complex types + +// TODO: Add tests for complex integer types + +_Complex float pass_complex_float(_Complex float arg) { return arg; } +// CHECK-LABEL: define { float, float } @pass_complex_float(float %{{.*}}, float %{{.*}}) + +_Complex double pass_complex_double(_Complex double arg) { return arg; } +// CHECK-LABEL: define { double, double } @pass_complex_double(double %{{.*}}, double %{{.*}}) + +_Complex long double pass_complex_longdouble(_Complex long double arg) { return arg; } +// CHECK-LABEL: define { fp128, fp128 } @pass_complex_longdouble(fp128 %{{.*}}, fp128 %{{.*}}) + +// Verify that the following are complex-like types +struct complexlike_float { float re, im; }; +struct complexlike_float pass_complexlike_float(struct complexlike_float arg) { return arg; } +// CHECK-LABEL: define %struct.complexlike_float @pass_complexlike_float(float %{{.*}}, float %{{.*}}) + +struct complexlike_double { double re, im; }; +struct complexlike_double pass_complexlike_double(struct complexlike_double arg) { return arg; } +// CHECK-LABEL: define %struct.complexlike_double @pass_complexlike_double(double %{{.*}}, double %{{.*}}) + +struct complexlike_longdouble { long double re, im; }; +struct complexlike_longdouble pass_complexlike_longdouble(struct complexlike_longdouble arg) { return arg; } +// CHECK-LABEL: define %struct.complexlike_longdouble @pass_complexlike_longdouble(fp128 %{{.*}}, fp128 %{{.*}}) + +// Aggregate types + fanbo-meng wrote: For z/OS vaargs I'll create another PR after this one goes in. https://github.com/llvm/llvm-project/pull/91384 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 6428b9603044031aa5c58b2d75a0e9310bc3af6a Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/5] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 489c08a4d4819..c7305dede7123 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
@@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +return true; + + if (const auto *EIT = Ty->getAs()) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + 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); +} + +bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const { + if (const BuiltinType *BT = Ty->getAs()) +switch (BT->getKind()) { +case BuiltinType::Float: +case BuiltinType::Double: +case BuiltinType::LongDouble: + return true; +default: + return false; +} + + return false; +} + +QualType ZOSXPLinkABIInfo::getSingleElementType(QualType Ty) const { + if (const RecordType *RT = Ty->getAsStructureType()) { +const RecordDecl *RD = RT->getDecl(); +QualType Found; + +// If this is a C++ record, check the bases first. +if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) + for (const auto &I : CXXRD->bases()) { +QualType Base = I.getType(); + +// Empty bases don't affect things either way. +if (isEmptyRecord(getContext(), Base, true)) + continue; + +if (!Found.isNull()) + return Ty; +Found = getSingleElementType(Base); + } + +// Check the fields. +for (const auto *FD : RD->fields()) { + // Unlike isSingleElementStruct(), empty structure and array fields + // do count. So do anonymous bitfields that aren't zero-sized. + if (getContext().getLangOpts().CPlusPlus && + FD->isZeroLengthBitField(getContext())) +continue; + + // Unlike isSingleElementStruct(), arrays do not count. + // Nested structures still do though. + if (!Found.isNull()) +return Ty; + Found = getSingleElementType(FD->getType()); +} + +// Unlike isSingleElementStruct(), trailing padding is allowed. +if (!Found.isNull()) + return Found; + } + + return Ty; +} + +unsigned ZOSXPLinkABIInfo::getMaxAlignFr
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 6428b9603044031aa5c58b2d75a0e9310bc3af6a Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/4] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 489c08a4d4819..c7305dede7123 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
@@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +return true; + + if (const auto *EIT = Ty->getAs()) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + 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); +} + +bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const { + if (const BuiltinType *BT = Ty->getAs()) +switch (BT->getKind()) { +case BuiltinType::Float: +case BuiltinType::Double: +case BuiltinType::LongDouble: + return true; +default: + return false; +} + + return false; +} + +QualType ZOSXPLinkABIInfo::getSingleElementType(QualType Ty) const { + if (const RecordType *RT = Ty->getAsStructureType()) { +const RecordDecl *RD = RT->getDecl(); +QualType Found; + +// If this is a C++ record, check the bases first. +if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) + for (const auto &I : CXXRD->bases()) { +QualType Base = I.getType(); + +// Empty bases don't affect things either way. +if (isEmptyRecord(getContext(), Base, true)) + continue; + +if (!Found.isNull()) + return Ty; +Found = getSingleElementType(Base); + } + +// Check the fields. +for (const auto *FD : RD->fields()) { + // Unlike isSingleElementStruct(), empty structure and array fields + // do count. So do anonymous bitfields that aren't zero-sized. + if (getContext().getLangOpts().CPlusPlus && + FD->isZeroLengthBitField(getContext())) +continue; + + // Unlike isSingleElementStruct(), arrays do not count. + // Nested structures still do though. + if (!Found.isNull()) +return Ty; + Found = getSingleElementType(FD->getType()); +} + +// Unlike isSingleElementStruct(), trailing padding is allowed. +if (!Found.isNull()) + return Found; + } + + return Ty; +} + +unsigned ZOSXPLinkABIInfo::getMaxAlignFr
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
@@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +return true; + + if (const auto *EIT = Ty->getAs()) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + 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); +} + +bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const { + if (const BuiltinType *BT = Ty->getAs()) +switch (BT->getKind()) { +case BuiltinType::Float: +case BuiltinType::Double: +case BuiltinType::LongDouble: + return true; +default: + return false; +} + + return false; +} + +QualType ZOSXPLinkABIInfo::getSingleElementType(QualType Ty) const { + if (const RecordType *RT = Ty->getAsStructureType()) { +const RecordDecl *RD = RT->getDecl(); +QualType Found; + +// If this is a C++ record, check the bases first. +if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) + for (const auto &I : CXXRD->bases()) { +QualType Base = I.getType(); + +// Empty bases don't affect things either way. +if (isEmptyRecord(getContext(), Base, true)) + continue; + +if (!Found.isNull()) + return Ty; +Found = getSingleElementType(Base); + } + +// Check the fields. +for (const auto *FD : RD->fields()) { + // Unlike isSingleElementStruct(), empty structure and array fields + // do count. So do anonymous bitfields that aren't zero-sized. + if (getContext().getLangOpts().CPlusPlus && + FD->isZeroLengthBitField(getContext())) +continue; + + // Unlike isSingleElementStruct(), arrays do not count. + // Nested structures still do though. + if (!Found.isNull()) +return Ty; + Found = getSingleElementType(FD->getType()); +} + +// Unlike isSingleElementStruct(), trailing padding is allowed. +if (!Found.isNull()) + return Found; + } + + return Ty; +} + +unsigned ZOSXPLinkABIInfo::getMaxAlignFr
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
@@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +return true; + + if (const auto *EIT = Ty->getAs()) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + 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); +} + +bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const { + if (const BuiltinType *BT = Ty->getAs()) +switch (BT->getKind()) { +case BuiltinType::Float: +case BuiltinType::Double: +case BuiltinType::LongDouble: + return true; +default: + return false; +} + + return false; +} + +QualType ZOSXPLinkABIInfo::getSingleElementType(QualType Ty) const { + if (const RecordType *RT = Ty->getAsStructureType()) { +const RecordDecl *RD = RT->getDecl(); +QualType Found; + +// If this is a C++ record, check the bases first. +if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) + for (const auto &I : CXXRD->bases()) { +QualType Base = I.getType(); + +// Empty bases don't affect things either way. +if (isEmptyRecord(getContext(), Base, true)) + continue; + +if (!Found.isNull()) + return Ty; +Found = getSingleElementType(Base); + } + +// Check the fields. +for (const auto *FD : RD->fields()) { + // Unlike isSingleElementStruct(), empty structure and array fields + // do count. So do anonymous bitfields that aren't zero-sized. + if (getContext().getLangOpts().CPlusPlus && + FD->isZeroLengthBitField(getContext())) +continue; + + // Unlike isSingleElementStruct(), arrays do not count. + // Nested structures still do though. + if (!Found.isNull()) +return Ty; + Found = getSingleElementType(FD->getType()); +} + +// Unlike isSingleElementStruct(), trailing padding is allowed. +if (!Found.isNull()) + return Found; + } + + return Ty; +} + +unsigned ZOSXPLinkABIInfo::getMaxAlignFr
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 6428b9603044031aa5c58b2d75a0e9310bc3af6a Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/3] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 489c08a4d4819..c7305dede7123 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 6428b9603044031aa5c58b2d75a0e9310bc3af6a Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 393 ++ clang/test/CodeGen/zos-abi.c | 162 +++ 4 files changed, 561 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 489c08a4d4819..c7305dede7123 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -242,6 +242,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..d420286c71c16 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -10,6 +10,7 @@ #include "TargetInfo.h" #include "clang/Basic/Builtins.h" #include "llvm/IR/IntrinsicsS390.h" +#include using namespace clang; using namespace clang::CodeGen; @@ -529,9 +530,401 @@ 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 isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType getSingleElementType(QualType Ty) const; + unsigned getMaxAlignFromTypeDefs(QualType Ty) const; + std::optional 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; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
@@ -0,0 +1,137 @@ +// RUN: %clang_cc1 -triple s390x-ibm-zos \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-feature +vector \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-cpu z13 \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-cpu arch11 \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-cpu z14 \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-cpu arch12 \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-cpu z15 \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple s390x-ibm-zos -target-cpu arch13 \ +// RUN: -emit-llvm -no-enable-noundef-analysis -o - %s | FileCheck %s + +// Scalar types + +char pass_char(char arg) { return arg; } +// CHECK-LABEL: define signext i8 @pass_char(i8 signext %{{.*}}) + +short pass_short(short arg) { return arg; } +// CHECK-LABEL: define signext i16 @pass_short(i16 signext %{{.*}}) + +int pass_int(int arg) { return arg; } +// CHECK-LABEL: define signext i32 @pass_int(i32 signext %{{.*}}) + +long pass_long(long arg) { return arg; } +// CHECK-LABEL: define i64 @pass_long(i64 %{{.*}}) + +long long pass_longlong(long long arg) { return arg; } +// CHECK-LABEL: define i64 @pass_longlong(i64 %{{.*}}) + +float pass_float(float arg) { return arg; } +// CHECK-LABEL: define float @pass_float(float %{{.*}}) + +double pass_double(double arg) { return arg; } +// CHECK-LABEL: define double @pass_double(double %{{.*}}) + +long double pass_longdouble(long double arg) { return arg; } +// CHECK-LABEL: define fp128 @pass_longdouble(fp128 %{{.*}}) + +enum Color { Red, Blue }; +enum Color pass_enum(enum Color arg) { return arg; } +// CHECK-LABEL: define zeroext i32 @pass_enum(i32 zeroext %{{.*}}) + +// Complex types + +// TODO: Add tests for complex integer types + +_Complex float pass_complex_float(_Complex float arg) { return arg; } +// CHECK-LABEL: define { float, float } @pass_complex_float(float %{{.*}}, float %{{.*}}) + +_Complex double pass_complex_double(_Complex double arg) { return arg; } +// CHECK-LABEL: define { double, double } @pass_complex_double(double %{{.*}}, double %{{.*}}) + +_Complex long double pass_complex_longdouble(_Complex long double arg) { return arg; } +// CHECK-LABEL: define { fp128, fp128 } @pass_complex_longdouble(fp128 %{{.*}}, fp128 %{{.*}}) + +// Verify that the following are complex-like types +struct complexlike_float { float re, im; }; +struct complexlike_float pass_complexlike_float(struct complexlike_float arg) { return arg; } +// CHECK-LABEL: define %struct.complexlike_float @pass_complexlike_float(float %{{.*}}, float %{{.*}}) + +struct complexlike_double { double re, im; }; +struct complexlike_double pass_complexlike_double(struct complexlike_double arg) { return arg; } +// CHECK-LABEL: define %struct.complexlike_double @pass_complexlike_double(double %{{.*}}, double %{{.*}}) + +struct complexlike_longdouble { long double re, im; }; +struct complexlike_longdouble pass_complexlike_longdouble(struct complexlike_longdouble arg) { return arg; } +// CHECK-LABEL: define %struct.complexlike_longdouble @pass_complexlike_longdouble(fp128 %{{.*}}, fp128 %{{.*}}) + +// Aggregate types + fanbo-meng wrote: I added some tests for unnamed args in https://github.com/llvm/llvm-project/pull/91384/commits/cffe40a198e2a9f78df5c9295c56237ce448bf19, can you provide some examples for the single element struct test? https://github.com/llvm/llvm-project/pull/91384 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 7b40fa0aab937dfc0ab8db48ed93db1a5debef0b Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/8] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 317 ++ clang/test/CodeGen/zos-abi.c | 137 +++ 4 files changed, 460 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c8898ce196c1e..39491d699f6d2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -241,6 +241,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..903e7391b314d 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -529,9 +529,326 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, return false; } +//===--===// +// z/OS XPLINK ABI Implementation +//===--===// + +namespace { + +class ZOSXPLinkABIInfo : public ABIInfo { + static const unsigned GPRBits = 64; + bool HasVector; + +public: + ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) + : ABIInfo(CGT), HasVector(HV) {} + + bool isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType GetSingleElementType(QualType Ty) const; + bool IsLikeComplexType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const; + + void computeInfo(CGFunctionInfo &FI) const override { +if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + +unsigned NumRequiredArgs = FI.getNumRequiredArgs(); +unsigned ArgNo = 0; + +for (auto &I : FI.arguments()) { + bool IsNamedArg = ArgNo < NumRequiredArgs; + I.info = classifyArgumentType(I.type, IsNamedArg); + ++ArgNo; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { + SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + return true; +default: + break; +} + + return false; +} + +bool ZOSXPLinkABIInfo::isCompoundType(QualTyp
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
@@ -529,9 +529,324 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, return false; } +//===--===// +// z/OS XPLINK ABI Implementation +//===--===// + +namespace { + +class ZOSXPLinkABIInfo : public ABIInfo { + static const unsigned GPRBits = 64; + bool HasVector; + +public: + ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) : ABIInfo(CGT), HasVector(HV) {} + + bool isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType GetSingleElementType(QualType Ty) const; + bool IsLikeComplexType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const; + + void computeInfo(CGFunctionInfo &FI) const override { +if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + +unsigned NumRequiredArgs = FI.getNumRequiredArgs(); +unsigned ArgNo = 0; + +for (auto &I : FI.arguments()) { + bool IsNamedArg = ArgNo < NumRequiredArgs; + I.info = classifyArgumentType(I.type, IsNamedArg); + ++ArgNo; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +return true; fanbo-meng wrote: added it https://github.com/llvm/llvm-project/pull/91384 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
@@ -529,9 +529,324 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, return false; } +//===--===// +// z/OS XPLINK ABI Implementation +//===--===// + +namespace { + +class ZOSXPLinkABIInfo : public ABIInfo { + static const unsigned GPRBits = 64; + bool HasVector; + +public: + ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) : ABIInfo(CGT), HasVector(HV) {} + + bool isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType GetSingleElementType(QualType Ty) const; + bool IsLikeComplexType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const; + + void computeInfo(CGFunctionInfo &FI) const override { +if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + +unsigned NumRequiredArgs = FI.getNumRequiredArgs(); +unsigned ArgNo = 0; + +for (auto &I : FI.arguments()) { + bool IsNamedArg = ArgNo < NumRequiredArgs; + I.info = classifyArgumentType(I.type, IsNamedArg); + ++ArgNo; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + 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); +} + +bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const { + if (const BuiltinType *BT = Ty->getAs()) +switch (BT->getKind()) { +case BuiltinType::Float: +case BuiltinType::Double: +case BuiltinType::LongDouble: + return true; +default: + return false; +} + + return false; +} + +QualType ZOSXPLinkABIInfo::GetSingleElementType(QualType Ty) const { + if (const RecordType *RT = Ty->getAsStructureType()) { +const RecordDecl *RD = RT->getDecl(); +QualType Found; + +// If this is a C++ record, check the bases first. +if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) + for (const auto &I : CXXRD->bases()) { +QualType Base = I.getType(); + +// Empty bases don't affect things either way. +if (isEmptyRecord(getContext(), Base, true)) + continue; + +if (!Found.isNull()) + return Ty; +Found = GetSingleElementType(Base); + } + +// Check the fields. +for (const auto *FD : RD->fields()) { + // For compatibility with GCC, ignore empty bitfields in C++ mode. + // Unlike isSingleElementStruct(), empty structure and array fields + // do count. So do anonymous bitfields that aren't zero-sized. + if (getContext().getLangOpts().CPlusPlus && + FD->isZeroLengthBitField(getContext())) +continue; + + // Unlike isSingleElementStruct(), arrays do not count. + // Nested structures still do though. + if (!Found.isNull()) +return Ty; + Found = GetSingleElementType(FD->getType()); +} + +// Unlike isSingleElementStruct(), trailing padding is allowed. +// An 8-byte aligned struct s { float f; } is passed as a double. fanbo-meng wrote: I've removed some of the linux specific comments here, anything needs to be changed for the code? https://github.com/llvm/llvm-project/pull/91384 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/list
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
@@ -529,9 +529,324 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, return false; } +//===--===// +// z/OS XPLINK ABI Implementation +//===--===// + +namespace { + +class ZOSXPLinkABIInfo : public ABIInfo { + static const unsigned GPRBits = 64; + bool HasVector; + +public: + ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) : ABIInfo(CGT), HasVector(HV) {} + + bool isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType GetSingleElementType(QualType Ty) const; + bool IsLikeComplexType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const; + + void computeInfo(CGFunctionInfo &FI) const override { +if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + +unsigned NumRequiredArgs = FI.getNumRequiredArgs(); +unsigned ArgNo = 0; + +for (auto &I : FI.arguments()) { + bool IsNamedArg = ArgNo < NumRequiredArgs; + I.info = classifyArgumentType(I.type, IsNamedArg); + ++ArgNo; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + 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); +} + +bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const { + if (const BuiltinType *BT = Ty->getAs()) +switch (BT->getKind()) { +case BuiltinType::Float: +case BuiltinType::Double: +case BuiltinType::LongDouble: + return true; +default: + return false; +} + + return false; +} + +QualType ZOSXPLinkABIInfo::GetSingleElementType(QualType Ty) const { + if (const RecordType *RT = Ty->getAsStructureType()) { +const RecordDecl *RD = RT->getDecl(); +QualType Found; + +// If this is a C++ record, check the bases first. +if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) + for (const auto &I : CXXRD->bases()) { +QualType Base = I.getType(); + +// Empty bases don't affect things either way. +if (isEmptyRecord(getContext(), Base, true)) + continue; + +if (!Found.isNull()) + return Ty; +Found = GetSingleElementType(Base); + } + +// Check the fields. +for (const auto *FD : RD->fields()) { + // For compatibility with GCC, ignore empty bitfields in C++ mode. + // Unlike isSingleElementStruct(), empty structure and array fields + // do count. So do anonymous bitfields that aren't zero-sized. + if (getContext().getLangOpts().CPlusPlus && + FD->isZeroLengthBitField(getContext())) +continue; + + // Unlike isSingleElementStruct(), arrays do not count. + // Nested structures still do though. + if (!Found.isNull()) +return Ty; + Found = GetSingleElementType(FD->getType()); +} + +// Unlike isSingleElementStruct(), trailing padding is allowed. +// An 8-byte aligned struct s { float f; } is passed as a double. +if (!Found.isNull()) + return Found; + } + + return Ty; +} + +bool ZOSXPLinkABIInfo::IsLikeComplexType(QualType Ty) const { + if (const RecordType *RT = Ty->getAsStructureType()) { +const RecordDecl *RD = RT->getDecl(); +int i = 0; +clang::BuiltinType::Kind elemKind; + +// Check for exactly two el
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
@@ -529,9 +529,324 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, return false; } +//===--===// +// z/OS XPLINK ABI Implementation +//===--===// + +namespace { + +class ZOSXPLinkABIInfo : public ABIInfo { + static const unsigned GPRBits = 64; + bool HasVector; + +public: + ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) : ABIInfo(CGT), HasVector(HV) {} + + bool isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType GetSingleElementType(QualType Ty) const; + bool IsLikeComplexType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const; + + void computeInfo(CGFunctionInfo &FI) const override { +if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + +unsigned NumRequiredArgs = FI.getNumRequiredArgs(); +unsigned ArgNo = 0; + +for (auto &I : FI.arguments()) { + bool IsNamedArg = ArgNo < NumRequiredArgs; + I.info = classifyArgumentType(I.type, IsNamedArg); + ++ArgNo; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { +SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + 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); +} + +bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const { + if (const BuiltinType *BT = Ty->getAs()) +switch (BT->getKind()) { +case BuiltinType::Float: +case BuiltinType::Double: +case BuiltinType::LongDouble: + return true; +default: + return false; +} + + return false; +} + +QualType ZOSXPLinkABIInfo::GetSingleElementType(QualType Ty) const { + if (const RecordType *RT = Ty->getAsStructureType()) { +const RecordDecl *RD = RT->getDecl(); +QualType Found; + +// If this is a C++ record, check the bases first. +if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) + for (const auto &I : CXXRD->bases()) { +QualType Base = I.getType(); + +// Empty bases don't affect things either way. +if (isEmptyRecord(getContext(), Base, true)) + continue; + +if (!Found.isNull()) + return Ty; +Found = GetSingleElementType(Base); + } + +// Check the fields. +for (const auto *FD : RD->fields()) { + // For compatibility with GCC, ignore empty bitfields in C++ mode. + // Unlike isSingleElementStruct(), empty structure and array fields + // do count. So do anonymous bitfields that aren't zero-sized. + if (getContext().getLangOpts().CPlusPlus && + FD->isZeroLengthBitField(getContext())) +continue; + + // Unlike isSingleElementStruct(), arrays do not count. + // Nested structures still do though. + if (!Found.isNull()) +return Ty; + Found = GetSingleElementType(FD->getType()); +} + +// Unlike isSingleElementStruct(), trailing padding is allowed. +// An 8-byte aligned struct s { float f; } is passed as a double. +if (!Found.isNull()) + return Found; + } + + return Ty; +} + +bool ZOSXPLinkABIInfo::IsLikeComplexType(QualType Ty) const { + if (const RecordType *RT = Ty->getAsStructureType()) { +const RecordDecl *RD = RT->getDecl(); +int i = 0; +clang::BuiltinType::Kind elemKind; + +// Check for exactly two el
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 7b40fa0aab937dfc0ab8db48ed93db1a5debef0b Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/6] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 317 ++ clang/test/CodeGen/zos-abi.c | 137 +++ 4 files changed, 460 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c8898ce196c1e..39491d699f6d2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -241,6 +241,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..903e7391b314d 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -529,9 +529,326 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, return false; } +//===--===// +// z/OS XPLINK ABI Implementation +//===--===// + +namespace { + +class ZOSXPLinkABIInfo : public ABIInfo { + static const unsigned GPRBits = 64; + bool HasVector; + +public: + ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) + : ABIInfo(CGT), HasVector(HV) {} + + bool isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType GetSingleElementType(QualType Ty) const; + bool IsLikeComplexType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const; + + void computeInfo(CGFunctionInfo &FI) const override { +if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + +unsigned NumRequiredArgs = FI.getNumRequiredArgs(); +unsigned ArgNo = 0; + +for (auto &I : FI.arguments()) { + bool IsNamedArg = ArgNo < NumRequiredArgs; + I.info = classifyArgumentType(I.type, IsNamedArg); + ++ArgNo; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { + SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + return true; +default: + break; +} + + return false; +} + +bool ZOSXPLinkABIInfo::isCompoundType(QualTyp
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 7b40fa0aab937dfc0ab8db48ed93db1a5debef0b Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/5] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 317 ++ clang/test/CodeGen/zos-abi.c | 137 +++ 4 files changed, 460 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c8898ce196c1e..39491d699f6d2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -241,6 +241,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..903e7391b314d 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -529,9 +529,326 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, return false; } +//===--===// +// z/OS XPLINK ABI Implementation +//===--===// + +namespace { + +class ZOSXPLinkABIInfo : public ABIInfo { + static const unsigned GPRBits = 64; + bool HasVector; + +public: + ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) + : ABIInfo(CGT), HasVector(HV) {} + + bool isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType GetSingleElementType(QualType Ty) const; + bool IsLikeComplexType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const; + + void computeInfo(CGFunctionInfo &FI) const override { +if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + +unsigned NumRequiredArgs = FI.getNumRequiredArgs(); +unsigned ArgNo = 0; + +for (auto &I : FI.arguments()) { + bool IsNamedArg = ArgNo < NumRequiredArgs; + I.info = classifyArgumentType(I.type, IsNamedArg); + ++ArgNo; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { + SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + return true; +default: + break; +} + + return false; +} + +bool ZOSXPLinkABIInfo::isCompoundType(QualTyp
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 7b40fa0aab937dfc0ab8db48ed93db1a5debef0b Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/4] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 317 ++ clang/test/CodeGen/zos-abi.c | 137 +++ 4 files changed, 460 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c8898ce196c1e..39491d699f6d2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -241,6 +241,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..903e7391b314d 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -529,9 +529,326 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, return false; } +//===--===// +// z/OS XPLINK ABI Implementation +//===--===// + +namespace { + +class ZOSXPLinkABIInfo : public ABIInfo { + static const unsigned GPRBits = 64; + bool HasVector; + +public: + ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) + : ABIInfo(CGT), HasVector(HV) {} + + bool isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType GetSingleElementType(QualType Ty) const; + bool IsLikeComplexType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const; + + void computeInfo(CGFunctionInfo &FI) const override { +if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + +unsigned NumRequiredArgs = FI.getNumRequiredArgs(); +unsigned ArgNo = 0; + +for (auto &I : FI.arguments()) { + bool IsNamedArg = ArgNo < NumRequiredArgs; + I.info = classifyArgumentType(I.type, IsNamedArg); + ++ArgNo; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { + SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + return true; +default: + break; +} + + return false; +} + +bool ZOSXPLinkABIInfo::isCompoundType(QualTyp
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 7b40fa0aab937dfc0ab8db48ed93db1a5debef0b Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/3] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 317 ++ clang/test/CodeGen/zos-abi.c | 137 +++ 4 files changed, 460 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c8898ce196c1e..39491d699f6d2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -241,6 +241,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..903e7391b314d 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -529,9 +529,326 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, return false; } +//===--===// +// z/OS XPLINK ABI Implementation +//===--===// + +namespace { + +class ZOSXPLinkABIInfo : public ABIInfo { + static const unsigned GPRBits = 64; + bool HasVector; + +public: + ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) + : ABIInfo(CGT), HasVector(HV) {} + + bool isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType GetSingleElementType(QualType Ty) const; + bool IsLikeComplexType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const; + + void computeInfo(CGFunctionInfo &FI) const override { +if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + +unsigned NumRequiredArgs = FI.getNumRequiredArgs(); +unsigned ArgNo = 0; + +for (auto &I : FI.arguments()) { + bool IsNamedArg = ArgNo < NumRequiredArgs; + I.info = classifyArgumentType(I.type, IsNamedArg); + ++ArgNo; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { + SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + return true; +default: + break; +} + + return false; +} + +bool ZOSXPLinkABIInfo::isCompoundType(QualTyp
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng updated https://github.com/llvm/llvm-project/pull/91384 >From 7b40fa0aab937dfc0ab8db48ed93db1a5debef0b Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH 1/2] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 317 ++ clang/test/CodeGen/zos-abi.c | 137 +++ 4 files changed, 460 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c8898ce196c1e..39491d699f6d2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -241,6 +241,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..903e7391b314d 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -529,9 +529,326 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, return false; } +//===--===// +// z/OS XPLINK ABI Implementation +//===--===// + +namespace { + +class ZOSXPLinkABIInfo : public ABIInfo { + static const unsigned GPRBits = 64; + bool HasVector; + +public: + ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) + : ABIInfo(CGT), HasVector(HV) {} + + bool isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType GetSingleElementType(QualType Ty) const; + bool IsLikeComplexType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const; + + void computeInfo(CGFunctionInfo &FI) const override { +if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + +unsigned NumRequiredArgs = FI.getNumRequiredArgs(); +unsigned ArgNo = 0; + +for (auto &I : FI.arguments()) { + bool IsNamedArg = ArgNo < NumRequiredArgs; + I.info = classifyArgumentType(I.type, IsNamedArg); + ++ArgNo; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { + SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +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()) +switch (BT->getKind()) { +case BuiltinType::Int: +case BuiltinType::UInt: + return true; +default: + break; +} + + return false; +} + +bool ZOSXPLinkABIInfo::isCompoundType(QualTyp
[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)
https://github.com/fanbo-meng created https://github.com/llvm/llvm-project/pull/91384 The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) >From 7b40fa0aab937dfc0ab8db48ed93db1a5debef0b Mon Sep 17 00:00:00 2001 From: Fanbo Meng Date: Tue, 7 May 2024 13:36:38 -0400 Subject: [PATCH] [SystemZ][z/OS] Implement z/OS XPLINK ABI The XPLINK calling convention is specified in the Language Environment Vendor Interface, chapter 22, (https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cee/cee.htm) and in Redbook XPLink: OS/390 Extra Performance Linkage (http://www.redbooks.ibm.com/abstracts/sg245991.html?Open) --- clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h| 4 + clang/lib/CodeGen/Targets/SystemZ.cpp | 317 ++ clang/test/CodeGen/zos-abi.c | 137 +++ 4 files changed, 460 insertions(+) create mode 100644 clang/test/CodeGen/zos-abi.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c8898ce196c1e..39491d699f6d2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -241,6 +241,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { case llvm::Triple::systemz: { bool SoftFloat = CodeGenOpts.FloatABI == "soft"; bool HasVector = !SoftFloat && Target.getABI() == "vector"; +if (Triple.getOS() == llvm::Triple::ZOS) + return createSystemZ_ZOS_TargetCodeGenInfo(CGM, HasVector, SoftFloat); return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f242d9e36ed40..e15f9bdf39356 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -527,6 +527,10 @@ std::unique_ptr createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI); +std::unique_ptr +createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, +bool SoftFloatABI); + std::unique_ptr createTCETargetCodeGenInfo(CodeGenModule &CGM); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a3157..903e7391b314d 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -529,9 +529,326 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, return false; } +//===--===// +// z/OS XPLINK ABI Implementation +//===--===// + +namespace { + +class ZOSXPLinkABIInfo : public ABIInfo { + static const unsigned GPRBits = 64; + bool HasVector; + +public: + ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) + : ABIInfo(CGT), HasVector(HV) {} + + bool isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + QualType GetSingleElementType(QualType Ty) const; + bool IsLikeComplexType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const; + + void computeInfo(CGFunctionInfo &FI) const override { +if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + +unsigned NumRequiredArgs = FI.getNumRequiredArgs(); +unsigned ArgNo = 0; + +for (auto &I : FI.arguments()) { + bool IsNamedArg = ArgNo < NumRequiredArgs; + I.info = classifyArgumentType(I.type, IsNamedArg); + ++ArgNo; +} + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, +QualType Ty) const override; +}; + +class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) + : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) { + SwiftInfo = +std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } +}; + +} // namespace + +// Return true if the ABI requires Ty to be passed sign- or zero- +// extended to 64 bits. +bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (getContext().isPromotableIntegerType(Ty)) +return true; + + // In addition to the usual promotable integer types, we also need to + // extend all 32-bit type
[clang] [llvm] Use llvm-config.h in CIndexer.cpp instead of private header (PR #75928)
https://github.com/fanbo-meng approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/75928 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SystemZ][z/OS] Add guard for dl_info and dladdr (PR #75637)
https://github.com/fanbo-meng approved this pull request. LGTM with nit https://github.com/llvm/llvm-project/pull/75637 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SystemZ][z/OS] Add guard for dl_info and dladdr (PR #75637)
https://github.com/fanbo-meng edited https://github.com/llvm/llvm-project/pull/75637 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SystemZ][z/OS] Add guard for dl_info and dladdr (PR #75637)
@@ -125,21 +126,28 @@ const std::string &CIndexer::getClangResourcesPath() { #elif defined(_AIX) getClangResourcesPathImplAIX(LibClangPath); #else + bool pathFound = false; fanbo-meng wrote: nit: Variables should start with upper case https://github.com/llvm/llvm-project/pull/75637 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ][z/OS] Add missing strnlen function for z/OS to fix build failures (PR #75339)
https://github.com/fanbo-meng approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/75339 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ][z/OS] Complete EBCDIC I/O support (PR #75212)
https://github.com/fanbo-meng approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/75212 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] be646ef - Make clang/test/C/C2x/n2934.c compatible with targets that do not support thread_local storage.
Author: Fanbo Meng Date: 2023-03-02T11:18:19-05:00 New Revision: be646ef39298503592407fd7eac9ce7fc2ee5f7c URL: https://github.com/llvm/llvm-project/commit/be646ef39298503592407fd7eac9ce7fc2ee5f7c DIFF: https://github.com/llvm/llvm-project/commit/be646ef39298503592407fd7eac9ce7fc2ee5f7c.diff LOG: Make clang/test/C/C2x/n2934.c compatible with targets that do not support thread_local storage. Add an optional error check to test case for it to pass on targets that do not support thread_local storage. Reviewed By: aaron.ballman, abhina.sreeskantharajan Differential Revision: https://reviews.llvm.org/D145158 Added: Modified: clang/test/C/C2x/n2934.c Removed: diff --git a/clang/test/C/C2x/n2934.c b/clang/test/C/C2x/n2934.c index d36e0b76344a3..d967446d8465a 100644 --- a/clang/test/C/C2x/n2934.c +++ b/clang/test/C/C2x/n2934.c @@ -7,6 +7,7 @@ thread_local struct alignas(int) S { // c2x-warning {{'alignas' is incompatible with C standards before C2x}} \ c2x-warning {{'thread_local' is incompatible with C standards before C2x}} \ +c2x-error 0+ {{thread-local storage is not supported for the current target}} \ c17-error {{unknown type name 'thread_local'}} \ c17-error {{expected identifier or '('}} \ c17-error {{expected ')'}} \ ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] ae206db - [SystemZ][z/OS] Create html report file with text flag
Author: Fanbo Meng Date: 2021-08-31T11:52:04-04:00 New Revision: ae206db2d653cfeb1021e4e8f5783de797e521a5 URL: https://github.com/llvm/llvm-project/commit/ae206db2d653cfeb1021e4e8f5783de797e521a5 DIFF: https://github.com/llvm/llvm-project/commit/ae206db2d653cfeb1021e4e8f5783de797e521a5.diff LOG: [SystemZ][z/OS] Create html report file with text flag Change OF_None to OF_Text flag in file creation, same reasoning as https://reviews.llvm.org/D97785 Reviewed By: abhina.sreeskantharajan Differential Revision: https://reviews.llvm.org/D108998 Added: Modified: clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp Removed: diff --git a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp index e7df9a70839de..9db3b140f21e5 100644 --- a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp @@ -344,7 +344,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, if (std::error_code EC = llvm::sys::fs::openFileForReadWrite( ResultPath, FD, llvm::sys::fs::CD_CreateNew, - llvm::sys::fs::OF_None)) { + llvm::sys::fs::OF_Text)) { // Existence of the file corresponds to the situation where a diff erent // Clang instance has emitted a bug report with the same issue hash. // This is an entirely normal situation that does not deserve a warning, ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 9d7a77c - [MCParser][z/OS] Mark test as unsupported for the z/OS Target
Author: Fanbo Meng Date: 2021-08-27T11:45:38-04:00 New Revision: 9d7a77c26d2f68e1c3b58b61d792d371bd3ed224 URL: https://github.com/llvm/llvm-project/commit/9d7a77c26d2f68e1c3b58b61d792d371bd3ed224 DIFF: https://github.com/llvm/llvm-project/commit/9d7a77c26d2f68e1c3b58b61d792d371bd3ed224.diff LOG: [MCParser][z/OS] Mark test as unsupported for the z/OS Target Marking test as unsupported for the same reason as https://reviews.llvm.org/D105204 Reviewed By: abhina.sreeskantharajan Differential Revision: https://reviews.llvm.org/D108819 Added: Modified: clang/test/Driver/as-version.s Removed: diff --git a/clang/test/Driver/as-version.s b/clang/test/Driver/as-version.s index e9e66563942f..296f9e83ece9 100644 --- a/clang/test/Driver/as-version.s +++ b/clang/test/Driver/as-version.s @@ -1,5 +1,6 @@ // Test version information. +// UNSUPPORTED: -zos // RUN: %clang -Wa,--version -c -fintegrated-as %s -o /dev/null \ // RUN: | FileCheck --check-prefix=IAS %s // IAS: clang version ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 91e3995 - Revert "[SystemZ][z/OS] Update target specific __attribute__((aligned)) value for test"
Author: Fanbo Meng Date: 2021-08-05T10:14:02-04:00 New Revision: 91e399519580930623e1eb7be43374f0ba8aba41 URL: https://github.com/llvm/llvm-project/commit/91e399519580930623e1eb7be43374f0ba8aba41 DIFF: https://github.com/llvm/llvm-project/commit/91e399519580930623e1eb7be43374f0ba8aba41.diff LOG: Revert "[SystemZ][z/OS] Update target specific __attribute__((aligned)) value for test" This reverts commit d91234b21c1a1a34d98157089a8769d8f9a32f06. Reviewed By: abhina.sreeskantharajan Differential Revision: https://reviews.llvm.org/D107565 Added: Modified: clang/test/Sema/struct-packed-align.c Removed: diff --git a/clang/test/Sema/struct-packed-align.c b/clang/test/Sema/struct-packed-align.c index b4bddebe230e2..03b012e340287 100644 --- a/clang/test/Sema/struct-packed-align.c +++ b/clang/test/Sema/struct-packed-align.c @@ -59,7 +59,7 @@ extern int e2[__alignof(struct as1) == 8 ? 1 : -1]; struct __attribute__((aligned)) as1_2 { char c; }; -#if ((defined(__s390x__) && !defined(__MVS__)) || (defined(__ARM_32BIT_STATE) && !defined(__ANDROID__))) +#if ( defined(__s390x__) || ( defined (__ARM_32BIT_STATE) && ! defined(__ANDROID__) ) ) extern int e1_2[sizeof(struct as1_2) == 8 ? 1 : -1]; extern int e2_2[__alignof(struct as1_2) == 8 ? 1 : -1]; #else ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] bdf4c7b - [z/OS]Remove overriding default attribute aligned value
Author: Fanbo Meng Date: 2021-07-30T15:51:40-04:00 New Revision: bdf4c7b738ee3dfbcd468ec347beec58b6e43a5a URL: https://github.com/llvm/llvm-project/commit/bdf4c7b738ee3dfbcd468ec347beec58b6e43a5a DIFF: https://github.com/llvm/llvm-project/commit/bdf4c7b738ee3dfbcd468ec347beec58b6e43a5a.diff LOG: [z/OS]Remove overriding default attribute aligned value Make DefaultAlignForAttributeAligned consistent with SystemZ. Reviewed By: abhina.sreeskantharajan, anirudhp Differential Revision: https://reviews.llvm.org/D107189 Added: Modified: clang/lib/Basic/Targets/OSTargets.h clang/test/CodeGen/SystemZ/zos-alignment.c Removed: diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 6329acf756834..9780d5036aa23 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -796,7 +796,6 @@ class LLVM_LIBRARY_VISIBILITY ZOSTargetInfo : public OSTargetInfo { this->UseZeroLengthBitfieldAlignment = true; this->UseLeadingZeroLengthBitfield = false; this->ZeroLengthBitfieldBoundary = 32; -this->DefaultAlignForAttributeAligned = 128; } }; diff --git a/clang/test/CodeGen/SystemZ/zos-alignment.c b/clang/test/CodeGen/SystemZ/zos-alignment.c index 7b08f4bf7f4a7..be26c5a2785dd 100644 --- a/clang/test/CodeGen/SystemZ/zos-alignment.c +++ b/clang/test/CodeGen/SystemZ/zos-alignment.c @@ -147,7 +147,7 @@ struct s10 { } S10; // CHECK: 0 | struct s10 // CHECK-NEXT: 0 | unsigned int a -// CHECK-NEXT: | [sizeof=16, align=16] +// CHECK-NEXT: | [sizeof=8, align=8] struct s11 { char a; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] a2d4b06 - [z/OS] Make MinGlobalAlign consistent with SystemZ
Author: Fanbo Meng Date: 2021-07-27T15:39:14-04:00 New Revision: a2d4b064644bdf146d0649c6a70e595567f1213f URL: https://github.com/llvm/llvm-project/commit/a2d4b064644bdf146d0649c6a70e595567f1213f DIFF: https://github.com/llvm/llvm-project/commit/a2d4b064644bdf146d0649c6a70e595567f1213f.diff LOG: [z/OS] Make MinGlobalAlign consistent with SystemZ Remove overriding MinGlobalAlign to 0 for z/OS target to be consistent with SystemZ. Reviewed By: abhina.sreeskantharajan Differential Revision: https://reviews.llvm.org/D106890 Added: Modified: clang/lib/Basic/Targets/OSTargets.h Removed: diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 31f8b4bea30d9..e24fb5cf082df 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -796,7 +796,6 @@ class LLVM_LIBRARY_VISIBILITY ZOSTargetInfo : public OSTargetInfo { this->UseZeroLengthBitfieldAlignment = true; this->UseLeadingZeroLengthBitfield = false; this->ZeroLengthBitfieldBoundary = 32; -this->MinGlobalAlign = 0; this->DefaultAlignForAttributeAligned = 128; } }; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] bd8dd58 - [NFC] clang-formatting zos-alignment.c
Author: Fanbo Meng Date: 2021-03-29T16:48:10-04:00 New Revision: bd8dd580ffd221dd38e28c609b30d9b6361efac7 URL: https://github.com/llvm/llvm-project/commit/bd8dd580ffd221dd38e28c609b30d9b6361efac7 DIFF: https://github.com/llvm/llvm-project/commit/bd8dd580ffd221dd38e28c609b30d9b6361efac7.diff LOG: [NFC] clang-formatting zos-alignment.c Reviewed By: abhina.sreeskantharajan Differential Revision: https://reviews.llvm.org/D99514 Added: Modified: clang/test/CodeGen/SystemZ/zos-alignment.c Removed: diff --git a/clang/test/CodeGen/SystemZ/zos-alignment.c b/clang/test/CodeGen/SystemZ/zos-alignment.c index b43968410cec..7b08f4bf7f4a 100644 --- a/clang/test/CodeGen/SystemZ/zos-alignment.c +++ b/clang/test/CodeGen/SystemZ/zos-alignment.c @@ -13,8 +13,8 @@ int f0() { return v0 + v1 + v2 + v3; } // DECL-NEXT: @v3 {{.*}} align 32 const struct cs0 { - unsigned long :0; - long longa; + unsigned long : 0; + long long a; } CS0 = {}; // CHECK: 0 | struct cs0 // CHECK-NEXT: 0:- | unsigned long @@ -22,8 +22,8 @@ const struct cs0 { // CHECK-NEXT: | [sizeof=8, align=8] volatile struct vs0 { - long:0; - short a; + long : 0; + short a; } VS0; // CHECK: 0 | struct vs0 // CHECK-NEXT: 0:- | long @@ -31,11 +31,11 @@ volatile struct vs0 { // CHECK-NEXT: | [sizeof=2, align=2] struct s0 { - short a:3; - long b:5; - int c:1; - long d:10; - char e:5; + short a : 3; + long b : 5; + int c : 1; + long d : 10; + char e : 5; } S0; // CHECK: 0 | struct s0 // CHECK-NEXT: 0:0-2 | short a @@ -46,9 +46,9 @@ struct s0 { // CHECK-NEXT: | [sizeof=3, align=1] struct s1 { - char a:7; - long b:27; - int c:2; + char a : 7; + long b : 27; + int c : 2; } S1; // CHECK: 0 | struct s1 // CHECK-NEXT: 0:0-6 | char a @@ -57,10 +57,10 @@ struct s1 { // CHECK-NEXT: | [sizeof=5, align=1] struct s2 { - char a:7; - char :0; - short :0; - short :0; + char a : 7; + char : 0; + short : 0; + short : 0; } S2; // CHECK: 0 | struct s2 // CHECK-NEXT: 0:0-6 | char a @@ -71,9 +71,9 @@ struct s2 { struct s3 { int a; - int b:16; - char :0; - char c:1; + int b : 16; + char : 0; + char c : 1; } S3; // CHECK: 0 | struct s3 // CHECK-NEXT: 0 | int a @@ -83,7 +83,7 @@ struct s3 { // CHECK-NEXT: | [sizeof=12, align=4] struct s4 { - unsigned int __attribute__((aligned(32))) a; + unsigned int __attribute__((aligned(32))) a; } S4; // CHECK: 0 | struct s4 // CHECK-NEXT: 0 | unsigned int a @@ -91,10 +91,10 @@ struct s4 { struct s5 { char a; - int b:19 __attribute__((aligned(4))); - int c:22 __attribute__((aligned(8))); - int :0; - int d:10; + int b : 19 __attribute__((aligned(4))); + int c : 22 __attribute__((aligned(8))); + int : 0; + int d : 10; } S5; // CHECK: 0 | struct s5 // CHECK-NEXT: 0 | char a @@ -105,8 +105,8 @@ struct s5 { // CHECK-NEXT: | [sizeof=16, align=8] struct s6 { - char * a; - char * b[]; + char *a; + char *b[]; } S6; // CHECK: 0 | struct s6 // CHECK-NEXT: 0 | char * a @@ -114,7 +114,7 @@ struct s6 { // CHECK-NEXT: | [sizeof=8, align=8] struct s7 { - long :0; + long : 0; short a; } S7; // CHECK: 0 | struct s7 @@ -124,8 +124,8 @@ struct s7 { #pragma pack(2) struct s8 { - unsigned long :0; - long long a; + unsigned long : 0; + long long a; } S8; #pragma pack() // CHECK: 0 | struct s8 @@ -134,8 +134,8 @@ struct s8 { // CHECK-NEXT: | [sizeof=8, align=2] struct s9 { - unsigned int :0; - unsigned short :0; + unsigned int : 0; + unsigned short : 0; } S9; // CHECK: 0 | struct s9 // CHECK-NEXT: 0:- | unsigned int @@ -143,7 +143,7 @@ struct s9 { // CHECK-NEXT: | [sizeof=0, align=1] struct s10 { - unsigned int __attribute__((aligned)) a; + unsigned int __attribute__((aligned)) a; } S10; // CHECK: 0 | struct s10 // CHECK-NEXT: 0 | unsigned int a @@ -151,7 +151,7 @@ struct s10 { struct s11 { char a; - long :0; + long : 0; char b; } S11; // CHECK: 0 | struct s11 @@ -161,9 +161,9 @@ struct s11 { // CHECK-NEXT: | [sizeof=16, align=8] union u0 { - unsigned short d1 __attribute__((packed)); - intd2:10; - long d3; + unsigned short d1 __attribute__((packed)); + int d2 : 10; + long d3; } U0 __attribute__((aligned(8))); // CHECK: 0 | union u0 // CHECK-NEXT: 0 | unsigned short d1 @@ -172,8 +172,8 @@ union u0 { // CHECK-NEXT: | [sizeof=8, align=8] union u1 { - unsigned int:0; - short a; +
[clang] f1e0c7f - [SystemZ][z/OS] Add test of leading zero length bitfield in const/volatile struct
Author: Fanbo Meng Date: 2021-03-29T12:06:30-04:00 New Revision: f1e0c7fdd72026f62e2c38ee249705fbb9213a30 URL: https://github.com/llvm/llvm-project/commit/f1e0c7fdd72026f62e2c38ee249705fbb9213a30 DIFF: https://github.com/llvm/llvm-project/commit/f1e0c7fdd72026f62e2c38ee249705fbb9213a30.diff LOG: [SystemZ][z/OS] Add test of leading zero length bitfield in const/volatile struct Reviewed By: abhina.sreeskantharajan Differential Revision: https://reviews.llvm.org/D99508 Added: Modified: clang/test/CodeGen/SystemZ/zos-alignment.c Removed: diff --git a/clang/test/CodeGen/SystemZ/zos-alignment.c b/clang/test/CodeGen/SystemZ/zos-alignment.c index 9371a54403e4..b43968410cec 100644 --- a/clang/test/CodeGen/SystemZ/zos-alignment.c +++ b/clang/test/CodeGen/SystemZ/zos-alignment.c @@ -12,6 +12,24 @@ int f0() { return v0 + v1 + v2 + v3; } // DECL-NEXT: @v2 {{.*}} align 16 // DECL-NEXT: @v3 {{.*}} align 32 +const struct cs0 { + unsigned long :0; + long longa; +} CS0 = {}; +// CHECK: 0 | struct cs0 +// CHECK-NEXT: 0:- | unsigned long +// CHECK-NEXT: 0 | long long a +// CHECK-NEXT: | [sizeof=8, align=8] + +volatile struct vs0 { + long:0; + short a; +} VS0; +// CHECK: 0 | struct vs0 +// CHECK-NEXT: 0:- | long +// CHECK-NEXT: 0 | short a +// CHECK-NEXT: | [sizeof=2, align=2] + struct s0 { short a:3; long b:5; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 0858f0e - [SystemZ][z/OS] Set maximum value to truncate attribute aligned to for static variables on z/OS target
Author: Fanbo Meng Date: 2021-03-29T09:44:33-04:00 New Revision: 0858f0e09e33f62fc1dcc45e0bdec47eee1e23ba URL: https://github.com/llvm/llvm-project/commit/0858f0e09e33f62fc1dcc45e0bdec47eee1e23ba DIFF: https://github.com/llvm/llvm-project/commit/0858f0e09e33f62fc1dcc45e0bdec47eee1e23ba.diff LOG: [SystemZ][z/OS] Set maximum value to truncate attribute aligned to for static variables on z/OS target On z/OS there is a hard limitation on on the maximum requestable alignment in aligned attribute for static variables. We need to truncate values greater than that. Reviewed By: abhina.sreeskantharajan Differential Revision: https://reviews.llvm.org/D98864 Added: Modified: clang/include/clang/Basic/TargetInfo.h clang/lib/AST/ASTContext.cpp clang/lib/Basic/TargetInfo.cpp clang/lib/Basic/Targets/OSTargets.h clang/test/CodeGen/SystemZ/zos-alignment.c Removed: diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 01ca9ca0d2a8..3ddb706dcf52 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -165,6 +165,10 @@ struct TransferrableTargetInfo { /// If non-zero, specifies a fixed alignment value for bitfields that follow /// zero length bitfield, regardless of the zero length bitfield type. unsigned ZeroLengthBitfieldBoundary; + + /// If non-zero, specifies a maximum alignment to truncate alignment + /// specified in the aligned attribute of a static variable to this value. + unsigned MaxAlignedAttribute; }; /// OpenCL type kinds. @@ -784,6 +788,10 @@ class TargetInfo : public virtual TransferrableTargetInfo, return ZeroLengthBitfieldBoundary; } + /// Get the maximum alignment in bits for a static variable with + /// aligned attribute. + unsigned getMaxAlignedAttribute() const { return MaxAlignedAttribute; } + /// Check whether explicit bitfield alignment attributes should be // honored, as in "__attribute__((aligned(2))) int b : 1;". bool useExplicitBitFieldAlignment() const { diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index d52aea88e092..c824bcfa0866 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1783,6 +1783,13 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { } } + // Some targets have hard limitation on the maximum requestable alignment in + // aligned attribute for static variables. + const unsigned MaxAlignedAttr = getTargetInfo().getMaxAlignedAttribute(); + const auto *VD = dyn_cast(D); + if (MaxAlignedAttr && VD && VD->getStorageClass() == SC_Static) +Align = std::min(Align, MaxAlignedAttr); + return toCharUnitsFromBits(Align); } diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 468c8a24498a..1783da8f9cfd 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -107,6 +107,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { UseLeadingZeroLengthBitfield = true; UseExplicitBitFieldAlignment = true; ZeroLengthBitfieldBoundary = 0; + MaxAlignedAttribute = 0; HalfFormat = &llvm::APFloat::IEEEhalf(); FloatFormat = &llvm::APFloat::IEEEsingle(); DoubleFormat = &llvm::APFloat::IEEEdouble(); diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 568f759bfa0d..6e757adfa8bf 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -794,6 +794,7 @@ class LLVM_LIBRARY_VISIBILITY ZOSTargetInfo : public OSTargetInfo { ZOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : OSTargetInfo(Triple, Opts) { this->WCharType = TargetInfo::UnsignedInt; +this->MaxAlignedAttribute = 128; this->UseBitFieldTypeAlignment = false; this->UseZeroLengthBitfieldAlignment = true; this->UseLeadingZeroLengthBitfield = false; diff --git a/clang/test/CodeGen/SystemZ/zos-alignment.c b/clang/test/CodeGen/SystemZ/zos-alignment.c index 703fd1a46c3b..9371a54403e4 100644 --- a/clang/test/CodeGen/SystemZ/zos-alignment.c +++ b/clang/test/CodeGen/SystemZ/zos-alignment.c @@ -1,4 +1,16 @@ -// RUN: %clang_cc1 -emit-llvm-only -triple s390x-none-zos -fdump-record-layouts %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm-only -triple s390x-none-zos -fdump-record-layouts %s | FileCheck %s --check-prefix=CHECK +// RUN: %clang_cc1 -emit-llvm -triple s390x-none-zos %s -o - | FileCheck %s --check-prefix=DECL + +static int __attribute__((aligned(32))) v0; +int __attribute__((aligned(32))) v1; +typedef int __attribute__((aligned(32))) int32; +static int32 v2; +int32 v3; +int f0() { return v0 + v1 + v2 + v3; } +// DECL: @v0 {{.*}} align 16 +// DECL-NEXT: @v1 {{.*}} align 32 +// DECL-NEXT: @v2 {{.*}} align 16 +// DECL-NEXT: @v3 {{.*}} align 32 struct s0 {
[clang] 6f91cf7 - [SystemZ][z/OS] Ignore leading zero width bitfield alignment on z/OS target
Author: Fanbo Meng Date: 2021-03-26T10:10:33-04:00 New Revision: 6f91cf75d7f55c7beadeebeac7c1010a2e7c6553 URL: https://github.com/llvm/llvm-project/commit/6f91cf75d7f55c7beadeebeac7c1010a2e7c6553 DIFF: https://github.com/llvm/llvm-project/commit/6f91cf75d7f55c7beadeebeac7c1010a2e7c6553.diff LOG: [SystemZ][z/OS] Ignore leading zero width bitfield alignment on z/OS target Zero length bitfield alignment is not respected if they are leading members on z/OS target. Reviewed By: abhina.sreeskantharajan Differential Revision: https://reviews.llvm.org/D98890 Added: Modified: clang/include/clang/Basic/TargetInfo.h clang/lib/AST/RecordLayoutBuilder.cpp clang/lib/Basic/TargetInfo.cpp clang/lib/Basic/Targets/OSTargets.h clang/test/CodeGen/SystemZ/zos-alignment.c Removed: diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 9791cb6bbee7..01ca9ca0d2a8 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -155,6 +155,10 @@ struct TransferrableTargetInfo { /// zero-length bitfield. unsigned UseZeroLengthBitfieldAlignment : 1; + /// Whether zero length bitfield alignment is respected if they are the + /// leading members. + unsigned UseLeadingZeroLengthBitfield : 1; + /// Whether explicit bit field alignment attributes are honored. unsigned UseExplicitBitFieldAlignment : 1; @@ -768,6 +772,12 @@ class TargetInfo : public virtual TransferrableTargetInfo, return UseZeroLengthBitfieldAlignment; } + /// Check whether zero length bitfield alignment is respected if they are + /// leading members. + bool useLeadingZeroLengthBitfield() const { +return UseLeadingZeroLengthBitfield; + } + /// Get the fixed alignment value in bits for a member that follows /// a zero length bitfield. unsigned getZeroLengthBitfieldBoundary() const { diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 95d69fa5b11a..eb9bfc20342f 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -1627,12 +1627,17 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { // Some such targets do honor it on zero-width bitfields. if (FieldSize == 0 && Context.getTargetInfo().useZeroLengthBitfieldAlignment()) { - // The alignment to round up to is the max of the field's natural - // alignment and a target-specific fixed value (sometimes zero). - unsigned ZeroLengthBitfieldBoundary = -Context.getTargetInfo().getZeroLengthBitfieldBoundary(); - FieldAlign = std::max(FieldAlign, ZeroLengthBitfieldBoundary); - + // Some targets don't honor leading zero-width bitfield. + if (!IsUnion && FieldOffset == 0 && + !Context.getTargetInfo().useLeadingZeroLengthBitfield()) +FieldAlign = 1; + else { +// The alignment to round up to is the max of the field's natural +// alignment and a target-specific fixed value (sometimes zero). +unsigned ZeroLengthBitfieldBoundary = +Context.getTargetInfo().getZeroLengthBitfieldBoundary(); +FieldAlign = std::max(FieldAlign, ZeroLengthBitfieldBoundary); + } // If that doesn't apply, just ignore the field alignment. } else { FieldAlign = 1; diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index bc3c607dd74e..468c8a24498a 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -104,6 +104,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { UseSignedCharForObjCBool = true; UseBitFieldTypeAlignment = true; UseZeroLengthBitfieldAlignment = false; + UseLeadingZeroLengthBitfield = true; UseExplicitBitFieldAlignment = true; ZeroLengthBitfieldBoundary = 0; HalfFormat = &llvm::APFloat::IEEEhalf(); diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 4de1b8d2db4f..568f759bfa0d 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -796,6 +796,7 @@ class LLVM_LIBRARY_VISIBILITY ZOSTargetInfo : public OSTargetInfo { this->WCharType = TargetInfo::UnsignedInt; this->UseBitFieldTypeAlignment = false; this->UseZeroLengthBitfieldAlignment = true; +this->UseLeadingZeroLengthBitfield = false; this->ZeroLengthBitfieldBoundary = 32; this->MinGlobalAlign = 0; this->DefaultAlignForAttributeAligned = 128; diff --git a/clang/test/CodeGen/SystemZ/zos-alignment.c b/clang/test/CodeGen/SystemZ/zos-alignment.c index 4b572fcac5a9..703fd1a46c3b 100644 --- a/clang/test/CodeGen/SystemZ/zos-alignment.c +++ b/clang/test/CodeGen/SystemZ/zos-alignment.c @@ -83,6 +83,35 @@ struct s6 { // CHECK-NEXT: 8 | char *[] b // CHECK-NEXT: | [sizeof
[clang] d91234b - [SystemZ][z/OS] Update target specific __attribute__((aligned)) value for test
Author: Fanbo Meng Date: 2020-10-09T10:14:44-04:00 New Revision: d91234b21c1a1a34d98157089a8769d8f9a32f06 URL: https://github.com/llvm/llvm-project/commit/d91234b21c1a1a34d98157089a8769d8f9a32f06 DIFF: https://github.com/llvm/llvm-project/commit/d91234b21c1a1a34d98157089a8769d8f9a32f06.diff LOG: [SystemZ][z/OS] Update target specific __attribute__((aligned)) value for test z/OS defaults to 16 bytes for __attribute__((aligned)), modify the test to differentiate between z/OS and Linux on s390x. Reviewed By: abhina.sreeskantharajan Differential Revision: https://reviews.llvm.org/D89127 Added: Modified: clang/test/Sema/struct-packed-align.c Removed: diff --git a/clang/test/Sema/struct-packed-align.c b/clang/test/Sema/struct-packed-align.c index 91c7ce39cc25..122b7f276461 100644 --- a/clang/test/Sema/struct-packed-align.c +++ b/clang/test/Sema/struct-packed-align.c @@ -59,7 +59,7 @@ extern int e2[__alignof(struct as1) == 8 ? 1 : -1]; struct __attribute__((aligned)) as1_2 { char c; }; -#if ( defined(__s390x__) || ( defined (__ARM_32BIT_STATE) && ! defined(__ANDROID__) ) ) +#if ((defined(__s390x__) && !defined(__MVS__)) || (defined(__ARM_32BIT_STATE) && !defined(__ANDROID__))) extern int e1_2[sizeof(struct as1_2) == 8 ? 1 : -1]; extern int e2_2[__alignof(struct as1_2) == 8 ? 1 : -1]; #else ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits