/*========================== begin_copyright_notice ============================
Copyright (C) 2021-2022 Intel Corporation

SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/

/*!
 * @file Basic properties of the GEN architecture and concrete GEN models
 */

#ifndef IGT_GEN_ARCH_H_
#define IGT_GEN_ARCH_H_

#include "ged.h"
#include "gt_basic_defs.h"
#include "gt_gpu_defs.h"
#include "igt_core.h"

namespace gtpin
{
#pragma pack(push, 8)

inline constexpr uint32_t NativeInsSize()   { return 16; }      ///< Size of the native GEN instruction, in bytes
inline constexpr uint32_t CompactInsSize()  { return 8; }       ///< Size of the compact GEN instruction, in bytes
inline constexpr uint32_t MaxInsSize()      { return 16; }      ///< Maximum size of the GEN instruction, in bytes
inline constexpr uint32_t MemPageSize()     { return 0x1000; }  ///< Size of the memory page, in bytes

/* ===================================================================================================== */
// Class IGtGenModel
/* ===================================================================================================== */
/*! @ingroup GTPIN_GEN_ARCH
 *  @brief Basic properties of the GEN model
 * 
 * @par Availability:
 * - Anytime and anywhere
 */
class IGtGenModel
{
public:
    virtual GtGenModelId Id()                   const = 0; ///< Return identifier of the GEN model represented by this object

    virtual uint32_t     MaxGrfRegs()           const = 0; ///< Return maximum number of GRF registers per thread
    virtual uint32_t     MinGrfRegs()           const = 0; ///< Return minimum number of GRF registers per thread
    virtual uint32_t     GrfRegSize()           const = 0; ///< Return GRF register size, in bytes
    virtual uint32_t     MaxThreadPayloadReg()  const = 0; ///< Return maximum GRF register number in the thread payload

    virtual uint32_t     NumFlagRegs()          const = 0; ///< Return number of ARF flag registers
    virtual uint32_t     NumAccRegs()           const = 0; ///< Return number of ARF accumulator registers
    virtual uint32_t     NumSpRegs()            const = 0; ///< Return number of ARF stack pointer registers (could be zero)

    virtual bool         HasSwsb()              const = 0; ///< Return true, if this GEN model supports software scoreboarding
    virtual uint32_t     NumSbids()             const = 0; ///< Return number software scoreboarding IDs
    virtual bool         HasAccWrCtrl()         const = 0; ///< Return true, if GEN model's instructions have AccWrCtrl field
    virtual uint32_t     MaxThreads()           const = 0; ///< Return maximum number of HW threads
    virtual uint32_t     MaxThreadBuckets()     const = 0; ///< Return effective maximum of HW thread buckets (by FFTID hash)

    /// Return true if this GEN model supports 64-bit atomic operations in the specified address model
    virtual bool        IsAtomic64Supported(GtMemoryAddrModel addrModel) const = 0;

    /// Return true if this GEN model supports 64-bit integer arithmetic operations
    virtual bool        IsArithmetic64Supported() const = 0;

    /// Return Reference to the GtStateRegAccessor instance corresponding to this GEN model
    virtual const GtStateRegAccessor& StateRegAccessor() const = 0;

protected:
    /// @internal Protected destructor
    ~IGtGenModel() = default;
};
GTPIN_ASSERT_PURE_ABSTRACT(IGtGenModel);

/* ===================================================================================================== */
// Class IGtGenArch
/* ===================================================================================================== */
/*! @ingroup GTPIN_GEN_ARCH
 *  @brief Abstract singleton that provides access to generic and model-specific properties of the GEN architecture
 * 
 * @par Availability:
 * - Anytime and anywhere
 */
class IGtGenArch
{
public:
    /// Return object that provides access to basic properties of the specified GEN model
    virtual const IGtGenModel& Model(GtGenModelId id) const = 0;

    /// Given type of the data element (instruction operand), return its size in bytes
    virtual uint32_t DataElementSize(GED_DATA_TYPE dataType) const = 0;

    /// Return true if the specified data type represent an integer element
    virtual bool IsIntegerDataType(GED_DATA_TYPE dataType) const = 0;

    /// Return true if the specified shared function identifies a memory surface
    virtual bool IsMemorySurface(GED_SFID sfid) const = 0;

    /// Return true if the specified shared function identifies a read-only memory surface
    virtual bool IsMemorySurfaceReadOnly(GED_SFID sfid) const = 0;

    /// Return true if the specified shared function identifies a writable memory surface
    virtual bool IsMemorySurfaceWritable(GED_SFID sfid) const = 0;

    /// Return true if the specified message type identifies an atomic memory access
    virtual bool IsAtomicMemoryAccess(GED_MESSAGE_TYPE msgType) const = 0;

    /// Return effective maximum of subdevices (tiles) supported by the specified platform
    virtual uint32_t MaxTiles(GtGpuPlatform platform) const = 0;

protected:
    /// @internal Protected destructor
    virtual ~IGtGenArch() = default;
};
GTPIN_ASSERT_PURE_ABSTRACT(IGtGenArch);

/*! @ingroup GTPIN_GEN_ARCH
 *  @brief Return single instance of the IGtGenArch class
 */
inline const IGtGenArch& GetGenArch()
{
    static const IGtGenArch& genArch = GTPin_GetCore()->GenArch();
    return genArch;
}

/*! @ingroup GTPIN_GEN_ARCH
 *  @brief Return object that provides access to basic properties of the specified GEN model
 */
inline const IGtGenModel& GetGenModel(GtGenModelId id)
{
    return GetGenArch().Model(id);
}

#pragma pack(pop)
}
#endif
