/*
 * 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.
 */

#ifndef __ARCH_GCN3_INSTS_INST_UTIL_HH__
#define __ARCH_GCN3_INSTS_INST_UTIL_HH__

#include <cmath>

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

namespace gem5
{

// values for SDWA select operations
enum SDWASelVals : int
{
    SDWA_BYTE_0 = 0, /* select data[7:0] */
    SDWA_BYTE_1 = 1, /* select data[15:8] */
    SDWA_BYTE_2 = 2, /* select data[23:16] */
    SDWA_BYTE_3 = 3, /* select data[31:24] */
    SDWA_WORD_0 = 4, /* select data[15:0] */
    SDWA_WORD_1 = 5, /* select data[31:16] */
    SDWA_DWORD  = 6  /* select data[31:0] */
};

// values for format of destination bits for SDWA operations
enum SDWADstVals : int
{
    SDWA_UNUSED_PAD      = 0, /* Pad all unused bits with 0 */
    SDWA_UNUSED_SEXT     = 1, /* Sign-extend upper bits; pad lower bits w/ 0 */
    SDWA_UNUSED_PRESERVE = 2  /* select data[31:0] */
};

// values for DPP operations
enum SqDPPVals : int
{
    SQ_DPP_QUAD_PERM_MAX   = 0xFF,
    SQ_DPP_RESERVED        = 0x100,
    SQ_DPP_ROW_SL1         = 0x101,
    SQ_DPP_ROW_SL15        = 0x10F,
    SQ_DPP_ROW_SR1         = 0x111,
    SQ_DPP_ROW_SR15        = 0x11F,
    SQ_DPP_ROW_RR1         = 0x121,
    SQ_DPP_ROW_RR15        = 0x12F,
    SQ_DPP_WF_SL1          = 0x130,
    SQ_DPP_WF_RL1          = 0x134,
    SQ_DPP_WF_SR1          = 0x138,
    SQ_DPP_WF_RR1          = 0x13C,
    SQ_DPP_ROW_MIRROR      = 0x140,
    SQ_DPP_ROW_HALF_MIRROR = 0x141,
    SQ_DPP_ROW_BCAST15     = 0x142,
    SQ_DPP_ROW_BCAST31     = 0x143
};
static const int ROW_SIZE = 16; /* 16 registers per row */
static const int NUM_BANKS = 4; /* 64 registers, 16/bank */

namespace Gcn3ISA
{
    template<typename T>
    inline T
    wholeQuadMode(T val)
    {
        T wqm = 0;
        T mask = 0xF;

        for (T bits = val; mask != 0; mask <<= 4)
            if ((bits & mask) != 0)
                wqm |= mask;

        return wqm;
    }

    template<typename T>
    inline T
    quadMask(T val)
    {
        T qmsk = 0;
        T mask = 0xF;
        T qbit = 0x1;

        for (T bits = val; mask != 0; mask <<= 4, qbit <<= 1) {
            if (bits & mask) {
                qmsk |= qbit;
            }
        }

        return qmsk;
    }

    template<typename T>
    inline ScalarRegI32
    countZeroBits(T val)
    {
        ScalarRegI32 num_zeros
            = std::numeric_limits<T>::digits - popCount(val);

        return num_zeros;
    }

    template<typename T>
    inline ScalarRegI32
    findFirstZero(T val)
    {
        if (val == ~T(0)) {
            return -1;
        }

        return findLsbSet(~val);
    }

    template<typename T>
    inline ScalarRegI32
    findFirstOne(T val)
    {
        if (!val) {
            return -1;
        }

        return findLsbSet(val);
    }

    template<typename T>
    inline ScalarRegI32
    findFirstOneMsb(T val)
    {
        if (!val) {
            return -1;
        }

        return findMsbSet(val);
    }

    template<typename T>
    inline ScalarRegI32
    countZeroBitsMsb(T val)
    {
        if (!val) {
            return -1;
        }

        return std::numeric_limits<T>::digits - 1 - findMsbSet(val);
    }

