/*
 * Copyright (c) 2015-2017 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.
 *
 * Authors: Anthony Gutierrez
 */

#ifndef __ARCH_GCN3_INSTS_INST_UTIL_HH__
#define __ARCH_GCN3_INSTS_INST_UTIL_HH__

#include <cmath>

#include "arch/gcn3/registers.hh"

// 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 nearest_round = std::round(val * 0.5) * 2.0;
        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;
            }

            src0.write();
            // 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, T origOperVal, SDWASelVals sel,
                             bool signExt)
    {
        // local variables
        int first_bit = 0, last_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).
            */
            first_bit = (sel * Gcn3ISA::BITS_PER_BYTE);
            last_bit = first_bit + Gcn3ISA::MSB_PER_BYTE;
            retVal = bits(currOperVal, first_bit, last_bit);

            // make sure update propagated, since used next
            assert(bits(retVal, Gcn3ISA::MSB_PER_BYTE) ==
                   bits(origOperVal, (sel * Gcn3ISA::BITS_PER_BYTE) +
                        Gcn3ISA::MSB_PER_BYTE));
            // sign extended value depends on upper-most bit of the new byte 0
            signExt_local = (signExt &&
                             (bits(retVal, 0, Gcn3ISA::MSB_PER_BYTE) & 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).
            */
            first_bit = (sel & 1) * Gcn3ISA::BITS_PER_WORD;
            last_bit = first_bit + Gcn3ISA::MSB_PER_WORD;
            retVal = bits(currOperVal, first_bit, last_bit);

            // make sure update propagated, since used next
            assert(bits(retVal, Gcn3ISA::MSB_PER_WORD) ==
                   bits(origOperVal, ((sel & 1) * Gcn3ISA::BITS_PER_WORD) +
                        Gcn3ISA::MSB_PER_WORD));
            // sign extended value depends on upper-most bit of the new word 0
            signExt_local = (signExt &&
                             (bits(retVal, 0, Gcn3ISA::MSB_PER_WORD) &
                              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, SDWASelVals sel,
                         bool signExt)
    {
        // iterate over all lanes, setting appropriate, selected value
        currOper.read();
        origCurrOper.read();
        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, T origDstVal, bool clamp,
                             SDWASelVals sel, SDWADstVals unusedBits_format)
    {
        // local variables
        int first_bit = 0, last_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, 0, Gcn3ISA::MSB_PER_WORD) & 0x80));

            for (int byte = 0; byte < 4; ++byte) {
                first_bit = byte * Gcn3ISA::BITS_PER_BYTE;
                last_bit = first_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, first_bit, last_bit);
                currBits_thisByte = bits(currDstVal, first_bit, last_bit);
                newBits = ((byte == sel) ? origBits_thisByte :
                           ((preserve) ? currBits_thisByte :
                            (((byte > sel) && signExt) ? 0xff : 0)));
                retVal = insertBits(retVal, first_bit, last_bit, newBits);
            }
        } else if (sel < SDWA_DWORD) { // we are selecting 1 word
            first_bit = 0;
            last_bit = first_bit + Gcn3ISA::MSB_PER_WORD;
            // if we sign extended depends on upper-most bit of word 0
            signExt = (signExt &&
                       (bits(currDstVal, first_bit, last_bit) & 0x8000));

            for (int word = 0; word < 2; ++word) {
                first_bit = word * Gcn3ISA::BITS_PER_WORD;
                last_bit = first_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, first_bit, last_bit);
                currBits_thisWord = bits(currDstVal, first_bit, last_bit);
                newBits = ((word == (sel & 0x1)) ? origBits_thisWord :
                           ((preserve) ? currBits_thisWord :
                            (((word > (sel & 0x1)) && signExt) ? 0xffff : 0)));
                retVal = insertBits(retVal, first_bit, last_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, bool clamp,
                         SDWASelVals sel, SDWADstVals unusedBits_format)
    {
        // iterate over all lanes, setting appropriate, selected value
        dstOper.read();
        origDstOper.read();
        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,
                                SDWASelVals src_sel, bool src_signExt,
                                bool src_abs, 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(GPUDynInstPtr gpuDynInst, InFmt_VOP_SDWA sdwaInst,
                         T & src0, T & origSrc0)
    {
        // local variables
        SDWASelVals src0_sel = (SDWASelVals)sdwaInst.SRC0_SEL;
        bool src0_signExt = sdwaInst.SRC0_SEXT;
        bool src0_neg = sdwaInst.SRC0_NEG;
        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(GPUDynInstPtr gpuDynInst, InFmt_VOP_SDWA sdwaInst,
                         T & src0, T & origSrc0, T & src1, T & origSrc1)
    {
        // local variables
        SDWASelVals src0_sel = (SDWASelVals)sdwaInst.SRC0_SEL;
        bool src0_signExt = sdwaInst.SRC0_SEXT;
        bool src0_neg = sdwaInst.SRC0_NEG;
        bool src0_abs = sdwaInst.SRC0_ABS;
        SDWASelVals src1_sel = (SDWASelVals)sdwaInst.SRC1_SEL;
        bool src1_signExt = sdwaInst.SRC1_SEXT;
        bool src1_neg = sdwaInst.SRC1_NEG;
        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(GPUDynInstPtr gpuDynInst, InFmt_VOP_SDWA sdwaInst,
                         T & dst, T & origDst)
    {
        // local variables
        SDWADstVals dst_unusedBits_format = (SDWADstVals)sdwaInst.DST_UNUSED;
        SDWASelVals dst_sel = (SDWASelVals)sdwaInst.DST_SEL;
        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

#endif // __ARCH_GCN3_INSTS_INST_UTIL_HH__
