106c3fb27SDimitry Andric //===- PPC.cpp ------------------------------------------------------------===// 206c3fb27SDimitry Andric // 306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric // 706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric 906c3fb27SDimitry Andric #include "ABIInfoImpl.h" 1006c3fb27SDimitry Andric #include "TargetInfo.h" 11*0fca6ea1SDimitry Andric #include "clang/Basic/DiagnosticFrontend.h" 1206c3fb27SDimitry Andric 1306c3fb27SDimitry Andric using namespace clang; 1406c3fb27SDimitry Andric using namespace clang::CodeGen; 1506c3fb27SDimitry Andric 16*0fca6ea1SDimitry Andric static RValue complexTempStructure(CodeGenFunction &CGF, Address VAListAddr, 1706c3fb27SDimitry Andric QualType Ty, CharUnits SlotSize, 1806c3fb27SDimitry Andric CharUnits EltSize, const ComplexType *CTy) { 1906c3fb27SDimitry Andric Address Addr = 2006c3fb27SDimitry Andric emitVoidPtrDirectVAArg(CGF, VAListAddr, CGF.Int8Ty, SlotSize * 2, 2106c3fb27SDimitry Andric SlotSize, SlotSize, /*AllowHigher*/ true); 2206c3fb27SDimitry Andric 2306c3fb27SDimitry Andric Address RealAddr = Addr; 2406c3fb27SDimitry Andric Address ImagAddr = RealAddr; 2506c3fb27SDimitry Andric if (CGF.CGM.getDataLayout().isBigEndian()) { 2606c3fb27SDimitry Andric RealAddr = 2706c3fb27SDimitry Andric CGF.Builder.CreateConstInBoundsByteGEP(RealAddr, SlotSize - EltSize); 2806c3fb27SDimitry Andric ImagAddr = CGF.Builder.CreateConstInBoundsByteGEP(ImagAddr, 2906c3fb27SDimitry Andric 2 * SlotSize - EltSize); 3006c3fb27SDimitry Andric } else { 3106c3fb27SDimitry Andric ImagAddr = CGF.Builder.CreateConstInBoundsByteGEP(RealAddr, SlotSize); 3206c3fb27SDimitry Andric } 3306c3fb27SDimitry Andric 3406c3fb27SDimitry Andric llvm::Type *EltTy = CGF.ConvertTypeForMem(CTy->getElementType()); 3506c3fb27SDimitry Andric RealAddr = RealAddr.withElementType(EltTy); 3606c3fb27SDimitry Andric ImagAddr = ImagAddr.withElementType(EltTy); 3706c3fb27SDimitry Andric llvm::Value *Real = CGF.Builder.CreateLoad(RealAddr, ".vareal"); 3806c3fb27SDimitry Andric llvm::Value *Imag = CGF.Builder.CreateLoad(ImagAddr, ".vaimag"); 3906c3fb27SDimitry Andric 40*0fca6ea1SDimitry Andric return RValue::getComplex(Real, Imag); 4106c3fb27SDimitry Andric } 4206c3fb27SDimitry Andric 4306c3fb27SDimitry Andric static bool PPC_initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 4406c3fb27SDimitry Andric llvm::Value *Address, bool Is64Bit, 4506c3fb27SDimitry Andric bool IsAIX) { 4606c3fb27SDimitry Andric // This is calculated from the LLVM and GCC tables and verified 4706c3fb27SDimitry Andric // against gcc output. AFAIK all PPC ABIs use the same encoding. 4806c3fb27SDimitry Andric 4906c3fb27SDimitry Andric CodeGen::CGBuilderTy &Builder = CGF.Builder; 5006c3fb27SDimitry Andric 5106c3fb27SDimitry Andric llvm::IntegerType *i8 = CGF.Int8Ty; 5206c3fb27SDimitry Andric llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4); 5306c3fb27SDimitry Andric llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8); 5406c3fb27SDimitry Andric llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16); 5506c3fb27SDimitry Andric 5606c3fb27SDimitry Andric // 0-31: r0-31, the 4-byte or 8-byte general-purpose registers 5706c3fb27SDimitry Andric AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 0, 31); 5806c3fb27SDimitry Andric 5906c3fb27SDimitry Andric // 32-63: fp0-31, the 8-byte floating-point registers 6006c3fb27SDimitry Andric AssignToArrayRange(Builder, Address, Eight8, 32, 63); 6106c3fb27SDimitry Andric 6206c3fb27SDimitry Andric // 64-67 are various 4-byte or 8-byte special-purpose registers: 6306c3fb27SDimitry Andric // 64: mq 6406c3fb27SDimitry Andric // 65: lr 6506c3fb27SDimitry Andric // 66: ctr 6606c3fb27SDimitry Andric // 67: ap 6706c3fb27SDimitry Andric AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 64, 67); 6806c3fb27SDimitry Andric 6906c3fb27SDimitry Andric // 68-76 are various 4-byte special-purpose registers: 7006c3fb27SDimitry Andric // 68-75 cr0-7 7106c3fb27SDimitry Andric // 76: xer 7206c3fb27SDimitry Andric AssignToArrayRange(Builder, Address, Four8, 68, 76); 7306c3fb27SDimitry Andric 7406c3fb27SDimitry Andric // 77-108: v0-31, the 16-byte vector registers 7506c3fb27SDimitry Andric AssignToArrayRange(Builder, Address, Sixteen8, 77, 108); 7606c3fb27SDimitry Andric 7706c3fb27SDimitry Andric // 109: vrsave 7806c3fb27SDimitry Andric // 110: vscr 7906c3fb27SDimitry Andric AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 109, 110); 8006c3fb27SDimitry Andric 8106c3fb27SDimitry Andric // AIX does not utilize the rest of the registers. 8206c3fb27SDimitry Andric if (IsAIX) 8306c3fb27SDimitry Andric return false; 8406c3fb27SDimitry Andric 8506c3fb27SDimitry Andric // 111: spe_acc 8606c3fb27SDimitry Andric // 112: spefscr 8706c3fb27SDimitry Andric // 113: sfp 8806c3fb27SDimitry Andric AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 111, 113); 8906c3fb27SDimitry Andric 9006c3fb27SDimitry Andric if (!Is64Bit) 9106c3fb27SDimitry Andric return false; 9206c3fb27SDimitry Andric 9306c3fb27SDimitry Andric // TODO: Need to verify if these registers are used on 64 bit AIX with Power8 9406c3fb27SDimitry Andric // or above CPU. 9506c3fb27SDimitry Andric // 64-bit only registers: 9606c3fb27SDimitry Andric // 114: tfhar 9706c3fb27SDimitry Andric // 115: tfiar 9806c3fb27SDimitry Andric // 116: texasr 9906c3fb27SDimitry Andric AssignToArrayRange(Builder, Address, Eight8, 114, 116); 10006c3fb27SDimitry Andric 10106c3fb27SDimitry Andric return false; 10206c3fb27SDimitry Andric } 10306c3fb27SDimitry Andric 10406c3fb27SDimitry Andric // AIX 10506c3fb27SDimitry Andric namespace { 10606c3fb27SDimitry Andric /// AIXABIInfo - The AIX XCOFF ABI information. 10706c3fb27SDimitry Andric class AIXABIInfo : public ABIInfo { 10806c3fb27SDimitry Andric const bool Is64Bit; 10906c3fb27SDimitry Andric const unsigned PtrByteSize; 11006c3fb27SDimitry Andric CharUnits getParamTypeAlignment(QualType Ty) const; 11106c3fb27SDimitry Andric 11206c3fb27SDimitry Andric public: 11306c3fb27SDimitry Andric AIXABIInfo(CodeGen::CodeGenTypes &CGT, bool Is64Bit) 11406c3fb27SDimitry Andric : ABIInfo(CGT), Is64Bit(Is64Bit), PtrByteSize(Is64Bit ? 8 : 4) {} 11506c3fb27SDimitry Andric 11606c3fb27SDimitry Andric bool isPromotableTypeForABI(QualType Ty) const; 11706c3fb27SDimitry Andric 11806c3fb27SDimitry Andric ABIArgInfo classifyReturnType(QualType RetTy) const; 11906c3fb27SDimitry Andric ABIArgInfo classifyArgumentType(QualType Ty) const; 12006c3fb27SDimitry Andric 12106c3fb27SDimitry Andric void computeInfo(CGFunctionInfo &FI) const override { 12206c3fb27SDimitry Andric if (!getCXXABI().classifyReturnType(FI)) 12306c3fb27SDimitry Andric FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); 12406c3fb27SDimitry Andric 12506c3fb27SDimitry Andric for (auto &I : FI.arguments()) 12606c3fb27SDimitry Andric I.info = classifyArgumentType(I.type); 12706c3fb27SDimitry Andric } 12806c3fb27SDimitry Andric 129*0fca6ea1SDimitry Andric RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 130*0fca6ea1SDimitry Andric AggValueSlot Slot) const override; 13106c3fb27SDimitry Andric }; 13206c3fb27SDimitry Andric 13306c3fb27SDimitry Andric class AIXTargetCodeGenInfo : public TargetCodeGenInfo { 13406c3fb27SDimitry Andric const bool Is64Bit; 13506c3fb27SDimitry Andric 13606c3fb27SDimitry Andric public: 13706c3fb27SDimitry Andric AIXTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool Is64Bit) 13806c3fb27SDimitry Andric : TargetCodeGenInfo(std::make_unique<AIXABIInfo>(CGT, Is64Bit)), 13906c3fb27SDimitry Andric Is64Bit(Is64Bit) {} 14006c3fb27SDimitry Andric int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { 14106c3fb27SDimitry Andric return 1; // r1 is the dedicated stack pointer 14206c3fb27SDimitry Andric } 14306c3fb27SDimitry Andric 14406c3fb27SDimitry Andric bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 14506c3fb27SDimitry Andric llvm::Value *Address) const override; 146*0fca6ea1SDimitry Andric 147*0fca6ea1SDimitry Andric void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, 148*0fca6ea1SDimitry Andric CodeGen::CodeGenModule &M) const override; 14906c3fb27SDimitry Andric }; 15006c3fb27SDimitry Andric } // namespace 15106c3fb27SDimitry Andric 15206c3fb27SDimitry Andric // Return true if the ABI requires Ty to be passed sign- or zero- 15306c3fb27SDimitry Andric // extended to 32/64 bits. 15406c3fb27SDimitry Andric bool AIXABIInfo::isPromotableTypeForABI(QualType Ty) const { 15506c3fb27SDimitry Andric // Treat an enum type as its underlying type. 15606c3fb27SDimitry Andric if (const EnumType *EnumTy = Ty->getAs<EnumType>()) 15706c3fb27SDimitry Andric Ty = EnumTy->getDecl()->getIntegerType(); 15806c3fb27SDimitry Andric 15906c3fb27SDimitry Andric // Promotable integer types are required to be promoted by the ABI. 16006c3fb27SDimitry Andric if (getContext().isPromotableIntegerType(Ty)) 16106c3fb27SDimitry Andric return true; 16206c3fb27SDimitry Andric 16306c3fb27SDimitry Andric if (!Is64Bit) 16406c3fb27SDimitry Andric return false; 16506c3fb27SDimitry Andric 16606c3fb27SDimitry Andric // For 64 bit mode, in addition to the usual promotable integer types, we also 16706c3fb27SDimitry Andric // need to extend all 32-bit types, since the ABI requires promotion to 64 16806c3fb27SDimitry Andric // bits. 16906c3fb27SDimitry Andric if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) 17006c3fb27SDimitry Andric switch (BT->getKind()) { 17106c3fb27SDimitry Andric case BuiltinType::Int: 17206c3fb27SDimitry Andric case BuiltinType::UInt: 17306c3fb27SDimitry Andric return true; 17406c3fb27SDimitry Andric default: 17506c3fb27SDimitry Andric break; 17606c3fb27SDimitry Andric } 17706c3fb27SDimitry Andric 17806c3fb27SDimitry Andric return false; 17906c3fb27SDimitry Andric } 18006c3fb27SDimitry Andric 18106c3fb27SDimitry Andric ABIArgInfo AIXABIInfo::classifyReturnType(QualType RetTy) const { 18206c3fb27SDimitry Andric if (RetTy->isAnyComplexType()) 18306c3fb27SDimitry Andric return ABIArgInfo::getDirect(); 18406c3fb27SDimitry Andric 18506c3fb27SDimitry Andric if (RetTy->isVectorType()) 18606c3fb27SDimitry Andric return ABIArgInfo::getDirect(); 18706c3fb27SDimitry Andric 18806c3fb27SDimitry Andric if (RetTy->isVoidType()) 18906c3fb27SDimitry Andric return ABIArgInfo::getIgnore(); 19006c3fb27SDimitry Andric 19106c3fb27SDimitry Andric if (isAggregateTypeForABI(RetTy)) 19206c3fb27SDimitry Andric return getNaturalAlignIndirect(RetTy); 19306c3fb27SDimitry Andric 19406c3fb27SDimitry Andric return (isPromotableTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) 19506c3fb27SDimitry Andric : ABIArgInfo::getDirect()); 19606c3fb27SDimitry Andric } 19706c3fb27SDimitry Andric 19806c3fb27SDimitry Andric ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const { 19906c3fb27SDimitry Andric Ty = useFirstFieldIfTransparentUnion(Ty); 20006c3fb27SDimitry Andric 20106c3fb27SDimitry Andric if (Ty->isAnyComplexType()) 20206c3fb27SDimitry Andric return ABIArgInfo::getDirect(); 20306c3fb27SDimitry Andric 20406c3fb27SDimitry Andric if (Ty->isVectorType()) 20506c3fb27SDimitry Andric return ABIArgInfo::getDirect(); 20606c3fb27SDimitry Andric 20706c3fb27SDimitry Andric if (isAggregateTypeForABI(Ty)) { 20806c3fb27SDimitry Andric // Records with non-trivial destructors/copy-constructors should not be 20906c3fb27SDimitry Andric // passed by value. 21006c3fb27SDimitry Andric if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) 21106c3fb27SDimitry Andric return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); 21206c3fb27SDimitry Andric 21306c3fb27SDimitry Andric CharUnits CCAlign = getParamTypeAlignment(Ty); 21406c3fb27SDimitry Andric CharUnits TyAlign = getContext().getTypeAlignInChars(Ty); 21506c3fb27SDimitry Andric 21606c3fb27SDimitry Andric return ABIArgInfo::getIndirect(CCAlign, /*ByVal*/ true, 21706c3fb27SDimitry Andric /*Realign*/ TyAlign > CCAlign); 21806c3fb27SDimitry Andric } 21906c3fb27SDimitry Andric 22006c3fb27SDimitry Andric return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) 22106c3fb27SDimitry Andric : ABIArgInfo::getDirect()); 22206c3fb27SDimitry Andric } 22306c3fb27SDimitry Andric 22406c3fb27SDimitry Andric CharUnits AIXABIInfo::getParamTypeAlignment(QualType Ty) const { 22506c3fb27SDimitry Andric // Complex types are passed just like their elements. 22606c3fb27SDimitry Andric if (const ComplexType *CTy = Ty->getAs<ComplexType>()) 22706c3fb27SDimitry Andric Ty = CTy->getElementType(); 22806c3fb27SDimitry Andric 22906c3fb27SDimitry Andric if (Ty->isVectorType()) 23006c3fb27SDimitry Andric return CharUnits::fromQuantity(16); 23106c3fb27SDimitry Andric 23206c3fb27SDimitry Andric // If the structure contains a vector type, the alignment is 16. 23306c3fb27SDimitry Andric if (isRecordWithSIMDVectorType(getContext(), Ty)) 23406c3fb27SDimitry Andric return CharUnits::fromQuantity(16); 23506c3fb27SDimitry Andric 23606c3fb27SDimitry Andric return CharUnits::fromQuantity(PtrByteSize); 23706c3fb27SDimitry Andric } 23806c3fb27SDimitry Andric 239*0fca6ea1SDimitry Andric RValue AIXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 240*0fca6ea1SDimitry Andric QualType Ty, AggValueSlot Slot) const { 24106c3fb27SDimitry Andric 24206c3fb27SDimitry Andric auto TypeInfo = getContext().getTypeInfoInChars(Ty); 24306c3fb27SDimitry Andric TypeInfo.Align = getParamTypeAlignment(Ty); 24406c3fb27SDimitry Andric 24506c3fb27SDimitry Andric CharUnits SlotSize = CharUnits::fromQuantity(PtrByteSize); 24606c3fb27SDimitry Andric 24706c3fb27SDimitry Andric // If we have a complex type and the base type is smaller than the register 24806c3fb27SDimitry Andric // size, the ABI calls for the real and imaginary parts to be right-adjusted 24906c3fb27SDimitry Andric // in separate words in 32bit mode or doublewords in 64bit mode. However, 25006c3fb27SDimitry Andric // Clang expects us to produce a pointer to a structure with the two parts 25106c3fb27SDimitry Andric // packed tightly. So generate loads of the real and imaginary parts relative 25206c3fb27SDimitry Andric // to the va_list pointer, and store them to a temporary structure. We do the 25306c3fb27SDimitry Andric // same as the PPC64ABI here. 25406c3fb27SDimitry Andric if (const ComplexType *CTy = Ty->getAs<ComplexType>()) { 25506c3fb27SDimitry Andric CharUnits EltSize = TypeInfo.Width / 2; 25606c3fb27SDimitry Andric if (EltSize < SlotSize) 25706c3fb27SDimitry Andric return complexTempStructure(CGF, VAListAddr, Ty, SlotSize, EltSize, CTy); 25806c3fb27SDimitry Andric } 25906c3fb27SDimitry Andric 26006c3fb27SDimitry Andric return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo, 261*0fca6ea1SDimitry Andric SlotSize, /*AllowHigher*/ true, Slot); 26206c3fb27SDimitry Andric } 26306c3fb27SDimitry Andric 26406c3fb27SDimitry Andric bool AIXTargetCodeGenInfo::initDwarfEHRegSizeTable( 26506c3fb27SDimitry Andric CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const { 26606c3fb27SDimitry Andric return PPC_initDwarfEHRegSizeTable(CGF, Address, Is64Bit, /*IsAIX*/ true); 26706c3fb27SDimitry Andric } 26806c3fb27SDimitry Andric 269*0fca6ea1SDimitry Andric void AIXTargetCodeGenInfo::setTargetAttributes( 270*0fca6ea1SDimitry Andric const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const { 271*0fca6ea1SDimitry Andric if (!isa<llvm::GlobalVariable>(GV)) 272*0fca6ea1SDimitry Andric return; 273*0fca6ea1SDimitry Andric 274*0fca6ea1SDimitry Andric auto *GVar = cast<llvm::GlobalVariable>(GV); 275*0fca6ea1SDimitry Andric auto GVId = GV->getName(); 276*0fca6ea1SDimitry Andric 277*0fca6ea1SDimitry Andric // Is this a global variable specified by the user as toc-data? 278*0fca6ea1SDimitry Andric bool UserSpecifiedTOC = 279*0fca6ea1SDimitry Andric llvm::binary_search(M.getCodeGenOpts().TocDataVarsUserSpecified, GVId); 280*0fca6ea1SDimitry Andric // Assumes the same variable cannot be in both TocVarsUserSpecified and 281*0fca6ea1SDimitry Andric // NoTocVars. 282*0fca6ea1SDimitry Andric if (UserSpecifiedTOC || 283*0fca6ea1SDimitry Andric ((M.getCodeGenOpts().AllTocData) && 284*0fca6ea1SDimitry Andric !llvm::binary_search(M.getCodeGenOpts().NoTocDataVars, GVId))) { 285*0fca6ea1SDimitry Andric const unsigned long PointerSize = 286*0fca6ea1SDimitry Andric GV->getParent()->getDataLayout().getPointerSizeInBits() / 8; 287*0fca6ea1SDimitry Andric auto *VarD = dyn_cast<VarDecl>(D); 288*0fca6ea1SDimitry Andric assert(VarD && "Invalid declaration of global variable."); 289*0fca6ea1SDimitry Andric 290*0fca6ea1SDimitry Andric ASTContext &Context = D->getASTContext(); 291*0fca6ea1SDimitry Andric unsigned Alignment = Context.toBits(Context.getDeclAlign(D)) / 8; 292*0fca6ea1SDimitry Andric const auto *Ty = VarD->getType().getTypePtr(); 293*0fca6ea1SDimitry Andric const RecordDecl *RDecl = 294*0fca6ea1SDimitry Andric Ty->isRecordType() ? Ty->getAs<RecordType>()->getDecl() : nullptr; 295*0fca6ea1SDimitry Andric 296*0fca6ea1SDimitry Andric bool EmitDiagnostic = UserSpecifiedTOC && GV->hasExternalLinkage(); 297*0fca6ea1SDimitry Andric auto reportUnsupportedWarning = [&](bool ShouldEmitWarning, StringRef Msg) { 298*0fca6ea1SDimitry Andric if (ShouldEmitWarning) 299*0fca6ea1SDimitry Andric M.getDiags().Report(D->getLocation(), diag::warn_toc_unsupported_type) 300*0fca6ea1SDimitry Andric << GVId << Msg; 301*0fca6ea1SDimitry Andric }; 302*0fca6ea1SDimitry Andric if (!Ty || Ty->isIncompleteType()) 303*0fca6ea1SDimitry Andric reportUnsupportedWarning(EmitDiagnostic, "of incomplete type"); 304*0fca6ea1SDimitry Andric else if (RDecl && RDecl->hasFlexibleArrayMember()) 305*0fca6ea1SDimitry Andric reportUnsupportedWarning(EmitDiagnostic, 306*0fca6ea1SDimitry Andric "it contains a flexible array member"); 307*0fca6ea1SDimitry Andric else if (VarD->getTLSKind() != VarDecl::TLS_None) 308*0fca6ea1SDimitry Andric reportUnsupportedWarning(EmitDiagnostic, "of thread local storage"); 309*0fca6ea1SDimitry Andric else if (PointerSize < Context.getTypeInfo(VarD->getType()).Width / 8) 310*0fca6ea1SDimitry Andric reportUnsupportedWarning(EmitDiagnostic, 311*0fca6ea1SDimitry Andric "variable is larger than a pointer"); 312*0fca6ea1SDimitry Andric else if (PointerSize < Alignment) 313*0fca6ea1SDimitry Andric reportUnsupportedWarning(EmitDiagnostic, 314*0fca6ea1SDimitry Andric "variable is aligned wider than a pointer"); 315*0fca6ea1SDimitry Andric else if (D->hasAttr<SectionAttr>()) 316*0fca6ea1SDimitry Andric reportUnsupportedWarning(EmitDiagnostic, 317*0fca6ea1SDimitry Andric "variable has a section attribute"); 318*0fca6ea1SDimitry Andric else if (GV->hasExternalLinkage() || 319*0fca6ea1SDimitry Andric (M.getCodeGenOpts().AllTocData && !GV->hasLocalLinkage())) 320*0fca6ea1SDimitry Andric GVar->addAttribute("toc-data"); 321*0fca6ea1SDimitry Andric } 322*0fca6ea1SDimitry Andric } 323*0fca6ea1SDimitry Andric 32406c3fb27SDimitry Andric // PowerPC-32 32506c3fb27SDimitry Andric namespace { 32606c3fb27SDimitry Andric /// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information. 32706c3fb27SDimitry Andric class PPC32_SVR4_ABIInfo : public DefaultABIInfo { 32806c3fb27SDimitry Andric bool IsSoftFloatABI; 32906c3fb27SDimitry Andric bool IsRetSmallStructInRegABI; 33006c3fb27SDimitry Andric 33106c3fb27SDimitry Andric CharUnits getParamTypeAlignment(QualType Ty) const; 33206c3fb27SDimitry Andric 33306c3fb27SDimitry Andric public: 33406c3fb27SDimitry Andric PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI, 33506c3fb27SDimitry Andric bool RetSmallStructInRegABI) 33606c3fb27SDimitry Andric : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI), 33706c3fb27SDimitry Andric IsRetSmallStructInRegABI(RetSmallStructInRegABI) {} 33806c3fb27SDimitry Andric 33906c3fb27SDimitry Andric ABIArgInfo classifyReturnType(QualType RetTy) const; 34006c3fb27SDimitry Andric 34106c3fb27SDimitry Andric void computeInfo(CGFunctionInfo &FI) const override { 34206c3fb27SDimitry Andric if (!getCXXABI().classifyReturnType(FI)) 34306c3fb27SDimitry Andric FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); 34406c3fb27SDimitry Andric for (auto &I : FI.arguments()) 34506c3fb27SDimitry Andric I.info = classifyArgumentType(I.type); 34606c3fb27SDimitry Andric } 34706c3fb27SDimitry Andric 348*0fca6ea1SDimitry Andric RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 349*0fca6ea1SDimitry Andric AggValueSlot Slot) const override; 35006c3fb27SDimitry Andric }; 35106c3fb27SDimitry Andric 35206c3fb27SDimitry Andric class PPC32TargetCodeGenInfo : public TargetCodeGenInfo { 35306c3fb27SDimitry Andric public: 35406c3fb27SDimitry Andric PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI, 35506c3fb27SDimitry Andric bool RetSmallStructInRegABI) 35606c3fb27SDimitry Andric : TargetCodeGenInfo(std::make_unique<PPC32_SVR4_ABIInfo>( 35706c3fb27SDimitry Andric CGT, SoftFloatABI, RetSmallStructInRegABI)) {} 35806c3fb27SDimitry Andric 35906c3fb27SDimitry Andric static bool isStructReturnInRegABI(const llvm::Triple &Triple, 36006c3fb27SDimitry Andric const CodeGenOptions &Opts); 36106c3fb27SDimitry Andric 36206c3fb27SDimitry Andric int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { 36306c3fb27SDimitry Andric // This is recovered from gcc output. 36406c3fb27SDimitry Andric return 1; // r1 is the dedicated stack pointer 36506c3fb27SDimitry Andric } 36606c3fb27SDimitry Andric 36706c3fb27SDimitry Andric bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 36806c3fb27SDimitry Andric llvm::Value *Address) const override; 36906c3fb27SDimitry Andric }; 37006c3fb27SDimitry Andric } 37106c3fb27SDimitry Andric 37206c3fb27SDimitry Andric CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { 37306c3fb27SDimitry Andric // Complex types are passed just like their elements. 37406c3fb27SDimitry Andric if (const ComplexType *CTy = Ty->getAs<ComplexType>()) 37506c3fb27SDimitry Andric Ty = CTy->getElementType(); 37606c3fb27SDimitry Andric 37706c3fb27SDimitry Andric if (Ty->isVectorType()) 37806c3fb27SDimitry Andric return CharUnits::fromQuantity(getContext().getTypeSize(Ty) == 128 ? 16 37906c3fb27SDimitry Andric : 4); 38006c3fb27SDimitry Andric 38106c3fb27SDimitry Andric // For single-element float/vector structs, we consider the whole type 38206c3fb27SDimitry Andric // to have the same alignment requirements as its single element. 38306c3fb27SDimitry Andric const Type *AlignTy = nullptr; 38406c3fb27SDimitry Andric if (const Type *EltType = isSingleElementStruct(Ty, getContext())) { 38506c3fb27SDimitry Andric const BuiltinType *BT = EltType->getAs<BuiltinType>(); 38606c3fb27SDimitry Andric if ((EltType->isVectorType() && getContext().getTypeSize(EltType) == 128) || 38706c3fb27SDimitry Andric (BT && BT->isFloatingPoint())) 38806c3fb27SDimitry Andric AlignTy = EltType; 38906c3fb27SDimitry Andric } 39006c3fb27SDimitry Andric 39106c3fb27SDimitry Andric if (AlignTy) 39206c3fb27SDimitry Andric return CharUnits::fromQuantity(AlignTy->isVectorType() ? 16 : 4); 39306c3fb27SDimitry Andric return CharUnits::fromQuantity(4); 39406c3fb27SDimitry Andric } 39506c3fb27SDimitry Andric 39606c3fb27SDimitry Andric ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const { 39706c3fb27SDimitry Andric uint64_t Size; 39806c3fb27SDimitry Andric 39906c3fb27SDimitry Andric // -msvr4-struct-return puts small aggregates in GPR3 and GPR4. 40006c3fb27SDimitry Andric if (isAggregateTypeForABI(RetTy) && IsRetSmallStructInRegABI && 40106c3fb27SDimitry Andric (Size = getContext().getTypeSize(RetTy)) <= 64) { 40206c3fb27SDimitry Andric // System V ABI (1995), page 3-22, specified: 40306c3fb27SDimitry Andric // > A structure or union whose size is less than or equal to 8 bytes 40406c3fb27SDimitry Andric // > shall be returned in r3 and r4, as if it were first stored in the 40506c3fb27SDimitry Andric // > 8-byte aligned memory area and then the low addressed word were 40606c3fb27SDimitry Andric // > loaded into r3 and the high-addressed word into r4. Bits beyond 40706c3fb27SDimitry Andric // > the last member of the structure or union are not defined. 40806c3fb27SDimitry Andric // 40906c3fb27SDimitry Andric // GCC for big-endian PPC32 inserts the pad before the first member, 41006c3fb27SDimitry Andric // not "beyond the last member" of the struct. To stay compatible 41106c3fb27SDimitry Andric // with GCC, we coerce the struct to an integer of the same size. 41206c3fb27SDimitry Andric // LLVM will extend it and return i32 in r3, or i64 in r3:r4. 41306c3fb27SDimitry Andric if (Size == 0) 41406c3fb27SDimitry Andric return ABIArgInfo::getIgnore(); 41506c3fb27SDimitry Andric else { 41606c3fb27SDimitry Andric llvm::Type *CoerceTy = llvm::Type::getIntNTy(getVMContext(), Size); 41706c3fb27SDimitry Andric return ABIArgInfo::getDirect(CoerceTy); 41806c3fb27SDimitry Andric } 41906c3fb27SDimitry Andric } 42006c3fb27SDimitry Andric 42106c3fb27SDimitry Andric return DefaultABIInfo::classifyReturnType(RetTy); 42206c3fb27SDimitry Andric } 42306c3fb27SDimitry Andric 42406c3fb27SDimitry Andric // TODO: this implementation is now likely redundant with 42506c3fb27SDimitry Andric // DefaultABIInfo::EmitVAArg. 426*0fca6ea1SDimitry Andric RValue PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, 427*0fca6ea1SDimitry Andric QualType Ty, AggValueSlot Slot) const { 42806c3fb27SDimitry Andric if (getTarget().getTriple().isOSDarwin()) { 42906c3fb27SDimitry Andric auto TI = getContext().getTypeInfoInChars(Ty); 43006c3fb27SDimitry Andric TI.Align = getParamTypeAlignment(Ty); 43106c3fb27SDimitry Andric 43206c3fb27SDimitry Andric CharUnits SlotSize = CharUnits::fromQuantity(4); 43306c3fb27SDimitry Andric return emitVoidPtrVAArg(CGF, VAList, Ty, 43406c3fb27SDimitry Andric classifyArgumentType(Ty).isIndirect(), TI, SlotSize, 435*0fca6ea1SDimitry Andric /*AllowHigherAlign=*/true, Slot); 43606c3fb27SDimitry Andric } 43706c3fb27SDimitry Andric 43806c3fb27SDimitry Andric const unsigned OverflowLimit = 8; 43906c3fb27SDimitry Andric if (const ComplexType *CTy = Ty->getAs<ComplexType>()) { 44006c3fb27SDimitry Andric // TODO: Implement this. For now ignore. 44106c3fb27SDimitry Andric (void)CTy; 442*0fca6ea1SDimitry Andric return RValue::getAggregate(Address::invalid()); // FIXME? 44306c3fb27SDimitry Andric } 44406c3fb27SDimitry Andric 44506c3fb27SDimitry Andric // struct __va_list_tag { 44606c3fb27SDimitry Andric // unsigned char gpr; 44706c3fb27SDimitry Andric // unsigned char fpr; 44806c3fb27SDimitry Andric // unsigned short reserved; 44906c3fb27SDimitry Andric // void *overflow_arg_area; 45006c3fb27SDimitry Andric // void *reg_save_area; 45106c3fb27SDimitry Andric // }; 45206c3fb27SDimitry Andric 45306c3fb27SDimitry Andric bool isI64 = Ty->isIntegerType() && getContext().getTypeSize(Ty) == 64; 45406c3fb27SDimitry Andric bool isInt = !Ty->isFloatingType(); 45506c3fb27SDimitry Andric bool isF64 = Ty->isFloatingType() && getContext().getTypeSize(Ty) == 64; 45606c3fb27SDimitry Andric 45706c3fb27SDimitry Andric // All aggregates are passed indirectly? That doesn't seem consistent 45806c3fb27SDimitry Andric // with the argument-lowering code. 45906c3fb27SDimitry Andric bool isIndirect = isAggregateTypeForABI(Ty); 46006c3fb27SDimitry Andric 46106c3fb27SDimitry Andric CGBuilderTy &Builder = CGF.Builder; 46206c3fb27SDimitry Andric 46306c3fb27SDimitry Andric // The calling convention either uses 1-2 GPRs or 1 FPR. 46406c3fb27SDimitry Andric Address NumRegsAddr = Address::invalid(); 46506c3fb27SDimitry Andric if (isInt || IsSoftFloatABI) { 46606c3fb27SDimitry Andric NumRegsAddr = Builder.CreateStructGEP(VAList, 0, "gpr"); 46706c3fb27SDimitry Andric } else { 46806c3fb27SDimitry Andric NumRegsAddr = Builder.CreateStructGEP(VAList, 1, "fpr"); 46906c3fb27SDimitry Andric } 47006c3fb27SDimitry Andric 47106c3fb27SDimitry Andric llvm::Value *NumRegs = Builder.CreateLoad(NumRegsAddr, "numUsedRegs"); 47206c3fb27SDimitry Andric 47306c3fb27SDimitry Andric // "Align" the register count when TY is i64. 47406c3fb27SDimitry Andric if (isI64 || (isF64 && IsSoftFloatABI)) { 47506c3fb27SDimitry Andric NumRegs = Builder.CreateAdd(NumRegs, Builder.getInt8(1)); 47606c3fb27SDimitry Andric NumRegs = Builder.CreateAnd(NumRegs, Builder.getInt8((uint8_t) ~1U)); 47706c3fb27SDimitry Andric } 47806c3fb27SDimitry Andric 47906c3fb27SDimitry Andric llvm::Value *CC = 48006c3fb27SDimitry Andric Builder.CreateICmpULT(NumRegs, Builder.getInt8(OverflowLimit), "cond"); 48106c3fb27SDimitry Andric 48206c3fb27SDimitry Andric llvm::BasicBlock *UsingRegs = CGF.createBasicBlock("using_regs"); 48306c3fb27SDimitry Andric llvm::BasicBlock *UsingOverflow = CGF.createBasicBlock("using_overflow"); 48406c3fb27SDimitry Andric llvm::BasicBlock *Cont = CGF.createBasicBlock("cont"); 48506c3fb27SDimitry Andric 48606c3fb27SDimitry Andric Builder.CreateCondBr(CC, UsingRegs, UsingOverflow); 48706c3fb27SDimitry Andric 48806c3fb27SDimitry Andric llvm::Type *DirectTy = CGF.ConvertType(Ty), *ElementTy = DirectTy; 48906c3fb27SDimitry Andric if (isIndirect) 4905f757f3fSDimitry Andric DirectTy = CGF.UnqualPtrTy; 49106c3fb27SDimitry Andric 49206c3fb27SDimitry Andric // Case 1: consume registers. 49306c3fb27SDimitry Andric Address RegAddr = Address::invalid(); 49406c3fb27SDimitry Andric { 49506c3fb27SDimitry Andric CGF.EmitBlock(UsingRegs); 49606c3fb27SDimitry Andric 49706c3fb27SDimitry Andric Address RegSaveAreaPtr = Builder.CreateStructGEP(VAList, 4); 49806c3fb27SDimitry Andric RegAddr = Address(Builder.CreateLoad(RegSaveAreaPtr), CGF.Int8Ty, 49906c3fb27SDimitry Andric CharUnits::fromQuantity(8)); 50006c3fb27SDimitry Andric assert(RegAddr.getElementType() == CGF.Int8Ty); 50106c3fb27SDimitry Andric 50206c3fb27SDimitry Andric // Floating-point registers start after the general-purpose registers. 50306c3fb27SDimitry Andric if (!(isInt || IsSoftFloatABI)) { 50406c3fb27SDimitry Andric RegAddr = Builder.CreateConstInBoundsByteGEP(RegAddr, 50506c3fb27SDimitry Andric CharUnits::fromQuantity(32)); 50606c3fb27SDimitry Andric } 50706c3fb27SDimitry Andric 50806c3fb27SDimitry Andric // Get the address of the saved value by scaling the number of 50906c3fb27SDimitry Andric // registers we've used by the number of 51006c3fb27SDimitry Andric CharUnits RegSize = CharUnits::fromQuantity((isInt || IsSoftFloatABI) ? 4 : 8); 51106c3fb27SDimitry Andric llvm::Value *RegOffset = 51206c3fb27SDimitry Andric Builder.CreateMul(NumRegs, Builder.getInt8(RegSize.getQuantity())); 513*0fca6ea1SDimitry Andric RegAddr = Address(Builder.CreateInBoundsGEP( 514*0fca6ea1SDimitry Andric CGF.Int8Ty, RegAddr.emitRawPointer(CGF), RegOffset), 515*0fca6ea1SDimitry Andric DirectTy, 516*0fca6ea1SDimitry Andric RegAddr.getAlignment().alignmentOfArrayElement(RegSize)); 51706c3fb27SDimitry Andric 51806c3fb27SDimitry Andric // Increase the used-register count. 51906c3fb27SDimitry Andric NumRegs = 52006c3fb27SDimitry Andric Builder.CreateAdd(NumRegs, 52106c3fb27SDimitry Andric Builder.getInt8((isI64 || (isF64 && IsSoftFloatABI)) ? 2 : 1)); 52206c3fb27SDimitry Andric Builder.CreateStore(NumRegs, NumRegsAddr); 52306c3fb27SDimitry Andric 52406c3fb27SDimitry Andric CGF.EmitBranch(Cont); 52506c3fb27SDimitry Andric } 52606c3fb27SDimitry Andric 52706c3fb27SDimitry Andric // Case 2: consume space in the overflow area. 52806c3fb27SDimitry Andric Address MemAddr = Address::invalid(); 52906c3fb27SDimitry Andric { 53006c3fb27SDimitry Andric CGF.EmitBlock(UsingOverflow); 53106c3fb27SDimitry Andric 53206c3fb27SDimitry Andric Builder.CreateStore(Builder.getInt8(OverflowLimit), NumRegsAddr); 53306c3fb27SDimitry Andric 53406c3fb27SDimitry Andric // Everything in the overflow area is rounded up to a size of at least 4. 53506c3fb27SDimitry Andric CharUnits OverflowAreaAlign = CharUnits::fromQuantity(4); 53606c3fb27SDimitry Andric 53706c3fb27SDimitry Andric CharUnits Size; 53806c3fb27SDimitry Andric if (!isIndirect) { 53906c3fb27SDimitry Andric auto TypeInfo = CGF.getContext().getTypeInfoInChars(Ty); 54006c3fb27SDimitry Andric Size = TypeInfo.Width.alignTo(OverflowAreaAlign); 54106c3fb27SDimitry Andric } else { 54206c3fb27SDimitry Andric Size = CGF.getPointerSize(); 54306c3fb27SDimitry Andric } 54406c3fb27SDimitry Andric 54506c3fb27SDimitry Andric Address OverflowAreaAddr = Builder.CreateStructGEP(VAList, 3); 54606c3fb27SDimitry Andric Address OverflowArea = 54706c3fb27SDimitry Andric Address(Builder.CreateLoad(OverflowAreaAddr, "argp.cur"), CGF.Int8Ty, 54806c3fb27SDimitry Andric OverflowAreaAlign); 54906c3fb27SDimitry Andric // Round up address of argument to alignment 55006c3fb27SDimitry Andric CharUnits Align = CGF.getContext().getTypeAlignInChars(Ty); 55106c3fb27SDimitry Andric if (Align > OverflowAreaAlign) { 552*0fca6ea1SDimitry Andric llvm::Value *Ptr = OverflowArea.emitRawPointer(CGF); 55306c3fb27SDimitry Andric OverflowArea = Address(emitRoundPointerUpToAlignment(CGF, Ptr, Align), 55406c3fb27SDimitry Andric OverflowArea.getElementType(), Align); 55506c3fb27SDimitry Andric } 55606c3fb27SDimitry Andric 55706c3fb27SDimitry Andric MemAddr = OverflowArea.withElementType(DirectTy); 55806c3fb27SDimitry Andric 55906c3fb27SDimitry Andric // Increase the overflow area. 56006c3fb27SDimitry Andric OverflowArea = Builder.CreateConstInBoundsByteGEP(OverflowArea, Size); 561*0fca6ea1SDimitry Andric Builder.CreateStore(OverflowArea.emitRawPointer(CGF), OverflowAreaAddr); 56206c3fb27SDimitry Andric CGF.EmitBranch(Cont); 56306c3fb27SDimitry Andric } 56406c3fb27SDimitry Andric 56506c3fb27SDimitry Andric CGF.EmitBlock(Cont); 56606c3fb27SDimitry Andric 56706c3fb27SDimitry Andric // Merge the cases with a phi. 56806c3fb27SDimitry Andric Address Result = emitMergePHI(CGF, RegAddr, UsingRegs, MemAddr, UsingOverflow, 56906c3fb27SDimitry Andric "vaarg.addr"); 57006c3fb27SDimitry Andric 57106c3fb27SDimitry Andric // Load the pointer if the argument was passed indirectly. 57206c3fb27SDimitry Andric if (isIndirect) { 57306c3fb27SDimitry Andric Result = Address(Builder.CreateLoad(Result, "aggr"), ElementTy, 57406c3fb27SDimitry Andric getContext().getTypeAlignInChars(Ty)); 57506c3fb27SDimitry Andric } 57606c3fb27SDimitry Andric 577*0fca6ea1SDimitry Andric return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Result, Ty), Slot); 57806c3fb27SDimitry Andric } 57906c3fb27SDimitry Andric 58006c3fb27SDimitry Andric bool PPC32TargetCodeGenInfo::isStructReturnInRegABI( 58106c3fb27SDimitry Andric const llvm::Triple &Triple, const CodeGenOptions &Opts) { 58206c3fb27SDimitry Andric assert(Triple.isPPC32()); 58306c3fb27SDimitry Andric 58406c3fb27SDimitry Andric switch (Opts.getStructReturnConvention()) { 58506c3fb27SDimitry Andric case CodeGenOptions::SRCK_Default: 58606c3fb27SDimitry Andric break; 58706c3fb27SDimitry Andric case CodeGenOptions::SRCK_OnStack: // -maix-struct-return 58806c3fb27SDimitry Andric return false; 58906c3fb27SDimitry Andric case CodeGenOptions::SRCK_InRegs: // -msvr4-struct-return 59006c3fb27SDimitry Andric return true; 59106c3fb27SDimitry Andric } 59206c3fb27SDimitry Andric 59306c3fb27SDimitry Andric if (Triple.isOSBinFormatELF() && !Triple.isOSLinux()) 59406c3fb27SDimitry Andric return true; 59506c3fb27SDimitry Andric 59606c3fb27SDimitry Andric return false; 59706c3fb27SDimitry Andric } 59806c3fb27SDimitry Andric 59906c3fb27SDimitry Andric bool 60006c3fb27SDimitry Andric PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 60106c3fb27SDimitry Andric llvm::Value *Address) const { 60206c3fb27SDimitry Andric return PPC_initDwarfEHRegSizeTable(CGF, Address, /*Is64Bit*/ false, 60306c3fb27SDimitry Andric /*IsAIX*/ false); 60406c3fb27SDimitry Andric } 60506c3fb27SDimitry Andric 60606c3fb27SDimitry Andric // PowerPC-64 60706c3fb27SDimitry Andric 60806c3fb27SDimitry Andric namespace { 60906c3fb27SDimitry Andric 61006c3fb27SDimitry Andric /// PPC64_SVR4_ABIInfo - The 64-bit PowerPC ELF (SVR4) ABI information. 61106c3fb27SDimitry Andric class PPC64_SVR4_ABIInfo : public ABIInfo { 61206c3fb27SDimitry Andric static const unsigned GPRBits = 64; 61306c3fb27SDimitry Andric PPC64_SVR4_ABIKind Kind; 61406c3fb27SDimitry Andric bool IsSoftFloatABI; 61506c3fb27SDimitry Andric 61606c3fb27SDimitry Andric public: 61706c3fb27SDimitry Andric PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, PPC64_SVR4_ABIKind Kind, 61806c3fb27SDimitry Andric bool SoftFloatABI) 61906c3fb27SDimitry Andric : ABIInfo(CGT), Kind(Kind), IsSoftFloatABI(SoftFloatABI) {} 62006c3fb27SDimitry Andric 62106c3fb27SDimitry Andric bool isPromotableTypeForABI(QualType Ty) const; 62206c3fb27SDimitry Andric CharUnits getParamTypeAlignment(QualType Ty) const; 62306c3fb27SDimitry Andric 62406c3fb27SDimitry Andric ABIArgInfo classifyReturnType(QualType RetTy) const; 62506c3fb27SDimitry Andric ABIArgInfo classifyArgumentType(QualType Ty) const; 62606c3fb27SDimitry Andric 62706c3fb27SDimitry Andric bool isHomogeneousAggregateBaseType(QualType Ty) const override; 62806c3fb27SDimitry Andric bool isHomogeneousAggregateSmallEnough(const Type *Ty, 62906c3fb27SDimitry Andric uint64_t Members) const override; 63006c3fb27SDimitry Andric 63106c3fb27SDimitry Andric // TODO: We can add more logic to computeInfo to improve performance. 63206c3fb27SDimitry Andric // Example: For aggregate arguments that fit in a register, we could 63306c3fb27SDimitry Andric // use getDirectInReg (as is done below for structs containing a single 63406c3fb27SDimitry Andric // floating-point value) to avoid pushing them to memory on function 63506c3fb27SDimitry Andric // entry. This would require changing the logic in PPCISelLowering 63606c3fb27SDimitry Andric // when lowering the parameters in the caller and args in the callee. 63706c3fb27SDimitry Andric void computeInfo(CGFunctionInfo &FI) const override { 63806c3fb27SDimitry Andric if (!getCXXABI().classifyReturnType(FI)) 63906c3fb27SDimitry Andric FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); 64006c3fb27SDimitry Andric for (auto &I : FI.arguments()) { 64106c3fb27SDimitry Andric // We rely on the default argument classification for the most part. 64206c3fb27SDimitry Andric // One exception: An aggregate containing a single floating-point 64306c3fb27SDimitry Andric // or vector item must be passed in a register if one is available. 64406c3fb27SDimitry Andric const Type *T = isSingleElementStruct(I.type, getContext()); 64506c3fb27SDimitry Andric if (T) { 64606c3fb27SDimitry Andric const BuiltinType *BT = T->getAs<BuiltinType>(); 64706c3fb27SDimitry Andric if ((T->isVectorType() && getContext().getTypeSize(T) == 128) || 64806c3fb27SDimitry Andric (BT && BT->isFloatingPoint())) { 64906c3fb27SDimitry Andric QualType QT(T, 0); 65006c3fb27SDimitry Andric I.info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT)); 65106c3fb27SDimitry Andric continue; 65206c3fb27SDimitry Andric } 65306c3fb27SDimitry Andric } 65406c3fb27SDimitry Andric I.info = classifyArgumentType(I.type); 65506c3fb27SDimitry Andric } 65606c3fb27SDimitry Andric } 65706c3fb27SDimitry Andric 658*0fca6ea1SDimitry Andric RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 659*0fca6ea1SDimitry Andric AggValueSlot Slot) const override; 66006c3fb27SDimitry Andric }; 66106c3fb27SDimitry Andric 66206c3fb27SDimitry Andric class PPC64_SVR4_TargetCodeGenInfo : public TargetCodeGenInfo { 66306c3fb27SDimitry Andric 66406c3fb27SDimitry Andric public: 66506c3fb27SDimitry Andric PPC64_SVR4_TargetCodeGenInfo(CodeGenTypes &CGT, PPC64_SVR4_ABIKind Kind, 66606c3fb27SDimitry Andric bool SoftFloatABI) 66706c3fb27SDimitry Andric : TargetCodeGenInfo( 66806c3fb27SDimitry Andric std::make_unique<PPC64_SVR4_ABIInfo>(CGT, Kind, SoftFloatABI)) { 66906c3fb27SDimitry Andric SwiftInfo = 67006c3fb27SDimitry Andric std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false); 67106c3fb27SDimitry Andric } 67206c3fb27SDimitry Andric 67306c3fb27SDimitry Andric int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { 67406c3fb27SDimitry Andric // This is recovered from gcc output. 67506c3fb27SDimitry Andric return 1; // r1 is the dedicated stack pointer 67606c3fb27SDimitry Andric } 67706c3fb27SDimitry Andric 67806c3fb27SDimitry Andric bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 67906c3fb27SDimitry Andric llvm::Value *Address) const override; 6805f757f3fSDimitry Andric void emitTargetMetadata(CodeGen::CodeGenModule &CGM, 6815f757f3fSDimitry Andric const llvm::MapVector<GlobalDecl, StringRef> 6825f757f3fSDimitry Andric &MangledDeclNames) const override; 68306c3fb27SDimitry Andric }; 68406c3fb27SDimitry Andric 68506c3fb27SDimitry Andric class PPC64TargetCodeGenInfo : public TargetCodeGenInfo { 68606c3fb27SDimitry Andric public: 68706c3fb27SDimitry Andric PPC64TargetCodeGenInfo(CodeGenTypes &CGT) 68806c3fb27SDimitry Andric : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {} 68906c3fb27SDimitry Andric 69006c3fb27SDimitry Andric int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { 69106c3fb27SDimitry Andric // This is recovered from gcc output. 69206c3fb27SDimitry Andric return 1; // r1 is the dedicated stack pointer 69306c3fb27SDimitry Andric } 69406c3fb27SDimitry Andric 69506c3fb27SDimitry Andric bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 69606c3fb27SDimitry Andric llvm::Value *Address) const override; 69706c3fb27SDimitry Andric }; 69806c3fb27SDimitry Andric } 69906c3fb27SDimitry Andric 70006c3fb27SDimitry Andric // Return true if the ABI requires Ty to be passed sign- or zero- 70106c3fb27SDimitry Andric // extended to 64 bits. 70206c3fb27SDimitry Andric bool 70306c3fb27SDimitry Andric PPC64_SVR4_ABIInfo::isPromotableTypeForABI(QualType Ty) const { 70406c3fb27SDimitry Andric // Treat an enum type as its underlying type. 70506c3fb27SDimitry Andric if (const EnumType *EnumTy = Ty->getAs<EnumType>()) 70606c3fb27SDimitry Andric Ty = EnumTy->getDecl()->getIntegerType(); 70706c3fb27SDimitry Andric 70806c3fb27SDimitry Andric // Promotable integer types are required to be promoted by the ABI. 70906c3fb27SDimitry Andric if (isPromotableIntegerTypeForABI(Ty)) 71006c3fb27SDimitry Andric return true; 71106c3fb27SDimitry Andric 71206c3fb27SDimitry Andric // In addition to the usual promotable integer types, we also need to 71306c3fb27SDimitry Andric // extend all 32-bit types, since the ABI requires promotion to 64 bits. 71406c3fb27SDimitry Andric if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) 71506c3fb27SDimitry Andric switch (BT->getKind()) { 71606c3fb27SDimitry Andric case BuiltinType::Int: 71706c3fb27SDimitry Andric case BuiltinType::UInt: 71806c3fb27SDimitry Andric return true; 71906c3fb27SDimitry Andric default: 72006c3fb27SDimitry Andric break; 72106c3fb27SDimitry Andric } 72206c3fb27SDimitry Andric 72306c3fb27SDimitry Andric if (const auto *EIT = Ty->getAs<BitIntType>()) 72406c3fb27SDimitry Andric if (EIT->getNumBits() < 64) 72506c3fb27SDimitry Andric return true; 72606c3fb27SDimitry Andric 72706c3fb27SDimitry Andric return false; 72806c3fb27SDimitry Andric } 72906c3fb27SDimitry Andric 73006c3fb27SDimitry Andric /// isAlignedParamType - Determine whether a type requires 16-byte or 73106c3fb27SDimitry Andric /// higher alignment in the parameter area. Always returns at least 8. 73206c3fb27SDimitry Andric CharUnits PPC64_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { 73306c3fb27SDimitry Andric // Complex types are passed just like their elements. 73406c3fb27SDimitry Andric if (const ComplexType *CTy = Ty->getAs<ComplexType>()) 73506c3fb27SDimitry Andric Ty = CTy->getElementType(); 73606c3fb27SDimitry Andric 73706c3fb27SDimitry Andric auto FloatUsesVector = [this](QualType Ty){ 73806c3fb27SDimitry Andric return Ty->isRealFloatingType() && &getContext().getFloatTypeSemantics( 73906c3fb27SDimitry Andric Ty) == &llvm::APFloat::IEEEquad(); 74006c3fb27SDimitry Andric }; 74106c3fb27SDimitry Andric 74206c3fb27SDimitry Andric // Only vector types of size 16 bytes need alignment (larger types are 74306c3fb27SDimitry Andric // passed via reference, smaller types are not aligned). 74406c3fb27SDimitry Andric if (Ty->isVectorType()) { 74506c3fb27SDimitry Andric return CharUnits::fromQuantity(getContext().getTypeSize(Ty) == 128 ? 16 : 8); 74606c3fb27SDimitry Andric } else if (FloatUsesVector(Ty)) { 74706c3fb27SDimitry Andric // According to ABI document section 'Optional Save Areas': If extended 74806c3fb27SDimitry Andric // precision floating-point values in IEEE BINARY 128 QUADRUPLE PRECISION 74906c3fb27SDimitry Andric // format are supported, map them to a single quadword, quadword aligned. 75006c3fb27SDimitry Andric return CharUnits::fromQuantity(16); 75106c3fb27SDimitry Andric } 75206c3fb27SDimitry Andric 75306c3fb27SDimitry Andric // For single-element float/vector structs, we consider the whole type 75406c3fb27SDimitry Andric // to have the same alignment requirements as its single element. 75506c3fb27SDimitry Andric const Type *AlignAsType = nullptr; 75606c3fb27SDimitry Andric const Type *EltType = isSingleElementStruct(Ty, getContext()); 75706c3fb27SDimitry Andric if (EltType) { 75806c3fb27SDimitry Andric const BuiltinType *BT = EltType->getAs<BuiltinType>(); 75906c3fb27SDimitry Andric if ((EltType->isVectorType() && getContext().getTypeSize(EltType) == 128) || 76006c3fb27SDimitry Andric (BT && BT->isFloatingPoint())) 76106c3fb27SDimitry Andric AlignAsType = EltType; 76206c3fb27SDimitry Andric } 76306c3fb27SDimitry Andric 76406c3fb27SDimitry Andric // Likewise for ELFv2 homogeneous aggregates. 76506c3fb27SDimitry Andric const Type *Base = nullptr; 76606c3fb27SDimitry Andric uint64_t Members = 0; 76706c3fb27SDimitry Andric if (!AlignAsType && Kind == PPC64_SVR4_ABIKind::ELFv2 && 76806c3fb27SDimitry Andric isAggregateTypeForABI(Ty) && isHomogeneousAggregate(Ty, Base, Members)) 76906c3fb27SDimitry Andric AlignAsType = Base; 77006c3fb27SDimitry Andric 77106c3fb27SDimitry Andric // With special case aggregates, only vector base types need alignment. 77206c3fb27SDimitry Andric if (AlignAsType) { 77306c3fb27SDimitry Andric bool UsesVector = AlignAsType->isVectorType() || 77406c3fb27SDimitry Andric FloatUsesVector(QualType(AlignAsType, 0)); 77506c3fb27SDimitry Andric return CharUnits::fromQuantity(UsesVector ? 16 : 8); 77606c3fb27SDimitry Andric } 77706c3fb27SDimitry Andric 77806c3fb27SDimitry Andric // Otherwise, we only need alignment for any aggregate type that 77906c3fb27SDimitry Andric // has an alignment requirement of >= 16 bytes. 78006c3fb27SDimitry Andric if (isAggregateTypeForABI(Ty) && getContext().getTypeAlign(Ty) >= 128) { 78106c3fb27SDimitry Andric return CharUnits::fromQuantity(16); 78206c3fb27SDimitry Andric } 78306c3fb27SDimitry Andric 78406c3fb27SDimitry Andric return CharUnits::fromQuantity(8); 78506c3fb27SDimitry Andric } 78606c3fb27SDimitry Andric 78706c3fb27SDimitry Andric bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { 78806c3fb27SDimitry Andric // Homogeneous aggregates for ELFv2 must have base types of float, 78906c3fb27SDimitry Andric // double, long double, or 128-bit vectors. 79006c3fb27SDimitry Andric if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { 79106c3fb27SDimitry Andric if (BT->getKind() == BuiltinType::Float || 79206c3fb27SDimitry Andric BT->getKind() == BuiltinType::Double || 79306c3fb27SDimitry Andric BT->getKind() == BuiltinType::LongDouble || 79406c3fb27SDimitry Andric BT->getKind() == BuiltinType::Ibm128 || 79506c3fb27SDimitry Andric (getContext().getTargetInfo().hasFloat128Type() && 79606c3fb27SDimitry Andric (BT->getKind() == BuiltinType::Float128))) { 79706c3fb27SDimitry Andric if (IsSoftFloatABI) 79806c3fb27SDimitry Andric return false; 79906c3fb27SDimitry Andric return true; 80006c3fb27SDimitry Andric } 80106c3fb27SDimitry Andric } 80206c3fb27SDimitry Andric if (const VectorType *VT = Ty->getAs<VectorType>()) { 80306c3fb27SDimitry Andric if (getContext().getTypeSize(VT) == 128) 80406c3fb27SDimitry Andric return true; 80506c3fb27SDimitry Andric } 80606c3fb27SDimitry Andric return false; 80706c3fb27SDimitry Andric } 80806c3fb27SDimitry Andric 80906c3fb27SDimitry Andric bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateSmallEnough( 81006c3fb27SDimitry Andric const Type *Base, uint64_t Members) const { 81106c3fb27SDimitry Andric // Vector and fp128 types require one register, other floating point types 81206c3fb27SDimitry Andric // require one or two registers depending on their size. 81306c3fb27SDimitry Andric uint32_t NumRegs = 81406c3fb27SDimitry Andric ((getContext().getTargetInfo().hasFloat128Type() && 81506c3fb27SDimitry Andric Base->isFloat128Type()) || 81606c3fb27SDimitry Andric Base->isVectorType()) ? 1 81706c3fb27SDimitry Andric : (getContext().getTypeSize(Base) + 63) / 64; 81806c3fb27SDimitry Andric 81906c3fb27SDimitry Andric // Homogeneous Aggregates may occupy at most 8 registers. 82006c3fb27SDimitry Andric return Members * NumRegs <= 8; 82106c3fb27SDimitry Andric } 82206c3fb27SDimitry Andric 82306c3fb27SDimitry Andric ABIArgInfo 82406c3fb27SDimitry Andric PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { 82506c3fb27SDimitry Andric Ty = useFirstFieldIfTransparentUnion(Ty); 82606c3fb27SDimitry Andric 82706c3fb27SDimitry Andric if (Ty->isAnyComplexType()) 82806c3fb27SDimitry Andric return ABIArgInfo::getDirect(); 82906c3fb27SDimitry Andric 83006c3fb27SDimitry Andric // Non-Altivec vector types are passed in GPRs (smaller than 16 bytes) 83106c3fb27SDimitry Andric // or via reference (larger than 16 bytes). 83206c3fb27SDimitry Andric if (Ty->isVectorType()) { 83306c3fb27SDimitry Andric uint64_t Size = getContext().getTypeSize(Ty); 83406c3fb27SDimitry Andric if (Size > 128) 83506c3fb27SDimitry Andric return getNaturalAlignIndirect(Ty, /*ByVal=*/false); 83606c3fb27SDimitry Andric else if (Size < 128) { 83706c3fb27SDimitry Andric llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size); 83806c3fb27SDimitry Andric return ABIArgInfo::getDirect(CoerceTy); 83906c3fb27SDimitry Andric } 84006c3fb27SDimitry Andric } 84106c3fb27SDimitry Andric 84206c3fb27SDimitry Andric if (const auto *EIT = Ty->getAs<BitIntType>()) 84306c3fb27SDimitry Andric if (EIT->getNumBits() > 128) 84406c3fb27SDimitry Andric return getNaturalAlignIndirect(Ty, /*ByVal=*/true); 84506c3fb27SDimitry Andric 84606c3fb27SDimitry Andric if (isAggregateTypeForABI(Ty)) { 84706c3fb27SDimitry Andric if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) 84806c3fb27SDimitry Andric return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); 84906c3fb27SDimitry Andric 85006c3fb27SDimitry Andric uint64_t ABIAlign = getParamTypeAlignment(Ty).getQuantity(); 85106c3fb27SDimitry Andric uint64_t TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity(); 85206c3fb27SDimitry Andric 85306c3fb27SDimitry Andric // ELFv2 homogeneous aggregates are passed as array types. 85406c3fb27SDimitry Andric const Type *Base = nullptr; 85506c3fb27SDimitry Andric uint64_t Members = 0; 85606c3fb27SDimitry Andric if (Kind == PPC64_SVR4_ABIKind::ELFv2 && 85706c3fb27SDimitry Andric isHomogeneousAggregate(Ty, Base, Members)) { 85806c3fb27SDimitry Andric llvm::Type *BaseTy = CGT.ConvertType(QualType(Base, 0)); 85906c3fb27SDimitry Andric llvm::Type *CoerceTy = llvm::ArrayType::get(BaseTy, Members); 86006c3fb27SDimitry Andric return ABIArgInfo::getDirect(CoerceTy); 86106c3fb27SDimitry Andric } 86206c3fb27SDimitry Andric 86306c3fb27SDimitry Andric // If an aggregate may end up fully in registers, we do not 86406c3fb27SDimitry Andric // use the ByVal method, but pass the aggregate as array. 86506c3fb27SDimitry Andric // This is usually beneficial since we avoid forcing the 86606c3fb27SDimitry Andric // back-end to store the argument to memory. 86706c3fb27SDimitry Andric uint64_t Bits = getContext().getTypeSize(Ty); 86806c3fb27SDimitry Andric if (Bits > 0 && Bits <= 8 * GPRBits) { 86906c3fb27SDimitry Andric llvm::Type *CoerceTy; 87006c3fb27SDimitry Andric 87106c3fb27SDimitry Andric // Types up to 8 bytes are passed as integer type (which will be 87206c3fb27SDimitry Andric // properly aligned in the argument save area doubleword). 87306c3fb27SDimitry Andric if (Bits <= GPRBits) 87406c3fb27SDimitry Andric CoerceTy = 87506c3fb27SDimitry Andric llvm::IntegerType::get(getVMContext(), llvm::alignTo(Bits, 8)); 87606c3fb27SDimitry Andric // Larger types are passed as arrays, with the base type selected 87706c3fb27SDimitry Andric // according to the required alignment in the save area. 87806c3fb27SDimitry Andric else { 87906c3fb27SDimitry Andric uint64_t RegBits = ABIAlign * 8; 88006c3fb27SDimitry Andric uint64_t NumRegs = llvm::alignTo(Bits, RegBits) / RegBits; 88106c3fb27SDimitry Andric llvm::Type *RegTy = llvm::IntegerType::get(getVMContext(), RegBits); 88206c3fb27SDimitry Andric CoerceTy = llvm::ArrayType::get(RegTy, NumRegs); 88306c3fb27SDimitry Andric } 88406c3fb27SDimitry Andric 88506c3fb27SDimitry Andric return ABIArgInfo::getDirect(CoerceTy); 88606c3fb27SDimitry Andric } 88706c3fb27SDimitry Andric 88806c3fb27SDimitry Andric // All other aggregates are passed ByVal. 88906c3fb27SDimitry Andric return ABIArgInfo::getIndirect(CharUnits::fromQuantity(ABIAlign), 89006c3fb27SDimitry Andric /*ByVal=*/true, 89106c3fb27SDimitry Andric /*Realign=*/TyAlign > ABIAlign); 89206c3fb27SDimitry Andric } 89306c3fb27SDimitry Andric 89406c3fb27SDimitry Andric return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) 89506c3fb27SDimitry Andric : ABIArgInfo::getDirect()); 89606c3fb27SDimitry Andric } 89706c3fb27SDimitry Andric 89806c3fb27SDimitry Andric ABIArgInfo 89906c3fb27SDimitry Andric PPC64_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const { 90006c3fb27SDimitry Andric if (RetTy->isVoidType()) 90106c3fb27SDimitry Andric return ABIArgInfo::getIgnore(); 90206c3fb27SDimitry Andric 90306c3fb27SDimitry Andric if (RetTy->isAnyComplexType()) 90406c3fb27SDimitry Andric return ABIArgInfo::getDirect(); 90506c3fb27SDimitry Andric 90606c3fb27SDimitry Andric // Non-Altivec vector types are returned in GPRs (smaller than 16 bytes) 90706c3fb27SDimitry Andric // or via reference (larger than 16 bytes). 90806c3fb27SDimitry Andric if (RetTy->isVectorType()) { 90906c3fb27SDimitry Andric uint64_t Size = getContext().getTypeSize(RetTy); 91006c3fb27SDimitry Andric if (Size > 128) 91106c3fb27SDimitry Andric return getNaturalAlignIndirect(RetTy); 91206c3fb27SDimitry Andric else if (Size < 128) { 91306c3fb27SDimitry Andric llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size); 91406c3fb27SDimitry Andric return ABIArgInfo::getDirect(CoerceTy); 91506c3fb27SDimitry Andric } 91606c3fb27SDimitry Andric } 91706c3fb27SDimitry Andric 91806c3fb27SDimitry Andric if (const auto *EIT = RetTy->getAs<BitIntType>()) 91906c3fb27SDimitry Andric if (EIT->getNumBits() > 128) 92006c3fb27SDimitry Andric return getNaturalAlignIndirect(RetTy, /*ByVal=*/false); 92106c3fb27SDimitry Andric 92206c3fb27SDimitry Andric if (isAggregateTypeForABI(RetTy)) { 92306c3fb27SDimitry Andric // ELFv2 homogeneous aggregates are returned as array types. 92406c3fb27SDimitry Andric const Type *Base = nullptr; 92506c3fb27SDimitry Andric uint64_t Members = 0; 92606c3fb27SDimitry Andric if (Kind == PPC64_SVR4_ABIKind::ELFv2 && 92706c3fb27SDimitry Andric isHomogeneousAggregate(RetTy, Base, Members)) { 92806c3fb27SDimitry Andric llvm::Type *BaseTy = CGT.ConvertType(QualType(Base, 0)); 92906c3fb27SDimitry Andric llvm::Type *CoerceTy = llvm::ArrayType::get(BaseTy, Members); 93006c3fb27SDimitry Andric return ABIArgInfo::getDirect(CoerceTy); 93106c3fb27SDimitry Andric } 93206c3fb27SDimitry Andric 93306c3fb27SDimitry Andric // ELFv2 small aggregates are returned in up to two registers. 93406c3fb27SDimitry Andric uint64_t Bits = getContext().getTypeSize(RetTy); 93506c3fb27SDimitry Andric if (Kind == PPC64_SVR4_ABIKind::ELFv2 && Bits <= 2 * GPRBits) { 93606c3fb27SDimitry Andric if (Bits == 0) 93706c3fb27SDimitry Andric return ABIArgInfo::getIgnore(); 93806c3fb27SDimitry Andric 93906c3fb27SDimitry Andric llvm::Type *CoerceTy; 94006c3fb27SDimitry Andric if (Bits > GPRBits) { 94106c3fb27SDimitry Andric CoerceTy = llvm::IntegerType::get(getVMContext(), GPRBits); 94206c3fb27SDimitry Andric CoerceTy = llvm::StructType::get(CoerceTy, CoerceTy); 94306c3fb27SDimitry Andric } else 94406c3fb27SDimitry Andric CoerceTy = 94506c3fb27SDimitry Andric llvm::IntegerType::get(getVMContext(), llvm::alignTo(Bits, 8)); 94606c3fb27SDimitry Andric return ABIArgInfo::getDirect(CoerceTy); 94706c3fb27SDimitry Andric } 94806c3fb27SDimitry Andric 94906c3fb27SDimitry Andric // All other aggregates are returned indirectly. 95006c3fb27SDimitry Andric return getNaturalAlignIndirect(RetTy); 95106c3fb27SDimitry Andric } 95206c3fb27SDimitry Andric 95306c3fb27SDimitry Andric return (isPromotableTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) 95406c3fb27SDimitry Andric : ABIArgInfo::getDirect()); 95506c3fb27SDimitry Andric } 95606c3fb27SDimitry Andric 95706c3fb27SDimitry Andric // Based on ARMABIInfo::EmitVAArg, adjusted for 64-bit machine. 958*0fca6ea1SDimitry Andric RValue PPC64_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 959*0fca6ea1SDimitry Andric QualType Ty, AggValueSlot Slot) const { 96006c3fb27SDimitry Andric auto TypeInfo = getContext().getTypeInfoInChars(Ty); 96106c3fb27SDimitry Andric TypeInfo.Align = getParamTypeAlignment(Ty); 96206c3fb27SDimitry Andric 96306c3fb27SDimitry Andric CharUnits SlotSize = CharUnits::fromQuantity(8); 96406c3fb27SDimitry Andric 96506c3fb27SDimitry Andric // If we have a complex type and the base type is smaller than 8 bytes, 96606c3fb27SDimitry Andric // the ABI calls for the real and imaginary parts to be right-adjusted 96706c3fb27SDimitry Andric // in separate doublewords. However, Clang expects us to produce a 96806c3fb27SDimitry Andric // pointer to a structure with the two parts packed tightly. So generate 96906c3fb27SDimitry Andric // loads of the real and imaginary parts relative to the va_list pointer, 97006c3fb27SDimitry Andric // and store them to a temporary structure. 97106c3fb27SDimitry Andric if (const ComplexType *CTy = Ty->getAs<ComplexType>()) { 97206c3fb27SDimitry Andric CharUnits EltSize = TypeInfo.Width / 2; 97306c3fb27SDimitry Andric if (EltSize < SlotSize) 97406c3fb27SDimitry Andric return complexTempStructure(CGF, VAListAddr, Ty, SlotSize, EltSize, CTy); 97506c3fb27SDimitry Andric } 97606c3fb27SDimitry Andric 97706c3fb27SDimitry Andric // Otherwise, just use the general rule. 97806c3fb27SDimitry Andric // 97906c3fb27SDimitry Andric // The PPC64 ABI passes some arguments in integer registers, even to variadic 98006c3fb27SDimitry Andric // functions. To allow va_list to use the simple "void*" representation, 98106c3fb27SDimitry Andric // variadic calls allocate space in the argument area for the integer argument 98206c3fb27SDimitry Andric // registers, and variadic functions spill their integer argument registers to 98306c3fb27SDimitry Andric // this area in their prologues. When aggregates smaller than a register are 98406c3fb27SDimitry Andric // passed this way, they are passed in the least significant bits of the 98506c3fb27SDimitry Andric // register, which means that after spilling on big-endian targets they will 98606c3fb27SDimitry Andric // be right-aligned in their argument slot. This is uncommon; for a variety of 98706c3fb27SDimitry Andric // reasons, other big-endian targets don't end up right-aligning aggregate 98806c3fb27SDimitry Andric // types this way, and so right-alignment only applies to fundamental types. 98906c3fb27SDimitry Andric // So on PPC64, we must force the use of right-alignment even for aggregates. 99006c3fb27SDimitry Andric return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo, 991*0fca6ea1SDimitry Andric SlotSize, /*AllowHigher*/ true, Slot, 99206c3fb27SDimitry Andric /*ForceRightAdjust*/ true); 99306c3fb27SDimitry Andric } 99406c3fb27SDimitry Andric 99506c3fb27SDimitry Andric bool 99606c3fb27SDimitry Andric PPC64_SVR4_TargetCodeGenInfo::initDwarfEHRegSizeTable( 99706c3fb27SDimitry Andric CodeGen::CodeGenFunction &CGF, 99806c3fb27SDimitry Andric llvm::Value *Address) const { 99906c3fb27SDimitry Andric return PPC_initDwarfEHRegSizeTable(CGF, Address, /*Is64Bit*/ true, 100006c3fb27SDimitry Andric /*IsAIX*/ false); 100106c3fb27SDimitry Andric } 100206c3fb27SDimitry Andric 10035f757f3fSDimitry Andric void PPC64_SVR4_TargetCodeGenInfo::emitTargetMetadata( 10045f757f3fSDimitry Andric CodeGen::CodeGenModule &CGM, 10055f757f3fSDimitry Andric const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames) const { 10065f757f3fSDimitry Andric if (CGM.getTypes().isLongDoubleReferenced()) { 10075f757f3fSDimitry Andric llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 10085f757f3fSDimitry Andric const auto *flt = &CGM.getTarget().getLongDoubleFormat(); 10095f757f3fSDimitry Andric if (flt == &llvm::APFloat::PPCDoubleDouble()) 10105f757f3fSDimitry Andric CGM.getModule().addModuleFlag(llvm::Module::Error, "float-abi", 10115f757f3fSDimitry Andric llvm::MDString::get(Ctx, "doubledouble")); 10125f757f3fSDimitry Andric else if (flt == &llvm::APFloat::IEEEquad()) 10135f757f3fSDimitry Andric CGM.getModule().addModuleFlag(llvm::Module::Error, "float-abi", 10145f757f3fSDimitry Andric llvm::MDString::get(Ctx, "ieeequad")); 10155f757f3fSDimitry Andric else if (flt == &llvm::APFloat::IEEEdouble()) 10165f757f3fSDimitry Andric CGM.getModule().addModuleFlag(llvm::Module::Error, "float-abi", 10175f757f3fSDimitry Andric llvm::MDString::get(Ctx, "ieeedouble")); 10185f757f3fSDimitry Andric } 10195f757f3fSDimitry Andric } 10205f757f3fSDimitry Andric 102106c3fb27SDimitry Andric bool 102206c3fb27SDimitry Andric PPC64TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 102306c3fb27SDimitry Andric llvm::Value *Address) const { 102406c3fb27SDimitry Andric return PPC_initDwarfEHRegSizeTable(CGF, Address, /*Is64Bit*/ true, 102506c3fb27SDimitry Andric /*IsAIX*/ false); 102606c3fb27SDimitry Andric } 102706c3fb27SDimitry Andric 102806c3fb27SDimitry Andric std::unique_ptr<TargetCodeGenInfo> 102906c3fb27SDimitry Andric CodeGen::createAIXTargetCodeGenInfo(CodeGenModule &CGM, bool Is64Bit) { 103006c3fb27SDimitry Andric return std::make_unique<AIXTargetCodeGenInfo>(CGM.getTypes(), Is64Bit); 103106c3fb27SDimitry Andric } 103206c3fb27SDimitry Andric 103306c3fb27SDimitry Andric std::unique_ptr<TargetCodeGenInfo> 103406c3fb27SDimitry Andric CodeGen::createPPC32TargetCodeGenInfo(CodeGenModule &CGM, bool SoftFloatABI) { 103506c3fb27SDimitry Andric bool RetSmallStructInRegABI = PPC32TargetCodeGenInfo::isStructReturnInRegABI( 103606c3fb27SDimitry Andric CGM.getTriple(), CGM.getCodeGenOpts()); 103706c3fb27SDimitry Andric return std::make_unique<PPC32TargetCodeGenInfo>(CGM.getTypes(), SoftFloatABI, 103806c3fb27SDimitry Andric RetSmallStructInRegABI); 103906c3fb27SDimitry Andric } 104006c3fb27SDimitry Andric 104106c3fb27SDimitry Andric std::unique_ptr<TargetCodeGenInfo> 104206c3fb27SDimitry Andric CodeGen::createPPC64TargetCodeGenInfo(CodeGenModule &CGM) { 104306c3fb27SDimitry Andric return std::make_unique<PPC64TargetCodeGenInfo>(CGM.getTypes()); 104406c3fb27SDimitry Andric } 104506c3fb27SDimitry Andric 104606c3fb27SDimitry Andric std::unique_ptr<TargetCodeGenInfo> CodeGen::createPPC64_SVR4_TargetCodeGenInfo( 104706c3fb27SDimitry Andric CodeGenModule &CGM, PPC64_SVR4_ABIKind Kind, bool SoftFloatABI) { 104806c3fb27SDimitry Andric return std::make_unique<PPC64_SVR4_TargetCodeGenInfo>(CGM.getTypes(), Kind, 104906c3fb27SDimitry Andric SoftFloatABI); 105006c3fb27SDimitry Andric } 1051