10#include "TargetInfo.h"
12#include "llvm/IR/IntrinsicsS390.h"
23class SystemZABIInfo :
public ABIInfo {
29 :
ABIInfo(CGT), HasVector(HV), IsSoftFloatABI(SF) {}
32 bool isCompoundType(
QualType Ty)
const;
33 bool isVectorArgumentType(
QualType Ty)
const;
34 llvm::Type *getFPArgumentType(
QualType Ty, uint64_t Size)
const;
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);
75 if (!HasVisibleVecABIFlag && isVectorTypeBased(Ty, IsParam)) {
76 M.
getModule().addModuleFlag(llvm::Module::Warning,
77 "s390x-visible-vector-ABI", 1);
78 HasVisibleVecABIFlag =
true;
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,
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();
156 if (EIT->getNumBits() < 64)
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 {
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());
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()) {
231 for (
const auto *FD : RD->fields()) {
236 if (FD->hasAttr<NoUniqueAddressAttr>() &&
244 Found = GetSingleElementType(FD->getType());
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;
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;
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 =
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");
417 if (isVectorArgumentType(RetTy))
419 if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64)
420 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
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);
473 if (isCompoundType(Ty))
474 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
481 const SystemZTargetCodeGenInfo &SZCGI =
482 static_cast<const SystemZTargetCodeGenInfo &
>(
483 CGT.getCGM().getTargetCodeGenInfo());
484 if (!getCXXABI().classifyReturnType(FI))
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))
537 if (isVectorTypeBased(FT->getReturnType().getTypePtr(),
true))
540 for (
const auto &ParamType : Proto->getParamTypes())
541 if (isVectorTypeBased(ParamType.getTypePtr(),
true))
547std::unique_ptr<TargetCodeGenInfo>
550 return std::make_unique<SystemZTargetCodeGenInfo>(CGM.
getTypes(), HasVector,
Defines enum values for all the target-independent builtin functions.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
A fixed int type of a specified bitwidth.
This class is used for builtin types like 'int'.
Represents a C++ struct/union/class.
CharUnits - This is an opaque type for sizes expressed in character units.
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.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
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
ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.
bool isPromotableIntegerTypeForABI(QualType Ty) const
virtual RValue EmitVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty, AggValueSlot Slot) const =0
EmitVAArg - Emit the target dependent code to load a value of.
virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const =0
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
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.
CGFunctionInfo - Class to encapsulate the information about a function definition.
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
unsigned getNumRequiredArgs() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::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.
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()
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const
setTargetAttributes - Provides a convenient hook to handle extra target-specific attributes for the g...
virtual llvm::Value * testFPKind(llvm::Value *V, unsigned BuiltinID, CGBuilderTy &Builder, CodeGenModule &CGM) const
Performs a target specific test of a floating point value for things like IsNaN, Infinity,...
Decl - This represents one declaration (or definition), e.g.
Represents a function declaration or definition.
Represents a prototype with parameter type info, e.g.
FunctionType - C99 6.7.5.3 - Function Declarators.
A (possibly-)qualified type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getCanonicalType() const
The base class of the type hierarchy.
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isAnyComplexType() 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.
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)
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.
The JSON file list parser is used to communicate input to InstallAPI.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64