//===- PPC.cpp ------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "ABIInfoImpl.h"
#include "TargetInfo.h"

using namespace clang;
using namespace clang::CodeGen;

static Address complexTempStructure(CodeGenFunction &CGF, Address VAListAddr,
                                    QualType Ty, CharUnits SlotSize,
                                    CharUnits EltSize, const ComplexType *CTy) {
  Address Addr =
      emitVoidPtrDirectVAArg(CGF, VAListAddr, CGF.Int8Ty, SlotSize * 2,
                             SlotSize, SlotSize, /*AllowHigher*/ true);

  Address RealAddr = Addr;
  Address ImagAddr = RealAddr;
  if (CGF.CGM.getDataLayout().isBigEndian()) {
    RealAddr =
        CGF.Builder.CreateConstInBoundsByteGEP(RealAddr, SlotSize - EltSize);
    ImagAddr = CGF.Builder.CreateConstInBoundsByteGEP(ImagAddr,
                                                      2 * SlotSize - EltSize);
  } else {
    ImagAddr = CGF.Builder.CreateConstInBoundsByteGEP(RealAddr, SlotSize);
  }

  llvm::Type *EltTy = CGF.ConvertTypeForMem(CTy->getElementType());
  RealAddr = RealAddr.withElementType(EltTy);
  ImagAddr = ImagAddr.withElementType(EltTy);
  llvm::Value *Real = CGF.Builder.CreateLoad(RealAddr, ".vareal");
  llvm::Value *Imag = CGF.Builder.CreateLoad(ImagAddr, ".vaimag");

  Address Temp = CGF.CreateMemTemp(Ty, "vacplx");
  CGF.EmitStoreOfComplex({Real, Imag}, CGF.MakeAddrLValue(Temp, Ty),
                         /*init*/ true);
  return Temp;
}

static bool PPC_initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                                        llvm::Value *Address, bool Is64Bit,
                                        bool IsAIX) {
  // This is calculated from the LLVM and GCC tables and verified
  // against gcc output.  AFAIK all PPC ABIs use the same encoding.

  CodeGen::CGBuilderTy &Builder = CGF.Builder;

  llvm::IntegerType *i8 = CGF.Int8Ty;
  llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
  llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
  llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);

  // 0-31: r0-31, the 4-byte or 8-byte general-purpose registers
  AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 0, 31);

  // 32-63: fp0-31, the 8-byte floating-point registers
  AssignToArrayRange(Builder, Address, Eight8, 32, 63);

  // 64-67 are various 4-byte or 8-byte special-purpose registers:
  // 64: mq
  // 65: lr
  // 66: ctr
  // 67: ap
  AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 64, 67);

  // 68-76 are various 4-byte special-purpose registers:
  // 68-75 cr0-7
  // 76: xer
  AssignToArrayRange(Builder, Address, Four8, 68, 76);

  // 77-108: v0-31, the 16-byte vector registers
  AssignToArrayRange(Builder, Address, Sixteen8, 77, 108);

  // 109: vrsave
  // 110: vscr
  AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 109, 110);

  // AIX does not utilize the rest of the registers.
  if (IsAIX)
    return false;

  // 111: spe_acc
  // 112: spefscr
  // 113: sfp
  AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 111, 113);

  if (!Is64Bit)
    return false;

  // TODO: Need to verify if these registers are used on 64 bit AIX with Power8
  // or above CPU.
  // 64-bit only registers:
  // 114: tfhar
  // 115: tfiar
  // 116: texasr
  AssignToArrayRange(Builder, Address, Eight8, 114, 116);

  return false;
}

// AIX
namespace {
/// AIXABIInfo - The AIX XCOFF ABI information.
class AIXABIInfo : public ABIInfo {
  const bool Is64Bit;
  const unsigned PtrByteSize;
  CharUnits getParamTypeAlignment(QualType Ty) const;

public:
  AIXABIInfo(CodeGen::CodeGenTypes &CGT, bool Is64Bit)
      : ABIInfo(CGT), Is64Bit(Is64Bit), PtrByteSize(Is64Bit ? 8 : 4) {}

  bool isPromotableTypeForABI(QualType Ty) const;

  ABIArgInfo classifyReturnType(QualType RetTy) const;
  ABIArgInfo classifyArgumentType(QualType Ty) const;

  void computeInfo(CGFunctionInfo &FI) const override {
    if (!getCXXABI().classifyReturnType(FI))
      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());

    for (auto &I : FI.arguments())
      I.info = classifyArgumentType(I.type);
  }

  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                    QualType Ty) const override;
};