    inline ScalarRegI32
    firstOppositeSignBit(ScalarRegI32 val)
    {
        bool found(false);
        bool sign_bit = (val & 0x80000000) != 0;
        ScalarRegU32 tmp_val(0);
        int count(0);

        if (!val || val == -1) {
            return -1;
        }

        for (int i = 0; i < std::numeric_limits<ScalarRegU32>::digits; ++i) {
            tmp_val = val & (0x80000000 >> i);

            if (!sign_bit) {
                if (tmp_val) {
                    found = true;
                    break;
                }
            } else {
                if (!tmp_val) {
                    found = true;
                    break;
                }
            }
            ++count;
        }

        if (found) {
            return count;
        } else {
            return -1;
        }
    }

    inline ScalarRegI32
    firstOppositeSignBit(ScalarRegI64 val)
    {
        bool found(false);
        bool sign_bit = (val & 0x8000000000000000ULL) != 0;
        ScalarRegU64 tmp_val(0);
        int count(0);

        if (!val || val == -1) {
            return -1;
        }

        for (int i = 0; i < std::numeric_limits<ScalarRegU64>::digits; ++i) {
            tmp_val = val & (0x8000000000000000ULL >> i);

            if (!sign_bit) {
                if (tmp_val) {
                    found = true;
                    break;
                }
            } else {
                if (!tmp_val) {
                    found = true;
                    break;
                }
            }
            ++count;
        }

        if (found) {
            return count;
        } else {
            return -1;
        }
    }

    template<typename T>
    inline T
    median(T val_0, T val_1, T val_2)
    {
        if (std::is_floating_point<T>::value) {
            return std::fmax(std::fmin(val_0, val_1),
                std::fmin(std::fmax(val_0, val_1), val_2));
        } else {
            return std::max(std::min(val_0, val_1),
                std::min(std::max(val_0, val_1), val_2));
        }
    }

    template <typename T>
    inline T roundNearestEven(T val)
    {
        T int_part = 0;
        T nearest_round = std::floor(val + 0.5);
        if ((int)std::floor(val) % 2 == 0
            && std::modf(std::abs(val), &int_part) == 0.5) {
          nearest_round = nearest_round - 1;
        }

        return nearest_round;
    }

    inline VecElemU32
    muladd(VecElemU64 &dst, VecElemU32 val_0, VecElemU32 val_1,
        VecElemU64 val_2)
    {
        __uint128_t u0 = (__uint128_t)val_0;
        __uint128_t u1 = (__uint128_t)val_1;
        __uint128_t u2 = (__uint128_t)val_2;
        __uint128_t result = u0 * u1 + u2;

        dst = (VecElemU64)result;

        return (VecElemU32)(result >> 64) ? 1 : 0;
    }

    inline VecElemU32
    muladd(VecElemI64 &dst, VecElemI32 val_0, VecElemI32 val_1,
        VecElemI64 val_2)
    {
        __int128_t u0 = (__int128_t)val_0;
        __int128_t u1 = (__int128_t)val_1;
        __int128_t u2 = (__int128_t)val_2;
        __int128_t result = u0 * u1 + u2;

        dst = (VecElemI64)result;

        return (VecElemU32)(result >> 64) ? 1 : 0;
    }

