10#include "TargetInfo.h"
12#include "llvm/IR/IntrinsicsS390.h"
23class SystemZABIInfo :
public ABIInfo {
28 SystemZABIInfo(CodeGenTypes &CGT,
bool HV,
bool SF)
29 : ABIInfo(CGT), HasVector(HV), IsSoftFloatABI(SF) {}
31 bool isPromotableIntegerTypeForABI(QualType Ty)
const;
32 bool isCompoundType(QualType Ty)
const;
33 bool isVectorArgumentType(QualType Ty)
const;
34 llvm::Type *getFPArgumentType(QualType Ty, uint64_t Size)
const;
35 QualType getSingleElementType(QualType Ty)
const;
40 void computeInfo(CGFunctionInfo &FI)
const override;
41 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
42 AggValueSlot Slot)
const override;
49 mutable bool HasVisibleVecABIFlag =
false;
50 mutable std::set<const Type *> SeenTypes;
57 bool isVectorTypeBased(
const Type *Ty,
bool IsParam)
const;
60 SystemZTargetCodeGenInfo(CodeGenTypes &CGT,
bool HasVector,
bool SoftFloatABI)
62 std::make_unique<SystemZABIInfo>(CGT, HasVector, SoftFloatABI)),
63 Ctx(CGT.getContext()) {
65 std::make_unique<SwiftABIInfo>(CGT,
false);
73 void handleExternallyVisibleObjABI(
const Type *Ty, CodeGen::CodeGenModule &M,
75 if (!HasVisibleVecABIFlag && isVectorTypeBased(Ty, IsParam)) {
76 M.
getModule().addModuleFlag(llvm::Module::Warning,
77 "s390x-visible-vector-ABI", 1);
78 HasVisibleVecABIFlag =
true;
82 void setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV,
83 CodeGen::CodeGenModule &M)
const override {
89 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
90 if (VD->isExternallyVisible())
91 handleExternallyVisibleObjABI(VD->getType().getTypePtr(), M,
94 else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
95 if (FD->isExternallyVisible())
96 handleExternallyVisibleObjABI(FD->getType().getTypePtr(), M,
101 llvm::Value *testFPKind(llvm::Value *
V,
unsigned BuiltinID,
102 CGBuilderTy &Builder,
103 CodeGenModule &CGM)
const override {
104 assert(
V->getType()->isFloatingPointTy() &&
"V should have an FP type.");
106 if (!Builder.getIsFPConstrained())
109 llvm::Type *Ty =
V->getType();
110 if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy() ||
113 auto &Ctx = M.getContext();
114 llvm::Function *TDCFunc = llvm::Intrinsic::getOrInsertDeclaration(
115 &M, llvm::Intrinsic::s390_tdc, Ty);
116 unsigned TDCBits = 0;
118 case Builtin::BI__builtin_isnan:
121 case Builtin::BIfinite:
122 case Builtin::BI__finite:
123 case Builtin::BIfinitef:
124 case Builtin::BI__finitef:
125 case Builtin::BIfinitel:
126 case Builtin::BI__finitel:
127 case Builtin::BI__builtin_isfinite:
130 case Builtin::BI__builtin_isinf:
137 return Builder.CreateCall(
139 {
V, llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), TDCBits)});
146bool SystemZABIInfo::isPromotableIntegerTypeForABI(
QualType Ty)
const {
149 Ty = ED->getIntegerType();
155 if (
const auto *EIT = Ty->
getAs<BitIntType>())
156 if (EIT->getNumBits() < 64)
160 if (
const BuiltinType *BT = Ty->
getAs<BuiltinType>())
161 switch (BT->getKind()) {
162 case BuiltinType::Int:
163 case BuiltinType::UInt:
171bool SystemZABIInfo::isCompoundType(QualType Ty)
const {
177bool SystemZABIInfo::isVectorArgumentType(QualType Ty)
const {
180 getContext().getTypeSize(Ty) <= 128);
186llvm::Type *SystemZABIInfo::getFPArgumentType(QualType Ty,
187 uint64_t Size)
const {
191 if (
const BuiltinType *BT = Ty->
getAs<BuiltinType>())
192 switch (BT->getKind()) {
193 case BuiltinType::Float16:
195 return llvm::Type::getHalfTy(getVMContext());
197 case BuiltinType::Float:
199 return llvm::Type::getFloatTy(getVMContext());
201 case BuiltinType::Double:
202 return llvm::Type::getDoubleTy(getVMContext());
210QualType SystemZABIInfo::getSingleElementType(QualType Ty)
const {
212 if (RD && RD->isStructureOrClass()) {
216 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
217 if (CXXRD->hasDefinition())
218 for (
const auto &I : CXXRD->bases()) {
219 QualType
Base = I.getType();
227 Found = getSingleElementType(Base);
231 for (
const auto *FD : RD->fields()) {
236 if (FD->hasAttr<NoUniqueAddressAttr>() &&
244 Found = getSingleElementType(FD->getType());
256RValue SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
257 QualType Ty, AggValueSlot Slot)
const {
269 const SystemZTargetCodeGenInfo &SZCGI =
270 static_cast<const SystemZTargetCodeGenInfo &
>(
271 CGT.getCGM().getTargetCodeGenInfo());
273 auto TyInfo = getContext().getTypeInfoInChars(Ty);
275 llvm::Type *DirectTy = ArgTy;
279 bool IsVector =
false;
280 CharUnits UnpaddedSize;
281 CharUnits DirectAlign;
282 SZCGI.handleExternallyVisibleObjABI(Ty.
getTypePtr(), CGT.getCGM(),
285 DirectTy = llvm::PointerType::getUnqual(DirectTy->getContext());
290 InFPRs = (!IsSoftFloatABI &&
291 (ArgTy->isHalfTy() || ArgTy->isFloatTy() || ArgTy->isDoubleTy()));
292 IsVector = ArgTy->isVectorTy();
293 UnpaddedSize = TyInfo.Width;
294 DirectAlign = TyInfo.Align;
297 if (IsVector && UnpaddedSize > PaddedSize)
299 assert((UnpaddedSize <= PaddedSize) &&
"Invalid argument size.");
301 CharUnits Padding = (PaddedSize - UnpaddedSize);
303 llvm::Type *IndexTy = CGF.
Int64Ty;
304 llvm::Value *PaddedSizeV =
305 llvm::ConstantInt::get(IndexTy, PaddedSize.
getQuantity());
315 CGF.
Int8Ty, TyInfo.Align);
321 PaddedSizeV,
"overflow_arg_area");
329 unsigned MaxRegs, RegCountField, RegSaveIndex;
330 CharUnits RegPadding;
335 RegPadding = CharUnits();
340 RegPadding = Padding;
346 llvm::Value *MaxRegsV = llvm::ConstantInt::get(IndexTy, MaxRegs);
347 llvm::Value *InRegs = CGF.
Builder.CreateICmpULT(RegCount, MaxRegsV,
353 CGF.
Builder.CreateCondBr(InRegs, InRegBlock, InMemBlock);
359 llvm::Value *ScaledRegCount =
360 CGF.
Builder.CreateMul(RegCount, PaddedSizeV,
"scaled_reg_count");
361 llvm::Value *RegBase =
362 llvm::ConstantInt::get(IndexTy, RegSaveIndex * PaddedSize.
getQuantity()
364 llvm::Value *RegOffset =
365 CGF.
Builder.CreateAdd(ScaledRegCount, RegBase,
"reg_offset");
368 llvm::Value *RegSaveArea =
373 Address RegAddr = RawRegAddr.withElementType(DirectTy);
376 llvm::Value *One = llvm::ConstantInt::get(IndexTy, 1);
377 llvm::Value *NewRegCount =
378 CGF.
Builder.CreateAdd(RegCount, One,
"reg_count");
398 PaddedSizeV,
"overflow_arg_area");
414ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy)
const {
417 if (isVectorArgumentType(RetTy))
419 if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64)
420 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
425ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty)
const {
431 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
435 if (isPromotableIntegerTypeForABI(Ty))
442 QualType SingleElementTy = getSingleElementType(Ty);
443 if (isVectorArgumentType(SingleElementTy) &&
444 getContext().getTypeSize(SingleElementTy) == Size)
448 if (Size != 8 && Size != 16 && Size != 32 && Size != 64)
449 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
456 if (RD->hasFlexibleArrayMember())
457 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
462 if (llvm::Type *FPArgTy = getFPArgumentType(SingleElementTy, Size)) {
463 assert(Size == 16 || Size == 32 || Size == 64);
466 llvm::IntegerType *PassTy = llvm::IntegerType::get(getVMContext(), Size);
468 : ABIArgInfo::getDirect(PassTy);
473 if (isCompoundType(Ty))
474 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
480void SystemZABIInfo::computeInfo(CGFunctionInfo &FI)
const {
481 const SystemZTargetCodeGenInfo &SZCGI =
482 static_cast<const SystemZTargetCodeGenInfo &
>(
483 CGT.getCGM().getTargetCodeGenInfo());
493 SZCGI.handleExternallyVisibleObjABI(I.type.getTypePtr(), CGT.getCGM(),
498bool SystemZTargetCodeGenInfo::isVectorTypeBased(
const Type *Ty,
499 bool IsParam)
const {
500 if (!SeenTypes.insert(Ty).second)
508 const Type *SingleEltTy = getABIInfo<SystemZABIInfo>()
509 .getSingleElementType(QualType(Ty, 0))
511 bool SingleVecEltStruct = SingleEltTy != Ty && SingleEltTy->
isVectorType() &&
526 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
527 if (CXXRD->hasDefinition())
528 for (
const auto &I : CXXRD->bases())
529 if (isVectorTypeBased(I.getType().getTypePtr(),
false))
531 for (
const auto *FD : RD->fields())
532 if (isVectorTypeBased(FD->getType().getTypePtr(),
false))
536 if (
const auto *FT = Ty->
getAs<FunctionType>())
537 if (isVectorTypeBased(FT->getReturnType().getTypePtr(),
true))
539 if (
const FunctionProtoType *Proto = Ty->
getAs<FunctionProtoType>())
540 for (
const auto &ParamType : Proto->getParamTypes())
541 if (isVectorTypeBased(ParamType.getTypePtr(),
true))
553class ZOSXPLinkABIInfo :
public ABIInfo {
554 const unsigned GPRBits = 64;
558 ZOSXPLinkABIInfo(CodeGenTypes &CGT,
bool HV) : ABIInfo(CGT), HasVector(HV) {}
560 bool isPromotableIntegerTypeForABI(QualType Ty)
const;
561 bool isCompoundType(QualType Ty)
const;
562 bool isVectorArgumentType(QualType Ty)
const;
563 QualType getSingleElementType(QualType Ty)
const;
564 std::optional<QualType> getFPTypeOfComplexLikeType(QualType Ty)
const;
567 unsigned functionCallConv)
const;
569 unsigned functionCallConv)
const;
571 void computeInfo(CGFunctionInfo &FI)
const override {
580 bool IsNamedArg = ArgNo < NumRequiredArgs;
587 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
588 AggValueSlot Slot)
const override;
591class ZOSXPLinkTargetCodeGenInfo :
public TargetCodeGenInfo {
593 ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT,
bool HasVector)
594 : TargetCodeGenInfo(std::make_unique<ZOSXPLinkABIInfo>(CGT, HasVector)) {
596 std::make_unique<SwiftABIInfo>(CGT,
false);
604bool ZOSXPLinkABIInfo::isPromotableIntegerTypeForABI(QualType Ty)
const {
606 if (
const EnumType *EnumTy = Ty->
getAs<EnumType>())
607 Ty = EnumTy->getDecl()->getIntegerType();
613 if (
const auto *EIT = Ty->
getAs<BitIntType>())
614 if (EIT->getNumBits() < 64)
619 if (
const BuiltinType *BT = Ty->
getAs<BuiltinType>())
620 switch (BT->getKind()) {
621 case BuiltinType::Int:
622 case BuiltinType::UInt:
623 case BuiltinType::ULong:
624 case BuiltinType::Long:
633bool ZOSXPLinkABIInfo::isCompoundType(QualType Ty)
const {
638bool ZOSXPLinkABIInfo::isVectorArgumentType(QualType Ty)
const {
640 getContext().getTypeSize(Ty) <= 128);
643QualType ZOSXPLinkABIInfo::getSingleElementType(QualType Ty)
const {
651 const RecordDecl *RD = RT->getDecl();
652 for (
const auto *FD : RD->
fields()) {
654 Found = getSingleElementType(FD->getType());
655 else if (
Found != getSingleElementType(FD->getType()))
662 const RecordDecl *RD = RT->getDecl();
666 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
667 for (
const auto &I : CXXRD->bases()) {
668 QualType
Base = I.getType();
679 Found = getSingleElementType(Base);
686 for (
const auto *FD : RD->
fields()) {
689 Found = getSingleElementType(FD->getType());
696std::optional<QualType>
697ZOSXPLinkABIInfo::getFPTypeOfComplexLikeType(QualType Ty)
const {
699 const RecordDecl *RD = RT->getDecl();
702 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
703 if (CXXRD->hasDefinition())
704 for (
const auto &I : CXXRD->bases()) {
705 QualType
Base = I.getType();
718 for (
const auto *FD : RD->
fields()) {
722 QualType FT = FD->getType();
723 QualType FTSingleTy = getSingleElementType(FT);
725 if (
const BuiltinType *BT = FTSingleTy->
getAs<BuiltinType>()) {
726 switch (BT->getKind()) {
727 case BuiltinType::Float:
728 case BuiltinType::Double:
729 case BuiltinType::LongDouble:
731 elemKind = BT->getKind();
734 }
else if (elemKind == BT->getKind())
750 auto &Ctx = getContext();
758ABIArgInfo ZOSXPLinkABIInfo::classifyReturnType(QualType RetTy,
759 unsigned CallConv)
const {
769 if ((CallConv != llvm::CallingConv::C) &&
771 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
775 if (isVectorArgumentType(RetTy))
785 if (RetTy->
getAs<RecordType>()) {
786 if (getFPTypeOfComplexLikeType(RetTy))
793 uint64_t AggregateTypeSize = getContext().getTypeSize(RetTy);
795 if (AggregateTypeSize <= 3 * GPRBits) {
797 AggregateTypeSize / GPRBits + (AggregateTypeSize % GPRBits != 0);
803 llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), GPRBits);
804 CoerceTy = llvm::ArrayType::get(CoerceTy, NumElements);
807 return getNaturalAlignIndirect(RetTy,
808 getDataLayout().getAllocaAddrSpace());
810 return (isPromotableIntegerTypeForABI(RetTy)
815ABIArgInfo ZOSXPLinkABIInfo::classifyArgumentType(QualType Ty,
bool IsNamedArg,
816 unsigned CallConv)
const {
822 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
826 if (isPromotableIntegerTypeForABI(Ty))
830 if ((CallConv != llvm::CallingConv::C) && isCompoundType(Ty))
831 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
836 auto CompTy = getFPTypeOfComplexLikeType(Ty);
850 if (CompTy.has_value()) {
851 llvm::Type *FPTy = CGT.ConvertType(*CompTy);
852 llvm::Type *CoerceTy = llvm::StructType::get(FPTy, FPTy);
866 if (isVectorArgumentType(Ty))
877 uint64_t Bits = getContext().getTypeSize(Ty);
878 llvm::Type *CoerceTy;
883 CoerceTy = llvm::IntegerType::get(getVMContext(), GPRBits);
887 uint64_t NumRegs = llvm::alignTo(Bits, GPRBits) / GPRBits;
888 llvm::Type *RegTy = llvm::IntegerType::get(getVMContext(), GPRBits);
889 CoerceTy = llvm::ArrayType::get(RegTy, NumRegs);
895 if (isCompoundType(Ty))
896 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
902RValue ZOSXPLinkABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
903 QualType Ty, AggValueSlot Slot)
const {
910std::unique_ptr<TargetCodeGenInfo>
913 return std::make_unique<SystemZTargetCodeGenInfo>(CGM.
getTypes(), HasVector,
917std::unique_ptr<TargetCodeGenInfo>
920 return std::make_unique<ZOSXPLinkTargetCodeGenInfo>(CGM.
getTypes(),
Defines enum values for all the target-independent builtin functions.
TypeInfoChars getTypeInfoInChars(const Type *T) const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static ABIArgInfo getNoExtend(llvm::IntegerType *T)
static ABIArgInfo getIgnore()
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
llvm::Type * getCoerceToType() const
void setCanBeFlattened(bool Flatten)
static ABIArgInfo getDirectInReg(llvm::Type *T=nullptr)
ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.
bool isPromotableIntegerTypeForABI(QualType Ty) const
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
RecordArgABI
Specify how one should pass an argument of a record type.
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
ABIArgInfo & getReturnInfo()
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
unsigned getNumRequiredArgs() const
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
RValue EmitLoadOfAnyValue(LValue V, AggValueSlot Slot=AggValueSlot::ignored(), SourceLocation Loc={})
Like EmitLoadOfLValue but also handles complex and aggregate types.
ASTContext & getContext() const
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
CodeGenTypes & getTypes()
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
A (possibly-)qualified type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getCanonicalType() const
field_range fields() const
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isAnyComplexType() const
const RecordType * getAsStructureType() const
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isVectorType() const
const T * getAs() const
Member-template getAs<specific type>'.
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
std::unique_ptr< TargetCodeGenInfo > createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI)
RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, AggValueSlot Slot, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
Address emitMergePHI(CodeGenFunction &CGF, Address Addr1, llvm::BasicBlock *Block1, Address Addr2, llvm::BasicBlock *Block2, const llvm::Twine &Name="")
bool isAggregateTypeForABI(QualType T)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
std::unique_ptr< TargetCodeGenInfo > createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI)
@ Address
A pointer to a ValueDecl.
The JSON file list parser is used to communicate input to InstallAPI.
@ Type
The name was classified as a type.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CharUnits getPointerSize() const