class AIXTargetCodeGenInfo : public TargetCodeGenInfo {
  const bool Is64Bit;

public:
  AIXTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool Is64Bit)
      : TargetCodeGenInfo(std::make_unique<AIXABIInfo>(CGT, Is64Bit)),
        Is64Bit(Is64Bit) {}
  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
    return 1; // r1 is the dedicated stack pointer
  }

  bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                               llvm::Value *Address) const override;
};
} // namespace

// Return true if the ABI requires Ty to be passed sign- or zero-
// extended to 32/64 bits.
bool AIXABIInfo::isPromotableTypeForABI(QualType Ty) const {
  // Treat an enum type as its underlying type.
  if (const EnumType *EnumTy = Ty->getAs<EnumType>())
    Ty = EnumTy->getDecl()->getIntegerType();

  // Promotable integer types are required to be promoted by the ABI.
  if (getContext().isPromotableIntegerType(Ty))
    return true;

  if (!Is64Bit)
    return false;

  // For 64 bit mode, in addition to the usual promotable integer types, we also
  // need to extend all 32-bit types, since the ABI requires promotion to 64
  // bits.
  if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
    switch (BT->getKind()) {
    case BuiltinType::Int:
    case BuiltinType::UInt:
      return true;
    default:
      break;
    }

  return false;
}

ABIArgInfo AIXABIInfo::classifyReturnType(QualType RetTy) const {
  if (RetTy->isAnyComplexType())
    return ABIArgInfo::getDirect();

  if (RetTy->isVectorType())
    return ABIArgInfo::getDirect();

  if (RetTy->isVoidType())
    return ABIArgInfo::getIgnore();

  if (isAggregateTypeForABI(RetTy))
    return getNaturalAlignIndirect(RetTy);

  return (isPromotableTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
                                        : ABIArgInfo::getDirect());
}

ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const {
  Ty = useFirstFieldIfTransparentUnion(Ty);

  if (Ty->isAnyComplexType())
    return ABIArgInfo::getDirect();

  if (Ty->isVectorType())
    return ABIArgInfo::getDirect();

  if (isAggregateTypeForABI(Ty)) {
    // Records with non-trivial destructors/copy-constructors should not be
    // passed by value.
    if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
      return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);

    CharUnits CCAlign = getParamTypeAlignment(Ty);
    CharUnits TyAlign = getContext().getTypeAlignInChars(Ty);

    return ABIArgInfo::getIndirect(CCAlign, /*ByVal*/ true,
                                   /*Realign*/ TyAlign > CCAlign);
  }

  return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
                                     : ABIArgInfo::getDirect());
}

CharUnits AIXABIInfo::getParamTypeAlignment(QualType Ty) const {
  // Complex types are passed just like their elements.
  if (const ComplexType *CTy = Ty->getAs<ComplexType>())
    Ty = CTy->getElementType();

  if (Ty->isVectorType())
    return CharUnits::fromQuantity(16);

  // If the structure contains a vector type, the alignment is 16.
  if (isRecordWithSIMDVectorType(getContext(), Ty))
    return CharUnits::fromQuantity(16);

  return CharUnits::fromQuantity(PtrByteSize);
}

Address AIXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                              QualType Ty) const {

  auto TypeInfo = getContext().getTypeInfoInChars(Ty);
  TypeInfo.Align = getParamTypeAlignment(Ty);

  CharUnits SlotSize = CharUnits::fromQuantity(PtrByteSize);

  // If we have a complex type and the base type is smaller than the register
  // size, the ABI calls for the real and imaginary parts to be right-adjusted
  // in separate words in 32bit mode or doublewords in 64bit mode. However,
  // Clang expects us to produce a pointer to a structure with the two parts
  // packed tightly. So generate loads of the real and imaginary parts relative
  // to the va_list pointer, and store them to a temporary structure. We do the
  // same as the PPC64ABI here.
  if (const ComplexType *CTy = Ty->getAs<ComplexType>()) {
    CharUnits EltSize = TypeInfo.Width / 2;
    if (EltSize < SlotSize)
      return complexTempStructure(CGF, VAListAddr, Ty, SlotSize, EltSize, CTy);
  }

  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo,
                          SlotSize, /*AllowHigher*/ true);
}

bool AIXTargetCodeGenInfo::initDwarfEHRegSizeTable(
    CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const {
  return PPC_initDwarfEHRegSizeTable(CGF, Address, Is64Bit, /*IsAIX*/ true);
}

// PowerPC-32
namespace {
/// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information.
class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
  bool IsSoftFloatABI;
  bool IsRetSmallStructInRegABI;

  CharUnits getParamTypeAlignment(QualType Ty) const;

public:
  PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI,
                     bool RetSmallStructInRegABI)
      : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI),
        IsRetSmallStructInRegABI(RetSmallStructInRegABI) {}

  ABIArgInfo classifyReturnType(QualType RetTy) const;

  void computeInfo(CGFunctionInfo &FI) const override {
    if (!getCXXABI().classifyReturnType(FI))
      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
    for (auto &I : FI.arguments())
      I.info = classifyArgumentType(I.type);
  }

  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                    QualType Ty) const override;
};

