/*
 * Copyright (C) 2019 Connor Abbott <cwabbott0@gmail.com>
 * Copyright (C) 2019 Lyude Paul <thatslyude@gmail.com>
 * Copyright (C) 2019 Ryan Houdek <Sonicadvance1@gmail.com>
 * Copyright (C) 2019-2020 Collabora, Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "bi_print.h"

const char *
bi_clause_type_name(enum bifrost_clause_type T)
{
        switch (T) {
        case BIFROST_CLAUSE_NONE: return "";
        case BIFROST_CLAUSE_LOAD_VARY: return "load_vary";
        case BIFROST_CLAUSE_UBO: return "ubo";
        case BIFROST_CLAUSE_TEX: return "tex";
        case BIFROST_CLAUSE_SSBO_LOAD: return "load";
        case BIFROST_CLAUSE_SSBO_STORE: return "store";
        case BIFROST_CLAUSE_BLEND: return "blend";
        case BIFROST_CLAUSE_FRAGZ: return "fragz";
        case BIFROST_CLAUSE_ATEST: return "atest";
        case BIFROST_CLAUSE_64BIT: return "64";
        default: return "??";
        }
}

const char *
bi_output_mod_name(enum bifrost_outmod mod)
{
        switch (mod) {
        case BIFROST_NONE: return "";
        case BIFROST_POS: return ".pos";
        case BIFROST_SAT_SIGNED: return ".sat_signed";
        case BIFROST_SAT: return ".sat";
        default: return "invalid";
        }
}

const char *
bi_minmax_mode_name(enum bifrost_minmax_mode mod)
{
        switch (mod) {
        case BIFROST_MINMAX_NONE: return "";
        case BIFROST_NAN_WINS: return ".nan_wins";
        case BIFROST_SRC1_WINS: return ".src1_wins";
        case BIFROST_SRC0_WINS: return ".src0_wins";
        default: return "invalid";
        }
}

const char *
bi_round_mode_name(enum bifrost_roundmode mod)
{
        switch (mod) {
        case BIFROST_RTE: return "";
        case BIFROST_RTP: return ".rtp";
        case BIFROST_RTN: return ".rtn";
        case BIFROST_RTZ: return ".rtz";
        default: return "invalid";
        }
}

const char *
bi_csel_cond_name(enum bifrost_csel_cond cond)
{
        switch (cond) {
        case BIFROST_FEQ_F: return "feq.f";
        case BIFROST_FGT_F: return "fgt.f";
        case BIFROST_FGE_F: return "fge.f";
        case BIFROST_IEQ_F: return "ieq.f";
        case BIFROST_IGT_I: return "igt.i";
        case BIFROST_IGE_I: return "uge.i";
        case BIFROST_UGT_I: return "ugt.i";
        case BIFROST_UGE_I: return "uge.i";
        default: return "invalid";
        }
}

const char *
bi_interp_mode_name(enum bifrost_interp_mode mode)
{
        switch (mode) {
        case BIFROST_INTERP_PER_FRAG: return ".per_frag";
        case BIFROST_INTERP_CENTROID: return ".centroid";
        case BIFROST_INTERP_DEFAULT: return "";
        case BIFROST_INTERP_EXPLICIT: return ".explicit";
        default: return ".unknown";
        }
}

const char *
bi_ldst_type_name(enum bifrost_ldst_type type)
{
        switch (type) {
        case BIFROST_LDST_F16: return "f16";
        case BIFROST_LDST_F32: return "f32";
        case BIFROST_LDST_I32: return "i32";
        case BIFROST_LDST_U32: return "u32";
        default: return "invalid";
        }
}

/* The remaining functions in this file are for IR-internal
 * structures; the disassembler doesn't use them */

