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 bool isFPArgumentType(
QualType Ty)
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->isFloatTy() || Ty->isDoubleTy() || Ty->isFP128Ty()) {
112 auto &Ctx = M.getContext();
113 llvm::Function *TDCFunc = llvm::Intrinsic::getOrInsertDeclaration(
114 &M, llvm::Intrinsic::s390_tdc, Ty);
115 unsigned TDCBits = 0;
117 case Builtin::BI__builtin_isnan:
120 case Builtin::BIfinite:
121 case Builtin::BI__finite:
122 case Builtin::BIfinitef:
123 case Builtin::BI__finitef:
124 case Builtin::BIfinitel:
125 case Builtin::BI__finitel:
126 case Builtin::BI__builtin_isfinite:
129 case Builtin::BI__builtin_isinf:
136 return Builder.CreateCall(
138 {
V, llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), TDCBits)});
145bool SystemZABIInfo::isPromotableIntegerTypeForABI(
QualType Ty)
const {
148 Ty = EnumTy->getDecl()->getIntegerType();
155 if (EIT->getNumBits() < 64)
160 switch (BT->getKind()) {
161 case BuiltinType::Int:
162 case BuiltinType::UInt:
170bool SystemZABIInfo::isCompoundType(
QualType Ty)
const {
176bool SystemZABIInfo::isVectorArgumentType(
QualType Ty)
const {
179 getContext().getTypeSize(Ty) <= 128);
182bool SystemZABIInfo::isFPArgumentType(
QualType Ty)
const {
187 switch (BT->getKind()) {
188 case BuiltinType::Float:
189 case BuiltinType::Double:
206 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
207 if (CXXRD->hasDefinition())
208 for (
const auto &I : CXXRD->bases()) {
221 for (
const auto *FD : RD->
fields()) {
226 if (FD->hasAttr<NoUniqueAddressAttr>() &&
234 Found = GetSingleElementType(FD->getType());
259 const SystemZTargetCodeGenInfo &SZCGI =
260 static_cast<const SystemZTargetCodeGenInfo &
>(
261 CGT.getCGM().getTargetCodeGenInfo());
263 auto TyInfo = getContext().getTypeInfoInChars(Ty);
265 llvm::Type *DirectTy = ArgTy;
269 bool IsVector =
false;
272 SZCGI.handleExternallyVisibleObjABI(Ty.
getTypePtr(), CGT.getCGM(),
275 DirectTy = llvm::PointerType::getUnqual(DirectTy);
280 InFPRs = (!IsSoftFloatABI && (ArgTy->isFloatTy() || ArgTy->isDoubleTy()));
281 IsVector = ArgTy->isVectorTy();
282 UnpaddedSize = TyInfo.Width;
283 DirectAlign = TyInfo.Align;
286 if (IsVector && UnpaddedSize > PaddedSize)
288 assert((UnpaddedSize <= PaddedSize) &&
"Invalid argument size.");
290 CharUnits Padding = (PaddedSize - UnpaddedSize);
292 llvm::Type *IndexTy = CGF.
Int64Ty;
293 llvm::Value *PaddedSizeV =
294 llvm::ConstantInt::get(IndexTy, PaddedSize.
getQuantity());
304 CGF.
Int8Ty, TyInfo.Align);
310 PaddedSizeV,
"overflow_arg_area");
318 unsigned MaxRegs, RegCountField, RegSaveIndex;
329 RegPadding = Padding;
335 llvm::Value *MaxRegsV = llvm::ConstantInt::get(IndexTy, MaxRegs);
336 llvm::Value *InRegs = CGF.
Builder.CreateICmpULT(RegCount, MaxRegsV,
342 CGF.
Builder.CreateCondBr(InRegs, InRegBlock, InMemBlock);
348 llvm::Value *ScaledRegCount =
349 CGF.
Builder.CreateMul(RegCount, PaddedSizeV,
"scaled_reg_count");
350 llvm::Value *RegBase =
351 llvm::ConstantInt::get(IndexTy, RegSaveIndex * PaddedSize.
getQuantity()
353 llvm::Value *RegOffset =
354 CGF.
Builder.CreateAdd(ScaledRegCount, RegBase,
"reg_offset");
357 llvm::Value *RegSaveArea =
365 llvm::Value *One = llvm::ConstantInt::get(IndexTy, 1);
366 llvm::Value *NewRegCount =
367 CGF.
Builder.CreateAdd(RegCount, One,
"reg_count");
387 PaddedSizeV,
"overflow_arg_area");
406 if (isVectorArgumentType(RetTy))
408 if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64)
409 return getNaturalAlignIndirect(RetTy);
423 if (isPromotableIntegerTypeForABI(Ty))
430 QualType SingleElementTy = GetSingleElementType(Ty);
431 if (isVectorArgumentType(SingleElementTy) &&
432 getContext().getTypeSize(SingleElementTy) == Size)
436 if (Size != 8 && Size != 16 && Size != 32 && Size != 64)
437 return getNaturalAlignIndirect(Ty,
false);
445 return getNaturalAlignIndirect(Ty,
false);
448 if (isFPArgumentType(SingleElementTy)) {
449 assert(Size == 32 || Size == 64);
451 Size == 32 ? llvm::Type::getFloatTy(getVMContext())
452 : llvm::Type::getDoubleTy(getVMContext()));
454 llvm::IntegerType *PassTy = llvm::IntegerType::get(getVMContext(), Size);
461 if (isCompoundType(Ty))
462 return getNaturalAlignIndirect(Ty,
false);
468 const SystemZTargetCodeGenInfo &SZCGI =
469 static_cast<const SystemZTargetCodeGenInfo &
>(
470 CGT.getCGM().getTargetCodeGenInfo());
471 if (!getCXXABI().classifyReturnType(FI))
480 SZCGI.handleExternallyVisibleObjABI(I.type.getTypePtr(), CGT.getCGM(),
485bool SystemZTargetCodeGenInfo::isVectorTypeBased(
const Type *Ty,
486 bool IsParam)
const {
487 if (!SeenTypes.insert(Ty).second)
495 const Type *SingleEltTy = getABIInfo<SystemZABIInfo>()
496 .GetSingleElementType(
QualType(Ty, 0))
498 bool SingleVecEltStruct = SingleEltTy != Ty && SingleEltTy->
isVectorType() &&
514 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
515 if (CXXRD->hasDefinition())
516 for (
const auto &I : CXXRD->bases())
517 if (isVectorTypeBased(I.getType().getTypePtr(),
false))
519 for (
const auto *FD : RD->
fields())
520 if (isVectorTypeBased(FD->getType().getTypePtr(),
false))
525 if (isVectorTypeBased(FT->getReturnType().getTypePtr(),
true))
528 for (
const auto &ParamType : Proto->getParamTypes())
529 if (isVectorTypeBased(ParamType.getTypePtr(),
true))
535std::unique_ptr<TargetCodeGenInfo>
538 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.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
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)
RValue EmitLoadOfAnyValue(LValue V, AggValueSlot Slot=AggValueSlot::ignored(), SourceLocation Loc={})
Like EmitLoadOfLValue but also handles complex and aggregate types.
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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
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
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
The base class of the type hierarchy.
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
bool isPointerType() const
bool isAnyComplexType() const
bool isStructureOrClassType() const
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