class PPC32TargetCodeGenInfo : public TargetCodeGenInfo {
public:
  PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI,
                         bool RetSmallStructInRegABI)
      : TargetCodeGenInfo(std::make_unique<PPC32_SVR4_ABIInfo>(
            CGT, SoftFloatABI, RetSmallStructInRegABI)) {}

  static bool isStructReturnInRegABI(const llvm::Triple &Triple,
                                     const CodeGenOptions &Opts);

  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
    // This is recovered from gcc output.
    return 1; // r1 is the dedicated stack pointer
  }

  bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                               llvm::Value *Address) const override;
};
}

CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
  // Complex types are passed just like their elements.
  if (const ComplexType *CTy = Ty->getAs<ComplexType>())
    Ty = CTy->getElementType();

  if (Ty->isVectorType())
    return CharUnits::fromQuantity(getContext().getTypeSize(Ty) == 128 ? 16
                                                                       : 4);

  // For single-element float/vector structs, we consider the whole type
  // to have the same alignment requirements as its single element.
  const Type *AlignTy = nullptr;
  if (const Type *EltType = isSingleElementStruct(Ty, getContext())) {
    const BuiltinType *BT = EltType->getAs<BuiltinType>();
    if ((EltType->isVectorType() && getContext().getTypeSize(EltType) == 128) ||
        (BT && BT->isFloatingPoint()))
      AlignTy = EltType;
  }

  if (AlignTy)
    return CharUnits::fromQuantity(AlignTy->isVectorType() ? 16 : 4);
  return CharUnits::fromQuantity(4);
}

ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
  uint64_t Size;

  // -msvr4-struct-return puts small aggregates in GPR3 and GPR4.
  if (isAggregateTypeForABI(RetTy) && IsRetSmallStructInRegABI &&
      (Size = getContext().getTypeSize(RetTy)) <= 64) {
    // System V ABI (1995), page 3-22, specified:
    // > A structure or union whose size is less than or equal to 8 bytes
    // > shall be returned in r3 and r4, as if it were first stored in the
    // > 8-byte aligned memory area and then the low addressed word were
    // > loaded into r3 and the high-addressed word into r4.  Bits beyond
    // > the last member of the structure or union are not defined.
    //
    // GCC for big-endian PPC32 inserts the pad before the first member,
    // not "beyond the last member" of the struct.  To stay compatible
    // with GCC, we coerce the struct to an integer of the same size.
    // LLVM will extend it and return i32 in r3, or i64 in r3:r4.
    if (Size == 0)
      return ABIArgInfo::getIgnore();
    else {
      llvm::Type *CoerceTy = llvm::Type::getIntNTy(getVMContext(), Size);
      return ABIArgInfo::getDirect(CoerceTy);
    }
  }

  return DefaultABIInfo::classifyReturnType(RetTy);
}