    /**
     * dppInstImpl is a helper function that performs the inputted operation
     * on the inputted vector register lane.  The returned output lane
     * represents the input lane given the destination lane and DPP_CTRL word.
     *
     * Currently the values are:
     * 0x0 - 0xFF: full permute of four threads
     * 0x100: reserved
     * 0x101 - 0x10F: row shift right by 1-15 threads
     * 0x111 - 0x11F: row shift right by 1-15 threads
     * 0x121 - 0x12F: row shift right by 1-15 threads
     * 0x130: wavefront left shift by 1 thread
     * 0x134: wavefront left rotate by 1 thread
     * 0x138: wavefront right shift by 1 thread
     * 0x13C: wavefront right rotate by 1 thread
     * 0x140: mirror threads within row
     * 0x141: mirror threads within 1/2 row (8 threads)
     * 0x142: broadcast 15th thread of each row to next row
     * 0x143: broadcast thread 31 to rows 2 and 3
     */
    int dppInstImpl(SqDPPVals dppCtrl, int currLane, int rowNum,
                    int rowOffset, bool & outOfBounds)
    {
        // local variables
        // newLane will be the same as the input lane unless swizzling happens
        int newLane = currLane;
        // for shift/rotate permutations; positive values are LEFT rotates
        int count = 1;
        int localRowOffset = rowOffset;
        int localRowNum = rowNum;

        if (dppCtrl <= SQ_DPP_QUAD_PERM_MAX) { // DPP_QUAD_PERM{00:FF}
            int quadBase = (currLane & ~(3));
            int quadPix = (currLane & 3);
            quadPix = ((dppCtrl >> (2 * quadPix)) & 3);
            newLane = (quadBase | quadPix);
        } else if (dppCtrl == SQ_DPP_RESERVED) {
            panic("ERROR: instruction using reserved DPP_CTRL value\n");
        } else if ((dppCtrl >= SQ_DPP_ROW_SL1) &&
                   (dppCtrl <= SQ_DPP_ROW_SL15)) { // DPP_ROW_SL{1:15}
            count -= (dppCtrl - SQ_DPP_ROW_SL1 + 1);
            if ((localRowOffset + count >= 0) &&
                (localRowOffset + count < ROW_SIZE)) {
                localRowOffset += count;
                newLane = (rowNum | localRowOffset);
            } else {
                outOfBounds = true;
            }
        } else if ((dppCtrl >= SQ_DPP_ROW_SR1) &&
                   (dppCtrl <= SQ_DPP_ROW_SR15)) { // DPP_ROW_SR{1:15}
            count -= (dppCtrl - SQ_DPP_ROW_SR1 + 1);
            if ((localRowOffset + count >= 0) &&
                (localRowOffset + count < ROW_SIZE)) {
                localRowOffset += count;
                newLane = (rowNum | localRowOffset);
            } else {
                outOfBounds = true;
            }
        } else if ((dppCtrl >= SQ_DPP_ROW_RR1) &&
                   (dppCtrl <= SQ_DPP_ROW_RR15)) { // DPP_ROW_RR{1:15}
            count -= (dppCtrl - SQ_DPP_ROW_RR1 + 1);
            localRowOffset = (localRowOffset + count + ROW_SIZE) % ROW_SIZE;
            newLane = (rowNum | localRowOffset);
        } else if (dppCtrl == SQ_DPP_WF_SL1) { // DPP_WF_SL1
            count = 1;
            if ((currLane >= 0) && (currLane < NumVecElemPerVecReg)) {
                newLane += count;
            } else {
                outOfBounds = true;
            }
        } else if (dppCtrl == SQ_DPP_WF_RL1) { // DPP_WF_RL1
            count = 1;
            newLane = (currLane + count + NumVecElemPerVecReg) %
                      NumVecElemPerVecReg;
        } else if (dppCtrl == SQ_DPP_WF_SR1) { // DPP_WF_SR1
            count = -1;
            int currVal = (currLane + count);
            if ((currVal >= 0) && (currVal < NumVecElemPerVecReg)) {
                newLane += count;
            } else {
                outOfBounds = true;
            }
        } else if (dppCtrl == SQ_DPP_WF_RR1) { // DPP_WF_RR1
            count = -1;
            newLane = (currLane + count + NumVecElemPerVecReg) %
                      NumVecElemPerVecReg;
        } else if (dppCtrl == SQ_DPP_ROW_MIRROR) { // DPP_ROW_MIRROR
            localRowOffset = (15 - localRowOffset);
            newLane = (rowNum | localRowOffset);
        } else if (dppCtrl == SQ_DPP_ROW_HALF_MIRROR) { // DPP_ROW_HALF_MIRROR
            localRowNum = (currLane & -0x7);
            localRowOffset = (currLane & 0x7);
            localRowOffset = (7 - localRowNum);
            newLane = (localRowNum | localRowOffset);
        } else if (dppCtrl == SQ_DPP_ROW_BCAST15) { // DPP_ROW_BCAST15
            count = 15;
            if (currLane > count) {
                newLane = (currLane & ~count) - 1;
            }
        } else if (dppCtrl == SQ_DPP_ROW_BCAST31) { // DPP_ROW_BCAST31
            count = 31;
            if (currLane > count) {
                newLane = (currLane & ~count) - 1;
            }
        } else {
            panic("Unimplemented DPP control operation: %d\n", dppCtrl);
        }

        return newLane;
    }

