//===- Sparc.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"
#include <algorithm>

using namespace clang;
using namespace clang::CodeGen;

//===----------------------------------------------------------------------===//
// SPARC v8 ABI Implementation.
// Based on the SPARC Compliance Definition version 2.4.1.
//
// Ensures that complex values are passed in registers.
//
namespace {
class SparcV8ABIInfo : public DefaultABIInfo {
public:
  SparcV8ABIInfo(CodeGenTypes &CGT)
      : DefaultABIInfo(CGT),
        IsComplexGnuABI(!CGT.getContext().getLangOpts().isCompatibleWith(
            LangOptions::ClangABI::Ver23)) {}

private:
  /// Whether how `_Complex` values are passed and returned is GCC-compatible.
  bool IsComplexGnuABI;

  ABIArgInfo classifyComplexType(const ComplexType *Ty, bool IsRet) const;
  ABIArgInfo classifyReturnType(QualType RetTy) const;
  ABIArgInfo classifyArgumentType(QualType Ty) const;
  void computeInfo(CGFunctionInfo &FI) const override;
};
} // end anonymous namespace

ABIArgInfo SparcV8ABIInfo::classifyComplexType(const ComplexType *CT,
                                               bool IsRet) const {
  QualType ElementTy = CT->getElementType();

  if (IsComplexGnuABI && ElementTy->isIntegerType()) {
    // The default path already does the right thing for `long long _Complex`.
    uint64_t ElementTypeSize = getContext().getTypeSize(ElementTy);
    if (ElementTypeSize <= 32) {
      // Coerce to an integer to get the correct scalar-like behavior.
      return ABIArgInfo::getDirect(
          llvm::IntegerType::get(getVMContext(), 2 * ElementTypeSize));
    }
  }

  // Any other complex value is passed indirectly, but returned in registers.
  if (!IsRet)
    return getNaturalAlignIndirect(QualType(CT, 0),
                                   getDataLayout().getAllocaAddrSpace());

  // long double _Complex is special, it is marked as inreg.
  const auto *BT = ElementTy->getAs<BuiltinType>();
  if (BT && BT->getKind() == BuiltinType::LongDouble)
    return ABIArgInfo::getDirectInReg();

  return ABIArgInfo::getDirect();
}

ABIArgInfo SparcV8ABIInfo::classifyReturnType(QualType Ty) const {
  if (const auto *CT = Ty->getAs<ComplexType>())
    return classifyComplexType(CT, /*IsRet=*/true);

  if (const auto *BT = Ty->getAs<BuiltinType>();
      BT && BT->getKind() == BuiltinType::LongDouble)
    return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
                                   /*ByVal=*/false);

  return DefaultABIInfo::classifyReturnType(Ty);
}

ABIArgInfo SparcV8ABIInfo::classifyArgumentType(QualType Ty) const {
  if (const auto *CT = Ty->getAs<ComplexType>())
    return classifyComplexType(CT, /*IsRet=*/false);

  const auto *BT = Ty->getAs<BuiltinType>();
  if (BT && BT->getKind() == BuiltinType::LongDouble)
    return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());

  return DefaultABIInfo::classifyArgumentType(Ty);
}

void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI) const {
  FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
  for (auto &Arg : FI.arguments())
    Arg.info = classifyArgumentType(Arg.type);
}

namespace {
class SparcV8TargetCodeGenInfo : public TargetCodeGenInfo {
public:
  SparcV8TargetCodeGenInfo(CodeGenTypes &CGT)
      : TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(CGT)) {}

  llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *Address) const override {
    int Offset;
    if (isAggregateTypeForABI(CGF.CurFnInfo->getReturnType()))
      Offset = 12;
    else
      Offset = 8;
    return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
                                 llvm::ConstantInt::get(CGF.Int32Ty, Offset));
  }

  llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *Address) const override {
    int Offset;
    if (isAggregateTypeForABI(CGF.CurFnInfo->getReturnType()))
      Offset = -12;
    else
      Offset = -8;
    return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
                                 llvm::ConstantInt::get(CGF.Int32Ty, Offset));
  }
};
} // end anonymous namespace