// TODO: this implementation is now likely redundant with
// DefaultABIInfo::EmitVAArg.
Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
                                      QualType Ty) const {
  if (getTarget().getTriple().isOSDarwin()) {
    auto TI = getContext().getTypeInfoInChars(Ty);
    TI.Align = getParamTypeAlignment(Ty);

    CharUnits SlotSize = CharUnits::fromQuantity(4);
    return emitVoidPtrVAArg(CGF, VAList, Ty,
                            classifyArgumentType(Ty).isIndirect(), TI, SlotSize,
                            /*AllowHigherAlign=*/true);
  }

  const unsigned OverflowLimit = 8;
  if (const ComplexType *CTy = Ty->getAs<ComplexType>()) {
    // TODO: Implement this. For now ignore.
    (void)CTy;
    return Address::invalid(); // FIXME?
  }

  // struct __va_list_tag {
  //   unsigned char gpr;
  //   unsigned char fpr;
  //   unsigned short reserved;
  //   void *overflow_arg_area;
  //   void *reg_save_area;
  // };

  bool isI64 = Ty->isIntegerType() && getContext().getTypeSize(Ty) == 64;
  bool isInt = !Ty->isFloatingType();
  bool isF64 = Ty->isFloatingType() && getContext().getTypeSize(Ty) == 64;

  // All aggregates are passed indirectly?  That doesn't seem consistent
  // with the argument-lowering code.
  bool isIndirect = isAggregateTypeForABI(Ty);

  CGBuilderTy &Builder = CGF.Builder;

  // The calling convention either uses 1-2 GPRs or 1 FPR.
  Address NumRegsAddr = Address::invalid();
  if (isInt || IsSoftFloatABI) {
    NumRegsAddr = Builder.CreateStructGEP(VAList, 0, "gpr");
  } else {
    NumRegsAddr = Builder.CreateStructGEP(VAList, 1, "fpr");
  }

  llvm::Value *NumRegs = Builder.CreateLoad(NumRegsAddr, "numUsedRegs");

  // "Align" the register count when TY is i64.
  if (isI64 || (isF64 && IsSoftFloatABI)) {
    NumRegs = Builder.CreateAdd(NumRegs, Builder.getInt8(1));
    NumRegs = Builder.CreateAnd(NumRegs, Builder.getInt8((uint8_t) ~1U));
  }

  llvm::Value *CC =
      Builder.CreateICmpULT(NumRegs, Builder.getInt8(OverflowLimit), "cond");

  llvm::BasicBlock *UsingRegs = CGF.createBasicBlock("using_regs");
  llvm::BasicBlock *UsingOverflow = CGF.createBasicBlock("using_overflow");
  llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");

  Builder.CreateCondBr(CC, UsingRegs, UsingOverflow);

  llvm::Type *DirectTy = CGF.ConvertType(Ty), *ElementTy = DirectTy;
  if (isIndirect)
    DirectTy = CGF.UnqualPtrTy;

  // Case 1: consume registers.
  Address RegAddr = Address::invalid();
  {
    CGF.EmitBlock(UsingRegs);

    Address RegSaveAreaPtr = Builder.CreateStructGEP(VAList, 4);
    RegAddr = Address(Builder.CreateLoad(RegSaveAreaPtr), CGF.Int8Ty,
                      CharUnits::fromQuantity(8));
    assert(RegAddr.getElementType() == CGF.Int8Ty);

    // Floating-point registers start after the general-purpose registers.
    if (!(isInt || IsSoftFloatABI)) {
      RegAddr = Builder.CreateConstInBoundsByteGEP(RegAddr,
                                                   CharUnits::fromQuantity(32));
    }

    // Get the address of the saved value by scaling the number of
    // registers we've used by the number of
    CharUnits RegSize = CharUnits::fromQuantity((isInt || IsSoftFloatABI) ? 4 : 8);
    llvm::Value *RegOffset =
        Builder.CreateMul(NumRegs, Builder.getInt8(RegSize.getQuantity()));
    RegAddr = Address(
        Builder.CreateInBoundsGEP(CGF.Int8Ty, RegAddr.getPointer(), RegOffset),
        DirectTy, RegAddr.getAlignment().alignmentOfArrayElement(RegSize));

    // Increase the used-register count.
    NumRegs =
      Builder.CreateAdd(NumRegs,
                        Builder.getInt8((isI64 || (isF64 && IsSoftFloatABI)) ? 2 : 1));
    Builder.CreateStore(NumRegs, NumRegsAddr);

    CGF.EmitBranch(Cont);
  }

  // Case 2: consume space in the overflow area.
  Address MemAddr = Address::invalid();
  {
    CGF.EmitBlock(UsingOverflow);

    Builder.CreateStore(Builder.getInt8(OverflowLimit), NumRegsAddr);

    // Everything in the overflow area is rounded up to a size of at least 4.
    CharUnits OverflowAreaAlign = CharUnits::fromQuantity(4);

    CharUnits Size;
    if (!isIndirect) {
      auto TypeInfo = CGF.getContext().getTypeInfoInChars(Ty);
      Size = TypeInfo.Width.alignTo(OverflowAreaAlign);
    } else {
      Size = CGF.getPointerSize();
    }

    Address OverflowAreaAddr = Builder.CreateStructGEP(VAList, 3);
    Address OverflowArea =
        Address(Builder.CreateLoad(OverflowAreaAddr, "argp.cur"), CGF.Int8Ty,
                OverflowAreaAlign);
    // Round up address of argument to alignment
    CharUnits Align = CGF.getContext().getTypeAlignInChars(Ty);
    if (Align > OverflowAreaAlign) {
      llvm::Value *Ptr = OverflowArea.getPointer();
      OverflowArea = Address(emitRoundPointerUpToAlignment(CGF, Ptr, Align),
                             OverflowArea.getElementType(), Align);
    }

    MemAddr = OverflowArea.withElementType(DirectTy);

    // Increase the overflow area.
    OverflowArea = Builder.CreateConstInBoundsByteGEP(OverflowArea, Size);
    Builder.CreateStore(OverflowArea.getPointer(), OverflowAreaAddr);
    CGF.EmitBranch(Cont);
  }

  CGF.EmitBlock(Cont);

  // Merge the cases with a phi.
  Address Result = emitMergePHI(CGF, RegAddr, UsingRegs, MemAddr, UsingOverflow,
                                "vaarg.addr");

  // Load the pointer if the argument was passed indirectly.
  if (isIndirect) {
    Result = Address(Builder.CreateLoad(Result, "aggr"), ElementTy,
                     getContext().getTypeAlignInChars(Ty));
  }

  return Result;
}

