//===---- TargetInfo.h - Encapsulate target details -------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// These classes wrap the information about a call or function
// definition used to handle ABI compliancy.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H
#define LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H

#include "CGBuilder.h"
#include "CodeGenModule.h"
#include "CGValue.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SyncScope.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"

namespace llvm {
class Constant;
class GlobalValue;
class Type;
class Value;
}

namespace clang {
class Decl;

namespace CodeGen {
class ABIInfo;
class CallArgList;
class CodeGenFunction;
class CGBlockInfo;
class SwiftABIInfo;

/// TargetCodeGenInfo - This class organizes various target-specific
/// codegeneration issues, like target-specific attributes, builtins and so
/// on.
class TargetCodeGenInfo {
  std::unique_ptr<ABIInfo> Info;

protected:
  // Target hooks supporting Swift calling conventions. The target must
  // initialize this field if it claims to support these calling conventions
  // by returning true from TargetInfo::checkCallingConvention for them.
  std::unique_ptr<SwiftABIInfo> SwiftInfo;

  // Returns ABI info helper for the target. This is for use by derived classes.
  template <typename T> const T &getABIInfo() const {
    return static_cast<const T &>(*Info);
  }

public:
  TargetCodeGenInfo(std::unique_ptr<ABIInfo> Info);
  virtual ~TargetCodeGenInfo();

  /// getABIInfo() - Returns ABI info helper for the target.
  const ABIInfo &getABIInfo() const { return *Info; }

  /// Returns Swift ABI info helper for the target.
  const SwiftABIInfo &getSwiftABIInfo() const {
    assert(SwiftInfo && "Swift ABI info has not been initialized");
    return *SwiftInfo;
  }

  /// setTargetAttributes - Provides a convenient hook to handle extra
  /// target-specific attributes for the given global.
  virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
                                   CodeGen::CodeGenModule &M) const {}

  /// emitTargetMetadata - Provides a convenient hook to handle extra
  /// target-specific metadata for the given globals.
  virtual void emitTargetMetadata(
      CodeGen::CodeGenModule &CGM,
      const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames) const {}

  /// Provides a convenient hook to handle extra target-specific globals.
  virtual void emitTargetGlobals(CodeGen::CodeGenModule &CGM) const {}

  /// Any further codegen related checks that need to be done on a function call
  /// in a target specific manner.
  virtual void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc,
                                    const FunctionDecl *Caller,
                                    const FunctionDecl *Callee,
                                    const CallArgList &Args) const {}

  /// Determines the size of struct _Unwind_Exception on this platform,
  /// in 8-bit units.  The Itanium ABI defines this as:
  ///   struct _Unwind_Exception {
  ///     uint64 exception_class;
  ///     _Unwind_Exception_Cleanup_Fn exception_cleanup;
  ///     uint64 private_1;
  ///     uint64 private_2;
  ///   };
  virtual unsigned getSizeOfUnwindException() const;

  /// Controls whether __builtin_extend_pointer should sign-extend
  /// pointers to uint64_t or zero-extend them (the default).  Has
  /// no effect for targets:
  ///   - that have 64-bit pointers, or
  ///   - that cannot address through registers larger than pointers, or
  ///   - that implicitly ignore/truncate the top bits when addressing
  ///     through such registers.
  virtual bool extendPointerWithSExt() const { return false; }