//===----------------------------------------------------------------------===//
// SPARC v9 ABI Implementation.
// Based on the SPARC Compliance Definition version 2.4.1.
//
// Function arguments a mapped to a nominal "parameter array" and promoted to
// registers depending on their type. Each argument occupies 8 or 16 bytes in
// the array, structs larger than 16 bytes are passed indirectly.
//
// One case requires special care:
//
//   struct mixed {
//     int i;
//     float f;
//   };
//
// When a struct mixed is passed by value, it only occupies 8 bytes in the
// parameter array, but the int is passed in an integer register, and the float
// is passed in a floating point register. This is represented as two arguments
// with the LLVM IR inreg attribute:
//
//   declare void f(i32 inreg %i, float inreg %f)
//
// The code generator will only allocate 4 bytes from the parameter array for
// the inreg arguments. All other arguments are allocated a multiple of 8
// bytes.
//
namespace {
class SparcV9ABIInfo : public ABIInfo {
public:
  SparcV9ABIInfo(CodeGenTypes &CGT)
      : ABIInfo(CGT),
        IsComplexGnuABI(!CGT.getContext().getLangOpts().isCompatibleWith(
            LangOptions::ClangABI::Ver23)) {}

private:
  /// Whether how `_Complex` values are passed and returned is GCC-compatible.
  bool IsComplexGnuABI;

  ABIArgInfo classifyType(QualType RetTy, unsigned SizeLimit,
                          unsigned &RegOffset) const;
  void computeInfo(CGFunctionInfo &FI) const override;
  RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
                   AggValueSlot Slot) const override;

  // Coercion type builder for structs passed in registers. The coercion type
  // serves two purposes:
  //
  // 1. Pad structs to a multiple of 64 bits, so they are passed 'left-aligned'
  //    in registers.
  // 2. Expose aligned floating point elements as first-level elements, so the
  //    code generator knows to pass them in floating point registers.
  //
  // We also compute the InReg flag which indicates that the struct contains
  // aligned 32-bit floats.
  //
  struct CoerceBuilder {
    llvm::LLVMContext &Context;
    const llvm::DataLayout &DL;
    SmallVector<llvm::Type*, 8> Elems;
    uint64_t Size;
    bool InReg;

    CoerceBuilder(llvm::LLVMContext &c, const llvm::DataLayout &dl)
      : Context(c), DL(dl), Size(0), InReg(false) {}

    // Pad Elems with integers until Size is ToSize.
    void pad(uint64_t ToSize) {
      assert(ToSize >= Size && "Cannot remove elements");
      if (ToSize == Size)
        return;

      // Finish the current 64-bit word.
      uint64_t Aligned = llvm::alignTo(Size, 64);
      if (Aligned > Size && Aligned <= ToSize) {
        Elems.push_back(llvm::IntegerType::get(Context, Aligned - Size));
        Size = Aligned;
      }

      // Add whole 64-bit words.
      while (Size + 64 <= ToSize) {
        Elems.push_back(llvm::Type::getInt64Ty(Context));
        Size += 64;
      }

      // Final in-word padding.
      if (Size < ToSize) {
        Elems.push_back(llvm::IntegerType::get(Context, ToSize - Size));
        Size = ToSize;
      }
    }

    // Add a floating point element at Offset.
    void addFloat(uint64_t Offset, llvm::Type *Ty, unsigned Bits) {
      // Unaligned floats are treated as integers.
      if (Offset % Bits)
        return;
      // The InReg flag is only required if there are any floats < 64 bits.
      if (Bits < 64)
        InReg = true;
      pad(Offset);
      Elems.push_back(Ty);
      Size = Offset + Bits;
    }