bool PPC32TargetCodeGenInfo::isStructReturnInRegABI(
    const llvm::Triple &Triple, const CodeGenOptions &Opts) {
  assert(Triple.isPPC32());

  switch (Opts.getStructReturnConvention()) {
  case CodeGenOptions::SRCK_Default:
    break;
  case CodeGenOptions::SRCK_OnStack: // -maix-struct-return
    return false;
  case CodeGenOptions::SRCK_InRegs: // -msvr4-struct-return
    return true;
  }

  if (Triple.isOSBinFormatELF() && !Triple.isOSLinux())
    return true;

  return false;
}

bool
PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                                                llvm::Value *Address) const {
  return PPC_initDwarfEHRegSizeTable(CGF, Address, /*Is64Bit*/ false,
                                     /*IsAIX*/ false);
}

// PowerPC-64

namespace {

/// PPC64_SVR4_ABIInfo - The 64-bit PowerPC ELF (SVR4) ABI information.
class PPC64_SVR4_ABIInfo : public ABIInfo {
  static const unsigned GPRBits = 64;
  PPC64_SVR4_ABIKind Kind;
  bool IsSoftFloatABI;

public:
  PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, PPC64_SVR4_ABIKind Kind,
                     bool SoftFloatABI)
      : ABIInfo(CGT), Kind(Kind), IsSoftFloatABI(SoftFloatABI) {}

  bool isPromotableTypeForABI(QualType Ty) const;
  CharUnits getParamTypeAlignment(QualType Ty) const;

  ABIArgInfo classifyReturnType(QualType RetTy) const;
  ABIArgInfo classifyArgumentType(QualType Ty) const;

  bool isHomogeneousAggregateBaseType(QualType Ty) const override;
  bool isHomogeneousAggregateSmallEnough(const Type *Ty,
                                         uint64_t Members) const override;

  // TODO: We can add more logic to computeInfo to improve performance.
  // Example: For aggregate arguments that fit in a register, we could
  // use getDirectInReg (as is done below for structs containing a single
  // floating-point value) to avoid pushing them to memory on function
  // entry.  This would require changing the logic in PPCISelLowering
  // when lowering the parameters in the caller and args in the callee.
  void computeInfo(CGFunctionInfo &FI) const override {
    if (!getCXXABI().classifyReturnType(FI))
      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
    for (auto &I : FI.arguments()) {
      // We rely on the default argument classification for the most part.
      // One exception:  An aggregate containing a single floating-point
      // or vector item must be passed in a register if one is available.
      const Type *T = isSingleElementStruct(I.type, getContext());
      if (T) {
        const BuiltinType *BT = T->getAs<BuiltinType>();
        if ((T->isVectorType() && getContext().getTypeSize(T) == 128) ||
            (BT && BT->isFloatingPoint())) {
          QualType QT(T, 0);
          I.info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT));
          continue;
        }
      }
      I.info = classifyArgumentType(I.type);
    }
  }

  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                    QualType Ty) const override;
};

class PPC64_SVR4_TargetCodeGenInfo : public TargetCodeGenInfo {

public:
  PPC64_SVR4_TargetCodeGenInfo(CodeGenTypes &CGT, PPC64_SVR4_ABIKind Kind,
                               bool SoftFloatABI)
      : TargetCodeGenInfo(
            std::make_unique<PPC64_SVR4_ABIInfo>(CGT, Kind, SoftFloatABI)) {
    SwiftInfo =
        std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
  }

  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
    // This is recovered from gcc output.
    return 1; // r1 is the dedicated stack pointer
  }

  bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                               llvm::Value *Address) const override;
  void emitTargetMetadata(CodeGen::CodeGenModule &CGM,
                          const llvm::MapVector<GlobalDecl, StringRef>
                              &MangledDeclNames) const override;
};

class PPC64TargetCodeGenInfo : public TargetCodeGenInfo {
public:
  PPC64TargetCodeGenInfo(CodeGenTypes &CGT)
      : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {}

  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
    // This is recovered from gcc output.
    return 1; // r1 is the dedicated stack pointer
  }

  bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                               llvm::Value *Address) const override;
};
}

// Return true if the ABI requires Ty to be passed sign- or zero-
// extended to 64 bits.
bool
PPC64_SVR4_ABIInfo::isPromotableTypeForABI(QualType Ty) const {
  // Treat an enum type as its underlying type.
  if (const EnumType *EnumTy = Ty->getAs<EnumType>())
    Ty = EnumTy->getDecl()->getIntegerType();

  // Promotable integer types are required to be promoted by the ABI.
  if (isPromotableIntegerTypeForABI(Ty))
    return true;

  // In addition to the usual promotable integer types, we also need to
  // extend all 32-bit types, since the ABI requires promotion to 64 bits.
  if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
    switch (BT->getKind()) {
    case BuiltinType::Int:
    case BuiltinType::UInt:
      return true;
    default:
      break;
    }

  if (const auto *EIT = Ty->getAs<BitIntType>())
    if (EIT->getNumBits() < 64)
      return true;

  return false;
}

