1992cb984SSergei Barannikov //===- PPC.cpp ------------------------------------------------------------===// 2992cb984SSergei Barannikov // 3992cb984SSergei Barannikov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4992cb984SSergei Barannikov // See https://llvm.org/LICENSE.txt for license information. 5992cb984SSergei Barannikov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6992cb984SSergei Barannikov // 7992cb984SSergei Barannikov //===----------------------------------------------------------------------===// 8992cb984SSergei Barannikov 9992cb984SSergei Barannikov #include "ABIInfoImpl.h" 10992cb984SSergei Barannikov #include "TargetInfo.h" 1137b5eb0aSZaara Syeda #include "clang/Basic/DiagnosticFrontend.h" 12992cb984SSergei Barannikov 13992cb984SSergei Barannikov using namespace clang; 14992cb984SSergei Barannikov using namespace clang::CodeGen; 15992cb984SSergei Barannikov 166d973b45SMariya Podchishchaeva static RValue complexTempStructure(CodeGenFunction &CGF, Address VAListAddr, 17992cb984SSergei Barannikov QualType Ty, CharUnits SlotSize, 18992cb984SSergei Barannikov CharUnits EltSize, const ComplexType *CTy) { 19992cb984SSergei Barannikov Address Addr = 20992cb984SSergei Barannikov emitVoidPtrDirectVAArg(CGF, VAListAddr, CGF.Int8Ty, SlotSize * 2, 21992cb984SSergei Barannikov SlotSize, SlotSize, /*AllowHigher*/ true); 22992cb984SSergei Barannikov 23992cb984SSergei Barannikov Address RealAddr = Addr; 24992cb984SSergei Barannikov Address ImagAddr = RealAddr; 25992cb984SSergei Barannikov if (CGF.CGM.getDataLayout().isBigEndian()) { 26992cb984SSergei Barannikov RealAddr = 27992cb984SSergei Barannikov CGF.Builder.CreateConstInBoundsByteGEP(RealAddr, SlotSize - EltSize); 28992cb984SSergei Barannikov ImagAddr = CGF.Builder.CreateConstInBoundsByteGEP(ImagAddr, 29992cb984SSergei Barannikov 2 * SlotSize - EltSize); 30992cb984SSergei Barannikov } else { 31992cb984SSergei Barannikov ImagAddr = CGF.Builder.CreateConstInBoundsByteGEP(RealAddr, SlotSize); 32992cb984SSergei Barannikov } 33992cb984SSergei Barannikov 34992cb984SSergei Barannikov llvm::Type *EltTy = CGF.ConvertTypeForMem(CTy->getElementType()); 35474ec694SYoungsuk Kim RealAddr = RealAddr.withElementType(EltTy); 36474ec694SYoungsuk Kim ImagAddr = ImagAddr.withElementType(EltTy); 37992cb984SSergei Barannikov llvm::Value *Real = CGF.Builder.CreateLoad(RealAddr, ".vareal"); 38992cb984SSergei Barannikov llvm::Value *Imag = CGF.Builder.CreateLoad(ImagAddr, ".vaimag"); 39992cb984SSergei Barannikov 406d973b45SMariya Podchishchaeva return RValue::getComplex(Real, Imag); 41992cb984SSergei Barannikov } 42992cb984SSergei Barannikov 43992cb984SSergei Barannikov static bool PPC_initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 44992cb984SSergei Barannikov llvm::Value *Address, bool Is64Bit, 45992cb984SSergei Barannikov bool IsAIX) { 46992cb984SSergei Barannikov // This is calculated from the LLVM and GCC tables and verified 47992cb984SSergei Barannikov // against gcc output. AFAIK all PPC ABIs use the same encoding. 48992cb984SSergei Barannikov 49992cb984SSergei Barannikov CodeGen::CGBuilderTy &Builder = CGF.Builder; 50992cb984SSergei Barannikov 51992cb984SSergei Barannikov llvm::IntegerType *i8 = CGF.Int8Ty; 52992cb984SSergei Barannikov llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4); 53992cb984SSergei Barannikov llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8); 54992cb984SSergei Barannikov llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16); 55992cb984SSergei Barannikov 56992cb984SSergei Barannikov // 0-31: r0-31, the 4-byte or 8-byte general-purpose registers 57992cb984SSergei Barannikov AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 0, 31); 58992cb984SSergei Barannikov 59992cb984SSergei Barannikov // 32-63: fp0-31, the 8-byte floating-point registers 60992cb984SSergei Barannikov AssignToArrayRange(Builder, Address, Eight8, 32, 63); 61992cb984SSergei Barannikov 62992cb984SSergei Barannikov // 64-67 are various 4-byte or 8-byte special-purpose registers: 63992cb984SSergei Barannikov // 64: mq 64992cb984SSergei Barannikov // 65: lr 65992cb984SSergei Barannikov // 66: ctr 66992cb984SSergei Barannikov // 67: ap 67992cb984SSergei Barannikov AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 64, 67); 68992cb984SSergei Barannikov 69992cb984SSergei Barannikov // 68-76 are various 4-byte special-purpose registers: 70992cb984SSergei Barannikov // 68-75 cr0-7 71992cb984SSergei Barannikov // 76: xer 72992cb984SSergei Barannikov AssignToArrayRange(Builder, Address, Four8, 68, 76); 73992cb984SSergei Barannikov 74992cb984SSergei Barannikov // 77-108: v0-31, the 16-byte vector registers 75992cb984SSergei Barannikov AssignToArrayRange(Builder, Address, Sixteen8, 77, 108); 76992cb984SSergei Barannikov 77992cb984SSergei Barannikov // 109: vrsave 78992cb984SSergei Barannikov // 110: vscr 79992cb984SSergei Barannikov AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 109, 110); 80992cb984SSergei Barannikov 81992cb984SSergei Barannikov // AIX does not utilize the rest of the registers. 82992cb984SSergei Barannikov if (IsAIX) 83992cb984SSergei Barannikov return false; 84992cb984SSergei Barannikov 85992cb984SSergei Barannikov // 111: spe_acc 86992cb984SSergei Barannikov // 112: spefscr 87992cb984SSergei Barannikov // 113: sfp 88992cb984SSergei Barannikov AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 111, 113); 89992cb984SSergei Barannikov 90992cb984SSergei Barannikov if (!Is64Bit) 91992cb984SSergei Barannikov return false; 92992cb984SSergei Barannikov 93992cb984SSergei Barannikov // TODO: Need to verify if these registers are used on 64 bit AIX with Power8 94992cb984SSergei Barannikov // or above CPU. 95992cb984SSergei Barannikov // 64-bit only registers: 96992cb984SSergei Barannikov // 114: tfhar 97992cb984SSergei Barannikov // 115: tfiar 98992cb984SSergei Barannikov // 116: texasr 99992cb984SSergei Barannikov AssignToArrayRange(Builder, Address, Eight8, 114, 116); 100992cb984SSergei Barannikov 101992cb984SSergei Barannikov return false; 102992cb984SSergei Barannikov } 103992cb984SSergei Barannikov 104992cb984SSergei Barannikov // AIX 105992cb984SSergei Barannikov namespace { 106992cb984SSergei Barannikov /// AIXABIInfo - The AIX XCOFF ABI information. 107992cb984SSergei Barannikov class AIXABIInfo : public ABIInfo { 108992cb984SSergei Barannikov const bool Is64Bit; 109992cb984SSergei Barannikov const unsigned PtrByteSize; 110992cb984SSergei Barannikov CharUnits getParamTypeAlignment(QualType Ty) const; 111992cb984SSergei Barannikov 112992cb984SSergei Barannikov public: 113992cb984SSergei Barannikov AIXABIInfo(CodeGen::CodeGenTypes &CGT, bool Is64Bit) 114992cb984SSergei Barannikov : ABIInfo(CGT), Is64Bit(Is64Bit), PtrByteSize(Is64Bit ? 8 : 4) {} 115992cb984SSergei Barannikov 116992cb984SSergei Barannikov bool isPromotableTypeForABI(QualType Ty) const; 117992cb984SSergei Barannikov 118992cb984SSergei Barannikov ABIArgInfo classifyReturnType(QualType RetTy) const; 119992cb984SSergei Barannikov ABIArgInfo classifyArgumentType(QualType Ty) const; 120992cb984SSergei Barannikov 121992cb984SSergei Barannikov void computeInfo(CGFunctionInfo &FI) const override { 122992cb984SSergei Barannikov if (!getCXXABI().classifyReturnType(FI)) 123992cb984SSergei Barannikov FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); 124992cb984SSergei Barannikov 125992cb984SSergei Barannikov for (auto &I : FI.arguments()) 126992cb984SSergei Barannikov I.info = classifyArgumentType(I.type); 127992cb984SSergei Barannikov } 128992cb984SSergei Barannikov 1296d973b45SMariya Podchishchaeva RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 1306d973b45SMariya Podchishchaeva AggValueSlot Slot) const override; 131992cb984SSergei Barannikov }; 132992cb984SSergei Barannikov 133992cb984SSergei Barannikov class AIXTargetCodeGenInfo : public TargetCodeGenInfo { 134992cb984SSergei Barannikov const bool Is64Bit; 135992cb984SSergei Barannikov 136992cb984SSergei Barannikov public: 137992cb984SSergei Barannikov AIXTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool Is64Bit) 138992cb984SSergei Barannikov : TargetCodeGenInfo(std::make_unique<AIXABIInfo>(CGT, Is64Bit)), 139992cb984SSergei Barannikov Is64Bit(Is64Bit) {} 140992cb984SSergei Barannikov int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { 141992cb984SSergei Barannikov return 1; // r1 is the dedicated stack pointer 142992cb984SSergei Barannikov } 143992cb984SSergei Barannikov 144992cb984SSergei Barannikov bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 145992cb984SSergei Barannikov llvm::Value *Address) const override; 14637b5eb0aSZaara Syeda 14737b5eb0aSZaara Syeda void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, 14837b5eb0aSZaara Syeda CodeGen::CodeGenModule &M) const override; 149992cb984SSergei Barannikov }; 150992cb984SSergei Barannikov } // namespace 151992cb984SSergei Barannikov 152992cb984SSergei Barannikov // Return true if the ABI requires Ty to be passed sign- or zero- 153992cb984SSergei Barannikov // extended to 32/64 bits. 154992cb984SSergei Barannikov bool AIXABIInfo::isPromotableTypeForABI(QualType Ty) const { 155992cb984SSergei Barannikov // Treat an enum type as its underlying type. 156992cb984SSergei Barannikov if (const EnumType *EnumTy = Ty->getAs<EnumType>()) 157992cb984SSergei Barannikov Ty = EnumTy->getDecl()->getIntegerType(); 158992cb984SSergei Barannikov 159992cb984SSergei Barannikov // Promotable integer types are required to be promoted by the ABI. 160992cb984SSergei Barannikov if (getContext().isPromotableIntegerType(Ty)) 161992cb984SSergei Barannikov return true; 162992cb984SSergei Barannikov 163992cb984SSergei Barannikov if (!Is64Bit) 164992cb984SSergei Barannikov return false; 165992cb984SSergei Barannikov 166992cb984SSergei Barannikov // For 64 bit mode, in addition to the usual promotable integer types, we also 167992cb984SSergei Barannikov // need to extend all 32-bit types, since the ABI requires promotion to 64 168992cb984SSergei Barannikov // bits. 169992cb984SSergei Barannikov if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) 170992cb984SSergei Barannikov switch (BT->getKind()) { 171992cb984SSergei Barannikov case BuiltinType::Int: 172992cb984SSergei Barannikov case BuiltinType::UInt: 173992cb984SSergei Barannikov return true; 174992cb984SSergei Barannikov default: 175992cb984SSergei Barannikov break; 176992cb984SSergei Barannikov } 177992cb984SSergei Barannikov 178992cb984SSergei Barannikov return false; 179992cb984SSergei Barannikov } 180992cb984SSergei Barannikov 181992cb984SSergei Barannikov ABIArgInfo AIXABIInfo::classifyReturnType(QualType RetTy) const { 182992cb984SSergei Barannikov if (RetTy->isAnyComplexType()) 183992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 184992cb984SSergei Barannikov 185992cb984SSergei Barannikov if (RetTy->isVectorType()) 186992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 187992cb984SSergei Barannikov 188992cb984SSergei Barannikov if (RetTy->isVoidType()) 189992cb984SSergei Barannikov return ABIArgInfo::getIgnore(); 190992cb984SSergei Barannikov 191992cb984SSergei Barannikov if (isAggregateTypeForABI(RetTy)) 192992cb984SSergei Barannikov return getNaturalAlignIndirect(RetTy); 193992cb984SSergei Barannikov 194992cb984SSergei Barannikov return (isPromotableTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) 195992cb984SSergei Barannikov : ABIArgInfo::getDirect()); 196992cb984SSergei Barannikov } 197992cb984SSergei Barannikov 198992cb984SSergei Barannikov ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const { 199992cb984SSergei Barannikov Ty = useFirstFieldIfTransparentUnion(Ty); 200992cb984SSergei Barannikov 201992cb984SSergei Barannikov if (Ty->isAnyComplexType()) 202992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 203992cb984SSergei Barannikov 204992cb984SSergei Barannikov if (Ty->isVectorType()) 205992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 206992cb984SSergei Barannikov 207992cb984SSergei Barannikov if (isAggregateTypeForABI(Ty)) { 208992cb984SSergei Barannikov // Records with non-trivial destructors/copy-constructors should not be 209992cb984SSergei Barannikov // passed by value. 210992cb984SSergei Barannikov if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) 211992cb984SSergei Barannikov return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); 212992cb984SSergei Barannikov 213992cb984SSergei Barannikov CharUnits CCAlign = getParamTypeAlignment(Ty); 214992cb984SSergei Barannikov CharUnits TyAlign = getContext().getTypeAlignInChars(Ty); 215992cb984SSergei Barannikov 216992cb984SSergei Barannikov return ABIArgInfo::getIndirect(CCAlign, /*ByVal*/ true, 217992cb984SSergei Barannikov /*Realign*/ TyAlign > CCAlign); 218992cb984SSergei Barannikov } 219992cb984SSergei Barannikov 220*f95026dbSLei Huang return (isPromotableTypeForABI(Ty) 221*f95026dbSLei Huang ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)) 222992cb984SSergei Barannikov : ABIArgInfo::getDirect()); 223992cb984SSergei Barannikov } 224992cb984SSergei Barannikov 225992cb984SSergei Barannikov CharUnits AIXABIInfo::getParamTypeAlignment(QualType Ty) const { 226992cb984SSergei Barannikov // Complex types are passed just like their elements. 227992cb984SSergei Barannikov if (const ComplexType *CTy = Ty->getAs<ComplexType>()) 228992cb984SSergei Barannikov Ty = CTy->getElementType(); 229992cb984SSergei Barannikov 230992cb984SSergei Barannikov if (Ty->isVectorType()) 231992cb984SSergei Barannikov return CharUnits::fromQuantity(16); 232992cb984SSergei Barannikov 233992cb984SSergei Barannikov // If the structure contains a vector type, the alignment is 16. 234992cb984SSergei Barannikov if (isRecordWithSIMDVectorType(getContext(), Ty)) 235992cb984SSergei Barannikov return CharUnits::fromQuantity(16); 236992cb984SSergei Barannikov 237992cb984SSergei Barannikov return CharUnits::fromQuantity(PtrByteSize); 238992cb984SSergei Barannikov } 239992cb984SSergei Barannikov 2406d973b45SMariya Podchishchaeva RValue AIXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 2416d973b45SMariya Podchishchaeva QualType Ty, AggValueSlot Slot) const { 242992cb984SSergei Barannikov 243992cb984SSergei Barannikov auto TypeInfo = getContext().getTypeInfoInChars(Ty); 244992cb984SSergei Barannikov TypeInfo.Align = getParamTypeAlignment(Ty); 245992cb984SSergei Barannikov 246992cb984SSergei Barannikov CharUnits SlotSize = CharUnits::fromQuantity(PtrByteSize); 247992cb984SSergei Barannikov 248992cb984SSergei Barannikov // If we have a complex type and the base type is smaller than the register 249992cb984SSergei Barannikov // size, the ABI calls for the real and imaginary parts to be right-adjusted 250992cb984SSergei Barannikov // in separate words in 32bit mode or doublewords in 64bit mode. However, 251992cb984SSergei Barannikov // Clang expects us to produce a pointer to a structure with the two parts 252992cb984SSergei Barannikov // packed tightly. So generate loads of the real and imaginary parts relative 253992cb984SSergei Barannikov // to the va_list pointer, and store them to a temporary structure. We do the 254992cb984SSergei Barannikov // same as the PPC64ABI here. 255992cb984SSergei Barannikov if (const ComplexType *CTy = Ty->getAs<ComplexType>()) { 256992cb984SSergei Barannikov CharUnits EltSize = TypeInfo.Width / 2; 257992cb984SSergei Barannikov if (EltSize < SlotSize) 258992cb984SSergei Barannikov return complexTempStructure(CGF, VAListAddr, Ty, SlotSize, EltSize, CTy); 259992cb984SSergei Barannikov } 260992cb984SSergei Barannikov 261992cb984SSergei Barannikov return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo, 2626d973b45SMariya Podchishchaeva SlotSize, /*AllowHigher*/ true, Slot); 263992cb984SSergei Barannikov } 264992cb984SSergei Barannikov 265992cb984SSergei Barannikov bool AIXTargetCodeGenInfo::initDwarfEHRegSizeTable( 266992cb984SSergei Barannikov CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const { 267992cb984SSergei Barannikov return PPC_initDwarfEHRegSizeTable(CGF, Address, Is64Bit, /*IsAIX*/ true); 268992cb984SSergei Barannikov } 269992cb984SSergei Barannikov 27037b5eb0aSZaara Syeda void AIXTargetCodeGenInfo::setTargetAttributes( 27137b5eb0aSZaara Syeda const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const { 27237b5eb0aSZaara Syeda if (!isa<llvm::GlobalVariable>(GV)) 27337b5eb0aSZaara Syeda return; 27437b5eb0aSZaara Syeda 2751095f71bSsmanna12 auto *GVar = cast<llvm::GlobalVariable>(GV); 27637b5eb0aSZaara Syeda auto GVId = GV->getName(); 27737b5eb0aSZaara Syeda 27837b5eb0aSZaara Syeda // Is this a global variable specified by the user as toc-data? 27937b5eb0aSZaara Syeda bool UserSpecifiedTOC = 28037b5eb0aSZaara Syeda llvm::binary_search(M.getCodeGenOpts().TocDataVarsUserSpecified, GVId); 28137b5eb0aSZaara Syeda // Assumes the same variable cannot be in both TocVarsUserSpecified and 28237b5eb0aSZaara Syeda // NoTocVars. 28337b5eb0aSZaara Syeda if (UserSpecifiedTOC || 28437b5eb0aSZaara Syeda ((M.getCodeGenOpts().AllTocData) && 28537b5eb0aSZaara Syeda !llvm::binary_search(M.getCodeGenOpts().NoTocDataVars, GVId))) { 28637b5eb0aSZaara Syeda const unsigned long PointerSize = 28737b5eb0aSZaara Syeda GV->getParent()->getDataLayout().getPointerSizeInBits() / 8; 28837b5eb0aSZaara Syeda auto *VarD = dyn_cast<VarDecl>(D); 28937b5eb0aSZaara Syeda assert(VarD && "Invalid declaration of global variable."); 29037b5eb0aSZaara Syeda 29137b5eb0aSZaara Syeda ASTContext &Context = D->getASTContext(); 29237b5eb0aSZaara Syeda unsigned Alignment = Context.toBits(Context.getDeclAlign(D)) / 8; 29337b5eb0aSZaara Syeda const auto *Ty = VarD->getType().getTypePtr(); 29437b5eb0aSZaara Syeda const RecordDecl *RDecl = 29537b5eb0aSZaara Syeda Ty->isRecordType() ? Ty->getAs<RecordType>()->getDecl() : nullptr; 29637b5eb0aSZaara Syeda 29737b5eb0aSZaara Syeda bool EmitDiagnostic = UserSpecifiedTOC && GV->hasExternalLinkage(); 29837b5eb0aSZaara Syeda auto reportUnsupportedWarning = [&](bool ShouldEmitWarning, StringRef Msg) { 29937b5eb0aSZaara Syeda if (ShouldEmitWarning) 30037b5eb0aSZaara Syeda M.getDiags().Report(D->getLocation(), diag::warn_toc_unsupported_type) 30137b5eb0aSZaara Syeda << GVId << Msg; 30237b5eb0aSZaara Syeda }; 30337b5eb0aSZaara Syeda if (!Ty || Ty->isIncompleteType()) 30437b5eb0aSZaara Syeda reportUnsupportedWarning(EmitDiagnostic, "of incomplete type"); 30537b5eb0aSZaara Syeda else if (RDecl && RDecl->hasFlexibleArrayMember()) 30637b5eb0aSZaara Syeda reportUnsupportedWarning(EmitDiagnostic, 30737b5eb0aSZaara Syeda "it contains a flexible array member"); 30837b5eb0aSZaara Syeda else if (VarD->getTLSKind() != VarDecl::TLS_None) 30937b5eb0aSZaara Syeda reportUnsupportedWarning(EmitDiagnostic, "of thread local storage"); 31037b5eb0aSZaara Syeda else if (PointerSize < Context.getTypeInfo(VarD->getType()).Width / 8) 31137b5eb0aSZaara Syeda reportUnsupportedWarning(EmitDiagnostic, 31237b5eb0aSZaara Syeda "variable is larger than a pointer"); 31337b5eb0aSZaara Syeda else if (PointerSize < Alignment) 31437b5eb0aSZaara Syeda reportUnsupportedWarning(EmitDiagnostic, 31537b5eb0aSZaara Syeda "variable is aligned wider than a pointer"); 31637b5eb0aSZaara Syeda else if (D->hasAttr<SectionAttr>()) 31737b5eb0aSZaara Syeda reportUnsupportedWarning(EmitDiagnostic, 31837b5eb0aSZaara Syeda "variable has a section attribute"); 31937b5eb0aSZaara Syeda else if (GV->hasExternalLinkage() || 32037b5eb0aSZaara Syeda (M.getCodeGenOpts().AllTocData && !GV->hasLocalLinkage())) 32137b5eb0aSZaara Syeda GVar->addAttribute("toc-data"); 32237b5eb0aSZaara Syeda } 32337b5eb0aSZaara Syeda } 32437b5eb0aSZaara Syeda 325992cb984SSergei Barannikov // PowerPC-32 326992cb984SSergei Barannikov namespace { 327992cb984SSergei Barannikov /// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information. 328992cb984SSergei Barannikov class PPC32_SVR4_ABIInfo : public DefaultABIInfo { 329992cb984SSergei Barannikov bool IsSoftFloatABI; 330992cb984SSergei Barannikov bool IsRetSmallStructInRegABI; 331992cb984SSergei Barannikov 332992cb984SSergei Barannikov CharUnits getParamTypeAlignment(QualType Ty) const; 333992cb984SSergei Barannikov 334992cb984SSergei Barannikov public: 335992cb984SSergei Barannikov PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI, 336992cb984SSergei Barannikov bool RetSmallStructInRegABI) 337992cb984SSergei Barannikov : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI), 338992cb984SSergei Barannikov IsRetSmallStructInRegABI(RetSmallStructInRegABI) {} 339992cb984SSergei Barannikov 340992cb984SSergei Barannikov ABIArgInfo classifyReturnType(QualType RetTy) const; 341992cb984SSergei Barannikov 342992cb984SSergei Barannikov void computeInfo(CGFunctionInfo &FI) const override { 343992cb984SSergei Barannikov if (!getCXXABI().classifyReturnType(FI)) 344992cb984SSergei Barannikov FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); 345992cb984SSergei Barannikov for (auto &I : FI.arguments()) 346992cb984SSergei Barannikov I.info = classifyArgumentType(I.type); 347992cb984SSergei Barannikov } 348992cb984SSergei Barannikov 3496d973b45SMariya Podchishchaeva RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 3506d973b45SMariya Podchishchaeva AggValueSlot Slot) const override; 351992cb984SSergei Barannikov }; 352992cb984SSergei Barannikov 353992cb984SSergei Barannikov class PPC32TargetCodeGenInfo : public TargetCodeGenInfo { 354992cb984SSergei Barannikov public: 355992cb984SSergei Barannikov PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI, 356992cb984SSergei Barannikov bool RetSmallStructInRegABI) 357992cb984SSergei Barannikov : TargetCodeGenInfo(std::make_unique<PPC32_SVR4_ABIInfo>( 358992cb984SSergei Barannikov CGT, SoftFloatABI, RetSmallStructInRegABI)) {} 359992cb984SSergei Barannikov 360992cb984SSergei Barannikov static bool isStructReturnInRegABI(const llvm::Triple &Triple, 361992cb984SSergei Barannikov const CodeGenOptions &Opts); 362992cb984SSergei Barannikov 363992cb984SSergei Barannikov int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { 364992cb984SSergei Barannikov // This is recovered from gcc output. 365992cb984SSergei Barannikov return 1; // r1 is the dedicated stack pointer 366992cb984SSergei Barannikov } 367992cb984SSergei Barannikov 368992cb984SSergei Barannikov bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 369992cb984SSergei Barannikov llvm::Value *Address) const override; 370992cb984SSergei Barannikov }; 371992cb984SSergei Barannikov } 372992cb984SSergei Barannikov 373992cb984SSergei Barannikov CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { 374992cb984SSergei Barannikov // Complex types are passed just like their elements. 375992cb984SSergei Barannikov if (const ComplexType *CTy = Ty->getAs<ComplexType>()) 376992cb984SSergei Barannikov Ty = CTy->getElementType(); 377992cb984SSergei Barannikov 378992cb984SSergei Barannikov if (Ty->isVectorType()) 379992cb984SSergei Barannikov return CharUnits::fromQuantity(getContext().getTypeSize(Ty) == 128 ? 16 380992cb984SSergei Barannikov : 4); 381992cb984SSergei Barannikov 382992cb984SSergei Barannikov // For single-element float/vector structs, we consider the whole type 383992cb984SSergei Barannikov // to have the same alignment requirements as its single element. 384992cb984SSergei Barannikov const Type *AlignTy = nullptr; 385992cb984SSergei Barannikov if (const Type *EltType = isSingleElementStruct(Ty, getContext())) { 386992cb984SSergei Barannikov const BuiltinType *BT = EltType->getAs<BuiltinType>(); 387992cb984SSergei Barannikov if ((EltType->isVectorType() && getContext().getTypeSize(EltType) == 128) || 388992cb984SSergei Barannikov (BT && BT->isFloatingPoint())) 389992cb984SSergei Barannikov AlignTy = EltType; 390992cb984SSergei Barannikov } 391992cb984SSergei Barannikov 392992cb984SSergei Barannikov if (AlignTy) 393992cb984SSergei Barannikov return CharUnits::fromQuantity(AlignTy->isVectorType() ? 16 : 4); 394992cb984SSergei Barannikov return CharUnits::fromQuantity(4); 395992cb984SSergei Barannikov } 396992cb984SSergei Barannikov 397992cb984SSergei Barannikov ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const { 398992cb984SSergei Barannikov uint64_t Size; 399992cb984SSergei Barannikov 400992cb984SSergei Barannikov // -msvr4-struct-return puts small aggregates in GPR3 and GPR4. 401992cb984SSergei Barannikov if (isAggregateTypeForABI(RetTy) && IsRetSmallStructInRegABI && 402992cb984SSergei Barannikov (Size = getContext().getTypeSize(RetTy)) <= 64) { 403992cb984SSergei Barannikov // System V ABI (1995), page 3-22, specified: 404992cb984SSergei Barannikov // > A structure or union whose size is less than or equal to 8 bytes 405992cb984SSergei Barannikov // > shall be returned in r3 and r4, as if it were first stored in the 406992cb984SSergei Barannikov // > 8-byte aligned memory area and then the low addressed word were 407992cb984SSergei Barannikov // > loaded into r3 and the high-addressed word into r4. Bits beyond 408992cb984SSergei Barannikov // > the last member of the structure or union are not defined. 409992cb984SSergei Barannikov // 410992cb984SSergei Barannikov // GCC for big-endian PPC32 inserts the pad before the first member, 411992cb984SSergei Barannikov // not "beyond the last member" of the struct. To stay compatible 412992cb984SSergei Barannikov // with GCC, we coerce the struct to an integer of the same size. 413992cb984SSergei Barannikov // LLVM will extend it and return i32 in r3, or i64 in r3:r4. 414992cb984SSergei Barannikov if (Size == 0) 415992cb984SSergei Barannikov return ABIArgInfo::getIgnore(); 416992cb984SSergei Barannikov else { 417992cb984SSergei Barannikov llvm::Type *CoerceTy = llvm::Type::getIntNTy(getVMContext(), Size); 418992cb984SSergei Barannikov return ABIArgInfo::getDirect(CoerceTy); 419992cb984SSergei Barannikov } 420992cb984SSergei Barannikov } 421992cb984SSergei Barannikov 422992cb984SSergei Barannikov return DefaultABIInfo::classifyReturnType(RetTy); 423992cb984SSergei Barannikov } 424992cb984SSergei Barannikov 425992cb984SSergei Barannikov // TODO: this implementation is now likely redundant with 426992cb984SSergei Barannikov // DefaultABIInfo::EmitVAArg. 4276d973b45SMariya Podchishchaeva RValue PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, 4286d973b45SMariya Podchishchaeva QualType Ty, AggValueSlot Slot) const { 429992cb984SSergei Barannikov if (getTarget().getTriple().isOSDarwin()) { 430992cb984SSergei Barannikov auto TI = getContext().getTypeInfoInChars(Ty); 431992cb984SSergei Barannikov TI.Align = getParamTypeAlignment(Ty); 432992cb984SSergei Barannikov 433992cb984SSergei Barannikov CharUnits SlotSize = CharUnits::fromQuantity(4); 434992cb984SSergei Barannikov return emitVoidPtrVAArg(CGF, VAList, Ty, 435992cb984SSergei Barannikov classifyArgumentType(Ty).isIndirect(), TI, SlotSize, 4366d973b45SMariya Podchishchaeva /*AllowHigherAlign=*/true, Slot); 437992cb984SSergei Barannikov } 438992cb984SSergei Barannikov 439992cb984SSergei Barannikov const unsigned OverflowLimit = 8; 440992cb984SSergei Barannikov if (const ComplexType *CTy = Ty->getAs<ComplexType>()) { 441992cb984SSergei Barannikov // TODO: Implement this. For now ignore. 442992cb984SSergei Barannikov (void)CTy; 4436d973b45SMariya Podchishchaeva return RValue::getAggregate(Address::invalid()); // FIXME? 444992cb984SSergei Barannikov } 445992cb984SSergei Barannikov 446992cb984SSergei Barannikov // struct __va_list_tag { 447992cb984SSergei Barannikov // unsigned char gpr; 448992cb984SSergei Barannikov // unsigned char fpr; 449992cb984SSergei Barannikov // unsigned short reserved; 450992cb984SSergei Barannikov // void *overflow_arg_area; 451992cb984SSergei Barannikov // void *reg_save_area; 452992cb984SSergei Barannikov // }; 453992cb984SSergei Barannikov 454992cb984SSergei Barannikov bool isI64 = Ty->isIntegerType() && getContext().getTypeSize(Ty) == 64; 455992cb984SSergei Barannikov bool isInt = !Ty->isFloatingType(); 456992cb984SSergei Barannikov bool isF64 = Ty->isFloatingType() && getContext().getTypeSize(Ty) == 64; 457992cb984SSergei Barannikov 458992cb984SSergei Barannikov // All aggregates are passed indirectly? That doesn't seem consistent 459992cb984SSergei Barannikov // with the argument-lowering code. 460992cb984SSergei Barannikov bool isIndirect = isAggregateTypeForABI(Ty); 461992cb984SSergei Barannikov 462992cb984SSergei Barannikov CGBuilderTy &Builder = CGF.Builder; 463992cb984SSergei Barannikov 464992cb984SSergei Barannikov // The calling convention either uses 1-2 GPRs or 1 FPR. 465992cb984SSergei Barannikov Address NumRegsAddr = Address::invalid(); 466992cb984SSergei Barannikov if (isInt || IsSoftFloatABI) { 467992cb984SSergei Barannikov NumRegsAddr = Builder.CreateStructGEP(VAList, 0, "gpr"); 468992cb984SSergei Barannikov } else { 469992cb984SSergei Barannikov NumRegsAddr = Builder.CreateStructGEP(VAList, 1, "fpr"); 470992cb984SSergei Barannikov } 471992cb984SSergei Barannikov 472992cb984SSergei Barannikov llvm::Value *NumRegs = Builder.CreateLoad(NumRegsAddr, "numUsedRegs"); 473992cb984SSergei Barannikov 474992cb984SSergei Barannikov // "Align" the register count when TY is i64. 475992cb984SSergei Barannikov if (isI64 || (isF64 && IsSoftFloatABI)) { 476992cb984SSergei Barannikov NumRegs = Builder.CreateAdd(NumRegs, Builder.getInt8(1)); 477992cb984SSergei Barannikov NumRegs = Builder.CreateAnd(NumRegs, Builder.getInt8((uint8_t) ~1U)); 478992cb984SSergei Barannikov } 479992cb984SSergei Barannikov 480992cb984SSergei Barannikov llvm::Value *CC = 481992cb984SSergei Barannikov Builder.CreateICmpULT(NumRegs, Builder.getInt8(OverflowLimit), "cond"); 482992cb984SSergei Barannikov 483992cb984SSergei Barannikov llvm::BasicBlock *UsingRegs = CGF.createBasicBlock("using_regs"); 484992cb984SSergei Barannikov llvm::BasicBlock *UsingOverflow = CGF.createBasicBlock("using_overflow"); 485992cb984SSergei Barannikov llvm::BasicBlock *Cont = CGF.createBasicBlock("cont"); 486992cb984SSergei Barannikov 487992cb984SSergei Barannikov Builder.CreateCondBr(CC, UsingRegs, UsingOverflow); 488992cb984SSergei Barannikov 489992cb984SSergei Barannikov llvm::Type *DirectTy = CGF.ConvertType(Ty), *ElementTy = DirectTy; 490992cb984SSergei Barannikov if (isIndirect) 491b4858c63SBjörn Pettersson DirectTy = CGF.UnqualPtrTy; 492992cb984SSergei Barannikov 493992cb984SSergei Barannikov // Case 1: consume registers. 494992cb984SSergei Barannikov Address RegAddr = Address::invalid(); 495992cb984SSergei Barannikov { 496992cb984SSergei Barannikov CGF.EmitBlock(UsingRegs); 497992cb984SSergei Barannikov 498992cb984SSergei Barannikov Address RegSaveAreaPtr = Builder.CreateStructGEP(VAList, 4); 499992cb984SSergei Barannikov RegAddr = Address(Builder.CreateLoad(RegSaveAreaPtr), CGF.Int8Ty, 500992cb984SSergei Barannikov CharUnits::fromQuantity(8)); 501992cb984SSergei Barannikov assert(RegAddr.getElementType() == CGF.Int8Ty); 502992cb984SSergei Barannikov 503992cb984SSergei Barannikov // Floating-point registers start after the general-purpose registers. 504992cb984SSergei Barannikov if (!(isInt || IsSoftFloatABI)) { 505992cb984SSergei Barannikov RegAddr = Builder.CreateConstInBoundsByteGEP(RegAddr, 506992cb984SSergei Barannikov CharUnits::fromQuantity(32)); 507992cb984SSergei Barannikov } 508992cb984SSergei Barannikov 509992cb984SSergei Barannikov // Get the address of the saved value by scaling the number of 510992cb984SSergei Barannikov // registers we've used by the number of 511992cb984SSergei Barannikov CharUnits RegSize = CharUnits::fromQuantity((isInt || IsSoftFloatABI) ? 4 : 8); 512992cb984SSergei Barannikov llvm::Value *RegOffset = 513992cb984SSergei Barannikov Builder.CreateMul(NumRegs, Builder.getInt8(RegSize.getQuantity())); 51484780af4SAkira Hatanaka RegAddr = Address(Builder.CreateInBoundsGEP( 51584780af4SAkira Hatanaka CGF.Int8Ty, RegAddr.emitRawPointer(CGF), RegOffset), 51684780af4SAkira Hatanaka DirectTy, 51784780af4SAkira Hatanaka RegAddr.getAlignment().alignmentOfArrayElement(RegSize)); 518992cb984SSergei Barannikov 519992cb984SSergei Barannikov // Increase the used-register count. 520992cb984SSergei Barannikov NumRegs = 521992cb984SSergei Barannikov Builder.CreateAdd(NumRegs, 522992cb984SSergei Barannikov Builder.getInt8((isI64 || (isF64 && IsSoftFloatABI)) ? 2 : 1)); 523992cb984SSergei Barannikov Builder.CreateStore(NumRegs, NumRegsAddr); 524992cb984SSergei Barannikov 525992cb984SSergei Barannikov CGF.EmitBranch(Cont); 526992cb984SSergei Barannikov } 527992cb984SSergei Barannikov 528992cb984SSergei Barannikov // Case 2: consume space in the overflow area. 529992cb984SSergei Barannikov Address MemAddr = Address::invalid(); 530992cb984SSergei Barannikov { 531992cb984SSergei Barannikov CGF.EmitBlock(UsingOverflow); 532992cb984SSergei Barannikov 533992cb984SSergei Barannikov Builder.CreateStore(Builder.getInt8(OverflowLimit), NumRegsAddr); 534992cb984SSergei Barannikov 535992cb984SSergei Barannikov // Everything in the overflow area is rounded up to a size of at least 4. 536992cb984SSergei Barannikov CharUnits OverflowAreaAlign = CharUnits::fromQuantity(4); 537992cb984SSergei Barannikov 538992cb984SSergei Barannikov CharUnits Size; 539992cb984SSergei Barannikov if (!isIndirect) { 540992cb984SSergei Barannikov auto TypeInfo = CGF.getContext().getTypeInfoInChars(Ty); 541992cb984SSergei Barannikov Size = TypeInfo.Width.alignTo(OverflowAreaAlign); 542992cb984SSergei Barannikov } else { 543992cb984SSergei Barannikov Size = CGF.getPointerSize(); 544992cb984SSergei Barannikov } 545992cb984SSergei Barannikov 546992cb984SSergei Barannikov Address OverflowAreaAddr = Builder.CreateStructGEP(VAList, 3); 547992cb984SSergei Barannikov Address OverflowArea = 548992cb984SSergei Barannikov Address(Builder.CreateLoad(OverflowAreaAddr, "argp.cur"), CGF.Int8Ty, 549992cb984SSergei Barannikov OverflowAreaAlign); 550992cb984SSergei Barannikov // Round up address of argument to alignment 551992cb984SSergei Barannikov CharUnits Align = CGF.getContext().getTypeAlignInChars(Ty); 552992cb984SSergei Barannikov if (Align > OverflowAreaAlign) { 55384780af4SAkira Hatanaka llvm::Value *Ptr = OverflowArea.emitRawPointer(CGF); 554992cb984SSergei Barannikov OverflowArea = Address(emitRoundPointerUpToAlignment(CGF, Ptr, Align), 555992cb984SSergei Barannikov OverflowArea.getElementType(), Align); 556992cb984SSergei Barannikov } 557992cb984SSergei Barannikov 558474ec694SYoungsuk Kim MemAddr = OverflowArea.withElementType(DirectTy); 559992cb984SSergei Barannikov 560992cb984SSergei Barannikov // Increase the overflow area. 561992cb984SSergei Barannikov OverflowArea = Builder.CreateConstInBoundsByteGEP(OverflowArea, Size); 56284780af4SAkira Hatanaka Builder.CreateStore(OverflowArea.emitRawPointer(CGF), OverflowAreaAddr); 563992cb984SSergei Barannikov CGF.EmitBranch(Cont); 564992cb984SSergei Barannikov } 565992cb984SSergei Barannikov 566992cb984SSergei Barannikov CGF.EmitBlock(Cont); 567992cb984SSergei Barannikov 568992cb984SSergei Barannikov // Merge the cases with a phi. 569992cb984SSergei Barannikov Address Result = emitMergePHI(CGF, RegAddr, UsingRegs, MemAddr, UsingOverflow, 570992cb984SSergei Barannikov "vaarg.addr"); 571992cb984SSergei Barannikov 572992cb984SSergei Barannikov // Load the pointer if the argument was passed indirectly. 573992cb984SSergei Barannikov if (isIndirect) { 574992cb984SSergei Barannikov Result = Address(Builder.CreateLoad(Result, "aggr"), ElementTy, 575992cb984SSergei Barannikov getContext().getTypeAlignInChars(Ty)); 576992cb984SSergei Barannikov } 577992cb984SSergei Barannikov 5786d973b45SMariya Podchishchaeva return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Result, Ty), Slot); 579992cb984SSergei Barannikov } 580992cb984SSergei Barannikov 581992cb984SSergei Barannikov bool PPC32TargetCodeGenInfo::isStructReturnInRegABI( 582992cb984SSergei Barannikov const llvm::Triple &Triple, const CodeGenOptions &Opts) { 583992cb984SSergei Barannikov assert(Triple.isPPC32()); 584992cb984SSergei Barannikov 585992cb984SSergei Barannikov switch (Opts.getStructReturnConvention()) { 586992cb984SSergei Barannikov case CodeGenOptions::SRCK_Default: 587992cb984SSergei Barannikov break; 588992cb984SSergei Barannikov case CodeGenOptions::SRCK_OnStack: // -maix-struct-return 589992cb984SSergei Barannikov return false; 590992cb984SSergei Barannikov case CodeGenOptions::SRCK_InRegs: // -msvr4-struct-return 591992cb984SSergei Barannikov return true; 592992cb984SSergei Barannikov } 593992cb984SSergei Barannikov 594992cb984SSergei Barannikov if (Triple.isOSBinFormatELF() && !Triple.isOSLinux()) 595992cb984SSergei Barannikov return true; 596992cb984SSergei Barannikov 597992cb984SSergei Barannikov return false; 598992cb984SSergei Barannikov } 599992cb984SSergei Barannikov 600992cb984SSergei Barannikov bool 601992cb984SSergei Barannikov PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 602992cb984SSergei Barannikov llvm::Value *Address) const { 603992cb984SSergei Barannikov return PPC_initDwarfEHRegSizeTable(CGF, Address, /*Is64Bit*/ false, 604992cb984SSergei Barannikov /*IsAIX*/ false); 605992cb984SSergei Barannikov } 606992cb984SSergei Barannikov 607992cb984SSergei Barannikov // PowerPC-64 608992cb984SSergei Barannikov 609992cb984SSergei Barannikov namespace { 610992cb984SSergei Barannikov 611992cb984SSergei Barannikov /// PPC64_SVR4_ABIInfo - The 64-bit PowerPC ELF (SVR4) ABI information. 612992cb984SSergei Barannikov class PPC64_SVR4_ABIInfo : public ABIInfo { 613992cb984SSergei Barannikov static const unsigned GPRBits = 64; 614992cb984SSergei Barannikov PPC64_SVR4_ABIKind Kind; 615992cb984SSergei Barannikov bool IsSoftFloatABI; 616992cb984SSergei Barannikov 617992cb984SSergei Barannikov public: 618992cb984SSergei Barannikov PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, PPC64_SVR4_ABIKind Kind, 619992cb984SSergei Barannikov bool SoftFloatABI) 620992cb984SSergei Barannikov : ABIInfo(CGT), Kind(Kind), IsSoftFloatABI(SoftFloatABI) {} 621992cb984SSergei Barannikov 622992cb984SSergei Barannikov bool isPromotableTypeForABI(QualType Ty) const; 623992cb984SSergei Barannikov CharUnits getParamTypeAlignment(QualType Ty) const; 624992cb984SSergei Barannikov 625992cb984SSergei Barannikov ABIArgInfo classifyReturnType(QualType RetTy) const; 626992cb984SSergei Barannikov ABIArgInfo classifyArgumentType(QualType Ty) const; 627992cb984SSergei Barannikov 628992cb984SSergei Barannikov bool isHomogeneousAggregateBaseType(QualType Ty) const override; 629992cb984SSergei Barannikov bool isHomogeneousAggregateSmallEnough(const Type *Ty, 630992cb984SSergei Barannikov uint64_t Members) const override; 631992cb984SSergei Barannikov 632992cb984SSergei Barannikov // TODO: We can add more logic to computeInfo to improve performance. 633992cb984SSergei Barannikov // Example: For aggregate arguments that fit in a register, we could 634992cb984SSergei Barannikov // use getDirectInReg (as is done below for structs containing a single 635992cb984SSergei Barannikov // floating-point value) to avoid pushing them to memory on function 636992cb984SSergei Barannikov // entry. This would require changing the logic in PPCISelLowering 637992cb984SSergei Barannikov // when lowering the parameters in the caller and args in the callee. 638992cb984SSergei Barannikov void computeInfo(CGFunctionInfo &FI) const override { 639992cb984SSergei Barannikov if (!getCXXABI().classifyReturnType(FI)) 640992cb984SSergei Barannikov FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); 641992cb984SSergei Barannikov for (auto &I : FI.arguments()) { 642992cb984SSergei Barannikov // We rely on the default argument classification for the most part. 643992cb984SSergei Barannikov // One exception: An aggregate containing a single floating-point 644992cb984SSergei Barannikov // or vector item must be passed in a register if one is available. 645992cb984SSergei Barannikov const Type *T = isSingleElementStruct(I.type, getContext()); 646992cb984SSergei Barannikov if (T) { 647992cb984SSergei Barannikov const BuiltinType *BT = T->getAs<BuiltinType>(); 648992cb984SSergei Barannikov if ((T->isVectorType() && getContext().getTypeSize(T) == 128) || 649992cb984SSergei Barannikov (BT && BT->isFloatingPoint())) { 650992cb984SSergei Barannikov QualType QT(T, 0); 651992cb984SSergei Barannikov I.info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT)); 652992cb984SSergei Barannikov continue; 653992cb984SSergei Barannikov } 654992cb984SSergei Barannikov } 655992cb984SSergei Barannikov I.info = classifyArgumentType(I.type); 656992cb984SSergei Barannikov } 657992cb984SSergei Barannikov } 658992cb984SSergei Barannikov 6596d973b45SMariya Podchishchaeva RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 6606d973b45SMariya Podchishchaeva AggValueSlot Slot) const override; 661992cb984SSergei Barannikov }; 662992cb984SSergei Barannikov 663992cb984SSergei Barannikov class PPC64_SVR4_TargetCodeGenInfo : public TargetCodeGenInfo { 664992cb984SSergei Barannikov 665992cb984SSergei Barannikov public: 666992cb984SSergei Barannikov PPC64_SVR4_TargetCodeGenInfo(CodeGenTypes &CGT, PPC64_SVR4_ABIKind Kind, 667992cb984SSergei Barannikov bool SoftFloatABI) 668992cb984SSergei Barannikov : TargetCodeGenInfo( 669992cb984SSergei Barannikov std::make_unique<PPC64_SVR4_ABIInfo>(CGT, Kind, SoftFloatABI)) { 670992cb984SSergei Barannikov SwiftInfo = 671992cb984SSergei Barannikov std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false); 672992cb984SSergei Barannikov } 673992cb984SSergei Barannikov 674992cb984SSergei Barannikov int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { 675992cb984SSergei Barannikov // This is recovered from gcc output. 676992cb984SSergei Barannikov return 1; // r1 is the dedicated stack pointer 677992cb984SSergei Barannikov } 678992cb984SSergei Barannikov 679992cb984SSergei Barannikov bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 680992cb984SSergei Barannikov llvm::Value *Address) const override; 6813e97db89SQiu Chaofan void emitTargetMetadata(CodeGen::CodeGenModule &CGM, 6823e97db89SQiu Chaofan const llvm::MapVector<GlobalDecl, StringRef> 6833e97db89SQiu Chaofan &MangledDeclNames) const override; 684992cb984SSergei Barannikov }; 685992cb984SSergei Barannikov 686992cb984SSergei Barannikov class PPC64TargetCodeGenInfo : public TargetCodeGenInfo { 687992cb984SSergei Barannikov public: 688992cb984SSergei Barannikov PPC64TargetCodeGenInfo(CodeGenTypes &CGT) 689992cb984SSergei Barannikov : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {} 690992cb984SSergei Barannikov 691992cb984SSergei Barannikov int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { 692992cb984SSergei Barannikov // This is recovered from gcc output. 693992cb984SSergei Barannikov return 1; // r1 is the dedicated stack pointer 694992cb984SSergei Barannikov } 695992cb984SSergei Barannikov 696992cb984SSergei Barannikov bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 697992cb984SSergei Barannikov llvm::Value *Address) const override; 698992cb984SSergei Barannikov }; 699992cb984SSergei Barannikov } 700992cb984SSergei Barannikov 701992cb984SSergei Barannikov // Return true if the ABI requires Ty to be passed sign- or zero- 702992cb984SSergei Barannikov // extended to 64 bits. 703992cb984SSergei Barannikov bool 704992cb984SSergei Barannikov PPC64_SVR4_ABIInfo::isPromotableTypeForABI(QualType Ty) const { 705992cb984SSergei Barannikov // Treat an enum type as its underlying type. 706992cb984SSergei Barannikov if (const EnumType *EnumTy = Ty->getAs<EnumType>()) 707992cb984SSergei Barannikov Ty = EnumTy->getDecl()->getIntegerType(); 708992cb984SSergei Barannikov 709992cb984SSergei Barannikov // Promotable integer types are required to be promoted by the ABI. 710992cb984SSergei Barannikov if (isPromotableIntegerTypeForABI(Ty)) 711992cb984SSergei Barannikov return true; 712992cb984SSergei Barannikov 713992cb984SSergei Barannikov // In addition to the usual promotable integer types, we also need to 714992cb984SSergei Barannikov // extend all 32-bit types, since the ABI requires promotion to 64 bits. 715992cb984SSergei Barannikov if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) 716992cb984SSergei Barannikov switch (BT->getKind()) { 717992cb984SSergei Barannikov case BuiltinType::Int: 718992cb984SSergei Barannikov case BuiltinType::UInt: 719992cb984SSergei Barannikov return true; 720992cb984SSergei Barannikov default: 721992cb984SSergei Barannikov break; 722992cb984SSergei Barannikov } 723992cb984SSergei Barannikov 724992cb984SSergei Barannikov if (const auto *EIT = Ty->getAs<BitIntType>()) 725992cb984SSergei Barannikov if (EIT->getNumBits() < 64) 726992cb984SSergei Barannikov return true; 727992cb984SSergei Barannikov 728992cb984SSergei Barannikov return false; 729992cb984SSergei Barannikov } 730992cb984SSergei Barannikov 731992cb984SSergei Barannikov /// isAlignedParamType - Determine whether a type requires 16-byte or 732992cb984SSergei Barannikov /// higher alignment in the parameter area. Always returns at least 8. 733992cb984SSergei Barannikov CharUnits PPC64_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { 734992cb984SSergei Barannikov // Complex types are passed just like their elements. 735992cb984SSergei Barannikov if (const ComplexType *CTy = Ty->getAs<ComplexType>()) 736992cb984SSergei Barannikov Ty = CTy->getElementType(); 737992cb984SSergei Barannikov 738992cb984SSergei Barannikov auto FloatUsesVector = [this](QualType Ty){ 739992cb984SSergei Barannikov return Ty->isRealFloatingType() && &getContext().getFloatTypeSemantics( 740992cb984SSergei Barannikov Ty) == &llvm::APFloat::IEEEquad(); 741992cb984SSergei Barannikov }; 742992cb984SSergei Barannikov 743992cb984SSergei Barannikov // Only vector types of size 16 bytes need alignment (larger types are 744992cb984SSergei Barannikov // passed via reference, smaller types are not aligned). 745992cb984SSergei Barannikov if (Ty->isVectorType()) { 746992cb984SSergei Barannikov return CharUnits::fromQuantity(getContext().getTypeSize(Ty) == 128 ? 16 : 8); 747992cb984SSergei Barannikov } else if (FloatUsesVector(Ty)) { 748992cb984SSergei Barannikov // According to ABI document section 'Optional Save Areas': If extended 749992cb984SSergei Barannikov // precision floating-point values in IEEE BINARY 128 QUADRUPLE PRECISION 750992cb984SSergei Barannikov // format are supported, map them to a single quadword, quadword aligned. 751992cb984SSergei Barannikov return CharUnits::fromQuantity(16); 752992cb984SSergei Barannikov } 753992cb984SSergei Barannikov 754992cb984SSergei Barannikov // For single-element float/vector structs, we consider the whole type 755992cb984SSergei Barannikov // to have the same alignment requirements as its single element. 756992cb984SSergei Barannikov const Type *AlignAsType = nullptr; 757992cb984SSergei Barannikov const Type *EltType = isSingleElementStruct(Ty, getContext()); 758992cb984SSergei Barannikov if (EltType) { 759992cb984SSergei Barannikov const BuiltinType *BT = EltType->getAs<BuiltinType>(); 760992cb984SSergei Barannikov if ((EltType->isVectorType() && getContext().getTypeSize(EltType) == 128) || 761992cb984SSergei Barannikov (BT && BT->isFloatingPoint())) 762992cb984SSergei Barannikov AlignAsType = EltType; 763992cb984SSergei Barannikov } 764992cb984SSergei Barannikov 765992cb984SSergei Barannikov // Likewise for ELFv2 homogeneous aggregates. 766992cb984SSergei Barannikov const Type *Base = nullptr; 767992cb984SSergei Barannikov uint64_t Members = 0; 768992cb984SSergei Barannikov if (!AlignAsType && Kind == PPC64_SVR4_ABIKind::ELFv2 && 769992cb984SSergei Barannikov isAggregateTypeForABI(Ty) && isHomogeneousAggregate(Ty, Base, Members)) 770992cb984SSergei Barannikov AlignAsType = Base; 771992cb984SSergei Barannikov 772992cb984SSergei Barannikov // With special case aggregates, only vector base types need alignment. 773992cb984SSergei Barannikov if (AlignAsType) { 774992cb984SSergei Barannikov bool UsesVector = AlignAsType->isVectorType() || 775992cb984SSergei Barannikov FloatUsesVector(QualType(AlignAsType, 0)); 776992cb984SSergei Barannikov return CharUnits::fromQuantity(UsesVector ? 16 : 8); 777992cb984SSergei Barannikov } 778992cb984SSergei Barannikov 779992cb984SSergei Barannikov // Otherwise, we only need alignment for any aggregate type that 780992cb984SSergei Barannikov // has an alignment requirement of >= 16 bytes. 781992cb984SSergei Barannikov if (isAggregateTypeForABI(Ty) && getContext().getTypeAlign(Ty) >= 128) { 782992cb984SSergei Barannikov return CharUnits::fromQuantity(16); 783992cb984SSergei Barannikov } 784992cb984SSergei Barannikov 785992cb984SSergei Barannikov return CharUnits::fromQuantity(8); 786992cb984SSergei Barannikov } 787992cb984SSergei Barannikov 788992cb984SSergei Barannikov bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { 789992cb984SSergei Barannikov // Homogeneous aggregates for ELFv2 must have base types of float, 790992cb984SSergei Barannikov // double, long double, or 128-bit vectors. 791992cb984SSergei Barannikov if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { 792992cb984SSergei Barannikov if (BT->getKind() == BuiltinType::Float || 793992cb984SSergei Barannikov BT->getKind() == BuiltinType::Double || 794992cb984SSergei Barannikov BT->getKind() == BuiltinType::LongDouble || 795992cb984SSergei Barannikov BT->getKind() == BuiltinType::Ibm128 || 796992cb984SSergei Barannikov (getContext().getTargetInfo().hasFloat128Type() && 797992cb984SSergei Barannikov (BT->getKind() == BuiltinType::Float128))) { 798992cb984SSergei Barannikov if (IsSoftFloatABI) 799992cb984SSergei Barannikov return false; 800992cb984SSergei Barannikov return true; 801992cb984SSergei Barannikov } 802992cb984SSergei Barannikov } 803992cb984SSergei Barannikov if (const VectorType *VT = Ty->getAs<VectorType>()) { 804992cb984SSergei Barannikov if (getContext().getTypeSize(VT) == 128) 805992cb984SSergei Barannikov return true; 806992cb984SSergei Barannikov } 807992cb984SSergei Barannikov return false; 808992cb984SSergei Barannikov } 809992cb984SSergei Barannikov 810992cb984SSergei Barannikov bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateSmallEnough( 811992cb984SSergei Barannikov const Type *Base, uint64_t Members) const { 812992cb984SSergei Barannikov // Vector and fp128 types require one register, other floating point types 813992cb984SSergei Barannikov // require one or two registers depending on their size. 814992cb984SSergei Barannikov uint32_t NumRegs = 815992cb984SSergei Barannikov ((getContext().getTargetInfo().hasFloat128Type() && 816992cb984SSergei Barannikov Base->isFloat128Type()) || 817992cb984SSergei Barannikov Base->isVectorType()) ? 1 818992cb984SSergei Barannikov : (getContext().getTypeSize(Base) + 63) / 64; 819992cb984SSergei Barannikov 820992cb984SSergei Barannikov // Homogeneous Aggregates may occupy at most 8 registers. 821992cb984SSergei Barannikov return Members * NumRegs <= 8; 822992cb984SSergei Barannikov } 823992cb984SSergei Barannikov 824992cb984SSergei Barannikov ABIArgInfo 825992cb984SSergei Barannikov PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { 826992cb984SSergei Barannikov Ty = useFirstFieldIfTransparentUnion(Ty); 827992cb984SSergei Barannikov 828992cb984SSergei Barannikov if (Ty->isAnyComplexType()) 829992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 830992cb984SSergei Barannikov 831992cb984SSergei Barannikov // Non-Altivec vector types are passed in GPRs (smaller than 16 bytes) 832992cb984SSergei Barannikov // or via reference (larger than 16 bytes). 833992cb984SSergei Barannikov if (Ty->isVectorType()) { 834992cb984SSergei Barannikov uint64_t Size = getContext().getTypeSize(Ty); 835992cb984SSergei Barannikov if (Size > 128) 836992cb984SSergei Barannikov return getNaturalAlignIndirect(Ty, /*ByVal=*/false); 837992cb984SSergei Barannikov else if (Size < 128) { 838992cb984SSergei Barannikov llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size); 839992cb984SSergei Barannikov return ABIArgInfo::getDirect(CoerceTy); 840992cb984SSergei Barannikov } 841992cb984SSergei Barannikov } 842992cb984SSergei Barannikov 843992cb984SSergei Barannikov if (const auto *EIT = Ty->getAs<BitIntType>()) 844992cb984SSergei Barannikov if (EIT->getNumBits() > 128) 845992cb984SSergei Barannikov return getNaturalAlignIndirect(Ty, /*ByVal=*/true); 846992cb984SSergei Barannikov 847992cb984SSergei Barannikov if (isAggregateTypeForABI(Ty)) { 848992cb984SSergei Barannikov if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) 849992cb984SSergei Barannikov return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); 850992cb984SSergei Barannikov 851992cb984SSergei Barannikov uint64_t ABIAlign = getParamTypeAlignment(Ty).getQuantity(); 852992cb984SSergei Barannikov uint64_t TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity(); 853992cb984SSergei Barannikov 854992cb984SSergei Barannikov // ELFv2 homogeneous aggregates are passed as array types. 855992cb984SSergei Barannikov const Type *Base = nullptr; 856992cb984SSergei Barannikov uint64_t Members = 0; 857992cb984SSergei Barannikov if (Kind == PPC64_SVR4_ABIKind::ELFv2 && 858992cb984SSergei Barannikov isHomogeneousAggregate(Ty, Base, Members)) { 859992cb984SSergei Barannikov llvm::Type *BaseTy = CGT.ConvertType(QualType(Base, 0)); 860992cb984SSergei Barannikov llvm::Type *CoerceTy = llvm::ArrayType::get(BaseTy, Members); 861992cb984SSergei Barannikov return ABIArgInfo::getDirect(CoerceTy); 862992cb984SSergei Barannikov } 863992cb984SSergei Barannikov 864992cb984SSergei Barannikov // If an aggregate may end up fully in registers, we do not 865992cb984SSergei Barannikov // use the ByVal method, but pass the aggregate as array. 866992cb984SSergei Barannikov // This is usually beneficial since we avoid forcing the 867992cb984SSergei Barannikov // back-end to store the argument to memory. 868992cb984SSergei Barannikov uint64_t Bits = getContext().getTypeSize(Ty); 869992cb984SSergei Barannikov if (Bits > 0 && Bits <= 8 * GPRBits) { 870992cb984SSergei Barannikov llvm::Type *CoerceTy; 871992cb984SSergei Barannikov 872992cb984SSergei Barannikov // Types up to 8 bytes are passed as integer type (which will be 873992cb984SSergei Barannikov // properly aligned in the argument save area doubleword). 874992cb984SSergei Barannikov if (Bits <= GPRBits) 875992cb984SSergei Barannikov CoerceTy = 876992cb984SSergei Barannikov llvm::IntegerType::get(getVMContext(), llvm::alignTo(Bits, 8)); 877992cb984SSergei Barannikov // Larger types are passed as arrays, with the base type selected 878992cb984SSergei Barannikov // according to the required alignment in the save area. 879992cb984SSergei Barannikov else { 880992cb984SSergei Barannikov uint64_t RegBits = ABIAlign * 8; 881992cb984SSergei Barannikov uint64_t NumRegs = llvm::alignTo(Bits, RegBits) / RegBits; 882992cb984SSergei Barannikov llvm::Type *RegTy = llvm::IntegerType::get(getVMContext(), RegBits); 883992cb984SSergei Barannikov CoerceTy = llvm::ArrayType::get(RegTy, NumRegs); 884992cb984SSergei Barannikov } 885992cb984SSergei Barannikov 886992cb984SSergei Barannikov return ABIArgInfo::getDirect(CoerceTy); 887992cb984SSergei Barannikov } 888992cb984SSergei Barannikov 889992cb984SSergei Barannikov // All other aggregates are passed ByVal. 890992cb984SSergei Barannikov return ABIArgInfo::getIndirect(CharUnits::fromQuantity(ABIAlign), 891992cb984SSergei Barannikov /*ByVal=*/true, 892992cb984SSergei Barannikov /*Realign=*/TyAlign > ABIAlign); 893992cb984SSergei Barannikov } 894992cb984SSergei Barannikov 895*f95026dbSLei Huang return (isPromotableTypeForABI(Ty) 896*f95026dbSLei Huang ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)) 897992cb984SSergei Barannikov : ABIArgInfo::getDirect()); 898992cb984SSergei Barannikov } 899992cb984SSergei Barannikov 900992cb984SSergei Barannikov ABIArgInfo 901992cb984SSergei Barannikov PPC64_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const { 902992cb984SSergei Barannikov if (RetTy->isVoidType()) 903992cb984SSergei Barannikov return ABIArgInfo::getIgnore(); 904992cb984SSergei Barannikov 905992cb984SSergei Barannikov if (RetTy->isAnyComplexType()) 906992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 907992cb984SSergei Barannikov 908992cb984SSergei Barannikov // Non-Altivec vector types are returned in GPRs (smaller than 16 bytes) 909992cb984SSergei Barannikov // or via reference (larger than 16 bytes). 910992cb984SSergei Barannikov if (RetTy->isVectorType()) { 911992cb984SSergei Barannikov uint64_t Size = getContext().getTypeSize(RetTy); 912992cb984SSergei Barannikov if (Size > 128) 913992cb984SSergei Barannikov return getNaturalAlignIndirect(RetTy); 914992cb984SSergei Barannikov else if (Size < 128) { 915992cb984SSergei Barannikov llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size); 916992cb984SSergei Barannikov return ABIArgInfo::getDirect(CoerceTy); 917992cb984SSergei Barannikov } 918992cb984SSergei Barannikov } 919992cb984SSergei Barannikov 920992cb984SSergei Barannikov if (const auto *EIT = RetTy->getAs<BitIntType>()) 921992cb984SSergei Barannikov if (EIT->getNumBits() > 128) 922992cb984SSergei Barannikov return getNaturalAlignIndirect(RetTy, /*ByVal=*/false); 923992cb984SSergei Barannikov 924992cb984SSergei Barannikov if (isAggregateTypeForABI(RetTy)) { 925992cb984SSergei Barannikov // ELFv2 homogeneous aggregates are returned as array types. 926992cb984SSergei Barannikov const Type *Base = nullptr; 927992cb984SSergei Barannikov uint64_t Members = 0; 928992cb984SSergei Barannikov if (Kind == PPC64_SVR4_ABIKind::ELFv2 && 929992cb984SSergei Barannikov isHomogeneousAggregate(RetTy, Base, Members)) { 930992cb984SSergei Barannikov llvm::Type *BaseTy = CGT.ConvertType(QualType(Base, 0)); 931992cb984SSergei Barannikov llvm::Type *CoerceTy = llvm::ArrayType::get(BaseTy, Members); 932992cb984SSergei Barannikov return ABIArgInfo::getDirect(CoerceTy); 933992cb984SSergei Barannikov } 934992cb984SSergei Barannikov 935992cb984SSergei Barannikov // ELFv2 small aggregates are returned in up to two registers. 936992cb984SSergei Barannikov uint64_t Bits = getContext().getTypeSize(RetTy); 937992cb984SSergei Barannikov if (Kind == PPC64_SVR4_ABIKind::ELFv2 && Bits <= 2 * GPRBits) { 938992cb984SSergei Barannikov if (Bits == 0) 939992cb984SSergei Barannikov return ABIArgInfo::getIgnore(); 940992cb984SSergei Barannikov 941992cb984SSergei Barannikov llvm::Type *CoerceTy; 942992cb984SSergei Barannikov if (Bits > GPRBits) { 943992cb984SSergei Barannikov CoerceTy = llvm::IntegerType::get(getVMContext(), GPRBits); 944992cb984SSergei Barannikov CoerceTy = llvm::StructType::get(CoerceTy, CoerceTy); 945992cb984SSergei Barannikov } else 946992cb984SSergei Barannikov CoerceTy = 947992cb984SSergei Barannikov llvm::IntegerType::get(getVMContext(), llvm::alignTo(Bits, 8)); 948992cb984SSergei Barannikov return ABIArgInfo::getDirect(CoerceTy); 949992cb984SSergei Barannikov } 950992cb984SSergei Barannikov 951992cb984SSergei Barannikov // All other aggregates are returned indirectly. 952992cb984SSergei Barannikov return getNaturalAlignIndirect(RetTy); 953992cb984SSergei Barannikov } 954992cb984SSergei Barannikov 955992cb984SSergei Barannikov return (isPromotableTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) 956992cb984SSergei Barannikov : ABIArgInfo::getDirect()); 957992cb984SSergei Barannikov } 958992cb984SSergei Barannikov 959992cb984SSergei Barannikov // Based on ARMABIInfo::EmitVAArg, adjusted for 64-bit machine. 9606d973b45SMariya Podchishchaeva RValue PPC64_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 9616d973b45SMariya Podchishchaeva QualType Ty, AggValueSlot Slot) const { 962992cb984SSergei Barannikov auto TypeInfo = getContext().getTypeInfoInChars(Ty); 963992cb984SSergei Barannikov TypeInfo.Align = getParamTypeAlignment(Ty); 964992cb984SSergei Barannikov 965992cb984SSergei Barannikov CharUnits SlotSize = CharUnits::fromQuantity(8); 966992cb984SSergei Barannikov 967992cb984SSergei Barannikov // If we have a complex type and the base type is smaller than 8 bytes, 968992cb984SSergei Barannikov // the ABI calls for the real and imaginary parts to be right-adjusted 969992cb984SSergei Barannikov // in separate doublewords. However, Clang expects us to produce a 970992cb984SSergei Barannikov // pointer to a structure with the two parts packed tightly. So generate 971992cb984SSergei Barannikov // loads of the real and imaginary parts relative to the va_list pointer, 972992cb984SSergei Barannikov // and store them to a temporary structure. 973992cb984SSergei Barannikov if (const ComplexType *CTy = Ty->getAs<ComplexType>()) { 974992cb984SSergei Barannikov CharUnits EltSize = TypeInfo.Width / 2; 975992cb984SSergei Barannikov if (EltSize < SlotSize) 976992cb984SSergei Barannikov return complexTempStructure(CGF, VAListAddr, Ty, SlotSize, EltSize, CTy); 977992cb984SSergei Barannikov } 978992cb984SSergei Barannikov 979992cb984SSergei Barannikov // Otherwise, just use the general rule. 980992cb984SSergei Barannikov // 981992cb984SSergei Barannikov // The PPC64 ABI passes some arguments in integer registers, even to variadic 982992cb984SSergei Barannikov // functions. To allow va_list to use the simple "void*" representation, 983992cb984SSergei Barannikov // variadic calls allocate space in the argument area for the integer argument 984992cb984SSergei Barannikov // registers, and variadic functions spill their integer argument registers to 985992cb984SSergei Barannikov // this area in their prologues. When aggregates smaller than a register are 986992cb984SSergei Barannikov // passed this way, they are passed in the least significant bits of the 987992cb984SSergei Barannikov // register, which means that after spilling on big-endian targets they will 988992cb984SSergei Barannikov // be right-aligned in their argument slot. This is uncommon; for a variety of 989992cb984SSergei Barannikov // reasons, other big-endian targets don't end up right-aligning aggregate 990992cb984SSergei Barannikov // types this way, and so right-alignment only applies to fundamental types. 991992cb984SSergei Barannikov // So on PPC64, we must force the use of right-alignment even for aggregates. 992992cb984SSergei Barannikov return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo, 9936d973b45SMariya Podchishchaeva SlotSize, /*AllowHigher*/ true, Slot, 994992cb984SSergei Barannikov /*ForceRightAdjust*/ true); 995992cb984SSergei Barannikov } 996992cb984SSergei Barannikov 997992cb984SSergei Barannikov bool 998992cb984SSergei Barannikov PPC64_SVR4_TargetCodeGenInfo::initDwarfEHRegSizeTable( 999992cb984SSergei Barannikov CodeGen::CodeGenFunction &CGF, 1000992cb984SSergei Barannikov llvm::Value *Address) const { 1001992cb984SSergei Barannikov return PPC_initDwarfEHRegSizeTable(CGF, Address, /*Is64Bit*/ true, 1002992cb984SSergei Barannikov /*IsAIX*/ false); 1003992cb984SSergei Barannikov } 1004992cb984SSergei Barannikov 10053e97db89SQiu Chaofan void PPC64_SVR4_TargetCodeGenInfo::emitTargetMetadata( 10063e97db89SQiu Chaofan CodeGen::CodeGenModule &CGM, 10073e97db89SQiu Chaofan const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames) const { 10083e97db89SQiu Chaofan if (CGM.getTypes().isLongDoubleReferenced()) { 10093e97db89SQiu Chaofan llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 10103e97db89SQiu Chaofan const auto *flt = &CGM.getTarget().getLongDoubleFormat(); 10113e97db89SQiu Chaofan if (flt == &llvm::APFloat::PPCDoubleDouble()) 10123e97db89SQiu Chaofan CGM.getModule().addModuleFlag(llvm::Module::Error, "float-abi", 10133e97db89SQiu Chaofan llvm::MDString::get(Ctx, "doubledouble")); 10143e97db89SQiu Chaofan else if (flt == &llvm::APFloat::IEEEquad()) 10153e97db89SQiu Chaofan CGM.getModule().addModuleFlag(llvm::Module::Error, "float-abi", 10163e97db89SQiu Chaofan llvm::MDString::get(Ctx, "ieeequad")); 10173e97db89SQiu Chaofan else if (flt == &llvm::APFloat::IEEEdouble()) 10183e97db89SQiu Chaofan CGM.getModule().addModuleFlag(llvm::Module::Error, "float-abi", 10193e97db89SQiu Chaofan llvm::MDString::get(Ctx, "ieeedouble")); 10203e97db89SQiu Chaofan } 10213e97db89SQiu Chaofan } 10223e97db89SQiu Chaofan 1023992cb984SSergei Barannikov bool 1024992cb984SSergei Barannikov PPC64TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 1025992cb984SSergei Barannikov llvm::Value *Address) const { 1026992cb984SSergei Barannikov return PPC_initDwarfEHRegSizeTable(CGF, Address, /*Is64Bit*/ true, 1027992cb984SSergei Barannikov /*IsAIX*/ false); 1028992cb984SSergei Barannikov } 1029992cb984SSergei Barannikov 1030992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo> 1031992cb984SSergei Barannikov CodeGen::createAIXTargetCodeGenInfo(CodeGenModule &CGM, bool Is64Bit) { 1032992cb984SSergei Barannikov return std::make_unique<AIXTargetCodeGenInfo>(CGM.getTypes(), Is64Bit); 1033992cb984SSergei Barannikov } 1034992cb984SSergei Barannikov 1035992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo> 1036992cb984SSergei Barannikov CodeGen::createPPC32TargetCodeGenInfo(CodeGenModule &CGM, bool SoftFloatABI) { 1037992cb984SSergei Barannikov bool RetSmallStructInRegABI = PPC32TargetCodeGenInfo::isStructReturnInRegABI( 1038992cb984SSergei Barannikov CGM.getTriple(), CGM.getCodeGenOpts()); 1039992cb984SSergei Barannikov return std::make_unique<PPC32TargetCodeGenInfo>(CGM.getTypes(), SoftFloatABI, 1040992cb984SSergei Barannikov RetSmallStructInRegABI); 1041992cb984SSergei Barannikov } 1042992cb984SSergei Barannikov 1043992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo> 1044992cb984SSergei Barannikov CodeGen::createPPC64TargetCodeGenInfo(CodeGenModule &CGM) { 1045992cb984SSergei Barannikov return std::make_unique<PPC64TargetCodeGenInfo>(CGM.getTypes()); 1046992cb984SSergei Barannikov } 1047992cb984SSergei Barannikov 1048992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo> CodeGen::createPPC64_SVR4_TargetCodeGenInfo( 1049992cb984SSergei Barannikov CodeGenModule &CGM, PPC64_SVR4_ABIKind Kind, bool SoftFloatABI) { 1050992cb984SSergei Barannikov return std::make_unique<PPC64_SVR4_TargetCodeGenInfo>(CGM.getTypes(), Kind, 1051992cb984SSergei Barannikov SoftFloatABI); 1052992cb984SSergei Barannikov } 1053