    // Add a struct type to the coercion type, starting at Offset (in bits).
    void addStruct(uint64_t Offset, llvm::StructType *StrTy) {
      const llvm::StructLayout *Layout = DL.getStructLayout(StrTy);
      for (unsigned i = 0, e = StrTy->getNumElements(); i != e; ++i) {
        llvm::Type *ElemTy = StrTy->getElementType(i);
        uint64_t ElemOffset = Offset + Layout->getElementOffsetInBits(i);
        switch (ElemTy->getTypeID()) {
        case llvm::Type::StructTyID:
          addStruct(ElemOffset, cast<llvm::StructType>(ElemTy));
          break;
        case llvm::Type::FloatTyID:
          addFloat(ElemOffset, ElemTy, 32);
          break;
        case llvm::Type::DoubleTyID:
          addFloat(ElemOffset, ElemTy, 64);
          break;
        case llvm::Type::FP128TyID:
          addFloat(ElemOffset, ElemTy, 128);
          break;
        case llvm::Type::PointerTyID:
          if (ElemOffset % 64 == 0) {
            pad(ElemOffset);
            Elems.push_back(ElemTy);
            Size += 64;
          }
          break;
        default:
          break;
        }
      }
    }

    // Check if Ty is a usable substitute for the coercion type.
    bool isUsableType(llvm::StructType *Ty) const {
      return llvm::ArrayRef(Elems) == Ty->elements();
    }

    // Get the coercion type as a literal struct type.
    llvm::Type *getType() const {
      if (Elems.size() == 1)
        return Elems.front();
      else
        return llvm::StructType::get(Context, Elems);
    }
  };
};
} // end anonymous namespace

ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit,
                                        unsigned &RegOffset) const {
  if (Ty->isVoidType())
    return ABIArgInfo::getIgnore();

  auto &Context = getContext();
  auto &VMContext = getVMContext();

  // FIXME: the GCC-style `aligned` attribute on typedefs is not taken into
  // account here, because the canonicalized type no longer has that
  // information. Hence such over-aligned typedefs are not ABI-compatible with
  // GCC.
  //
  // This is different from the `aligned` attribute on structs or fields, which
  // is taken into account.
  unsigned Alignment = Context.getTypeAlign(Ty);
  uint64_t Size = Context.getTypeSize(Ty);

  // Anything too big to fit in registers is passed with an explicit indirect
  // pointer / sret pointer.
  if (Size > SizeLimit) {
    RegOffset += 1;
    return getNaturalAlignIndirect(
        Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
        /*ByVal=*/false);
  }

  // An argument that is passed in registers but has an alignment higher than 8
  // bytes must be register-aligned. Insert a dummy i64 argument to fill the
  // odd-numbered register.
  //
  // See SCD 2.4.1, pages 3P-11 and 3P-12.
  llvm::Type *Padding = (Alignment > 64 && RegOffset % 2 != 0)
                            ? llvm::Type::getInt64Ty(VMContext)
                            : nullptr;
  unsigned PaddingSlots = Padding ? 1 : 0;
  unsigned SizeSlots = llvm::divideCeil(Size, 64);

  // Treat an enum type as its underlying type.
  if (const auto *ED = Ty->getAsEnumDecl())
    Ty = ED->getIntegerType();

  // Integer types smaller than a register are extended.
  if (Size < 64 && Ty->isIntegerType()) {
    RegOffset += PaddingSlots + SizeSlots;
    return ABIArgInfo::getExtend(Ty, /*T=*/nullptr, Padding);
  }

  if (const auto *EIT = Ty->getAs<BitIntType>())
    if (EIT->getNumBits() < 64) {
      RegOffset += PaddingSlots + SizeSlots;
      return ABIArgInfo::getExtend(Ty, /*T=*/nullptr, Padding);
    }

  // When being GCC-compatible, cast a complex char, short and int to an integer
  // type of the right size to get the correct scalar-like behavior. Other
  // complex types fall through and are treated like a struct containing the
  // real and imaginary parts, e.g. `{ i64, i64 }` or `{ double, double }`.
  if (IsComplexGnuABI) {
    const auto *CT = Ty->getAs<ComplexType>();
    if (CT && CT->getElementType()->isIntegerType()) {
      uint64_t ElementTypeSize = Context.getTypeSize(CT->getElementType());
      if (ElementTypeSize <= 32) {
        RegOffset += 1;
        return ABIArgInfo::getDirect(
            llvm::IntegerType::get(VMContext, 2 * ElementTypeSize),
            /*Offset=*/0, Padding);
      }
    }
  }

  // Other non-aggregates go in registers.
  if (!isAggregateTypeForABI(Ty)) {
    RegOffset += PaddingSlots + SizeSlots;
    return ABIArgInfo::getDirect(/*T=*/nullptr, /*Offset=*/0, Padding);
  }

  // If a C++ object has either a non-trivial copy constructor or a non-trivial
  // destructor, it is passed with an explicit indirect pointer / sret pointer.
  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
    RegOffset += 1;
    return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
                                   RAA == CGCXXABI::RAA_DirectInMemory);
  }

  // This is a small aggregate type that should be passed in registers.
  // Build a coercion type from the LLVM struct type.
  llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
  if (!StrTy) {
    RegOffset += PaddingSlots + SizeSlots;
    return ABIArgInfo::getDirect(/*T=*/nullptr, /*Offset=*/0, Padding);
  }

  CoerceBuilder CB(VMContext, getDataLayout());
  CB.addStruct(0, StrTy);
  // All structs, even empty ones, should take up a register argument slot,
  // so pin the minimum struct size to one bit.
  CB.pad(llvm::alignTo(
      std::max(CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue(), uint64_t(1)),
      64));
  RegOffset += PaddingSlots + CB.Size / 64;

  // Try to use the original type for coercion.
  llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();

  ABIArgInfo AAI = ABIArgInfo::getDirect(CoerceTy, 0, Padding);
  AAI.setInReg(CB.InReg);
  return AAI;
}

RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                                 QualType Ty, AggValueSlot Slot) const {
  CharUnits SlotSize = CharUnits::fromQuantity(8);
  auto TInfo = getContext().getTypeInfoInChars(Ty);

  // Zero-sized types have a width of one byte for parameter passing purposes.
  TInfo.Width = std::max(TInfo.Width, CharUnits::fromQuantity(1));

  // Small _Complex types are right-adjusted, but small aggregates are not.
  bool ForceRightAdjust = Ty->isAnyComplexType();

  // Arguments bigger than 2*SlotSize bytes are passed indirectly.
  return emitVoidPtrVAArg(CGF, VAListAddr, Ty,
                          /*IsIndirect=*/TInfo.Width > 2 * SlotSize, TInfo,
                          SlotSize,
                          /*AllowHigherAlign=*/true, Slot, ForceRightAdjust);
}

void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI) const {
  unsigned RetOffset = 0;
  ABIArgInfo RetType = classifyType(FI.getReturnType(), 32 * 8, RetOffset);
  FI.getReturnInfo() = RetType;

  // Indirect returns will have its pointer passed as an argument.
  unsigned ArgOffset = RetType.isIndirect() ? RetOffset : 0;
  for (auto &I : FI.arguments())
    I.info = classifyType(I.type, 16 * 8, ArgOffset);
}

namespace {
class SparcV9TargetCodeGenInfo : public TargetCodeGenInfo {
public:
  SparcV9TargetCodeGenInfo(CodeGenTypes &CGT)
      : TargetCodeGenInfo(std::make_unique<SparcV9ABIInfo>(CGT)) {}

  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
    return 14;
  }

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

  llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *Address) const override {
    return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
                                 llvm::ConstantInt::get(CGF.Int32Ty, 8));
  }

  llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *Address) const override {
    return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
                                 llvm::ConstantInt::get(CGF.Int32Ty, -8));
  }
};
} // end anonymous namespace

bool
SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                                                llvm::Value *Address) const {
  // This is calculated from the LLVM and GCC tables and verified
  // against gcc output.  AFAIK all 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);

  // 0-31: the 8-byte general-purpose registers
  AssignToArrayRange(Builder, Address, Eight8, 0, 31);

  // 32-63: f0-31, the 4-byte floating-point registers
  AssignToArrayRange(Builder, Address, Four8, 32, 63);

  //   Y   = 64
  //   PSR = 65
  //   WIM = 66
  //   TBR = 67
  //   PC  = 68
  //   NPC = 69
  //   FSR = 70
  //   CSR = 71
  AssignToArrayRange(Builder, Address, Eight8, 64, 71);

  // 72-87: d0-15, the 8-byte floating-point registers
  AssignToArrayRange(Builder, Address, Eight8, 72, 87);

  return false;
}

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

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