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