/// isAlignedParamType - Determine whether a type requires 16-byte or
/// higher alignment in the parameter area.  Always returns at least 8.
CharUnits PPC64_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
  // Complex types are passed just like their elements.
  if (const ComplexType *CTy = Ty->getAs<ComplexType>())
    Ty = CTy->getElementType();

  auto FloatUsesVector = [this](QualType Ty){
    return Ty->isRealFloatingType() && &getContext().getFloatTypeSemantics(
                                           Ty) == &llvm::APFloat::IEEEquad();
  };

  // Only vector types of size 16 bytes need alignment (larger types are
  // passed via reference, smaller types are not aligned).
  if (Ty->isVectorType()) {
    return CharUnits::fromQuantity(getContext().getTypeSize(Ty) == 128 ? 16 : 8);
  } else if (FloatUsesVector(Ty)) {
    // According to ABI document section 'Optional Save Areas': If extended
    // precision floating-point values in IEEE BINARY 128 QUADRUPLE PRECISION
    // format are supported, map them to a single quadword, quadword aligned.
    return CharUnits::fromQuantity(16);
  }

  // For single-element float/vector structs, we consider the whole type
  // to have the same alignment requirements as its single element.
  const Type *AlignAsType = nullptr;
  const Type *EltType = isSingleElementStruct(Ty, getContext());
  if (EltType) {
    const BuiltinType *BT = EltType->getAs<BuiltinType>();
    if ((EltType->isVectorType() && getContext().getTypeSize(EltType) == 128) ||
        (BT && BT->isFloatingPoint()))
      AlignAsType = EltType;
  }

  // Likewise for ELFv2 homogeneous aggregates.
  const Type *Base = nullptr;
  uint64_t Members = 0;
  if (!AlignAsType && Kind == PPC64_SVR4_ABIKind::ELFv2 &&
      isAggregateTypeForABI(Ty) && isHomogeneousAggregate(Ty, Base, Members))
    AlignAsType = Base;

  // With special case aggregates, only vector base types need alignment.
  if (AlignAsType) {
    bool UsesVector = AlignAsType->isVectorType() ||
                      FloatUsesVector(QualType(AlignAsType, 0));
    return CharUnits::fromQuantity(UsesVector ? 16 : 8);
  }

  // Otherwise, we only need alignment for any aggregate type that
  // has an alignment requirement of >= 16 bytes.
  if (isAggregateTypeForABI(Ty) && getContext().getTypeAlign(Ty) >= 128) {
    return CharUnits::fromQuantity(16);
  }

  return CharUnits::fromQuantity(8);
}

bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
  // Homogeneous aggregates for ELFv2 must have base types of float,
  // double, long double, or 128-bit vectors.
  if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {
    if (BT->getKind() == BuiltinType::Float ||
        BT->getKind() == BuiltinType::Double ||
        BT->getKind() == BuiltinType::LongDouble ||
        BT->getKind() == BuiltinType::Ibm128 ||
        (getContext().getTargetInfo().hasFloat128Type() &&
         (BT->getKind() == BuiltinType::Float128))) {
      if (IsSoftFloatABI)
        return false;
      return true;
    }
  }
  if (const VectorType *VT = Ty->getAs<VectorType>()) {
    if (getContext().getTypeSize(VT) == 128)
      return true;
  }
  return false;
}

bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateSmallEnough(
    const Type *Base, uint64_t Members) const {
  // Vector and fp128 types require one register, other floating point types
  // require one or two registers depending on their size.
  uint32_t NumRegs =
      ((getContext().getTargetInfo().hasFloat128Type() &&
          Base->isFloat128Type()) ||
        Base->isVectorType()) ? 1
                              : (getContext().getTypeSize(Base) + 63) / 64;

  // Homogeneous Aggregates may occupy at most 8 registers.
  return Members * NumRegs <= 8;
}