const char *
bi_class_name(enum bi_class cl)
{
        switch (cl) {
        case BI_ADD: return "add";
        case BI_ATEST: return "atest";
        case BI_BRANCH: return "branch";
        case BI_CMP: return "cmp";
        case BI_BLEND: return "blend";
        case BI_BITWISE: return "bitwise";
        case BI_COMBINE: return "combine";
        case BI_CONVERT: return "convert";
        case BI_CSEL: return "csel";
        case BI_DISCARD: return "discard";
        case BI_FMA: return "fma";
        case BI_FMOV: return "fmov";
        case BI_FREXP: return "frexp";
        case BI_IMATH: return "imath";
        case BI_LOAD: return "load";
        case BI_LOAD_UNIFORM: return "load_uniform";
        case BI_LOAD_ATTR: return "load_attr";
        case BI_LOAD_VAR: return "load_var";
        case BI_LOAD_VAR_ADDRESS: return "load_var_address";
        case BI_MINMAX: return "minmax";
        case BI_MOV: return "mov";
        case BI_SELECT: return "select";
        case BI_STORE: return "store";
        case BI_STORE_VAR: return "store_var";
        case BI_SPECIAL: return "special";
        case BI_TABLE: return "table";
        case BI_TEX: return "tex";
        case BI_ROUND: return "round";
        case BI_IMUL: return "imul";
        default: return "unknown_class";
        }
}

static bool
bi_print_dest_index(FILE *fp, bi_instruction *ins, unsigned index)
{
        if (!index)
                fprintf(fp, "_");
        else if (index & BIR_INDEX_REGISTER)
                fprintf(fp, "br%u", index & ~BIR_INDEX_REGISTER);
        else if (index & PAN_IS_REG)
                fprintf(fp, "r%u", index >> 1);
        else if (!(index & BIR_SPECIAL))
                fprintf(fp, "%u", (index >> 1) - 1);
        else
                return false;

        return true;
}

static void
bi_print_index(FILE *fp, bi_instruction *ins, unsigned index, unsigned s)
{
        if (bi_print_dest_index(fp, ins, index))
                return;

        if (index & BIR_INDEX_UNIFORM)
                fprintf(fp, "u%u", index & ~BIR_INDEX_UNIFORM);
        else if (index & BIR_INDEX_CONSTANT)
                fprintf(fp, "#0x%" PRIx64, bi_get_immediate(ins, s));
        else if (index & BIR_INDEX_ZERO)
                fprintf(fp, "#0");
        else
                fprintf(fp, "#err");
}

static void
bi_print_src(FILE *fp, bi_instruction *ins, unsigned s)
{
        unsigned src = ins->src[s];
        bool mods = bi_has_source_mods(ins);
        bool abs = ins->src_abs[s] && mods;
        bool neg = ins->src_neg[s] && mods;

        if (neg)
                fprintf(fp, "-");

        if (abs)
                fprintf(fp, "abs(");

        if (ins->type == BI_BITWISE && ins->bitwise.src_invert[s])
                fprintf(fp, "~");

        bi_print_index(fp, ins, src, s);

        if (abs)
                fprintf(fp, ")");
}

static void
bi_print_swizzle(bi_instruction *ins, unsigned src, FILE *fp)
{
        fprintf(fp, ".");

        for (unsigned u = 0; u < bi_get_component_count(ins, src); ++u) {
                assert(ins->swizzle[src][u] < 4);
                fputc("xyzw"[ins->swizzle[src][u]], fp);
        }
}

static const char *
bi_bitwise_op_name(enum bi_bitwise_op op)
{
        switch (op) {
        case BI_BITWISE_AND: return "and";
        case BI_BITWISE_OR: return "or";
        case BI_BITWISE_XOR: return "xor";
        default: return "invalid";
        }
}

static const char *
bi_imath_op_name(enum bi_imath_op op)
{
        switch (op) {
        case BI_IMATH_ADD: return "iadd";
        case BI_IMATH_SUB: return "isub";
        default: return "invalid";
        }
}

const char *
bi_table_op_name(enum bi_table_op op)
{
        switch (op) {
        case BI_TABLE_LOG2_U_OVER_U_1_LOW: return "log2.help";
        default: return "invalid";
        }
}

const char *
bi_special_op_name(enum bi_special_op op)
{
        switch (op) {
        case BI_SPECIAL_FRCP: return "frcp";
        case BI_SPECIAL_FRSQ: return "frsq";
        case BI_SPECIAL_EXP2_LOW: return "exp2_low";
        default: return "invalid";
        }
}

