/*========================== begin_copyright_notice ============================

Copyright (C) 2017-2021 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

#pragma once
#include "Compiler/CodeGenPublic.h"
#include "visaBuilder_interface.h"
#include "common/UFO/portable_compiler.h"

namespace USC
{
    struct SShaderStageBTLayout;
}

namespace llvm
{
    class Function;
}

namespace IGC
{

    enum e_mask : unsigned char
    {
        EMASK_Q1,
        EMASK_Q2,
        EMASK_Q3,
        EMASK_Q4,
        EMASK_H1,
        EMASK_H2,
    };

    enum e_varType : unsigned char
    {
        EVARTYPE_GENERAL,
        EVARTYPE_ADDRESS,
        EVARTYPE_PREDICATE,
        EVARTYPE_SURFACE,
        EVARTYPE_SAMPLER
    };

    enum e_alignment : unsigned char
    {
        // In the increasing alignment order, except AUTO
        // (AUTO: naturally aligned)
        EALIGN_BYTE,
        EALIGN_WORD,
        EALIGN_DWORD,
        EALIGN_QWORD,
        EALIGN_OWORD,
        EALIGN_HWORD,
        EALIGN_32WORD,
        EALIGN_64WORD,
        EALIGN_AUTO
    };

#define EALIGN_GRF (getGRFSize() == 64 ? EALIGN_32WORD : EALIGN_HWORD)
#define EALIGN_2GRF (getGRFSize() == 64 ? EALIGN_64WORD : EALIGN_32WORD)

    // XMACRO defining the CISA opCode
    // need to move to the CISA encoding file when breaking down code
#define DECLARE_CISA_OPCODE(opCode, name, visaname) \
    opCode,
    enum e_opcode
    {
#include "isaDef.h"
    };
#undef DECLARE_CISA_OPCODE

#define DECLARE_CISA_OPCODE(opCode, name, visaname) \
    visaname,
    __attr_unused static ISA_Opcode ConvertOpcode[] =
    {
    #include "isaDef.h"
    };
#undef DECLARE_CISA_OPCODE

    enum e_modifier : unsigned char
    {
        EMOD_NONE,
        EMOD_SAT,
        EMOD_ABS,
        EMOD_NEG,
        EMOD_NEGABS,
        EMOD_NOT,
    };

    enum e_predMode
    {
        EPRED_NORMAL,
        EPRED_ALL,
        EPRED_ANY,
    };

    enum e_instType : unsigned char
    {
        EINSTTYPE_INVALID,
        EINSTTYPE_ALU,
        EINSTTYPE_BRANCH,
        EINSTTYPE_URBWRITE,
        EINSTTYPE_SEND,
        EINSTTYPE_RENDERTARGETWRITE,
        EINSTTYPE_SAMPLE,
        EINSTTYPE_LD,
        EINSTTYPE_INFO,
        EINSTTYPE_GATHER4,
        EINSTTYPE_TYPED4_READ,
        EINSTTYPE_OWLOAD,
        EINSTTYPE_GATHER,
        EINSTTYPE_SCATTER,
        EINSTTYPE_SCATTER4,
        EINSTTYPE_TYPED4_WRITE,
        EINSTTYPE_EOT,
        EINSTTYPE_ADDRADD,
        EINSTTYPE_LDMS,
        EINSTTYPE_BARRIER,
        EINSTTYPE_FENCE,
    };

    enum e_predicate : unsigned char
    {
        EPREDICATE_EQ,
        EPREDICATE_NE,
        EPREDICATE_GT,
        EPREDICATE_GE,
        EPREDICATE_LT,
        EPREDICATE_LE,
    };

    enum e_predefSurface : unsigned char
    {
        ESURFACE_NORMAL,
        ESURFACE_SLM,
        ESURFACE_STATELESS,
        ESURFACE_BINDLESS,
        ESURFACE_SSHBINDLESS,
        ESURFACE_SCRATCH
    };

    enum e_predefSampler : unsigned char
    {
        ESAMPLER_NORMAL,
        ESAMPLER_BINDLESS,
    };

    enum e_barrierKind : unsigned char
    {
        EBARRIER_NORMAL,  // default (signal+wait)
        EBARRIER_SIGNAL,
        EBARRIER_WAIT
    };

    enum e_instance : unsigned char
    {
        EINSTANCE_UNSPECIFIED,
        EINSTANCE_FIRST_HALF,
        EINSTANCE_SECOND_HALF
    };

    class CVariable;

    struct ResourceDescriptor
    {
        CVariable* m_resource;
        e_predefSurface m_surfaceType;
        // this flag is set whenever addrspace is set to ADDRESS_SPACE_THREAD_ARG
        // to access thread arguments. we need to lower such messages
        // using special addressing mode.
        bool m_isThreadArg = false;
        ResourceDescriptor() : m_resource(nullptr), m_surfaceType(ESURFACE_NORMAL),
            m_isThreadArg(false) {}
    };

    struct SamplerDescriptor
    {
        CVariable* m_sampler;
        e_predefSampler m_samplerType;
        SamplerDescriptor() : m_sampler(nullptr), m_samplerType(ESAMPLER_NORMAL) {}
    };

}