ABIArgInfo
PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const {
  Ty = useFirstFieldIfTransparentUnion(Ty);

  if (Ty->isAnyComplexType())
    return ABIArgInfo::getDirect();

  // Non-Altivec vector types are passed in GPRs (smaller than 16 bytes)
  // or via reference (larger than 16 bytes).
  if (Ty->isVectorType()) {
    uint64_t Size = getContext().getTypeSize(Ty);
    if (Size > 128)
      return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
    else if (Size < 128) {
      llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size);
      return ABIArgInfo::getDirect(CoerceTy);
    }
  }

  if (const auto *EIT = Ty->getAs<BitIntType>())
    if (EIT->getNumBits() > 128)
      return getNaturalAlignIndirect(Ty, /*ByVal=*/true);

  if (isAggregateTypeForABI(Ty)) {
    if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
      return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);

    uint64_t ABIAlign = getParamTypeAlignment(Ty).getQuantity();
    uint64_t TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity();

    // ELFv2 homogeneous aggregates are passed as array types.
    const Type *Base = nullptr;
    uint64_t Members = 0;
    if (Kind == PPC64_SVR4_ABIKind::ELFv2 &&
        isHomogeneousAggregate(Ty, Base, Members)) {
      llvm::Type *BaseTy = CGT.ConvertType(QualType(Base, 0));
      llvm::Type *CoerceTy = llvm::ArrayType::get(BaseTy, Members);
      return ABIArgInfo::getDirect(CoerceTy);
    }

    // If an aggregate may end up fully in registers, we do not
    // use the ByVal method, but pass the aggregate as array.
    // This is usually beneficial since we avoid forcing the
    // back-end to store the argument to memory.
    uint64_t Bits = getContext().getTypeSize(Ty);
    if (Bits > 0 && Bits <= 8 * GPRBits) {
      llvm::Type *CoerceTy;

      // Types up to 8 bytes are passed as integer type (which will be
      // properly aligned in the argument save area doubleword).
      if (Bits <= GPRBits)
        CoerceTy =
            llvm::IntegerType::get(getVMContext(), llvm::alignTo(Bits, 8));
      // Larger types are passed as arrays, with the base type selected
      // according to the required alignment in the save area.
      else {
        uint64_t RegBits = ABIAlign * 8;
        uint64_t NumRegs = llvm::alignTo(Bits, RegBits) / RegBits;
        llvm::Type *RegTy = llvm::IntegerType::get(getVMContext(), RegBits);
        CoerceTy = llvm::ArrayType::get(RegTy, NumRegs);
      }

      return ABIArgInfo::getDirect(CoerceTy);
    }

    // All other aggregates are passed ByVal.
    return ABIArgInfo::getIndirect(CharUnits::fromQuantity(ABIAlign),
                                   /*ByVal=*/true,
                                   /*Realign=*/TyAlign > ABIAlign);
  }

  return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
                                     : ABIArgInfo::getDirect());
}

ABIArgInfo
PPC64_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
  if (RetTy->isVoidType())
    return ABIArgInfo::getIgnore();

  if (RetTy->isAnyComplexType())
    return ABIArgInfo::getDirect();

  // Non-Altivec vector types are returned in GPRs (smaller than 16 bytes)
  // or via reference (larger than 16 bytes).
  if (RetTy->isVectorType()) {
    uint64_t Size = getContext().getTypeSize(RetTy);
    if (Size > 128)
      return getNaturalAlignIndirect(RetTy);
    else if (Size < 128) {
      llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size);
      return ABIArgInfo::getDirect(CoerceTy);
    }
  }

  if (const auto *EIT = RetTy->getAs<BitIntType>())
    if (EIT->getNumBits() > 128)
      return getNaturalAlignIndirect(RetTy, /*ByVal=*/false);

  if (isAggregateTypeForABI(RetTy)) {
    // ELFv2 homogeneous aggregates are returned as array types.
    const Type *Base = nullptr;
    uint64_t Members = 0;
    if (Kind == PPC64_SVR4_ABIKind::ELFv2 &&
        isHomogeneousAggregate(RetTy, Base, Members)) {
      llvm::Type *BaseTy = CGT.ConvertType(QualType(Base, 0));
      llvm::Type *CoerceTy = llvm::ArrayType::get(BaseTy, Members);
      return ABIArgInfo::getDirect(CoerceTy);
    }

    // ELFv2 small aggregates are returned in up to two registers.
    uint64_t Bits = getContext().getTypeSize(RetTy);
    if (Kind == PPC64_SVR4_ABIKind::ELFv2 && Bits <= 2 * GPRBits) {
      if (Bits == 0)
        return ABIArgInfo::getIgnore();

      llvm::Type *CoerceTy;
      if (Bits > GPRBits) {
        CoerceTy = llvm::IntegerType::get(getVMContext(), GPRBits);
        CoerceTy = llvm::StructType::get(CoerceTy, CoerceTy);
      } else
        CoerceTy =
            llvm::IntegerType::get(getVMContext(), llvm::alignTo(Bits, 8));
      return ABIArgInfo::getDirect(CoerceTy);
    }

    // All other aggregates are returned indirectly.
    return getNaturalAlignIndirect(RetTy);
  }

  return (isPromotableTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
                                        : ABIArgInfo::getDirect());
}

