/*
 * Copyright (c) 2015-2021 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * For use for simulation and test purposes only
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "arch/amdgpu/gcn3/gpu_registers.hh"

namespace gem5
{

namespace Gcn3ISA
{
    std::string
    opSelectorToRegSym(int idx, int numRegs)
    {
        std::string reg_sym;

        // we have an SGPR
        if (idx <= REG_SGPR_MAX) {
            if (numRegs > 1)
                reg_sym = "s[" + std::to_string(idx) + ":" +
                    std::to_string(idx + numRegs - 1) + "]";
            else
                reg_sym = "s" + std::to_string(idx);
            return reg_sym;
        } else if (idx >= REG_VGPR_MIN && idx <= REG_VGPR_MAX) {
            if (numRegs > 1)
                reg_sym = "v[" + std::to_string(idx - REG_VGPR_MIN) + ":" +
                    std::to_string(idx - REG_VGPR_MIN + numRegs - 1) + "]";
            else
                reg_sym = "v" + std::to_string(idx - REG_VGPR_MIN);
            return reg_sym;
        } else if (idx >= REG_INT_CONST_POS_MIN &&
                   idx <= REG_INT_CONST_POS_MAX) {
            reg_sym = std::to_string(idx - REG_INT_CONST_POS_MIN + 1);
            return reg_sym;
        } else if (idx >= REG_INT_CONST_NEG_MIN &&
                   idx <= REG_INT_CONST_NEG_MAX) {
            int inline_val = -1 - (idx - REG_INT_CONST_NEG_MIN);
            reg_sym = std::to_string(inline_val);
            return reg_sym;
        }

        switch (idx) {
          case REG_FLAT_SCRATCH_LO:
            reg_sym = "flat_scratch_lo";
            break;
          case REG_FLAT_SCRATCH_HI:
            reg_sym = "flat_scratch_hi";
            break;
          case REG_VCC_LO:
            reg_sym = "vcc";
            break;
          case REG_M0:
            reg_sym = "m0";
            break;
          case REG_EXEC_LO:
            reg_sym = "exec";
            break;
          case REG_ZERO:
            reg_sym = "0";
            break;
          case REG_POS_HALF:
            reg_sym = "0.5";
            break;
          case REG_NEG_HALF:
            reg_sym = "-0.5";
            break;
          case REG_POS_ONE:
            reg_sym = "1";
            break;
          case REG_NEG_ONE:
            reg_sym = "-1";
            break;
          case REG_POS_TWO:
            reg_sym = "2";
            break;
          case REG_NEG_TWO:
            reg_sym = "-2";
            break;
          case REG_POS_FOUR:
            reg_sym = "4";
            break;
          case REG_NEG_FOUR:
            reg_sym = "-4";
            break;
          default:
            fatal("GCN3 ISA instruction has unknown register index %u\n", idx);
            break;
        }

        return reg_sym;
    }

    int
    opSelectorToRegIdx(int idx, int numScalarRegs)
    {
        int regIdx = -1;

        if (idx <= REG_SGPR_MAX) {
            regIdx = idx;
        } else if (idx >= REG_VGPR_MIN && idx <= REG_VGPR_MAX) {
            regIdx = idx - REG_VGPR_MIN;
        } else if (idx == REG_VCC_LO) {
            /**
             * the VCC register occupies the two highest numbered
             * SRF entries. VCC is typically indexed by specifying
             * VCC_LO (simply called VCC) in the instruction encoding
             * and reading it as a 64b value so we only return the
             * index to the lower half of the VCC register.
             *
             * VCC_LO = s[NUM_SGPRS - 2]
             * VCC_HI = s[NUM_SGPRS - 1]
             *
             */
            regIdx = numScalarRegs - 2;
        } else if (idx == REG_VCC_HI) {
            regIdx = numScalarRegs - 1;
        } else if (idx == REG_FLAT_SCRATCH_LO) {
            /**
             * the FLAT_SCRATCH register occupies the two SRF entries
             * just below VCC. FLAT_SCRATCH is typically indexed by
             * specifying FLAT_SCRATCH_LO (simply called FLAT_SCRATCH)
             * in the instruction encoding and reading it as a 64b value
             * so we only return the index to the lower half of the
             * FLAT_SCRATCH register.
             *
             * FLAT_SCRATCH_LO = s[NUM_SGPRS - 4]
             * FLAT_SCRATCH_HI = s[NUM_SGPRS - 3]
             *
             */
            regIdx = numScalarRegs - 4;
        } else if (idx == REG_FLAT_SCRATCH_HI) {
            regIdx = numScalarRegs - 3;
        }

        return regIdx;
    }

    bool
    isPosConstVal(int opIdx)
    {
        bool is_pos_const_val = (opIdx >= REG_INT_CONST_POS_MIN
            && opIdx <= REG_INT_CONST_POS_MAX);

        return is_pos_const_val;
    }

    bool
    isNegConstVal(int opIdx)
    {
        bool is_neg_const_val = (opIdx >= REG_INT_CONST_NEG_MIN
            && opIdx <= REG_INT_CONST_NEG_MAX);

        return is_neg_const_val;
    }

    bool
    isConstVal(int opIdx)
    {
        bool is_const_val = isPosConstVal(opIdx) || isNegConstVal(opIdx);
        return is_const_val;
    }

    bool
    isLiteral(int opIdx)
    {
        return opIdx == REG_SRC_LITERAL;
    }

    bool
    isExecMask(int opIdx)
    {
        return opIdx == REG_EXEC_LO || opIdx == REG_EXEC_HI;
    }

    bool
    isVccReg(int opIdx)
    {
        return opIdx == REG_VCC_LO || opIdx == REG_VCC_HI;
    }

    bool
    isFlatScratchReg(int opIdx)
    {
        return opIdx == REG_FLAT_SCRATCH_LO || opIdx == REG_FLAT_SCRATCH_HI;
    }

    bool
    isScalarReg(int opIdx)
    {
        // FLAT_SCRATCH and VCC are stored in an SGPR pair
        if (opIdx <= REG_SGPR_MAX || opIdx == REG_FLAT_SCRATCH_LO ||
            opIdx == REG_FLAT_SCRATCH_HI || opIdx == REG_VCC_LO ||
            opIdx == REG_VCC_HI) {
            return true;
        }

        return false;
    }

    bool
    isVectorReg(int opIdx)
    {
        if (opIdx >= REG_VGPR_MIN && opIdx <= REG_VGPR_MAX)
            return true;

        return false;
    }

} // namespace Gcn3ISA
} // namespace gem5