const char *
bi_reduce_op_name(enum bi_reduce_op op)
{
        switch (op) {
        case BI_REDUCE_ADD_FREXPM: return "add_frexpm";
        default: return "invalid";
        }
}

const char *
bi_frexp_op_name(enum bi_frexp_op op)
{
        switch (op) {
        case BI_FREXPE_LOG: return "frexpe_log";
        default: return "invalid";
        }
}

const char *
bi_tex_op_name(enum bi_tex_op op)
{
        switch (op) {
        case BI_TEX_NORMAL: return "normal";
        case BI_TEX_COMPACT: return "compact";
        case BI_TEX_DUAL: return "dual";
        default: return "invalid";
        }
}

static void
bi_print_load_vary(struct bi_load_vary *load, FILE *fp)
{
        fprintf(fp, "%s", bi_interp_mode_name(load->interp_mode));

        if (load->reuse)
                fprintf(fp, ".reuse");

        if (load->flat)
                fprintf(fp, ".flat");
}

const char *
bi_cond_name(enum bi_cond cond)
{
        switch (cond) {
        case BI_COND_ALWAYS: return "always";
        case BI_COND_LT: return "lt";
        case BI_COND_LE: return "le";
        case BI_COND_GE: return "ge";
        case BI_COND_GT: return "gt";
        case BI_COND_EQ: return "eq";
        case BI_COND_NE: return "ne";
        default: return "invalid";
        }
}

static void
bi_print_texture(struct bi_texture *tex, FILE *fp)
{
        fprintf(fp, " - texture %u, sampler %u",
                        tex->texture_index, tex->sampler_index);
}

void
bi_print_instruction(bi_instruction *ins, FILE *fp)
{
        if (ins->type == BI_MINMAX)
                fprintf(fp, "%s", ins->op.minmax == BI_MINMAX_MIN ? "min" : "max");
        else if (ins->type == BI_BITWISE)
                fprintf(fp, "%s", bi_bitwise_op_name(ins->op.bitwise));
        else if (ins->type == BI_IMATH)
                fprintf(fp, "%s", bi_imath_op_name(ins->op.imath));
        else if (ins->type == BI_SPECIAL)
                fprintf(fp, "%s", bi_special_op_name(ins->op.special));
        else if (ins->type == BI_TABLE)
                fprintf(fp, "%s", bi_table_op_name(ins->op.table));
        else if (ins->type == BI_REDUCE_FMA)
                fprintf(fp, "%s", bi_reduce_op_name(ins->op.reduce));
        else if (ins->type == BI_FREXP)
                fprintf(fp, "%s", bi_frexp_op_name(ins->op.frexp));
        else
                fprintf(fp, "%s", bi_class_name(ins->type));

        if ((ins->type == BI_ADD || ins->type == BI_FMA) && ins->op.mscale)
                fprintf(fp, ".mscale");

        if (ins->type == BI_MINMAX)
                fprintf(fp, "%s", bi_minmax_mode_name(ins->minmax));
        else if (ins->type == BI_LOAD_VAR)
                bi_print_load_vary(&ins->load_vary, fp);
        else if (ins->type == BI_BLEND)
                fprintf(fp, ".loc%u", ins->blend_location);
        else if (ins->type == BI_TEX) {
                fprintf(fp, ".%s", bi_tex_op_name(ins->op.texture));
        } else if (ins->type == BI_BITWISE)
                fprintf(fp, ".%cshift", ins->bitwise.rshift ? 'r' : 'l');

        if (bi_class_props[ins->type] & BI_CONDITIONAL)
                fprintf(fp, ".%s", bi_cond_name(ins->cond));

        if (ins->vector_channels)
                fprintf(fp, ".v%u", ins->vector_channels);

        if (ins->dest)
                pan_print_alu_type(ins->dest_type, fp);

        if (bi_has_outmod(ins))
                fprintf(fp, "%s", bi_output_mod_name(ins->outmod));

        if (bi_class_props[ins->type] & BI_ROUNDMODE)
                fprintf(fp, "%s", bi_round_mode_name(ins->roundmode));

        fprintf(fp, " ");
        bool succ = bi_print_dest_index(fp, ins, ins->dest);
        assert(succ);

        if (ins->dest_offset)
                fprintf(fp, "+%u", ins->dest_offset);

        fprintf(fp, ", ");

        bi_foreach_src(ins, s) {
                bi_print_src(fp, ins, s);

                if (ins->src[s] && !(ins->src[s] & (BIR_INDEX_CONSTANT | BIR_INDEX_ZERO))) {
                        pan_print_alu_type(ins->src_types[s], fp);
                        bi_print_swizzle(ins, s, fp);
                }

                if (s < BIR_SRC_COUNT)
                        fprintf(fp, ", ");
        }

        if (ins->type == BI_BRANCH) {
                if (ins->branch_target) {
                        fprintf(fp, "-> block%u", ins->branch_target->base.name);
                } else {
                        fprintf(fp, "-> void");
                }
        } else if (ins->type == BI_TEX) {
                bi_print_texture(&ins->texture, fp);
        }

        fprintf(fp, "\n");
}

