10#include "TargetInfo.h"
20 SlotSize, SlotSize,
true);
28 2 * SlotSize - EltSize);
46 llvm::Value *
Address,
bool Is64Bit,
53 llvm::IntegerType *i8 = CGF.
Int8Ty;
54 llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
55 llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
56 llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
109class AIXABIInfo :
public ABIInfo {
111 const unsigned PtrByteSize;
116 :
ABIInfo(CGT), Is64Bit(Is64Bit), PtrByteSize(Is64Bit ? 8 : 4) {}
118 bool isPromotableTypeForABI(
QualType Ty)
const;
147 llvm::Value *
Address)
const override;
153bool AIXABIInfo::isPromotableTypeForABI(
QualType Ty)
const {
156 Ty = EnumTy->getDecl()->getIntegerType();
159 if (getContext().isPromotableIntegerType(Ty))
169 switch (BT->getKind()) {
170 case BuiltinType::Int:
171 case BuiltinType::UInt:
191 return getNaturalAlignIndirect(RetTy);
212 CharUnits CCAlign = getParamTypeAlignment(Ty);
213 CharUnits TyAlign = getContext().getTypeAlignInChars(Ty);
226 Ty = CTy->getElementType();
241 auto TypeInfo = getContext().getTypeInfoInChars(Ty);
255 if (EltSize < SlotSize)
263bool AIXTargetCodeGenInfo::initDwarfEHRegSizeTable(
273 bool IsRetSmallStructInRegABI;
279 bool RetSmallStructInRegABI)
281 IsRetSmallStructInRegABI(RetSmallStructInRegABI) {}
298 PPC32TargetCodeGenInfo(
CodeGenTypes &CGT,
bool SoftFloatABI,
299 bool RetSmallStructInRegABI)
301 CGT, SoftFloatABI, RetSmallStructInRegABI)) {}
303 static bool isStructReturnInRegABI(
const llvm::Triple &Triple,
312 llvm::Value *
Address)
const override;
319 Ty = CTy->getElementType();
327 const Type *AlignTy =
nullptr;
330 if ((EltType->isVectorType() && getContext().getTypeSize(EltType) == 128) ||
345 (Size = getContext().getTypeSize(RetTy)) <= 64) {
360 llvm::Type *CoerceTy = llvm::Type::getIntNTy(getVMContext(), Size);
372 if (getTarget().getTriple().isOSDarwin()) {
373 auto TI = getContext().getTypeInfoInChars(Ty);
374 TI.Align = getParamTypeAlignment(Ty);
382 const unsigned OverflowLimit = 8;
397 bool isI64 = Ty->
isIntegerType() && getContext().getTypeSize(Ty) == 64;
399 bool isF64 = Ty->
isFloatingType() && getContext().getTypeSize(Ty) == 64;
409 if (isInt || IsSoftFloatABI) {
410 NumRegsAddr = Builder.CreateStructGEP(VAList, 0,
"gpr");
412 NumRegsAddr = Builder.CreateStructGEP(VAList, 1,
"fpr");
415 llvm::Value *NumRegs = Builder.CreateLoad(NumRegsAddr,
"numUsedRegs");
418 if (isI64 || (isF64 && IsSoftFloatABI)) {
419 NumRegs = Builder.CreateAdd(NumRegs, Builder.getInt8(1));
420 NumRegs = Builder.CreateAnd(NumRegs, Builder.getInt8((uint8_t) ~1U));
424 Builder.CreateICmpULT(NumRegs, Builder.getInt8(OverflowLimit),
"cond");
430 Builder.CreateCondBr(CC, UsingRegs, UsingOverflow);
432 llvm::Type *DirectTy = CGF.
ConvertType(Ty), *ElementTy = DirectTy;
441 Address RegSaveAreaPtr = Builder.CreateStructGEP(VAList, 4);
442 RegAddr =
Address(Builder.CreateLoad(RegSaveAreaPtr), CGF.
Int8Ty,
447 if (!(isInt || IsSoftFloatABI)) {
448 RegAddr = Builder.CreateConstInBoundsByteGEP(RegAddr,
455 llvm::Value *RegOffset =
456 Builder.CreateMul(NumRegs, Builder.getInt8(RegSize.
getQuantity()));
463 Builder.CreateAdd(NumRegs,
464 Builder.getInt8((isI64 || (isF64 && IsSoftFloatABI)) ? 2 : 1));
465 Builder.CreateStore(NumRegs, NumRegsAddr);
475 Builder.CreateStore(Builder.getInt8(OverflowLimit), NumRegsAddr);
488 Address OverflowAreaAddr = Builder.CreateStructGEP(VAList, 3);
490 Address(Builder.CreateLoad(OverflowAreaAddr,
"argp.cur"), CGF.
Int8Ty,
494 if (Align > OverflowAreaAlign) {
503 OverflowArea = Builder.CreateConstInBoundsByteGEP(OverflowArea, Size);
504 Builder.CreateStore(OverflowArea.
getPointer(), OverflowAreaAddr);
516 Result =
Address(Builder.CreateLoad(Result,
"aggr"), ElementTy,
517 getContext().getTypeAlignInChars(Ty));
523bool PPC32TargetCodeGenInfo::isStructReturnInRegABI(
525 assert(Triple.isPPC32());
527 switch (Opts.getStructReturnConvention()) {
536 if (Triple.isOSBinFormatELF() && !Triple.isOSLinux())
554class PPC64_SVR4_ABIInfo :
public ABIInfo {
555 static const unsigned GPRBits = 64;
564 bool isPromotableTypeForABI(
QualType Ty)
const;
572 uint64_t Members)
const override;
590 if ((T->
isVectorType() && getContext().getTypeSize(T) == 128) ||
611 std::make_unique<PPC64_SVR4_ABIInfo>(CGT,
Kind, SoftFloatABI)) {
613 std::make_unique<SwiftABIInfo>(CGT,
false);
622 llvm::Value *
Address)
const override;
624 const llvm::MapVector<GlobalDecl, StringRef>
625 &MangledDeclNames)
const override;
639 llvm::Value *
Address)
const override;
646PPC64_SVR4_ABIInfo::isPromotableTypeForABI(
QualType Ty)
const {
649 Ty = EnumTy->getDecl()->getIntegerType();
652 if (isPromotableIntegerTypeForABI(Ty))
659 case BuiltinType::Int:
660 case BuiltinType::UInt:
667 if (EIT->getNumBits() < 64)
678 Ty = CTy->getElementType();
680 auto FloatUsesVector = [
this](
QualType Ty){
682 Ty) == &llvm::APFloat::IEEEquad();
689 }
else if (FloatUsesVector(Ty)) {
698 const Type *AlignAsType =
nullptr;
702 if ((EltType->
isVectorType() && getContext().getTypeSize(EltType) == 128) ||
704 AlignAsType = EltType;
710 if (!AlignAsType && Kind == PPC64_SVR4_ABIKind::ELFv2 &&
717 FloatUsesVector(
QualType(AlignAsType, 0));
730bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateBaseType(
QualType Ty)
const {
734 if (BT->
getKind() == BuiltinType::Float ||
735 BT->
getKind() == BuiltinType::Double ||
736 BT->
getKind() == BuiltinType::LongDouble ||
737 BT->
getKind() == BuiltinType::Ibm128 ||
738 (getContext().getTargetInfo().hasFloat128Type() &&
739 (BT->
getKind() == BuiltinType::Float128))) {
746 if (getContext().getTypeSize(VT) == 128)
752bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateSmallEnough(
753 const Type *
Base, uint64_t Members)
const {
757 ((getContext().getTargetInfo().hasFloat128Type() &&
758 Base->isFloat128Type()) ||
759 Base->isVectorType()) ? 1
760 : (getContext().getTypeSize(
Base) + 63) / 64;
763 return Members * NumRegs <= 8;
767PPC64_SVR4_ABIInfo::classifyArgumentType(
QualType Ty)
const {
778 return getNaturalAlignIndirect(Ty,
false);
779 else if (Size < 128) {
780 llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size);
786 if (EIT->getNumBits() > 128)
787 return getNaturalAlignIndirect(Ty,
true);
793 uint64_t ABIAlign = getParamTypeAlignment(Ty).getQuantity();
799 if (Kind == PPC64_SVR4_ABIKind::ELFv2 &&
800 isHomogeneousAggregate(Ty,
Base, Members)) {
801 llvm::Type *BaseTy = CGT.ConvertType(
QualType(
Base, 0));
802 llvm::Type *CoerceTy = llvm::ArrayType::get(BaseTy, Members);
810 uint64_t Bits = getContext().getTypeSize(Ty);
811 if (Bits > 0 && Bits <= 8 * GPRBits) {
812 llvm::Type *CoerceTy;
818 llvm::IntegerType::get(getVMContext(), llvm::alignTo(Bits, 8));
823 uint64_t NumRegs = llvm::alignTo(Bits, RegBits) / RegBits;
824 llvm::Type *RegTy = llvm::IntegerType::get(getVMContext(), RegBits);
825 CoerceTy = llvm::ArrayType::get(RegTy, NumRegs);
842PPC64_SVR4_ABIInfo::classifyReturnType(
QualType RetTy)
const {
854 return getNaturalAlignIndirect(RetTy);
855 else if (Size < 128) {
856 llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size);
862 if (EIT->getNumBits() > 128)
863 return getNaturalAlignIndirect(RetTy,
false);
869 if (Kind == PPC64_SVR4_ABIKind::ELFv2 &&
870 isHomogeneousAggregate(RetTy,
Base, Members)) {
871 llvm::Type *BaseTy = CGT.ConvertType(
QualType(
Base, 0));
872 llvm::Type *CoerceTy = llvm::ArrayType::get(BaseTy, Members);
877 uint64_t Bits = getContext().getTypeSize(RetTy);
878 if (Kind == PPC64_SVR4_ABIKind::ELFv2 && Bits <= 2 * GPRBits) {
882 llvm::Type *CoerceTy;
883 if (Bits > GPRBits) {
884 CoerceTy = llvm::IntegerType::get(getVMContext(), GPRBits);
885 CoerceTy = llvm::StructType::get(CoerceTy, CoerceTy);
888 llvm::IntegerType::get(getVMContext(), llvm::alignTo(Bits, 8));
893 return getNaturalAlignIndirect(RetTy);
903 auto TypeInfo = getContext().getTypeInfoInChars(Ty);
916 if (EltSize < SlotSize)
939PPC64_SVR4_TargetCodeGenInfo::initDwarfEHRegSizeTable(
946void PPC64_SVR4_TargetCodeGenInfo::emitTargetMetadata(
948 const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames)
const {
952 if (flt == &llvm::APFloat::PPCDoubleDouble())
953 CGM.
getModule().addModuleFlag(llvm::Module::Error,
"float-abi",
954 llvm::MDString::get(Ctx,
"doubledouble"));
955 else if (flt == &llvm::APFloat::IEEEquad())
956 CGM.
getModule().addModuleFlag(llvm::Module::Error,
"float-abi",
957 llvm::MDString::get(Ctx,
"ieeequad"));
958 else if (flt == &llvm::APFloat::IEEEdouble())
959 CGM.
getModule().addModuleFlag(llvm::Module::Error,
"float-abi",
960 llvm::MDString::get(Ctx,
"ieeedouble"));
971std::unique_ptr<TargetCodeGenInfo>
973 return std::make_unique<AIXTargetCodeGenInfo>(CGM.
getTypes(), Is64Bit);
976std::unique_ptr<TargetCodeGenInfo>
978 bool RetSmallStructInRegABI = PPC32TargetCodeGenInfo::isStructReturnInRegABI(
980 return std::make_unique<PPC32TargetCodeGenInfo>(CGM.
getTypes(), SoftFloatABI,
981 RetSmallStructInRegABI);
984std::unique_ptr<TargetCodeGenInfo>
986 return std::make_unique<PPC64TargetCodeGenInfo>(CGM.
getTypes());
991 return std::make_unique<PPC64_SVR4_TargetCodeGenInfo>(CGM.
getTypes(), Kind,
static Address complexTempStructure(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, CharUnits SlotSize, CharUnits EltSize, const ComplexType *CTy)
static bool PPC_initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address, bool Is64Bit, bool IsAIX)
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
TypeInfoChars getTypeInfoInChars(const Type *T) const
A fixed int type of a specified bitwidth.
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
static ABIArgInfo getIgnore()
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
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)
static ABIArgInfo getDirectInReg(llvm::Type *T=nullptr)
ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.
CodeGen::CGCXXABI & getCXXABI() const
virtual bool isHomogeneousAggregateBaseType(QualType Ty) const
virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty) const =0
EmitVAArg - Emit the target dependent code to load a value of.
virtual bool isHomogeneousAggregateSmallEnough(const Type *Base, uint64_t Members) const
virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const =0
CharUnits getAlignment() const
Return the alignment of this pointer.
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::Value * getPointer() const
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::LoadInst * CreateLoad(Address Addr, 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()
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,...
ASTContext & getContext() const
Address CreateMemTemp(QualType T, const Twine &Name="tmp", Address *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
llvm::Type * ConvertType(QualType T)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
const llvm::DataLayout & getDataLayout() const
const llvm::Triple & getTriple() const
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
bool isLongDoubleReferenced() const
DefaultABIInfo - The default implementation for ABI specific details.
ABIArgInfo classifyArgumentType(QualType RetTy) const
ABIArgInfo classifyReturnType(QualType RetTy) const
void computeInfo(CGFunctionInfo &FI) const override
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const override
EmitVAArg - Emit the target dependent code to load a value of.
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
virtual bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const
Initializes the given DWARF EH register-size table, a char*.
virtual int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const
Determines the DWARF register number for the stack pointer, for exception-handling purposes.
virtual void emitTargetMetadata(CodeGen::CodeGenModule &CGM, const llvm::MapVector< GlobalDecl, StringRef > &MangledDeclNames) const
emitTargetMetadata - Provides a convenient hook to handle extra target-specific metadata for the give...
Complex values, per C99 6.2.5p11.
QualType getElementType() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
A (possibly-)qualified type.
const llvm::fltSemantics & getLongDoubleFormat() const
The base class of the type hierarchy.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isAnyComplexType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a GCC generic vector 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 > createPPC64_SVR4_TargetCodeGenInfo(CodeGenModule &CGM, PPC64_SVR4_ABIKind Kind, bool SoftFloatABI)
Address emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr, llvm::Type *DirectTy, CharUnits DirectSize, CharUnits DirectAlign, CharUnits SlotSize, bool AllowHigherAlign, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
std::unique_ptr< TargetCodeGenInfo > createAIXTargetCodeGenInfo(CodeGenModule &CGM, bool Is64Bit)
bool isRecordWithSIMDVectorType(ASTContext &Context, QualType Ty)
Address emitMergePHI(CodeGenFunction &CGF, Address Addr1, llvm::BasicBlock *Block1, Address Addr2, llvm::BasicBlock *Block2, const llvm::Twine &Name="")
llvm::Value * emitRoundPointerUpToAlignment(CodeGenFunction &CGF, llvm::Value *Ptr, CharUnits Align)
bool isAggregateTypeForABI(QualType T)
const Type * isSingleElementStruct(QualType T, ASTContext &Context)
isSingleElementStruct - Determine if a structure is a "single element struct", i.e.
void AssignToArrayRange(CodeGen::CGBuilderTy &Builder, llvm::Value *Array, llvm::Value *Value, unsigned FirstIndex, unsigned LastIndex)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
std::unique_ptr< TargetCodeGenInfo > createPPC32TargetCodeGenInfo(CodeGenModule &CGM, bool SoftFloatABI)
std::unique_ptr< TargetCodeGenInfo > createPPC64TargetCodeGenInfo(CodeGenModule &CGM)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CharUnits getPointerSize() const
llvm::PointerType * UnqualPtrTy