    /**
     * processDPP is a helper function for implementing Data Parallel Primitive
     * instructions.  This function may be called by many different VOP1
     * instructions to do operations within a register.
     */
    template<typename T>
    void processDPP(GPUDynInstPtr gpuDynInst, InFmt_VOP_DPP dppInst,
                    T & src0)
    {
        // local variables
        SqDPPVals dppCtrl = (SqDPPVals)dppInst.DPP_CTRL;
        int boundCtrl = dppInst.BOUND_CTRL;
        int bankMask = dppInst.BANK_MASK;
        int rowMask = dppInst.ROW_MASK;
        // row, bank info to be calculated per lane
        int rowNum = 0, bankNum = 0, rowOffset = 0;
        // outLane will be the same as the input lane unless swizzling happens
        int outLane = 0;
        bool laneDisabled = false;
        // flags used for determining if a lane should be written to/reset/etc.
        bool outOfBounds = false, zeroSrc = false;
        long long threadValid = 0;

        /**
         * STEP 1a: check if the absolute value (ABS) or negation (NEG) tags
         * are set.  If so, do the appropriate action(s) on src0 and/or src1.
         *
         * NOTE: ABS takes priority over NEG.
         */
        if (dppInst.SRC0_NEG) {
            src0.negModifier();
        }

        if (dppInst.SRC0_ABS) {
            src0.absModifier();
        }

        // iterate over all register lanes, performing steps 2-4
        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            threadValid = (0x1LL << lane);
            /**
             * STEP 2: check the row and bank mask values.  These determine
             * which threads are enabled for the subsequent DPP_CTRL
             * operations.
             */
            rowNum = (lane / ROW_SIZE);
            rowOffset = (lane % ROW_SIZE);
            bankNum = (rowOffset / NUM_BANKS);

            if (((rowMask & (0x1 << rowNum)) == 0)   /* row mask */   ||
                ((bankMask & (0x1 << bankNum)) == 0) /* bank mask */) {
                laneDisabled = true;
                continue;
            }

            /**
             * STEP 4: Handle the potential values of DPP_CTRL:
             * 0x0 - 0xFF: full permute of four threads
             * 0x100: reserved
             * 0x101 - 0x10F: row shift right by 1-15 threads
             * 0x111 - 0x11F: row shift right by 1-15 threads
             * 0x121 - 0x12F: row shift right by 1-15 threads
             * 0x130: wavefront left shift by 1 thread
             * 0x134: wavefront left rotate by 1 thread
             * 0x138: wavefront right shift by 1 thread
             * 0x13C: wavefront right rotate by 1 thread
             * 0x140: mirror threads within row
             * 0x141: mirror threads within 1/2 row (8 threads)
             * 0x142: broadcast 15th thread of each row to next row
             * 0x143: broadcast thread 31 to rows 2 and 3
             */
            if (!laneDisabled) {
                outLane = dppInstImpl(dppCtrl, lane, rowNum, rowOffset,
                                      outOfBounds);
            }

            /**
             * STEP 4: Implement bound control for disabled threads.  If thread
             * is disabled but boundCtrl is set, then we need to set the source
             * data to 0 (i.e., set this lane to 0).
             */
            if (laneDisabled) {
                threadValid = 0;
            } else if (outOfBounds) {
                if (boundCtrl == 1) {
                    zeroSrc = true;
                } else {
                    threadValid = 0;
                }
            } else if (!gpuDynInst->exec_mask[lane]) {
                if (boundCtrl == 1) {
                    zeroSrc = true;
                } else {
                    threadValid = 0;
                }
            }

            if (threadValid != 0 && !outOfBounds && !zeroSrc) {
                assert(!laneDisabled);
                src0[outLane] = src0[lane];
            } else if (zeroSrc) {
                src0[lane] = 0;
            }

            // reset for next iteration
            laneDisabled = false;
        }
    }