  /// Determines the DWARF register number for the stack pointer, for
  /// exception-handling purposes.  Implements __builtin_dwarf_sp_column.
  ///
  /// Returns -1 if the operation is unsupported by this target.
  virtual int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
    return -1;
  }

  /// Initializes the given DWARF EH register-size table, a char*.
  /// Implements __builtin_init_dwarf_reg_size_table.
  ///
  /// Returns true if the operation is unsupported by this target.
  virtual bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                                       llvm::Value *Address) const {
    return true;
  }

  /// Performs the code-generation required to convert a return
  /// address as stored by the system into the actual address of the
  /// next instruction that will be executed.
  ///
  /// Used by __builtin_extract_return_addr().
  virtual llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
                                           llvm::Value *Address) const {
    return Address;
  }

  /// Performs the code-generation required to convert the address
  /// of an instruction into a return address suitable for storage
  /// by the system in a return slot.
  ///
  /// Used by __builtin_frob_return_addr().
  virtual llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
                                           llvm::Value *Address) const {
    return Address;
  }

  /// Performs a target specific test of a floating point value for things
  /// like IsNaN, Infinity, ... Nullptr is returned if no implementation
  /// exists.
  virtual llvm::Value *
  testFPKind(llvm::Value *V, unsigned BuiltinID, CGBuilderTy &Builder,
             CodeGenModule &CGM) const {
    assert(V->getType()->isFloatingPointTy() && "V should have an FP type.");
    return nullptr;
  }

  /// Corrects the low-level LLVM type for a given constraint and "usual"
  /// type.
  ///
  /// \returns A pointer to a new LLVM type, possibly the same as the original
  /// on success; 0 on failure.
  virtual llvm::Type *adjustInlineAsmType(CodeGen::CodeGenFunction &CGF,
                                          StringRef Constraint,
                                          llvm::Type *Ty) const {
    return Ty;
  }

  /// Target hook to decide whether an inline asm operand can be passed
  /// by value.
  virtual bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF,
                                        llvm::Type *Ty) const {
    return false;
  }

  /// Adds constraints and types for result registers.
  virtual void addReturnRegisterOutputs(
      CodeGen::CodeGenFunction &CGF, CodeGen::LValue ReturnValue,
      std::string &Constraints, std::vector<llvm::Type *> &ResultRegTypes,
      std::vector<llvm::Type *> &ResultTruncRegTypes,
      std::vector<CodeGen::LValue> &ResultRegDests, std::string &AsmString,
      unsigned NumOutputs) const {}

  /// doesReturnSlotInterfereWithArgs - Return true if the target uses an
  /// argument slot for an 'sret' type.
  virtual bool doesReturnSlotInterfereWithArgs() const { return true; }

  /// Retrieve the address of a function to call immediately before
  /// calling objc_retainAutoreleasedReturnValue.  The
  /// implementation of objc_autoreleaseReturnValue sniffs the
  /// instruction stream following its return address to decide
  /// whether it's a call to objc_retainAutoreleasedReturnValue.
  /// This can be prohibitively expensive, depending on the
  /// relocation model, and so on some targets it instead sniffs for
  /// a particular instruction sequence.  This functions returns
  /// that instruction sequence in inline assembly, which will be
  /// empty if none is required.
  virtual StringRef getARCRetainAutoreleasedReturnValueMarker() const {
    return "";
  }

  /// Determine whether a call to objc_retainAutoreleasedReturnValue or
  /// objc_unsafeClaimAutoreleasedReturnValue should be marked as 'notail'.
  virtual bool markARCOptimizedReturnCallsAsNoTail() const { return false; }

  /// Return a constant used by UBSan as a signature to identify functions
  /// possessing type information, or 0 if the platform is unsupported.
  /// This magic number is invalid instruction encoding in many targets.
  virtual llvm::Constant *
  getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const {
    return llvm::ConstantInt::get(CGM.Int32Ty, 0xc105cafe);
  }

  /// Determine whether a call to an unprototyped functions under
  /// the given calling convention should use the variadic
  /// convention or the non-variadic convention.
  ///
  /// There's a good reason to make a platform's variadic calling
  /// convention be different from its non-variadic calling
  /// convention: the non-variadic arguments can be passed in
  /// registers (better for performance), and the variadic arguments
  /// can be passed on the stack (also better for performance).  If
  /// this is done, however, unprototyped functions *must* use the
  /// non-variadic convention, because C99 states that a call
  /// through an unprototyped function type must succeed if the
  /// function was defined with a non-variadic prototype with
  /// compatible parameters.  Therefore, splitting the conventions
  /// makes it impossible to call a variadic function through an
  /// unprototyped type.  Since function prototypes came out in the
  /// late 1970s, this is probably an acceptable trade-off.
  /// Nonetheless, not all platforms are willing to make it, and in
  /// particularly x86-64 bends over backwards to make the
  /// conventions compatible.
  ///
  /// The default is false.  This is correct whenever:
  ///   - the conventions are exactly the same, because it does not
  ///     matter and the resulting IR will be somewhat prettier in
  ///     certain cases; or
  ///   - the conventions are substantively different in how they pass
  ///     arguments, because in this case using the variadic convention
  ///     will lead to C99 violations.
  ///
  /// However, some platforms make the conventions identical except
  /// for passing additional out-of-band information to a variadic
  /// function: for example, x86-64 passes the number of SSE
  /// arguments in %al.  On these platforms, it is desirable to
  /// call unprototyped functions using the variadic convention so
  /// that unprototyped calls to varargs functions still succeed.
  ///
  /// Relatedly, platforms which pass the fixed arguments to this:
  ///   A foo(B, C, D);
  /// differently than they would pass them to this:
  ///   A foo(B, C, D, ...);
  /// may need to adjust the debugger-support code in Sema to do the
  /// right thing when calling a function with no know signature.
  virtual bool isNoProtoCallVariadic(const CodeGen::CallArgList &args,
                                     const FunctionNoProtoType *fnType) const;

  /// Gets the linker options necessary to link a dependent library on this
  /// platform.
  virtual void getDependentLibraryOption(llvm::StringRef Lib,
                                         llvm::SmallString<24> &Opt) const;

  /// Gets the linker options necessary to detect object file mismatches on
  /// this platform.
  virtual void getDetectMismatchOption(llvm::StringRef Name,
                                       llvm::StringRef Value,
                                       llvm::SmallString<32> &Opt) const {}

  /// Get LLVM calling convention for OpenCL kernel.
  virtual unsigned getOpenCLKernelCallingConv() const;

  /// Get target specific null pointer.
  /// \param T is the LLVM type of the null pointer.
  /// \param QT is the clang QualType of the null pointer.
  /// \return ConstantPointerNull with the given type \p T.
  /// Each target can override it to return its own desired constant value.
  virtual llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM,
      llvm::PointerType *T, QualType QT) const;

  /// Get target favored AST address space of a global variable for languages
  /// other than OpenCL and CUDA.
  /// If \p D is nullptr, returns the default target favored address space
  /// for global variable.
  virtual LangAS getGlobalVarAddressSpace(CodeGenModule &CGM,
                                          const VarDecl *D) const;

  /// Get the AST address space for alloca.
  virtual LangAS getASTAllocaAddressSpace() const { return LangAS::Default; }

  /// Perform address space cast of an expression of pointer type.
  /// \param V is the LLVM value to be casted to another address space.
  /// \param SrcAddr is the language address space of \p V.
  /// \param DestAddr is the targeted language address space.
  /// \param DestTy is the destination LLVM pointer type.
  /// \param IsNonNull is the flag indicating \p V is known to be non null.
  virtual llvm::Value *performAddrSpaceCast(CodeGen::CodeGenFunction &CGF,
                                            llvm::Value *V, LangAS SrcAddr,
                                            LangAS DestAddr, llvm::Type *DestTy,
                                            bool IsNonNull = false) const;

  /// Perform address space cast of a constant expression of pointer type.
  /// \param V is the LLVM constant to be casted to another address space.
  /// \param SrcAddr is the language address space of \p V.
  /// \param DestAddr is the targeted language address space.
  /// \param DestTy is the destination LLVM pointer type.
  virtual llvm::Constant *performAddrSpaceCast(CodeGenModule &CGM,
                                               llvm::Constant *V,
                                               LangAS SrcAddr, LangAS DestAddr,
                                               llvm::Type *DestTy) const;

  /// Get address space of pointer parameter for __cxa_atexit.
  virtual LangAS getAddrSpaceOfCxaAtexitPtrParam() const {
    return LangAS::Default;
  }

  /// Get the syncscope used in LLVM IR.
  virtual llvm::SyncScope::ID getLLVMSyncScopeID(const LangOptions &LangOpts,
                                                 SyncScope Scope,
                                                 llvm::AtomicOrdering Ordering,
                                                 llvm::LLVMContext &Ctx) const;

  /// Interface class for filling custom fields of a block literal for OpenCL.
  class TargetOpenCLBlockHelper {
  public:
    typedef std::pair<llvm::Value *, StringRef> ValueTy;
    TargetOpenCLBlockHelper() {}
    virtual ~TargetOpenCLBlockHelper() {}
    /// Get the custom field types for OpenCL blocks.
    virtual llvm::SmallVector<llvm::Type *, 1> getCustomFieldTypes() = 0;
    /// Get the custom field values for OpenCL blocks.
    virtual llvm::SmallVector<ValueTy, 1>
    getCustomFieldValues(CodeGenFunction &CGF, const CGBlockInfo &Info) = 0;
    virtual bool areAllCustomFieldValuesConstant(const CGBlockInfo &Info) = 0;
    /// Get the custom field values for OpenCL blocks if all values are LLVM
    /// constants.
    virtual llvm::SmallVector<llvm::Constant *, 1>
    getCustomFieldValues(CodeGenModule &CGM, const CGBlockInfo &Info) = 0;
  };
  virtual TargetOpenCLBlockHelper *getTargetOpenCLBlockHelper() const {
    return nullptr;
  }

  /// Create an OpenCL kernel for an enqueued block. The kernel function is
  /// a wrapper for the block invoke function with target-specific calling
  /// convention and ABI as an OpenCL kernel. The wrapper function accepts
  /// block context and block arguments in target-specific way and calls
  /// the original block invoke function.
  virtual llvm::Value *
  createEnqueuedBlockKernel(CodeGenFunction &CGF,
                            llvm::Function *BlockInvokeFunc,
                            llvm::Type *BlockTy) const;

  /// \return true if the target supports alias from the unmangled name to the
  /// mangled name of functions declared within an extern "C" region and marked
  /// as 'used', and having internal linkage.
  virtual bool shouldEmitStaticExternCAliases() const { return true; }

  /// \return true if annonymous zero-sized bitfields should be emitted to
  /// correctly distinguish between struct types whose memory layout is the
  /// same, but whose layout may differ when used as argument passed by value
  virtual bool shouldEmitDWARFBitFieldSeparators() const { return false; }

  virtual void setCUDAKernelCallingConvention(const FunctionType *&FT) const {}

  /// Return the device-side type for the CUDA device builtin surface type.
  virtual llvm::Type *getCUDADeviceBuiltinSurfaceDeviceType() const {
    // By default, no change from the original one.
    return nullptr;
  }
  /// Return the device-side type for the CUDA device builtin texture type.
  virtual llvm::Type *getCUDADeviceBuiltinTextureDeviceType() const {
    // By default, no change from the original one.
    return nullptr;
  }

  /// Return the WebAssembly externref reference type.
  virtual llvm::Type *getWasmExternrefReferenceType() const { return nullptr; }

  /// Return the WebAssembly funcref reference type.
  virtual llvm::Type *getWasmFuncrefReferenceType() const { return nullptr; }

  /// Emit the device-side copy of the builtin surface type.
  virtual bool emitCUDADeviceBuiltinSurfaceDeviceCopy(CodeGenFunction &CGF,
                                                      LValue Dst,
                                                      LValue Src) const {
    // DO NOTHING by default.
    return false;
  }
  /// Emit the device-side copy of the builtin texture type.
  virtual bool emitCUDADeviceBuiltinTextureDeviceCopy(CodeGenFunction &CGF,
                                                      LValue Dst,
                                                      LValue Src) const {
    // DO NOTHING by default.
    return false;
  }

  /// Return an LLVM type that corresponds to an OpenCL type.
  virtual llvm::Type *getOpenCLType(CodeGenModule &CGM, const Type *T) const {
    return nullptr;
  }