void
bi_print_ports(bi_registers *regs, FILE *fp)
{
        for (unsigned i = 0; i < 2; ++i) {
                if (regs->enabled[i])
                        fprintf(fp, "port %u: %u\n", i, regs->port[i]);
        }

        if (regs->write_fma || regs->write_add) {
                fprintf(fp, "port 2 (%s): %u\n",
                                regs->write_add ? "ADD" : "FMA",
                                regs->port[2]);
        }

        if ((regs->write_fma && regs->write_add) || regs->read_port3) {
                fprintf(fp, "port 3 (%s): %u\n",
                                regs->read_port3 ? "read" : "FMA",
                                regs->port[3]);
        }
}

void
bi_print_bundle(bi_bundle *bundle, FILE *fp)
{
        bi_instruction *ins[2] = { bundle->fma, bundle->add };

        for (unsigned i = 0; i < 2; ++i) {
                if (ins[i])
                        bi_print_instruction(ins[i], fp);
                else
                        fprintf(fp, "nop\n");
        }
}

void
bi_print_clause(bi_clause *clause, FILE *fp)
{
        fprintf(fp, "\tid(%u)", clause->scoreboard_id);

        if (clause->dependencies) {
                fprintf(fp, ", wait(");

                for (unsigned i = 0; i < 8; ++i) {
                        if (clause->dependencies & (1 << i))
                                fprintf(fp, "%u ", i);
                }

                fprintf(fp, ")");
        }

        if (!clause->back_to_back)
                fprintf(fp, " nbb %s", clause->branch_conditional ? "branch-cond" : "branch-uncond");

        if (clause->data_register_write_barrier)
                fprintf(fp, " drwb");

        fprintf(fp, "\n");

        for (unsigned i = 0; i < clause->bundle_count; ++i)
                bi_print_bundle(&clause->bundles[i], fp);

        if (clause->constant_count) {
                for (unsigned i = 0; i < clause->constant_count; ++i)
                        fprintf(fp, "%" PRIx64 " ", clause->constants[i]);

                if (clause->branch_constant)
                        fprintf(fp, "*");

                fprintf(fp, "\n");
        }
}

void
bi_print_block(bi_block *block, FILE *fp)
{
        fprintf(fp, "block%u {\n", block->base.name);

        if (block->scheduled) {
                bi_foreach_clause_in_block(block, clause)
                        bi_print_clause(clause, fp);
        } else {
                bi_foreach_instr_in_block(block, ins)
                        bi_print_instruction(ins, fp);
        }

        fprintf(fp, "}");

        if (block->base.successors[0]) {
                fprintf(fp, " -> ");

                pan_foreach_successor((&block->base), succ)
                        fprintf(fp, "block%u ", succ->name);
        }

        if (block->base.predecessors->entries) {
                fprintf(fp, " from");

                bi_foreach_predecessor(block, pred)
                        fprintf(fp, " block%u", pred->base.name);
        }

        fprintf(fp, "\n\n");
}

void
bi_print_shader(bi_context *ctx, FILE *fp)
{
        bi_foreach_block(ctx, block)
                bi_print_block((bi_block *) block, fp);
}