    /**
     * processDPP is a helper function for implementing Data Parallel Primitive
     * instructions.  This function may be called by many different
     * VOP2/VOPC instructions to do operations within a register.
     */
    template<typename T>
    void processDPP(GPUDynInstPtr gpuDynInst, InFmt_VOP_DPP dppInst,
                    T & src0, T & src1)
    {
        /**
         * STEP 1b: check if the absolute value (ABS) or negation (NEG) tags
         * are set.  If so, do the appropriate action(s) on src0 and/or src1.
         *
         * NOTE: ABS takes priority over NEG.
         */
        if (dppInst.SRC1_NEG) {
            src1.negModifier();
        }

        if (dppInst.SRC1_ABS) {
            src1.absModifier();
        }

        // Since only difference for VOP1 and VOP2/VOPC instructions is SRC1,
        // which is only used for negation/absolute value, call other version
        // to do everything else.
        processDPP(gpuDynInst, dppInst, src0);
    }

    /**
     * sdwaInstSrcImpl_helper contains the per-lane code for selecting the
     * appropriate bytes/words of the lane and doing the appropriate
     * masking/padding/sign extending.  It returns the value after these
     * operations are done on it.
     */
    template<typename T>
    T sdwaInstSrcImpl_helper(T currOperVal, const T origOperVal,
                             const SDWASelVals sel, const bool signExt)
    {
        // local variables
        int low_bit = 0, high_bit = 0;
        bool signExt_local = signExt;
        T retVal = 0;

        // if we're preserving all of the bits, then we can immediately return
        if (sel == SDWA_DWORD) {
            return currOperVal;
        }

        if (sel < SDWA_WORD_0) { // we are selecting 1 byte
            /*
              Process byte 0 first.  This code eiter selects the original bits
              of byte 0, or makes the bits of the selected byte be byte 0 (and
              next either sign extends or zero's out upper bits).
            */
            low_bit = (sel * Gcn3ISA::BITS_PER_BYTE);
            high_bit = low_bit + Gcn3ISA::MSB_PER_BYTE;
            retVal = bits(currOperVal, high_bit, low_bit);

            // make sure update propagated, since used next
            fatal_if(bits(retVal, Gcn3ISA::MSB_PER_BYTE) !=
                     bits(origOperVal, high_bit),
                     "ERROR: SDWA byte update not propagated: retVal: %d, "
                     "orig: %d\n", bits(retVal, Gcn3ISA::MSB_PER_BYTE),
                     bits(origOperVal, high_bit));
            // sign extended value depends on upper-most bit of the new byte 0
            signExt_local = (signExt &&
                             (bits(retVal, Gcn3ISA::MSB_PER_BYTE, 0) & 0x80));

            // process all other bytes -- if sign extending, make them 1, else
            // all 0's so leave as is
            if (signExt_local) {
                retVal = (uint32_t)sext<Gcn3ISA::MSB_PER_BYTE>(retVal);
            }
        } else if (sel < SDWA_DWORD) { // we are selecting 1 word
            /*
              Process word 0 first.  This code eiter selects the original bits
              of word 0, or makes the bits of the selected word be word 0 (and
              next either sign extends or zero's out upper bits).
            */
            low_bit = (sel & 1) * Gcn3ISA::BITS_PER_WORD;
            high_bit = low_bit + Gcn3ISA::MSB_PER_WORD;
            retVal = bits(currOperVal, high_bit, low_bit);

            // make sure update propagated, since used next
            fatal_if(bits(retVal, Gcn3ISA::MSB_PER_WORD) !=
                     bits(origOperVal, high_bit),
                     "ERROR: SDWA word update not propagated: retVal: %d, "
                     "orig: %d\n",
                     bits(retVal, Gcn3ISA::MSB_PER_WORD),
                     bits(origOperVal, high_bit));
            // sign extended value depends on upper-most bit of the new word 0
            signExt_local = (signExt &&
                             (bits(retVal, Gcn3ISA::MSB_PER_WORD, 0) &
                              0x8000));

            // process other word -- if sign extending, make them 1, else all
            // 0's so leave as is
            if (signExt_local) {
                retVal = (uint32_t)sext<Gcn3ISA::MSB_PER_WORD>(retVal);
            }
        } else {
            assert(sel != SDWA_DWORD); // should have returned earlier
            panic("Unimplemented SDWA select operation: %d\n", sel);
        }

        return retVal;
    }