protected:
  static std::string qualifyWindowsLibrary(StringRef Lib);

  void addStackProbeTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
                                     CodeGen::CodeGenModule &CGM) const;
};

std::unique_ptr<TargetCodeGenInfo>
createDefaultTargetCodeGenInfo(CodeGenModule &CGM);

enum class AArch64ABIKind {
  AAPCS = 0,
  DarwinPCS,
  Win64,
};

std::unique_ptr<TargetCodeGenInfo>
createAArch64TargetCodeGenInfo(CodeGenModule &CGM, AArch64ABIKind Kind);

std::unique_ptr<TargetCodeGenInfo>
createWindowsAArch64TargetCodeGenInfo(CodeGenModule &CGM, AArch64ABIKind K);

std::unique_ptr<TargetCodeGenInfo>
createAMDGPUTargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createARCTargetCodeGenInfo(CodeGenModule &CGM);

enum class ARMABIKind {
  APCS = 0,
  AAPCS = 1,
  AAPCS_VFP = 2,
  AAPCS16_VFP = 3,
};

std::unique_ptr<TargetCodeGenInfo>
createARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind Kind);

std::unique_ptr<TargetCodeGenInfo>
createWindowsARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind K);

std::unique_ptr<TargetCodeGenInfo>
createAVRTargetCodeGenInfo(CodeGenModule &CGM, unsigned NPR, unsigned NRR);