// Based on ARMABIInfo::EmitVAArg, adjusted for 64-bit machine.
Address PPC64_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                                      QualType Ty) const {
  auto TypeInfo = getContext().getTypeInfoInChars(Ty);
  TypeInfo.Align = getParamTypeAlignment(Ty);

  CharUnits SlotSize = CharUnits::fromQuantity(8);

  // If we have a complex type and the base type is smaller than 8 bytes,
  // the ABI calls for the real and imaginary parts to be right-adjusted
  // in separate doublewords.  However, Clang expects us to produce a
  // pointer to a structure with the two parts packed tightly.  So generate
  // loads of the real and imaginary parts relative to the va_list pointer,
  // and store them to a temporary structure.
  if (const ComplexType *CTy = Ty->getAs<ComplexType>()) {
    CharUnits EltSize = TypeInfo.Width / 2;
    if (EltSize < SlotSize)
      return complexTempStructure(CGF, VAListAddr, Ty, SlotSize, EltSize, CTy);
  }

  // Otherwise, just use the general rule.
  //
  // The PPC64 ABI passes some arguments in integer registers, even to variadic
  // functions. To allow va_list to use the simple "void*" representation,
  // variadic calls allocate space in the argument area for the integer argument
  // registers, and variadic functions spill their integer argument registers to
  // this area in their prologues. When aggregates smaller than a register are
  // passed this way, they are passed in the least significant bits of the
  // register, which means that after spilling on big-endian targets they will
  // be right-aligned in their argument slot. This is uncommon; for a variety of
  // reasons, other big-endian targets don't end up right-aligning aggregate
  // types this way, and so right-alignment only applies to fundamental types.
  // So on PPC64, we must force the use of right-alignment even for aggregates.
  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo,
                          SlotSize, /*AllowHigher*/ true,
                          /*ForceRightAdjust*/ true);
}

bool
PPC64_SVR4_TargetCodeGenInfo::initDwarfEHRegSizeTable(
  CodeGen::CodeGenFunction &CGF,
  llvm::Value *Address) const {
  return PPC_initDwarfEHRegSizeTable(CGF, Address, /*Is64Bit*/ true,
                                     /*IsAIX*/ false);
}

void PPC64_SVR4_TargetCodeGenInfo::emitTargetMetadata(
    CodeGen::CodeGenModule &CGM,
    const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames) const {
  if (CGM.getTypes().isLongDoubleReferenced()) {
    llvm::LLVMContext &Ctx = CGM.getLLVMContext();
    const auto *flt = &CGM.getTarget().getLongDoubleFormat();
    if (flt == &llvm::APFloat::PPCDoubleDouble())
      CGM.getModule().addModuleFlag(llvm::Module::Error, "float-abi",
                                    llvm::MDString::get(Ctx, "doubledouble"));
    else if (flt == &llvm::APFloat::IEEEquad())
      CGM.getModule().addModuleFlag(llvm::Module::Error, "float-abi",
                                    llvm::MDString::get(Ctx, "ieeequad"));
    else if (flt == &llvm::APFloat::IEEEdouble())
      CGM.getModule().addModuleFlag(llvm::Module::Error, "float-abi",
                                    llvm::MDString::get(Ctx, "ieeedouble"));
  }
}

bool
PPC64TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                                                llvm::Value *Address) const {
  return PPC_initDwarfEHRegSizeTable(CGF, Address, /*Is64Bit*/ true,
                                     /*IsAIX*/ false);
}

std::unique_ptr<TargetCodeGenInfo>
CodeGen::createAIXTargetCodeGenInfo(CodeGenModule &CGM, bool Is64Bit) {
  return std::make_unique<AIXTargetCodeGenInfo>(CGM.getTypes(), Is64Bit);
}

std::unique_ptr<TargetCodeGenInfo>
CodeGen::createPPC32TargetCodeGenInfo(CodeGenModule &CGM, bool SoftFloatABI) {
  bool RetSmallStructInRegABI = PPC32TargetCodeGenInfo::isStructReturnInRegABI(
      CGM.getTriple(), CGM.getCodeGenOpts());
  return std::make_unique<PPC32TargetCodeGenInfo>(CGM.getTypes(), SoftFloatABI,
                                                  RetSmallStructInRegABI);
}

std::unique_ptr<TargetCodeGenInfo>
CodeGen::createPPC64TargetCodeGenInfo(CodeGenModule &CGM) {
  return std::make_unique<PPC64TargetCodeGenInfo>(CGM.getTypes());
}

std::unique_ptr<TargetCodeGenInfo> CodeGen::createPPC64_SVR4_TargetCodeGenInfo(
    CodeGenModule &CGM, PPC64_SVR4_ABIKind Kind, bool SoftFloatABI) {
  return std::make_unique<PPC64_SVR4_TargetCodeGenInfo>(CGM.getTypes(), Kind,
                                                        SoftFloatABI);
}