    /**
     * sdwaInstSrcImpl is a helper function that selects the appropriate
     * bits/bytes for each lane of the inputted source operand of an SDWA
     * instruction, does the appropriate masking/padding/sign extending for the
     * non-selected bits/bytes, and updates the operands values with the
     * resultant value.
     *
     * The desired behavior is:
     *   1.  Select the appropriate bits/bytes based on sel:
     *       0 (SDWA_BYTE_0): select data[7:0]
     *       1 (SDWA_BYTE_1): select data[15:8]
     *       2 (SDWA_BYTE_2): select data[23:16]
     *       3 (SDWA_BYTE_3): select data[31:24]
     *       4 (SDWA_WORD_0): select data[15:0]
     *       5 (SDWA_WORD_1): select data[31:16]
     *       6 (SDWA_DWORD): select data[31:0]
     *   2.  if sign extend is set, then sign extend the value
     */
    template<typename T>
    void sdwaInstSrcImpl(T & currOper, T & origCurrOper,
                         const SDWASelVals sel, const bool signExt)
    {
        // iterate over all lanes, setting appropriate, selected value
        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            currOper[lane] = sdwaInstSrcImpl_helper(currOper[lane],
                                                    origCurrOper[lane], sel,
                                                    signExt);
        }
    }


    /**
     * sdwaInstDstImpl_helper contains the per-lane code for selecting the
     * appropriate bytes/words of the lane and doing the appropriate
     * masking/padding/sign extending.  It returns the value after these
     * operations are done on it.
     */
    template<typename T>
    T sdwaInstDstImpl_helper(T currDstVal, const T origDstVal,
                             const bool clamp, const SDWASelVals sel,
                             const SDWADstVals unusedBits_format)
    {
        // local variables
        int low_bit = 0, high_bit = 0;
        bool signExt = (unusedBits_format == SDWA_UNUSED_SEXT);
        //bool pad = (unusedBits_format == SDWA_UNUSED_PAD);
        bool preserve = (unusedBits_format == SDWA_UNUSED_PRESERVE);
        T retVal = 0, origBits_thisByte = 0, currBits_thisByte = 0,
          origBits_thisWord = 0, currBits_thisWord = 0, newBits = 0;

        // if we're preserving all of the bits, then we can immediately return
        if (unusedBits_format == SDWA_UNUSED_PRESERVE) {
            assert(sel == SDWA_DWORD);
            return currDstVal;
        } else if (sel == SDWA_DWORD) {
            // NOTE: users may set the unused bits variable to anything in this
            // scenario, because it will be ignored
            return currDstVal;
        }

        if (sel < SDWA_WORD_0) { // we are selecting 1 byte
            // if we sign extended depends on upper-most bit of byte 0
            signExt = (signExt &&
                       (bits(currDstVal, Gcn3ISA::MSB_PER_WORD, 0) & 0x80));

            for (int byte = 0; byte < 4; ++byte) {
                low_bit = byte * Gcn3ISA::BITS_PER_BYTE;
                high_bit = low_bit + Gcn3ISA::MSB_PER_BYTE;
                /*
                  Options:
                    1.  byte == sel: we are keeping all bits in this byte
                    2.  preserve is set: keep this byte as is because the
                    output preserve flag is set
                    3.  byte > sel && signExt: we're sign extending and
                    this byte is one of the bytes we need to sign extend
                */
                origBits_thisByte = bits(origDstVal, high_bit, low_bit);
                currBits_thisByte = bits(currDstVal, high_bit, low_bit);
                newBits = ((byte == sel) ? origBits_thisByte :
                           ((preserve) ? currBits_thisByte :
                            (((byte > sel) && signExt) ? 0xff : 0)));
                retVal = insertBits(retVal, high_bit, low_bit, newBits);
            }
        } else if (sel < SDWA_DWORD) { // we are selecting 1 word
            low_bit = 0;
            high_bit = low_bit + Gcn3ISA::MSB_PER_WORD;
            // if we sign extended depends on upper-most bit of word 0
            signExt = (signExt &&
                       (bits(currDstVal, high_bit, low_bit) & 0x8000));

            for (int word = 0; word < 2; ++word) {
                low_bit = word * Gcn3ISA::BITS_PER_WORD;
                high_bit = low_bit + Gcn3ISA::MSB_PER_WORD;
                /*
                  Options:
                    1.  word == sel & 1: we are keeping all bits in this word
                    2.  preserve is set: keep this word as is because the
                    output preserve flag is set
                    3.  word > (sel & 1) && signExt: we're sign extending and
                    this word is one of the words we need to sign extend
                */
                origBits_thisWord = bits(origDstVal, high_bit, low_bit);
                currBits_thisWord = bits(currDstVal, high_bit, low_bit);
                newBits = ((word == (sel & 0x1)) ? origBits_thisWord :
                           ((preserve) ? currBits_thisWord :
                            (((word > (sel & 0x1)) && signExt) ? 0xffff : 0)));
                retVal = insertBits(retVal, high_bit, low_bit, newBits);
            }
        } else {
            assert(sel != SDWA_DWORD); // should have returned earlier
            panic("Unimplemented SDWA select operation: %d\n", sel);
        }

        return retVal;
    }


    /**
     * sdwaInstDestImpl is a helper function that selects the appropriate
     * bits/bytes for the inputted dest operand of an SDWA instruction, does
     * the appropriate masking/padding/sign extending for the non-selected
     * bits/bytes, and updates the operands values with the resultant value.
     *
     * The desired behavior is:
     *   1.  Select the appropriate bits/bytes based on sel:
     *       0 (SDWA_BYTE_0): select data[7:0]
     *       1 (SDWA_BYTE_1): select data[15:8]
     *       2 (SDWA_BYTE_2): select data[23:16]
     *       3 (SDWA_BYTE_3): select data[31:24]
     *       4 (SDWA_WORD_0): select data[15:0]
     *       5 (SDWA_WORD_1): select data[31:16]
     *       6 (SDWA_DWORD): select data[31:0]
     *   2.  either pad, sign extend, or select all bits based on the value of
     *   unusedBits_format:
     *       0 (SDWA_UNUSED_PAD): pad all unused bits with 0
     *       1 (SDWA_UNUSED_SEXT): sign-extend upper bits; pad lower bits w/ 0
     *       2 (SDWA_UNUSED_PRESERVE): select data[31:0]
     */
    template<typename T>
    void sdwaInstDstImpl(T & dstOper, T & origDstOper, const bool clamp,
                         const SDWASelVals sel,
                         const SDWADstVals unusedBits_format)
    {
        // iterate over all lanes, setting appropriate, selected value
        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            dstOper[lane] = sdwaInstDstImpl_helper(dstOper[lane],
                                                   origDstOper[lane], clamp,
                                                   sel, unusedBits_format);
        }
    }


    /**
     * processSDWA_srcHelper is a helper function for implementing sub d-word
     * addressing instructions for the src operands.  This function may be
     * called by many different VOP1/VOP2/VOPC instructions to do operations
     * within a register.  This function is also agnostic of which operand it
     * is operating on, so that it can be called for any src operand.
     */
    template<typename T>
    void processSDWA_src_helper(T & currSrc, T & origCurrSrc,
                                const SDWASelVals src_sel,
                                const bool src_signExt, const bool src_abs,
                                const bool src_neg)
    {
        /**
         * STEP 1: check if the absolute value (ABS) or negation (NEG) tags
         * are set.  If so, do the appropriate action(s) on the src operand.
         *
         * NOTE: According to the CSim implementation, ABS takes priority over
         * NEG.
         */
        if (src_neg) {
            currSrc.negModifier();
        }

        if (src_abs) {
            currSrc.absModifier();
        }

        /**
         * STEP 2: select the appropriate bits for each lane of source operand.
         */
        sdwaInstSrcImpl(currSrc, origCurrSrc, src_sel, src_signExt);
    }


    /**
     * processSDWA_src is a helper function for implementing sub d-word
     * addressing instructions for the src operands.  This function may be
     * called by many different VOP1 instructions to do operations within a
     * register.  processSDWA_dst is called after the math, while
     * processSDWA_src is called before the math.
     */
    template<typename T>
    void processSDWA_src(InFmt_VOP_SDWA sdwaInst, T & src0, T & origSrc0)
    {
        // local variables
        const SDWASelVals src0_sel = (SDWASelVals)sdwaInst.SRC0_SEL;
        const bool src0_signExt = sdwaInst.SRC0_SEXT;
        const bool src0_neg = sdwaInst.SRC0_NEG;
        const bool src0_abs = sdwaInst.SRC0_ABS;

        // NOTE: difference between VOP1 and VOP2/VOPC is that there is no src1
        // operand.  So ensure that SRC1 fields are not set, then call helper
        // function only on src0.
        assert(!sdwaInst.SRC1_SEXT);
        assert(!sdwaInst.SRC1_NEG);
        assert(!sdwaInst.SRC1_ABS);

        processSDWA_src_helper(src0, origSrc0, src0_sel, src0_signExt,
                               src0_abs, src0_neg);
    }


    /**
     * processSDWA_src is a helper function for implementing sub d-word
     * addressing instructions.  This function may be called by many different
     * VOP2/VOPC instructions to do operations within a register.
     * processSDWA_dst is called after the math, while processSDWA_src is
     * called before the math.
     */
    template<typename T>
    void processSDWA_src(InFmt_VOP_SDWA sdwaInst, T & src0, T & origSrc0,
                         T & src1, T & origSrc1)
    {
        // local variables
        const SDWASelVals src0_sel = (SDWASelVals)sdwaInst.SRC0_SEL;
        const bool src0_signExt = sdwaInst.SRC0_SEXT;
        const bool src0_neg = sdwaInst.SRC0_NEG;
        const bool src0_abs = sdwaInst.SRC0_ABS;
        const SDWASelVals src1_sel = (SDWASelVals)sdwaInst.SRC1_SEL;
        const bool src1_signExt = sdwaInst.SRC1_SEXT;
        const bool src1_neg = sdwaInst.SRC1_NEG;
        const bool src1_abs = sdwaInst.SRC1_ABS;

        processSDWA_src_helper(src0, origSrc0, src0_sel, src0_signExt,
                               src0_abs, src0_neg);
        processSDWA_src_helper(src1, origSrc1, src1_sel, src1_signExt,
                               src1_abs, src1_neg);
    }


    /**
     * processSDWA_dst is a helper function for implementing sub d-word
     * addressing instructions for the dst operand.  This function may be
     * called by many different VOP1/VOP2/VOPC instructions to do operations
     * within a register.  processSDWA_dst is called after the math, while
     * processSDWA_src is called before the math.
     */
    template<typename T>
    void processSDWA_dst(InFmt_VOP_SDWA sdwaInst, T & dst, T & origDst)
    {
        // local variables
        const SDWADstVals dst_unusedBits_format =
            (SDWADstVals)sdwaInst.DST_UNUSED;
        const SDWASelVals dst_sel = (SDWASelVals)sdwaInst.DST_SEL;
        const bool clamp = sdwaInst.CLAMP;

        /**
         * STEP 1: select the appropriate bits for dst and pad/sign-extend as
         * appropriate.
         */
        sdwaInstDstImpl(dst, origDst, clamp, dst_sel, dst_unusedBits_format);
    }
} // namespace Gcn3ISA
} // namespace gem5

#endif // __ARCH_GCN3_INSTS_INST_UTIL_HH__