std::unique_ptr<TargetCodeGenInfo>
createBPFTargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createCSKYTargetCodeGenInfo(CodeGenModule &CGM, unsigned FLen);

std::unique_ptr<TargetCodeGenInfo>
createHexagonTargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createLanaiTargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createLoongArchTargetCodeGenInfo(CodeGenModule &CGM, unsigned GRLen,
                                 unsigned FLen);

std::unique_ptr<TargetCodeGenInfo>
createM68kTargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32);

std::unique_ptr<TargetCodeGenInfo>
createMSP430TargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createNVPTXTargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createPNaClTargetCodeGenInfo(CodeGenModule &CGM);

enum class PPC64_SVR4_ABIKind {
  ELFv1 = 0,
  ELFv2,
};

std::unique_ptr<TargetCodeGenInfo>
createAIXTargetCodeGenInfo(CodeGenModule &CGM, bool Is64Bit);

std::unique_ptr<TargetCodeGenInfo>
createPPC32TargetCodeGenInfo(CodeGenModule &CGM, bool SoftFloatABI);

std::unique_ptr<TargetCodeGenInfo>
createPPC64TargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createPPC64_SVR4_TargetCodeGenInfo(CodeGenModule &CGM, PPC64_SVR4_ABIKind Kind,
                                   bool SoftFloatABI);

