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

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

#ifndef _GTRACE_H
#define _GTRACE_H

#include "ged.h"

#define GLIT_VERSION_MAJOR 1
#define GLIT_VERSION_MINOR 6

#define GLIT_GENERIC_BASE_VERSION_MAJOR 1
#define GLIT_GENERIC_BASE_VERSION_MINOR 6

#pragma pack(push, 1)

/*! @internal
 * GLIT version Changelog:
 * 6. 1.6 Configurable instruction trace
 * 5. 1.5 DPAS instruction emulation added
 * 4. 1.4 Moved instruction decode from Gentrace to GTReplay side (backward compatability)
 * 3. 1.3.Multi-tile supported
 * 2. 1.2.PVC supported
 * 1. 1.1.DG2 supported
 * 1. 1.0 First introduction of gLIT
 * 0. 0.0 Not supported
 */
typedef struct {
    uint16_t ver_major;
    uint16_t ver_minor;
} version_t;

enum GLIT_MODE {
    GLIT_MODE_NORMAL = 0,
    GLIT_MODE_TEST   = 1,
    GLIT_MODE_INVALID
};

typedef struct {
    uint32_t      id;           ///< instruction ID within the kernel
    uint32_t      offset;       ///< instruction offset within the kernel binary
    uint32_t      bbl_id;       ///< ID of the basic block containing this instruction
    uint8_t       encode[16];   ///< Instruction encode bits
    uint8_t       disasm[1024]; ///< disasm of the instruction
} inst_info_t;

/// @internal Packed trace instruction description
typedef struct
{
    uint32_t    offset;        ///< Offset of the instruction within the kernel
    uint32_t    dst;           ///< Destination register base
    uint32_t    num_ret_regs;  ///< Number of returned registers
} trace_instr_data_t;

enum class GLIT_PROPERTIES {
    SLM_READS     = (1 << 0), // reads from SLM
    SCRATCH_READS = (1 << 1), // reads from Scratch area
    DPAS          = (1 << 2), // systolic array instructions
    MATH          = (1 << 3), // math instructions
};

class GlitProperties {
public:
    static GlitProperties* Instance()
    {
        static GlitProperties instance;
        return &instance;
    }

    uint64_t GetProperties() const { return _properties;  }

    uint32_t GetMode() const { return _mode; }

    void     SetMode(uint32_t mode) { _mode = mode; }

    void     SetProperties(uint64_t properties) { _properties = properties; }

    void     SetProperty(GLIT_PROPERTIES property) { _properties |= (uint64_t)property; }

    bool     IsEnabled(GLIT_PROPERTIES properties) const { return ((_properties & (uint64_t)properties) == (uint64_t)properties); }

    bool     IsTestMode() const   { return _mode == GLIT_MODE_TEST; }

    bool     IsNormalMode() const { return _mode == GLIT_MODE_NORMAL; }

private:
    GlitProperties() = default;
    ~GlitProperties() = default;

private:
    uint64_t  _properties = 0;
    uint32_t  _mode = GLIT_MODE_NORMAL;
};

#pragma pack(pop)

#endif // _GTRACE_H