std::unique_ptr<TargetCodeGenInfo>
createRISCVTargetCodeGenInfo(CodeGenModule &CGM, unsigned XLen, unsigned FLen);

std::unique_ptr<TargetCodeGenInfo>
createCommonSPIRTargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createSPIRVTargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createSparcV8TargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createSparcV9TargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector,
                               bool SoftFloatABI);

std::unique_ptr<TargetCodeGenInfo>
createTCETargetCodeGenInfo(CodeGenModule &CGM);

std::unique_ptr<TargetCodeGenInfo>
createVETargetCodeGenInfo(CodeGenModule &CGM);

enum class WebAssemblyABIKind {
  MVP = 0,
  ExperimentalMV = 1,
};

std::unique_ptr<TargetCodeGenInfo>
createWebAssemblyTargetCodeGenInfo(CodeGenModule &CGM, WebAssemblyABIKind K);

/// The AVX ABI level for X86 targets.
enum class X86AVXABILevel {
  None,
  AVX,
  AVX512,
};

std::unique_ptr<TargetCodeGenInfo> createX86_32TargetCodeGenInfo(
    CodeGenModule &CGM, bool DarwinVectorABI, bool Win32StructABI,
    unsigned NumRegisterParameters, bool SoftFloatABI);

std::unique_ptr<TargetCodeGenInfo>
createWinX86_32TargetCodeGenInfo(CodeGenModule &CGM, bool DarwinVectorABI,
                                 bool Win32StructABI,
                                 unsigned NumRegisterParameters);

std::unique_ptr<TargetCodeGenInfo>
createX86_64TargetCodeGenInfo(CodeGenModule &CGM, X86AVXABILevel AVXLevel);

std::unique_ptr<TargetCodeGenInfo>
createWinX86_64TargetCodeGenInfo(CodeGenModule &CGM, X86AVXABILevel AVXLevel);

std::unique_ptr<TargetCodeGenInfo>
createXCoreTargetCodeGenInfo(CodeGenModule &CGM);

} // namespace CodeGen
} // namespace clang

#endif // LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H
