/*
 * 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/vega/insts/instructions.hh"

#include <cmath>

#include "arch/amdgpu/vega/insts/inst_util.hh"
#include "debug/VEGA.hh"
#include "debug/GPUSync.hh"
#include "gpu-compute/shader.hh"

namespace gem5
{

namespace VegaISA
{
    // --- Inst_SOP2__S_ADD_U32 class methods ---

    Inst_SOP2__S_ADD_U32::Inst_SOP2__S_ADD_U32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_add_u32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_ADD_U32

    Inst_SOP2__S_ADD_U32::~Inst_SOP2__S_ADD_U32()
    {
    } // ~Inst_SOP2__S_ADD_U32

    // --- description from .arch file ---
    // D.u = S0.u + S1.u;
    // SCC = (S0.u + S1.u >= 0x800000000ULL ? 1 : 0) is an unsigned
    // ---  overflow/carry-out for S_ADDC_U32.
    void
    Inst_SOP2__S_ADD_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() + src1.rawData();
        scc = ((ScalarRegU64)src0.rawData() + (ScalarRegU64)src1.rawData())
            >= 0x100000000ULL ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_SUB_U32 class methods ---

    Inst_SOP2__S_SUB_U32::Inst_SOP2__S_SUB_U32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_sub_u32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_SUB_U32

    Inst_SOP2__S_SUB_U32::~Inst_SOP2__S_SUB_U32()
    {
    } // ~Inst_SOP2__S_SUB_U32

    // --- description from .arch file ---
    // D.u = S0.u - S1.u;
    // SCC = (S1.u > S0.u ? 1 : 0) is an unsigned overflow or carry-out for
    // ---  S_SUBB_U32.
    void
    Inst_SOP2__S_SUB_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() - src1.rawData();
        scc = (src1.rawData() > src0.rawData()) ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_ADD_I32 class methods ---

    Inst_SOP2__S_ADD_I32::Inst_SOP2__S_ADD_I32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_add_i32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_ADD_I32

    Inst_SOP2__S_ADD_I32::~Inst_SOP2__S_ADD_I32()
    {
    } // ~Inst_SOP2__S_ADD_I32

    // --- description from .arch file ---
    // D.i = S0.i + S1.i;
    // SCC = (S0.u[31] == S1.u[31] && S0.u[31] != D.u[31]) is a signed
    // overflow.
    // This opcode is not suitable for use with S_ADDC_U32 for implementing
    // 64-bit operations.
    void
    Inst_SOP2__S_ADD_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() + src1.rawData();
        scc = (bits(src0.rawData(), 31) == bits(src1.rawData(), 31)
            && bits(src0.rawData(), 31) != bits(sdst.rawData(), 31))
            ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_SUB_I32 class methods ---

    Inst_SOP2__S_SUB_I32::Inst_SOP2__S_SUB_I32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_sub_i32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_SUB_I32

    Inst_SOP2__S_SUB_I32::~Inst_SOP2__S_SUB_I32()
    {
    } // ~Inst_SOP2__S_SUB_I32

    // --- description from .arch file ---
    // D.i = S0.i - S1.i;
    // SCC = (S0.u[31] != S1.u[31] && S0.u[31] != D.u[31]) is a signed
    // overflow.
    // CAUTION: The condition code behaviour for this opcode is inconsistent
    // with V_SUB_I32; see V_SUB_I32 for further details.
    // This opcode is not suitable for use with S_SUBB_U32 for implementing
    // 64-bit operations.
    void
    Inst_SOP2__S_SUB_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() - src1.rawData();
        scc = (bits(src0.rawData(), 31) != bits(src1.rawData(), 31)
            && bits(src0.rawData(), 31) != bits(sdst.rawData(), 31)) ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_ADDC_U32 class methods ---

    Inst_SOP2__S_ADDC_U32::Inst_SOP2__S_ADDC_U32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_addc_u32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_ADDC_U32

    Inst_SOP2__S_ADDC_U32::~Inst_SOP2__S_ADDC_U32()
    {
    } // ~Inst_SOP2__S_ADDC_U32

    // --- description from .arch file ---
    // D.u = S0.u + S1.u + SCC;
    // SCC = (S0.u + S1.u + SCC >= 0x800000000ULL ? 1 : 0) is an unsigned
    // overflow.
    void
    Inst_SOP2__S_ADDC_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();
        scc.read();

        sdst = src0.rawData() + src1.rawData() + scc.rawData();
        scc = ((ScalarRegU64)src0.rawData() + (ScalarRegU64)src1.rawData()
            + (ScalarRegU64)scc.rawData()) >= 0x100000000ULL ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_SUBB_U32 class methods ---

    Inst_SOP2__S_SUBB_U32::Inst_SOP2__S_SUBB_U32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_subb_u32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_SUBB_U32

    Inst_SOP2__S_SUBB_U32::~Inst_SOP2__S_SUBB_U32()
    {
    } // ~Inst_SOP2__S_SUBB_U32

    // --- description from .arch file ---
    // D.u = S0.u - S1.u - SCC;
    // SCC = (S1.u + SCC > S0.u ? 1 : 0) is an unsigned overflow.
    void
    Inst_SOP2__S_SUBB_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();
        scc.read();

        sdst = src0.rawData() - src1.rawData() - scc.rawData();
        scc = (src1.rawData() + scc.rawData()) > src0.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_MIN_I32 class methods ---

    Inst_SOP2__S_MIN_I32::Inst_SOP2__S_MIN_I32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_min_i32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_MIN_I32

    Inst_SOP2__S_MIN_I32::~Inst_SOP2__S_MIN_I32()
    {
    } // ~Inst_SOP2__S_MIN_I32

    // --- description from .arch file ---
    // D.i = (S0.i < S1.i) ? S0.i : S1.i;
    // SCC = 1 if S0 is chosen as the minimum value.
    void
    Inst_SOP2__S_MIN_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = std::min(src0.rawData(), src1.rawData());
        scc = (src0.rawData() < src1.rawData()) ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_MIN_U32 class methods ---

    Inst_SOP2__S_MIN_U32::Inst_SOP2__S_MIN_U32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_min_u32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_MIN_U32

    Inst_SOP2__S_MIN_U32::~Inst_SOP2__S_MIN_U32()
    {
    } // ~Inst_SOP2__S_MIN_U32

    // --- description from .arch file ---
    // D.u = (S0.u < S1.u) ? S0.u : S1.u;
    // SCC = 1 if S0 is chosen as the minimum value.
    void
    Inst_SOP2__S_MIN_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = std::min(src0.rawData(), src1.rawData());
        scc = (src0.rawData() < src1.rawData()) ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_MAX_I32 class methods ---

    Inst_SOP2__S_MAX_I32::Inst_SOP2__S_MAX_I32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_max_i32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_MAX_I32

    Inst_SOP2__S_MAX_I32::~Inst_SOP2__S_MAX_I32()
    {
    } // ~Inst_SOP2__S_MAX_I32

    // --- description from .arch file ---
    // D.i = (S0.i > S1.i) ? S0.i : S1.i;
    // SCC = 1 if S0 is chosen as the maximum value.
    void
    Inst_SOP2__S_MAX_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = std::max(src0.rawData(), src1.rawData());
        scc = (src0.rawData() > src1.rawData()) ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_MAX_U32 class methods ---

    Inst_SOP2__S_MAX_U32::Inst_SOP2__S_MAX_U32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_max_u32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_MAX_U32

    Inst_SOP2__S_MAX_U32::~Inst_SOP2__S_MAX_U32()
    {
    } // ~Inst_SOP2__S_MAX_U32

    // --- description from .arch file ---
    // D.u = (S0.u > S1.u) ? S0.u : S1.u;
    // SCC = 1 if S0 is chosen as the maximum value.
    void
    Inst_SOP2__S_MAX_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = std::max(src0.rawData(), src1.rawData());
        scc = (src0.rawData() > src1.rawData()) ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_CSELECT_B32 class methods ---

    Inst_SOP2__S_CSELECT_B32::Inst_SOP2__S_CSELECT_B32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_cselect_b32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_CSELECT_B32

    Inst_SOP2__S_CSELECT_B32::~Inst_SOP2__S_CSELECT_B32()
    {
    } // ~Inst_SOP2__S_CSELECT_B32

    // --- description from .arch file ---
    // D.u = SCC ? S0.u : S1.u (conditional select).
    void
    Inst_SOP2__S_CSELECT_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ConstScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();
        scc.read();

        sdst = scc.rawData() ? src0.rawData() : src1.rawData();

        sdst.write();
    } // execute
    // --- Inst_SOP2__S_CSELECT_B64 class methods ---

    Inst_SOP2__S_CSELECT_B64::Inst_SOP2__S_CSELECT_B64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_cselect_b64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_CSELECT_B64

    Inst_SOP2__S_CSELECT_B64::~Inst_SOP2__S_CSELECT_B64()
    {
    } // ~Inst_SOP2__S_CSELECT_B64

    // --- description from .arch file ---
    // D.u64 = SCC ? S0.u64 : S1.u64 (conditional select).
    void
    Inst_SOP2__S_CSELECT_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ConstScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();
        scc.read();

        sdst = scc.rawData() ? src0.rawData() : src1.rawData();

        sdst.write();
    } // execute
    // --- Inst_SOP2__S_AND_B32 class methods ---

    Inst_SOP2__S_AND_B32::Inst_SOP2__S_AND_B32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_and_b32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_AND_B32

    Inst_SOP2__S_AND_B32::~Inst_SOP2__S_AND_B32()
    {
    } // ~Inst_SOP2__S_AND_B32

    // --- description from .arch file ---
    // D.u = S0.u & S1.u;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_AND_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() & src1.rawData();
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_AND_B64 class methods ---

    Inst_SOP2__S_AND_B64::Inst_SOP2__S_AND_B64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_and_b64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_AND_B64

    Inst_SOP2__S_AND_B64::~Inst_SOP2__S_AND_B64()
    {
    } // ~Inst_SOP2__S_AND_B64

    // --- description from .arch file ---
    // D.u64 = S0.u64 & S1.u64;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_AND_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() & src1.rawData();
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_OR_B32 class methods ---

    Inst_SOP2__S_OR_B32::Inst_SOP2__S_OR_B32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_or_b32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_OR_B32

    Inst_SOP2__S_OR_B32::~Inst_SOP2__S_OR_B32()
    {
    } // ~Inst_SOP2__S_OR_B32

    // --- description from .arch file ---
    // D.u = S0.u | S1.u;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_OR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() | src1.rawData();
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_OR_B64 class methods ---

    Inst_SOP2__S_OR_B64::Inst_SOP2__S_OR_B64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_or_b64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_OR_B64

    Inst_SOP2__S_OR_B64::~Inst_SOP2__S_OR_B64()
    {
    } // ~Inst_SOP2__S_OR_B64

    // --- description from .arch file ---
    // D.u64 = S0.u64 | S1.u64;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_OR_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() | src1.rawData();
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_XOR_B32 class methods ---

    Inst_SOP2__S_XOR_B32::Inst_SOP2__S_XOR_B32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_xor_b32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_XOR_B32

    Inst_SOP2__S_XOR_B32::~Inst_SOP2__S_XOR_B32()
    {
    } // ~Inst_SOP2__S_XOR_B32

    // --- description from .arch file ---
    // D.u = S0.u ^ S1.u;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_XOR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() ^ src1.rawData();
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_XOR_B64 class methods ---

    Inst_SOP2__S_XOR_B64::Inst_SOP2__S_XOR_B64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_xor_b64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_XOR_B64

    Inst_SOP2__S_XOR_B64::~Inst_SOP2__S_XOR_B64()
    {
    } // ~Inst_SOP2__S_XOR_B64

    // --- description from .arch file ---
    // D.u64 = S0.u64 ^ S1.u64;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_XOR_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() ^ src1.rawData();
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_ANDN2_B32 class methods ---

    Inst_SOP2__S_ANDN2_B32::Inst_SOP2__S_ANDN2_B32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_andn2_b32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_ANDN2_B32

    Inst_SOP2__S_ANDN2_B32::~Inst_SOP2__S_ANDN2_B32()
    {
    } // ~Inst_SOP2__S_ANDN2_B32

    // --- description from .arch file ---
    // D.u = S0.u & ~S1.u;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_ANDN2_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() &~ src1.rawData();
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_ANDN2_B64 class methods ---

    Inst_SOP2__S_ANDN2_B64::Inst_SOP2__S_ANDN2_B64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_andn2_b64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_ANDN2_B64

    Inst_SOP2__S_ANDN2_B64::~Inst_SOP2__S_ANDN2_B64()
    {
    } // ~Inst_SOP2__S_ANDN2_B64

    // --- description from .arch file ---
    // D.u64 = S0.u64 & ~S1.u64;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_ANDN2_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() &~ src1.rawData();
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_ORN2_B32 class methods ---

    Inst_SOP2__S_ORN2_B32::Inst_SOP2__S_ORN2_B32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_orn2_b32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_ORN2_B32

    Inst_SOP2__S_ORN2_B32::~Inst_SOP2__S_ORN2_B32()
    {
    } // ~Inst_SOP2__S_ORN2_B32

    // --- description from .arch file ---
    // D.u = S0.u | ~S1.u;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_ORN2_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() |~ src1.rawData();
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_ORN2_B64 class methods ---

    Inst_SOP2__S_ORN2_B64::Inst_SOP2__S_ORN2_B64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_orn2_b64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_ORN2_B64

    Inst_SOP2__S_ORN2_B64::~Inst_SOP2__S_ORN2_B64()
    {
    } // ~Inst_SOP2__S_ORN2_B64

    // --- description from .arch file ---
    // D.u64 = S0.u64 | ~S1.u64;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_ORN2_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = src0.rawData() |~ src1.rawData();
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_NAND_B32 class methods ---

    Inst_SOP2__S_NAND_B32::Inst_SOP2__S_NAND_B32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_nand_b32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_NAND_B32

    Inst_SOP2__S_NAND_B32::~Inst_SOP2__S_NAND_B32()
    {
    } // ~Inst_SOP2__S_NAND_B32

    // --- description from .arch file ---
    // D.u = ~(S0.u & S1.u);
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_NAND_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = ~(src0.rawData() & src1.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_NAND_B64 class methods ---

    Inst_SOP2__S_NAND_B64::Inst_SOP2__S_NAND_B64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_nand_b64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_NAND_B64

    Inst_SOP2__S_NAND_B64::~Inst_SOP2__S_NAND_B64()
    {
    } // ~Inst_SOP2__S_NAND_B64

    // --- description from .arch file ---
    // D.u64 = ~(S0.u64 & S1.u64);
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_NAND_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = ~(src0.rawData() & src1.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_NOR_B32 class methods ---

    Inst_SOP2__S_NOR_B32::Inst_SOP2__S_NOR_B32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_nor_b32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_NOR_B32

    Inst_SOP2__S_NOR_B32::~Inst_SOP2__S_NOR_B32()
    {
    } // ~Inst_SOP2__S_NOR_B32

    // --- description from .arch file ---
    // D.u = ~(S0.u | S1.u);
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_NOR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = ~(src0.rawData() | src1.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_NOR_B64 class methods ---

    Inst_SOP2__S_NOR_B64::Inst_SOP2__S_NOR_B64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_nor_b64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_NOR_B64

    Inst_SOP2__S_NOR_B64::~Inst_SOP2__S_NOR_B64()
    {
    } // ~Inst_SOP2__S_NOR_B64

    // --- description from .arch file ---
    // D.u64 = ~(S0.u64 | S1.u64);
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_NOR_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = ~(src0.rawData() | src1.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_XNOR_B32 class methods ---

    Inst_SOP2__S_XNOR_B32::Inst_SOP2__S_XNOR_B32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_xnor_b32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_XNOR_B32

    Inst_SOP2__S_XNOR_B32::~Inst_SOP2__S_XNOR_B32()
    {
    } // ~Inst_SOP2__S_XNOR_B32

    // --- description from .arch file ---
    // D.u = ~(S0.u ^ S1.u);
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_XNOR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = ~(src0.rawData() ^ src1.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_XNOR_B64 class methods ---

    Inst_SOP2__S_XNOR_B64::Inst_SOP2__S_XNOR_B64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_xnor_b64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_XNOR_B64

    Inst_SOP2__S_XNOR_B64::~Inst_SOP2__S_XNOR_B64()
    {
    } // ~Inst_SOP2__S_XNOR_B64

    // --- description from .arch file ---
    // D.u64 = ~(S0.u64 ^ S1.u64);
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_XNOR_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = ~(src0.rawData() ^ src1.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_LSHL_B32 class methods ---

    Inst_SOP2__S_LSHL_B32::Inst_SOP2__S_LSHL_B32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_lshl_b32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_LSHL_B32

    Inst_SOP2__S_LSHL_B32::~Inst_SOP2__S_LSHL_B32()
    {
    } // ~Inst_SOP2__S_LSHL_B32

    // --- description from .arch file ---
    // D.u = S0.u << S1.u[4:0];
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_LSHL_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = (src0.rawData() << bits(src1.rawData(), 4, 0));
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_LSHL_B64 class methods ---

    Inst_SOP2__S_LSHL_B64::Inst_SOP2__S_LSHL_B64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_lshl_b64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_LSHL_B64

    Inst_SOP2__S_LSHL_B64::~Inst_SOP2__S_LSHL_B64()
    {
    } // ~Inst_SOP2__S_LSHL_B64

    // --- description from .arch file ---
    // D.u64 = S0.u64 << S1.u[5:0];
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_LSHL_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = (src0.rawData() << bits(src1.rawData(), 5, 0));
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_LSHR_B32 class methods ---

    Inst_SOP2__S_LSHR_B32::Inst_SOP2__S_LSHR_B32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_lshr_b32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_LSHR_B32

    Inst_SOP2__S_LSHR_B32::~Inst_SOP2__S_LSHR_B32()
    {
    } // ~Inst_SOP2__S_LSHR_B32

    // --- description from .arch file ---
    // D.u = S0.u >> S1.u[4:0];
    // SCC = 1 if result is non-zero.
    // The vacated bits are set to zero.
    void
    Inst_SOP2__S_LSHR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = (src0.rawData() >> bits(src1.rawData(), 4, 0));
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_LSHR_B64 class methods ---

    Inst_SOP2__S_LSHR_B64::Inst_SOP2__S_LSHR_B64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_lshr_b64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_LSHR_B64

    Inst_SOP2__S_LSHR_B64::~Inst_SOP2__S_LSHR_B64()
    {
    } // ~Inst_SOP2__S_LSHR_B64

    // --- description from .arch file ---
    // D.u64 = S0.u64 >> S1.u[5:0];
    // SCC = 1 if result is non-zero.
    // The vacated bits are set to zero.
    void
    Inst_SOP2__S_LSHR_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = (src0.rawData() >> bits(src1.rawData(), 5, 0));
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_ASHR_I32 class methods ---

    Inst_SOP2__S_ASHR_I32::Inst_SOP2__S_ASHR_I32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_ashr_i32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_ASHR_I32

    Inst_SOP2__S_ASHR_I32::~Inst_SOP2__S_ASHR_I32()
    {
    } // ~Inst_SOP2__S_ASHR_I32

    // --- description from .arch file ---
    // D.i = signext(S0.i) >> S1.u[4:0];
    // SCC = 1 if result is non-zero.
    // The vacated bits are set to the sign bit of the input value.
    void
    Inst_SOP2__S_ASHR_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = (src0.rawData() >> bits(src1.rawData(), 4, 0));
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_ASHR_I64 class methods ---

    Inst_SOP2__S_ASHR_I64::Inst_SOP2__S_ASHR_I64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_ashr_i64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_ASHR_I64

    Inst_SOP2__S_ASHR_I64::~Inst_SOP2__S_ASHR_I64()
    {
    } // ~Inst_SOP2__S_ASHR_I64

    // --- description from .arch file ---
    // D.i64 = signext(S0.i64) >> S1.u[5:0];
    // SCC = 1 if result is non-zero.
    // The vacated bits are set to the sign bit of the input value.
    void
    Inst_SOP2__S_ASHR_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandI64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = (src0.rawData() >> bits(src1.rawData(), 5, 0));
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_BFM_B32 class methods ---

    Inst_SOP2__S_BFM_B32::Inst_SOP2__S_BFM_B32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_bfm_b32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_BFM_B32

    Inst_SOP2__S_BFM_B32::~Inst_SOP2__S_BFM_B32()
    {
    } // ~Inst_SOP2__S_BFM_B32

    // --- description from .arch file ---
    // D.u = ((1 << S0.u[4:0]) - 1) << S1.u[4:0] (bitfield mask).
    void
    Inst_SOP2__S_BFM_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);

        src0.read();
        src1.read();

        sdst = ((1 << bits(src0.rawData(), 4, 0)) - 1)
            << bits(src1.rawData(), 4, 0);

        sdst.write();
    } // execute
    // --- Inst_SOP2__S_BFM_B64 class methods ---

    Inst_SOP2__S_BFM_B64::Inst_SOP2__S_BFM_B64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_bfm_b64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_BFM_B64

    Inst_SOP2__S_BFM_B64::~Inst_SOP2__S_BFM_B64()
    {
    } // ~Inst_SOP2__S_BFM_B64

    // --- description from .arch file ---
    // D.u64 = ((1ULL << S0.u[5:0]) - 1) << S1.u[5:0] (bitfield mask).
    void
    Inst_SOP2__S_BFM_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);

        src0.read();
        src1.read();

        sdst = ((1ULL << bits(src0.rawData(), 5, 0)) - 1)
            << bits(src1.rawData(), 5, 0);

        sdst.write();
    } // execute
    // --- Inst_SOP2__S_MUL_I32 class methods ---

    Inst_SOP2__S_MUL_I32::Inst_SOP2__S_MUL_I32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_mul_i32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_MUL_I32

    Inst_SOP2__S_MUL_I32::~Inst_SOP2__S_MUL_I32()
    {
    } // ~Inst_SOP2__S_MUL_I32

    // --- description from .arch file ---
    // D.i = S0.i * S1.i.
    void
    Inst_SOP2__S_MUL_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        src0.read();
        src1.read();

        sdst = src0.rawData() * src1.rawData();

        sdst.write();
    } // execute
    // --- Inst_SOP2__S_BFE_U32 class methods ---

    Inst_SOP2__S_BFE_U32::Inst_SOP2__S_BFE_U32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_bfe_u32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_BFE_U32

    Inst_SOP2__S_BFE_U32::~Inst_SOP2__S_BFE_U32()
    {
    } // ~Inst_SOP2__S_BFE_U32

    // --- description from .arch file ---
    // Bit field extract. S0 is Data, S1[4:0] is field offset, S1[22:16] is
    // field width.
    // D.u = (S0.u>>S1.u[4:0]) & ((1<<S1.u[22:16])-1);
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_BFE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = (src0.rawData() >> bits(src1.rawData(), 4, 0))
            & ((1 << bits(src1.rawData(), 22, 16)) - 1);
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_BFE_I32 class methods ---

    Inst_SOP2__S_BFE_I32::Inst_SOP2__S_BFE_I32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_bfe_i32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_BFE_I32

    Inst_SOP2__S_BFE_I32::~Inst_SOP2__S_BFE_I32()
    {
    } // ~Inst_SOP2__S_BFE_I32

    // --- description from .arch file ---
    // Bit field extract. S0 is Data, S1[4:0] is field offset, S1[22:16] is
    // field width.
    // D.i = (S0.i>>S1.u[4:0]) & ((1<<S1.u[22:16])-1);
    // Sign-extend the result;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_BFE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = (src0.rawData() >> bits(src1.rawData(), 4, 0))
            & ((1 << bits(src1.rawData(), 22, 16)) - 1);
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_BFE_U64 class methods ---

    Inst_SOP2__S_BFE_U64::Inst_SOP2__S_BFE_U64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_bfe_u64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_BFE_U64

    Inst_SOP2__S_BFE_U64::~Inst_SOP2__S_BFE_U64()
    {
    } // ~Inst_SOP2__S_BFE_U64

    // --- description from .arch file ---
    // Bit field extract. S0 is Data, S1[5:0] is field offset, S1[22:16] is
    // field width.
    // D.u64 = (S0.u64>>S1.u[5:0]) & ((1<<S1.u[22:16])-1);
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_BFE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = (src0.rawData() >> bits(src1.rawData(), 5, 0))
            & ((1 << bits(src1.rawData(), 22, 16)) - 1);
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_BFE_I64 class methods ---

    Inst_SOP2__S_BFE_I64::Inst_SOP2__S_BFE_I64(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_bfe_i64")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_BFE_I64

    Inst_SOP2__S_BFE_I64::~Inst_SOP2__S_BFE_I64()
    {
    } // ~Inst_SOP2__S_BFE_I64

    // --- description from .arch file ---
    // Bit field extract. S0 is Data, S1[5:0] is field offset, S1[22:16] is
    // field width.
    // D.i64 = (S0.i64>>S1.u[5:0]) & ((1<<S1.u[22:16])-1);
    // Sign-extend result;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP2__S_BFE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandI64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        sdst = (src0.rawData() >> bits(src1.rawData(), 5, 0))
            & ((1 << bits(src1.rawData(), 22, 16)) - 1);
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_CBRANCH_G_FORK class methods ---

    Inst_SOP2__S_CBRANCH_G_FORK::Inst_SOP2__S_CBRANCH_G_FORK(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_cbranch_g_fork")
    {
        setFlag(Branch);
    } // Inst_SOP2__S_CBRANCH_G_FORK

    Inst_SOP2__S_CBRANCH_G_FORK::~Inst_SOP2__S_CBRANCH_G_FORK()
    {
    } // ~Inst_SOP2__S_CBRANCH_G_FORK

    // --- description from .arch file ---
    // mask_pass = S0.u64 & EXEC;
    // mask_fail = ~S0.u64 & EXEC;
    // if(mask_pass == EXEC)
    //     PC = S1.u64;
    // elsif(mask_fail == EXEC)
    //     PC += 4;
    // elsif(bitcount(mask_fail) < bitcount(mask_pass))
    //     EXEC = mask_fail;
    //     SGPR[CSP*4] = { S1.u64, mask_pass };
    //     CSP++;
    //     PC += 4;
    // else
    //     EXEC = mask_pass;
    //     SGPR[CSP*4] = { PC + 4, mask_fail };
    //     CSP++;
    //     PC = S1.u64;
    // end.
    // Conditional branch using branch-stack.
    // S0 = compare mask(vcc or any sgpr) and
    // S1 = 64-bit byte address of target instruction.
    // See also S_CBRANCH_JOIN.
    void
    Inst_SOP2__S_CBRANCH_G_FORK::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOP2__S_ABSDIFF_I32 class methods ---

    Inst_SOP2__S_ABSDIFF_I32::Inst_SOP2__S_ABSDIFF_I32(InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_absdiff_i32")
    {
        setFlag(ALU);
    } // Inst_SOP2__S_ABSDIFF_I32

    Inst_SOP2__S_ABSDIFF_I32::~Inst_SOP2__S_ABSDIFF_I32()
    {
    } // ~Inst_SOP2__S_ABSDIFF_I32

    // --- description from .arch file ---
    // D.i = S0.i - S1.i;
    // if(D.i < 0) then D.i = -D.i;
    // SCC = 1 if result is non-zero.
    // Compute the absolute value of difference between two values.
    void
    Inst_SOP2__S_ABSDIFF_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        sdst = std::abs(src0.rawData() - src1.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP2__S_RFE_RESTORE_B64 class methods ---

    Inst_SOP2__S_RFE_RESTORE_B64::Inst_SOP2__S_RFE_RESTORE_B64(
          InFmt_SOP2 *iFmt)
        : Inst_SOP2(iFmt, "s_rfe_restore_b64")
    {
    } // Inst_SOP2__S_RFE_RESTORE_B64

    Inst_SOP2__S_RFE_RESTORE_B64::~Inst_SOP2__S_RFE_RESTORE_B64()
    {
    } // ~Inst_SOP2__S_RFE_RESTORE_B64

    // --- description from .arch file ---
    // PRIV = 0;
    // PC = S0.u64;
    // INST_ATC = S1.u32[0].
    // Return from exception handler and continue, possibly changing the
    // ---  instruction ATC mode.
    // This instruction may only be used within a trap handler.
    // Use this instruction when the main program may be in a different memory
    // ---  space than the trap handler.
    void
    Inst_SOP2__S_RFE_RESTORE_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPK__S_MOVK_I32 class methods ---

    Inst_SOPK__S_MOVK_I32::Inst_SOPK__S_MOVK_I32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_movk_i32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_MOVK_I32

    Inst_SOPK__S_MOVK_I32::~Inst_SOPK__S_MOVK_I32()
    {
    } // ~Inst_SOPK__S_MOVK_I32

    // --- description from .arch file ---
    // D.i = signext(SIMM16) (sign extension).
    void
    Inst_SOPK__S_MOVK_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI32 simm16 = (ScalarRegI32)instData.SIMM16;
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        sdst = simm16;

        sdst.write();
    } // execute
    // --- Inst_SOPK__S_CMOVK_I32 class methods ---

    Inst_SOPK__S_CMOVK_I32::Inst_SOPK__S_CMOVK_I32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmovk_i32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMOVK_I32

    Inst_SOPK__S_CMOVK_I32::~Inst_SOPK__S_CMOVK_I32()
    {
    } // ~Inst_SOPK__S_CMOVK_I32

    // --- description from .arch file ---
    // if(SCC) then D.i = signext(SIMM16);
    // else NOP.
    // Conditional move with sign extension.
    void
    Inst_SOPK__S_CMOVK_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI32 simm16 = (ScalarRegI32)instData.SIMM16;
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ConstScalarOperandU32 scc(gpuDynInst, REG_SCC);

        scc.read();

        if (scc.rawData()) {
            sdst = simm16;
            sdst.write();
        }
    } // execute
    // --- Inst_SOPK__S_CMPK_EQ_I32 class methods ---

    Inst_SOPK__S_CMPK_EQ_I32::Inst_SOPK__S_CMPK_EQ_I32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmpk_eq_i32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMPK_EQ_I32

    Inst_SOPK__S_CMPK_EQ_I32::~Inst_SOPK__S_CMPK_EQ_I32()
    {
    } // ~Inst_SOPK__S_CMPK_EQ_I32

    // --- description from .arch file ---
    // SCC = (S0.i == signext(SIMM16)).
    void
    Inst_SOPK__S_CMPK_EQ_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI32 simm16 = (ScalarRegI32)instData.SIMM16;
        ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        scc = (src.rawData() == simm16) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPK__S_CMPK_LG_I32 class methods ---

    Inst_SOPK__S_CMPK_LG_I32::Inst_SOPK__S_CMPK_LG_I32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmpk_lg_i32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMPK_LG_I32

    Inst_SOPK__S_CMPK_LG_I32::~Inst_SOPK__S_CMPK_LG_I32()
    {
    } // ~Inst_SOPK__S_CMPK_LG_I32

    // --- description from .arch file ---
    // SCC = (S0.i != signext(SIMM16)).
    void
    Inst_SOPK__S_CMPK_LG_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI32 simm16 = (ScalarRegI32)instData.SIMM16;
        ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        scc = (src.rawData() != simm16) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPK__S_CMPK_GT_I32 class methods ---

    Inst_SOPK__S_CMPK_GT_I32::Inst_SOPK__S_CMPK_GT_I32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmpk_gt_i32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMPK_GT_I32

    Inst_SOPK__S_CMPK_GT_I32::~Inst_SOPK__S_CMPK_GT_I32()
    {
    } // ~Inst_SOPK__S_CMPK_GT_I32

    // --- description from .arch file ---
    // SCC = (S0.i > signext(SIMM16)).
    void
    Inst_SOPK__S_CMPK_GT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI32 simm16 = (ScalarRegI32)instData.SIMM16;
        ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        scc = (src.rawData() > simm16) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPK__S_CMPK_GE_I32 class methods ---

    Inst_SOPK__S_CMPK_GE_I32::Inst_SOPK__S_CMPK_GE_I32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmpk_ge_i32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMPK_GE_I32

    Inst_SOPK__S_CMPK_GE_I32::~Inst_SOPK__S_CMPK_GE_I32()
    {
    } // ~Inst_SOPK__S_CMPK_GE_I32

    // --- description from .arch file ---
    // SCC = (S0.i >= signext(SIMM16)).
    void
    Inst_SOPK__S_CMPK_GE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI32 simm16 = (ScalarRegI32)instData.SIMM16;
        ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        scc = (src.rawData() >= simm16) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPK__S_CMPK_LT_I32 class methods ---

    Inst_SOPK__S_CMPK_LT_I32::Inst_SOPK__S_CMPK_LT_I32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmpk_lt_i32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMPK_LT_I32

    Inst_SOPK__S_CMPK_LT_I32::~Inst_SOPK__S_CMPK_LT_I32()
    {
    } // ~Inst_SOPK__S_CMPK_LT_I32

    // --- description from .arch file ---
    // SCC = (S0.i < signext(SIMM16)).
    void
    Inst_SOPK__S_CMPK_LT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI32 simm16 = (ScalarRegI32)instData.SIMM16;
        ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        scc = (src.rawData() < simm16) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPK__S_CMPK_LE_I32 class methods ---

    Inst_SOPK__S_CMPK_LE_I32::Inst_SOPK__S_CMPK_LE_I32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmpk_le_i32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMPK_LE_I32

    Inst_SOPK__S_CMPK_LE_I32::~Inst_SOPK__S_CMPK_LE_I32()
    {
    } // ~Inst_SOPK__S_CMPK_LE_I32

    // --- description from .arch file ---
    // SCC = (S0.i <= signext(SIMM16)).
    void
    Inst_SOPK__S_CMPK_LE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI32 simm16 = (ScalarRegI32)instData.SIMM16;
        ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        scc = (src.rawData() <= simm16) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPK__S_CMPK_EQ_U32 class methods ---

    Inst_SOPK__S_CMPK_EQ_U32::Inst_SOPK__S_CMPK_EQ_U32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmpk_eq_u32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMPK_EQ_U32

    Inst_SOPK__S_CMPK_EQ_U32::~Inst_SOPK__S_CMPK_EQ_U32()
    {
    } // ~Inst_SOPK__S_CMPK_EQ_U32

    // --- description from .arch file ---
    // SCC = (S0.u == SIMM16).
    void
    Inst_SOPK__S_CMPK_EQ_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegU32 simm16 = (ScalarRegU32)instData.SIMM16;
        ConstScalarOperandU32 src(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        scc = (src.rawData() == simm16) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPK__S_CMPK_LG_U32 class methods ---

    Inst_SOPK__S_CMPK_LG_U32::Inst_SOPK__S_CMPK_LG_U32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmpk_lg_u32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMPK_LG_U32

    Inst_SOPK__S_CMPK_LG_U32::~Inst_SOPK__S_CMPK_LG_U32()
    {
    } // ~Inst_SOPK__S_CMPK_LG_U32

    // --- description from .arch file ---
    // SCC = (S0.u != SIMM16).
    void
    Inst_SOPK__S_CMPK_LG_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegU32 simm16 = (ScalarRegU32)instData.SIMM16;
        ConstScalarOperandU32 src(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        scc = (src.rawData() != simm16) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPK__S_CMPK_GT_U32 class methods ---

    Inst_SOPK__S_CMPK_GT_U32::Inst_SOPK__S_CMPK_GT_U32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmpk_gt_u32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMPK_GT_U32

    Inst_SOPK__S_CMPK_GT_U32::~Inst_SOPK__S_CMPK_GT_U32()
    {
    } // ~Inst_SOPK__S_CMPK_GT_U32

    // --- description from .arch file ---
    // SCC = (S0.u > SIMM16).
    void
    Inst_SOPK__S_CMPK_GT_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegU32 simm16 = (ScalarRegU32)instData.SIMM16;
        ConstScalarOperandU32 src(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        scc = (src.rawData() > simm16) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPK__S_CMPK_GE_U32 class methods ---

    Inst_SOPK__S_CMPK_GE_U32::Inst_SOPK__S_CMPK_GE_U32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmpk_ge_u32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMPK_GE_U32

    Inst_SOPK__S_CMPK_GE_U32::~Inst_SOPK__S_CMPK_GE_U32()
    {
    } // ~Inst_SOPK__S_CMPK_GE_U32

    // --- description from .arch file ---
    // SCC = (S0.u >= SIMM16).
    void
    Inst_SOPK__S_CMPK_GE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegU32 simm16 = (ScalarRegU32)instData.SIMM16;
        ConstScalarOperandU32 src(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        scc = (src.rawData() >= simm16) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPK__S_CMPK_LT_U32 class methods ---

    Inst_SOPK__S_CMPK_LT_U32::Inst_SOPK__S_CMPK_LT_U32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmpk_lt_u32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMPK_LT_U32

    Inst_SOPK__S_CMPK_LT_U32::~Inst_SOPK__S_CMPK_LT_U32()
    {
    } // ~Inst_SOPK__S_CMPK_LT_U32

    // --- description from .arch file ---
    // SCC = (S0.u < SIMM16).
    void
    Inst_SOPK__S_CMPK_LT_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegU32 simm16 = (ScalarRegU32)instData.SIMM16;
        ConstScalarOperandU32 src(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        scc = (src.rawData() < simm16) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPK__S_CMPK_LE_U32 class methods ---

    Inst_SOPK__S_CMPK_LE_U32::Inst_SOPK__S_CMPK_LE_U32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cmpk_le_u32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_CMPK_LE_U32

    Inst_SOPK__S_CMPK_LE_U32::~Inst_SOPK__S_CMPK_LE_U32()
    {
    } // ~Inst_SOPK__S_CMPK_LE_U32

    // --- description from .arch file ---
    // SCC = (S0.u <= SIMM16).
    void
    Inst_SOPK__S_CMPK_LE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegU32 simm16 = (ScalarRegU32)instData.SIMM16;
        ConstScalarOperandU32 src(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        scc = (src.rawData() <= simm16) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPK__S_ADDK_I32 class methods ---

    Inst_SOPK__S_ADDK_I32::Inst_SOPK__S_ADDK_I32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_addk_i32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_ADDK_I32

    Inst_SOPK__S_ADDK_I32::~Inst_SOPK__S_ADDK_I32()
    {
    } // ~Inst_SOPK__S_ADDK_I32

    // --- description from .arch file ---
    // D.i = D.i + signext(SIMM16);
    // SCC = overflow.
    void
    Inst_SOPK__S_ADDK_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI16 simm16 = instData.SIMM16;
        ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = src.rawData() + (ScalarRegI32)simm16;
        scc = (bits(src.rawData(), 31) == bits(simm16, 15)
            && bits(src.rawData(), 31) != bits(sdst.rawData(), 31)) ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOPK__S_MULK_I32 class methods ---

    Inst_SOPK__S_MULK_I32::Inst_SOPK__S_MULK_I32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_mulk_i32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_MULK_I32

    Inst_SOPK__S_MULK_I32::~Inst_SOPK__S_MULK_I32()
    {
    } // ~Inst_SOPK__S_MULK_I32

    // --- description from .arch file ---
    // D.i = D.i * signext(SIMM16).
    void
    Inst_SOPK__S_MULK_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI16 simm16 = instData.SIMM16;
        ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = src.rawData() * (ScalarRegI32)simm16;

        sdst.write();
    } // execute
    // --- Inst_SOPK__S_CBRANCH_I_FORK class methods ---

    Inst_SOPK__S_CBRANCH_I_FORK::Inst_SOPK__S_CBRANCH_I_FORK(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_cbranch_i_fork")
    {
        setFlag(Branch);
    } // Inst_SOPK__S_CBRANCH_I_FORK

    Inst_SOPK__S_CBRANCH_I_FORK::~Inst_SOPK__S_CBRANCH_I_FORK()
    {
    } // ~Inst_SOPK__S_CBRANCH_I_FORK

    // --- description from .arch file ---
    // mask_pass = S0.u64 & EXEC;
    // mask_fail = ~S0.u64 & EXEC;
    // target_addr = PC + signext(SIMM16 * 4) + 4;
    // if(mask_pass == EXEC)
    //     PC = target_addr;
    // elsif(mask_fail == EXEC)
    //     PC += 4;
    // elsif(bitcount(mask_fail) < bitcount(mask_pass))
    //     EXEC = mask_fail;
    //     SGPR[CSP*4] = { target_addr, mask_pass };
    //     CSP++;
    //     PC += 4;
    // else
    //     EXEC = mask_pass;
    //     SGPR[CSP*4] = { PC + 4, mask_fail };
    //     CSP++;
    //     PC = target_addr;
    // end.
    // Conditional branch using branch-stack.
    // S0 = compare mask(vcc or any sgpr), and
    // SIMM16 = signed DWORD branch offset relative to next instruction.
    // See also S_CBRANCH_JOIN.
    void
    Inst_SOPK__S_CBRANCH_I_FORK::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPK__S_GETREG_B32 class methods ---

    Inst_SOPK__S_GETREG_B32::Inst_SOPK__S_GETREG_B32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_getreg_b32")
    {
    } // Inst_SOPK__S_GETREG_B32

    Inst_SOPK__S_GETREG_B32::~Inst_SOPK__S_GETREG_B32()
    {
    } // ~Inst_SOPK__S_GETREG_B32

    // --- description from .arch file ---
    // D.u = hardware-reg. Read some or all of a hardware register into the
    // LSBs of D.
    // SIMM16 = {size[4:0], offset[4:0], hwRegId[5:0]}; offset is 0..31, size
    // is 1..32.
    void
    Inst_SOPK__S_GETREG_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPK__S_SETREG_B32 class methods ---

    Inst_SOPK__S_SETREG_B32::Inst_SOPK__S_SETREG_B32(InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_setreg_b32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_SETREG_B32

    Inst_SOPK__S_SETREG_B32::~Inst_SOPK__S_SETREG_B32()
    {
    } // ~Inst_SOPK__S_SETREG_B32

    // --- description from .arch file ---
    // hardware-reg = S0.u. Write some or all of the LSBs of D into a hardware
    // register.
    // SIMM16 = {size[4:0], offset[4:0], hwRegId[5:0]}; offset is 0..31, size
    // is 1..32.
    void
    Inst_SOPK__S_SETREG_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI16 simm16 = instData.SIMM16;
        ScalarRegU32 hwregId = simm16 & 0x3f;
        ScalarRegU32 offset = (simm16 >> 6) & 31;
        ScalarRegU32 size = ((simm16 >> 11) & 31) + 1;

        ScalarOperandU32 hwreg(gpuDynInst, hwregId);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        hwreg.read();
        sdst.read();

        // Store value from SDST to part of the hardware register.
        ScalarRegU32 mask = (((1U << size) - 1U) << offset);
        hwreg = ((hwreg.rawData() & ~mask)
                        | ((sdst.rawData() << offset) & mask));
        hwreg.write();

        // set MODE register to control the behavior of single precision
        // floating-point numbers: denormal mode or round mode
        if (hwregId==1 && size==2
                        && (offset==4 || offset==0)) {
            warn_once("Be cautious that s_setreg_b32 has no real effect "
                            "on FP modes: %s\n", gpuDynInst->disassemble());
            return;
        }

        // panic if not changing MODE of floating-point numbers
        panicUnimplemented();
    } // execute
    // --- Inst_SOPK__S_SETREG_IMM32_B32 class methods ---

    Inst_SOPK__S_SETREG_IMM32_B32::Inst_SOPK__S_SETREG_IMM32_B32(
          InFmt_SOPK *iFmt)
        : Inst_SOPK(iFmt, "s_setreg_imm32_b32")
    {
        setFlag(ALU);
    } // Inst_SOPK__S_SETREG_IMM32_B32

    Inst_SOPK__S_SETREG_IMM32_B32::~Inst_SOPK__S_SETREG_IMM32_B32()
    {
    } // ~Inst_SOPK__S_SETREG_IMM32_B32

    // --- description from .arch file ---
    // Write some or all of the LSBs of IMM32 into a hardware register; this
    // ---  instruction requires a 32-bit literal constant.
    // SIMM16 = {size[4:0], offset[4:0], hwRegId[5:0]}; offset is 0..31, size
    // is 1..32.
    void
    Inst_SOPK__S_SETREG_IMM32_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI16 simm16 = instData.SIMM16;
        ScalarRegU32 hwregId = simm16 & 0x3f;
        ScalarRegU32 offset = (simm16 >> 6) & 31;
        ScalarRegU32 size = ((simm16 >> 11) & 31) + 1;

        ScalarOperandU32 hwreg(gpuDynInst, hwregId);
        ScalarRegI32 simm32 = extData.imm_u32;
        hwreg.read();

        // Store value from SIMM32 to part of the hardware register.
        ScalarRegU32 mask = (((1U << size) - 1U) << offset);
        hwreg = ((hwreg.rawData() & ~mask)
                        | ((simm32 << offset) & mask));
        hwreg.write();

        // set MODE register to control the behavior of single precision
        // floating-point numbers: denormal mode or round mode
        if (hwregId==1 && size==2
                        && (offset==4 || offset==0)) {
            warn_once("Be cautious that s_setreg_imm32_b32 has no real effect "
                            "on FP modes: %s\n", gpuDynInst->disassemble());
            return;
        }

        // panic if not changing modes of single-precision FPs
        panicUnimplemented();
    } // execute
    // --- Inst_SOP1__S_MOV_B32 class methods ---

    Inst_SOP1__S_MOV_B32::Inst_SOP1__S_MOV_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_mov_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_MOV_B32

    Inst_SOP1__S_MOV_B32::~Inst_SOP1__S_MOV_B32()
    {
    } // ~Inst_SOP1__S_MOV_B32

    // --- description from .arch file ---
    // D.u = S0.u.
    void
    Inst_SOP1__S_MOV_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = src.rawData();

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_MOV_B64 class methods ---

    Inst_SOP1__S_MOV_B64::Inst_SOP1__S_MOV_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_mov_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_MOV_B64

    Inst_SOP1__S_MOV_B64::~Inst_SOP1__S_MOV_B64()
    {
    } // ~Inst_SOP1__S_MOV_B64

    // --- description from .arch file ---
    // D.u64 = S0.u64.
    void
    Inst_SOP1__S_MOV_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = src.rawData();

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_CMOV_B32 class methods ---

    Inst_SOP1__S_CMOV_B32::Inst_SOP1__S_CMOV_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_cmov_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_CMOV_B32

    Inst_SOP1__S_CMOV_B32::~Inst_SOP1__S_CMOV_B32()
    {
    } // ~Inst_SOP1__S_CMOV_B32

    // --- description from .arch file ---
    // (SCC) then D.u = S0.u;
    // else NOP.
    // Conditional move.
    void
    Inst_SOP1__S_CMOV_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();
        scc.read();

        if (scc.rawData()) {
            sdst = src.rawData();
            sdst.write();
        }
    } // execute
    // --- Inst_SOP1__S_CMOV_B64 class methods ---

    Inst_SOP1__S_CMOV_B64::Inst_SOP1__S_CMOV_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_cmov_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_CMOV_B64

    Inst_SOP1__S_CMOV_B64::~Inst_SOP1__S_CMOV_B64()
    {
    } // ~Inst_SOP1__S_CMOV_B64

    // --- description from .arch file ---
    // if(SCC) then D.u64 = S0.u64;
    // else NOP.
    // Conditional move.
    void
    Inst_SOP1__S_CMOV_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();
        scc.read();

        if (scc.rawData()) {
            sdst = src.rawData();
            sdst.write();
        }
    } // execute
    // --- Inst_SOP1__S_NOT_B32 class methods ---

    Inst_SOP1__S_NOT_B32::Inst_SOP1__S_NOT_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_not_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_NOT_B32

    Inst_SOP1__S_NOT_B32::~Inst_SOP1__S_NOT_B32()
    {
    } // ~Inst_SOP1__S_NOT_B32

    // --- description from .arch file ---
    // D.u = ~S0.u;
    // SCC = 1 if result is non-zero.
    // Bitwise negation.
    void
    Inst_SOP1__S_NOT_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = ~src.rawData();

        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_NOT_B64 class methods ---

    Inst_SOP1__S_NOT_B64::Inst_SOP1__S_NOT_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_not_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_NOT_B64

    Inst_SOP1__S_NOT_B64::~Inst_SOP1__S_NOT_B64()
    {
    } // ~Inst_SOP1__S_NOT_B64

    // --- description from .arch file ---
    // D.u64 = ~S0.u64;
    // SCC = 1 if result is non-zero.
    // Bitwise negation.
    void
    Inst_SOP1__S_NOT_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = ~src.rawData();
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_WQM_B32 class methods ---

    Inst_SOP1__S_WQM_B32::Inst_SOP1__S_WQM_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_wqm_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_WQM_B32

    Inst_SOP1__S_WQM_B32::~Inst_SOP1__S_WQM_B32()
    {
    } // ~Inst_SOP1__S_WQM_B32

    // --- description from .arch file ---
    // D[i] = (S0[(i & ~3):(i | 3)] != 0);
    // Computes whole quad mode for an active/valid mask.
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP1__S_WQM_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = wholeQuadMode(src.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_WQM_B64 class methods ---

    Inst_SOP1__S_WQM_B64::Inst_SOP1__S_WQM_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_wqm_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_WQM_B64

    Inst_SOP1__S_WQM_B64::~Inst_SOP1__S_WQM_B64()
    {
    } // ~Inst_SOP1__S_WQM_B64

    // --- description from .arch file ---
    // D[i] = (S0[(i & ~3):(i | 3)] != 0);
    // Computes whole quad mode for an active/valid mask.
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP1__S_WQM_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = wholeQuadMode(src.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_BREV_B32 class methods ---

    Inst_SOP1__S_BREV_B32::Inst_SOP1__S_BREV_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_brev_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_BREV_B32

    Inst_SOP1__S_BREV_B32::~Inst_SOP1__S_BREV_B32()
    {
    } // ~Inst_SOP1__S_BREV_B32

    // --- description from .arch file ---
    // D.u[31:0] = S0.u[0:31] (reverse bits).
    void
    Inst_SOP1__S_BREV_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = reverseBits(src.rawData());

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_BREV_B64 class methods ---

    Inst_SOP1__S_BREV_B64::Inst_SOP1__S_BREV_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_brev_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_BREV_B64

    Inst_SOP1__S_BREV_B64::~Inst_SOP1__S_BREV_B64()
    {
    } // ~Inst_SOP1__S_BREV_B64

    // --- description from .arch file ---
    // D.u64[63:0] = S0.u64[0:63] (reverse bits).
    void
    Inst_SOP1__S_BREV_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = reverseBits(src.rawData());

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_BCNT0_I32_B32 class methods ---

    Inst_SOP1__S_BCNT0_I32_B32::Inst_SOP1__S_BCNT0_I32_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_bcnt0_i32_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_BCNT0_I32_B32

    Inst_SOP1__S_BCNT0_I32_B32::~Inst_SOP1__S_BCNT0_I32_B32()
    {
    } // ~Inst_SOP1__S_BCNT0_I32_B32

    // --- description from .arch file ---
    // D.i = CountZeroBits(S0.u);
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP1__S_BCNT0_I32_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = countZeroBits(src.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_BCNT0_I32_B64 class methods ---

    Inst_SOP1__S_BCNT0_I32_B64::Inst_SOP1__S_BCNT0_I32_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_bcnt0_i32_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_BCNT0_I32_B64

    Inst_SOP1__S_BCNT0_I32_B64::~Inst_SOP1__S_BCNT0_I32_B64()
    {
    } // ~Inst_SOP1__S_BCNT0_I32_B64

    // --- description from .arch file ---
    // D.i = CountZeroBits(S0.u64);
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP1__S_BCNT0_I32_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = countZeroBits(src.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_BCNT1_I32_B32 class methods ---

    Inst_SOP1__S_BCNT1_I32_B32::Inst_SOP1__S_BCNT1_I32_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_bcnt1_i32_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_BCNT1_I32_B32

    Inst_SOP1__S_BCNT1_I32_B32::~Inst_SOP1__S_BCNT1_I32_B32()
    {
    } // ~Inst_SOP1__S_BCNT1_I32_B32

    // --- description from .arch file ---
    // D.i = CountOneBits(S0.u);
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP1__S_BCNT1_I32_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = popCount(src.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_BCNT1_I32_B64 class methods ---

    Inst_SOP1__S_BCNT1_I32_B64::Inst_SOP1__S_BCNT1_I32_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_bcnt1_i32_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_BCNT1_I32_B64

    Inst_SOP1__S_BCNT1_I32_B64::~Inst_SOP1__S_BCNT1_I32_B64()
    {
    } // ~Inst_SOP1__S_BCNT1_I32_B64

    // --- description from .arch file ---
    // D.i = CountOneBits(S0.u64);
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP1__S_BCNT1_I32_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = popCount(src.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_FF0_I32_B32 class methods ---

    Inst_SOP1__S_FF0_I32_B32::Inst_SOP1__S_FF0_I32_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_ff0_i32_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_FF0_I32_B32

    Inst_SOP1__S_FF0_I32_B32::~Inst_SOP1__S_FF0_I32_B32()
    {
    } // ~Inst_SOP1__S_FF0_I32_B32

    // --- description from .arch file ---
    // D.i = FindFirstZero(S0.u);
    // If no zeros are found, return -1.
    // Returns the bit position of the first zero from the LSB.
    void
    Inst_SOP1__S_FF0_I32_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = findFirstZero(src.rawData());

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_FF0_I32_B64 class methods ---

    Inst_SOP1__S_FF0_I32_B64::Inst_SOP1__S_FF0_I32_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_ff0_i32_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_FF0_I32_B64

    Inst_SOP1__S_FF0_I32_B64::~Inst_SOP1__S_FF0_I32_B64()
    {
    } // ~Inst_SOP1__S_FF0_I32_B64

    // --- description from .arch file ---
    // D.i = FindFirstZero(S0.u64);
    // If no zeros are found, return -1.
    // Returns the bit position of the first zero from the LSB.
    void
    Inst_SOP1__S_FF0_I32_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = findFirstZero(src.rawData());

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_FF1_I32_B32 class methods ---

    Inst_SOP1__S_FF1_I32_B32::Inst_SOP1__S_FF1_I32_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_ff1_i32_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_FF1_I32_B32

    Inst_SOP1__S_FF1_I32_B32::~Inst_SOP1__S_FF1_I32_B32()
    {
    } // ~Inst_SOP1__S_FF1_I32_B32

    // --- description from .arch file ---
    // D.i = FindFirstOne(S0.u);
    // If no ones are found, return -1.
    // Returns the bit position of the first one from the LSB.
    void
    Inst_SOP1__S_FF1_I32_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = findFirstOne(src.rawData());

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_FF1_I32_B64 class methods ---

    Inst_SOP1__S_FF1_I32_B64::Inst_SOP1__S_FF1_I32_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_ff1_i32_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_FF1_I32_B64

    Inst_SOP1__S_FF1_I32_B64::~Inst_SOP1__S_FF1_I32_B64()
    {
    } // ~Inst_SOP1__S_FF1_I32_B64

    // --- description from .arch file ---
    // D.i = FindFirstOne(S0.u64);
    // If no ones are found, return -1.
    // Returns the bit position of the first one from the LSB.
    void
    Inst_SOP1__S_FF1_I32_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = findFirstOne(src.rawData());

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_FLBIT_I32_B32 class methods ---

    Inst_SOP1__S_FLBIT_I32_B32::Inst_SOP1__S_FLBIT_I32_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_flbit_i32_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_FLBIT_I32_B32

    Inst_SOP1__S_FLBIT_I32_B32::~Inst_SOP1__S_FLBIT_I32_B32()
    {
    } // ~Inst_SOP1__S_FLBIT_I32_B32

    // --- description from .arch file ---
    // D.i = FindFirstOne(S0.u);
    // If no ones are found, return -1.
    // Counts how many zeros before the first one starting from the MSB.
    void
    Inst_SOP1__S_FLBIT_I32_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = countZeroBitsMsb(src.rawData());

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_FLBIT_I32_B64 class methods ---

    Inst_SOP1__S_FLBIT_I32_B64::Inst_SOP1__S_FLBIT_I32_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_flbit_i32_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_FLBIT_I32_B64

    Inst_SOP1__S_FLBIT_I32_B64::~Inst_SOP1__S_FLBIT_I32_B64()
    {
    } // ~Inst_SOP1__S_FLBIT_I32_B64

    // --- description from .arch file ---
    // D.i = FindFirstOne(S0.u64);
    // If no ones are found, return -1.
    // Counts how many zeros before the first one starting from the MSB.
    void
    Inst_SOP1__S_FLBIT_I32_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = countZeroBitsMsb(src.rawData());

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_FLBIT_I32 class methods ---

    Inst_SOP1__S_FLBIT_I32::Inst_SOP1__S_FLBIT_I32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_flbit_i32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_FLBIT_I32

    Inst_SOP1__S_FLBIT_I32::~Inst_SOP1__S_FLBIT_I32()
    {
    } // ~Inst_SOP1__S_FLBIT_I32

    // --- description from .arch file ---
    // D.i = FirstOppositeSignBit(S0.i);
    // If S0.i == 0 or S0.i == -1 (all bits are the same), return -1.
    // Counts how many bits in a row (from MSB to LSB) are the same as the
    // sign bit.
    void
    Inst_SOP1__S_FLBIT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = firstOppositeSignBit(src.rawData());

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_FLBIT_I32_I64 class methods ---

    Inst_SOP1__S_FLBIT_I32_I64::Inst_SOP1__S_FLBIT_I32_I64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_flbit_i32_i64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_FLBIT_I32_I64

    Inst_SOP1__S_FLBIT_I32_I64::~Inst_SOP1__S_FLBIT_I32_I64()
    {
    } // ~Inst_SOP1__S_FLBIT_I32_I64

    // --- description from .arch file ---
    // D.i = FirstOppositeSignBit(S0.i64);
    // If S0.i == 0 or S0.i == -1 (all bits are the same), return -1.
    // Counts how many bits in a row (from MSB to LSB) are the same as the
    // sign bit.
    void
    Inst_SOP1__S_FLBIT_I32_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = firstOppositeSignBit(src.rawData());

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_SEXT_I32_I8 class methods ---

    Inst_SOP1__S_SEXT_I32_I8::Inst_SOP1__S_SEXT_I32_I8(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_sext_i32_i8")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_SEXT_I32_I8

    Inst_SOP1__S_SEXT_I32_I8::~Inst_SOP1__S_SEXT_I32_I8()
    {
    } // ~Inst_SOP1__S_SEXT_I32_I8

    // --- description from .arch file ---
    // D.i = signext(S0.i[7:0]) (sign extension).
    void
    Inst_SOP1__S_SEXT_I32_I8::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = sext<std::numeric_limits<ScalarRegI8>::digits>(
            bits(src.rawData(), 7, 0));

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_SEXT_I32_I16 class methods ---

    Inst_SOP1__S_SEXT_I32_I16::Inst_SOP1__S_SEXT_I32_I16(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_sext_i32_i16")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_SEXT_I32_I16

    Inst_SOP1__S_SEXT_I32_I16::~Inst_SOP1__S_SEXT_I32_I16()
    {
    } // ~Inst_SOP1__S_SEXT_I32_I16

    // --- description from .arch file ---
    // D.i = signext(S0.i[15:0]) (sign extension).
    void
    Inst_SOP1__S_SEXT_I32_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = sext<std::numeric_limits<ScalarRegI16>::digits>(
            bits(src.rawData(), 15, 0));

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_BITSET0_B32 class methods ---

    Inst_SOP1__S_BITSET0_B32::Inst_SOP1__S_BITSET0_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_bitset0_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_BITSET0_B32

    Inst_SOP1__S_BITSET0_B32::~Inst_SOP1__S_BITSET0_B32()
    {
    } // ~Inst_SOP1__S_BITSET0_B32

    // --- description from .arch file ---
    // D.u[S0.u[4:0]] = 0.
    void
    Inst_SOP1__S_BITSET0_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst.setBit(bits(src.rawData(), 4, 0), 0);

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_BITSET0_B64 class methods ---

    Inst_SOP1__S_BITSET0_B64::Inst_SOP1__S_BITSET0_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_bitset0_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_BITSET0_B64

    Inst_SOP1__S_BITSET0_B64::~Inst_SOP1__S_BITSET0_B64()
    {
    } // ~Inst_SOP1__S_BITSET0_B64

    // --- description from .arch file ---
    // D.u64[S0.u[5:0]] = 0.
    void
    Inst_SOP1__S_BITSET0_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst.setBit(bits(src.rawData(), 5, 0), 0);

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_BITSET1_B32 class methods ---

    Inst_SOP1__S_BITSET1_B32::Inst_SOP1__S_BITSET1_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_bitset1_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_BITSET1_B32

    Inst_SOP1__S_BITSET1_B32::~Inst_SOP1__S_BITSET1_B32()
    {
    } // ~Inst_SOP1__S_BITSET1_B32

    // --- description from .arch file ---
    // D.u[S0.u[4:0]] = 1.
    void
    Inst_SOP1__S_BITSET1_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst.setBit(bits(src.rawData(), 4, 0), 1);

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_BITSET1_B64 class methods ---

    Inst_SOP1__S_BITSET1_B64::Inst_SOP1__S_BITSET1_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_bitset1_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_BITSET1_B64

    Inst_SOP1__S_BITSET1_B64::~Inst_SOP1__S_BITSET1_B64()
    {
    } // ~Inst_SOP1__S_BITSET1_B64

    // --- description from .arch file ---
    // D.u64[S0.u[5:0]] = 1.
    void
    Inst_SOP1__S_BITSET1_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst.setBit(bits(src.rawData(), 5, 0), 1);

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_GETPC_B64 class methods ---

    Inst_SOP1__S_GETPC_B64::Inst_SOP1__S_GETPC_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_getpc_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_GETPC_B64

    Inst_SOP1__S_GETPC_B64::~Inst_SOP1__S_GETPC_B64()
    {
    } // ~Inst_SOP1__S_GETPC_B64

    // --- description from .arch file ---
    // D.u64 = PC + 4.
    // Destination receives the byte address of the next instruction.
    void
    Inst_SOP1__S_GETPC_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Addr pc = gpuDynInst->pc();
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);

        sdst = pc + 4;

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_SETPC_B64 class methods ---

    Inst_SOP1__S_SETPC_B64::Inst_SOP1__S_SETPC_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_setpc_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_SETPC_B64

    Inst_SOP1__S_SETPC_B64::~Inst_SOP1__S_SETPC_B64()
    {
    } // ~Inst_SOP1__S_SETPC_B64

    // --- description from .arch file ---
    // PC = S0.u64.
    // S0.u64 is a byte address of the instruction to jump to.
    void
    Inst_SOP1__S_SETPC_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);

        src.read();

        wf->pc(src.rawData());
    } // execute
    // --- Inst_SOP1__S_SWAPPC_B64 class methods ---

    Inst_SOP1__S_SWAPPC_B64::Inst_SOP1__S_SWAPPC_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_swappc_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_SWAPPC_B64

    Inst_SOP1__S_SWAPPC_B64::~Inst_SOP1__S_SWAPPC_B64()
    {
    } // ~Inst_SOP1__S_SWAPPC_B64

    // --- description from .arch file ---
    // D.u64 = PC + 4; PC = S0.u64.
    // S0.u64 is a byte address of the instruction to jump to.
    void
    Inst_SOP1__S_SWAPPC_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        Addr pc = gpuDynInst->pc();
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = pc + 4;

        wf->pc(src.rawData());
        sdst.write();
    } // execute
    // --- Inst_SOP1__S_RFE_B64 class methods ---

    Inst_SOP1__S_RFE_B64::Inst_SOP1__S_RFE_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_rfe_b64")
    {
    } // Inst_SOP1__S_RFE_B64

    Inst_SOP1__S_RFE_B64::~Inst_SOP1__S_RFE_B64()
    {
    } // ~Inst_SOP1__S_RFE_B64

    // --- description from .arch file ---
    // PRIV = 0;
    // PC = S0.u64.
    // Return from exception handler and continue.
    // This instruction may only be used within a trap handler.
    void
    Inst_SOP1__S_RFE_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOP1__S_AND_SAVEEXEC_B64 class methods ---

    Inst_SOP1__S_AND_SAVEEXEC_B64::Inst_SOP1__S_AND_SAVEEXEC_B64(
          InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_and_saveexec_b64")
    {
        setFlag(ALU);
        setFlag(ReadsEXEC);
        setFlag(WritesEXEC);
    } // Inst_SOP1__S_AND_SAVEEXEC_B64

    Inst_SOP1__S_AND_SAVEEXEC_B64::~Inst_SOP1__S_AND_SAVEEXEC_B64()
    {
    } // ~Inst_SOP1__S_AND_SAVEEXEC_B64

    // --- description from .arch file ---
    // D.u64 = EXEC;
    // EXEC = S0.u64 & EXEC;
    // SCC = 1 if the new value of EXEC is non-zero.
    void
    Inst_SOP1__S_AND_SAVEEXEC_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = wf->execMask().to_ullong();
        wf->execMask() = src.rawData() & wf->execMask().to_ullong();
        scc = wf->execMask().any() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_OR_SAVEEXEC_B64 class methods ---

    Inst_SOP1__S_OR_SAVEEXEC_B64::Inst_SOP1__S_OR_SAVEEXEC_B64(
          InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_or_saveexec_b64")
    {
        setFlag(ALU);
        setFlag(ReadsEXEC);
        setFlag(WritesEXEC);
    } // Inst_SOP1__S_OR_SAVEEXEC_B64

    Inst_SOP1__S_OR_SAVEEXEC_B64::~Inst_SOP1__S_OR_SAVEEXEC_B64()
    {
    } // ~Inst_SOP1__S_OR_SAVEEXEC_B64

    // --- description from .arch file ---
    // D.u64 = EXEC;
    // EXEC = S0.u64 | EXEC;
    // SCC = 1 if the new value of EXEC is non-zero.
    void
    Inst_SOP1__S_OR_SAVEEXEC_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = wf->execMask().to_ullong();
        wf->execMask() = src.rawData() | wf->execMask().to_ullong();
        scc = wf->execMask().any() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_XOR_SAVEEXEC_B64 class methods ---

    Inst_SOP1__S_XOR_SAVEEXEC_B64::Inst_SOP1__S_XOR_SAVEEXEC_B64(
          InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_xor_saveexec_b64")
    {
        setFlag(ALU);
        setFlag(ReadsEXEC);
        setFlag(WritesEXEC);
    } // Inst_SOP1__S_XOR_SAVEEXEC_B64

    Inst_SOP1__S_XOR_SAVEEXEC_B64::~Inst_SOP1__S_XOR_SAVEEXEC_B64()
    {
    } // ~Inst_SOP1__S_XOR_SAVEEXEC_B64

    // --- description from .arch file ---
    // D.u64 = EXEC;
    // EXEC = S0.u64 ^ EXEC;
    // SCC = 1 if the new value of EXEC is non-zero.
    void
    Inst_SOP1__S_XOR_SAVEEXEC_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = wf->execMask().to_ullong();
        wf->execMask() = src.rawData() ^ wf->execMask().to_ullong();
        scc = wf->execMask().any() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_ANDN2_SAVEEXEC_B64 class methods ---

    Inst_SOP1__S_ANDN2_SAVEEXEC_B64::Inst_SOP1__S_ANDN2_SAVEEXEC_B64(
          InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_andn2_saveexec_b64")
    {
        setFlag(ALU);
        setFlag(ReadsEXEC);
        setFlag(WritesEXEC);
    } // Inst_SOP1__S_ANDN2_SAVEEXEC_B64

    Inst_SOP1__S_ANDN2_SAVEEXEC_B64::~Inst_SOP1__S_ANDN2_SAVEEXEC_B64()
    {
    } // ~Inst_SOP1__S_ANDN2_SAVEEXEC_B64

    // --- description from .arch file ---
    // D.u64 = EXEC;
    // EXEC = S0.u64 & ~EXEC;
    // SCC = 1 if the new value of EXEC is non-zero.
    void
    Inst_SOP1__S_ANDN2_SAVEEXEC_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = wf->execMask().to_ullong();
        wf->execMask() = src.rawData() &~ wf->execMask().to_ullong();
        scc = wf->execMask().any() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_ORN2_SAVEEXEC_B64 class methods ---

    Inst_SOP1__S_ORN2_SAVEEXEC_B64::Inst_SOP1__S_ORN2_SAVEEXEC_B64(
          InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_orn2_saveexec_b64")
    {
        setFlag(ALU);
        setFlag(ReadsEXEC);
        setFlag(WritesEXEC);
    } // Inst_SOP1__S_ORN2_SAVEEXEC_B64

    Inst_SOP1__S_ORN2_SAVEEXEC_B64::~Inst_SOP1__S_ORN2_SAVEEXEC_B64()
    {
    } // ~Inst_SOP1__S_ORN2_SAVEEXEC_B64

    // --- description from .arch file ---
    // D.u64 = EXEC;
    // EXEC = S0.u64 | ~EXEC;
    // SCC = 1 if the new value of EXEC is non-zero.
    void
    Inst_SOP1__S_ORN2_SAVEEXEC_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = wf->execMask().to_ullong();
        wf->execMask() = src.rawData() |~ wf->execMask().to_ullong();
        scc = wf->execMask().any() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_NAND_SAVEEXEC_B64 class methods ---

    Inst_SOP1__S_NAND_SAVEEXEC_B64::Inst_SOP1__S_NAND_SAVEEXEC_B64(
          InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_nand_saveexec_b64")
    {
        setFlag(ALU);
        setFlag(ReadsEXEC);
        setFlag(WritesEXEC);
    } // Inst_SOP1__S_NAND_SAVEEXEC_B64

    Inst_SOP1__S_NAND_SAVEEXEC_B64::~Inst_SOP1__S_NAND_SAVEEXEC_B64()
    {
    } // ~Inst_SOP1__S_NAND_SAVEEXEC_B64

    // --- description from .arch file ---
    // D.u64 = EXEC;
    // EXEC = ~(S0.u64 & EXEC);
    // SCC = 1 if the new value of EXEC is non-zero.
    void
    Inst_SOP1__S_NAND_SAVEEXEC_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = wf->execMask().to_ullong();
        wf->execMask() = ~(src.rawData() & wf->execMask().to_ullong());
        scc = wf->execMask().any() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_NOR_SAVEEXEC_B64 class methods ---

    Inst_SOP1__S_NOR_SAVEEXEC_B64::Inst_SOP1__S_NOR_SAVEEXEC_B64(
          InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_nor_saveexec_b64")
    {
        setFlag(ALU);
        setFlag(ReadsEXEC);
        setFlag(WritesEXEC);
    } // Inst_SOP1__S_NOR_SAVEEXEC_B64

    Inst_SOP1__S_NOR_SAVEEXEC_B64::~Inst_SOP1__S_NOR_SAVEEXEC_B64()
    {
    } // ~Inst_SOP1__S_NOR_SAVEEXEC_B64

    // --- description from .arch file ---
    // D.u64 = EXEC;
    // EXEC = ~(S0.u64 | EXEC);
    // SCC = 1 if the new value of EXEC is non-zero.
    void
    Inst_SOP1__S_NOR_SAVEEXEC_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = wf->execMask().to_ullong();
        wf->execMask() = ~(src.rawData() | wf->execMask().to_ullong());
        scc = wf->execMask().any() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_XNOR_SAVEEXEC_B64 class methods ---

    Inst_SOP1__S_XNOR_SAVEEXEC_B64::Inst_SOP1__S_XNOR_SAVEEXEC_B64(
          InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_xnor_saveexec_b64")
    {
        setFlag(ALU);
        setFlag(ReadsEXEC);
        setFlag(WritesEXEC);
    } // Inst_SOP1__S_XNOR_SAVEEXEC_B64

    Inst_SOP1__S_XNOR_SAVEEXEC_B64::~Inst_SOP1__S_XNOR_SAVEEXEC_B64()
    {
    } // ~Inst_SOP1__S_XNOR_SAVEEXEC_B64

    // --- description from .arch file ---
    // D.u64 = EXEC;
    // EXEC = ~(S0.u64 ^ EXEC);
    // SCC = 1 if the new value of EXEC is non-zero.
    void
    Inst_SOP1__S_XNOR_SAVEEXEC_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = wf->execMask().to_ullong();
        wf->execMask() = ~(src.rawData() ^ wf->execMask().to_ullong());
        scc = wf->execMask().any() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_QUADMASK_B32 class methods ---

    Inst_SOP1__S_QUADMASK_B32::Inst_SOP1__S_QUADMASK_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_quadmask_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_QUADMASK_B32

    Inst_SOP1__S_QUADMASK_B32::~Inst_SOP1__S_QUADMASK_B32()
    {
    } // ~Inst_SOP1__S_QUADMASK_B32

    // --- description from .arch file ---
    // D.u = QuadMask(S0.u):
    // D[0] = OR(S0[3:0]), D[1] = OR(S0[7:4]) ... D[31:8] = 0;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP1__S_QUADMASK_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = quadMask(src.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_QUADMASK_B64 class methods ---

    Inst_SOP1__S_QUADMASK_B64::Inst_SOP1__S_QUADMASK_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_quadmask_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_QUADMASK_B64

    Inst_SOP1__S_QUADMASK_B64::~Inst_SOP1__S_QUADMASK_B64()
    {
    } // ~Inst_SOP1__S_QUADMASK_B64

    // --- description from .arch file ---
    // D.u64 = QuadMask(S0.u64):
    // D[0] = OR(S0[3:0]), D[1] = OR(S0[7:4]) ... D[63:16] = 0;
    // SCC = 1 if result is non-zero.
    void
    Inst_SOP1__S_QUADMASK_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = quadMask(src.rawData());
        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_MOVRELS_B32 class methods ---

    Inst_SOP1__S_MOVRELS_B32::Inst_SOP1__S_MOVRELS_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_movrels_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_MOVRELS_B32

    Inst_SOP1__S_MOVRELS_B32::~Inst_SOP1__S_MOVRELS_B32()
    {
    } // ~Inst_SOP1__S_MOVRELS_B32

    // --- description from .arch file ---
    // D.u = SGPR[S0.u + M0.u].u (move from relative source).
    void
    Inst_SOP1__S_MOVRELS_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 m0(gpuDynInst, REG_M0);
        m0.read();
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0 + m0.rawData());
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = src.rawData();

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_MOVRELS_B64 class methods ---

    Inst_SOP1__S_MOVRELS_B64::Inst_SOP1__S_MOVRELS_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_movrels_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_MOVRELS_B64

    Inst_SOP1__S_MOVRELS_B64::~Inst_SOP1__S_MOVRELS_B64()
    {
    } // ~Inst_SOP1__S_MOVRELS_B64

    // --- description from .arch file ---
    // D.u64 = SGPR[S0.u + M0.u].u64 (move from relative source).
    // The index in M0.u must be even for this operation.
    void
    Inst_SOP1__S_MOVRELS_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 m0(gpuDynInst, REG_M0);
        m0.read();
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0 + m0.rawData());
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);

        src.read();

        sdst = src.rawData();

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_MOVRELD_B32 class methods ---

    Inst_SOP1__S_MOVRELD_B32::Inst_SOP1__S_MOVRELD_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_movreld_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_MOVRELD_B32

    Inst_SOP1__S_MOVRELD_B32::~Inst_SOP1__S_MOVRELD_B32()
    {
    } // ~Inst_SOP1__S_MOVRELD_B32

    // --- description from .arch file ---
    // SGPR[D.u + M0.u].u = S0.u (move to relative destination).
    void
    Inst_SOP1__S_MOVRELD_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 m0(gpuDynInst, REG_M0);
        m0.read();
        ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU32 sdst(gpuDynInst, instData.SDST + m0.rawData());

        src.read();

        sdst = src.rawData();

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_MOVRELD_B64 class methods ---

    Inst_SOP1__S_MOVRELD_B64::Inst_SOP1__S_MOVRELD_B64(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_movreld_b64")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_MOVRELD_B64

    Inst_SOP1__S_MOVRELD_B64::~Inst_SOP1__S_MOVRELD_B64()
    {
    } // ~Inst_SOP1__S_MOVRELD_B64

    // --- description from .arch file ---
    // SGPR[D.u + M0.u].u64 = S0.u64 (move to relative destination).
    // The index in M0.u must be even for this operation.
    void
    Inst_SOP1__S_MOVRELD_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 m0(gpuDynInst, REG_M0);
        m0.read();
        ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST + m0.rawData());

        src.read();

        sdst = src.rawData();

        sdst.write();
    } // execute
    // --- Inst_SOP1__S_CBRANCH_JOIN class methods ---

    Inst_SOP1__S_CBRANCH_JOIN::Inst_SOP1__S_CBRANCH_JOIN(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_cbranch_join")
    {
        setFlag(Branch);
        setFlag(WritesEXEC);
    } // Inst_SOP1__S_CBRANCH_JOIN

    Inst_SOP1__S_CBRANCH_JOIN::~Inst_SOP1__S_CBRANCH_JOIN()
    {
    } // ~Inst_SOP1__S_CBRANCH_JOIN

    // --- description from .arch file ---
    // saved_csp = S0.u;
    // if(CSP == saved_csp) then
    //     PC += 4; // Second time to JOIN: continue with program.
    // else
    //     CSP -= 1; // First time to JOIN; jump to other FORK path.
    //     {PC, EXEC} = SGPR[CSP * 4]; // Read 128 bits from 4 consecutive
    //     SGPRs.
    // end
    // Conditional branch join point (end of conditional branch block). S0 is
    // saved CSP value.
    // See S_CBRANCH_G_FORK and S_CBRANCH_I_FORK for related instructions.
    void
    Inst_SOP1__S_CBRANCH_JOIN::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOP1__S_ABS_I32 class methods ---

    Inst_SOP1__S_ABS_I32::Inst_SOP1__S_ABS_I32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_abs_i32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_ABS_I32

    Inst_SOP1__S_ABS_I32::~Inst_SOP1__S_ABS_I32()
    {
    } // ~Inst_SOP1__S_ABS_I32

    // --- description from .arch file ---
    // if(S.i < 0) then D.i = -S.i;
    // else D.i = S.i;
    // SCC = 1 if result is non-zero.
    // Integer absolute value.
    void
    Inst_SOP1__S_ABS_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src(gpuDynInst, instData.SSRC0);
        ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src.read();

        sdst = std::abs(src.rawData());

        scc = sdst.rawData() ? 1 : 0;

        sdst.write();
        scc.write();
    } // execute
    // --- Inst_SOP1__S_MOV_FED_B32 class methods ---

    Inst_SOP1__S_MOV_FED_B32::Inst_SOP1__S_MOV_FED_B32(InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_mov_fed_b32")
    {
        setFlag(ALU);
    } // Inst_SOP1__S_MOV_FED_B32

    Inst_SOP1__S_MOV_FED_B32::~Inst_SOP1__S_MOV_FED_B32()
    {
    } // ~Inst_SOP1__S_MOV_FED_B32

    // --- description from .arch file ---
    // D.u = S0.u. Introduce an EDC double-detect error on write to the
    // destination SGPR.
    void
    Inst_SOP1__S_MOV_FED_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOP1__S_SET_GPR_IDX_IDX class methods ---

    Inst_SOP1__S_SET_GPR_IDX_IDX::Inst_SOP1__S_SET_GPR_IDX_IDX(
          InFmt_SOP1 *iFmt)
        : Inst_SOP1(iFmt, "s_set_gpr_idx_idx")
    {
    } // Inst_SOP1__S_SET_GPR_IDX_IDX

    Inst_SOP1__S_SET_GPR_IDX_IDX::~Inst_SOP1__S_SET_GPR_IDX_IDX()
    {
    } // ~Inst_SOP1__S_SET_GPR_IDX_IDX

    // --- description from .arch file ---
    // M0[7:0] = S0.u[7:0].
    // Modify the index used in vector GPR indexing.
    void
    Inst_SOP1__S_SET_GPR_IDX_IDX::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPC__S_CMP_EQ_I32 class methods ---

    Inst_SOPC__S_CMP_EQ_I32::Inst_SOPC__S_CMP_EQ_I32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_eq_i32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_EQ_I32

    Inst_SOPC__S_CMP_EQ_I32::~Inst_SOPC__S_CMP_EQ_I32()
    {
    } // ~Inst_SOPC__S_CMP_EQ_I32

    // --- description from .arch file ---
    // SCC = (S0.i == S1.i).
    void
    Inst_SOPC__S_CMP_EQ_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() == src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_CMP_LG_I32 class methods ---

    Inst_SOPC__S_CMP_LG_I32::Inst_SOPC__S_CMP_LG_I32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_lg_i32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_LG_I32

    Inst_SOPC__S_CMP_LG_I32::~Inst_SOPC__S_CMP_LG_I32()
    {
    } // ~Inst_SOPC__S_CMP_LG_I32

    // --- description from .arch file ---
    // SCC = (S0.i != S1.i).
    void
    Inst_SOPC__S_CMP_LG_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() != src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_CMP_GT_I32 class methods ---

    Inst_SOPC__S_CMP_GT_I32::Inst_SOPC__S_CMP_GT_I32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_gt_i32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_GT_I32

    Inst_SOPC__S_CMP_GT_I32::~Inst_SOPC__S_CMP_GT_I32()
    {
    } // ~Inst_SOPC__S_CMP_GT_I32

    // --- description from .arch file ---
    // SCC = (S0.i > S1.i).
    void
    Inst_SOPC__S_CMP_GT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() > src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_CMP_GE_I32 class methods ---

    Inst_SOPC__S_CMP_GE_I32::Inst_SOPC__S_CMP_GE_I32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_ge_i32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_GE_I32

    Inst_SOPC__S_CMP_GE_I32::~Inst_SOPC__S_CMP_GE_I32()
    {
    } // ~Inst_SOPC__S_CMP_GE_I32

    // --- description from .arch file ---
    // SCC = (S0.i >= S1.i).
    void
    Inst_SOPC__S_CMP_GE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() >= src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_CMP_LT_I32 class methods ---

    Inst_SOPC__S_CMP_LT_I32::Inst_SOPC__S_CMP_LT_I32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_lt_i32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_LT_I32

    Inst_SOPC__S_CMP_LT_I32::~Inst_SOPC__S_CMP_LT_I32()
    {
    } // ~Inst_SOPC__S_CMP_LT_I32

    // --- description from .arch file ---
    // SCC = (S0.i < S1.i).
    void
    Inst_SOPC__S_CMP_LT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() < src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_CMP_LE_I32 class methods ---

    Inst_SOPC__S_CMP_LE_I32::Inst_SOPC__S_CMP_LE_I32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_le_i32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_LE_I32

    Inst_SOPC__S_CMP_LE_I32::~Inst_SOPC__S_CMP_LE_I32()
    {
    } // ~Inst_SOPC__S_CMP_LE_I32

    // --- description from .arch file ---
    // SCC = (S0.i <= S1.i).
    void
    Inst_SOPC__S_CMP_LE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() <= src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_CMP_EQ_U32 class methods ---

    Inst_SOPC__S_CMP_EQ_U32::Inst_SOPC__S_CMP_EQ_U32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_eq_u32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_EQ_U32

    Inst_SOPC__S_CMP_EQ_U32::~Inst_SOPC__S_CMP_EQ_U32()
    {
    } // ~Inst_SOPC__S_CMP_EQ_U32

    // --- description from .arch file ---
    // SCC = (S0.u == S1.u).
    void
    Inst_SOPC__S_CMP_EQ_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() == src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_CMP_LG_U32 class methods ---

    Inst_SOPC__S_CMP_LG_U32::Inst_SOPC__S_CMP_LG_U32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_lg_u32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_LG_U32

    Inst_SOPC__S_CMP_LG_U32::~Inst_SOPC__S_CMP_LG_U32()
    {
    } // ~Inst_SOPC__S_CMP_LG_U32

    // --- description from .arch file ---
    // SCC = (S0.u != S1.u).
    void
    Inst_SOPC__S_CMP_LG_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() != src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_CMP_GT_U32 class methods ---

    Inst_SOPC__S_CMP_GT_U32::Inst_SOPC__S_CMP_GT_U32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_gt_u32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_GT_U32

    Inst_SOPC__S_CMP_GT_U32::~Inst_SOPC__S_CMP_GT_U32()
    {
    } // ~Inst_SOPC__S_CMP_GT_U32

    // --- description from .arch file ---
    // SCC = (S0.u > S1.u).
    void
    Inst_SOPC__S_CMP_GT_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() > src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_CMP_GE_U32 class methods ---

    Inst_SOPC__S_CMP_GE_U32::Inst_SOPC__S_CMP_GE_U32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_ge_u32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_GE_U32

    Inst_SOPC__S_CMP_GE_U32::~Inst_SOPC__S_CMP_GE_U32()
    {
    } // ~Inst_SOPC__S_CMP_GE_U32

    // --- description from .arch file ---
    // SCC = (S0.u >= S1.u).
    void
    Inst_SOPC__S_CMP_GE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() >= src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_CMP_LT_U32 class methods ---

    Inst_SOPC__S_CMP_LT_U32::Inst_SOPC__S_CMP_LT_U32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_lt_u32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_LT_U32

    Inst_SOPC__S_CMP_LT_U32::~Inst_SOPC__S_CMP_LT_U32()
    {
    } // ~Inst_SOPC__S_CMP_LT_U32

    // --- description from .arch file ---
    // SCC = (S0.u < S1.u).
    void
    Inst_SOPC__S_CMP_LT_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() < src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_CMP_LE_U32 class methods ---

    Inst_SOPC__S_CMP_LE_U32::Inst_SOPC__S_CMP_LE_U32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_le_u32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_LE_U32

    Inst_SOPC__S_CMP_LE_U32::~Inst_SOPC__S_CMP_LE_U32()
    {
    } // ~Inst_SOPC__S_CMP_LE_U32

    // --- description from .arch file ---
    // SCC = (S0.u <= S1.u).
    void
    Inst_SOPC__S_CMP_LE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() <= src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_BITCMP0_B32 class methods ---

    Inst_SOPC__S_BITCMP0_B32::Inst_SOPC__S_BITCMP0_B32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_bitcmp0_b32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_BITCMP0_B32

    Inst_SOPC__S_BITCMP0_B32::~Inst_SOPC__S_BITCMP0_B32()
    {
    } // ~Inst_SOPC__S_BITCMP0_B32

    // --- description from .arch file ---
    // SCC = (S0.u[S1.u[4:0]] == 0).
    void
    Inst_SOPC__S_BITCMP0_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = !bits(src0.rawData(), bits(src1.rawData(), 4, 0)) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_BITCMP1_B32 class methods ---

    Inst_SOPC__S_BITCMP1_B32::Inst_SOPC__S_BITCMP1_B32(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_bitcmp1_b32")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_BITCMP1_B32

    Inst_SOPC__S_BITCMP1_B32::~Inst_SOPC__S_BITCMP1_B32()
    {
    } // ~Inst_SOPC__S_BITCMP1_B32

    // --- description from .arch file ---
    // SCC = (S0.u[S1.u[4:0]] == 1).
    void
    Inst_SOPC__S_BITCMP1_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = bits(src0.rawData(), bits(src1.rawData(), 4, 0)) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_BITCMP0_B64 class methods ---

    Inst_SOPC__S_BITCMP0_B64::Inst_SOPC__S_BITCMP0_B64(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_bitcmp0_b64")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_BITCMP0_B64

    Inst_SOPC__S_BITCMP0_B64::~Inst_SOPC__S_BITCMP0_B64()
    {
    } // ~Inst_SOPC__S_BITCMP0_B64

    // --- description from .arch file ---
    // SCC = (S0.u64[S1.u[5:0]] == 0).
    void
    Inst_SOPC__S_BITCMP0_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = !bits(src0.rawData(), bits(src1.rawData(), 5, 0)) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_BITCMP1_B64 class methods ---

    Inst_SOPC__S_BITCMP1_B64::Inst_SOPC__S_BITCMP1_B64(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_bitcmp1_b64")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_BITCMP1_B64

    Inst_SOPC__S_BITCMP1_B64::~Inst_SOPC__S_BITCMP1_B64()
    {
    } // ~Inst_SOPC__S_BITCMP1_B64

    // --- description from .arch file ---
    // SCC = (S0.u64[S1.u[5:0]] == 1).
    void
    Inst_SOPC__S_BITCMP1_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = bits(src0.rawData(), bits(src1.rawData(), 5, 0)) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_SETVSKIP class methods ---

    Inst_SOPC__S_SETVSKIP::Inst_SOPC__S_SETVSKIP(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_setvskip")
    {
    } // Inst_SOPC__S_SETVSKIP

    Inst_SOPC__S_SETVSKIP::~Inst_SOPC__S_SETVSKIP()
    {
    } // ~Inst_SOPC__S_SETVSKIP

    // --- description from .arch file ---
    // VSKIP = S0.u[S1.u[4:0]].
    // Enables and disables VSKIP mode.
    // When VSKIP is enabled, no VOP*/M*BUF/MIMG/DS/FLAT/EXP instuctions are
    // issued.
    // If any vector operations are outstanding, S_WAITCNT must be issued
    // before executing.
    // This instruction requires one waitstate after executing (e.g. S_NOP 0).
    // Example:
    //     s_waitcnt 0
    //     s_setvskip 1, 0  // Enable vskip mode.
    //     s_nop 1
    void
    Inst_SOPC__S_SETVSKIP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPC__S_SET_GPR_IDX_ON class methods ---

    Inst_SOPC__S_SET_GPR_IDX_ON::Inst_SOPC__S_SET_GPR_IDX_ON(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_set_gpr_idx_on")
    {
    } // Inst_SOPC__S_SET_GPR_IDX_ON

    Inst_SOPC__S_SET_GPR_IDX_ON::~Inst_SOPC__S_SET_GPR_IDX_ON()
    {
    } // ~Inst_SOPC__S_SET_GPR_IDX_ON

    // --- description from .arch file ---
    // MODE.gpr_idx_en = 1;
    // M0[7:0] = S0.u[7:0];
    // M0[15:12] = SIMM4 (direct contents of S1 field);
    // // Remaining bits of M0 are unmodified.
    // Enable GPR indexing mode. Vector operations after this will perform
    // relative GPR addressing based on the contents of M0. The structure
    // SQ_M0_GPR_IDX_WORD may be used to decode M0.
    // The raw contents of the S1 field are read and used to set the enable
    // bits. S1[0] = VSRC0_REL, S1[1] = VSRC1_REL, S1[2] = VSRC2_REL and
    // S1[3] = VDST_REL.
    void
    Inst_SOPC__S_SET_GPR_IDX_ON::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPC__S_CMP_EQ_U64 class methods ---

    Inst_SOPC__S_CMP_EQ_U64::Inst_SOPC__S_CMP_EQ_U64(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_eq_u64")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_EQ_U64

    Inst_SOPC__S_CMP_EQ_U64::~Inst_SOPC__S_CMP_EQ_U64()
    {
    } // ~Inst_SOPC__S_CMP_EQ_U64

    // --- description from .arch file ---
    // SCC = (S0.i64 == S1.i64).
    void
    Inst_SOPC__S_CMP_EQ_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI64 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() == src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPC__S_CMP_LG_U64 class methods ---

    Inst_SOPC__S_CMP_LG_U64::Inst_SOPC__S_CMP_LG_U64(InFmt_SOPC *iFmt)
        : Inst_SOPC(iFmt, "s_cmp_lg_u64")
    {
        setFlag(ALU);
    } // Inst_SOPC__S_CMP_LG_U64

    Inst_SOPC__S_CMP_LG_U64::~Inst_SOPC__S_CMP_LG_U64()
    {
    } // ~Inst_SOPC__S_CMP_LG_U64

    // --- description from .arch file ---
    // SCC = (S0.i64 != S1.i64).
    void
    Inst_SOPC__S_CMP_LG_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandI64 src0(gpuDynInst, instData.SSRC0);
        ConstScalarOperandI64 src1(gpuDynInst, instData.SSRC1);
        ScalarOperandU32 scc(gpuDynInst, REG_SCC);

        src0.read();
        src1.read();

        scc = (src0.rawData() != src1.rawData()) ? 1 : 0;

        scc.write();
    } // execute
    // --- Inst_SOPP__S_NOP class methods ---

    Inst_SOPP__S_NOP::Inst_SOPP__S_NOP(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_nop")
    {
        setFlag(Nop);
    } // Inst_SOPP__S_NOP

    Inst_SOPP__S_NOP::~Inst_SOPP__S_NOP()
    {
    } // ~Inst_SOPP__S_NOP

    // --- description from .arch file ---
    // Do nothing. Repeat NOP 1..8 times based on SIMM16[2:0] -- 0 = 1 time,
    // 7 = 8 times.
    // This instruction may be used to introduce wait states to resolve
    // hazards; see the shader programming guide for details. Compare with
    // S_SLEEP.
    void
    Inst_SOPP__S_NOP::execute(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_SOPP__S_ENDPGM class methods ---

    Inst_SOPP__S_ENDPGM::Inst_SOPP__S_ENDPGM(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_endpgm")
    {
        setFlag(EndOfKernel);
    } // Inst_SOPP__S_ENDPGM

    Inst_SOPP__S_ENDPGM::~Inst_SOPP__S_ENDPGM()
    {
    } // ~Inst_SOPP__S_ENDPGM

    // --- description from .arch file ---
    // End of program; terminate wavefront.
    // The hardware implicitly executes S_WAITCNT 0 before executing this
    // ---  instruction.
    // See S_ENDPGM_SAVED for the context-switch version of this instruction.
    void
    Inst_SOPP__S_ENDPGM::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ComputeUnit *cu = gpuDynInst->computeUnit();

        // delete extra instructions fetched for completed work-items
        wf->instructionBuffer.erase(wf->instructionBuffer.begin() + 1,
            wf->instructionBuffer.end());

        if (wf->pendingFetch) {
            wf->dropFetch = true;
        }

        wf->computeUnit->fetchStage.fetchUnit(wf->simdId)
            .flushBuf(wf->wfSlotId);
        wf->setStatus(Wavefront::S_STOPPED);

        int refCount = wf->computeUnit->getLds()
            .decreaseRefCounter(wf->dispatchId, wf->wgId);

        /**
         * The parent WF of this instruction is exiting, therefore
         * it should not participate in this barrier any longer. This
         * prevents possible deadlock issues if WFs exit early.
         */
        int bar_id = WFBarrier::InvalidID;
        if (wf->hasBarrier()) {
            assert(wf->getStatus() != Wavefront::S_BARRIER);
            bar_id = wf->barrierId();
            assert(bar_id != WFBarrier::InvalidID);
            wf->releaseBarrier();
            cu->decMaxBarrierCnt(bar_id);
            DPRINTF(GPUSync, "CU[%d] WF[%d][%d] Wave[%d] - Exiting the "
                    "program and decrementing max barrier count for "
                    "barrier Id%d. New max count: %d.\n", cu->cu_id,
                    wf->simdId, wf->wfSlotId, wf->wfDynId, bar_id,
                    cu->maxBarrierCnt(bar_id));
        }

        DPRINTF(GPUExec, "CU%d: decrease ref ctr WG[%d] to [%d]\n",
            wf->computeUnit->cu_id, wf->wgId, refCount);

        wf->computeUnit->registerManager->freeRegisters(wf);
        wf->computeUnit->stats.completedWfs++;
        wf->computeUnit->activeWaves--;

        panic_if(wf->computeUnit->activeWaves < 0, "CU[%d] Active waves less "
            "than zero\n", wf->computeUnit->cu_id);

        DPRINTF(GPUExec, "Doing return for CU%d: WF[%d][%d][%d]\n",
            wf->computeUnit->cu_id, wf->simdId, wf->wfSlotId, wf->wfDynId);

        for (int i = 0; i < wf->vecReads.size(); i++) {
            if (wf->rawDist.find(i) != wf->rawDist.end()) {
                wf->stats.readsPerWrite.sample(wf->vecReads.at(i));
            }
        }
        wf->vecReads.clear();
        wf->rawDist.clear();
        wf->lastInstExec = 0;

        if (!refCount) {
            /**
             * If all WFs have finished, and hence the WG has finished,
             * then we can free up the barrier belonging to the parent
             * WG, but only if we actually used a barrier (i.e., more
             * than one WF in the WG).
             */
            if (bar_id != WFBarrier::InvalidID) {
                DPRINTF(GPUSync, "CU[%d] WF[%d][%d] Wave[%d] - All waves are "
                        "now complete. Releasing barrier Id%d.\n", cu->cu_id,
                        wf->simdId, wf->wfSlotId, wf->wfDynId,
                        wf->barrierId());
                cu->releaseBarrier(bar_id);
            }

           /**
             * Last wavefront of the workgroup has executed return. If the
             * workgroup is not the final one in the kernel, then simply
             * retire it; however, if it is the final one, i.e., indicating
             * the kernel end, then release operation (i.e., GL2 WB) is
             * needed
             */

            //check whether the workgroup is indicating the kernel end, i.e.,
            //the last workgroup in the kernel
            bool kernelEnd =
                wf->computeUnit->shader->dispatcher().isReachingKernelEnd(wf);

            bool relNeeded =
                wf->computeUnit->shader->impl_kern_end_rel;

            //if it is not a kernel end, then retire the workgroup directly
            if (!kernelEnd || !relNeeded) {
                wf->computeUnit->shader->dispatcher().notifyWgCompl(wf);
                wf->setStatus(Wavefront::S_STOPPED);
                wf->computeUnit->stats.completedWGs++;

                return;
            }

            /**
             * if it is a kernel end, inject a memory sync, i.e., GL2 WB, and
             * retire the workgroup after receving response.
             * note that GL0V and GL1 are read only, and they just forward GL2
             * WB request. When forwarding, GL1 send the request to all GL2 in
             * the complex
             */
            setFlag(MemSync);
            setFlag(GlobalSegment);
            // Notify Memory System of Kernel Completion
            // Kernel End = isKernel + isMemSync
            wf->setStatus(Wavefront::S_RETURNING);
            gpuDynInst->simdId = wf->simdId;
            gpuDynInst->wfSlotId = wf->wfSlotId;
            gpuDynInst->wfDynId = wf->wfDynId;

            DPRINTF(GPUExec, "inject global memory fence for CU%d: "
                            "WF[%d][%d][%d]\n", wf->computeUnit->cu_id,
                            wf->simdId, wf->wfSlotId, wf->wfDynId);

            // call shader to prepare the flush operations
            wf->computeUnit->shader->prepareFlush(gpuDynInst);

            wf->computeUnit->stats.completedWGs++;
        } else {
            wf->computeUnit->shader->dispatcher().scheduleDispatch();
        }
    } // execute

    // --- Inst_SOPP__S_BRANCH class methods ---

    Inst_SOPP__S_BRANCH::Inst_SOPP__S_BRANCH(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_branch")
    {
        setFlag(Branch);
    } // Inst_SOPP__S_BRANCH

    Inst_SOPP__S_BRANCH::~Inst_SOPP__S_BRANCH()
    {
    } // ~Inst_SOPP__S_BRANCH

    // --- description from .arch file ---
    // PC = PC + signext(SIMM16 * 4) + 4 (short jump).
    // For a long jump, use S_SETPC.
    void
    Inst_SOPP__S_BRANCH::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        Addr pc = gpuDynInst->pc();
        ScalarRegI16 simm16 = instData.SIMM16;

        pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;

        wf->pc(pc);
    } // execute
    // --- Inst_SOPP__S_WAKEUP class methods ---

    Inst_SOPP__S_WAKEUP::Inst_SOPP__S_WAKEUP(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_wakeup")
    {
    } // Inst_SOPP__S_WAKEUP

    Inst_SOPP__S_WAKEUP::~Inst_SOPP__S_WAKEUP()
    {
    } // ~Inst_SOPP__S_WAKEUP

    // --- description from .arch file ---
    // Allow a wave to 'ping' all the other waves in its threadgroup to force
    // them to wake up immediately from an S_SLEEP instruction. The ping is
    // ignored if the waves are not sleeping.
    // This allows for more efficient polling on a memory location. The waves
    // which are polling can sit in a long S_SLEEP between memory reads, but
    // the wave which writes the value can tell them all to wake up early now
    // that the data is available. This is useful for fBarrier implementations
    // (speedup).
    // This method is also safe from races because if any wave misses the ping,
    // everything still works fine (whoever missed it just completes their
    // normal S_SLEEP).
    void
    Inst_SOPP__S_WAKEUP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_CBRANCH_SCC0 class methods ---

    Inst_SOPP__S_CBRANCH_SCC0::Inst_SOPP__S_CBRANCH_SCC0(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_cbranch_scc0")
    {
        setFlag(Branch);
    } // Inst_SOPP__S_CBRANCH_SCC0

    Inst_SOPP__S_CBRANCH_SCC0::~Inst_SOPP__S_CBRANCH_SCC0()
    {
    } // ~Inst_SOPP__S_CBRANCH_SCC0

    // --- description from .arch file ---
    // if(SCC == 0) then PC = PC + signext(SIMM16 * 4) + 4;
    // else NOP.
    void
    Inst_SOPP__S_CBRANCH_SCC0::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        Addr pc = gpuDynInst->pc();
        ScalarRegI16 simm16 = instData.SIMM16;
        ConstScalarOperandU32 scc(gpuDynInst, REG_SCC);

        scc.read();

        if (!scc.rawData()) {
            pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
        }

        wf->pc(pc);
    } // execute
    // --- Inst_SOPP__S_CBRANCH_SCC1 class methods ---

    Inst_SOPP__S_CBRANCH_SCC1::Inst_SOPP__S_CBRANCH_SCC1(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_cbranch_scc1")
    {
        setFlag(Branch);
    } // Inst_SOPP__S_CBRANCH_SCC1

    Inst_SOPP__S_CBRANCH_SCC1::~Inst_SOPP__S_CBRANCH_SCC1()
    {
    } // ~Inst_SOPP__S_CBRANCH_SCC1

    // --- description from .arch file ---
    // if(SCC == 1) then PC = PC + signext(SIMM16 * 4) + 4;
    // else NOP.
    void
    Inst_SOPP__S_CBRANCH_SCC1::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        Addr pc = gpuDynInst->pc();
        ScalarRegI16 simm16 = instData.SIMM16;
        ConstScalarOperandU32 scc(gpuDynInst, REG_SCC);

        scc.read();

        if (scc.rawData()) {
            pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
        }

        wf->pc(pc);
    } // execute
    // --- Inst_SOPP__S_CBRANCH_VCCZ class methods ---

    Inst_SOPP__S_CBRANCH_VCCZ::Inst_SOPP__S_CBRANCH_VCCZ(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_cbranch_vccz")
    {
        setFlag(Branch);
        setFlag(ReadsVCC);
    } // Inst_SOPP__S_CBRANCH_VCCZ

    Inst_SOPP__S_CBRANCH_VCCZ::~Inst_SOPP__S_CBRANCH_VCCZ()
    {
    } // ~Inst_SOPP__S_CBRANCH_VCCZ

    // --- description from .arch file ---
    // if(VCC == 0) then PC = PC + signext(SIMM16 * 4) + 4;
    // else NOP.
    void
    Inst_SOPP__S_CBRANCH_VCCZ::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);
        Addr pc = gpuDynInst->pc();
        ScalarRegI16 simm16 = instData.SIMM16;

        vcc.read();

        if (!vcc.rawData()) {
            pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
        }

        wf->pc(pc);
    } // execute
    // --- Inst_SOPP__S_CBRANCH_VCCNZ class methods ---

    Inst_SOPP__S_CBRANCH_VCCNZ::Inst_SOPP__S_CBRANCH_VCCNZ(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_cbranch_vccnz")
    {
        setFlag(Branch);
        setFlag(ReadsVCC);
    } // Inst_SOPP__S_CBRANCH_VCCNZ

    Inst_SOPP__S_CBRANCH_VCCNZ::~Inst_SOPP__S_CBRANCH_VCCNZ()
    {
    } // ~Inst_SOPP__S_CBRANCH_VCCNZ

    // --- description from .arch file ---
    // if(VCC != 0) then PC = PC + signext(SIMM16 * 4) + 4;
    // else NOP.
    void
    Inst_SOPP__S_CBRANCH_VCCNZ::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        vcc.read();

        if (vcc.rawData()) {
            Addr pc = gpuDynInst->pc();
            ScalarRegI16 simm16 = instData.SIMM16;
            pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
            wf->pc(pc);
        }
    } // execute
    // --- Inst_SOPP__S_CBRANCH_EXECZ class methods ---

    Inst_SOPP__S_CBRANCH_EXECZ::Inst_SOPP__S_CBRANCH_EXECZ(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_cbranch_execz")
    {
        setFlag(Branch);
        setFlag(ReadsEXEC);
    } // Inst_SOPP__S_CBRANCH_EXECZ

    Inst_SOPP__S_CBRANCH_EXECZ::~Inst_SOPP__S_CBRANCH_EXECZ()
    {
    } // ~Inst_SOPP__S_CBRANCH_EXECZ

    // --- description from .arch file ---
    // if(EXEC == 0) then PC = PC + signext(SIMM16 * 4) + 4;
    // else NOP.
    void
    Inst_SOPP__S_CBRANCH_EXECZ::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (wf->execMask().none()) {
            Addr pc = gpuDynInst->pc();
            ScalarRegI16 simm16 = instData.SIMM16;
            pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
            wf->pc(pc);
        }
    } // execute
    // --- Inst_SOPP__S_CBRANCH_EXECNZ class methods ---

    Inst_SOPP__S_CBRANCH_EXECNZ::Inst_SOPP__S_CBRANCH_EXECNZ(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_cbranch_execnz")
    {
        setFlag(Branch);
        setFlag(ReadsEXEC);
    } // Inst_SOPP__S_CBRANCH_EXECNZ

    Inst_SOPP__S_CBRANCH_EXECNZ::~Inst_SOPP__S_CBRANCH_EXECNZ()
    {
    } // ~Inst_SOPP__S_CBRANCH_EXECNZ

    // --- description from .arch file ---
    // if(EXEC != 0) then PC = PC + signext(SIMM16 * 4) + 4;
    // else NOP.
    void
    Inst_SOPP__S_CBRANCH_EXECNZ::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (wf->execMask().any()) {
            Addr pc = gpuDynInst->pc();
            ScalarRegI16 simm16 = instData.SIMM16;
            pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
            wf->pc(pc);
        }
    } // execute
    // --- Inst_SOPP__S_BARRIER class methods ---

    Inst_SOPP__S_BARRIER::Inst_SOPP__S_BARRIER(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_barrier")
    {
        setFlag(MemBarrier);
    } // Inst_SOPP__S_BARRIER

    Inst_SOPP__S_BARRIER::~Inst_SOPP__S_BARRIER()
    {
    } // ~Inst_SOPP__S_BARRIER

    // --- description from .arch file ---
    // Synchronize waves within a threadgroup.
    // If not all waves of the threadgroup have been created yet, waits for
    // entire group before proceeding.
    // If some waves in the threadgroup have already terminated, this waits on
    // only the surviving waves.
    // Barriers are legal inside trap handlers.
    void
    Inst_SOPP__S_BARRIER::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ComputeUnit *cu = gpuDynInst->computeUnit();

        if (wf->hasBarrier()) {
            int bar_id = wf->barrierId();
            assert(wf->getStatus() == Wavefront::S_BARRIER);
            cu->incNumAtBarrier(bar_id);
            DPRINTF(GPUSync, "CU[%d] WF[%d][%d] Wave[%d] - Stalling at "
                    "barrier Id%d. %d waves now at barrier, %d waves "
                    "remain.\n", cu->cu_id, wf->simdId, wf->wfSlotId,
                    wf->wfDynId, bar_id, cu->numAtBarrier(bar_id),
                    cu->numYetToReachBarrier(bar_id));
        }
    } // execute
    // --- Inst_SOPP__S_SETKILL class methods ---

    Inst_SOPP__S_SETKILL::Inst_SOPP__S_SETKILL(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_setkill")
    {
    } // Inst_SOPP__S_SETKILL

    Inst_SOPP__S_SETKILL::~Inst_SOPP__S_SETKILL()
    {
    } // ~Inst_SOPP__S_SETKILL

    // --- description from .arch file ---
    // set KILL bit to value of SIMM16[0].
    // Used primarily for debugging kill wave host command behavior.
    void
    Inst_SOPP__S_SETKILL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_WAITCNT class methods ---

    Inst_SOPP__S_WAITCNT::Inst_SOPP__S_WAITCNT(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_waitcnt")
    {
        setFlag(ALU);
        setFlag(Waitcnt);
    } // Inst_SOPP__S_WAITCNT

    Inst_SOPP__S_WAITCNT::~Inst_SOPP__S_WAITCNT()
    {
    } // ~Inst_SOPP__S_WAITCNT

    // --- description from .arch file ---
    // Wait for the counts of outstanding lds, vector-memory and
    // ---  export/vmem-write-data to be at or below the specified levels.
    // SIMM16[3:0] = vmcount (vector memory operations),
    // SIMM16[6:4] = export/mem-write-data count,
    // SIMM16[12:8] = LGKM_cnt (scalar-mem/GDS/LDS count).
    void
    Inst_SOPP__S_WAITCNT::execute(GPUDynInstPtr gpuDynInst)
    {
        ScalarRegI32 vm_cnt = 0;
        ScalarRegI32 exp_cnt = 0;
        ScalarRegI32 lgkm_cnt = 0;
        vm_cnt = bits<ScalarRegI16>(instData.SIMM16, 3, 0);
        exp_cnt = bits<ScalarRegI16>(instData.SIMM16, 6, 4);
        lgkm_cnt = bits<ScalarRegI16>(instData.SIMM16, 12, 8);
        gpuDynInst->wavefront()->setStatus(Wavefront::S_WAITCNT);
        gpuDynInst->wavefront()->setWaitCnts(vm_cnt, exp_cnt, lgkm_cnt);
    } // execute
    // --- Inst_SOPP__S_SETHALT class methods ---

    Inst_SOPP__S_SETHALT::Inst_SOPP__S_SETHALT(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_sethalt")
    {
    } // Inst_SOPP__S_SETHALT

    Inst_SOPP__S_SETHALT::~Inst_SOPP__S_SETHALT()
    {
    } // ~Inst_SOPP__S_SETHALT

    // --- description from .arch file ---
    // Set HALT bit to value of SIMM16[0]; 1 = halt, 0 = resume.
    // The halt flag is ignored while PRIV == 1 (inside trap handlers) but the
    // shader will halt immediately after the handler returns if HALT is still
    // set at that time.
    void
    Inst_SOPP__S_SETHALT::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_SLEEP class methods ---

    Inst_SOPP__S_SLEEP::Inst_SOPP__S_SLEEP(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_sleep")
    {
    } // Inst_SOPP__S_SLEEP

    Inst_SOPP__S_SLEEP::~Inst_SOPP__S_SLEEP()
    {
    } // ~Inst_SOPP__S_SLEEP

    // --- description from .arch file ---
    // Cause a wave to sleep for (64 * SIMM16[2:0] + 1..64) clocks.
    // The exact amount of delay is approximate. Compare with S_NOP.
    void
    Inst_SOPP__S_SLEEP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_SETPRIO class methods ---

    Inst_SOPP__S_SETPRIO::Inst_SOPP__S_SETPRIO(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_setprio")
    {
    } // Inst_SOPP__S_SETPRIO

    Inst_SOPP__S_SETPRIO::~Inst_SOPP__S_SETPRIO()
    {
    } // ~Inst_SOPP__S_SETPRIO

    // --- description from .arch file ---
    // User settable wave priority is set to SIMM16[1:0]. 0 = lowest,
    // 3 = highest.
    // The overall wave priority is {SPIPrio[1:0] + UserPrio[1:0],
    // WaveAge[3:0]}.
    void
    Inst_SOPP__S_SETPRIO::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_SENDMSG class methods ---

    Inst_SOPP__S_SENDMSG::Inst_SOPP__S_SENDMSG(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_sendmsg")
    {
    } // Inst_SOPP__S_SENDMSG

    Inst_SOPP__S_SENDMSG::~Inst_SOPP__S_SENDMSG()
    {
    } // ~Inst_SOPP__S_SENDMSG

    // --- description from .arch file ---
    // Send a message upstream to VGT or the interrupt handler.
    // SIMM16[9:0] contains the message type and is documented in the shader
    // ---  programming guide.
    void
    Inst_SOPP__S_SENDMSG::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_SENDMSGHALT class methods ---

    Inst_SOPP__S_SENDMSGHALT::Inst_SOPP__S_SENDMSGHALT(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_sendmsghalt")
    {
    } // Inst_SOPP__S_SENDMSGHALT

    Inst_SOPP__S_SENDMSGHALT::~Inst_SOPP__S_SENDMSGHALT()
    {
    } // ~Inst_SOPP__S_SENDMSGHALT

    // --- description from .arch file ---
    // Send a message and then HALT the wavefront; see S_SENDMSG for details.
    void
    Inst_SOPP__S_SENDMSGHALT::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_TRAP class methods ---

    Inst_SOPP__S_TRAP::Inst_SOPP__S_TRAP(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_trap")
    {
    } // Inst_SOPP__S_TRAP

    Inst_SOPP__S_TRAP::~Inst_SOPP__S_TRAP()
    {
    } // ~Inst_SOPP__S_TRAP

    // --- description from .arch file ---
    // TrapID = SIMM16[7:0];
    // Wait for all instructions to complete;
    // set {TTMP1, TTMP0} = {3'h0, PCRewind[3:0], HT[0], TrapID[7:0],
    // PC[47:0]};
    // PC = TBA (trap base address);
    // PRIV = 1.
    // Enter the trap handler. This instruction may be generated internally as
    // well in response to a host trap (HT = 1) or an exception.
    // TrapID 0 is reserved for hardware use and should not be used in a
    // shader-generated trap.
    void
    Inst_SOPP__S_TRAP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_ICACHE_INV class methods ---

    Inst_SOPP__S_ICACHE_INV::Inst_SOPP__S_ICACHE_INV(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_icache_inv")
    {
    } // Inst_SOPP__S_ICACHE_INV

    Inst_SOPP__S_ICACHE_INV::~Inst_SOPP__S_ICACHE_INV()
    {
    } // ~Inst_SOPP__S_ICACHE_INV

    // --- description from .arch file ---
    // Invalidate entire L1 instruction cache.
    // You must have 12 separate S_NOP instructions or a jump/branch
    // instruction after this instruction
    // to ensure the SQ instruction buffer is purged.
    void
    Inst_SOPP__S_ICACHE_INV::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_INCPERFLEVEL class methods ---

    Inst_SOPP__S_INCPERFLEVEL::Inst_SOPP__S_INCPERFLEVEL(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_incperflevel")
    {
    } // Inst_SOPP__S_INCPERFLEVEL

    Inst_SOPP__S_INCPERFLEVEL::~Inst_SOPP__S_INCPERFLEVEL()
    {
    } // ~Inst_SOPP__S_INCPERFLEVEL

    // --- description from .arch file ---
    // Increment performance counter specified in SIMM16[3:0] by 1.
    void
    Inst_SOPP__S_INCPERFLEVEL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_DECPERFLEVEL class methods ---

    Inst_SOPP__S_DECPERFLEVEL::Inst_SOPP__S_DECPERFLEVEL(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_decperflevel")
    {
    } // Inst_SOPP__S_DECPERFLEVEL

    Inst_SOPP__S_DECPERFLEVEL::~Inst_SOPP__S_DECPERFLEVEL()
    {
    } // ~Inst_SOPP__S_DECPERFLEVEL

    // --- description from .arch file ---
    // Decrement performance counter specified in SIMM16[3:0] by 1.
    void
    Inst_SOPP__S_DECPERFLEVEL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_TTRACEDATA class methods ---

    Inst_SOPP__S_TTRACEDATA::Inst_SOPP__S_TTRACEDATA(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_ttracedata")
    {
    } // Inst_SOPP__S_TTRACEDATA

    Inst_SOPP__S_TTRACEDATA::~Inst_SOPP__S_TTRACEDATA()
    {
    } // ~Inst_SOPP__S_TTRACEDATA

    // --- description from .arch file ---
    // Send M0 as user data to the thread trace stream.
    void
    Inst_SOPP__S_TTRACEDATA::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_CBRANCH_CDBGSYS class methods ---

    Inst_SOPP__S_CBRANCH_CDBGSYS::Inst_SOPP__S_CBRANCH_CDBGSYS(
          InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_cbranch_cdbgsys")
    {
        setFlag(Branch);
    } // Inst_SOPP__S_CBRANCH_CDBGSYS

    Inst_SOPP__S_CBRANCH_CDBGSYS::~Inst_SOPP__S_CBRANCH_CDBGSYS()
    {
    } // ~Inst_SOPP__S_CBRANCH_CDBGSYS

    // --- description from .arch file ---
    // if(conditional_debug_system != 0) then PC = PC + signext(SIMM16 * 4)
    // + 4;
    // else NOP.
    void
    Inst_SOPP__S_CBRANCH_CDBGSYS::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_CBRANCH_CDBGUSER class methods ---

    Inst_SOPP__S_CBRANCH_CDBGUSER::Inst_SOPP__S_CBRANCH_CDBGUSER(
          InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_cbranch_cdbguser")
    {
        setFlag(Branch);
    } // Inst_SOPP__S_CBRANCH_CDBGUSER

    Inst_SOPP__S_CBRANCH_CDBGUSER::~Inst_SOPP__S_CBRANCH_CDBGUSER()
    {
    } // ~Inst_SOPP__S_CBRANCH_CDBGUSER

    // --- description from .arch file ---
    // if(conditional_debug_user != 0) then PC = PC + signext(SIMM16 * 4) + 4;
    // else NOP.
    void
    Inst_SOPP__S_CBRANCH_CDBGUSER::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_CBRANCH_CDBGSYS_OR_USER class methods ---

    Inst_SOPP__S_CBRANCH_CDBGSYS_OR_USER::Inst_SOPP__S_CBRANCH_CDBGSYS_OR_USER(
          InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_cbranch_cdbgsys_or_user")
    {
        setFlag(Branch);
    } // Inst_SOPP__S_CBRANCH_CDBGSYS_OR_USER

    Inst_SOPP__S_CBRANCH_CDBGSYS_OR_USER::
        ~Inst_SOPP__S_CBRANCH_CDBGSYS_OR_USER()
    {
    } // ~Inst_SOPP__S_CBRANCH_CDBGSYS_OR_USER

    // --- description from .arch file ---
    // if(conditional_debug_system || conditional_debug_user) then PC = PC +
    // ---  signext(SIMM16 * 4) + 4;
    // else NOP.
    void
    Inst_SOPP__S_CBRANCH_CDBGSYS_OR_USER::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_CBRANCH_CDBGSYS_AND_USER class methods ---

    Inst_SOPP__S_CBRANCH_CDBGSYS_AND_USER::
        Inst_SOPP__S_CBRANCH_CDBGSYS_AND_USER(InFmt_SOPP *iFmt)
            : Inst_SOPP(iFmt, "s_cbranch_cdbgsys_and_user")
    {
        setFlag(Branch);
    } // Inst_SOPP__S_CBRANCH_CDBGSYS_AND_USER

    Inst_SOPP__S_CBRANCH_CDBGSYS_AND_USER::
        ~Inst_SOPP__S_CBRANCH_CDBGSYS_AND_USER()
    {
    } // ~Inst_SOPP__S_CBRANCH_CDBGSYS_AND_USER

    // --- description from .arch file ---
    // if(conditional_debug_system && conditional_debug_user) then PC = PC +
    // ---  signext(SIMM16 * 4) + 4;
    // else NOP.
    void
    Inst_SOPP__S_CBRANCH_CDBGSYS_AND_USER::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_ENDPGM_SAVED class methods ---

    Inst_SOPP__S_ENDPGM_SAVED::Inst_SOPP__S_ENDPGM_SAVED(InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_endpgm_saved")
    {
    } // Inst_SOPP__S_ENDPGM_SAVED

    Inst_SOPP__S_ENDPGM_SAVED::~Inst_SOPP__S_ENDPGM_SAVED()
    {
    } // ~Inst_SOPP__S_ENDPGM_SAVED

    // --- description from .arch file ---
    // End of program; signal that a wave has been saved by the context-switch
    // trap handler and terminate wavefront.
    // The hardware implicitly executes S_WAITCNT 0 before executing this
    // instruction.
    // Use S_ENDPGM in all cases unless you are executing the context-switch
    // save handler.
    void
    Inst_SOPP__S_ENDPGM_SAVED::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_SET_GPR_IDX_OFF class methods ---

    Inst_SOPP__S_SET_GPR_IDX_OFF::Inst_SOPP__S_SET_GPR_IDX_OFF(
          InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_set_gpr_idx_off")
    {
    } // Inst_SOPP__S_SET_GPR_IDX_OFF

    Inst_SOPP__S_SET_GPR_IDX_OFF::~Inst_SOPP__S_SET_GPR_IDX_OFF()
    {
    } // ~Inst_SOPP__S_SET_GPR_IDX_OFF

    // --- description from .arch file ---
    // MODE.gpr_idx_en = 0.
    // Clear GPR indexing mode. Vector operations after this will not perform
    // ---  relative GPR addressing regardless of the contents of M0. This
    // ---  instruction does not modify M0.
    void
    Inst_SOPP__S_SET_GPR_IDX_OFF::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SOPP__S_SET_GPR_IDX_MODE class methods ---

    Inst_SOPP__S_SET_GPR_IDX_MODE::Inst_SOPP__S_SET_GPR_IDX_MODE(
          InFmt_SOPP *iFmt)
        : Inst_SOPP(iFmt, "s_set_gpr_idx_mode")
    {
    } // Inst_SOPP__S_SET_GPR_IDX_MODE

    Inst_SOPP__S_SET_GPR_IDX_MODE::~Inst_SOPP__S_SET_GPR_IDX_MODE()
    {
    } // ~Inst_SOPP__S_SET_GPR_IDX_MODE

    // --- description from .arch file ---
    // M0[15:12] = SIMM4.
    // Modify the mode used for vector GPR indexing.
    // The raw contents of the source field are read and used to set the enable
    // bits. SIMM4[0] = VSRC0_REL, SIMM4[1] = VSRC1_REL, SIMM4[2] = VSRC2_REL
    // and SIMM4[3] = VDST_REL.
    void
    Inst_SOPP__S_SET_GPR_IDX_MODE::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SMEM__S_LOAD_DWORD class methods ---

    Inst_SMEM__S_LOAD_DWORD::Inst_SMEM__S_LOAD_DWORD(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_load_dword")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_SMEM__S_LOAD_DWORD

    Inst_SMEM__S_LOAD_DWORD::~Inst_SMEM__S_LOAD_DWORD()
    {
    } // ~Inst_SMEM__S_LOAD_DWORD

    /**
     * Read 1 dword from scalar data cache. If the offset is specified as an
     * sgpr, the sgpr contains an unsigned byte offset (the 2 LSBs are
     * ignored). If the offset is specified as an immediate 20-bit constant,
     * the constant is an unsigned byte offset.
     */
    void
    Inst_SMEM__S_LOAD_DWORD::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);

        addr.read();

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, addr, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe
            .issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_LOAD_DWORD::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<1>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_LOAD_DWORD::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        ScalarOperandU32 sdst(gpuDynInst, instData.SDATA);
        sdst.write();
    } // completeAcc
    // --- Inst_SMEM__S_LOAD_DWORDX2 class methods ---

    Inst_SMEM__S_LOAD_DWORDX2::Inst_SMEM__S_LOAD_DWORDX2(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_load_dwordx2")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_SMEM__S_LOAD_DWORDX2

    Inst_SMEM__S_LOAD_DWORDX2::~Inst_SMEM__S_LOAD_DWORDX2()
    {
    } // ~Inst_SMEM__S_LOAD_DWORDX2

    /**
     * Read 2 dwords from scalar data cache. See s_load_dword for details on
     * the offset input.
     */
    void
    Inst_SMEM__S_LOAD_DWORDX2::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);

        addr.read();

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, addr, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe.
            issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_LOAD_DWORDX2::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<2>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_LOAD_DWORDX2::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        ScalarOperandU64 sdst(gpuDynInst, instData.SDATA);
        sdst.write();
    } // completeAcc
    // --- Inst_SMEM__S_LOAD_DWORDX4 class methods ---

    Inst_SMEM__S_LOAD_DWORDX4::Inst_SMEM__S_LOAD_DWORDX4(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_load_dwordx4")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_SMEM__S_LOAD_DWORDX4

    Inst_SMEM__S_LOAD_DWORDX4::~Inst_SMEM__S_LOAD_DWORDX4()
    {
    } // ~Inst_SMEM__S_LOAD_DWORDX4

    // --- description from .arch file ---
    // Read 4 dwords from scalar data cache. See S_LOAD_DWORD for details on
    // the offset input.
    void
    Inst_SMEM__S_LOAD_DWORDX4::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);

        addr.read();

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, addr, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe.
            issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_LOAD_DWORDX4::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<4>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_LOAD_DWORDX4::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        ScalarOperandU128 sdst(gpuDynInst, instData.SDATA);
        sdst.write();
    } // completeAcc
    // --- Inst_SMEM__S_LOAD_DWORDX8 class methods ---

    Inst_SMEM__S_LOAD_DWORDX8::Inst_SMEM__S_LOAD_DWORDX8(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_load_dwordx8")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_SMEM__S_LOAD_DWORDX8

    Inst_SMEM__S_LOAD_DWORDX8::~Inst_SMEM__S_LOAD_DWORDX8()
    {
    } // ~Inst_SMEM__S_LOAD_DWORDX8

    // --- description from .arch file ---
    // Read 8 dwords from scalar data cache. See S_LOAD_DWORD for details on
    // the offset input.
    void
    Inst_SMEM__S_LOAD_DWORDX8::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);

        addr.read();

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, addr, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe.
            issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_LOAD_DWORDX8::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<8>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_LOAD_DWORDX8::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        ScalarOperandU256 sdst(gpuDynInst, instData.SDATA);
        sdst.write();
    } // completeAcc
    // --- Inst_SMEM__S_LOAD_DWORDX16 class methods ---

    Inst_SMEM__S_LOAD_DWORDX16::Inst_SMEM__S_LOAD_DWORDX16(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_load_dwordx16")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_SMEM__S_LOAD_DWORDX16

    Inst_SMEM__S_LOAD_DWORDX16::~Inst_SMEM__S_LOAD_DWORDX16()
    {
    } // ~Inst_SMEM__S_LOAD_DWORDX16

    // --- description from .arch file ---
    // Read 16 dwords from scalar data cache. See S_LOAD_DWORD for details on
    // the offset input.
    void
    Inst_SMEM__S_LOAD_DWORDX16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);

        addr.read();

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, addr, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe.
            issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_LOAD_DWORDX16::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<16>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_LOAD_DWORDX16::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        ScalarOperandU512 sdst(gpuDynInst, instData.SDATA);
        sdst.write();
    } // completeAcc
    // --- Inst_SMEM__S_BUFFER_LOAD_DWORD class methods ---

    Inst_SMEM__S_BUFFER_LOAD_DWORD::Inst_SMEM__S_BUFFER_LOAD_DWORD(
          InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_buffer_load_dword")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_SMEM__S_BUFFER_LOAD_DWORD

    Inst_SMEM__S_BUFFER_LOAD_DWORD::~Inst_SMEM__S_BUFFER_LOAD_DWORD()
    {
    } // ~Inst_SMEM__S_BUFFER_LOAD_DWORD

    // --- description from .arch file ---
    // Read 1 dword from scalar data cache. See S_LOAD_DWORD for details on the
    // ---  offset input.
    void
    Inst_SMEM__S_BUFFER_LOAD_DWORD::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, instData.SBASE);

        rsrcDesc.read();

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, rsrcDesc, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe
            .issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_BUFFER_LOAD_DWORD::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<1>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_BUFFER_LOAD_DWORD::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        // 1 request, size 32
        ScalarOperandU32 sdst(gpuDynInst, instData.SDATA);
        sdst.write();
    } // completeAcc
    // --- Inst_SMEM__S_BUFFER_LOAD_DWORDX2 class methods ---

    Inst_SMEM__S_BUFFER_LOAD_DWORDX2::Inst_SMEM__S_BUFFER_LOAD_DWORDX2(
          InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_buffer_load_dwordx2")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_SMEM__S_BUFFER_LOAD_DWORDX2

    Inst_SMEM__S_BUFFER_LOAD_DWORDX2::~Inst_SMEM__S_BUFFER_LOAD_DWORDX2()
    {
    } // ~Inst_SMEM__S_BUFFER_LOAD_DWORDX2

    // --- description from .arch file ---
    // Read 2 dwords from scalar data cache. See S_LOAD_DWORD for details on
    // the offset input.
    void
    Inst_SMEM__S_BUFFER_LOAD_DWORDX2::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, instData.SBASE);

        rsrcDesc.read();

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, rsrcDesc, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe
            .issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_BUFFER_LOAD_DWORDX2::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<2>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_BUFFER_LOAD_DWORDX2::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        // use U64 because 2 requests, each size 32
        ScalarOperandU64 sdst(gpuDynInst, instData.SDATA);
        sdst.write();
    } // completeAcc
    // --- Inst_SMEM__S_BUFFER_LOAD_DWORDX4 class methods ---

    Inst_SMEM__S_BUFFER_LOAD_DWORDX4::Inst_SMEM__S_BUFFER_LOAD_DWORDX4(
          InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_buffer_load_dwordx4")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_SMEM__S_BUFFER_LOAD_DWORDX4

    Inst_SMEM__S_BUFFER_LOAD_DWORDX4::~Inst_SMEM__S_BUFFER_LOAD_DWORDX4()
    {
    } // ~Inst_SMEM__S_BUFFER_LOAD_DWORDX4

    // --- description from .arch file ---
    // Read 4 dwords from scalar data cache. See S_LOAD_DWORD for details on
    // the offset input.
    void
    Inst_SMEM__S_BUFFER_LOAD_DWORDX4::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, instData.SBASE);

        rsrcDesc.read();

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, rsrcDesc, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe
            .issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_BUFFER_LOAD_DWORDX4::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<4>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_BUFFER_LOAD_DWORDX4::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        // 4 requests, each size 32
        ScalarOperandU128 sdst(gpuDynInst, instData.SDATA);
        sdst.write();
    } // completeAcc
    // --- Inst_SMEM__S_BUFFER_LOAD_DWORDX8 class methods ---

    Inst_SMEM__S_BUFFER_LOAD_DWORDX8::Inst_SMEM__S_BUFFER_LOAD_DWORDX8(
          InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_buffer_load_dwordx8")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_SMEM__S_BUFFER_LOAD_DWORDX8

    Inst_SMEM__S_BUFFER_LOAD_DWORDX8::~Inst_SMEM__S_BUFFER_LOAD_DWORDX8()
    {
    } // ~Inst_SMEM__S_BUFFER_LOAD_DWORDX8

    // --- description from .arch file ---
    // Read 8 dwords from scalar data cache. See S_LOAD_DWORD for details on
    // the offset input.
    void
    Inst_SMEM__S_BUFFER_LOAD_DWORDX8::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, instData.SBASE);

        rsrcDesc.read();

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, rsrcDesc, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe
            .issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_BUFFER_LOAD_DWORDX8::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<8>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_BUFFER_LOAD_DWORDX8::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        // 8 requests, each size 32
        ScalarOperandU256 sdst(gpuDynInst, instData.SDATA);
        sdst.write();
    } // completeAcc
    // --- Inst_SMEM__S_BUFFER_LOAD_DWORDX16 class methods ---

    Inst_SMEM__S_BUFFER_LOAD_DWORDX16::Inst_SMEM__S_BUFFER_LOAD_DWORDX16(
          InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_buffer_load_dwordx16")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_SMEM__S_BUFFER_LOAD_DWORDX16

    Inst_SMEM__S_BUFFER_LOAD_DWORDX16::~Inst_SMEM__S_BUFFER_LOAD_DWORDX16()
    {
    } // ~Inst_SMEM__S_BUFFER_LOAD_DWORDX16

    // --- description from .arch file ---
    // Read 16 dwords from scalar data cache. See S_LOAD_DWORD for details on
    // the offset input.
    void
    Inst_SMEM__S_BUFFER_LOAD_DWORDX16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, instData.SBASE);

        rsrcDesc.read();

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, rsrcDesc, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe
            .issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_BUFFER_LOAD_DWORDX16::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<16>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_BUFFER_LOAD_DWORDX16::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        // 16 requests, each size 32
        ScalarOperandU512 sdst(gpuDynInst, instData.SDATA);
        sdst.write();
    } // completeAcc
    // --- Inst_SMEM__S_STORE_DWORD class methods ---

    Inst_SMEM__S_STORE_DWORD::Inst_SMEM__S_STORE_DWORD(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_store_dword")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_SMEM__S_STORE_DWORD

    Inst_SMEM__S_STORE_DWORD::~Inst_SMEM__S_STORE_DWORD()
    {
    } // ~Inst_SMEM__S_STORE_DWORD

    // --- description from .arch file ---
    // Write 1 dword to scalar data cache.
    // If the offset is specified as an SGPR, the SGPR contains an unsigned
    // BYTE offset (the 2 LSBs are ignored).
    // If the offset is specified as an immediate 20-bit constant, the
    // constant is an unsigned BYTE offset.
    void
    Inst_SMEM__S_STORE_DWORD::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);
        ConstScalarOperandU32 sdata(gpuDynInst, instData.SDATA);

        addr.read();
        sdata.read();

        std::memcpy((void*)gpuDynInst->scalar_data, sdata.rawDataPtr(),
            sizeof(ScalarRegU32));

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, addr, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe.
            issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_STORE_DWORD::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<1>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_STORE_DWORD::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_SMEM__S_STORE_DWORDX2 class methods ---

    Inst_SMEM__S_STORE_DWORDX2::Inst_SMEM__S_STORE_DWORDX2(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_store_dwordx2")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_SMEM__S_STORE_DWORDX2

    Inst_SMEM__S_STORE_DWORDX2::~Inst_SMEM__S_STORE_DWORDX2()
    {
    } // ~Inst_SMEM__S_STORE_DWORDX2

    // --- description from .arch file ---
    // Write 2 dwords to scalar data cache. See S_STORE_DWORD for details on
    // the offset input.
    void
    Inst_SMEM__S_STORE_DWORDX2::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);
        ConstScalarOperandU64 sdata(gpuDynInst, instData.SDATA);

        addr.read();
        sdata.read();

        std::memcpy((void*)gpuDynInst->scalar_data, sdata.rawDataPtr(),
            sizeof(ScalarRegU64));

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, addr, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe.
            issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_STORE_DWORDX2::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<2>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_STORE_DWORDX2::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_SMEM__S_STORE_DWORDX4 class methods ---

    Inst_SMEM__S_STORE_DWORDX4::Inst_SMEM__S_STORE_DWORDX4(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_store_dwordx4")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_SMEM__S_STORE_DWORDX4

    Inst_SMEM__S_STORE_DWORDX4::~Inst_SMEM__S_STORE_DWORDX4()
    {
    } // ~Inst_SMEM__S_STORE_DWORDX4

    // --- description from .arch file ---
    // Write 4 dwords to scalar data cache. See S_STORE_DWORD for details on
    // the offset input.
    void
    Inst_SMEM__S_STORE_DWORDX4::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        ScalarRegU32 offset(0);
        ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);
        ConstScalarOperandU64 sdata(gpuDynInst, instData.SDATA);

        addr.read();
        sdata.read();

        std::memcpy((void*)gpuDynInst->scalar_data, sdata.rawDataPtr(),
            sizeof(gpuDynInst->scalar_data));

        if (instData.IMM) {
            offset = extData.OFFSET;
        } else {
            ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
            off_sgpr.read();
            offset = off_sgpr.rawData();
        }

        calcAddr(gpuDynInst, addr, offset);

        gpuDynInst->computeUnit()->scalarMemoryPipe.
            issueRequest(gpuDynInst);
    } // execute

    void
    Inst_SMEM__S_STORE_DWORDX4::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<4>(gpuDynInst);
    } // initiateAcc

    void
    Inst_SMEM__S_STORE_DWORDX4::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_SMEM__S_BUFFER_STORE_DWORD class methods ---

    Inst_SMEM__S_BUFFER_STORE_DWORD::Inst_SMEM__S_BUFFER_STORE_DWORD(
          InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_buffer_store_dword")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_SMEM__S_BUFFER_STORE_DWORD

    Inst_SMEM__S_BUFFER_STORE_DWORD::~Inst_SMEM__S_BUFFER_STORE_DWORD()
    {
    } // ~Inst_SMEM__S_BUFFER_STORE_DWORD

    // --- description from .arch file ---
    // Write 1 dword to scalar data cache. See S_STORE_DWORD for details on the
    // ---  offset input.
    void
    Inst_SMEM__S_BUFFER_STORE_DWORD::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_SMEM__S_BUFFER_STORE_DWORD::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_SMEM__S_BUFFER_STORE_DWORD::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_SMEM__S_BUFFER_STORE_DWORDX2 class methods ---

    Inst_SMEM__S_BUFFER_STORE_DWORDX2::Inst_SMEM__S_BUFFER_STORE_DWORDX2(
          InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_buffer_store_dwordx2")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_SMEM__S_BUFFER_STORE_DWORDX2

    Inst_SMEM__S_BUFFER_STORE_DWORDX2::~Inst_SMEM__S_BUFFER_STORE_DWORDX2()
    {
    } // ~Inst_SMEM__S_BUFFER_STORE_DWORDX2

    // --- description from .arch file ---
    // Write 2 dwords to scalar data cache. See S_STORE_DWORD for details on
    // the offset input.
    void
    Inst_SMEM__S_BUFFER_STORE_DWORDX2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_SMEM__S_BUFFER_STORE_DWORDX2::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_SMEM__S_BUFFER_STORE_DWORDX2::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_SMEM__S_BUFFER_STORE_DWORDX4 class methods ---

    Inst_SMEM__S_BUFFER_STORE_DWORDX4::Inst_SMEM__S_BUFFER_STORE_DWORDX4(
          InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_buffer_store_dwordx4")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_SMEM__S_BUFFER_STORE_DWORDX4

    Inst_SMEM__S_BUFFER_STORE_DWORDX4::~Inst_SMEM__S_BUFFER_STORE_DWORDX4()
    {
    } // ~Inst_SMEM__S_BUFFER_STORE_DWORDX4

    // --- description from .arch file ---
    // Write 4 dwords to scalar data cache. See S_STORE_DWORD for details on
    // the offset input.
    void
    Inst_SMEM__S_BUFFER_STORE_DWORDX4::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_SMEM__S_BUFFER_STORE_DWORDX4::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_SMEM__S_BUFFER_STORE_DWORDX4::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_SMEM__S_DCACHE_INV class methods ---

    Inst_SMEM__S_DCACHE_INV::Inst_SMEM__S_DCACHE_INV(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_dcache_inv")
    {
    } // Inst_SMEM__S_DCACHE_INV

    Inst_SMEM__S_DCACHE_INV::~Inst_SMEM__S_DCACHE_INV()
    {
    } // ~Inst_SMEM__S_DCACHE_INV

    // --- description from .arch file ---
    // Invalidate the scalar data cache.
    void
    Inst_SMEM__S_DCACHE_INV::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SMEM__S_DCACHE_WB class methods ---

    Inst_SMEM__S_DCACHE_WB::Inst_SMEM__S_DCACHE_WB(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_dcache_wb")
    {
    } // Inst_SMEM__S_DCACHE_WB

    Inst_SMEM__S_DCACHE_WB::~Inst_SMEM__S_DCACHE_WB()
    {
    } // ~Inst_SMEM__S_DCACHE_WB

    // --- description from .arch file ---
    // Write back dirty data in the scalar data cache.
    void
    Inst_SMEM__S_DCACHE_WB::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SMEM__S_DCACHE_INV_VOL class methods ---

    Inst_SMEM__S_DCACHE_INV_VOL::Inst_SMEM__S_DCACHE_INV_VOL(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_dcache_inv_vol")
    {
    } // Inst_SMEM__S_DCACHE_INV_VOL

    Inst_SMEM__S_DCACHE_INV_VOL::~Inst_SMEM__S_DCACHE_INV_VOL()
    {
    } // ~Inst_SMEM__S_DCACHE_INV_VOL

    // --- description from .arch file ---
    // Invalidate the scalar data cache volatile lines.
    void
    Inst_SMEM__S_DCACHE_INV_VOL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SMEM__S_DCACHE_WB_VOL class methods ---

    Inst_SMEM__S_DCACHE_WB_VOL::Inst_SMEM__S_DCACHE_WB_VOL(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_dcache_wb_vol")
    {
    } // Inst_SMEM__S_DCACHE_WB_VOL

    Inst_SMEM__S_DCACHE_WB_VOL::~Inst_SMEM__S_DCACHE_WB_VOL()
    {
    } // ~Inst_SMEM__S_DCACHE_WB_VOL

    // --- description from .arch file ---
    // Write back dirty data in the scalar data cache volatile lines.
    void
    Inst_SMEM__S_DCACHE_WB_VOL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SMEM__S_MEMTIME class methods ---

    Inst_SMEM__S_MEMTIME::Inst_SMEM__S_MEMTIME(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_memtime")
    {
    } // Inst_SMEM__S_MEMTIME

    Inst_SMEM__S_MEMTIME::~Inst_SMEM__S_MEMTIME()
    {
    } // ~Inst_SMEM__S_MEMTIME

    // --- description from .arch file ---
    // Return current 64-bit timestamp.
    void
    Inst_SMEM__S_MEMTIME::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SMEM__S_MEMREALTIME class methods ---

    Inst_SMEM__S_MEMREALTIME::Inst_SMEM__S_MEMREALTIME(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_memrealtime")
    {
    } // Inst_SMEM__S_MEMREALTIME

    Inst_SMEM__S_MEMREALTIME::~Inst_SMEM__S_MEMREALTIME()
    {
    } // ~Inst_SMEM__S_MEMREALTIME

    // --- description from .arch file ---
    // Return current 64-bit RTC.
    void
    Inst_SMEM__S_MEMREALTIME::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SMEM__S_ATC_PROBE class methods ---

    Inst_SMEM__S_ATC_PROBE::Inst_SMEM__S_ATC_PROBE(InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_atc_probe")
    {
    } // Inst_SMEM__S_ATC_PROBE

    Inst_SMEM__S_ATC_PROBE::~Inst_SMEM__S_ATC_PROBE()
    {
    } // ~Inst_SMEM__S_ATC_PROBE

    // --- description from .arch file ---
    // Probe or prefetch an address into the SQC data cache.
    void
    Inst_SMEM__S_ATC_PROBE::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_SMEM__S_ATC_PROBE_BUFFER class methods ---

    Inst_SMEM__S_ATC_PROBE_BUFFER::Inst_SMEM__S_ATC_PROBE_BUFFER(
          InFmt_SMEM *iFmt)
        : Inst_SMEM(iFmt, "s_atc_probe_buffer")
    {
    } // Inst_SMEM__S_ATC_PROBE_BUFFER

    Inst_SMEM__S_ATC_PROBE_BUFFER::~Inst_SMEM__S_ATC_PROBE_BUFFER()
    {
    } // ~Inst_SMEM__S_ATC_PROBE_BUFFER

    // --- description from .arch file ---
    // Probe or prefetch an address into the SQC data cache.
    void
    Inst_SMEM__S_ATC_PROBE_BUFFER::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP2__V_CNDMASK_B32 class methods ---

    Inst_VOP2__V_CNDMASK_B32::Inst_VOP2__V_CNDMASK_B32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_cndmask_b32")
    {
        setFlag(ALU);
        setFlag(ReadsVCC);
    } // Inst_VOP2__V_CNDMASK_B32

    Inst_VOP2__V_CNDMASK_B32::~Inst_VOP2__V_CNDMASK_B32()
    {
    } // ~Inst_VOP2__V_CNDMASK_B32

    // --- description from .arch file ---
    // D.u = (VCC[i] ? S1.u : S0.u) (i = threadID in wave); VOP3: specify VCC
    // as a scalar GPR in S2.
    void
    Inst_VOP2__V_CNDMASK_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        ConstScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();
        vcc.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane]
                    = bits(vcc.rawData(), lane) ? src1[lane] : src0[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_ADD_F32 class methods ---

    Inst_VOP2__V_ADD_F32::Inst_VOP2__V_ADD_F32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_add_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP2__V_ADD_F32

    Inst_VOP2__V_ADD_F32::~Inst_VOP2__V_ADD_F32()
    {
    } // ~Inst_VOP2__V_ADD_F32

    // --- description from .arch file ---
    // D.f = S0.f + S1.f.
    void
    Inst_VOP2__V_ADD_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        VecOperandF32 src1(gpuDynInst, instData.VSRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        if (isDPPInst()) {
            VecOperandF32 src0_dpp(gpuDynInst, extData.iFmt_VOP_DPP.SRC0);
            src0_dpp.read();

            DPRINTF(VEGA, "Handling V_ADD_F32 SRC DPP. SRC0: register v[%d], "
                    "DPP_CTRL: 0x%#x, SRC0_ABS: %d, SRC0_NEG: %d, "
                    "SRC1_ABS: %d, SRC1_NEG: %d, BC: %d, "
                    "BANK_MASK: %d, ROW_MASK: %d\n", extData.iFmt_VOP_DPP.SRC0,
                    extData.iFmt_VOP_DPP.DPP_CTRL,
                    extData.iFmt_VOP_DPP.SRC0_ABS,
                    extData.iFmt_VOP_DPP.SRC0_NEG,
                    extData.iFmt_VOP_DPP.SRC1_ABS,
                    extData.iFmt_VOP_DPP.SRC1_NEG,
                    extData.iFmt_VOP_DPP.BC,
                    extData.iFmt_VOP_DPP.BANK_MASK,
                    extData.iFmt_VOP_DPP.ROW_MASK);

            processDPP(gpuDynInst, extData.iFmt_VOP_DPP, src0_dpp, src1);

            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = src0_dpp[lane] + src1[lane];
                }
            }
        } else {
            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = src0[lane] + src1[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_SUB_F32 class methods ---

    Inst_VOP2__V_SUB_F32::Inst_VOP2__V_SUB_F32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_sub_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP2__V_SUB_F32

    Inst_VOP2__V_SUB_F32::~Inst_VOP2__V_SUB_F32()
    {
    } // ~Inst_VOP2__V_SUB_F32

    // --- description from .arch file ---
    // D.f = S0.f - S1.f.
    // SQ translates to V_ADD_F32.
    void
    Inst_VOP2__V_SUB_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] - src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_SUBREV_F32 class methods ---

    Inst_VOP2__V_SUBREV_F32::Inst_VOP2__V_SUBREV_F32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_subrev_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP2__V_SUBREV_F32

    Inst_VOP2__V_SUBREV_F32::~Inst_VOP2__V_SUBREV_F32()
    {
    } // ~Inst_VOP2__V_SUBREV_F32

    // --- description from .arch file ---
    // D.f = S1.f - S0.f.
    // SQ translates to V_ADD_F32.
    void
    Inst_VOP2__V_SUBREV_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] - src0[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MUL_LEGACY_F32 class methods ---

    Inst_VOP2__V_MUL_LEGACY_F32::Inst_VOP2__V_MUL_LEGACY_F32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_mul_legacy_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP2__V_MUL_LEGACY_F32

    Inst_VOP2__V_MUL_LEGACY_F32::~Inst_VOP2__V_MUL_LEGACY_F32()
    {
    } // ~Inst_VOP2__V_MUL_LEGACY_F32

    // --- description from .arch file ---
    // D.f = S0.f * S1.f (DX9 rules, 0.0*x = 0.0).
    void
    Inst_VOP2__V_MUL_LEGACY_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] * src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MUL_F32 class methods ---

    Inst_VOP2__V_MUL_F32::Inst_VOP2__V_MUL_F32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_mul_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP2__V_MUL_F32

    Inst_VOP2__V_MUL_F32::~Inst_VOP2__V_MUL_F32()
    {
    } // ~Inst_VOP2__V_MUL_F32

    // --- description from .arch file ---
    // D.f = S0.f * S1.f.
    void
    Inst_VOP2__V_MUL_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isnan(src0[lane]) ||
                    std::isnan(src1[lane])) {
                    vdst[lane] = NAN;
                } else if ((std::fpclassify(src0[lane]) == FP_SUBNORMAL ||
                           std::fpclassify(src0[lane]) == FP_ZERO) &&
                           !std::signbit(src0[lane])) {
                    if (std::isinf(src1[lane])) {
                        vdst[lane] = NAN;
                    } else if (!std::signbit(src1[lane])) {
                        vdst[lane] = +0.0;
                    } else {
                        vdst[lane] = -0.0;
                    }
                } else if ((std::fpclassify(src0[lane]) == FP_SUBNORMAL ||
                           std::fpclassify(src0[lane]) == FP_ZERO) &&
                           std::signbit(src0[lane])) {
                    if (std::isinf(src1[lane])) {
                        vdst[lane] = NAN;
                    } else if (std::signbit(src1[lane])) {
                        vdst[lane] = +0.0;
                    } else {
                        vdst[lane] = -0.0;
                    }
                } else if (std::isinf(src0[lane]) &&
                           !std::signbit(src0[lane])) {
                    if (std::fpclassify(src1[lane]) == FP_SUBNORMAL ||
                        std::fpclassify(src1[lane]) == FP_ZERO) {
                        vdst[lane] = NAN;
                    } else if (!std::signbit(src1[lane])) {
                        vdst[lane] = +INFINITY;
                    } else {
                        vdst[lane] = -INFINITY;
                    }
                } else if (std::isinf(src0[lane]) &&
                           std::signbit(src0[lane])) {
                    if (std::fpclassify(src1[lane]) == FP_SUBNORMAL ||
                        std::fpclassify(src1[lane]) == FP_ZERO) {
                        vdst[lane] = NAN;
                    } else if (std::signbit(src1[lane])) {
                        vdst[lane] = +INFINITY;
                    } else {
                        vdst[lane] = -INFINITY;
                    }
                } else {
                    vdst[lane] = src0[lane] * src1[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MUL_I32_I24 class methods ---

    Inst_VOP2__V_MUL_I32_I24::Inst_VOP2__V_MUL_I32_I24(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_mul_i32_i24")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MUL_I32_I24

    Inst_VOP2__V_MUL_I32_I24::~Inst_VOP2__V_MUL_I32_I24()
    {
    } // ~Inst_VOP2__V_MUL_I32_I24

    // --- description from .arch file ---
    // D.i = S0.i[23:0] * S1.i[23:0].
    void
    Inst_VOP2__V_MUL_I32_I24::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = sext<24>(bits(src0[lane], 23, 0))
                    * sext<24>(bits(src1[lane], 23, 0));
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MUL_HI_I32_I24 class methods ---

    Inst_VOP2__V_MUL_HI_I32_I24::Inst_VOP2__V_MUL_HI_I32_I24(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_mul_hi_i32_i24")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MUL_HI_I32_I24

    Inst_VOP2__V_MUL_HI_I32_I24::~Inst_VOP2__V_MUL_HI_I32_I24()
    {
    } // ~Inst_VOP2__V_MUL_HI_I32_I24

    // --- description from .arch file ---
    // D.i = (S0.i[23:0] * S1.i[23:0])>>32.
    void
    Inst_VOP2__V_MUL_HI_I32_I24::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemI64 tmp_src0
                    = (VecElemI64)sext<24>(bits(src0[lane], 23, 0));
                VecElemI64 tmp_src1
                    = (VecElemI64)sext<24>(bits(src1[lane], 23, 0));

                vdst[lane] = (VecElemI32)((tmp_src0 * tmp_src1) >> 32);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MUL_U32_U24 class methods ---

    Inst_VOP2__V_MUL_U32_U24::Inst_VOP2__V_MUL_U32_U24(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_mul_u32_u24")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MUL_U32_U24

    Inst_VOP2__V_MUL_U32_U24::~Inst_VOP2__V_MUL_U32_U24()
    {
    } // ~Inst_VOP2__V_MUL_U32_U24

    // --- description from .arch file ---
    // D.u = S0.u[23:0] * S1.u[23:0].
    void
    Inst_VOP2__V_MUL_U32_U24::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        VecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        if (isSDWAInst()) {
            VecOperandU32 src0_sdwa(gpuDynInst, extData.iFmt_VOP_SDWA.SRC0);
            // use copies of original src0, src1, and dest during selecting
            VecOperandU32 origSrc0_sdwa(gpuDynInst,
                                        extData.iFmt_VOP_SDWA.SRC0);
            VecOperandU32 origSrc1(gpuDynInst, instData.VSRC1);
            VecOperandU32 origVdst(gpuDynInst, instData.VDST);

            src0_sdwa.read();
            origSrc0_sdwa.read();
            origSrc1.read();

            DPRINTF(VEGA, "Handling V_MUL_U32_U24 SRC SDWA. SRC0: register "
                    "v[%d], DST_SEL: %d, DST_U: %d, CLMP: %d, SRC0_SEL: "
                    "%d, SRC0_SEXT: %d, SRC0_NEG: %d, SRC0_ABS: %d, SRC1_SEL: "
                    "%d, SRC1_SEXT: %d, SRC1_NEG: %d, SRC1_ABS: %d\n",
                    extData.iFmt_VOP_SDWA.SRC0, extData.iFmt_VOP_SDWA.DST_SEL,
                    extData.iFmt_VOP_SDWA.DST_U,
                    extData.iFmt_VOP_SDWA.CLMP,
                    extData.iFmt_VOP_SDWA.SRC0_SEL,
                    extData.iFmt_VOP_SDWA.SRC0_SEXT,
                    extData.iFmt_VOP_SDWA.SRC0_NEG,
                    extData.iFmt_VOP_SDWA.SRC0_ABS,
                    extData.iFmt_VOP_SDWA.SRC1_SEL,
                    extData.iFmt_VOP_SDWA.SRC1_SEXT,
                    extData.iFmt_VOP_SDWA.SRC1_NEG,
                    extData.iFmt_VOP_SDWA.SRC1_ABS);

            processSDWA_src(extData.iFmt_VOP_SDWA, src0_sdwa, origSrc0_sdwa,
                            src1, origSrc1);

            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = bits(src0_sdwa[lane], 23, 0) *
                                 bits(src1[lane], 23, 0);
                    origVdst[lane] = vdst[lane]; // keep copy consistent
                }
            }

            processSDWA_dst(extData.iFmt_VOP_SDWA, vdst, origVdst);
        } else {
            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = bits(src0[lane], 23, 0) *
                                 bits(src1[lane], 23, 0);
                }
            }
        }


        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MUL_HI_U32_U24 class methods ---

    Inst_VOP2__V_MUL_HI_U32_U24::Inst_VOP2__V_MUL_HI_U32_U24(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_mul_hi_u32_u24")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MUL_HI_U32_U24

    Inst_VOP2__V_MUL_HI_U32_U24::~Inst_VOP2__V_MUL_HI_U32_U24()
    {
    } // ~Inst_VOP2__V_MUL_HI_U32_U24

    // --- description from .arch file ---
    // D.i = (S0.u[23:0] * S1.u[23:0])>>32.
    void
    Inst_VOP2__V_MUL_HI_U32_U24::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemU64 tmp_src0 = (VecElemU64)bits(src0[lane], 23, 0);
                VecElemU64 tmp_src1 = (VecElemU64)bits(src1[lane], 23, 0);
                vdst[lane] = (VecElemU32)((tmp_src0 * tmp_src1) >> 32);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MIN_F32 class methods ---

    Inst_VOP2__V_MIN_F32::Inst_VOP2__V_MIN_F32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_min_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP2__V_MIN_F32

    Inst_VOP2__V_MIN_F32::~Inst_VOP2__V_MIN_F32()
    {
    } // ~Inst_VOP2__V_MIN_F32

    // --- description from .arch file ---
    // D.f = (S0.f < S1.f ? S0.f : S1.f).
    void
    Inst_VOP2__V_MIN_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fmin(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MAX_F32 class methods ---

    Inst_VOP2__V_MAX_F32::Inst_VOP2__V_MAX_F32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_max_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP2__V_MAX_F32

    Inst_VOP2__V_MAX_F32::~Inst_VOP2__V_MAX_F32()
    {
    } // ~Inst_VOP2__V_MAX_F32

    // --- description from .arch file ---
    // D.f = (S0.f >= S1.f ? S0.f : S1.f).
    void
    Inst_VOP2__V_MAX_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fmax(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MIN_I32 class methods ---

    Inst_VOP2__V_MIN_I32::Inst_VOP2__V_MIN_I32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_min_i32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MIN_I32

    Inst_VOP2__V_MIN_I32::~Inst_VOP2__V_MIN_I32()
    {
    } // ~Inst_VOP2__V_MIN_I32

    // --- description from .arch file ---
    // D.i = min(S0.i, S1.i).
    void
    Inst_VOP2__V_MIN_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::min(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MAX_I32 class methods ---

    Inst_VOP2__V_MAX_I32::Inst_VOP2__V_MAX_I32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_max_i32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MAX_I32

    Inst_VOP2__V_MAX_I32::~Inst_VOP2__V_MAX_I32()
    {
    } // ~Inst_VOP2__V_MAX_I32

    // --- description from .arch file ---
    // D.i = max(S0.i, S1.i).
    void
    Inst_VOP2__V_MAX_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::max(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MIN_U32 class methods ---

    Inst_VOP2__V_MIN_U32::Inst_VOP2__V_MIN_U32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_min_u32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MIN_U32

    Inst_VOP2__V_MIN_U32::~Inst_VOP2__V_MIN_U32()
    {
    } // ~Inst_VOP2__V_MIN_U32

    // --- description from .arch file ---
    // D.u = min(S0.u, S1.u).
    void
    Inst_VOP2__V_MIN_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::min(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MAX_U32 class methods ---

    Inst_VOP2__V_MAX_U32::Inst_VOP2__V_MAX_U32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_max_u32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MAX_U32

    Inst_VOP2__V_MAX_U32::~Inst_VOP2__V_MAX_U32()
    {
    } // ~Inst_VOP2__V_MAX_U32

    // --- description from .arch file ---
    // D.u = max(S0.u, S1.u).
    void
    Inst_VOP2__V_MAX_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::max(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_LSHRREV_B32 class methods ---

    Inst_VOP2__V_LSHRREV_B32::Inst_VOP2__V_LSHRREV_B32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_lshrrev_b32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_LSHRREV_B32

    Inst_VOP2__V_LSHRREV_B32::~Inst_VOP2__V_LSHRREV_B32()
    {
    } // ~Inst_VOP2__V_LSHRREV_B32

    // --- description from .arch file ---
    // D.u = S1.u >> S0.u[4:0].
    // The vacated bits are set to zero.
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP2__V_LSHRREV_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] >> bits(src0[lane], 4, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_ASHRREV_I32 class methods ---

    Inst_VOP2__V_ASHRREV_I32::Inst_VOP2__V_ASHRREV_I32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_ashrrev_i32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_ASHRREV_I32

    Inst_VOP2__V_ASHRREV_I32::~Inst_VOP2__V_ASHRREV_I32()
    {
    } // ~Inst_VOP2__V_ASHRREV_I32

    // --- description from .arch file ---
    // D.i = signext(S1.i) >> S0.i[4:0].
    // The vacated bits are set to the sign bit of the input value.
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP2__V_ASHRREV_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] >> bits(src0[lane], 4, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_LSHLREV_B32 class methods ---

    Inst_VOP2__V_LSHLREV_B32::Inst_VOP2__V_LSHLREV_B32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_lshlrev_b32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_LSHLREV_B32

    Inst_VOP2__V_LSHLREV_B32::~Inst_VOP2__V_LSHLREV_B32()
    {
    } // ~Inst_VOP2__V_LSHLREV_B32

    // --- description from .arch file ---
    // D.u = S1.u << S0.u[4:0].
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP2__V_LSHLREV_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        VecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        if (isSDWAInst()) {
            VecOperandU32 src0_sdwa(gpuDynInst, extData.iFmt_VOP_SDWA.SRC0);
            // use copies of original src0, src1, and vdst during selecting
            VecOperandU32 origSrc0_sdwa(gpuDynInst,
                                        extData.iFmt_VOP_SDWA.SRC0);
            VecOperandU32 origSrc1(gpuDynInst, instData.VSRC1);
            VecOperandU32 origVdst(gpuDynInst, instData.VDST);

            src0_sdwa.read();
            origSrc0_sdwa.read();
            origSrc1.read();

            DPRINTF(VEGA, "Handling V_LSHLREV_B32 SRC SDWA. SRC0: register "
                    "v[%d], DST_SEL: %d, DST_U: %d, CLMP: %d, SRC0_SEL: "
                    "%d, SRC0_SEXT: %d, SRC0_NEG: %d, SRC0_ABS: %d, SRC1_SEL: "
                    "%d, SRC1_SEXT: %d, SRC1_NEG: %d, SRC1_ABS: %d\n",
                    extData.iFmt_VOP_SDWA.SRC0, extData.iFmt_VOP_SDWA.DST_SEL,
                    extData.iFmt_VOP_SDWA.DST_U,
                    extData.iFmt_VOP_SDWA.CLMP,
                    extData.iFmt_VOP_SDWA.SRC0_SEL,
                    extData.iFmt_VOP_SDWA.SRC0_SEXT,
                    extData.iFmt_VOP_SDWA.SRC0_NEG,
                    extData.iFmt_VOP_SDWA.SRC0_ABS,
                    extData.iFmt_VOP_SDWA.SRC1_SEL,
                    extData.iFmt_VOP_SDWA.SRC1_SEXT,
                    extData.iFmt_VOP_SDWA.SRC1_NEG,
                    extData.iFmt_VOP_SDWA.SRC1_ABS);

            processSDWA_src(extData.iFmt_VOP_SDWA, src0_sdwa, origSrc0_sdwa,
                            src1, origSrc1);

            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = src1[lane] << bits(src0_sdwa[lane], 4, 0);
                    origVdst[lane] = vdst[lane]; // keep copy consistent
                }
            }

            processSDWA_dst(extData.iFmt_VOP_SDWA, vdst, origVdst);
        } else {
            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = src1[lane] << bits(src0[lane], 4, 0);
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_AND_B32 class methods ---

    Inst_VOP2__V_AND_B32::Inst_VOP2__V_AND_B32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_and_b32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_AND_B32

    Inst_VOP2__V_AND_B32::~Inst_VOP2__V_AND_B32()
    {
    } // ~Inst_VOP2__V_AND_B32

    // --- description from .arch file ---
    // D.u = S0.u & S1.u.
    // Input and output modifiers not supported.
    void
    Inst_VOP2__V_AND_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] & src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_OR_B32 class methods ---

    Inst_VOP2__V_OR_B32::Inst_VOP2__V_OR_B32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_or_b32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_OR_B32

    Inst_VOP2__V_OR_B32::~Inst_VOP2__V_OR_B32()
    {
    } // ~Inst_VOP2__V_OR_B32

    // --- description from .arch file ---
    // D.u = S0.u | S1.u.
    // Input and output modifiers not supported.
    void
    Inst_VOP2__V_OR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        VecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        if (isSDWAInst()) {
            VecOperandU32 src0_sdwa(gpuDynInst, extData.iFmt_VOP_SDWA.SRC0);
            // use copies of original src0, src1, and dest during selecting
            VecOperandU32 origSrc0_sdwa(gpuDynInst,
                                        extData.iFmt_VOP_SDWA.SRC0);
            VecOperandU32 origSrc1(gpuDynInst, instData.VSRC1);
            VecOperandU32 origVdst(gpuDynInst, instData.VDST);

            src0_sdwa.read();
            origSrc0_sdwa.read();
            origSrc1.read();

            DPRINTF(VEGA, "Handling V_OR_B32 SRC SDWA. SRC0: register v[%d], "
                    "DST_SEL: %d, DST_U: %d, CLMP: %d, SRC0_SEL: %d, "
                    "SRC0_SEXT: %d, SRC0_NEG: %d, SRC0_ABS: %d, SRC1_SEL: %d, "
                    "SRC1_SEXT: %d, SRC1_NEG: %d, SRC1_ABS: %d\n",
                    extData.iFmt_VOP_SDWA.SRC0, extData.iFmt_VOP_SDWA.DST_SEL,
                    extData.iFmt_VOP_SDWA.DST_U,
                    extData.iFmt_VOP_SDWA.CLMP,
                    extData.iFmt_VOP_SDWA.SRC0_SEL,
                    extData.iFmt_VOP_SDWA.SRC0_SEXT,
                    extData.iFmt_VOP_SDWA.SRC0_NEG,
                    extData.iFmt_VOP_SDWA.SRC0_ABS,
                    extData.iFmt_VOP_SDWA.SRC1_SEL,
                    extData.iFmt_VOP_SDWA.SRC1_SEXT,
                    extData.iFmt_VOP_SDWA.SRC1_NEG,
                    extData.iFmt_VOP_SDWA.SRC1_ABS);

            processSDWA_src(extData.iFmt_VOP_SDWA, src0_sdwa, origSrc0_sdwa,
                            src1, origSrc1);

            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = src0_sdwa[lane] | src1[lane];
                    origVdst[lane] = vdst[lane]; // keep copy consistent
                }
            }

            processSDWA_dst(extData.iFmt_VOP_SDWA, vdst, origVdst);
        } else {
            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = src0[lane] | src1[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_XOR_B32 class methods ---

    Inst_VOP2__V_XOR_B32::Inst_VOP2__V_XOR_B32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_xor_b32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_XOR_B32

    Inst_VOP2__V_XOR_B32::~Inst_VOP2__V_XOR_B32()
    {
    } // ~Inst_VOP2__V_XOR_B32

    // --- description from .arch file ---
    // D.u = S0.u ^ S1.u.
    // Input and output modifiers not supported.
    void
    Inst_VOP2__V_XOR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] ^ src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MAC_F32 class methods ---

    Inst_VOP2__V_MAC_F32::Inst_VOP2__V_MAC_F32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_mac_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(MAC);
    } // Inst_VOP2__V_MAC_F32

    Inst_VOP2__V_MAC_F32::~Inst_VOP2__V_MAC_F32()
    {
    } // ~Inst_VOP2__V_MAC_F32

    // --- description from .arch file ---
    // D.f = S0.f * S1.f + D.f.
    // SQ translates to V_MAD_F32.
    void
    Inst_VOP2__V_MAC_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        VecOperandF32 src1(gpuDynInst, instData.VSRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();
        vdst.read();

        if (isDPPInst()) {
            VecOperandF32 src0_dpp(gpuDynInst, extData.iFmt_VOP_DPP.SRC0);
            src0_dpp.read();

            DPRINTF(VEGA, "Handling V_MAC_F32 SRC DPP. SRC0: register v[%d], "
                    "DPP_CTRL: 0x%#x, SRC0_ABS: %d, SRC0_NEG: %d, "
                    "SRC1_ABS: %d, SRC1_NEG: %d, BC: %d, "
                    "BANK_MASK: %d, ROW_MASK: %d\n", extData.iFmt_VOP_DPP.SRC0,
                    extData.iFmt_VOP_DPP.DPP_CTRL,
                    extData.iFmt_VOP_DPP.SRC0_ABS,
                    extData.iFmt_VOP_DPP.SRC0_NEG,
                    extData.iFmt_VOP_DPP.SRC1_ABS,
                    extData.iFmt_VOP_DPP.SRC1_NEG,
                    extData.iFmt_VOP_DPP.BC,
                    extData.iFmt_VOP_DPP.BANK_MASK,
                    extData.iFmt_VOP_DPP.ROW_MASK);

            processDPP(gpuDynInst, extData.iFmt_VOP_DPP, src0_dpp, src1);

            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = std::fma(src0_dpp[lane], src1[lane],
                                          vdst[lane]);
                }
            }
        } else {
            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = std::fma(src0[lane], src1[lane], vdst[lane]);
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MADMK_F32 class methods ---

    Inst_VOP2__V_MADMK_F32::Inst_VOP2__V_MADMK_F32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_madmk_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(MAD);
    } // Inst_VOP2__V_MADMK_F32

    Inst_VOP2__V_MADMK_F32::~Inst_VOP2__V_MADMK_F32()
    {
    } // ~Inst_VOP2__V_MADMK_F32

    // --- description from .arch file ---
    // D.f = S0.f * K + S1.f; K is a 32-bit inline constant.
    // This opcode cannot use the VOP3 encoding and cannot use input/output
    // ---  modifiers.
    // SQ translates to V_MAD_F32.
    void
    Inst_VOP2__V_MADMK_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);
        VecElemF32 k = extData.imm_f32;

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fma(src0[lane], k, src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MADAK_F32 class methods ---

    Inst_VOP2__V_MADAK_F32::Inst_VOP2__V_MADAK_F32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_madak_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(MAD);
    } // Inst_VOP2__V_MADAK_F32

    Inst_VOP2__V_MADAK_F32::~Inst_VOP2__V_MADAK_F32()
    {
    } // ~Inst_VOP2__V_MADAK_F32

    // --- description from .arch file ---
    // D.f = S0.f * S1.f + K; K is a 32-bit inline constant.
    // This opcode cannot use the VOP3 encoding and cannot use input/output
    // ---  modifiers.
    // SQ translates to V_MAD_F32.
    void
    Inst_VOP2__V_MADAK_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);
        VecElemF32 k = extData.imm_f32;

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fma(src0[lane], src1[lane], k);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_ADD_CO_U32 class methods ---

    Inst_VOP2__V_ADD_CO_U32::Inst_VOP2__V_ADD_CO_U32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_add_co_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
    } // Inst_VOP2__V_ADD_CO_U32

    Inst_VOP2__V_ADD_CO_U32::~Inst_VOP2__V_ADD_CO_U32()
    {
    } // ~Inst_VOP2__V_ADD_CO_U32

    // --- description from .arch file ---
    // D.u = S0.u + S1.u;
    // VCC[threadId] = (S0.u + S1.u >= 0x800000000ULL ? 1 : 0) is an UNSIGNED
    // ---  overflow or carry-out for V_ADDC_U32.
    // In VOP3 the VCC destination may be an arbitrary SGPR-pair.
    void
    Inst_VOP2__V_ADD_CO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        VecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        if (isSDWAInst()) {
            VecOperandU32 src0_sdwa(gpuDynInst, extData.iFmt_VOP_SDWA.SRC0);
            // use copies of original src0, src1, and dest during selecting
            VecOperandU32 origSrc0_sdwa(gpuDynInst,
                                        extData.iFmt_VOP_SDWA.SRC0);
            VecOperandU32 origSrc1(gpuDynInst, instData.VSRC1);
            VecOperandU32 origVdst(gpuDynInst, instData.VDST);

            src0_sdwa.read();
            origSrc0_sdwa.read();
            origSrc1.read();

            DPRINTF(VEGA, "Handling V_ADD_CO_U32 SRC SDWA. SRC0: register "
                    "v[%d], DST_SEL: %d, DST_U: %d, CLMP: %d, SRC0_SEL: %d, "
                    "SRC0_SEXT: %d, SRC0_NEG: %d, SRC0_ABS: %d, SRC1_SEL: %d, "
                    "SRC1_SEXT: %d, SRC1_NEG: %d, SRC1_ABS: %d\n",
                    extData.iFmt_VOP_SDWA.SRC0, extData.iFmt_VOP_SDWA.DST_SEL,
                    extData.iFmt_VOP_SDWA.DST_U,
                    extData.iFmt_VOP_SDWA.CLMP,
                    extData.iFmt_VOP_SDWA.SRC0_SEL,
                    extData.iFmt_VOP_SDWA.SRC0_SEXT,
                    extData.iFmt_VOP_SDWA.SRC0_NEG,
                    extData.iFmt_VOP_SDWA.SRC0_ABS,
                    extData.iFmt_VOP_SDWA.SRC1_SEL,
                    extData.iFmt_VOP_SDWA.SRC1_SEXT,
                    extData.iFmt_VOP_SDWA.SRC1_NEG,
                    extData.iFmt_VOP_SDWA.SRC1_ABS);

            processSDWA_src(extData.iFmt_VOP_SDWA, src0_sdwa, origSrc0_sdwa,
                            src1, origSrc1);

            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = src0_sdwa[lane] + src1[lane];
                    origVdst[lane] = vdst[lane]; // keep copy consistent
                    vcc.setBit(lane, ((VecElemU64)src0_sdwa[lane]
                        + (VecElemU64)src1[lane] >= 0x100000000ULL) ? 1 : 0);
                }
            }

            processSDWA_dst(extData.iFmt_VOP_SDWA, vdst, origVdst);
        } else {
            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = src0[lane] + src1[lane];
                    vcc.setBit(lane, ((VecElemU64)src0[lane]
                        + (VecElemU64)src1[lane] >= 0x100000000ULL) ? 1 : 0);
                }
            }
        }

        vcc.write();
        vdst.write();
    } // execute
    // --- Inst_VOP2__V_SUB_CO_U32 class methods ---

    Inst_VOP2__V_SUB_CO_U32::Inst_VOP2__V_SUB_CO_U32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_sub_co_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
    } // Inst_VOP2__V_SUB_CO_U32

    Inst_VOP2__V_SUB_CO_U32::~Inst_VOP2__V_SUB_CO_U32()
    {
    } // ~Inst_VOP2__V_SUB_CO_U32

    // --- description from .arch file ---
    // D.u = S0.u - S1.u;
    // VCC[threadId] = (S1.u > S0.u ? 1 : 0) is an UNSIGNED overflow or
    // carry-out for V_SUBB_U32.
    // In VOP3 the VCC destination may be an arbitrary SGPR-pair.
    void
    Inst_VOP2__V_SUB_CO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] - src1[lane];
                vcc.setBit(lane, src1[lane] > src0[lane] ? 1 : 0);
            }
        }

        vdst.write();
        vcc.write();
    } // execute
    // --- Inst_VOP2__V_SUBREV_CO_U32 class methods ---

    Inst_VOP2__V_SUBREV_CO_U32::Inst_VOP2__V_SUBREV_CO_U32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_subrev_co_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
    } // Inst_VOP2__V_SUBREV_CO_U32

    Inst_VOP2__V_SUBREV_CO_U32::~Inst_VOP2__V_SUBREV_CO_U32()
    {
    } // ~Inst_VOP2__V_SUBREV_CO_U32

    // --- description from .arch file ---
    // D.u = S1.u - S0.u;
    // VCC[threadId] = (S0.u > S1.u ? 1 : 0) is an UNSIGNED overflow or
    // carry-out for V_SUBB_U32.
    // In VOP3 the VCC destination may be an arbitrary SGPR-pair.
    void
    Inst_VOP2__V_SUBREV_CO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] - src0[lane];
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        vdst.write();
        vcc.write();
    } // execute
    // --- Inst_VOP2__V_ADDC_CO_U32 class methods ---

    Inst_VOP2__V_ADDC_CO_U32::Inst_VOP2__V_ADDC_CO_U32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_addc_co_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
        setFlag(ReadsVCC);
    } // Inst_VOP2__V_ADDC_CO_U32

    Inst_VOP2__V_ADDC_CO_U32::~Inst_VOP2__V_ADDC_CO_U32()
    {
    } // ~Inst_VOP2__V_ADDC_CO_U32

    // --- description from .arch file ---
    // D.u = S0.u + S1.u + VCC[threadId];
    // VCC[threadId] = (S0.u + S1.u + VCC[threadId] >= 0x800000000ULL ? 1 : 0)
    // is an UNSIGNED overflow.
    // In VOP3 the VCC destination may be an arbitrary SGPR-pair, and the VCC
    // source comes from the SGPR-pair at S2.u.
    void
    Inst_VOP2__V_ADDC_CO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();
        vcc.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] + src1[lane]
                    + bits(vcc.rawData(), lane);
                vcc.setBit(lane, ((VecElemU64)src0[lane]
                    + (VecElemU64)src1[lane]
                        + (VecElemU64)bits(vcc.rawData(), lane, lane))
                            >= 0x100000000 ? 1 : 0);
            }
        }

        vdst.write();
        vcc.write();
    } // execute
    // --- Inst_VOP2__V_SUBB_CO_U32 class methods ---

    Inst_VOP2__V_SUBB_CO_U32::Inst_VOP2__V_SUBB_CO_U32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_subb_co_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
        setFlag(ReadsVCC);
    } // Inst_VOP2__V_SUBB_CO_U32

    Inst_VOP2__V_SUBB_CO_U32::~Inst_VOP2__V_SUBB_CO_U32()
    {
    } // ~Inst_VOP2__V_SUBB_CO_U32

    // --- description from .arch file ---
    // D.u = S0.u - S1.u - VCC[threadId];
    // VCC[threadId] = (S1.u + VCC[threadId] > S0.u ? 1 : 0) is an UNSIGNED
    // ---  overflow.
    // In VOP3 the VCC destination may be an arbitrary SGPR-pair, and the VCC
    // ---  source comes from the SGPR-pair at S2.u.
    void
    Inst_VOP2__V_SUBB_CO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();
        vcc.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane]
                    = src0[lane] - src1[lane] - bits(vcc.rawData(), lane);
                vcc.setBit(lane, (src1[lane] + bits(vcc.rawData(), lane))
                    > src0[lane] ? 1 : 0);
            }
        }

        vdst.write();
        vcc.write();
    } // execute
    // --- Inst_VOP2__V_SUBBREV_CO_U32 class methods ---

    Inst_VOP2__V_SUBBREV_CO_U32::Inst_VOP2__V_SUBBREV_CO_U32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_subbrev_co_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
        setFlag(ReadsVCC);
    } // Inst_VOP2__V_SUBBREV_CO_U32

    Inst_VOP2__V_SUBBREV_CO_U32::~Inst_VOP2__V_SUBBREV_CO_U32()
    {
    } // ~Inst_VOP2__V_SUBBREV_CO_U32

    // --- description from .arch file ---
    // D.u = S1.u - S0.u - VCC[threadId];
    // VCC[threadId] = (S1.u + VCC[threadId] > S0.u ? 1 : 0) is an UNSIGNED
    // overflow.
    // In VOP3 the VCC destination may be an arbitrary SGPR-pair, and the VCC
    // source comes from the SGPR-pair at S2.u. SQ translates to V_SUBB_U32.
    // SQ translates this to V_SUBREV_U32 with reversed operands.
    void
    Inst_VOP2__V_SUBBREV_CO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();
        vcc.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane]
                    = src1[lane] - src0[lane] - bits(vcc.rawData(), lane);
                vcc.setBit(lane, (src0[lane] + bits(vcc.rawData(), lane))
                    > src1[lane] ? 1 : 0);
            }
        }

        vdst.write();
        vcc.write();
    } // execute
    // --- Inst_VOP2__V_ADD_F16 class methods ---

    Inst_VOP2__V_ADD_F16::Inst_VOP2__V_ADD_F16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_add_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP2__V_ADD_F16

    Inst_VOP2__V_ADD_F16::~Inst_VOP2__V_ADD_F16()
    {
    } // ~Inst_VOP2__V_ADD_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 + S1.f16.
    // Supports denormals, round mode, exception flags, saturation.
    void
    Inst_VOP2__V_ADD_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP2__V_SUB_F16 class methods ---

    Inst_VOP2__V_SUB_F16::Inst_VOP2__V_SUB_F16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_sub_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP2__V_SUB_F16

    Inst_VOP2__V_SUB_F16::~Inst_VOP2__V_SUB_F16()
    {
    } // ~Inst_VOP2__V_SUB_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 - S1.f16.
    // Supports denormals, round mode, exception flags, saturation.
    // SQ translates to V_ADD_F16.
    void
    Inst_VOP2__V_SUB_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP2__V_SUBREV_F16 class methods ---

    Inst_VOP2__V_SUBREV_F16::Inst_VOP2__V_SUBREV_F16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_subrev_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP2__V_SUBREV_F16

    Inst_VOP2__V_SUBREV_F16::~Inst_VOP2__V_SUBREV_F16()
    {
    } // ~Inst_VOP2__V_SUBREV_F16

    // --- description from .arch file ---
    // D.f16 = S1.f16 - S0.f16.
    // Supports denormals, round mode, exception flags, saturation.
    // SQ translates to V_ADD_F16.
    void
    Inst_VOP2__V_SUBREV_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP2__V_MUL_F16 class methods ---

    Inst_VOP2__V_MUL_F16::Inst_VOP2__V_MUL_F16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_mul_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP2__V_MUL_F16

    Inst_VOP2__V_MUL_F16::~Inst_VOP2__V_MUL_F16()
    {
    } // ~Inst_VOP2__V_MUL_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 * S1.f16.
    // Supports denormals, round mode, exception flags, saturation.
    void
    Inst_VOP2__V_MUL_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP2__V_MAC_F16 class methods ---

    Inst_VOP2__V_MAC_F16::Inst_VOP2__V_MAC_F16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_mac_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(MAC);
    } // Inst_VOP2__V_MAC_F16

    Inst_VOP2__V_MAC_F16::~Inst_VOP2__V_MAC_F16()
    {
    } // ~Inst_VOP2__V_MAC_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 * S1.f16 + D.f16.
    // Supports round mode, exception flags, saturation.
    // SQ translates this to V_MAD_F16.
    void
    Inst_VOP2__V_MAC_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP2__V_MADMK_F16 class methods ---

    Inst_VOP2__V_MADMK_F16::Inst_VOP2__V_MADMK_F16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_madmk_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(MAD);
    } // Inst_VOP2__V_MADMK_F16

    Inst_VOP2__V_MADMK_F16::~Inst_VOP2__V_MADMK_F16()
    {
    } // ~Inst_VOP2__V_MADMK_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 * K.f16 + S1.f16; K is a 16-bit inline constant stored
    // in the following literal DWORD.
    // This opcode cannot use the VOP3 encoding and cannot use input/output
    // modifiers. Supports round mode, exception flags, saturation.
    // SQ translates this to V_MAD_F16.
    void
    Inst_VOP2__V_MADMK_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP2__V_MADAK_F16 class methods ---

    Inst_VOP2__V_MADAK_F16::Inst_VOP2__V_MADAK_F16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_madak_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(MAD);
    } // Inst_VOP2__V_MADAK_F16

    Inst_VOP2__V_MADAK_F16::~Inst_VOP2__V_MADAK_F16()
    {
    } // ~Inst_VOP2__V_MADAK_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 * S1.f16 + K.f16; K is a 16-bit inline constant stored
    // in the following literal DWORD.
    // This opcode cannot use the VOP3 encoding and cannot use input/output
    // modifiers. Supports round mode, exception flags, saturation.
    // SQ translates this to V_MAD_F16.
    void
    Inst_VOP2__V_MADAK_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP2__V_ADD_U16 class methods ---

    Inst_VOP2__V_ADD_U16::Inst_VOP2__V_ADD_U16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_add_u16")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_ADD_U16

    Inst_VOP2__V_ADD_U16::~Inst_VOP2__V_ADD_U16()
    {
    } // ~Inst_VOP2__V_ADD_U16

    // --- description from .arch file ---
    // D.u16 = S0.u16 + S1.u16.
    // Supports saturation (unsigned 16-bit integer domain).
    void
    Inst_VOP2__V_ADD_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] + src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_SUB_U16 class methods ---

    Inst_VOP2__V_SUB_U16::Inst_VOP2__V_SUB_U16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_sub_u16")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_SUB_U16

    Inst_VOP2__V_SUB_U16::~Inst_VOP2__V_SUB_U16()
    {
    } // ~Inst_VOP2__V_SUB_U16

    // --- description from .arch file ---
    // D.u16 = S0.u16 - S1.u16.
    // Supports saturation (unsigned 16-bit integer domain).
    void
    Inst_VOP2__V_SUB_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] - src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_SUBREV_U16 class methods ---

    Inst_VOP2__V_SUBREV_U16::Inst_VOP2__V_SUBREV_U16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_subrev_u16")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_SUBREV_U16

    Inst_VOP2__V_SUBREV_U16::~Inst_VOP2__V_SUBREV_U16()
    {
    } // ~Inst_VOP2__V_SUBREV_U16

    // --- description from .arch file ---
    // D.u16 = S1.u16 - S0.u16.
    // Supports saturation (unsigned 16-bit integer domain).
    // SQ translates this to V_SUB_U16 with reversed operands.
    void
    Inst_VOP2__V_SUBREV_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] - src0[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MUL_LO_U16 class methods ---

    Inst_VOP2__V_MUL_LO_U16::Inst_VOP2__V_MUL_LO_U16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_mul_lo_u16")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MUL_LO_U16

    Inst_VOP2__V_MUL_LO_U16::~Inst_VOP2__V_MUL_LO_U16()
    {
    } // ~Inst_VOP2__V_MUL_LO_U16

    // --- description from .arch file ---
    // D.u16 = S0.u16 * S1.u16.
    // Supports saturation (unsigned 16-bit integer domain).
    void
    Inst_VOP2__V_MUL_LO_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] * src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_LSHLREV_B16 class methods ---

    Inst_VOP2__V_LSHLREV_B16::Inst_VOP2__V_LSHLREV_B16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_lshlrev_b16")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_LSHLREV_B16

    Inst_VOP2__V_LSHLREV_B16::~Inst_VOP2__V_LSHLREV_B16()
    {
    } // ~Inst_VOP2__V_LSHLREV_B16

    // --- description from .arch file ---
    // D.u[15:0] = S1.u[15:0] << S0.u[3:0].
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP2__V_LSHLREV_B16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] << bits(src0[lane], 3, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_LSHRREV_B16 class methods ---

    Inst_VOP2__V_LSHRREV_B16::Inst_VOP2__V_LSHRREV_B16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_lshrrev_b16")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_LSHRREV_B16

    Inst_VOP2__V_LSHRREV_B16::~Inst_VOP2__V_LSHRREV_B16()
    {
    } // ~Inst_VOP2__V_LSHRREV_B16

    // --- description from .arch file ---
    // D.u[15:0] = S1.u[15:0] >> S0.u[3:0].
    // The vacated bits are set to zero.
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP2__V_LSHRREV_B16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] >> src0[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_ASHRREV_I16 class methods ---

    Inst_VOP2__V_ASHRREV_I16::Inst_VOP2__V_ASHRREV_I16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_ashrrev_i16")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_ASHRREV_I16

    Inst_VOP2__V_ASHRREV_I16::~Inst_VOP2__V_ASHRREV_I16()
    {
    } // ~Inst_VOP2__V_ASHRREV_I16

    // --- description from .arch file ---
    // D.i[15:0] = signext(S1.i[15:0]) >> S0.i[3:0].
    // The vacated bits are set to the sign bit of the input value.
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP2__V_ASHRREV_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        VecOperandI16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] >> src0[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MAX_F16 class methods ---

    Inst_VOP2__V_MAX_F16::Inst_VOP2__V_MAX_F16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_max_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP2__V_MAX_F16

    Inst_VOP2__V_MAX_F16::~Inst_VOP2__V_MAX_F16()
    {
    } // ~Inst_VOP2__V_MAX_F16

    // --- description from .arch file ---
    // D.f16 = max(S0.f16, S1.f16).
    // IEEE compliant. Supports denormals, round mode, exception flags,
    // saturation.
    void
    Inst_VOP2__V_MAX_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP2__V_MIN_F16 class methods ---

    Inst_VOP2__V_MIN_F16::Inst_VOP2__V_MIN_F16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_min_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP2__V_MIN_F16

    Inst_VOP2__V_MIN_F16::~Inst_VOP2__V_MIN_F16()
    {
    } // ~Inst_VOP2__V_MIN_F16

    // --- description from .arch file ---
    // D.f16 = min(S0.f16, S1.f16).
    // IEEE compliant. Supports denormals, round mode, exception flags,
    // saturation.
    void
    Inst_VOP2__V_MIN_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP2__V_MAX_U16 class methods ---

    Inst_VOP2__V_MAX_U16::Inst_VOP2__V_MAX_U16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_max_u16")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MAX_U16

    Inst_VOP2__V_MAX_U16::~Inst_VOP2__V_MAX_U16()
    {
    } // ~Inst_VOP2__V_MAX_U16

    // --- description from .arch file ---
    // D.u[15:0] = max(S0.u[15:0], S1.u[15:0]).
    void
    Inst_VOP2__V_MAX_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::max(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MAX_I16 class methods ---

    Inst_VOP2__V_MAX_I16::Inst_VOP2__V_MAX_I16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_max_i16")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MAX_I16

    Inst_VOP2__V_MAX_I16::~Inst_VOP2__V_MAX_I16()
    {
    } // ~Inst_VOP2__V_MAX_I16

    // --- description from .arch file ---
    // D.i[15:0] = max(S0.i[15:0], S1.i[15:0]).
    void
    Inst_VOP2__V_MAX_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        VecOperandI16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::max(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MIN_U16 class methods ---

    Inst_VOP2__V_MIN_U16::Inst_VOP2__V_MIN_U16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_min_u16")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MIN_U16

    Inst_VOP2__V_MIN_U16::~Inst_VOP2__V_MIN_U16()
    {
    } // ~Inst_VOP2__V_MIN_U16

    // --- description from .arch file ---
    // D.u[15:0] = min(S0.u[15:0], S1.u[15:0]).
    void
    Inst_VOP2__V_MIN_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::min(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_MIN_I16 class methods ---

    Inst_VOP2__V_MIN_I16::Inst_VOP2__V_MIN_I16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_min_i16")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_MIN_I16

    Inst_VOP2__V_MIN_I16::~Inst_VOP2__V_MIN_I16()
    {
    } // ~Inst_VOP2__V_MIN_I16

    // --- description from .arch file ---
    // D.i[15:0] = min(S0.i[15:0], S1.i[15:0]).
    void
    Inst_VOP2__V_MIN_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        VecOperandI16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::min(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_LDEXP_F16 class methods ---

    Inst_VOP2__V_LDEXP_F16::Inst_VOP2__V_LDEXP_F16(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_ldexp_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP2__V_LDEXP_F16

    Inst_VOP2__V_LDEXP_F16::~Inst_VOP2__V_LDEXP_F16()
    {
    } // ~Inst_VOP2__V_LDEXP_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 * (2 ** S1.i16).
    void
    Inst_VOP2__V_LDEXP_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP2__V_ADD_U32 class methods ---

    Inst_VOP2__V_ADD_U32::Inst_VOP2__V_ADD_U32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_add_u32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_ADD_U32

    Inst_VOP2__V_ADD_U32::~Inst_VOP2__V_ADD_U32()
    {
    } // ~Inst_VOP2__V_ADD_U32

    // --- description from .arch file ---
    // D.u = S0.u + S1.u;
    void
    Inst_VOP2__V_ADD_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        VecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        if (isSDWAInst()) {
            VecOperandU32 src0_sdwa(gpuDynInst, extData.iFmt_VOP_SDWA.SRC0);
            // use copies of original src0, src1, and dest during selecting
            VecOperandU32 origSrc0_sdwa(gpuDynInst,
                                        extData.iFmt_VOP_SDWA.SRC0);
            VecOperandU32 origSrc1(gpuDynInst, instData.VSRC1);
            VecOperandU32 origVdst(gpuDynInst, instData.VDST);

            src0_sdwa.read();
            origSrc0_sdwa.read();
            origSrc1.read();

            DPRINTF(VEGA, "Handling V_ADD_U32 SRC SDWA. SRC0: register v[%d], "
                    "DST_SEL: %d, DST_U: %d, CLMP: %d, SRC0_SEL: %d, "
                    "SRC0_SEXT: %d, SRC0_NEG: %d, SRC0_ABS: %d, SRC1_SEL: %d, "
                    "SRC1_SEXT: %d, SRC1_NEG: %d, SRC1_ABS: %d\n",
                    extData.iFmt_VOP_SDWA.SRC0, extData.iFmt_VOP_SDWA.DST_SEL,
                    extData.iFmt_VOP_SDWA.DST_U,
                    extData.iFmt_VOP_SDWA.CLMP,
                    extData.iFmt_VOP_SDWA.SRC0_SEL,
                    extData.iFmt_VOP_SDWA.SRC0_SEXT,
                    extData.iFmt_VOP_SDWA.SRC0_NEG,
                    extData.iFmt_VOP_SDWA.SRC0_ABS,
                    extData.iFmt_VOP_SDWA.SRC1_SEL,
                    extData.iFmt_VOP_SDWA.SRC1_SEXT,
                    extData.iFmt_VOP_SDWA.SRC1_NEG,
                    extData.iFmt_VOP_SDWA.SRC1_ABS);

            processSDWA_src(extData.iFmt_VOP_SDWA, src0_sdwa, origSrc0_sdwa,
                            src1, origSrc1);

            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = src0_sdwa[lane] + src1[lane];
                    origVdst[lane] = vdst[lane]; // keep copy consistent
                }
            }

            processSDWA_dst(extData.iFmt_VOP_SDWA, vdst, origVdst);
        } else {
            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = src0[lane] + src1[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_SUB_U32 class methods ---

    Inst_VOP2__V_SUB_U32::Inst_VOP2__V_SUB_U32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_sub_u32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_SUB_U32

    Inst_VOP2__V_SUB_U32::~Inst_VOP2__V_SUB_U32()
    {
    } // ~Inst_VOP2__V_SUB_U32

    // --- description from .arch file ---
    // D.u = S0.u - S1.u;
    void
    Inst_VOP2__V_SUB_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] - src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP2__V_SUBREV_U32 class methods ---

    Inst_VOP2__V_SUBREV_U32::Inst_VOP2__V_SUBREV_U32(InFmt_VOP2 *iFmt)
        : Inst_VOP2(iFmt, "v_subrev_u32")
    {
        setFlag(ALU);
    } // Inst_VOP2__V_SUBREV_U32

    Inst_VOP2__V_SUBREV_U32::~Inst_VOP2__V_SUBREV_U32()
    {
    } // ~Inst_VOP2__V_SUBREV_U32

    // --- description from .arch file ---
    // D.u = S1.u - S0.u;
    void
    Inst_VOP2__V_SUBREV_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] - src0[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_NOP class methods ---

    Inst_VOP1__V_NOP::Inst_VOP1__V_NOP(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_nop")
    {
        setFlag(Nop);
        setFlag(ALU);
    } // Inst_VOP1__V_NOP

    Inst_VOP1__V_NOP::~Inst_VOP1__V_NOP()
    {
    } // ~Inst_VOP1__V_NOP

    // --- description from .arch file ---
    // Do nothing.
    void
    Inst_VOP1__V_NOP::execute(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_VOP1__V_MOV_B32 class methods ---

    Inst_VOP1__V_MOV_B32::Inst_VOP1__V_MOV_B32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_mov_b32")
    {
        setFlag(ALU);
    } // Inst_VOP1__V_MOV_B32

    Inst_VOP1__V_MOV_B32::~Inst_VOP1__V_MOV_B32()
    {
    } // ~Inst_VOP1__V_MOV_B32

    // --- description from .arch file ---
    // D.u = S0.u.
    // Input and output modifiers not supported; this is an untyped operation.
    void
    Inst_VOP1__V_MOV_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, instData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (isDPPInst()) {
            VecOperandU32 src_dpp(gpuDynInst, extData.iFmt_VOP_DPP.SRC0);
            src_dpp.read();

            DPRINTF(VEGA, "Handling V_MOV_B32 SRC DPP. SRC0: register v[%d], "
                    "DPP_CTRL: 0x%#x, SRC0_ABS: %d, SRC0_NEG: %d, "
                    "SRC1_ABS: %d, SRC1_NEG: %d, BC: %d, "
                    "BANK_MASK: %d, ROW_MASK: %d\n", extData.iFmt_VOP_DPP.SRC0,
                    extData.iFmt_VOP_DPP.DPP_CTRL,
                    extData.iFmt_VOP_DPP.SRC0_ABS,
                    extData.iFmt_VOP_DPP.SRC0_NEG,
                    extData.iFmt_VOP_DPP.SRC1_ABS,
                    extData.iFmt_VOP_DPP.SRC1_NEG,
                    extData.iFmt_VOP_DPP.BC,
                    extData.iFmt_VOP_DPP.BANK_MASK,
                    extData.iFmt_VOP_DPP.ROW_MASK);

            // NOTE: For VOP1, there is no SRC1, so make sure we're not trying
            // to negate it or take the absolute value of it
            assert(!extData.iFmt_VOP_DPP.SRC1_ABS);
            assert(!extData.iFmt_VOP_DPP.SRC1_NEG);
            processDPP(gpuDynInst, extData.iFmt_VOP_DPP, src_dpp);

            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = src_dpp[lane];
                }
            }
        } else {
            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (wf->execMask(lane)) {
                    vdst[lane] = src[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_READFIRSTLANE_B32 class methods ---

    Inst_VOP1__V_READFIRSTLANE_B32::Inst_VOP1__V_READFIRSTLANE_B32(
          InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_readfirstlane_b32")
    {
        setFlag(ALU);
    } // Inst_VOP1__V_READFIRSTLANE_B32

    Inst_VOP1__V_READFIRSTLANE_B32::~Inst_VOP1__V_READFIRSTLANE_B32()
    {
    } // ~Inst_VOP1__V_READFIRSTLANE_B32

    // --- description from .arch file ---
    // Copy one VGPR value to one SGPR. D = SGPR destination, S0 = source data
    // (VGPR# or M0 for lds direct access), Lane# = FindFirst1fromLSB(exec)
    // (Lane# = 0 if exec is zero). Ignores exec mask for the access. SQ
    // translates to V_READLANE_B32.
    // Input and output modifiers not supported; this is an untyped operation.
    void
    Inst_VOP1__V_READFIRSTLANE_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarRegI32 src_lane(0);
        ScalarRegU64 exec_mask = wf->execMask().to_ullong();
        ConstVecOperandU32 src(gpuDynInst, instData.SRC0);
        ScalarOperandU32 sdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (exec_mask) {
            src_lane = findLsbSet(exec_mask);
        }

        sdst = src[src_lane];

        sdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_I32_F64 class methods ---

    Inst_VOP1__V_CVT_I32_F64::Inst_VOP1__V_CVT_I32_F64(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_i32_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_CVT_I32_F64

    Inst_VOP1__V_CVT_I32_F64::~Inst_VOP1__V_CVT_I32_F64()
    {
    } // ~Inst_VOP1__V_CVT_I32_F64

    // --- description from .arch file ---
    // D.i = (int)S0.d.
    // Out-of-range floating point values (including infinity) saturate. NaN is
    // ---  converted to 0.
    void
    Inst_VOP1__V_CVT_I32_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                int exp;
                std::frexp(src[lane],&exp);
                if (std::isnan(src[lane])) {
                    vdst[lane] = 0;
                } else if (std::isinf(src[lane]) || exp > 30) {
                    if (std::signbit(src[lane])) {
                        vdst[lane] = INT_MIN;
                    } else {
                        vdst[lane] = INT_MAX;
                    }
                } else {
                    vdst[lane] = (VecElemI32)src[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_F64_I32 class methods ---

    Inst_VOP1__V_CVT_F64_I32::Inst_VOP1__V_CVT_F64_I32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f64_i32")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_CVT_F64_I32

    Inst_VOP1__V_CVT_F64_I32::~Inst_VOP1__V_CVT_F64_I32()
    {
    } // ~Inst_VOP1__V_CVT_F64_I32

    // --- description from .arch file ---
    // D.d = (double)S0.i.
    void
    Inst_VOP1__V_CVT_F64_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src(gpuDynInst, instData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF64)src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_F32_I32 class methods ---

    Inst_VOP1__V_CVT_F32_I32::Inst_VOP1__V_CVT_F32_I32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f32_i32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_F32_I32

    Inst_VOP1__V_CVT_F32_I32::~Inst_VOP1__V_CVT_F32_I32()
    {
    } // ~Inst_VOP1__V_CVT_F32_I32

    // --- description from .arch file ---
    // D.f = (float)S0.i.
    void
    Inst_VOP1__V_CVT_F32_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_F32_U32 class methods ---

    Inst_VOP1__V_CVT_F32_U32::Inst_VOP1__V_CVT_F32_U32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f32_u32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_F32_U32

    Inst_VOP1__V_CVT_F32_U32::~Inst_VOP1__V_CVT_F32_U32()
    {
    } // ~Inst_VOP1__V_CVT_F32_U32

    // --- description from .arch file ---
    // D.f = (float)S0.u.
    void
    Inst_VOP1__V_CVT_F32_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_U32_F32 class methods ---

    Inst_VOP1__V_CVT_U32_F32::Inst_VOP1__V_CVT_U32_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_u32_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_U32_F32

    Inst_VOP1__V_CVT_U32_F32::~Inst_VOP1__V_CVT_U32_F32()
    {
    } // ~Inst_VOP1__V_CVT_U32_F32

    // --- description from .arch file ---
    // D.u = (unsigned)S0.f.
    // Out-of-range floating point values (including infinity) saturate. NaN is
    // ---  converted to 0.
    void
    Inst_VOP1__V_CVT_U32_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                int exp;
                std::frexp(src[lane],&exp);
                if (std::isnan(src[lane])) {
                    vdst[lane] = 0;
                } else if (std::isinf(src[lane])) {
                    if (std::signbit(src[lane])) {
                        vdst[lane] = 0;
                    } else {
                        vdst[lane] = UINT_MAX;
                    }
                } else if (exp > 31) {
                    vdst[lane] = UINT_MAX;
                } else {
                    vdst[lane] = (VecElemU32)src[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_I32_F32 class methods ---

    Inst_VOP1__V_CVT_I32_F32::Inst_VOP1__V_CVT_I32_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_i32_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_I32_F32

    Inst_VOP1__V_CVT_I32_F32::~Inst_VOP1__V_CVT_I32_F32()
    {
    } // ~Inst_VOP1__V_CVT_I32_F32

    // --- description from .arch file ---
    // D.i = (int)S0.f.
    // Out-of-range floating point values (including infinity) saturate. NaN is
    // ---  converted to 0.
    void
    Inst_VOP1__V_CVT_I32_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                int exp;
                std::frexp(src[lane],&exp);
                if (std::isnan(src[lane])) {
                    vdst[lane] = 0;
                } else if (std::isinf(src[lane]) || exp > 30) {
                    if (std::signbit(src[lane])) {
                        vdst[lane] = INT_MIN;
                    } else {
                        vdst[lane] = INT_MAX;
                    }
                } else {
                    vdst[lane] = (VecElemI32)src[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_MOV_FED_B32 class methods ---

    Inst_VOP1__V_MOV_FED_B32::Inst_VOP1__V_MOV_FED_B32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_mov_fed_b32")
    {
        setFlag(ALU);
    } // Inst_VOP1__V_MOV_FED_B32

    Inst_VOP1__V_MOV_FED_B32::~Inst_VOP1__V_MOV_FED_B32()
    {
    } // ~Inst_VOP1__V_MOV_FED_B32

    // --- description from .arch file ---
    // D.u = S0.u;
    // Introduce EDC double error upon write to dest vgpr without causing an
    // ---  exception.
    // Input and output modifiers not supported; this is an untyped operation.
    void
    Inst_VOP1__V_MOV_FED_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_CVT_F16_F32 class methods ---

    Inst_VOP1__V_CVT_F16_F32::Inst_VOP1__V_CVT_F16_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f16_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_F16_F32

    Inst_VOP1__V_CVT_F16_F32::~Inst_VOP1__V_CVT_F16_F32()
    {
    } // ~Inst_VOP1__V_CVT_F16_F32

    // --- description from .arch file ---
    // D.f16 = flt32_to_flt16(S0.f).
    // Supports input modifiers and creates FP16 denormals when appropriate.
    void
    Inst_VOP1__V_CVT_F16_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_CVT_F32_F16 class methods ---

    Inst_VOP1__V_CVT_F32_F16::Inst_VOP1__V_CVT_F32_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f32_f16")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_F32_F16

    Inst_VOP1__V_CVT_F32_F16::~Inst_VOP1__V_CVT_F32_F16()
    {
    } // ~Inst_VOP1__V_CVT_F32_F16

    // --- description from .arch file ---
    // D.f = flt16_to_flt32(S0.f16).
    // FP16 denormal inputs are always accepted.
    void
    Inst_VOP1__V_CVT_F32_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_CVT_RPI_I32_F32 class methods ---

    Inst_VOP1__V_CVT_RPI_I32_F32::Inst_VOP1__V_CVT_RPI_I32_F32(
          InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_rpi_i32_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_RPI_I32_F32

    Inst_VOP1__V_CVT_RPI_I32_F32::~Inst_VOP1__V_CVT_RPI_I32_F32()
    {
    } // ~Inst_VOP1__V_CVT_RPI_I32_F32

    // --- description from .arch file ---
    // D.i = (int)floor(S0.f + 0.5).
    void
    Inst_VOP1__V_CVT_RPI_I32_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemI32)std::floor(src[lane] + 0.5);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_FLR_I32_F32 class methods ---

    Inst_VOP1__V_CVT_FLR_I32_F32::Inst_VOP1__V_CVT_FLR_I32_F32(
          InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_flr_i32_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_FLR_I32_F32

    Inst_VOP1__V_CVT_FLR_I32_F32::~Inst_VOP1__V_CVT_FLR_I32_F32()
    {
    } // ~Inst_VOP1__V_CVT_FLR_I32_F32

    // --- description from .arch file ---
    // D.i = (int)floor(S0.f).
    void
    Inst_VOP1__V_CVT_FLR_I32_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemI32)std::floor(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_OFF_F32_I4 class methods ---

    Inst_VOP1__V_CVT_OFF_F32_I4::Inst_VOP1__V_CVT_OFF_F32_I4(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_off_f32_i4")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_OFF_F32_I4

    Inst_VOP1__V_CVT_OFF_F32_I4::~Inst_VOP1__V_CVT_OFF_F32_I4()
    {
    } // ~Inst_VOP1__V_CVT_OFF_F32_I4

    // --- description from .arch file ---
    // 4-bit signed int to 32-bit float. Used for interpolation in shader.
    void
    Inst_VOP1__V_CVT_OFF_F32_I4::execute(GPUDynInstPtr gpuDynInst)
    {
        // Could not parse sq_uc.arch desc field
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_CVT_F32_F64 class methods ---

    Inst_VOP1__V_CVT_F32_F64::Inst_VOP1__V_CVT_F32_F64(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f32_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_CVT_F32_F64

    Inst_VOP1__V_CVT_F32_F64::~Inst_VOP1__V_CVT_F32_F64()
    {
    } // ~Inst_VOP1__V_CVT_F32_F64

    // --- description from .arch file ---
    // D.f = (float)S0.d.
    void
    Inst_VOP1__V_CVT_F32_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_F64_F32 class methods ---

    Inst_VOP1__V_CVT_F64_F32::Inst_VOP1__V_CVT_F64_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f64_f32")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_CVT_F64_F32

    Inst_VOP1__V_CVT_F64_F32::~Inst_VOP1__V_CVT_F64_F32()
    {
    } // ~Inst_VOP1__V_CVT_F64_F32

    // --- description from .arch file ---
    // D.d = (double)S0.f.
    void
    Inst_VOP1__V_CVT_F64_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF64)src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_F32_UBYTE0 class methods ---

    Inst_VOP1__V_CVT_F32_UBYTE0::Inst_VOP1__V_CVT_F32_UBYTE0(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f32_ubyte0")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_F32_UBYTE0

    Inst_VOP1__V_CVT_F32_UBYTE0::~Inst_VOP1__V_CVT_F32_UBYTE0()
    {
    } // ~Inst_VOP1__V_CVT_F32_UBYTE0

    // --- description from .arch file ---
    // D.f = (float)(S0.u[7:0]).
    void
    Inst_VOP1__V_CVT_F32_UBYTE0::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)(bits(src[lane], 7, 0));
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_F32_UBYTE1 class methods ---

    Inst_VOP1__V_CVT_F32_UBYTE1::Inst_VOP1__V_CVT_F32_UBYTE1(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f32_ubyte1")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_F32_UBYTE1

    Inst_VOP1__V_CVT_F32_UBYTE1::~Inst_VOP1__V_CVT_F32_UBYTE1()
    {
    } // ~Inst_VOP1__V_CVT_F32_UBYTE1

    // --- description from .arch file ---
    // D.f = (float)(S0.u[15:8]).
    void
    Inst_VOP1__V_CVT_F32_UBYTE1::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)(bits(src[lane], 15, 8));
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_F32_UBYTE2 class methods ---

    Inst_VOP1__V_CVT_F32_UBYTE2::Inst_VOP1__V_CVT_F32_UBYTE2(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f32_ubyte2")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_F32_UBYTE2

    Inst_VOP1__V_CVT_F32_UBYTE2::~Inst_VOP1__V_CVT_F32_UBYTE2()
    {
    } // ~Inst_VOP1__V_CVT_F32_UBYTE2

    // --- description from .arch file ---
    // D.f = (float)(S0.u[23:16]).
    void
    Inst_VOP1__V_CVT_F32_UBYTE2::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)(bits(src[lane], 23, 16));
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_F32_UBYTE3 class methods ---

    Inst_VOP1__V_CVT_F32_UBYTE3::Inst_VOP1__V_CVT_F32_UBYTE3(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f32_ubyte3")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CVT_F32_UBYTE3

    Inst_VOP1__V_CVT_F32_UBYTE3::~Inst_VOP1__V_CVT_F32_UBYTE3()
    {
    } // ~Inst_VOP1__V_CVT_F32_UBYTE3

    // --- description from .arch file ---
    // D.f = (float)(S0.u[31:24]).
    void
    Inst_VOP1__V_CVT_F32_UBYTE3::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)(bits(src[lane], 31, 24));
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_U32_F64 class methods ---

    Inst_VOP1__V_CVT_U32_F64::Inst_VOP1__V_CVT_U32_F64(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_u32_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_CVT_U32_F64

    Inst_VOP1__V_CVT_U32_F64::~Inst_VOP1__V_CVT_U32_F64()
    {
    } // ~Inst_VOP1__V_CVT_U32_F64

    // --- description from .arch file ---
    // D.u = (unsigned)S0.d.
    // Out-of-range floating point values (including infinity) saturate. NaN is
    // ---  converted to 0.
    void
    Inst_VOP1__V_CVT_U32_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                int exp;
                std::frexp(src[lane],&exp);
                if (std::isnan(src[lane])) {
                    vdst[lane] = 0;
                } else if (std::isinf(src[lane])) {
                    if (std::signbit(src[lane])) {
                        vdst[lane] = 0;
                    } else {
                        vdst[lane] = UINT_MAX;
                    }
                } else if (exp > 31) {
                    vdst[lane] = UINT_MAX;
                } else {
                    vdst[lane] = (VecElemU32)src[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CVT_F64_U32 class methods ---

    Inst_VOP1__V_CVT_F64_U32::Inst_VOP1__V_CVT_F64_U32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f64_u32")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_CVT_F64_U32

    Inst_VOP1__V_CVT_F64_U32::~Inst_VOP1__V_CVT_F64_U32()
    {
    } // ~Inst_VOP1__V_CVT_F64_U32

    // --- description from .arch file ---
    // D.d = (double)S0.u.
    void
    Inst_VOP1__V_CVT_F64_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, instData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF64)src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_TRUNC_F64 class methods ---

    Inst_VOP1__V_TRUNC_F64::Inst_VOP1__V_TRUNC_F64(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_trunc_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_TRUNC_F64

    Inst_VOP1__V_TRUNC_F64::~Inst_VOP1__V_TRUNC_F64()
    {
    } // ~Inst_VOP1__V_TRUNC_F64

    // --- description from .arch file ---
    // D.d = trunc(S0.d), return integer part of S0.d.
    void
    Inst_VOP1__V_TRUNC_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::trunc(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CEIL_F64 class methods ---

    Inst_VOP1__V_CEIL_F64::Inst_VOP1__V_CEIL_F64(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_ceil_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_CEIL_F64

    Inst_VOP1__V_CEIL_F64::~Inst_VOP1__V_CEIL_F64()
    {
    } // ~Inst_VOP1__V_CEIL_F64

    // --- description from .arch file ---
    // D.d = trunc(S0.d);
    // if(S0.d > 0.0 && S0.d != D.d) then D.d += 1.0.
    void
    Inst_VOP1__V_CEIL_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::ceil(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_RNDNE_F64 class methods ---

    Inst_VOP1__V_RNDNE_F64::Inst_VOP1__V_RNDNE_F64(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_rndne_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_RNDNE_F64

    Inst_VOP1__V_RNDNE_F64::~Inst_VOP1__V_RNDNE_F64()
    {
    } // ~Inst_VOP1__V_RNDNE_F64

    // --- description from .arch file ---
    // D.d = round_nearest_even(S0.d).
    void
    Inst_VOP1__V_RNDNE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = roundNearestEven(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_FLOOR_F64 class methods ---

    Inst_VOP1__V_FLOOR_F64::Inst_VOP1__V_FLOOR_F64(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_floor_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_FLOOR_F64

    Inst_VOP1__V_FLOOR_F64::~Inst_VOP1__V_FLOOR_F64()
    {
    } // ~Inst_VOP1__V_FLOOR_F64

    // --- description from .arch file ---
    // D.d = trunc(S0.d);
    // if(S0.d < 0.0 && S0.d != D.d) then D.d += -1.0.
    void
    Inst_VOP1__V_FLOOR_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::floor(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_FRACT_F32 class methods ---

    Inst_VOP1__V_FRACT_F32::Inst_VOP1__V_FRACT_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_fract_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_FRACT_F32

    Inst_VOP1__V_FRACT_F32::~Inst_VOP1__V_FRACT_F32()
    {
    } // ~Inst_VOP1__V_FRACT_F32

    // --- description from .arch file ---
    // D.f = S0.f - floor(S0.f).
    void
    Inst_VOP1__V_FRACT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemF32 int_part(0.0);
                vdst[lane] = std::modf(src[lane], &int_part);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_TRUNC_F32 class methods ---

    Inst_VOP1__V_TRUNC_F32::Inst_VOP1__V_TRUNC_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_trunc_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_TRUNC_F32

    Inst_VOP1__V_TRUNC_F32::~Inst_VOP1__V_TRUNC_F32()
    {
    } // ~Inst_VOP1__V_TRUNC_F32

    // --- description from .arch file ---
    // D.f = trunc(S0.f), return integer part of S0.f.
    void
    Inst_VOP1__V_TRUNC_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst (gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::trunc(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CEIL_F32 class methods ---

    Inst_VOP1__V_CEIL_F32::Inst_VOP1__V_CEIL_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_ceil_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_CEIL_F32

    Inst_VOP1__V_CEIL_F32::~Inst_VOP1__V_CEIL_F32()
    {
    } // ~Inst_VOP1__V_CEIL_F32

    // --- description from .arch file ---
    // D.f = trunc(S0.f);
    // if(S0.f > 0.0 && S0.f != D.f) then D.f += 1.0.
    void
    Inst_VOP1__V_CEIL_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::ceil(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_RNDNE_F32 class methods ---

    Inst_VOP1__V_RNDNE_F32::Inst_VOP1__V_RNDNE_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_rndne_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_RNDNE_F32

    Inst_VOP1__V_RNDNE_F32::~Inst_VOP1__V_RNDNE_F32()
    {
    } // ~Inst_VOP1__V_RNDNE_F32

    // --- description from .arch file ---
    // D.f = round_nearest_even(S0.f).
    void
    Inst_VOP1__V_RNDNE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = roundNearestEven(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_FLOOR_F32 class methods ---

    Inst_VOP1__V_FLOOR_F32::Inst_VOP1__V_FLOOR_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_floor_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_FLOOR_F32

    Inst_VOP1__V_FLOOR_F32::~Inst_VOP1__V_FLOOR_F32()
    {
    } // ~Inst_VOP1__V_FLOOR_F32

    // --- description from .arch file ---
    // D.f = trunc(S0.f);
    // if(S0.f < 0.0 && S0.f != D.f) then D.f += -1.0.
    void
    Inst_VOP1__V_FLOOR_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::floor(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_EXP_F32 class methods ---

    Inst_VOP1__V_EXP_F32::Inst_VOP1__V_EXP_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_exp_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_EXP_F32

    Inst_VOP1__V_EXP_F32::~Inst_VOP1__V_EXP_F32()
    {
    } // ~Inst_VOP1__V_EXP_F32

    // --- description from .arch file ---
    // D.f = pow(2.0, S0.f).
    void
    Inst_VOP1__V_EXP_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::pow(2.0, src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_LOG_F32 class methods ---

    Inst_VOP1__V_LOG_F32::Inst_VOP1__V_LOG_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_log_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_LOG_F32

    Inst_VOP1__V_LOG_F32::~Inst_VOP1__V_LOG_F32()
    {
    } // ~Inst_VOP1__V_LOG_F32

    // --- description from .arch file ---
    // D.f = log2(S0.f). Base 2 logarithm.
    void
    Inst_VOP1__V_LOG_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::log2(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_RCP_F32 class methods ---

    Inst_VOP1__V_RCP_F32::Inst_VOP1__V_RCP_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_rcp_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_RCP_F32

    Inst_VOP1__V_RCP_F32::~Inst_VOP1__V_RCP_F32()
    {
    } // ~Inst_VOP1__V_RCP_F32

    // --- description from .arch file ---
    // D.f = 1.0 / S0.f. Reciprocal with IEEE rules and < 1ulp error.
    void
    Inst_VOP1__V_RCP_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = 1.0 / src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_RCP_IFLAG_F32 class methods ---

    Inst_VOP1__V_RCP_IFLAG_F32::Inst_VOP1__V_RCP_IFLAG_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_rcp_iflag_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_RCP_IFLAG_F32

    Inst_VOP1__V_RCP_IFLAG_F32::~Inst_VOP1__V_RCP_IFLAG_F32()
    {
    } // ~Inst_VOP1__V_RCP_IFLAG_F32

    // --- description from .arch file ---
    // D.f = 1.0 / S0.f. Reciprocal intended for integer division, can raise
    // ---  integer DIV_BY_ZERO exception but cannot raise floating-point
    // ---  exceptions.
    void
    Inst_VOP1__V_RCP_IFLAG_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = 1.0 / src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_RSQ_F32 class methods ---

    Inst_VOP1__V_RSQ_F32::Inst_VOP1__V_RSQ_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_rsq_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_RSQ_F32

    Inst_VOP1__V_RSQ_F32::~Inst_VOP1__V_RSQ_F32()
    {
    } // ~Inst_VOP1__V_RSQ_F32

    // --- description from .arch file ---
    // D.f = 1.0 / sqrt(S0.f). Reciprocal square root with IEEE rules.
    void
    Inst_VOP1__V_RSQ_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = 1.0 / std::sqrt(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_RCP_F64 class methods ---

    Inst_VOP1__V_RCP_F64::Inst_VOP1__V_RCP_F64(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_rcp_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_RCP_F64

    Inst_VOP1__V_RCP_F64::~Inst_VOP1__V_RCP_F64()
    {
    } // ~Inst_VOP1__V_RCP_F64

    // --- description from .arch file ---
    // D.d = 1.0 / S0.d.
    void
    Inst_VOP1__V_RCP_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::fpclassify(src[lane]) == FP_ZERO) {
                    vdst[lane] = +INFINITY;
                } else if (std::isnan(src[lane])) {
                    vdst[lane] = NAN;
                } else if (std::isinf(src[lane])) {
                    if (std::signbit(src[lane])) {
                        vdst[lane] = -0.0;
                    } else {
                        vdst[lane] = 0.0;
                    }
                } else {
                    vdst[lane] = 1.0 / src[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_RSQ_F64 class methods ---

    Inst_VOP1__V_RSQ_F64::Inst_VOP1__V_RSQ_F64(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_rsq_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_RSQ_F64

    Inst_VOP1__V_RSQ_F64::~Inst_VOP1__V_RSQ_F64()
    {
    } // ~Inst_VOP1__V_RSQ_F64

    // --- description from .arch file ---
    // D.d = 1.0 / sqrt(S0.d). See V_RSQ_F32.
    void
    Inst_VOP1__V_RSQ_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::fpclassify(src[lane]) == FP_ZERO) {
                    vdst[lane] = +INFINITY;
                } else if (std::isnan(src[lane])) {
                    vdst[lane] = NAN;
                } else if (std::isinf(src[lane])
                           && !std::signbit(src[lane])) {
                    vdst[lane] = 0.0;
                } else if (std::signbit(src[lane])) {
                    vdst[lane] = NAN;
                } else {
                    vdst[lane] = 1.0 / std::sqrt(src[lane]);
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_SQRT_F32 class methods ---

    Inst_VOP1__V_SQRT_F32::Inst_VOP1__V_SQRT_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_sqrt_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_SQRT_F32

    Inst_VOP1__V_SQRT_F32::~Inst_VOP1__V_SQRT_F32()
    {
    } // ~Inst_VOP1__V_SQRT_F32

    // --- description from .arch file ---
    // D.f = sqrt(S0.f).
    void
    Inst_VOP1__V_SQRT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::sqrt(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_SQRT_F64 class methods ---

    Inst_VOP1__V_SQRT_F64::Inst_VOP1__V_SQRT_F64(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_sqrt_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_SQRT_F64

    Inst_VOP1__V_SQRT_F64::~Inst_VOP1__V_SQRT_F64()
    {
    } // ~Inst_VOP1__V_SQRT_F64

    // --- description from .arch file ---
    // D.d = sqrt(S0.d).
    void
    Inst_VOP1__V_SQRT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::sqrt(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_SIN_F32 class methods ---

    Inst_VOP1__V_SIN_F32::Inst_VOP1__V_SIN_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_sin_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_SIN_F32

    Inst_VOP1__V_SIN_F32::~Inst_VOP1__V_SIN_F32()
    {
    } // ~Inst_VOP1__V_SIN_F32

    // --- description from .arch file ---
    // D.f = sin(S0.f * 2 * PI).
    // Valid range of S0.f is [-256.0, +256.0]. Out of range input results in
    // float 0.0.
    void
    Inst_VOP1__V_SIN_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        ConstScalarOperandF32 pi(gpuDynInst, REG_PI);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();
        pi.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (src[lane] < -256.0 || src[lane] > 256.0) {
                    vdst[lane] = 0.0;
                } else {
                    vdst[lane] = std::sin(src[lane] * 2.0 * pi.rawData());
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_COS_F32 class methods ---

    Inst_VOP1__V_COS_F32::Inst_VOP1__V_COS_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cos_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_COS_F32

    Inst_VOP1__V_COS_F32::~Inst_VOP1__V_COS_F32()
    {
    } // ~Inst_VOP1__V_COS_F32

    // --- description from .arch file ---
    // D.f = cos(S0.f * 2 * PI).
    // Valid range of S0.f is [-256.0, +256.0]. Out of range input results in
    // float 1.0.
    void
    Inst_VOP1__V_COS_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        ConstScalarOperandF32 pi(gpuDynInst, REG_PI);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();
        pi.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (src[lane] < -256.0 || src[lane] > 256.0) {
                    vdst[lane] = 0.0;
                } else {
                    vdst[lane] = std::cos(src[lane] * 2.0 * pi.rawData());
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_NOT_B32 class methods ---

    Inst_VOP1__V_NOT_B32::Inst_VOP1__V_NOT_B32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_not_b32")
    {
        setFlag(ALU);
    } // Inst_VOP1__V_NOT_B32

    Inst_VOP1__V_NOT_B32::~Inst_VOP1__V_NOT_B32()
    {
    } // ~Inst_VOP1__V_NOT_B32

    // --- description from .arch file ---
    // D.u = ~S0.u.
    // Input and output modifiers not supported.
    void
    Inst_VOP1__V_NOT_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, instData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = ~src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_BFREV_B32 class methods ---

    Inst_VOP1__V_BFREV_B32::Inst_VOP1__V_BFREV_B32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_bfrev_b32")
    {
        setFlag(ALU);
    } // Inst_VOP1__V_BFREV_B32

    Inst_VOP1__V_BFREV_B32::~Inst_VOP1__V_BFREV_B32()
    {
    } // ~Inst_VOP1__V_BFREV_B32

    // --- description from .arch file ---
    // D.u[31:0] = S0.u[0:31], bitfield reverse.
    // Input and output modifiers not supported.
    void
    Inst_VOP1__V_BFREV_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, instData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = reverseBits(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_FFBH_U32 class methods ---

    Inst_VOP1__V_FFBH_U32::Inst_VOP1__V_FFBH_U32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_ffbh_u32")
    {
        setFlag(ALU);
    } // Inst_VOP1__V_FFBH_U32

    Inst_VOP1__V_FFBH_U32::~Inst_VOP1__V_FFBH_U32()
    {
    } // ~Inst_VOP1__V_FFBH_U32

    // --- description from .arch file ---
    // D.u = position of first 1 in S0.u from MSB;
    // D.u = 0xffffffff if S0.u == 0.
    void
    Inst_VOP1__V_FFBH_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, instData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = findFirstOneMsb(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_FFBL_B32 class methods ---

    Inst_VOP1__V_FFBL_B32::Inst_VOP1__V_FFBL_B32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_ffbl_b32")
    {
        setFlag(ALU);
    } // Inst_VOP1__V_FFBL_B32

    Inst_VOP1__V_FFBL_B32::~Inst_VOP1__V_FFBL_B32()
    {
    } // ~Inst_VOP1__V_FFBL_B32

    // --- description from .arch file ---
    // D.u = position of first 1 in S0.u from LSB;
    // D.u = 0xffffffff if S0.u == 0.
    void
    Inst_VOP1__V_FFBL_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, instData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = findFirstOne(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_FFBH_I32 class methods ---

    Inst_VOP1__V_FFBH_I32::Inst_VOP1__V_FFBH_I32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_ffbh_i32")
    {
        setFlag(ALU);
    } // Inst_VOP1__V_FFBH_I32

    Inst_VOP1__V_FFBH_I32::~Inst_VOP1__V_FFBH_I32()
    {
    } // ~Inst_VOP1__V_FFBH_I32

    // --- description from .arch file ---
    // D.u = position of first bit different from sign bit in S0.i from MSB;
    // D.u = 0xffffffff if S0.i == 0 or S0.i == 0xffffffff.
    void
    Inst_VOP1__V_FFBH_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src(gpuDynInst, instData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = firstOppositeSignBit(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_FREXP_EXP_I32_F64 class methods ---

    Inst_VOP1__V_FREXP_EXP_I32_F64::Inst_VOP1__V_FREXP_EXP_I32_F64(
          InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_frexp_exp_i32_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_FREXP_EXP_I32_F64

    Inst_VOP1__V_FREXP_EXP_I32_F64::~Inst_VOP1__V_FREXP_EXP_I32_F64()
    {
    } // ~Inst_VOP1__V_FREXP_EXP_I32_F64

    // --- description from .arch file ---
    // See V_FREXP_EXP_I32_F32.
    void
    Inst_VOP1__V_FREXP_EXP_I32_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isinf(src[lane]) || std::isnan(src[lane])) {
                    vdst[lane] = 0;
                } else {
                    VecElemI32 exp = 0;
                    std::frexp(src[lane], &exp);
                    vdst[lane] = exp;
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_FREXP_MANT_F64 class methods ---

    Inst_VOP1__V_FREXP_MANT_F64::Inst_VOP1__V_FREXP_MANT_F64(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_frexp_mant_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_FREXP_MANT_F64

    Inst_VOP1__V_FREXP_MANT_F64::~Inst_VOP1__V_FREXP_MANT_F64()
    {
    } // ~Inst_VOP1__V_FREXP_MANT_F64

    // --- description from .arch file ---
    // See V_FREXP_MANT_F32.
    void
    Inst_VOP1__V_FREXP_MANT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isinf(src[lane]) || std::isnan(src[lane])) {
                    vdst[lane] = src[lane];
                } else {
                    VecElemI32 exp(0);
                    vdst[lane] = std::frexp(src[lane], &exp);
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_FRACT_F64 class methods ---

    Inst_VOP1__V_FRACT_F64::Inst_VOP1__V_FRACT_F64(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_fract_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP1__V_FRACT_F64

    Inst_VOP1__V_FRACT_F64::~Inst_VOP1__V_FRACT_F64()
    {
    } // ~Inst_VOP1__V_FRACT_F64

    // --- description from .arch file ---
    // See V_FRACT_F32.
    void
    Inst_VOP1__V_FRACT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, instData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemF64 int_part(0.0);
                vdst[lane] = std::modf(src[lane], &int_part);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_FREXP_EXP_I32_F32 class methods ---

    Inst_VOP1__V_FREXP_EXP_I32_F32::Inst_VOP1__V_FREXP_EXP_I32_F32(
          InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_frexp_exp_i32_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_FREXP_EXP_I32_F32

    Inst_VOP1__V_FREXP_EXP_I32_F32::~Inst_VOP1__V_FREXP_EXP_I32_F32()
    {
    } // ~Inst_VOP1__V_FREXP_EXP_I32_F32

    // --- description from .arch file ---
    // if(S0.f == INF || S0.f == NAN) then D.i = 0;
    // else D.i = TwosComplement(Exponent(S0.f) - 127 + 1).
    // Returns exponent of single precision float input, such that S0.f =
    // significand * (2 ** exponent). See also FREXP_MANT_F32, which returns
    // the significand.
    void
    Inst_VOP1__V_FREXP_EXP_I32_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isinf(src[lane]) || std::isnan(src[lane])) {
                    vdst[lane] = 0;
                } else {
                    VecElemI32 exp(0);
                    std::frexp(src[lane], &exp);
                    vdst[lane] = exp;
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_FREXP_MANT_F32 class methods ---

    Inst_VOP1__V_FREXP_MANT_F32::Inst_VOP1__V_FREXP_MANT_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_frexp_mant_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_FREXP_MANT_F32

    Inst_VOP1__V_FREXP_MANT_F32::~Inst_VOP1__V_FREXP_MANT_F32()
    {
    } // ~Inst_VOP1__V_FREXP_MANT_F32

    // --- description from .arch file ---
    // if(S0.f == INF || S0.f == NAN) then D.f = S0.f;
    // else D.f = Mantissa(S0.f).
    // Result range is in (-1.0,-0.5][0.5,1.0) in normal cases. Returns binary
    // ---  significand of single precision float input, such that S0.f =
    // ---  significand * (2 ** exponent). See also FREXP_EXP_I32_F32, which
    // ---  returns integer exponent.
    void
    Inst_VOP1__V_FREXP_MANT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isinf(src[lane]) || std::isnan(src[lane])) {
                    vdst[lane] = src[lane];
                } else {
                    VecElemI32 exp(0);
                    vdst[lane] = std::frexp(src[lane], &exp);
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_CLREXCP class methods ---

    Inst_VOP1__V_CLREXCP::Inst_VOP1__V_CLREXCP(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_clrexcp")
    {
        setFlag(ALU);
    } // Inst_VOP1__V_CLREXCP

    Inst_VOP1__V_CLREXCP::~Inst_VOP1__V_CLREXCP()
    {
    } // ~Inst_VOP1__V_CLREXCP

    // --- description from .arch file ---
    // Clear wave's exception state in SIMD (SP).
    void
    Inst_VOP1__V_CLREXCP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_CVT_F16_U16 class methods ---

    Inst_VOP1__V_CVT_F16_U16::Inst_VOP1__V_CVT_F16_U16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f16_u16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_CVT_F16_U16

    Inst_VOP1__V_CVT_F16_U16::~Inst_VOP1__V_CVT_F16_U16()
    {
    } // ~Inst_VOP1__V_CVT_F16_U16

    // --- description from .arch file ---
    // D.f16 = uint16_to_flt16(S.u16).
    // Supports denormals, rounding, exception flags and saturation.
    void
    Inst_VOP1__V_CVT_F16_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_CVT_F16_I16 class methods ---

    Inst_VOP1__V_CVT_F16_I16::Inst_VOP1__V_CVT_F16_I16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_f16_i16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_CVT_F16_I16

    Inst_VOP1__V_CVT_F16_I16::~Inst_VOP1__V_CVT_F16_I16()
    {
    } // ~Inst_VOP1__V_CVT_F16_I16

    // --- description from .arch file ---
    // D.f16 = int16_to_flt16(S.i16).
    // Supports denormals, rounding, exception flags and saturation.
    void
    Inst_VOP1__V_CVT_F16_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_CVT_U16_F16 class methods ---

    Inst_VOP1__V_CVT_U16_F16::Inst_VOP1__V_CVT_U16_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_u16_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_CVT_U16_F16

    Inst_VOP1__V_CVT_U16_F16::~Inst_VOP1__V_CVT_U16_F16()
    {
    } // ~Inst_VOP1__V_CVT_U16_F16

    // --- description from .arch file ---
    // D.u16 = flt16_to_uint16(S.f16).
    // Supports rounding, exception flags and saturation.
    void
    Inst_VOP1__V_CVT_U16_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_CVT_I16_F16 class methods ---

    Inst_VOP1__V_CVT_I16_F16::Inst_VOP1__V_CVT_I16_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cvt_i16_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_CVT_I16_F16

    Inst_VOP1__V_CVT_I16_F16::~Inst_VOP1__V_CVT_I16_F16()
    {
    } // ~Inst_VOP1__V_CVT_I16_F16

    // --- description from .arch file ---
    // D.i16 = flt16_to_int16(S.f16).
    // Supports rounding, exception flags and saturation.
    void
    Inst_VOP1__V_CVT_I16_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_RCP_F16 class methods ---

    Inst_VOP1__V_RCP_F16::Inst_VOP1__V_RCP_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_rcp_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_RCP_F16

    Inst_VOP1__V_RCP_F16::~Inst_VOP1__V_RCP_F16()
    {
    } // ~Inst_VOP1__V_RCP_F16

    // --- description from .arch file ---
    // if(S0.f16 == 1.0f)
    //     D.f16 = 1.0f;
    // else
    //     D.f16 = ApproximateRecip(S0.f16).
    void
    Inst_VOP1__V_RCP_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_SQRT_F16 class methods ---

    Inst_VOP1__V_SQRT_F16::Inst_VOP1__V_SQRT_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_sqrt_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_SQRT_F16

    Inst_VOP1__V_SQRT_F16::~Inst_VOP1__V_SQRT_F16()
    {
    } // ~Inst_VOP1__V_SQRT_F16

    // --- description from .arch file ---
    // if(S0.f16 == 1.0f)
    //     D.f16 = 1.0f;
    // else
    //     D.f16 = ApproximateSqrt(S0.f16).
    void
    Inst_VOP1__V_SQRT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_RSQ_F16 class methods ---

    Inst_VOP1__V_RSQ_F16::Inst_VOP1__V_RSQ_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_rsq_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_RSQ_F16

    Inst_VOP1__V_RSQ_F16::~Inst_VOP1__V_RSQ_F16()
    {
    } // ~Inst_VOP1__V_RSQ_F16

    // --- description from .arch file ---
    // if(S0.f16 == 1.0f)
    //     D.f16 = 1.0f;
    // else
    //     D.f16 = ApproximateRecipSqrt(S0.f16).
    void
    Inst_VOP1__V_RSQ_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_LOG_F16 class methods ---

    Inst_VOP1__V_LOG_F16::Inst_VOP1__V_LOG_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_log_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_LOG_F16

    Inst_VOP1__V_LOG_F16::~Inst_VOP1__V_LOG_F16()
    {
    } // ~Inst_VOP1__V_LOG_F16

    // --- description from .arch file ---
    // if(S0.f16 == 1.0f)
    //     D.f16 = 0.0f;
    // else
    //     D.f16 = ApproximateLog2(S0.f16).
    void
    Inst_VOP1__V_LOG_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_EXP_F16 class methods ---

    Inst_VOP1__V_EXP_F16::Inst_VOP1__V_EXP_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_exp_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_EXP_F16

    Inst_VOP1__V_EXP_F16::~Inst_VOP1__V_EXP_F16()
    {
    } // ~Inst_VOP1__V_EXP_F16

    // --- description from .arch file ---
    // if(S0.f16 == 0.0f)
    //     D.f16 = 1.0f;
    // else
    //     D.f16 = Approximate2ToX(S0.f16).
    void
    Inst_VOP1__V_EXP_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_FREXP_MANT_F16 class methods ---

    Inst_VOP1__V_FREXP_MANT_F16::Inst_VOP1__V_FREXP_MANT_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_frexp_mant_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_FREXP_MANT_F16

    Inst_VOP1__V_FREXP_MANT_F16::~Inst_VOP1__V_FREXP_MANT_F16()
    {
    } // ~Inst_VOP1__V_FREXP_MANT_F16

    // --- description from .arch file ---
    // if(S0.f16 == +-INF || S0.f16 == NAN)
    //     D.f16 = S0.f16;
    // else
    //     D.f16 = mantissa(S0.f16).
    // Result range is (-1.0,-0.5][0.5,1.0).
    // C math library frexp function.
    // Returns binary significand of half precision float input, such that the
    // original single float = significand * (2 ** exponent).
    void
    Inst_VOP1__V_FREXP_MANT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_FREXP_EXP_I16_F16 class methods ---

    Inst_VOP1__V_FREXP_EXP_I16_F16::Inst_VOP1__V_FREXP_EXP_I16_F16(
          InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_frexp_exp_i16_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_FREXP_EXP_I16_F16

    Inst_VOP1__V_FREXP_EXP_I16_F16::~Inst_VOP1__V_FREXP_EXP_I16_F16()
    {
    } // ~Inst_VOP1__V_FREXP_EXP_I16_F16

    // --- description from .arch file ---
    // if(S0.f16 == +-INF || S0.f16 == NAN)
    //     D.i16 = 0;
    // else
    //     D.i16 = 2s_complement(exponent(S0.f16) - 15 + 1).
    // C math library frexp function.
    // Returns exponent of half precision float input, such that the
    // original single float = significand * (2 ** exponent).
    void
    Inst_VOP1__V_FREXP_EXP_I16_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_FLOOR_F16 class methods ---

    Inst_VOP1__V_FLOOR_F16::Inst_VOP1__V_FLOOR_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_floor_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_FLOOR_F16

    Inst_VOP1__V_FLOOR_F16::~Inst_VOP1__V_FLOOR_F16()
    {
    } // ~Inst_VOP1__V_FLOOR_F16

    // --- description from .arch file ---
    // D.f16 = trunc(S0.f16);
    // if(S0.f16 < 0.0f && S0.f16 != D.f16) then D.f16 -= 1.0f.
    void
    Inst_VOP1__V_FLOOR_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_CEIL_F16 class methods ---

    Inst_VOP1__V_CEIL_F16::Inst_VOP1__V_CEIL_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_ceil_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_CEIL_F16

    Inst_VOP1__V_CEIL_F16::~Inst_VOP1__V_CEIL_F16()
    {
    } // ~Inst_VOP1__V_CEIL_F16

    // --- description from .arch file ---
    // D.f16 = trunc(S0.f16);
    // if(S0.f16 > 0.0f && S0.f16 != D.f16) then D.f16 += 1.0f.
    void
    Inst_VOP1__V_CEIL_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_TRUNC_F16 class methods ---

    Inst_VOP1__V_TRUNC_F16::Inst_VOP1__V_TRUNC_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_trunc_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_TRUNC_F16

    Inst_VOP1__V_TRUNC_F16::~Inst_VOP1__V_TRUNC_F16()
    {
    } // ~Inst_VOP1__V_TRUNC_F16

    // --- description from .arch file ---
    // D.f16 = trunc(S0.f16).
    // Round-to-zero semantics.
    void
    Inst_VOP1__V_TRUNC_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_RNDNE_F16 class methods ---

    Inst_VOP1__V_RNDNE_F16::Inst_VOP1__V_RNDNE_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_rndne_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_RNDNE_F16

    Inst_VOP1__V_RNDNE_F16::~Inst_VOP1__V_RNDNE_F16()
    {
    } // ~Inst_VOP1__V_RNDNE_F16

    // --- description from .arch file ---
    // D.f16 = FLOOR(S0.f16 + 0.5f);
    // if(floor(S0.f16) is even && fract(S0.f16) == 0.5f) then D.f16 -= 1.0f.
    // Round-to-nearest-even semantics.
    void
    Inst_VOP1__V_RNDNE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_FRACT_F16 class methods ---

    Inst_VOP1__V_FRACT_F16::Inst_VOP1__V_FRACT_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_fract_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_FRACT_F16

    Inst_VOP1__V_FRACT_F16::~Inst_VOP1__V_FRACT_F16()
    {
    } // ~Inst_VOP1__V_FRACT_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 + -floor(S0.f16).
    void
    Inst_VOP1__V_FRACT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_SIN_F16 class methods ---

    Inst_VOP1__V_SIN_F16::Inst_VOP1__V_SIN_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_sin_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_SIN_F16

    Inst_VOP1__V_SIN_F16::~Inst_VOP1__V_SIN_F16()
    {
    } // ~Inst_VOP1__V_SIN_F16

    // --- description from .arch file ---
    // D.f16 = sin(S0.f16 * 2 * PI).
    void
    Inst_VOP1__V_SIN_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_COS_F16 class methods ---

    Inst_VOP1__V_COS_F16::Inst_VOP1__V_COS_F16(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_cos_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP1__V_COS_F16

    Inst_VOP1__V_COS_F16::~Inst_VOP1__V_COS_F16()
    {
    } // ~Inst_VOP1__V_COS_F16

    // --- description from .arch file ---
    // D.f16 = cos(S0.f16 * 2 * PI).
    void
    Inst_VOP1__V_COS_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP1__V_EXP_LEGACY_F32 class methods ---

    Inst_VOP1__V_EXP_LEGACY_F32::Inst_VOP1__V_EXP_LEGACY_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_exp_legacy_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_EXP_LEGACY_F32

    Inst_VOP1__V_EXP_LEGACY_F32::~Inst_VOP1__V_EXP_LEGACY_F32()
    {
    } // ~Inst_VOP1__V_EXP_LEGACY_F32

    // --- description from .arch file ---
    // D.f = pow(2.0, S0.f) with legacy semantics.
    void
    Inst_VOP1__V_EXP_LEGACY_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::pow(2.0, src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP1__V_LOG_LEGACY_F32 class methods ---

    Inst_VOP1__V_LOG_LEGACY_F32::Inst_VOP1__V_LOG_LEGACY_F32(InFmt_VOP1 *iFmt)
        : Inst_VOP1(iFmt, "v_log_legacy_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP1__V_LOG_LEGACY_F32

    Inst_VOP1__V_LOG_LEGACY_F32::~Inst_VOP1__V_LOG_LEGACY_F32()
    {
    } // ~Inst_VOP1__V_LOG_LEGACY_F32

    // --- description from .arch file ---
    // D.f = log2(S0.f). Base 2 logarithm with legacy semantics.
    void
    Inst_VOP1__V_LOG_LEGACY_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, instData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::log2(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOPC__V_CMP_CLASS_F32 class methods ---

    Inst_VOPC__V_CMP_CLASS_F32::Inst_VOPC__V_CMP_CLASS_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_class_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_CLASS_F32

    Inst_VOPC__V_CMP_CLASS_F32::~Inst_VOPC__V_CMP_CLASS_F32()
    {
    } // ~Inst_VOPC__V_CMP_CLASS_F32

    // --- description from .arch file ---
    // VCC = IEEE numeric class function specified in S1.u, performed on S0.f
    // The function reports true if the floating point value is *any* of the
    // ---  numeric types selected in S1.u according to the following list:
    // S1.u[0] -- value is a signaling NaN.
    // S1.u[1] -- value is a quiet NaN.
    // S1.u[2] -- value is negative infinity.
    // S1.u[3] -- value is a negative normal value.
    // S1.u[4] -- value is a negative denormal value.
    // S1.u[5] -- value is negative zero.
    // S1.u[6] -- value is positive zero.
    // S1.u[7] -- value is a positive denormal value.
    // S1.u[8] -- value is a positive normal value.
    // S1.u[9] -- value is positive infinity.
    void
    Inst_VOPC__V_CMP_CLASS_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ConstScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (bits(src1[lane], 0) || bits(src1[lane], 1)) {
                    // is NaN
                    if (std::isnan(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 2)) {
                    // is -infinity
                    if (std::isinf(src0[lane]) && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 3)) {
                    // is -normal
                    if (std::isnormal(src0[lane])
                        && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 4)) {
                    // is -denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 5)) {
                    // is -zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 6)) {
                    // is +zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 7)) {
                    // is +denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 8)) {
                    // is +normal
                    if (std::isnormal(src0[lane])
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 9)) {
                    // is +infinity
                    if (std::isinf(src0[lane]) && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_CLASS_F32 class methods ---

    Inst_VOPC__V_CMPX_CLASS_F32::Inst_VOPC__V_CMPX_CLASS_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_class_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_CLASS_F32

    Inst_VOPC__V_CMPX_CLASS_F32::~Inst_VOPC__V_CMPX_CLASS_F32()
    {
    } // ~Inst_VOPC__V_CMPX_CLASS_F32

    // --- description from .arch file ---
    // EXEC, VCC = IEEE numeric class function specified in S1.u, performed on
    // S0.f The function reports true if the floating point value is *any* of
    // the numeric types selected in S1.u according to the following list:
    // S1.u[0] -- value is a signaling NaN.
    // S1.u[1] -- value is a quiet NaN.
    // S1.u[2] -- value is negative infinity.
    // S1.u[3] -- value is a negative normal value.
    // S1.u[4] -- value is a negative denormal value.
    // S1.u[5] -- value is negative zero.
    // S1.u[6] -- value is positive zero.
    // S1.u[7] -- value is a positive denormal value.
    // S1.u[8] -- value is a positive normal value.
    // S1.u[9] -- value is positive infinity.
    void
    Inst_VOPC__V_CMPX_CLASS_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ConstScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (bits(src1[lane], 0) || bits(src1[lane], 1)) {
                    // is NaN
                    if (std::isnan(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 2)) {
                    // is -infinity
                    if (std::isinf(src0[lane]) && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 3)) {
                    // is -normal
                    if (std::isnormal(src0[lane])
                        && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 4)) {
                    // is -denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 5)) {
                    // is -zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 6)) {
                    // is +zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 7)) {
                    // is +denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 8)) {
                    // is +normal
                    if (std::isnormal(src0[lane])
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 9)) {
                    // is +infinity
                    if (std::isinf(src0[lane]) && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMP_CLASS_F64 class methods ---

    Inst_VOPC__V_CMP_CLASS_F64::Inst_VOPC__V_CMP_CLASS_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_class_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_CLASS_F64

    Inst_VOPC__V_CMP_CLASS_F64::~Inst_VOPC__V_CMP_CLASS_F64()
    {
    } // ~Inst_VOPC__V_CMP_CLASS_F64

    // --- description from .arch file ---
    // VCC = IEEE numeric class function specified in S1.u, performed on S0.d
    // The function reports true if the floating point value is *any* of the
    // ---  numeric types selected in S1.u according to the following list:
    // S1.u[0] -- value is a signaling NaN.
    // S1.u[1] -- value is a quiet NaN.
    // S1.u[2] -- value is negative infinity.
    // S1.u[3] -- value is a negative normal value.
    // S1.u[4] -- value is a negative denormal value.
    // S1.u[5] -- value is negative zero.
    // S1.u[6] -- value is positive zero.
    // S1.u[7] -- value is a positive denormal value.
    // S1.u[8] -- value is a positive normal value.
    // S1.u[9] -- value is positive infinity.
    void
    Inst_VOPC__V_CMP_CLASS_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ConstScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (bits(src1[lane], 0) || bits(src1[lane], 1)) {
                    // is NaN
                    if (std::isnan(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 2)) {
                    // is -infinity
                    if (std::isinf(src0[lane]) && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 3)) {
                    // is -normal
                    if (std::isnormal(src0[lane])
                        && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 4)) {
                    // is -denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 5)) {
                    // is -zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 6)) {
                    // is +zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 7)) {
                    // is +denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 8)) {
                    // is +normal
                    if (std::isnormal(src0[lane])
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 9)) {
                    // is +infinity
                    if (std::isinf(src0[lane])
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_CLASS_F64 class methods ---

    Inst_VOPC__V_CMPX_CLASS_F64::Inst_VOPC__V_CMPX_CLASS_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_class_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_CLASS_F64

    Inst_VOPC__V_CMPX_CLASS_F64::~Inst_VOPC__V_CMPX_CLASS_F64()
    {
    } // ~Inst_VOPC__V_CMPX_CLASS_F64

    // --- description from .arch file ---
    // EXEC, VCC = IEEE numeric class function specified in S1.u, performed on
    // S0.d The function reports true if the floating point value is *any* of
    // the numeric types selected in S1.u according to the following list:
    // S1.u[0] -- value is a signaling NaN.
    // S1.u[1] -- value is a quiet NaN.
    // S1.u[2] -- value is negative infinity.
    // S1.u[3] -- value is a negative normal value.
    // S1.u[4] -- value is a negative denormal value.
    // S1.u[5] -- value is negative zero.
    // S1.u[6] -- value is positive zero.
    // S1.u[7] -- value is a positive denormal value.
    // S1.u[8] -- value is a positive normal value.
    // S1.u[9] -- value is positive infinity.
    void
    Inst_VOPC__V_CMPX_CLASS_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ConstScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (bits(src1[lane], 0) || bits(src1[lane], 1)) {
                    // is NaN
                    if (std::isnan(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 2)) {
                    // is -infinity
                    if (std::isinf(src0[lane]) && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 3)) {
                    // is -normal
                    if (std::isnormal(src0[lane])
                        && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 4)) {
                    // is -denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 5)) {
                    // is -zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 6)) {
                    // is +zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 7)) {
                    // is +denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 8)) {
                    // is +normal
                    if (std::isnormal(src0[lane])
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 9)) {
                    // is +infinity
                    if (std::isinf(src0[lane])
                        && !std::signbit(src0[lane])) {
                        vcc.setBit(lane, 1);
                        continue;
                    }
                }
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMP_CLASS_F16 class methods ---

    Inst_VOPC__V_CMP_CLASS_F16::Inst_VOPC__V_CMP_CLASS_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_class_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_CLASS_F16

    Inst_VOPC__V_CMP_CLASS_F16::~Inst_VOPC__V_CMP_CLASS_F16()
    {
    } // ~Inst_VOPC__V_CMP_CLASS_F16

    // --- description from .arch file ---
    // VCC = IEEE numeric class function specified in S1.u, performed on S0.f16
    // The function reports true if the floating point value is *any* of the
    // ---  numeric types selected in S1.u according to the following list:
    // S1.u[0] -- value is a signaling NaN.
    // S1.u[1] -- value is a quiet NaN.
    // S1.u[2] -- value is negative infinity.
    // S1.u[3] -- value is a negative normal value.
    // S1.u[4] -- value is a negative denormal value.
    // S1.u[5] -- value is negative zero.
    // S1.u[6] -- value is positive zero.
    // S1.u[7] -- value is a positive denormal value.
    // S1.u[8] -- value is a positive normal value.
    // S1.u[9] -- value is positive infinity.
    void
    Inst_VOPC__V_CMP_CLASS_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_CLASS_F16 class methods ---

    Inst_VOPC__V_CMPX_CLASS_F16::Inst_VOPC__V_CMPX_CLASS_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_class_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_CLASS_F16

    Inst_VOPC__V_CMPX_CLASS_F16::~Inst_VOPC__V_CMPX_CLASS_F16()
    {
    } // ~Inst_VOPC__V_CMPX_CLASS_F16

    // --- description from .arch file ---
    // EXEC, VCC = IEEE numeric class function specified in S1.u, performed on
    // ---  S0.f16
    // The function reports true if the floating point value is *any* of the
    // ---  numeric types selected in S1.u according to the following list:
    // S1.u[0] -- value is a signaling NaN.
    // S1.u[1] -- value is a quiet NaN.
    // S1.u[2] -- value is negative infinity.
    // S1.u[3] -- value is a negative normal value.
    // S1.u[4] -- value is a negative denormal value.
    // S1.u[5] -- value is negative zero.
    // S1.u[6] -- value is positive zero.
    // S1.u[7] -- value is a positive denormal value.
    // S1.u[8] -- value is a positive normal value.
    // S1.u[9] -- value is positive infinity.
    void
    Inst_VOPC__V_CMPX_CLASS_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_F_F16 class methods ---

    Inst_VOPC__V_CMP_F_F16::Inst_VOPC__V_CMP_F_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_f_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_F_F16

    Inst_VOPC__V_CMP_F_F16::~Inst_VOPC__V_CMP_F_F16()
    {
    } // ~Inst_VOPC__V_CMP_F_F16

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_F_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_LT_F16 class methods ---

    Inst_VOPC__V_CMP_LT_F16::Inst_VOPC__V_CMP_LT_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_lt_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_LT_F16

    Inst_VOPC__V_CMP_LT_F16::~Inst_VOPC__V_CMP_LT_F16()
    {
    } // ~Inst_VOPC__V_CMP_LT_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_EQ_F16 class methods ---

    Inst_VOPC__V_CMP_EQ_F16::Inst_VOPC__V_CMP_EQ_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_eq_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_EQ_F16

    Inst_VOPC__V_CMP_EQ_F16::~Inst_VOPC__V_CMP_EQ_F16()
    {
    } // ~Inst_VOPC__V_CMP_EQ_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_EQ_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_LE_F16 class methods ---

    Inst_VOPC__V_CMP_LE_F16::Inst_VOPC__V_CMP_LE_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_le_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_LE_F16

    Inst_VOPC__V_CMP_LE_F16::~Inst_VOPC__V_CMP_LE_F16()
    {
    } // ~Inst_VOPC__V_CMP_LE_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_GT_F16 class methods ---

    Inst_VOPC__V_CMP_GT_F16::Inst_VOPC__V_CMP_GT_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_gt_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_GT_F16

    Inst_VOPC__V_CMP_GT_F16::~Inst_VOPC__V_CMP_GT_F16()
    {
    } // ~Inst_VOPC__V_CMP_GT_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_LG_F16 class methods ---

    Inst_VOPC__V_CMP_LG_F16::Inst_VOPC__V_CMP_LG_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_lg_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_LG_F16

    Inst_VOPC__V_CMP_LG_F16::~Inst_VOPC__V_CMP_LG_F16()
    {
    } // ~Inst_VOPC__V_CMP_LG_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LG_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_GE_F16 class methods ---

    Inst_VOPC__V_CMP_GE_F16::Inst_VOPC__V_CMP_GE_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ge_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_GE_F16

    Inst_VOPC__V_CMP_GE_F16::~Inst_VOPC__V_CMP_GE_F16()
    {
    } // ~Inst_VOPC__V_CMP_GE_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_O_F16 class methods ---

    Inst_VOPC__V_CMP_O_F16::Inst_VOPC__V_CMP_O_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_o_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_O_F16

    Inst_VOPC__V_CMP_O_F16::~Inst_VOPC__V_CMP_O_F16()
    {
    } // ~Inst_VOPC__V_CMP_O_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (!isNan(S0) && !isNan(S1)); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_O_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_U_F16 class methods ---

    Inst_VOPC__V_CMP_U_F16::Inst_VOPC__V_CMP_U_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_u_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_U_F16

    Inst_VOPC__V_CMP_U_F16::~Inst_VOPC__V_CMP_U_F16()
    {
    } // ~Inst_VOPC__V_CMP_U_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (isNan(S0)  ||  isNan(S1)); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_U_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_NGE_F16 class methods ---

    Inst_VOPC__V_CMP_NGE_F16::Inst_VOPC__V_CMP_NGE_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_nge_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_NGE_F16

    Inst_VOPC__V_CMP_NGE_F16::~Inst_VOPC__V_CMP_NGE_F16()
    {
    } // ~Inst_VOPC__V_CMP_NGE_F16

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NGE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_NLG_F16 class methods ---

    Inst_VOPC__V_CMP_NLG_F16::Inst_VOPC__V_CMP_NLG_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_nlg_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_NLG_F16

    Inst_VOPC__V_CMP_NLG_F16::~Inst_VOPC__V_CMP_NLG_F16()
    {
    } // ~Inst_VOPC__V_CMP_NLG_F16

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NLG_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_NGT_F16 class methods ---

    Inst_VOPC__V_CMP_NGT_F16::Inst_VOPC__V_CMP_NGT_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ngt_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_NGT_F16

    Inst_VOPC__V_CMP_NGT_F16::~Inst_VOPC__V_CMP_NGT_F16()
    {
    } // ~Inst_VOPC__V_CMP_NGT_F16

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NGT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_NLE_F16 class methods ---

    Inst_VOPC__V_CMP_NLE_F16::Inst_VOPC__V_CMP_NLE_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_nle_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_NLE_F16

    Inst_VOPC__V_CMP_NLE_F16::~Inst_VOPC__V_CMP_NLE_F16()
    {
    } // ~Inst_VOPC__V_CMP_NLE_F16

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NLE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_NEQ_F16 class methods ---

    Inst_VOPC__V_CMP_NEQ_F16::Inst_VOPC__V_CMP_NEQ_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_neq_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_NEQ_F16

    Inst_VOPC__V_CMP_NEQ_F16::~Inst_VOPC__V_CMP_NEQ_F16()
    {
    } // ~Inst_VOPC__V_CMP_NEQ_F16

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NEQ_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_NLT_F16 class methods ---

    Inst_VOPC__V_CMP_NLT_F16::Inst_VOPC__V_CMP_NLT_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_nlt_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_NLT_F16

    Inst_VOPC__V_CMP_NLT_F16::~Inst_VOPC__V_CMP_NLT_F16()
    {
    } // ~Inst_VOPC__V_CMP_NLT_F16

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NLT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_TRU_F16 class methods ---

    Inst_VOPC__V_CMP_TRU_F16::Inst_VOPC__V_CMP_TRU_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_tru_f16")
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOPC__V_CMP_TRU_F16

    Inst_VOPC__V_CMP_TRU_F16::~Inst_VOPC__V_CMP_TRU_F16()
    {
    } // ~Inst_VOPC__V_CMP_TRU_F16

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_TRU_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_F_F16 class methods ---

    Inst_VOPC__V_CMPX_F_F16::Inst_VOPC__V_CMPX_F_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_f_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_F_F16

    Inst_VOPC__V_CMPX_F_F16::~Inst_VOPC__V_CMPX_F_F16()
    {
    } // ~Inst_VOPC__V_CMPX_F_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_F_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_LT_F16 class methods ---

    Inst_VOPC__V_CMPX_LT_F16::Inst_VOPC__V_CMPX_LT_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_lt_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LT_F16

    Inst_VOPC__V_CMPX_LT_F16::~Inst_VOPC__V_CMPX_LT_F16()
    {
    } // ~Inst_VOPC__V_CMPX_LT_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_EQ_F16 class methods ---

    Inst_VOPC__V_CMPX_EQ_F16::Inst_VOPC__V_CMPX_EQ_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_eq_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_EQ_F16

    Inst_VOPC__V_CMPX_EQ_F16::~Inst_VOPC__V_CMPX_EQ_F16()
    {
    } // ~Inst_VOPC__V_CMPX_EQ_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_EQ_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_LE_F16 class methods ---

    Inst_VOPC__V_CMPX_LE_F16::Inst_VOPC__V_CMPX_LE_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_le_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LE_F16

    Inst_VOPC__V_CMPX_LE_F16::~Inst_VOPC__V_CMPX_LE_F16()
    {
    } // ~Inst_VOPC__V_CMPX_LE_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_GT_F16 class methods ---

    Inst_VOPC__V_CMPX_GT_F16::Inst_VOPC__V_CMPX_GT_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_gt_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GT_F16

    Inst_VOPC__V_CMPX_GT_F16::~Inst_VOPC__V_CMPX_GT_F16()
    {
    } // ~Inst_VOPC__V_CMPX_GT_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_LG_F16 class methods ---

    Inst_VOPC__V_CMPX_LG_F16::Inst_VOPC__V_CMPX_LG_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_lg_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LG_F16

    Inst_VOPC__V_CMPX_LG_F16::~Inst_VOPC__V_CMPX_LG_F16()
    {
    } // ~Inst_VOPC__V_CMPX_LG_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LG_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_GE_F16 class methods ---

    Inst_VOPC__V_CMPX_GE_F16::Inst_VOPC__V_CMPX_GE_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ge_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GE_F16

    Inst_VOPC__V_CMPX_GE_F16::~Inst_VOPC__V_CMPX_GE_F16()
    {
    } // ~Inst_VOPC__V_CMPX_GE_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_O_F16 class methods ---

    Inst_VOPC__V_CMPX_O_F16::Inst_VOPC__V_CMPX_O_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_o_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_O_F16

    Inst_VOPC__V_CMPX_O_F16::~Inst_VOPC__V_CMPX_O_F16()
    {
    } // ~Inst_VOPC__V_CMPX_O_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (!isNan(S0) && !isNan(S1)); D = VCC in VOPC
    // encoding.
    void
    Inst_VOPC__V_CMPX_O_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_U_F16 class methods ---

    Inst_VOPC__V_CMPX_U_F16::Inst_VOPC__V_CMPX_U_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_u_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_U_F16

    Inst_VOPC__V_CMPX_U_F16::~Inst_VOPC__V_CMPX_U_F16()
    {
    } // ~Inst_VOPC__V_CMPX_U_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (isNan(S0)  ||  isNan(S1)); D = VCC in VOPC
    // encoding.
    void
    Inst_VOPC__V_CMPX_U_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_NGE_F16 class methods ---

    Inst_VOPC__V_CMPX_NGE_F16::Inst_VOPC__V_CMPX_NGE_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_nge_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NGE_F16

    Inst_VOPC__V_CMPX_NGE_F16::~Inst_VOPC__V_CMPX_NGE_F16()
    {
    } // ~Inst_VOPC__V_CMPX_NGE_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NGE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_NLG_F16 class methods ---

    Inst_VOPC__V_CMPX_NLG_F16::Inst_VOPC__V_CMPX_NLG_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_nlg_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NLG_F16

    Inst_VOPC__V_CMPX_NLG_F16::~Inst_VOPC__V_CMPX_NLG_F16()
    {
    } // ~Inst_VOPC__V_CMPX_NLG_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NLG_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_NGT_F16 class methods ---

    Inst_VOPC__V_CMPX_NGT_F16::Inst_VOPC__V_CMPX_NGT_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ngt_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NGT_F16

    Inst_VOPC__V_CMPX_NGT_F16::~Inst_VOPC__V_CMPX_NGT_F16()
    {
    } // ~Inst_VOPC__V_CMPX_NGT_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NGT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_NLE_F16 class methods ---

    Inst_VOPC__V_CMPX_NLE_F16::Inst_VOPC__V_CMPX_NLE_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_nle_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NLE_F16

    Inst_VOPC__V_CMPX_NLE_F16::~Inst_VOPC__V_CMPX_NLE_F16()
    {
    } // ~Inst_VOPC__V_CMPX_NLE_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NLE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_NEQ_F16 class methods ---

    Inst_VOPC__V_CMPX_NEQ_F16::Inst_VOPC__V_CMPX_NEQ_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_neq_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NEQ_F16

    Inst_VOPC__V_CMPX_NEQ_F16::~Inst_VOPC__V_CMPX_NEQ_F16()
    {
    } // ~Inst_VOPC__V_CMPX_NEQ_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NEQ_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_NLT_F16 class methods ---

    Inst_VOPC__V_CMPX_NLT_F16::Inst_VOPC__V_CMPX_NLT_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_nlt_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NLT_F16

    Inst_VOPC__V_CMPX_NLT_F16::~Inst_VOPC__V_CMPX_NLT_F16()
    {
    } // ~Inst_VOPC__V_CMPX_NLT_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NLT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMPX_TRU_F16 class methods ---

    Inst_VOPC__V_CMPX_TRU_F16::Inst_VOPC__V_CMPX_TRU_F16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_tru_f16")
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_TRU_F16

    Inst_VOPC__V_CMPX_TRU_F16::~Inst_VOPC__V_CMPX_TRU_F16()
    {
    } // ~Inst_VOPC__V_CMPX_TRU_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_TRU_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOPC__V_CMP_F_F32 class methods ---

    Inst_VOPC__V_CMP_F_F32::Inst_VOPC__V_CMP_F_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_f_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_F_F32

    Inst_VOPC__V_CMP_F_F32::~Inst_VOPC__V_CMP_F_F32()
    {
    } // ~Inst_VOPC__V_CMP_F_F32

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_F_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LT_F32 class methods ---

    Inst_VOPC__V_CMP_LT_F32::Inst_VOPC__V_CMP_LT_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_lt_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_LT_F32

    Inst_VOPC__V_CMP_LT_F32::~Inst_VOPC__V_CMP_LT_F32()
    {
    } // ~Inst_VOPC__V_CMP_LT_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_EQ_F32 class methods ---

    Inst_VOPC__V_CMP_EQ_F32::Inst_VOPC__V_CMP_EQ_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_eq_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_EQ_F32

    Inst_VOPC__V_CMP_EQ_F32::~Inst_VOPC__V_CMP_EQ_F32()
    {
    } // ~Inst_VOPC__V_CMP_EQ_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_EQ_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LE_F32 class methods ---

    Inst_VOPC__V_CMP_LE_F32::Inst_VOPC__V_CMP_LE_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_le_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_LE_F32

    Inst_VOPC__V_CMP_LE_F32::~Inst_VOPC__V_CMP_LE_F32()
    {
    } // ~Inst_VOPC__V_CMP_LE_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GT_F32 class methods ---

    Inst_VOPC__V_CMP_GT_F32::Inst_VOPC__V_CMP_GT_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_gt_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_GT_F32

    Inst_VOPC__V_CMP_GT_F32::~Inst_VOPC__V_CMP_GT_F32()
    {
    } // ~Inst_VOPC__V_CMP_GT_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LG_F32 class methods ---

    Inst_VOPC__V_CMP_LG_F32::Inst_VOPC__V_CMP_LG_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_lg_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_LG_F32

    Inst_VOPC__V_CMP_LG_F32::~Inst_VOPC__V_CMP_LG_F32()
    {
    } // ~Inst_VOPC__V_CMP_LG_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LG_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, (src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GE_F32 class methods ---

    Inst_VOPC__V_CMP_GE_F32::Inst_VOPC__V_CMP_GE_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ge_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_GE_F32

    Inst_VOPC__V_CMP_GE_F32::~Inst_VOPC__V_CMP_GE_F32()
    {
    } // ~Inst_VOPC__V_CMP_GE_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_O_F32 class methods ---

    Inst_VOPC__V_CMP_O_F32::Inst_VOPC__V_CMP_O_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_o_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_O_F32

    Inst_VOPC__V_CMP_O_F32::~Inst_VOPC__V_CMP_O_F32()
    {
    } // ~Inst_VOPC__V_CMP_O_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (!isNan(S0) && !isNan(S1)); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_O_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, (!std::isnan(src0[lane])
                    && !std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_U_F32 class methods ---

    Inst_VOPC__V_CMP_U_F32::Inst_VOPC__V_CMP_U_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_u_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_U_F32

    Inst_VOPC__V_CMP_U_F32::~Inst_VOPC__V_CMP_U_F32()
    {
    } // ~Inst_VOPC__V_CMP_U_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (isNan(S0)  ||  isNan(S1)); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_U_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, (std::isnan(src0[lane])
                    || std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NGE_F32 class methods ---

    Inst_VOPC__V_CMP_NGE_F32::Inst_VOPC__V_CMP_NGE_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_nge_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_NGE_F32

    Inst_VOPC__V_CMP_NGE_F32::~Inst_VOPC__V_CMP_NGE_F32()
    {
    } // ~Inst_VOPC__V_CMP_NGE_F32

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NGE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] >= src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NLG_F32 class methods ---

    Inst_VOPC__V_CMP_NLG_F32::Inst_VOPC__V_CMP_NLG_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_nlg_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_NLG_F32

    Inst_VOPC__V_CMP_NLG_F32::~Inst_VOPC__V_CMP_NLG_F32()
    {
    } // ~Inst_VOPC__V_CMP_NLG_F32

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NLG_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NGT_F32 class methods ---

    Inst_VOPC__V_CMP_NGT_F32::Inst_VOPC__V_CMP_NGT_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ngt_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_NGT_F32

    Inst_VOPC__V_CMP_NGT_F32::~Inst_VOPC__V_CMP_NGT_F32()
    {
    } // ~Inst_VOPC__V_CMP_NGT_F32

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NGT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NLE_F32 class methods ---

    Inst_VOPC__V_CMP_NLE_F32::Inst_VOPC__V_CMP_NLE_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_nle_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_NLE_F32

    Inst_VOPC__V_CMP_NLE_F32::~Inst_VOPC__V_CMP_NLE_F32()
    {
    } // ~Inst_VOPC__V_CMP_NLE_F32

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NLE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] <= src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NEQ_F32 class methods ---

    Inst_VOPC__V_CMP_NEQ_F32::Inst_VOPC__V_CMP_NEQ_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_neq_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_NEQ_F32

    Inst_VOPC__V_CMP_NEQ_F32::~Inst_VOPC__V_CMP_NEQ_F32()
    {
    } // ~Inst_VOPC__V_CMP_NEQ_F32

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NEQ_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NLT_F32 class methods ---

    Inst_VOPC__V_CMP_NLT_F32::Inst_VOPC__V_CMP_NLT_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_nlt_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_NLT_F32

    Inst_VOPC__V_CMP_NLT_F32::~Inst_VOPC__V_CMP_NLT_F32()
    {
    } // ~Inst_VOPC__V_CMP_NLT_F32

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NLT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] < src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_TRU_F32 class methods ---

    Inst_VOPC__V_CMP_TRU_F32::Inst_VOPC__V_CMP_TRU_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_tru_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOPC__V_CMP_TRU_F32

    Inst_VOPC__V_CMP_TRU_F32::~Inst_VOPC__V_CMP_TRU_F32()
    {
    } // ~Inst_VOPC__V_CMP_TRU_F32

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_TRU_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_F_F32 class methods ---

    Inst_VOPC__V_CMPX_F_F32::Inst_VOPC__V_CMPX_F_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_f_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_F_F32

    Inst_VOPC__V_CMPX_F_F32::~Inst_VOPC__V_CMPX_F_F32()
    {
    } // ~Inst_VOPC__V_CMPX_F_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_F_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_LT_F32 class methods ---

    Inst_VOPC__V_CMPX_LT_F32::Inst_VOPC__V_CMPX_LT_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_lt_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LT_F32

    Inst_VOPC__V_CMPX_LT_F32::~Inst_VOPC__V_CMPX_LT_F32()
    {
    } // ~Inst_VOPC__V_CMPX_LT_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_EQ_F32 class methods ---

    Inst_VOPC__V_CMPX_EQ_F32::Inst_VOPC__V_CMPX_EQ_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_eq_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_EQ_F32

    Inst_VOPC__V_CMPX_EQ_F32::~Inst_VOPC__V_CMPX_EQ_F32()
    {
    } // ~Inst_VOPC__V_CMPX_EQ_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_EQ_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_LE_F32 class methods ---

    Inst_VOPC__V_CMPX_LE_F32::Inst_VOPC__V_CMPX_LE_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_le_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LE_F32

    Inst_VOPC__V_CMPX_LE_F32::~Inst_VOPC__V_CMPX_LE_F32()
    {
    } // ~Inst_VOPC__V_CMPX_LE_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_GT_F32 class methods ---

    Inst_VOPC__V_CMPX_GT_F32::Inst_VOPC__V_CMPX_GT_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_gt_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GT_F32

    Inst_VOPC__V_CMPX_GT_F32::~Inst_VOPC__V_CMPX_GT_F32()
    {
    } // ~Inst_VOPC__V_CMPX_GT_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_LG_F32 class methods ---

    Inst_VOPC__V_CMPX_LG_F32::Inst_VOPC__V_CMPX_LG_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_lg_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LG_F32

    Inst_VOPC__V_CMPX_LG_F32::~Inst_VOPC__V_CMPX_LG_F32()
    {
    } // ~Inst_VOPC__V_CMPX_LG_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LG_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, (src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_GE_F32 class methods ---

    Inst_VOPC__V_CMPX_GE_F32::Inst_VOPC__V_CMPX_GE_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ge_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GE_F32

    Inst_VOPC__V_CMPX_GE_F32::~Inst_VOPC__V_CMPX_GE_F32()
    {
    } // ~Inst_VOPC__V_CMPX_GE_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_O_F32 class methods ---

    Inst_VOPC__V_CMPX_O_F32::Inst_VOPC__V_CMPX_O_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_o_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_O_F32

    Inst_VOPC__V_CMPX_O_F32::~Inst_VOPC__V_CMPX_O_F32()
    {
    } // ~Inst_VOPC__V_CMPX_O_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (!isNan(S0) && !isNan(S1)); D = VCC in VOPC
    // encoding.
    void
    Inst_VOPC__V_CMPX_O_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, (!std::isnan(src0[lane])
                    && !std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_U_F32 class methods ---

    Inst_VOPC__V_CMPX_U_F32::Inst_VOPC__V_CMPX_U_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_u_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_U_F32

    Inst_VOPC__V_CMPX_U_F32::~Inst_VOPC__V_CMPX_U_F32()
    {
    } // ~Inst_VOPC__V_CMPX_U_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (isNan(S0)  ||  isNan(S1)); D = VCC in VOPC
    // encoding.
    void
    Inst_VOPC__V_CMPX_U_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, (std::isnan(src0[lane])
                    || std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_NGE_F32 class methods ---

    Inst_VOPC__V_CMPX_NGE_F32::Inst_VOPC__V_CMPX_NGE_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_nge_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NGE_F32

    Inst_VOPC__V_CMPX_NGE_F32::~Inst_VOPC__V_CMPX_NGE_F32()
    {
    } // ~Inst_VOPC__V_CMPX_NGE_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NGE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] >= src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_NLG_F32 class methods ---

    Inst_VOPC__V_CMPX_NLG_F32::Inst_VOPC__V_CMPX_NLG_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_nlg_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NLG_F32

    Inst_VOPC__V_CMPX_NLG_F32::~Inst_VOPC__V_CMPX_NLG_F32()
    {
    } // ~Inst_VOPC__V_CMPX_NLG_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NLG_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_NGT_F32 class methods ---

    Inst_VOPC__V_CMPX_NGT_F32::Inst_VOPC__V_CMPX_NGT_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ngt_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NGT_F32

    Inst_VOPC__V_CMPX_NGT_F32::~Inst_VOPC__V_CMPX_NGT_F32()
    {
    } // ~Inst_VOPC__V_CMPX_NGT_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NGT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_NLE_F32 class methods ---

    Inst_VOPC__V_CMPX_NLE_F32::Inst_VOPC__V_CMPX_NLE_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_nle_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NLE_F32

    Inst_VOPC__V_CMPX_NLE_F32::~Inst_VOPC__V_CMPX_NLE_F32()
    {
    } // ~Inst_VOPC__V_CMPX_NLE_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NLE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] <= src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_NEQ_F32 class methods ---

    Inst_VOPC__V_CMPX_NEQ_F32::Inst_VOPC__V_CMPX_NEQ_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_neq_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NEQ_F32

    Inst_VOPC__V_CMPX_NEQ_F32::~Inst_VOPC__V_CMPX_NEQ_F32()
    {
    } // ~Inst_VOPC__V_CMPX_NEQ_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NEQ_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] == src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_NLT_F32 class methods ---

    Inst_VOPC__V_CMPX_NLT_F32::Inst_VOPC__V_CMPX_NLT_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_nlt_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NLT_F32

    Inst_VOPC__V_CMPX_NLT_F32::~Inst_VOPC__V_CMPX_NLT_F32()
    {
    } // ~Inst_VOPC__V_CMPX_NLT_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NLT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] < src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_TRU_F32 class methods ---

    Inst_VOPC__V_CMPX_TRU_F32::Inst_VOPC__V_CMPX_TRU_F32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_tru_f32")
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_TRU_F32

    Inst_VOPC__V_CMPX_TRU_F32::~Inst_VOPC__V_CMPX_TRU_F32()
    {
    } // ~Inst_VOPC__V_CMPX_TRU_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_TRU_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMP_F_F64 class methods ---

    Inst_VOPC__V_CMP_F_F64::Inst_VOPC__V_CMP_F_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_f_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_F_F64

    Inst_VOPC__V_CMP_F_F64::~Inst_VOPC__V_CMP_F_F64()
    {
    } // ~Inst_VOPC__V_CMP_F_F64

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_F_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LT_F64 class methods ---

    Inst_VOPC__V_CMP_LT_F64::Inst_VOPC__V_CMP_LT_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_lt_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_LT_F64

    Inst_VOPC__V_CMP_LT_F64::~Inst_VOPC__V_CMP_LT_F64()
    {
    } // ~Inst_VOPC__V_CMP_LT_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_EQ_F64 class methods ---

    Inst_VOPC__V_CMP_EQ_F64::Inst_VOPC__V_CMP_EQ_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_eq_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_EQ_F64

    Inst_VOPC__V_CMP_EQ_F64::~Inst_VOPC__V_CMP_EQ_F64()
    {
    } // ~Inst_VOPC__V_CMP_EQ_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_EQ_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LE_F64 class methods ---

    Inst_VOPC__V_CMP_LE_F64::Inst_VOPC__V_CMP_LE_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_le_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_LE_F64

    Inst_VOPC__V_CMP_LE_F64::~Inst_VOPC__V_CMP_LE_F64()
    {
    } // ~Inst_VOPC__V_CMP_LE_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GT_F64 class methods ---

    Inst_VOPC__V_CMP_GT_F64::Inst_VOPC__V_CMP_GT_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_gt_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_GT_F64

    Inst_VOPC__V_CMP_GT_F64::~Inst_VOPC__V_CMP_GT_F64()
    {
    } // ~Inst_VOPC__V_CMP_GT_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LG_F64 class methods ---

    Inst_VOPC__V_CMP_LG_F64::Inst_VOPC__V_CMP_LG_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_lg_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_LG_F64

    Inst_VOPC__V_CMP_LG_F64::~Inst_VOPC__V_CMP_LG_F64()
    {
    } // ~Inst_VOPC__V_CMP_LG_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LG_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, (src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GE_F64 class methods ---

    Inst_VOPC__V_CMP_GE_F64::Inst_VOPC__V_CMP_GE_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ge_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_GE_F64

    Inst_VOPC__V_CMP_GE_F64::~Inst_VOPC__V_CMP_GE_F64()
    {
    } // ~Inst_VOPC__V_CMP_GE_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_O_F64 class methods ---

    Inst_VOPC__V_CMP_O_F64::Inst_VOPC__V_CMP_O_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_o_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_O_F64

    Inst_VOPC__V_CMP_O_F64::~Inst_VOPC__V_CMP_O_F64()
    {
    } // ~Inst_VOPC__V_CMP_O_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (!isNan(S0) && !isNan(S1)); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_O_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, (!std::isnan(src0[lane])
                    && !std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_U_F64 class methods ---

    Inst_VOPC__V_CMP_U_F64::Inst_VOPC__V_CMP_U_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_u_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_U_F64

    Inst_VOPC__V_CMP_U_F64::~Inst_VOPC__V_CMP_U_F64()
    {
    } // ~Inst_VOPC__V_CMP_U_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (isNan(S0)  ||  isNan(S1)); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_U_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, (std::isnan(src0[lane])
                    || std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NGE_F64 class methods ---

    Inst_VOPC__V_CMP_NGE_F64::Inst_VOPC__V_CMP_NGE_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_nge_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_NGE_F64

    Inst_VOPC__V_CMP_NGE_F64::~Inst_VOPC__V_CMP_NGE_F64()
    {
    } // ~Inst_VOPC__V_CMP_NGE_F64

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NGE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] >= src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NLG_F64 class methods ---

    Inst_VOPC__V_CMP_NLG_F64::Inst_VOPC__V_CMP_NLG_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_nlg_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_NLG_F64

    Inst_VOPC__V_CMP_NLG_F64::~Inst_VOPC__V_CMP_NLG_F64()
    {
    } // ~Inst_VOPC__V_CMP_NLG_F64

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NLG_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NGT_F64 class methods ---

    Inst_VOPC__V_CMP_NGT_F64::Inst_VOPC__V_CMP_NGT_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ngt_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_NGT_F64

    Inst_VOPC__V_CMP_NGT_F64::~Inst_VOPC__V_CMP_NGT_F64()
    {
    } // ~Inst_VOPC__V_CMP_NGT_F64

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NGT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NLE_F64 class methods ---

    Inst_VOPC__V_CMP_NLE_F64::Inst_VOPC__V_CMP_NLE_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_nle_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_NLE_F64

    Inst_VOPC__V_CMP_NLE_F64::~Inst_VOPC__V_CMP_NLE_F64()
    {
    } // ~Inst_VOPC__V_CMP_NLE_F64

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NLE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] <= src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NEQ_F64 class methods ---

    Inst_VOPC__V_CMP_NEQ_F64::Inst_VOPC__V_CMP_NEQ_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_neq_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_NEQ_F64

    Inst_VOPC__V_CMP_NEQ_F64::~Inst_VOPC__V_CMP_NEQ_F64()
    {
    } // ~Inst_VOPC__V_CMP_NEQ_F64

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NEQ_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NLT_F64 class methods ---

    Inst_VOPC__V_CMP_NLT_F64::Inst_VOPC__V_CMP_NLT_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_nlt_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_NLT_F64

    Inst_VOPC__V_CMP_NLT_F64::~Inst_VOPC__V_CMP_NLT_F64()
    {
    } // ~Inst_VOPC__V_CMP_NLT_F64

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NLT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] < src1[lane]) ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_TRU_F64 class methods ---

    Inst_VOPC__V_CMP_TRU_F64::Inst_VOPC__V_CMP_TRU_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_tru_f64")
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOPC__V_CMP_TRU_F64

    Inst_VOPC__V_CMP_TRU_F64::~Inst_VOPC__V_CMP_TRU_F64()
    {
    } // ~Inst_VOPC__V_CMP_TRU_F64

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_TRU_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_F_F64 class methods ---

    Inst_VOPC__V_CMPX_F_F64::Inst_VOPC__V_CMPX_F_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_f_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_F_F64

    Inst_VOPC__V_CMPX_F_F64::~Inst_VOPC__V_CMPX_F_F64()
    {
    } // ~Inst_VOPC__V_CMPX_F_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_F_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_LT_F64 class methods ---

    Inst_VOPC__V_CMPX_LT_F64::Inst_VOPC__V_CMPX_LT_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_lt_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LT_F64

    Inst_VOPC__V_CMPX_LT_F64::~Inst_VOPC__V_CMPX_LT_F64()
    {
    } // ~Inst_VOPC__V_CMPX_LT_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_EQ_F64 class methods ---

    Inst_VOPC__V_CMPX_EQ_F64::Inst_VOPC__V_CMPX_EQ_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_eq_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_EQ_F64

    Inst_VOPC__V_CMPX_EQ_F64::~Inst_VOPC__V_CMPX_EQ_F64()
    {
    } // ~Inst_VOPC__V_CMPX_EQ_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_EQ_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
        wf->execMask() = vcc.rawData();
    } // execute
    // --- Inst_VOPC__V_CMPX_LE_F64 class methods ---

    Inst_VOPC__V_CMPX_LE_F64::Inst_VOPC__V_CMPX_LE_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_le_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LE_F64

    Inst_VOPC__V_CMPX_LE_F64::~Inst_VOPC__V_CMPX_LE_F64()
    {
    } // ~Inst_VOPC__V_CMPX_LE_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GT_F64 class methods ---

    Inst_VOPC__V_CMPX_GT_F64::Inst_VOPC__V_CMPX_GT_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_gt_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GT_F64

    Inst_VOPC__V_CMPX_GT_F64::~Inst_VOPC__V_CMPX_GT_F64()
    {
    } // ~Inst_VOPC__V_CMPX_GT_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LG_F64 class methods ---

    Inst_VOPC__V_CMPX_LG_F64::Inst_VOPC__V_CMPX_LG_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_lg_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LG_F64

    Inst_VOPC__V_CMPX_LG_F64::~Inst_VOPC__V_CMPX_LG_F64()
    {
    } // ~Inst_VOPC__V_CMPX_LG_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LG_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, (src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GE_F64 class methods ---

    Inst_VOPC__V_CMPX_GE_F64::Inst_VOPC__V_CMPX_GE_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ge_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GE_F64

    Inst_VOPC__V_CMPX_GE_F64::~Inst_VOPC__V_CMPX_GE_F64()
    {
    } // ~Inst_VOPC__V_CMPX_GE_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_O_F64 class methods ---

    Inst_VOPC__V_CMPX_O_F64::Inst_VOPC__V_CMPX_O_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_o_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_O_F64

    Inst_VOPC__V_CMPX_O_F64::~Inst_VOPC__V_CMPX_O_F64()
    {
    } // ~Inst_VOPC__V_CMPX_O_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (!isNan(S0) && !isNan(S1)); D = VCC in VOPC
    // encoding.
    void
    Inst_VOPC__V_CMPX_O_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, (!std::isnan(src0[lane])
                    && !std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_U_F64 class methods ---

    Inst_VOPC__V_CMPX_U_F64::Inst_VOPC__V_CMPX_U_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_u_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_U_F64

    Inst_VOPC__V_CMPX_U_F64::~Inst_VOPC__V_CMPX_U_F64()
    {
    } // ~Inst_VOPC__V_CMPX_U_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (isNan(S0)  ||  isNan(S1)); D = VCC in VOPC
    // encoding.
    void
    Inst_VOPC__V_CMPX_U_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, (std::isnan(src0[lane])
                    || std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_NGE_F64 class methods ---

    Inst_VOPC__V_CMPX_NGE_F64::Inst_VOPC__V_CMPX_NGE_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_nge_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NGE_F64

    Inst_VOPC__V_CMPX_NGE_F64::~Inst_VOPC__V_CMPX_NGE_F64()
    {
    } // ~Inst_VOPC__V_CMPX_NGE_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NGE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] >= src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_NLG_F64 class methods ---

    Inst_VOPC__V_CMPX_NLG_F64::Inst_VOPC__V_CMPX_NLG_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_nlg_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NLG_F64

    Inst_VOPC__V_CMPX_NLG_F64::~Inst_VOPC__V_CMPX_NLG_F64()
    {
    } // ~Inst_VOPC__V_CMPX_NLG_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NLG_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_NGT_F64 class methods ---

    Inst_VOPC__V_CMPX_NGT_F64::Inst_VOPC__V_CMPX_NGT_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ngt_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NGT_F64

    Inst_VOPC__V_CMPX_NGT_F64::~Inst_VOPC__V_CMPX_NGT_F64()
    {
    } // ~Inst_VOPC__V_CMPX_NGT_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NGT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_NLE_F64 class methods ---

    Inst_VOPC__V_CMPX_NLE_F64::Inst_VOPC__V_CMPX_NLE_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_nle_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NLE_F64

    Inst_VOPC__V_CMPX_NLE_F64::~Inst_VOPC__V_CMPX_NLE_F64()
    {
    } // ~Inst_VOPC__V_CMPX_NLE_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NLE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] <= src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_NEQ_F64 class methods ---

    Inst_VOPC__V_CMPX_NEQ_F64::Inst_VOPC__V_CMPX_NEQ_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_neq_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NEQ_F64

    Inst_VOPC__V_CMPX_NEQ_F64::~Inst_VOPC__V_CMPX_NEQ_F64()
    {
    } // ~Inst_VOPC__V_CMPX_NEQ_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NEQ_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_NLT_F64 class methods ---

    Inst_VOPC__V_CMPX_NLT_F64::Inst_VOPC__V_CMPX_NLT_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_nlt_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NLT_F64

    Inst_VOPC__V_CMPX_NLT_F64::~Inst_VOPC__V_CMPX_NLT_F64()
    {
    } // ~Inst_VOPC__V_CMPX_NLT_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NLT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, !(src0[lane] < src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_TRU_F64 class methods ---

    Inst_VOPC__V_CMPX_TRU_F64::Inst_VOPC__V_CMPX_TRU_F64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_tru_f64")
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_TRU_F64

    Inst_VOPC__V_CMPX_TRU_F64::~Inst_VOPC__V_CMPX_TRU_F64()
    {
    } // ~Inst_VOPC__V_CMPX_TRU_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_TRU_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_F_I16 class methods ---

    Inst_VOPC__V_CMP_F_I16::Inst_VOPC__V_CMP_F_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_f_i16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_F_I16

    Inst_VOPC__V_CMP_F_I16::~Inst_VOPC__V_CMP_F_I16()
    {
    } // ~Inst_VOPC__V_CMP_F_I16

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_F_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LT_I16 class methods ---

    Inst_VOPC__V_CMP_LT_I16::Inst_VOPC__V_CMP_LT_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_lt_i16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_LT_I16

    Inst_VOPC__V_CMP_LT_I16::~Inst_VOPC__V_CMP_LT_I16()
    {
    } // ~Inst_VOPC__V_CMP_LT_I16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LT_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_EQ_I16 class methods ---

    Inst_VOPC__V_CMP_EQ_I16::Inst_VOPC__V_CMP_EQ_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_eq_i16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_EQ_I16

    Inst_VOPC__V_CMP_EQ_I16::~Inst_VOPC__V_CMP_EQ_I16()
    {
    } // ~Inst_VOPC__V_CMP_EQ_I16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_EQ_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LE_I16 class methods ---

    Inst_VOPC__V_CMP_LE_I16::Inst_VOPC__V_CMP_LE_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_le_i16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_LE_I16

    Inst_VOPC__V_CMP_LE_I16::~Inst_VOPC__V_CMP_LE_I16()
    {
    } // ~Inst_VOPC__V_CMP_LE_I16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LE_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GT_I16 class methods ---

    Inst_VOPC__V_CMP_GT_I16::Inst_VOPC__V_CMP_GT_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_gt_i16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_GT_I16

    Inst_VOPC__V_CMP_GT_I16::~Inst_VOPC__V_CMP_GT_I16()
    {
    } // ~Inst_VOPC__V_CMP_GT_I16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GT_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NE_I16 class methods ---

    Inst_VOPC__V_CMP_NE_I16::Inst_VOPC__V_CMP_NE_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ne_i16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_NE_I16

    Inst_VOPC__V_CMP_NE_I16::~Inst_VOPC__V_CMP_NE_I16()
    {
    } // ~Inst_VOPC__V_CMP_NE_I16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NE_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GE_I16 class methods ---

    Inst_VOPC__V_CMP_GE_I16::Inst_VOPC__V_CMP_GE_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ge_i16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_GE_I16

    Inst_VOPC__V_CMP_GE_I16::~Inst_VOPC__V_CMP_GE_I16()
    {
    } // ~Inst_VOPC__V_CMP_GE_I16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GE_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_T_I16 class methods ---

    Inst_VOPC__V_CMP_T_I16::Inst_VOPC__V_CMP_T_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_t_i16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_T_I16

    Inst_VOPC__V_CMP_T_I16::~Inst_VOPC__V_CMP_T_I16()
    {
    } // ~Inst_VOPC__V_CMP_T_I16

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_T_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_F_U16 class methods ---

    Inst_VOPC__V_CMP_F_U16::Inst_VOPC__V_CMP_F_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_f_u16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_F_U16

    Inst_VOPC__V_CMP_F_U16::~Inst_VOPC__V_CMP_F_U16()
    {
    } // ~Inst_VOPC__V_CMP_F_U16

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_F_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LT_U16 class methods ---

    Inst_VOPC__V_CMP_LT_U16::Inst_VOPC__V_CMP_LT_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_lt_u16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_LT_U16

    Inst_VOPC__V_CMP_LT_U16::~Inst_VOPC__V_CMP_LT_U16()
    {
    } // ~Inst_VOPC__V_CMP_LT_U16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LT_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_EQ_U16 class methods ---

    Inst_VOPC__V_CMP_EQ_U16::Inst_VOPC__V_CMP_EQ_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_eq_u16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_EQ_U16

    Inst_VOPC__V_CMP_EQ_U16::~Inst_VOPC__V_CMP_EQ_U16()
    {
    } // ~Inst_VOPC__V_CMP_EQ_U16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_EQ_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LE_U16 class methods ---

    Inst_VOPC__V_CMP_LE_U16::Inst_VOPC__V_CMP_LE_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_le_u16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_LE_U16

    Inst_VOPC__V_CMP_LE_U16::~Inst_VOPC__V_CMP_LE_U16()
    {
    } // ~Inst_VOPC__V_CMP_LE_U16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LE_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GT_U16 class methods ---

    Inst_VOPC__V_CMP_GT_U16::Inst_VOPC__V_CMP_GT_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_gt_u16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_GT_U16

    Inst_VOPC__V_CMP_GT_U16::~Inst_VOPC__V_CMP_GT_U16()
    {
    } // ~Inst_VOPC__V_CMP_GT_U16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GT_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NE_U16 class methods ---

    Inst_VOPC__V_CMP_NE_U16::Inst_VOPC__V_CMP_NE_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ne_u16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_NE_U16

    Inst_VOPC__V_CMP_NE_U16::~Inst_VOPC__V_CMP_NE_U16()
    {
    } // ~Inst_VOPC__V_CMP_NE_U16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NE_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GE_U16 class methods ---

    Inst_VOPC__V_CMP_GE_U16::Inst_VOPC__V_CMP_GE_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ge_u16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_GE_U16

    Inst_VOPC__V_CMP_GE_U16::~Inst_VOPC__V_CMP_GE_U16()
    {
    } // ~Inst_VOPC__V_CMP_GE_U16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GE_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_T_U16 class methods ---

    Inst_VOPC__V_CMP_T_U16::Inst_VOPC__V_CMP_T_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_t_u16")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_T_U16

    Inst_VOPC__V_CMP_T_U16::~Inst_VOPC__V_CMP_T_U16()
    {
    } // ~Inst_VOPC__V_CMP_T_U16

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_T_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_F_I16 class methods ---

    Inst_VOPC__V_CMPX_F_I16::Inst_VOPC__V_CMPX_F_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_f_i16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_F_I16

    Inst_VOPC__V_CMPX_F_I16::~Inst_VOPC__V_CMPX_F_I16()
    {
    } // ~Inst_VOPC__V_CMPX_F_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_F_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LT_I16 class methods ---

    Inst_VOPC__V_CMPX_LT_I16::Inst_VOPC__V_CMPX_LT_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_lt_i16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LT_I16

    Inst_VOPC__V_CMPX_LT_I16::~Inst_VOPC__V_CMPX_LT_I16()
    {
    } // ~Inst_VOPC__V_CMPX_LT_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LT_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_EQ_I16 class methods ---

    Inst_VOPC__V_CMPX_EQ_I16::Inst_VOPC__V_CMPX_EQ_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_eq_i16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_EQ_I16

    Inst_VOPC__V_CMPX_EQ_I16::~Inst_VOPC__V_CMPX_EQ_I16()
    {
    } // ~Inst_VOPC__V_CMPX_EQ_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_EQ_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LE_I16 class methods ---

    Inst_VOPC__V_CMPX_LE_I16::Inst_VOPC__V_CMPX_LE_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_le_i16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LE_I16

    Inst_VOPC__V_CMPX_LE_I16::~Inst_VOPC__V_CMPX_LE_I16()
    {
    } // ~Inst_VOPC__V_CMPX_LE_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LE_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GT_I16 class methods ---

    Inst_VOPC__V_CMPX_GT_I16::Inst_VOPC__V_CMPX_GT_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_gt_i16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GT_I16

    Inst_VOPC__V_CMPX_GT_I16::~Inst_VOPC__V_CMPX_GT_I16()
    {
    } // ~Inst_VOPC__V_CMPX_GT_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GT_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_NE_I16 class methods ---

    Inst_VOPC__V_CMPX_NE_I16::Inst_VOPC__V_CMPX_NE_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ne_i16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NE_I16

    Inst_VOPC__V_CMPX_NE_I16::~Inst_VOPC__V_CMPX_NE_I16()
    {
    } // ~Inst_VOPC__V_CMPX_NE_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NE_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GE_I16 class methods ---

    Inst_VOPC__V_CMPX_GE_I16::Inst_VOPC__V_CMPX_GE_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ge_i16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GE_I16

    Inst_VOPC__V_CMPX_GE_I16::~Inst_VOPC__V_CMPX_GE_I16()
    {
    } // ~Inst_VOPC__V_CMPX_GE_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GE_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_T_I16 class methods ---

    Inst_VOPC__V_CMPX_T_I16::Inst_VOPC__V_CMPX_T_I16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_t_i16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_T_I16

    Inst_VOPC__V_CMPX_T_I16::~Inst_VOPC__V_CMPX_T_I16()
    {
    } // ~Inst_VOPC__V_CMPX_T_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_T_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_F_U16 class methods ---

    Inst_VOPC__V_CMPX_F_U16::Inst_VOPC__V_CMPX_F_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_f_u16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_F_U16

    Inst_VOPC__V_CMPX_F_U16::~Inst_VOPC__V_CMPX_F_U16()
    {
    } // ~Inst_VOPC__V_CMPX_F_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_F_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LT_U16 class methods ---

    Inst_VOPC__V_CMPX_LT_U16::Inst_VOPC__V_CMPX_LT_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_lt_u16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LT_U16

    Inst_VOPC__V_CMPX_LT_U16::~Inst_VOPC__V_CMPX_LT_U16()
    {
    } // ~Inst_VOPC__V_CMPX_LT_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LT_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_EQ_U16 class methods ---

    Inst_VOPC__V_CMPX_EQ_U16::Inst_VOPC__V_CMPX_EQ_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_eq_u16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_EQ_U16

    Inst_VOPC__V_CMPX_EQ_U16::~Inst_VOPC__V_CMPX_EQ_U16()
    {
    } // ~Inst_VOPC__V_CMPX_EQ_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_EQ_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LE_U16 class methods ---

    Inst_VOPC__V_CMPX_LE_U16::Inst_VOPC__V_CMPX_LE_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_le_u16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LE_U16

    Inst_VOPC__V_CMPX_LE_U16::~Inst_VOPC__V_CMPX_LE_U16()
    {
    } // ~Inst_VOPC__V_CMPX_LE_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LE_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GT_U16 class methods ---

    Inst_VOPC__V_CMPX_GT_U16::Inst_VOPC__V_CMPX_GT_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_gt_u16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GT_U16

    Inst_VOPC__V_CMPX_GT_U16::~Inst_VOPC__V_CMPX_GT_U16()
    {
    } // ~Inst_VOPC__V_CMPX_GT_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GT_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_NE_U16 class methods ---

    Inst_VOPC__V_CMPX_NE_U16::Inst_VOPC__V_CMPX_NE_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ne_u16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NE_U16

    Inst_VOPC__V_CMPX_NE_U16::~Inst_VOPC__V_CMPX_NE_U16()
    {
    } // ~Inst_VOPC__V_CMPX_NE_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NE_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GE_U16 class methods ---

    Inst_VOPC__V_CMPX_GE_U16::Inst_VOPC__V_CMPX_GE_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ge_u16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GE_U16

    Inst_VOPC__V_CMPX_GE_U16::~Inst_VOPC__V_CMPX_GE_U16()
    {
    } // ~Inst_VOPC__V_CMPX_GE_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GE_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_T_U16 class methods ---

    Inst_VOPC__V_CMPX_T_U16::Inst_VOPC__V_CMPX_T_U16(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_t_u16")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_T_U16

    Inst_VOPC__V_CMPX_T_U16::~Inst_VOPC__V_CMPX_T_U16()
    {
    } // ~Inst_VOPC__V_CMPX_T_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_T_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_F_I32 class methods ---

    Inst_VOPC__V_CMP_F_I32::Inst_VOPC__V_CMP_F_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_f_i32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_F_I32

    Inst_VOPC__V_CMP_F_I32::~Inst_VOPC__V_CMP_F_I32()
    {
    } // ~Inst_VOPC__V_CMP_F_I32

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_F_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LT_I32 class methods ---

    Inst_VOPC__V_CMP_LT_I32::Inst_VOPC__V_CMP_LT_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_lt_i32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_LT_I32

    Inst_VOPC__V_CMP_LT_I32::~Inst_VOPC__V_CMP_LT_I32()
    {
    } // ~Inst_VOPC__V_CMP_LT_I32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_EQ_I32 class methods ---

    Inst_VOPC__V_CMP_EQ_I32::Inst_VOPC__V_CMP_EQ_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_eq_i32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_EQ_I32

    Inst_VOPC__V_CMP_EQ_I32::~Inst_VOPC__V_CMP_EQ_I32()
    {
    } // ~Inst_VOPC__V_CMP_EQ_I32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_EQ_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LE_I32 class methods ---

    Inst_VOPC__V_CMP_LE_I32::Inst_VOPC__V_CMP_LE_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_le_i32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_LE_I32

    Inst_VOPC__V_CMP_LE_I32::~Inst_VOPC__V_CMP_LE_I32()
    {
    } // ~Inst_VOPC__V_CMP_LE_I32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GT_I32 class methods ---

    Inst_VOPC__V_CMP_GT_I32::Inst_VOPC__V_CMP_GT_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_gt_i32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_GT_I32

    Inst_VOPC__V_CMP_GT_I32::~Inst_VOPC__V_CMP_GT_I32()
    {
    } // ~Inst_VOPC__V_CMP_GT_I32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NE_I32 class methods ---

    Inst_VOPC__V_CMP_NE_I32::Inst_VOPC__V_CMP_NE_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ne_i32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_NE_I32

    Inst_VOPC__V_CMP_NE_I32::~Inst_VOPC__V_CMP_NE_I32()
    {
    } // ~Inst_VOPC__V_CMP_NE_I32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GE_I32 class methods ---

    Inst_VOPC__V_CMP_GE_I32::Inst_VOPC__V_CMP_GE_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ge_i32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_GE_I32

    Inst_VOPC__V_CMP_GE_I32::~Inst_VOPC__V_CMP_GE_I32()
    {
    } // ~Inst_VOPC__V_CMP_GE_I32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_T_I32 class methods ---

    Inst_VOPC__V_CMP_T_I32::Inst_VOPC__V_CMP_T_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_t_i32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_T_I32

    Inst_VOPC__V_CMP_T_I32::~Inst_VOPC__V_CMP_T_I32()
    {
    } // ~Inst_VOPC__V_CMP_T_I32

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_T_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_F_U32 class methods ---

    Inst_VOPC__V_CMP_F_U32::Inst_VOPC__V_CMP_F_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_f_u32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_F_U32

    Inst_VOPC__V_CMP_F_U32::~Inst_VOPC__V_CMP_F_U32()
    {
    } // ~Inst_VOPC__V_CMP_F_U32

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_F_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LT_U32 class methods ---

    Inst_VOPC__V_CMP_LT_U32::Inst_VOPC__V_CMP_LT_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_lt_u32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_LT_U32

    Inst_VOPC__V_CMP_LT_U32::~Inst_VOPC__V_CMP_LT_U32()
    {
    } // ~Inst_VOPC__V_CMP_LT_U32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LT_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_EQ_U32 class methods ---

    Inst_VOPC__V_CMP_EQ_U32::Inst_VOPC__V_CMP_EQ_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_eq_u32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_EQ_U32

    Inst_VOPC__V_CMP_EQ_U32::~Inst_VOPC__V_CMP_EQ_U32()
    {
    } // ~Inst_VOPC__V_CMP_EQ_U32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_EQ_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LE_U32 class methods ---

    Inst_VOPC__V_CMP_LE_U32::Inst_VOPC__V_CMP_LE_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_le_u32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_LE_U32

    Inst_VOPC__V_CMP_LE_U32::~Inst_VOPC__V_CMP_LE_U32()
    {
    } // ~Inst_VOPC__V_CMP_LE_U32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GT_U32 class methods ---

    Inst_VOPC__V_CMP_GT_U32::Inst_VOPC__V_CMP_GT_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_gt_u32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_GT_U32

    Inst_VOPC__V_CMP_GT_U32::~Inst_VOPC__V_CMP_GT_U32()
    {
    } // ~Inst_VOPC__V_CMP_GT_U32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GT_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NE_U32 class methods ---

    Inst_VOPC__V_CMP_NE_U32::Inst_VOPC__V_CMP_NE_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ne_u32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_NE_U32

    Inst_VOPC__V_CMP_NE_U32::~Inst_VOPC__V_CMP_NE_U32()
    {
    } // ~Inst_VOPC__V_CMP_NE_U32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GE_U32 class methods ---

    Inst_VOPC__V_CMP_GE_U32::Inst_VOPC__V_CMP_GE_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ge_u32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_GE_U32

    Inst_VOPC__V_CMP_GE_U32::~Inst_VOPC__V_CMP_GE_U32()
    {
    } // ~Inst_VOPC__V_CMP_GE_U32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_T_U32 class methods ---

    Inst_VOPC__V_CMP_T_U32::Inst_VOPC__V_CMP_T_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_t_u32")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_T_U32

    Inst_VOPC__V_CMP_T_U32::~Inst_VOPC__V_CMP_T_U32()
    {
    } // ~Inst_VOPC__V_CMP_T_U32

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_T_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_F_I32 class methods ---

    Inst_VOPC__V_CMPX_F_I32::Inst_VOPC__V_CMPX_F_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_f_i32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_F_I32

    Inst_VOPC__V_CMPX_F_I32::~Inst_VOPC__V_CMPX_F_I32()
    {
    } // ~Inst_VOPC__V_CMPX_F_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_F_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LT_I32 class methods ---

    Inst_VOPC__V_CMPX_LT_I32::Inst_VOPC__V_CMPX_LT_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_lt_i32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LT_I32

    Inst_VOPC__V_CMPX_LT_I32::~Inst_VOPC__V_CMPX_LT_I32()
    {
    } // ~Inst_VOPC__V_CMPX_LT_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_EQ_I32 class methods ---

    Inst_VOPC__V_CMPX_EQ_I32::Inst_VOPC__V_CMPX_EQ_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_eq_i32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_EQ_I32

    Inst_VOPC__V_CMPX_EQ_I32::~Inst_VOPC__V_CMPX_EQ_I32()
    {
    } // ~Inst_VOPC__V_CMPX_EQ_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_EQ_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LE_I32 class methods ---

    Inst_VOPC__V_CMPX_LE_I32::Inst_VOPC__V_CMPX_LE_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_le_i32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LE_I32

    Inst_VOPC__V_CMPX_LE_I32::~Inst_VOPC__V_CMPX_LE_I32()
    {
    } // ~Inst_VOPC__V_CMPX_LE_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GT_I32 class methods ---

    Inst_VOPC__V_CMPX_GT_I32::Inst_VOPC__V_CMPX_GT_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_gt_i32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GT_I32

    Inst_VOPC__V_CMPX_GT_I32::~Inst_VOPC__V_CMPX_GT_I32()
    {
    } // ~Inst_VOPC__V_CMPX_GT_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_NE_I32 class methods ---

    Inst_VOPC__V_CMPX_NE_I32::Inst_VOPC__V_CMPX_NE_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ne_i32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NE_I32

    Inst_VOPC__V_CMPX_NE_I32::~Inst_VOPC__V_CMPX_NE_I32()
    {
    } // ~Inst_VOPC__V_CMPX_NE_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GE_I32 class methods ---

    Inst_VOPC__V_CMPX_GE_I32::Inst_VOPC__V_CMPX_GE_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ge_i32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GE_I32

    Inst_VOPC__V_CMPX_GE_I32::~Inst_VOPC__V_CMPX_GE_I32()
    {
    } // ~Inst_VOPC__V_CMPX_GE_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_T_I32 class methods ---

    Inst_VOPC__V_CMPX_T_I32::Inst_VOPC__V_CMPX_T_I32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_t_i32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_T_I32

    Inst_VOPC__V_CMPX_T_I32::~Inst_VOPC__V_CMPX_T_I32()
    {
    } // ~Inst_VOPC__V_CMPX_T_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_T_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_F_U32 class methods ---

    Inst_VOPC__V_CMPX_F_U32::Inst_VOPC__V_CMPX_F_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_f_u32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_F_U32

    Inst_VOPC__V_CMPX_F_U32::~Inst_VOPC__V_CMPX_F_U32()
    {
    } // ~Inst_VOPC__V_CMPX_F_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_F_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LT_U32 class methods ---

    Inst_VOPC__V_CMPX_LT_U32::Inst_VOPC__V_CMPX_LT_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_lt_u32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LT_U32

    Inst_VOPC__V_CMPX_LT_U32::~Inst_VOPC__V_CMPX_LT_U32()
    {
    } // ~Inst_VOPC__V_CMPX_LT_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LT_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_EQ_U32 class methods ---

    Inst_VOPC__V_CMPX_EQ_U32::Inst_VOPC__V_CMPX_EQ_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_eq_u32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_EQ_U32

    Inst_VOPC__V_CMPX_EQ_U32::~Inst_VOPC__V_CMPX_EQ_U32()
    {
    } // ~Inst_VOPC__V_CMPX_EQ_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_EQ_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LE_U32 class methods ---

    Inst_VOPC__V_CMPX_LE_U32::Inst_VOPC__V_CMPX_LE_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_le_u32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LE_U32

    Inst_VOPC__V_CMPX_LE_U32::~Inst_VOPC__V_CMPX_LE_U32()
    {
    } // ~Inst_VOPC__V_CMPX_LE_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GT_U32 class methods ---

    Inst_VOPC__V_CMPX_GT_U32::Inst_VOPC__V_CMPX_GT_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_gt_u32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GT_U32

    Inst_VOPC__V_CMPX_GT_U32::~Inst_VOPC__V_CMPX_GT_U32()
    {
    } // ~Inst_VOPC__V_CMPX_GT_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GT_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_NE_U32 class methods ---

    Inst_VOPC__V_CMPX_NE_U32::Inst_VOPC__V_CMPX_NE_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ne_u32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NE_U32

    Inst_VOPC__V_CMPX_NE_U32::~Inst_VOPC__V_CMPX_NE_U32()
    {
    } // ~Inst_VOPC__V_CMPX_NE_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GE_U32 class methods ---

    Inst_VOPC__V_CMPX_GE_U32::Inst_VOPC__V_CMPX_GE_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ge_u32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GE_U32

    Inst_VOPC__V_CMPX_GE_U32::~Inst_VOPC__V_CMPX_GE_U32()
    {
    } // ~Inst_VOPC__V_CMPX_GE_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_T_U32 class methods ---

    Inst_VOPC__V_CMPX_T_U32::Inst_VOPC__V_CMPX_T_U32(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_t_u32")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_T_U32

    Inst_VOPC__V_CMPX_T_U32::~Inst_VOPC__V_CMPX_T_U32()
    {
    } // ~Inst_VOPC__V_CMPX_T_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_T_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_F_I64 class methods ---

    Inst_VOPC__V_CMP_F_I64::Inst_VOPC__V_CMP_F_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_f_i64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_F_I64

    Inst_VOPC__V_CMP_F_I64::~Inst_VOPC__V_CMP_F_I64()
    {
    } // ~Inst_VOPC__V_CMP_F_I64

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_F_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LT_I64 class methods ---

    Inst_VOPC__V_CMP_LT_I64::Inst_VOPC__V_CMP_LT_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_lt_i64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_LT_I64

    Inst_VOPC__V_CMP_LT_I64::~Inst_VOPC__V_CMP_LT_I64()
    {
    } // ~Inst_VOPC__V_CMP_LT_I64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LT_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_EQ_I64 class methods ---

    Inst_VOPC__V_CMP_EQ_I64::Inst_VOPC__V_CMP_EQ_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_eq_i64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_EQ_I64

    Inst_VOPC__V_CMP_EQ_I64::~Inst_VOPC__V_CMP_EQ_I64()
    {
    } // ~Inst_VOPC__V_CMP_EQ_I64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_EQ_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LE_I64 class methods ---

    Inst_VOPC__V_CMP_LE_I64::Inst_VOPC__V_CMP_LE_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_le_i64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_LE_I64

    Inst_VOPC__V_CMP_LE_I64::~Inst_VOPC__V_CMP_LE_I64()
    {
    } // ~Inst_VOPC__V_CMP_LE_I64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GT_I64 class methods ---

    Inst_VOPC__V_CMP_GT_I64::Inst_VOPC__V_CMP_GT_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_gt_i64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_GT_I64

    Inst_VOPC__V_CMP_GT_I64::~Inst_VOPC__V_CMP_GT_I64()
    {
    } // ~Inst_VOPC__V_CMP_GT_I64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GT_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NE_I64 class methods ---

    Inst_VOPC__V_CMP_NE_I64::Inst_VOPC__V_CMP_NE_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ne_i64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_NE_I64

    Inst_VOPC__V_CMP_NE_I64::~Inst_VOPC__V_CMP_NE_I64()
    {
    } // ~Inst_VOPC__V_CMP_NE_I64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GE_I64 class methods ---

    Inst_VOPC__V_CMP_GE_I64::Inst_VOPC__V_CMP_GE_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ge_i64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_GE_I64

    Inst_VOPC__V_CMP_GE_I64::~Inst_VOPC__V_CMP_GE_I64()
    {
    } // ~Inst_VOPC__V_CMP_GE_I64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_T_I64 class methods ---

    Inst_VOPC__V_CMP_T_I64::Inst_VOPC__V_CMP_T_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_t_i64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_T_I64

    Inst_VOPC__V_CMP_T_I64::~Inst_VOPC__V_CMP_T_I64()
    {
    } // ~Inst_VOPC__V_CMP_T_I64

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_T_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_F_U64 class methods ---

    Inst_VOPC__V_CMP_F_U64::Inst_VOPC__V_CMP_F_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_f_u64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_F_U64

    Inst_VOPC__V_CMP_F_U64::~Inst_VOPC__V_CMP_F_U64()
    {
    } // ~Inst_VOPC__V_CMP_F_U64

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_F_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LT_U64 class methods ---

    Inst_VOPC__V_CMP_LT_U64::Inst_VOPC__V_CMP_LT_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_lt_u64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_LT_U64

    Inst_VOPC__V_CMP_LT_U64::~Inst_VOPC__V_CMP_LT_U64()
    {
    } // ~Inst_VOPC__V_CMP_LT_U64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LT_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_EQ_U64 class methods ---

    Inst_VOPC__V_CMP_EQ_U64::Inst_VOPC__V_CMP_EQ_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_eq_u64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_EQ_U64

    Inst_VOPC__V_CMP_EQ_U64::~Inst_VOPC__V_CMP_EQ_U64()
    {
    } // ~Inst_VOPC__V_CMP_EQ_U64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_EQ_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_LE_U64 class methods ---

    Inst_VOPC__V_CMP_LE_U64::Inst_VOPC__V_CMP_LE_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_le_u64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_LE_U64

    Inst_VOPC__V_CMP_LE_U64::~Inst_VOPC__V_CMP_LE_U64()
    {
    } // ~Inst_VOPC__V_CMP_LE_U64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_LE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GT_U64 class methods ---

    Inst_VOPC__V_CMP_GT_U64::Inst_VOPC__V_CMP_GT_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_gt_u64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_GT_U64

    Inst_VOPC__V_CMP_GT_U64::~Inst_VOPC__V_CMP_GT_U64()
    {
    } // ~Inst_VOPC__V_CMP_GT_U64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GT_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_NE_U64 class methods ---

    Inst_VOPC__V_CMP_NE_U64::Inst_VOPC__V_CMP_NE_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ne_u64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_NE_U64

    Inst_VOPC__V_CMP_NE_U64::~Inst_VOPC__V_CMP_NE_U64()
    {
    } // ~Inst_VOPC__V_CMP_NE_U64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_NE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_GE_U64 class methods ---

    Inst_VOPC__V_CMP_GE_U64::Inst_VOPC__V_CMP_GE_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_ge_u64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_GE_U64

    Inst_VOPC__V_CMP_GE_U64::~Inst_VOPC__V_CMP_GE_U64()
    {
    } // ~Inst_VOPC__V_CMP_GE_U64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_GE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMP_T_U64 class methods ---

    Inst_VOPC__V_CMP_T_U64::Inst_VOPC__V_CMP_T_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmp_t_u64")
    {
        setFlag(ALU);
    } // Inst_VOPC__V_CMP_T_U64

    Inst_VOPC__V_CMP_T_U64::~Inst_VOPC__V_CMP_T_U64()
    {
    } // ~Inst_VOPC__V_CMP_T_U64

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMP_T_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_F_I64 class methods ---

    Inst_VOPC__V_CMPX_F_I64::Inst_VOPC__V_CMPX_F_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_f_i64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_F_I64

    Inst_VOPC__V_CMPX_F_I64::~Inst_VOPC__V_CMPX_F_I64()
    {
    } // ~Inst_VOPC__V_CMPX_F_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_F_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LT_I64 class methods ---

    Inst_VOPC__V_CMPX_LT_I64::Inst_VOPC__V_CMPX_LT_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_lt_i64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LT_I64

    Inst_VOPC__V_CMPX_LT_I64::~Inst_VOPC__V_CMPX_LT_I64()
    {
    } // ~Inst_VOPC__V_CMPX_LT_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LT_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_EQ_I64 class methods ---

    Inst_VOPC__V_CMPX_EQ_I64::Inst_VOPC__V_CMPX_EQ_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_eq_i64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_EQ_I64

    Inst_VOPC__V_CMPX_EQ_I64::~Inst_VOPC__V_CMPX_EQ_I64()
    {
    } // ~Inst_VOPC__V_CMPX_EQ_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_EQ_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LE_I64 class methods ---

    Inst_VOPC__V_CMPX_LE_I64::Inst_VOPC__V_CMPX_LE_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_le_i64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LE_I64

    Inst_VOPC__V_CMPX_LE_I64::~Inst_VOPC__V_CMPX_LE_I64()
    {
    } // ~Inst_VOPC__V_CMPX_LE_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GT_I64 class methods ---

    Inst_VOPC__V_CMPX_GT_I64::Inst_VOPC__V_CMPX_GT_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_gt_i64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GT_I64

    Inst_VOPC__V_CMPX_GT_I64::~Inst_VOPC__V_CMPX_GT_I64()
    {
    } // ~Inst_VOPC__V_CMPX_GT_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GT_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_NE_I64 class methods ---

    Inst_VOPC__V_CMPX_NE_I64::Inst_VOPC__V_CMPX_NE_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ne_i64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NE_I64

    Inst_VOPC__V_CMPX_NE_I64::~Inst_VOPC__V_CMPX_NE_I64()
    {
    } // ~Inst_VOPC__V_CMPX_NE_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GE_I64 class methods ---

    Inst_VOPC__V_CMPX_GE_I64::Inst_VOPC__V_CMPX_GE_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ge_i64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GE_I64

    Inst_VOPC__V_CMPX_GE_I64::~Inst_VOPC__V_CMPX_GE_I64()
    {
    } // ~Inst_VOPC__V_CMPX_GE_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_T_I64 class methods ---

    Inst_VOPC__V_CMPX_T_I64::Inst_VOPC__V_CMPX_T_I64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_t_i64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_T_I64

    Inst_VOPC__V_CMPX_T_I64::~Inst_VOPC__V_CMPX_T_I64()
    {
    } // ~Inst_VOPC__V_CMPX_T_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_T_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_F_U64 class methods ---

    Inst_VOPC__V_CMPX_F_U64::Inst_VOPC__V_CMPX_F_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_f_u64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_F_U64

    Inst_VOPC__V_CMPX_F_U64::~Inst_VOPC__V_CMPX_F_U64()
    {
    } // ~Inst_VOPC__V_CMPX_F_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_F_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LT_U64 class methods ---

    Inst_VOPC__V_CMPX_LT_U64::Inst_VOPC__V_CMPX_LT_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_lt_u64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LT_U64

    Inst_VOPC__V_CMPX_LT_U64::~Inst_VOPC__V_CMPX_LT_U64()
    {
    } // ~Inst_VOPC__V_CMPX_LT_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LT_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_EQ_U64 class methods ---

    Inst_VOPC__V_CMPX_EQ_U64::Inst_VOPC__V_CMPX_EQ_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_eq_u64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_EQ_U64

    Inst_VOPC__V_CMPX_EQ_U64::~Inst_VOPC__V_CMPX_EQ_U64()
    {
    } // ~Inst_VOPC__V_CMPX_EQ_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_EQ_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_LE_U64 class methods ---

    Inst_VOPC__V_CMPX_LE_U64::Inst_VOPC__V_CMPX_LE_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_le_u64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_LE_U64

    Inst_VOPC__V_CMPX_LE_U64::~Inst_VOPC__V_CMPX_LE_U64()
    {
    } // ~Inst_VOPC__V_CMPX_LE_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_LE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GT_U64 class methods ---

    Inst_VOPC__V_CMPX_GT_U64::Inst_VOPC__V_CMPX_GT_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_gt_u64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GT_U64

    Inst_VOPC__V_CMPX_GT_U64::~Inst_VOPC__V_CMPX_GT_U64()
    {
    } // ~Inst_VOPC__V_CMPX_GT_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GT_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_NE_U64 class methods ---

    Inst_VOPC__V_CMPX_NE_U64::Inst_VOPC__V_CMPX_NE_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ne_u64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_NE_U64

    Inst_VOPC__V_CMPX_NE_U64::~Inst_VOPC__V_CMPX_NE_U64()
    {
    } // ~Inst_VOPC__V_CMPX_NE_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_NE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_GE_U64 class methods ---

    Inst_VOPC__V_CMPX_GE_U64::Inst_VOPC__V_CMPX_GE_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_ge_u64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_GE_U64

    Inst_VOPC__V_CMPX_GE_U64::~Inst_VOPC__V_CMPX_GE_U64()
    {
    } // ~Inst_VOPC__V_CMPX_GE_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_GE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, instData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, instData.VSRC1);
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VOPC__V_CMPX_T_U64 class methods ---

    Inst_VOPC__V_CMPX_T_U64::Inst_VOPC__V_CMPX_T_U64(InFmt_VOPC *iFmt)
        : Inst_VOPC(iFmt, "v_cmpx_t_u64")
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOPC__V_CMPX_T_U64

    Inst_VOPC__V_CMPX_T_U64::~Inst_VOPC__V_CMPX_T_U64()
    {
    } // ~Inst_VOPC__V_CMPX_T_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOPC__V_CMPX_T_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, 1);
            }
        }

        wf->execMask() = vcc.rawData();
        vcc.write();
    } // execute
    // --- Inst_VINTRP__V_INTERP_P1_F32 class methods ---

    Inst_VINTRP__V_INTERP_P1_F32::Inst_VINTRP__V_INTERP_P1_F32(
          InFmt_VINTRP *iFmt)
        : Inst_VINTRP(iFmt, "v_interp_p1_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VINTRP__V_INTERP_P1_F32

    Inst_VINTRP__V_INTERP_P1_F32::~Inst_VINTRP__V_INTERP_P1_F32()
    {
    } // ~Inst_VINTRP__V_INTERP_P1_F32

    // --- description from .arch file ---
    // D.f = P10 * S.f + P0; parameter interpolation (SQ translates to
    // V_MAD_F32 for SP).
    // CAUTION: when in HALF_LDS mode, D must not be the same GPR as S;
    // if D == S then data corruption will occur.
    // NOTE: In textual representations the I/J VGPR is the first source and
    // the attribute is the second source; however in the VOP3 encoding the
    // attribute is stored in the src0 field and the VGPR is stored in the
    // src1 field.
    void
    Inst_VINTRP__V_INTERP_P1_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VINTRP__V_INTERP_P2_F32 class methods ---

    Inst_VINTRP__V_INTERP_P2_F32::Inst_VINTRP__V_INTERP_P2_F32(
          InFmt_VINTRP *iFmt)
        : Inst_VINTRP(iFmt, "v_interp_p2_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VINTRP__V_INTERP_P2_F32

    Inst_VINTRP__V_INTERP_P2_F32::~Inst_VINTRP__V_INTERP_P2_F32()
    {
    } // ~Inst_VINTRP__V_INTERP_P2_F32

    // --- description from .arch file ---
    // D.f = P20 * S.f + D.f; parameter interpolation (SQ translates to
    // V_MAD_F32 for SP).
    // NOTE: In textual representations the I/J VGPR is the first source and
    // the attribute is the second source; however in the VOP3 encoding the
    // attribute is stored in the src0 field and the VGPR is stored in the
    // src1 field.
    void
    Inst_VINTRP__V_INTERP_P2_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VINTRP__V_INTERP_MOV_F32 class methods ---

    Inst_VINTRP__V_INTERP_MOV_F32::Inst_VINTRP__V_INTERP_MOV_F32(
          InFmt_VINTRP *iFmt)
        : Inst_VINTRP(iFmt, "v_interp_mov_f32")
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VINTRP__V_INTERP_MOV_F32

    Inst_VINTRP__V_INTERP_MOV_F32::~Inst_VINTRP__V_INTERP_MOV_F32()
    {
    } // ~Inst_VINTRP__V_INTERP_MOV_F32

    // --- description from .arch file ---
    // D.f = {P10,P20,P0}[S.u]; parameter load.
    void
    Inst_VINTRP__V_INTERP_MOV_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_CLASS_F32 class methods ---

    Inst_VOP3__V_CMP_CLASS_F32::Inst_VOP3__V_CMP_CLASS_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_class_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_CLASS_F32

    Inst_VOP3__V_CMP_CLASS_F32::~Inst_VOP3__V_CMP_CLASS_F32()
    {
    } // ~Inst_VOP3__V_CMP_CLASS_F32

    // --- description from .arch file ---
    // VCC = IEEE numeric class function specified in S1.u, performed on S0.f
    // The function reports true if the floating point value is *any* of the
    // ---  numeric types selected in S1.u according to the following list:
    // S1.u[0] -- value is a signaling NaN.
    // S1.u[1] -- value is a quiet NaN.
    // S1.u[2] -- value is negative infinity.
    // S1.u[3] -- value is a negative normal value.
    // S1.u[4] -- value is a negative denormal value.
    // S1.u[5] -- value is negative zero.
    // S1.u[6] -- value is positive zero.
    // S1.u[7] -- value is a positive denormal value.
    // S1.u[8] -- value is a positive normal value.
    // S1.u[9] -- value is positive infinity.
    void
    Inst_VOP3__V_CMP_CLASS_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (bits(src1[lane], 0) || bits(src1[lane], 1)) {
                    // is NaN
                    if (std::isnan(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 2)) {
                    // is -infinity
                    if (std::isinf(src0[lane]) && std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 3)) {
                    // is -normal
                    if (std::isnormal(src0[lane])
                        && std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 4)) {
                    // is -denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 5)) {
                    // is -zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 6)) {
                    // is +zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 7)) {
                    // is +denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 8)) {
                    // is +normal
                    if (std::isnormal(src0[lane])
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 9)) {
                    // is +infinity
                    if (std::isinf(src0[lane])
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_CLASS_F32 class methods ---

    Inst_VOP3__V_CMPX_CLASS_F32::Inst_VOP3__V_CMPX_CLASS_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_class_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_CLASS_F32

    Inst_VOP3__V_CMPX_CLASS_F32::~Inst_VOP3__V_CMPX_CLASS_F32()
    {
    } // ~Inst_VOP3__V_CMPX_CLASS_F32

    // --- description from .arch file ---
    // EXEC, VCC = IEEE numeric class function specified in S1.u, performed on
    // S0.f
    // The function reports true if the floating point value is *any* of the
    // numeric types selected in S1.u according to the following list:
    // S1.u[0] -- value is a signaling NaN.
    // S1.u[1] -- value is a quiet NaN.
    // S1.u[2] -- value is negative infinity.
    // S1.u[3] -- value is a negative normal value.
    // S1.u[4] -- value is a negative denormal value.
    // S1.u[5] -- value is negative zero.
    // S1.u[6] -- value is positive zero.
    // S1.u[7] -- value is a positive denormal value.
    // S1.u[8] -- value is a positive normal value.
    // S1.u[9] -- value is positive infinity.
    void
    Inst_VOP3__V_CMPX_CLASS_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (bits(src1[lane], 0) || bits(src1[lane], 1)) {
                    // is NaN
                    if (std::isnan(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 2)) {
                    // is -infinity
                    if (std::isinf(src0[lane]) && std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 3)) {
                    // is -normal
                    if (std::isnormal(src0[lane])
                        && std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 4)) {
                    // is -denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 5)) {
                    // is -zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 6)) {
                    // is +zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 7)) {
                    // is +denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 8)) {
                    // is +normal
                    if (std::isnormal(src0[lane])
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
                if (bits(src1[lane], 9)) {
                    // is +infinity
                    if (std::isinf(src0[lane])
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane,  1);
                        continue;
                    }
                }
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_CLASS_F64 class methods ---

    Inst_VOP3__V_CMP_CLASS_F64::Inst_VOP3__V_CMP_CLASS_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_class_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_CLASS_F64

    Inst_VOP3__V_CMP_CLASS_F64::~Inst_VOP3__V_CMP_CLASS_F64()
    {
    } // ~Inst_VOP3__V_CMP_CLASS_F64

    // --- description from .arch file ---
    // VCC = IEEE numeric class function specified in S1.u, performed on S0.d
    // The function reports true if the floating point value is *any* of the
    // ---  numeric types selected in S1.u according to the following list:
    // S1.u[0] -- value is a signaling NaN.
    // S1.u[1] -- value is a quiet NaN.
    // S1.u[2] -- value is negative infinity.
    // S1.u[3] -- value is a negative normal value.
    // S1.u[4] -- value is a negative denormal value.
    // S1.u[5] -- value is negative zero.
    // S1.u[6] -- value is positive zero.
    // S1.u[7] -- value is a positive denormal value.
    // S1.u[8] -- value is a positive normal value.
    // S1.u[9] -- value is positive infinity.
    void
    Inst_VOP3__V_CMP_CLASS_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (bits(src1[lane], 0) || bits(src1[lane], 1)) {
                    // is NaN
                    if (std::isnan(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 2)) {
                    // is -infinity
                    if (std::isinf(src0[lane]) && std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 3)) {
                    // is -normal
                    if (std::isnormal(src0[lane])
                        && std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 4)) {
                    // is -denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 5)) {
                    // is -zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 6)) {
                    // is +zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 7)) {
                    // is +denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 8)) {
                    // is +normal
                    if (std::isnormal(src0[lane])
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 9)) {
                    // is +infinity
                    if (std::isinf(src0[lane])
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_CLASS_F64 class methods ---

    Inst_VOP3__V_CMPX_CLASS_F64::Inst_VOP3__V_CMPX_CLASS_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_class_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_CLASS_F64

    Inst_VOP3__V_CMPX_CLASS_F64::~Inst_VOP3__V_CMPX_CLASS_F64()
    {
    } // ~Inst_VOP3__V_CMPX_CLASS_F64

    // --- description from .arch file ---
    // EXEC, VCC = IEEE numeric class function specified in S1.u, performed on
    // S0.d
    // The function reports true if the floating point value is *any* of the
    // numeric types selected in S1.u according to the following list:
    // S1.u[0] -- value is a signaling NaN.
    // S1.u[1] -- value is a quiet NaN.
    // S1.u[2] -- value is negative infinity.
    // S1.u[3] -- value is a negative normal value.
    // S1.u[4] -- value is a negative denormal value.
    // S1.u[5] -- value is negative zero.
    // S1.u[6] -- value is positive zero.
    // S1.u[7] -- value is a positive denormal value.
    // S1.u[8] -- value is a positive normal value.
    // S1.u[9] -- value is positive infinity.
    void
    Inst_VOP3__V_CMPX_CLASS_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (bits(src1[lane], 0) || bits(src1[lane], 1)) {
                    // is NaN
                    if (std::isnan(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 2)) {
                    // is -infinity
                    if (std::isinf(src0[lane]) && std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 3)) {
                    // is -normal
                    if (std::isnormal(src0[lane])
                        && std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 4)) {
                    // is -denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 5)) {
                    // is -zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 6)) {
                    // is +zero
                    if (std::fpclassify(src0[lane]) == FP_ZERO
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 7)) {
                    // is +denormal
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 8)) {
                    // is +normal
                    if (std::isnormal(src0[lane])
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
                if (bits(src1[lane], 9)) {
                    // is +infinity
                    if (std::isinf(src0[lane])
                        && !std::signbit(src0[lane])) {
                        sdst.setBit(lane, 1);
                        continue;
                    }
                }
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_CLASS_F16 class methods ---

    Inst_VOP3__V_CMP_CLASS_F16::Inst_VOP3__V_CMP_CLASS_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_class_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_CLASS_F16

    Inst_VOP3__V_CMP_CLASS_F16::~Inst_VOP3__V_CMP_CLASS_F16()
    {
    } // ~Inst_VOP3__V_CMP_CLASS_F16

    // --- description from .arch file ---
    // VCC = IEEE numeric class function specified in S1.u, performed on S0.f16
    // The function reports true if the floating point value is *any* of the
    // ---  numeric types selected in S1.u according to the following list:
    // S1.u[0] -- value is a signaling NaN.
    // S1.u[1] -- value is a quiet NaN.
    // S1.u[2] -- value is negative infinity.
    // S1.u[3] -- value is a negative normal value.
    // S1.u[4] -- value is a negative denormal value.
    // S1.u[5] -- value is negative zero.
    // S1.u[6] -- value is positive zero.
    // S1.u[7] -- value is a positive denormal value.
    // S1.u[8] -- value is a positive normal value.
    // S1.u[9] -- value is positive infinity.
    void
    Inst_VOP3__V_CMP_CLASS_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_CLASS_F16 class methods ---

    Inst_VOP3__V_CMPX_CLASS_F16::Inst_VOP3__V_CMPX_CLASS_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_class_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_CLASS_F16

    Inst_VOP3__V_CMPX_CLASS_F16::~Inst_VOP3__V_CMPX_CLASS_F16()
    {
    } // ~Inst_VOP3__V_CMPX_CLASS_F16

    // --- description from .arch file ---
    // EXEC, VCC = IEEE numeric class function specified in S1.u, performed on
    // ---  S0.f16
    // The function reports true if the floating point value is *any* of the
    // ---  numeric types selected in S1.u according to the following list:
    // S1.u[0] -- value is a signaling NaN.
    // S1.u[1] -- value is a quiet NaN.
    // S1.u[2] -- value is negative infinity.
    // S1.u[3] -- value is a negative normal value.
    // S1.u[4] -- value is a negative denormal value.
    // S1.u[5] -- value is negative zero.
    // S1.u[6] -- value is positive zero.
    // S1.u[7] -- value is a positive denormal value.
    // S1.u[8] -- value is a positive normal value.
    // S1.u[9] -- value is positive infinity.
    void
    Inst_VOP3__V_CMPX_CLASS_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_F_F16 class methods ---

    Inst_VOP3__V_CMP_F_F16::Inst_VOP3__V_CMP_F_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_f_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_F_F16

    Inst_VOP3__V_CMP_F_F16::~Inst_VOP3__V_CMP_F_F16()
    {
    } // ~Inst_VOP3__V_CMP_F_F16

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_F_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_LT_F16 class methods ---

    Inst_VOP3__V_CMP_LT_F16::Inst_VOP3__V_CMP_LT_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_lt_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_LT_F16

    Inst_VOP3__V_CMP_LT_F16::~Inst_VOP3__V_CMP_LT_F16()
    {
    } // ~Inst_VOP3__V_CMP_LT_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_EQ_F16 class methods ---

    Inst_VOP3__V_CMP_EQ_F16::Inst_VOP3__V_CMP_EQ_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_eq_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_EQ_F16

    Inst_VOP3__V_CMP_EQ_F16::~Inst_VOP3__V_CMP_EQ_F16()
    {
    } // ~Inst_VOP3__V_CMP_EQ_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_EQ_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_LE_F16 class methods ---

    Inst_VOP3__V_CMP_LE_F16::Inst_VOP3__V_CMP_LE_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_le_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_LE_F16

    Inst_VOP3__V_CMP_LE_F16::~Inst_VOP3__V_CMP_LE_F16()
    {
    } // ~Inst_VOP3__V_CMP_LE_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_GT_F16 class methods ---

    Inst_VOP3__V_CMP_GT_F16::Inst_VOP3__V_CMP_GT_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_gt_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_GT_F16

    Inst_VOP3__V_CMP_GT_F16::~Inst_VOP3__V_CMP_GT_F16()
    {
    } // ~Inst_VOP3__V_CMP_GT_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_LG_F16 class methods ---

    Inst_VOP3__V_CMP_LG_F16::Inst_VOP3__V_CMP_LG_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_lg_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_LG_F16

    Inst_VOP3__V_CMP_LG_F16::~Inst_VOP3__V_CMP_LG_F16()
    {
    } // ~Inst_VOP3__V_CMP_LG_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LG_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_GE_F16 class methods ---

    Inst_VOP3__V_CMP_GE_F16::Inst_VOP3__V_CMP_GE_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ge_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_GE_F16

    Inst_VOP3__V_CMP_GE_F16::~Inst_VOP3__V_CMP_GE_F16()
    {
    } // ~Inst_VOP3__V_CMP_GE_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_O_F16 class methods ---

    Inst_VOP3__V_CMP_O_F16::Inst_VOP3__V_CMP_O_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_o_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_O_F16

    Inst_VOP3__V_CMP_O_F16::~Inst_VOP3__V_CMP_O_F16()
    {
    } // ~Inst_VOP3__V_CMP_O_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (!isNan(S0) && !isNan(S1)); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_O_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_U_F16 class methods ---

    Inst_VOP3__V_CMP_U_F16::Inst_VOP3__V_CMP_U_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_u_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_U_F16

    Inst_VOP3__V_CMP_U_F16::~Inst_VOP3__V_CMP_U_F16()
    {
    } // ~Inst_VOP3__V_CMP_U_F16

    // --- description from .arch file ---
    // D.u64[threadID] = (isNan(S0)  ||  isNan(S1)); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_U_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_NGE_F16 class methods ---

    Inst_VOP3__V_CMP_NGE_F16::Inst_VOP3__V_CMP_NGE_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_nge_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_NGE_F16

    Inst_VOP3__V_CMP_NGE_F16::~Inst_VOP3__V_CMP_NGE_F16()
    {
    } // ~Inst_VOP3__V_CMP_NGE_F16

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NGE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_NLG_F16 class methods ---

    Inst_VOP3__V_CMP_NLG_F16::Inst_VOP3__V_CMP_NLG_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_nlg_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_NLG_F16

    Inst_VOP3__V_CMP_NLG_F16::~Inst_VOP3__V_CMP_NLG_F16()
    {
    } // ~Inst_VOP3__V_CMP_NLG_F16

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NLG_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_NGT_F16 class methods ---

    Inst_VOP3__V_CMP_NGT_F16::Inst_VOP3__V_CMP_NGT_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ngt_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_NGT_F16

    Inst_VOP3__V_CMP_NGT_F16::~Inst_VOP3__V_CMP_NGT_F16()
    {
    } // ~Inst_VOP3__V_CMP_NGT_F16

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NGT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_NLE_F16 class methods ---

    Inst_VOP3__V_CMP_NLE_F16::Inst_VOP3__V_CMP_NLE_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_nle_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_NLE_F16

    Inst_VOP3__V_CMP_NLE_F16::~Inst_VOP3__V_CMP_NLE_F16()
    {
    } // ~Inst_VOP3__V_CMP_NLE_F16

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NLE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_NEQ_F16 class methods ---

    Inst_VOP3__V_CMP_NEQ_F16::Inst_VOP3__V_CMP_NEQ_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_neq_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_NEQ_F16

    Inst_VOP3__V_CMP_NEQ_F16::~Inst_VOP3__V_CMP_NEQ_F16()
    {
    } // ~Inst_VOP3__V_CMP_NEQ_F16

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NEQ_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_NLT_F16 class methods ---

    Inst_VOP3__V_CMP_NLT_F16::Inst_VOP3__V_CMP_NLT_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_nlt_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_NLT_F16

    Inst_VOP3__V_CMP_NLT_F16::~Inst_VOP3__V_CMP_NLT_F16()
    {
    } // ~Inst_VOP3__V_CMP_NLT_F16

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NLT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMP_TRU_F16 class methods ---

    Inst_VOP3__V_CMP_TRU_F16::Inst_VOP3__V_CMP_TRU_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_tru_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CMP_TRU_F16

    Inst_VOP3__V_CMP_TRU_F16::~Inst_VOP3__V_CMP_TRU_F16()
    {
    } // ~Inst_VOP3__V_CMP_TRU_F16

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_TRU_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_F_F16 class methods ---

    Inst_VOP3__V_CMPX_F_F16::Inst_VOP3__V_CMPX_F_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_f_f16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_F_F16

    Inst_VOP3__V_CMPX_F_F16::~Inst_VOP3__V_CMPX_F_F16()
    {
    } // ~Inst_VOP3__V_CMPX_F_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_F_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LT_F16 class methods ---

    Inst_VOP3__V_CMPX_LT_F16::Inst_VOP3__V_CMPX_LT_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_lt_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LT_F16

    Inst_VOP3__V_CMPX_LT_F16::~Inst_VOP3__V_CMPX_LT_F16()
    {
    } // ~Inst_VOP3__V_CMPX_LT_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_EQ_F16 class methods ---

    Inst_VOP3__V_CMPX_EQ_F16::Inst_VOP3__V_CMPX_EQ_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_eq_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_EQ_F16

    Inst_VOP3__V_CMPX_EQ_F16::~Inst_VOP3__V_CMPX_EQ_F16()
    {
    } // ~Inst_VOP3__V_CMPX_EQ_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_EQ_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_LE_F16 class methods ---

    Inst_VOP3__V_CMPX_LE_F16::Inst_VOP3__V_CMPX_LE_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_le_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LE_F16

    Inst_VOP3__V_CMPX_LE_F16::~Inst_VOP3__V_CMPX_LE_F16()
    {
    } // ~Inst_VOP3__V_CMPX_LE_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_GT_F16 class methods ---

    Inst_VOP3__V_CMPX_GT_F16::Inst_VOP3__V_CMPX_GT_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_gt_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GT_F16

    Inst_VOP3__V_CMPX_GT_F16::~Inst_VOP3__V_CMPX_GT_F16()
    {
    } // ~Inst_VOP3__V_CMPX_GT_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_LG_F16 class methods ---

    Inst_VOP3__V_CMPX_LG_F16::Inst_VOP3__V_CMPX_LG_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_lg_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LG_F16

    Inst_VOP3__V_CMPX_LG_F16::~Inst_VOP3__V_CMPX_LG_F16()
    {
    } // ~Inst_VOP3__V_CMPX_LG_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LG_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_GE_F16 class methods ---

    Inst_VOP3__V_CMPX_GE_F16::Inst_VOP3__V_CMPX_GE_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ge_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GE_F16

    Inst_VOP3__V_CMPX_GE_F16::~Inst_VOP3__V_CMPX_GE_F16()
    {
    } // ~Inst_VOP3__V_CMPX_GE_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_O_F16 class methods ---

    Inst_VOP3__V_CMPX_O_F16::Inst_VOP3__V_CMPX_O_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_o_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_O_F16

    Inst_VOP3__V_CMPX_O_F16::~Inst_VOP3__V_CMPX_O_F16()
    {
    } // ~Inst_VOP3__V_CMPX_O_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (!isNan(S0) && !isNan(S1)); D = VCC in VOPC
    // encoding.
    void
    Inst_VOP3__V_CMPX_O_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_U_F16 class methods ---

    Inst_VOP3__V_CMPX_U_F16::Inst_VOP3__V_CMPX_U_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_u_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_U_F16

    Inst_VOP3__V_CMPX_U_F16::~Inst_VOP3__V_CMPX_U_F16()
    {
    } // ~Inst_VOP3__V_CMPX_U_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (isNan(S0)  ||  isNan(S1)); D = VCC in VOPC
    // encoding.
    void
    Inst_VOP3__V_CMPX_U_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_NGE_F16 class methods ---

    Inst_VOP3__V_CMPX_NGE_F16::Inst_VOP3__V_CMPX_NGE_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_nge_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NGE_F16

    Inst_VOP3__V_CMPX_NGE_F16::~Inst_VOP3__V_CMPX_NGE_F16()
    {
    } // ~Inst_VOP3__V_CMPX_NGE_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NGE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_NLG_F16 class methods ---

    Inst_VOP3__V_CMPX_NLG_F16::Inst_VOP3__V_CMPX_NLG_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_nlg_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NLG_F16

    Inst_VOP3__V_CMPX_NLG_F16::~Inst_VOP3__V_CMPX_NLG_F16()
    {
    } // ~Inst_VOP3__V_CMPX_NLG_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NLG_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_NGT_F16 class methods ---

    Inst_VOP3__V_CMPX_NGT_F16::Inst_VOP3__V_CMPX_NGT_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ngt_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NGT_F16

    Inst_VOP3__V_CMPX_NGT_F16::~Inst_VOP3__V_CMPX_NGT_F16()
    {
    } // ~Inst_VOP3__V_CMPX_NGT_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NGT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_NLE_F16 class methods ---

    Inst_VOP3__V_CMPX_NLE_F16::Inst_VOP3__V_CMPX_NLE_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_nle_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NLE_F16

    Inst_VOP3__V_CMPX_NLE_F16::~Inst_VOP3__V_CMPX_NLE_F16()
    {
    } // ~Inst_VOP3__V_CMPX_NLE_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NLE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_NEQ_F16 class methods ---

    Inst_VOP3__V_CMPX_NEQ_F16::Inst_VOP3__V_CMPX_NEQ_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_neq_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NEQ_F16

    Inst_VOP3__V_CMPX_NEQ_F16::~Inst_VOP3__V_CMPX_NEQ_F16()
    {
    } // ~Inst_VOP3__V_CMPX_NEQ_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NEQ_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_NLT_F16 class methods ---

    Inst_VOP3__V_CMPX_NLT_F16::Inst_VOP3__V_CMPX_NLT_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_nlt_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NLT_F16

    Inst_VOP3__V_CMPX_NLT_F16::~Inst_VOP3__V_CMPX_NLT_F16()
    {
    } // ~Inst_VOP3__V_CMPX_NLT_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NLT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CMPX_TRU_F16 class methods ---

    Inst_VOP3__V_CMPX_TRU_F16::Inst_VOP3__V_CMPX_TRU_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_tru_f16", true)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_TRU_F16

    Inst_VOP3__V_CMPX_TRU_F16::~Inst_VOP3__V_CMPX_TRU_F16()
    {
    } // ~Inst_VOP3__V_CMPX_TRU_F16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_TRU_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_F_F32 class methods ---

    Inst_VOP3__V_CMP_F_F32::Inst_VOP3__V_CMP_F_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_f_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_F_F32

    Inst_VOP3__V_CMP_F_F32::~Inst_VOP3__V_CMP_F_F32()
    {
    } // ~Inst_VOP3__V_CMP_F_F32

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_F_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LT_F32 class methods ---

    Inst_VOP3__V_CMP_LT_F32::Inst_VOP3__V_CMP_LT_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_lt_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_LT_F32

    Inst_VOP3__V_CMP_LT_F32::~Inst_VOP3__V_CMP_LT_F32()
    {
    } // ~Inst_VOP3__V_CMP_LT_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_EQ_F32 class methods ---

    Inst_VOP3__V_CMP_EQ_F32::Inst_VOP3__V_CMP_EQ_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_eq_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_EQ_F32

    Inst_VOP3__V_CMP_EQ_F32::~Inst_VOP3__V_CMP_EQ_F32()
    {
    } // ~Inst_VOP3__V_CMP_EQ_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_EQ_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LE_F32 class methods ---

    Inst_VOP3__V_CMP_LE_F32::Inst_VOP3__V_CMP_LE_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_le_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_LE_F32

    Inst_VOP3__V_CMP_LE_F32::~Inst_VOP3__V_CMP_LE_F32()
    {
    } // ~Inst_VOP3__V_CMP_LE_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GT_F32 class methods ---

    Inst_VOP3__V_CMP_GT_F32::Inst_VOP3__V_CMP_GT_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_gt_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_GT_F32

    Inst_VOP3__V_CMP_GT_F32::~Inst_VOP3__V_CMP_GT_F32()
    {
    } // ~Inst_VOP3__V_CMP_GT_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LG_F32 class methods ---

    Inst_VOP3__V_CMP_LG_F32::Inst_VOP3__V_CMP_LG_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_lg_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_LG_F32

    Inst_VOP3__V_CMP_LG_F32::~Inst_VOP3__V_CMP_LG_F32()
    {
    } // ~Inst_VOP3__V_CMP_LG_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LG_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GE_F32 class methods ---

    Inst_VOP3__V_CMP_GE_F32::Inst_VOP3__V_CMP_GE_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ge_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_GE_F32

    Inst_VOP3__V_CMP_GE_F32::~Inst_VOP3__V_CMP_GE_F32()
    {
    } // ~Inst_VOP3__V_CMP_GE_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_O_F32 class methods ---

    Inst_VOP3__V_CMP_O_F32::Inst_VOP3__V_CMP_O_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_o_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_O_F32

    Inst_VOP3__V_CMP_O_F32::~Inst_VOP3__V_CMP_O_F32()
    {
    } // ~Inst_VOP3__V_CMP_O_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (!isNan(S0) && !isNan(S1)); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_O_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, (!std::isnan(src0[lane])
                    && !std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_U_F32 class methods ---

    Inst_VOP3__V_CMP_U_F32::Inst_VOP3__V_CMP_U_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_u_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_U_F32

    Inst_VOP3__V_CMP_U_F32::~Inst_VOP3__V_CMP_U_F32()
    {
    } // ~Inst_VOP3__V_CMP_U_F32

    // --- description from .arch file ---
    // D.u64[threadID] = (isNan(S0)  ||  isNan(S1)); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_U_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, (std::isnan(src0[lane])
                    || std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NGE_F32 class methods ---

    Inst_VOP3__V_CMP_NGE_F32::Inst_VOP3__V_CMP_NGE_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_nge_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_NGE_F32

    Inst_VOP3__V_CMP_NGE_F32::~Inst_VOP3__V_CMP_NGE_F32()
    {
    } // ~Inst_VOP3__V_CMP_NGE_F32

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NGE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] >= src1[lane]) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NLG_F32 class methods ---

    Inst_VOP3__V_CMP_NLG_F32::Inst_VOP3__V_CMP_NLG_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_nlg_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_NLG_F32

    Inst_VOP3__V_CMP_NLG_F32::~Inst_VOP3__V_CMP_NLG_F32()
    {
    } // ~Inst_VOP3__V_CMP_NLG_F32

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NLG_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NGT_F32 class methods ---

    Inst_VOP3__V_CMP_NGT_F32::Inst_VOP3__V_CMP_NGT_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ngt_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_NGT_F32

    Inst_VOP3__V_CMP_NGT_F32::~Inst_VOP3__V_CMP_NGT_F32()
    {
    } // ~Inst_VOP3__V_CMP_NGT_F32

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NGT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NLE_F32 class methods ---

    Inst_VOP3__V_CMP_NLE_F32::Inst_VOP3__V_CMP_NLE_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_nle_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_NLE_F32

    Inst_VOP3__V_CMP_NLE_F32::~Inst_VOP3__V_CMP_NLE_F32()
    {
    } // ~Inst_VOP3__V_CMP_NLE_F32

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NLE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] <= src1[lane]) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NEQ_F32 class methods ---

    Inst_VOP3__V_CMP_NEQ_F32::Inst_VOP3__V_CMP_NEQ_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_neq_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_NEQ_F32

    Inst_VOP3__V_CMP_NEQ_F32::~Inst_VOP3__V_CMP_NEQ_F32()
    {
    } // ~Inst_VOP3__V_CMP_NEQ_F32

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NEQ_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NLT_F32 class methods ---

    Inst_VOP3__V_CMP_NLT_F32::Inst_VOP3__V_CMP_NLT_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_nlt_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_NLT_F32

    Inst_VOP3__V_CMP_NLT_F32::~Inst_VOP3__V_CMP_NLT_F32()
    {
    } // ~Inst_VOP3__V_CMP_NLT_F32

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NLT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] < src1[lane]) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_TRU_F32 class methods ---

    Inst_VOP3__V_CMP_TRU_F32::Inst_VOP3__V_CMP_TRU_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_tru_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CMP_TRU_F32

    Inst_VOP3__V_CMP_TRU_F32::~Inst_VOP3__V_CMP_TRU_F32()
    {
    } // ~Inst_VOP3__V_CMP_TRU_F32

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_TRU_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_F_F32 class methods ---

    Inst_VOP3__V_CMPX_F_F32::Inst_VOP3__V_CMPX_F_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_f_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_F_F32

    Inst_VOP3__V_CMPX_F_F32::~Inst_VOP3__V_CMPX_F_F32()
    {
    } // ~Inst_VOP3__V_CMPX_F_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_F_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LT_F32 class methods ---

    Inst_VOP3__V_CMPX_LT_F32::Inst_VOP3__V_CMPX_LT_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_lt_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LT_F32

    Inst_VOP3__V_CMPX_LT_F32::~Inst_VOP3__V_CMPX_LT_F32()
    {
    } // ~Inst_VOP3__V_CMPX_LT_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_EQ_F32 class methods ---

    Inst_VOP3__V_CMPX_EQ_F32::Inst_VOP3__V_CMPX_EQ_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_eq_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_EQ_F32

    Inst_VOP3__V_CMPX_EQ_F32::~Inst_VOP3__V_CMPX_EQ_F32()
    {
    } // ~Inst_VOP3__V_CMPX_EQ_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_EQ_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LE_F32 class methods ---

    Inst_VOP3__V_CMPX_LE_F32::Inst_VOP3__V_CMPX_LE_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_le_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LE_F32

    Inst_VOP3__V_CMPX_LE_F32::~Inst_VOP3__V_CMPX_LE_F32()
    {
    } // ~Inst_VOP3__V_CMPX_LE_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GT_F32 class methods ---

    Inst_VOP3__V_CMPX_GT_F32::Inst_VOP3__V_CMPX_GT_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_gt_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GT_F32

    Inst_VOP3__V_CMPX_GT_F32::~Inst_VOP3__V_CMPX_GT_F32()
    {
    } // ~Inst_VOP3__V_CMPX_GT_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LG_F32 class methods ---

    Inst_VOP3__V_CMPX_LG_F32::Inst_VOP3__V_CMPX_LG_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_lg_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LG_F32

    Inst_VOP3__V_CMPX_LG_F32::~Inst_VOP3__V_CMPX_LG_F32()
    {
    } // ~Inst_VOP3__V_CMPX_LG_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LG_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, (src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GE_F32 class methods ---

    Inst_VOP3__V_CMPX_GE_F32::Inst_VOP3__V_CMPX_GE_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ge_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GE_F32

    Inst_VOP3__V_CMPX_GE_F32::~Inst_VOP3__V_CMPX_GE_F32()
    {
    } // ~Inst_VOP3__V_CMPX_GE_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_O_F32 class methods ---

    Inst_VOP3__V_CMPX_O_F32::Inst_VOP3__V_CMPX_O_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_o_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_O_F32

    Inst_VOP3__V_CMPX_O_F32::~Inst_VOP3__V_CMPX_O_F32()
    {
    } // ~Inst_VOP3__V_CMPX_O_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (!isNan(S0) && !isNan(S1)); D = VCC in VOPC
    // encoding.
    void
    Inst_VOP3__V_CMPX_O_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, (!std::isnan(src0[lane])
                    && !std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_U_F32 class methods ---

    Inst_VOP3__V_CMPX_U_F32::Inst_VOP3__V_CMPX_U_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_u_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_U_F32

    Inst_VOP3__V_CMPX_U_F32::~Inst_VOP3__V_CMPX_U_F32()
    {
    } // ~Inst_VOP3__V_CMPX_U_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (isNan(S0)  ||  isNan(S1)); D = VCC in VOPC
    // encoding.
    void
    Inst_VOP3__V_CMPX_U_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, (std::isnan(src0[lane])
                        || std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NGE_F32 class methods ---

    Inst_VOP3__V_CMPX_NGE_F32::Inst_VOP3__V_CMPX_NGE_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_nge_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NGE_F32

    Inst_VOP3__V_CMPX_NGE_F32::~Inst_VOP3__V_CMPX_NGE_F32()
    {
    } // ~Inst_VOP3__V_CMPX_NGE_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NGE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] >= src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NLG_F32 class methods ---

    Inst_VOP3__V_CMPX_NLG_F32::Inst_VOP3__V_CMPX_NLG_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_nlg_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NLG_F32

    Inst_VOP3__V_CMPX_NLG_F32::~Inst_VOP3__V_CMPX_NLG_F32()
    {
    } // ~Inst_VOP3__V_CMPX_NLG_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NLG_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NGT_F32 class methods ---

    Inst_VOP3__V_CMPX_NGT_F32::Inst_VOP3__V_CMPX_NGT_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ngt_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NGT_F32

    Inst_VOP3__V_CMPX_NGT_F32::~Inst_VOP3__V_CMPX_NGT_F32()
    {
    } // ~Inst_VOP3__V_CMPX_NGT_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NGT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NLE_F32 class methods ---

    Inst_VOP3__V_CMPX_NLE_F32::Inst_VOP3__V_CMPX_NLE_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_nle_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NLE_F32

    Inst_VOP3__V_CMPX_NLE_F32::~Inst_VOP3__V_CMPX_NLE_F32()
    {
    } // ~Inst_VOP3__V_CMPX_NLE_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NLE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] <= src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NEQ_F32 class methods ---

    Inst_VOP3__V_CMPX_NEQ_F32::Inst_VOP3__V_CMPX_NEQ_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_neq_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NEQ_F32

    Inst_VOP3__V_CMPX_NEQ_F32::~Inst_VOP3__V_CMPX_NEQ_F32()
    {
    } // ~Inst_VOP3__V_CMPX_NEQ_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NEQ_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NLT_F32 class methods ---

    Inst_VOP3__V_CMPX_NLT_F32::Inst_VOP3__V_CMPX_NLT_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_nlt_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NLT_F32

    Inst_VOP3__V_CMPX_NLT_F32::~Inst_VOP3__V_CMPX_NLT_F32()
    {
    } // ~Inst_VOP3__V_CMPX_NLT_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NLT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] < src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_TRU_F32 class methods ---

    Inst_VOP3__V_CMPX_TRU_F32::Inst_VOP3__V_CMPX_TRU_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_tru_f32", true)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_TRU_F32

    Inst_VOP3__V_CMPX_TRU_F32::~Inst_VOP3__V_CMPX_TRU_F32()
    {
    } // ~Inst_VOP3__V_CMPX_TRU_F32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_TRU_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_F_F64 class methods ---

    Inst_VOP3__V_CMP_F_F64::Inst_VOP3__V_CMP_F_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_f_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_F_F64

    Inst_VOP3__V_CMP_F_F64::~Inst_VOP3__V_CMP_F_F64()
    {
    } // ~Inst_VOP3__V_CMP_F_F64

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_F_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LT_F64 class methods ---

    Inst_VOP3__V_CMP_LT_F64::Inst_VOP3__V_CMP_LT_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_lt_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_LT_F64

    Inst_VOP3__V_CMP_LT_F64::~Inst_VOP3__V_CMP_LT_F64()
    {
    } // ~Inst_VOP3__V_CMP_LT_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_EQ_F64 class methods ---

    Inst_VOP3__V_CMP_EQ_F64::Inst_VOP3__V_CMP_EQ_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_eq_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_EQ_F64

    Inst_VOP3__V_CMP_EQ_F64::~Inst_VOP3__V_CMP_EQ_F64()
    {
    } // ~Inst_VOP3__V_CMP_EQ_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_EQ_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LE_F64 class methods ---

    Inst_VOP3__V_CMP_LE_F64::Inst_VOP3__V_CMP_LE_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_le_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_LE_F64

    Inst_VOP3__V_CMP_LE_F64::~Inst_VOP3__V_CMP_LE_F64()
    {
    } // ~Inst_VOP3__V_CMP_LE_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GT_F64 class methods ---

    Inst_VOP3__V_CMP_GT_F64::Inst_VOP3__V_CMP_GT_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_gt_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_GT_F64

    Inst_VOP3__V_CMP_GT_F64::~Inst_VOP3__V_CMP_GT_F64()
    {
    } // ~Inst_VOP3__V_CMP_GT_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LG_F64 class methods ---

    Inst_VOP3__V_CMP_LG_F64::Inst_VOP3__V_CMP_LG_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_lg_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_LG_F64

    Inst_VOP3__V_CMP_LG_F64::~Inst_VOP3__V_CMP_LG_F64()
    {
    } // ~Inst_VOP3__V_CMP_LG_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LG_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, (src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GE_F64 class methods ---

    Inst_VOP3__V_CMP_GE_F64::Inst_VOP3__V_CMP_GE_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ge_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_GE_F64

    Inst_VOP3__V_CMP_GE_F64::~Inst_VOP3__V_CMP_GE_F64()
    {
    } // ~Inst_VOP3__V_CMP_GE_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_O_F64 class methods ---

    Inst_VOP3__V_CMP_O_F64::Inst_VOP3__V_CMP_O_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_o_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_O_F64

    Inst_VOP3__V_CMP_O_F64::~Inst_VOP3__V_CMP_O_F64()
    {
    } // ~Inst_VOP3__V_CMP_O_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (!isNan(S0) && !isNan(S1)); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_O_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, (!std::isnan(src0[lane])
                    && !std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_U_F64 class methods ---

    Inst_VOP3__V_CMP_U_F64::Inst_VOP3__V_CMP_U_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_u_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_U_F64

    Inst_VOP3__V_CMP_U_F64::~Inst_VOP3__V_CMP_U_F64()
    {
    } // ~Inst_VOP3__V_CMP_U_F64

    // --- description from .arch file ---
    // D.u64[threadID] = (isNan(S0)  ||  isNan(S1)); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_U_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, (std::isnan(src0[lane])
                    || std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NGE_F64 class methods ---

    Inst_VOP3__V_CMP_NGE_F64::Inst_VOP3__V_CMP_NGE_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_nge_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_NGE_F64

    Inst_VOP3__V_CMP_NGE_F64::~Inst_VOP3__V_CMP_NGE_F64()
    {
    } // ~Inst_VOP3__V_CMP_NGE_F64

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NGE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] >= src1[lane]) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NLG_F64 class methods ---

    Inst_VOP3__V_CMP_NLG_F64::Inst_VOP3__V_CMP_NLG_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_nlg_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_NLG_F64

    Inst_VOP3__V_CMP_NLG_F64::~Inst_VOP3__V_CMP_NLG_F64()
    {
    } // ~Inst_VOP3__V_CMP_NLG_F64

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NLG_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NGT_F64 class methods ---

    Inst_VOP3__V_CMP_NGT_F64::Inst_VOP3__V_CMP_NGT_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ngt_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_NGT_F64

    Inst_VOP3__V_CMP_NGT_F64::~Inst_VOP3__V_CMP_NGT_F64()
    {
    } // ~Inst_VOP3__V_CMP_NGT_F64

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NGT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NLE_F64 class methods ---

    Inst_VOP3__V_CMP_NLE_F64::Inst_VOP3__V_CMP_NLE_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_nle_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_NLE_F64

    Inst_VOP3__V_CMP_NLE_F64::~Inst_VOP3__V_CMP_NLE_F64()
    {
    } // ~Inst_VOP3__V_CMP_NLE_F64

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NLE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] <= src1[lane]) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NEQ_F64 class methods ---

    Inst_VOP3__V_CMP_NEQ_F64::Inst_VOP3__V_CMP_NEQ_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_neq_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_NEQ_F64

    Inst_VOP3__V_CMP_NEQ_F64::~Inst_VOP3__V_CMP_NEQ_F64()
    {
    } // ~Inst_VOP3__V_CMP_NEQ_F64

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NEQ_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NLT_F64 class methods ---

    Inst_VOP3__V_CMP_NLT_F64::Inst_VOP3__V_CMP_NLT_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_nlt_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_NLT_F64

    Inst_VOP3__V_CMP_NLT_F64::~Inst_VOP3__V_CMP_NLT_F64()
    {
    } // ~Inst_VOP3__V_CMP_NLT_F64

    // --- description from .arch file ---
    // D.u64[threadID] = !(S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NLT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] < src1[lane]) ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_TRU_F64 class methods ---

    Inst_VOP3__V_CMP_TRU_F64::Inst_VOP3__V_CMP_TRU_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_tru_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CMP_TRU_F64

    Inst_VOP3__V_CMP_TRU_F64::~Inst_VOP3__V_CMP_TRU_F64()
    {
    } // ~Inst_VOP3__V_CMP_TRU_F64

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_TRU_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_F_F64 class methods ---

    Inst_VOP3__V_CMPX_F_F64::Inst_VOP3__V_CMPX_F_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_f_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_F_F64

    Inst_VOP3__V_CMPX_F_F64::~Inst_VOP3__V_CMPX_F_F64()
    {
    } // ~Inst_VOP3__V_CMPX_F_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_F_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LT_F64 class methods ---

    Inst_VOP3__V_CMPX_LT_F64::Inst_VOP3__V_CMPX_LT_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_lt_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LT_F64

    Inst_VOP3__V_CMPX_LT_F64::~Inst_VOP3__V_CMPX_LT_F64()
    {
    } // ~Inst_VOP3__V_CMPX_LT_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_EQ_F64 class methods ---

    Inst_VOP3__V_CMPX_EQ_F64::Inst_VOP3__V_CMPX_EQ_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_eq_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_EQ_F64

    Inst_VOP3__V_CMPX_EQ_F64::~Inst_VOP3__V_CMPX_EQ_F64()
    {
    } // ~Inst_VOP3__V_CMPX_EQ_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_EQ_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LE_F64 class methods ---

    Inst_VOP3__V_CMPX_LE_F64::Inst_VOP3__V_CMPX_LE_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_le_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LE_F64

    Inst_VOP3__V_CMPX_LE_F64::~Inst_VOP3__V_CMPX_LE_F64()
    {
    } // ~Inst_VOP3__V_CMPX_LE_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GT_F64 class methods ---

    Inst_VOP3__V_CMPX_GT_F64::Inst_VOP3__V_CMPX_GT_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_gt_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GT_F64

    Inst_VOP3__V_CMPX_GT_F64::~Inst_VOP3__V_CMPX_GT_F64()
    {
    } // ~Inst_VOP3__V_CMPX_GT_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LG_F64 class methods ---

    Inst_VOP3__V_CMPX_LG_F64::Inst_VOP3__V_CMPX_LG_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_lg_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LG_F64

    Inst_VOP3__V_CMPX_LG_F64::~Inst_VOP3__V_CMPX_LG_F64()
    {
    } // ~Inst_VOP3__V_CMPX_LG_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LG_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, (src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GE_F64 class methods ---

    Inst_VOP3__V_CMPX_GE_F64::Inst_VOP3__V_CMPX_GE_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ge_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GE_F64

    Inst_VOP3__V_CMPX_GE_F64::~Inst_VOP3__V_CMPX_GE_F64()
    {
    } // ~Inst_VOP3__V_CMPX_GE_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_O_F64 class methods ---

    Inst_VOP3__V_CMPX_O_F64::Inst_VOP3__V_CMPX_O_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_o_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_O_F64

    Inst_VOP3__V_CMPX_O_F64::~Inst_VOP3__V_CMPX_O_F64()
    {
    } // ~Inst_VOP3__V_CMPX_O_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (!isNan(S0) && !isNan(S1)); D = VCC in VOPC
    // encoding.
    void
    Inst_VOP3__V_CMPX_O_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, (!std::isnan(src0[lane])
                    && !std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_U_F64 class methods ---

    Inst_VOP3__V_CMPX_U_F64::Inst_VOP3__V_CMPX_U_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_u_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_U_F64

    Inst_VOP3__V_CMPX_U_F64::~Inst_VOP3__V_CMPX_U_F64()
    {
    } // ~Inst_VOP3__V_CMPX_U_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (isNan(S0)  ||  isNan(S1)); D = VCC in VOPC
    // encoding.
    void
    Inst_VOP3__V_CMPX_U_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, (std::isnan(src0[lane])
                    || std::isnan(src1[lane])) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NGE_F64 class methods ---

    Inst_VOP3__V_CMPX_NGE_F64::Inst_VOP3__V_CMPX_NGE_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_nge_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NGE_F64

    Inst_VOP3__V_CMPX_NGE_F64::~Inst_VOP3__V_CMPX_NGE_F64()
    {
    } // ~Inst_VOP3__V_CMPX_NGE_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NGE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] >= src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NLG_F64 class methods ---

    Inst_VOP3__V_CMPX_NLG_F64::Inst_VOP3__V_CMPX_NLG_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_nlg_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NLG_F64

    Inst_VOP3__V_CMPX_NLG_F64::~Inst_VOP3__V_CMPX_NLG_F64()
    {
    } // ~Inst_VOP3__V_CMPX_NLG_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NLG_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] < src1[lane]
                    || src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NGT_F64 class methods ---

    Inst_VOP3__V_CMPX_NGT_F64::Inst_VOP3__V_CMPX_NGT_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ngt_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NGT_F64

    Inst_VOP3__V_CMPX_NGT_F64::~Inst_VOP3__V_CMPX_NGT_F64()
    {
    } // ~Inst_VOP3__V_CMPX_NGT_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NGT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] > src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NLE_F64 class methods ---

    Inst_VOP3__V_CMPX_NLE_F64::Inst_VOP3__V_CMPX_NLE_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_nle_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NLE_F64

    Inst_VOP3__V_CMPX_NLE_F64::~Inst_VOP3__V_CMPX_NLE_F64()
    {
    } // ~Inst_VOP3__V_CMPX_NLE_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NLE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] <= src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NEQ_F64 class methods ---

    Inst_VOP3__V_CMPX_NEQ_F64::Inst_VOP3__V_CMPX_NEQ_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_neq_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NEQ_F64

    Inst_VOP3__V_CMPX_NEQ_F64::~Inst_VOP3__V_CMPX_NEQ_F64()
    {
    } // ~Inst_VOP3__V_CMPX_NEQ_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NEQ_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NLT_F64 class methods ---

    Inst_VOP3__V_CMPX_NLT_F64::Inst_VOP3__V_CMPX_NLT_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_nlt_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NLT_F64

    Inst_VOP3__V_CMPX_NLT_F64::~Inst_VOP3__V_CMPX_NLT_F64()
    {
    } // ~Inst_VOP3__V_CMPX_NLT_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = !(S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NLT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, !(src0[lane] < src1[lane]) ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_TRU_F64 class methods ---

    Inst_VOP3__V_CMPX_TRU_F64::Inst_VOP3__V_CMPX_TRU_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_tru_f64", true)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_TRU_F64

    Inst_VOP3__V_CMPX_TRU_F64::~Inst_VOP3__V_CMPX_TRU_F64()
    {
    } // ~Inst_VOP3__V_CMPX_TRU_F64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_TRU_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_F_I16 class methods ---

    Inst_VOP3__V_CMP_F_I16::Inst_VOP3__V_CMP_F_I16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_f_i16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_F_I16

    Inst_VOP3__V_CMP_F_I16::~Inst_VOP3__V_CMP_F_I16()
    {
    } // ~Inst_VOP3__V_CMP_F_I16

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_F_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LT_I16 class methods ---

    Inst_VOP3__V_CMP_LT_I16::Inst_VOP3__V_CMP_LT_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_lt_i16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_LT_I16

    Inst_VOP3__V_CMP_LT_I16::~Inst_VOP3__V_CMP_LT_I16()
    {
    } // ~Inst_VOP3__V_CMP_LT_I16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LT_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_EQ_I16 class methods ---

    Inst_VOP3__V_CMP_EQ_I16::Inst_VOP3__V_CMP_EQ_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_eq_i16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_EQ_I16

    Inst_VOP3__V_CMP_EQ_I16::~Inst_VOP3__V_CMP_EQ_I16()
    {
    } // ~Inst_VOP3__V_CMP_EQ_I16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_EQ_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LE_I16 class methods ---

    Inst_VOP3__V_CMP_LE_I16::Inst_VOP3__V_CMP_LE_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_le_i16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_LE_I16

    Inst_VOP3__V_CMP_LE_I16::~Inst_VOP3__V_CMP_LE_I16()
    {
    } // ~Inst_VOP3__V_CMP_LE_I16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LE_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GT_I16 class methods ---

    Inst_VOP3__V_CMP_GT_I16::Inst_VOP3__V_CMP_GT_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_gt_i16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_GT_I16

    Inst_VOP3__V_CMP_GT_I16::~Inst_VOP3__V_CMP_GT_I16()
    {
    } // ~Inst_VOP3__V_CMP_GT_I16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GT_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NE_I16 class methods ---

    Inst_VOP3__V_CMP_NE_I16::Inst_VOP3__V_CMP_NE_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ne_i16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_NE_I16

    Inst_VOP3__V_CMP_NE_I16::~Inst_VOP3__V_CMP_NE_I16()
    {
    } // ~Inst_VOP3__V_CMP_NE_I16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NE_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GE_I16 class methods ---

    Inst_VOP3__V_CMP_GE_I16::Inst_VOP3__V_CMP_GE_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ge_i16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_GE_I16

    Inst_VOP3__V_CMP_GE_I16::~Inst_VOP3__V_CMP_GE_I16()
    {
    } // ~Inst_VOP3__V_CMP_GE_I16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GE_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_T_I16 class methods ---

    Inst_VOP3__V_CMP_T_I16::Inst_VOP3__V_CMP_T_I16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_t_i16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_T_I16

    Inst_VOP3__V_CMP_T_I16::~Inst_VOP3__V_CMP_T_I16()
    {
    } // ~Inst_VOP3__V_CMP_T_I16

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_T_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_F_U16 class methods ---

    Inst_VOP3__V_CMP_F_U16::Inst_VOP3__V_CMP_F_U16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_f_u16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_F_U16

    Inst_VOP3__V_CMP_F_U16::~Inst_VOP3__V_CMP_F_U16()
    {
    } // ~Inst_VOP3__V_CMP_F_U16

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_F_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LT_U16 class methods ---

    Inst_VOP3__V_CMP_LT_U16::Inst_VOP3__V_CMP_LT_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_lt_u16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_LT_U16

    Inst_VOP3__V_CMP_LT_U16::~Inst_VOP3__V_CMP_LT_U16()
    {
    } // ~Inst_VOP3__V_CMP_LT_U16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LT_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_EQ_U16 class methods ---

    Inst_VOP3__V_CMP_EQ_U16::Inst_VOP3__V_CMP_EQ_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_eq_u16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_EQ_U16

    Inst_VOP3__V_CMP_EQ_U16::~Inst_VOP3__V_CMP_EQ_U16()
    {
    } // ~Inst_VOP3__V_CMP_EQ_U16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_EQ_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LE_U16 class methods ---

    Inst_VOP3__V_CMP_LE_U16::Inst_VOP3__V_CMP_LE_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_le_u16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_LE_U16

    Inst_VOP3__V_CMP_LE_U16::~Inst_VOP3__V_CMP_LE_U16()
    {
    } // ~Inst_VOP3__V_CMP_LE_U16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LE_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GT_U16 class methods ---

    Inst_VOP3__V_CMP_GT_U16::Inst_VOP3__V_CMP_GT_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_gt_u16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_GT_U16

    Inst_VOP3__V_CMP_GT_U16::~Inst_VOP3__V_CMP_GT_U16()
    {
    } // ~Inst_VOP3__V_CMP_GT_U16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GT_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NE_U16 class methods ---

    Inst_VOP3__V_CMP_NE_U16::Inst_VOP3__V_CMP_NE_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ne_u16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_NE_U16

    Inst_VOP3__V_CMP_NE_U16::~Inst_VOP3__V_CMP_NE_U16()
    {
    } // ~Inst_VOP3__V_CMP_NE_U16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NE_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GE_U16 class methods ---

    Inst_VOP3__V_CMP_GE_U16::Inst_VOP3__V_CMP_GE_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ge_u16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_GE_U16

    Inst_VOP3__V_CMP_GE_U16::~Inst_VOP3__V_CMP_GE_U16()
    {
    } // ~Inst_VOP3__V_CMP_GE_U16

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GE_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_T_U16 class methods ---

    Inst_VOP3__V_CMP_T_U16::Inst_VOP3__V_CMP_T_U16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_t_u16", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_T_U16

    Inst_VOP3__V_CMP_T_U16::~Inst_VOP3__V_CMP_T_U16()
    {
    } // ~Inst_VOP3__V_CMP_T_U16

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_T_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_F_I16 class methods ---

    Inst_VOP3__V_CMPX_F_I16::Inst_VOP3__V_CMPX_F_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_f_i16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_F_I16

    Inst_VOP3__V_CMPX_F_I16::~Inst_VOP3__V_CMPX_F_I16()
    {
    } // ~Inst_VOP3__V_CMPX_F_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_F_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LT_I16 class methods ---

    Inst_VOP3__V_CMPX_LT_I16::Inst_VOP3__V_CMPX_LT_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_lt_i16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LT_I16

    Inst_VOP3__V_CMPX_LT_I16::~Inst_VOP3__V_CMPX_LT_I16()
    {
    } // ~Inst_VOP3__V_CMPX_LT_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LT_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_EQ_I16 class methods ---

    Inst_VOP3__V_CMPX_EQ_I16::Inst_VOP3__V_CMPX_EQ_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_eq_i16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_EQ_I16

    Inst_VOP3__V_CMPX_EQ_I16::~Inst_VOP3__V_CMPX_EQ_I16()
    {
    } // ~Inst_VOP3__V_CMPX_EQ_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_EQ_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LE_I16 class methods ---

    Inst_VOP3__V_CMPX_LE_I16::Inst_VOP3__V_CMPX_LE_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_le_i16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LE_I16

    Inst_VOP3__V_CMPX_LE_I16::~Inst_VOP3__V_CMPX_LE_I16()
    {
    } // ~Inst_VOP3__V_CMPX_LE_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LE_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GT_I16 class methods ---

    Inst_VOP3__V_CMPX_GT_I16::Inst_VOP3__V_CMPX_GT_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_gt_i16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GT_I16

    Inst_VOP3__V_CMPX_GT_I16::~Inst_VOP3__V_CMPX_GT_I16()
    {
    } // ~Inst_VOP3__V_CMPX_GT_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GT_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NE_I16 class methods ---

    Inst_VOP3__V_CMPX_NE_I16::Inst_VOP3__V_CMPX_NE_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ne_i16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NE_I16

    Inst_VOP3__V_CMPX_NE_I16::~Inst_VOP3__V_CMPX_NE_I16()
    {
    } // ~Inst_VOP3__V_CMPX_NE_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NE_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GE_I16 class methods ---

    Inst_VOP3__V_CMPX_GE_I16::Inst_VOP3__V_CMPX_GE_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ge_i16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GE_I16

    Inst_VOP3__V_CMPX_GE_I16::~Inst_VOP3__V_CMPX_GE_I16()
    {
    } // ~Inst_VOP3__V_CMPX_GE_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GE_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_T_I16 class methods ---

    Inst_VOP3__V_CMPX_T_I16::Inst_VOP3__V_CMPX_T_I16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_t_i16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_T_I16

    Inst_VOP3__V_CMPX_T_I16::~Inst_VOP3__V_CMPX_T_I16()
    {
    } // ~Inst_VOP3__V_CMPX_T_I16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_T_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_F_U16 class methods ---

    Inst_VOP3__V_CMPX_F_U16::Inst_VOP3__V_CMPX_F_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_f_u16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_F_U16

    Inst_VOP3__V_CMPX_F_U16::~Inst_VOP3__V_CMPX_F_U16()
    {
    } // ~Inst_VOP3__V_CMPX_F_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_F_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LT_U16 class methods ---

    Inst_VOP3__V_CMPX_LT_U16::Inst_VOP3__V_CMPX_LT_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_lt_u16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LT_U16

    Inst_VOP3__V_CMPX_LT_U16::~Inst_VOP3__V_CMPX_LT_U16()
    {
    } // ~Inst_VOP3__V_CMPX_LT_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LT_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_EQ_U16 class methods ---

    Inst_VOP3__V_CMPX_EQ_U16::Inst_VOP3__V_CMPX_EQ_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_eq_u16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_EQ_U16

    Inst_VOP3__V_CMPX_EQ_U16::~Inst_VOP3__V_CMPX_EQ_U16()
    {
    } // ~Inst_VOP3__V_CMPX_EQ_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_EQ_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LE_U16 class methods ---

    Inst_VOP3__V_CMPX_LE_U16::Inst_VOP3__V_CMPX_LE_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_le_u16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LE_U16

    Inst_VOP3__V_CMPX_LE_U16::~Inst_VOP3__V_CMPX_LE_U16()
    {
    } // ~Inst_VOP3__V_CMPX_LE_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LE_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GT_U16 class methods ---

    Inst_VOP3__V_CMPX_GT_U16::Inst_VOP3__V_CMPX_GT_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_gt_u16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GT_U16

    Inst_VOP3__V_CMPX_GT_U16::~Inst_VOP3__V_CMPX_GT_U16()
    {
    } // ~Inst_VOP3__V_CMPX_GT_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GT_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NE_U16 class methods ---

    Inst_VOP3__V_CMPX_NE_U16::Inst_VOP3__V_CMPX_NE_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ne_u16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NE_U16

    Inst_VOP3__V_CMPX_NE_U16::~Inst_VOP3__V_CMPX_NE_U16()
    {
    } // ~Inst_VOP3__V_CMPX_NE_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NE_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GE_U16 class methods ---

    Inst_VOP3__V_CMPX_GE_U16::Inst_VOP3__V_CMPX_GE_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ge_u16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GE_U16

    Inst_VOP3__V_CMPX_GE_U16::~Inst_VOP3__V_CMPX_GE_U16()
    {
    } // ~Inst_VOP3__V_CMPX_GE_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GE_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_T_U16 class methods ---

    Inst_VOP3__V_CMPX_T_U16::Inst_VOP3__V_CMPX_T_U16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_t_u16", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_T_U16

    Inst_VOP3__V_CMPX_T_U16::~Inst_VOP3__V_CMPX_T_U16()
    {
    } // ~Inst_VOP3__V_CMPX_T_U16

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_T_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_F_I32 class methods ---

    Inst_VOP3__V_CMP_F_I32::Inst_VOP3__V_CMP_F_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_f_i32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_F_I32

    Inst_VOP3__V_CMP_F_I32::~Inst_VOP3__V_CMP_F_I32()
    {
    } // ~Inst_VOP3__V_CMP_F_I32

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_F_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LT_I32 class methods ---

    Inst_VOP3__V_CMP_LT_I32::Inst_VOP3__V_CMP_LT_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_lt_i32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_LT_I32

    Inst_VOP3__V_CMP_LT_I32::~Inst_VOP3__V_CMP_LT_I32()
    {
    } // ~Inst_VOP3__V_CMP_LT_I32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_EQ_I32 class methods ---

    Inst_VOP3__V_CMP_EQ_I32::Inst_VOP3__V_CMP_EQ_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_eq_i32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_EQ_I32

    Inst_VOP3__V_CMP_EQ_I32::~Inst_VOP3__V_CMP_EQ_I32()
    {
    } // ~Inst_VOP3__V_CMP_EQ_I32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_EQ_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LE_I32 class methods ---

    Inst_VOP3__V_CMP_LE_I32::Inst_VOP3__V_CMP_LE_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_le_i32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_LE_I32

    Inst_VOP3__V_CMP_LE_I32::~Inst_VOP3__V_CMP_LE_I32()
    {
    } // ~Inst_VOP3__V_CMP_LE_I32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GT_I32 class methods ---

    Inst_VOP3__V_CMP_GT_I32::Inst_VOP3__V_CMP_GT_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_gt_i32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_GT_I32

    Inst_VOP3__V_CMP_GT_I32::~Inst_VOP3__V_CMP_GT_I32()
    {
    } // ~Inst_VOP3__V_CMP_GT_I32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NE_I32 class methods ---

    Inst_VOP3__V_CMP_NE_I32::Inst_VOP3__V_CMP_NE_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ne_i32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_NE_I32

    Inst_VOP3__V_CMP_NE_I32::~Inst_VOP3__V_CMP_NE_I32()
    {
    } // ~Inst_VOP3__V_CMP_NE_I32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GE_I32 class methods ---

    Inst_VOP3__V_CMP_GE_I32::Inst_VOP3__V_CMP_GE_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ge_i32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_GE_I32

    Inst_VOP3__V_CMP_GE_I32::~Inst_VOP3__V_CMP_GE_I32()
    {
    } // ~Inst_VOP3__V_CMP_GE_I32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_T_I32 class methods ---

    Inst_VOP3__V_CMP_T_I32::Inst_VOP3__V_CMP_T_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_t_i32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_T_I32

    Inst_VOP3__V_CMP_T_I32::~Inst_VOP3__V_CMP_T_I32()
    {
    } // ~Inst_VOP3__V_CMP_T_I32

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_T_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_F_U32 class methods ---

    Inst_VOP3__V_CMP_F_U32::Inst_VOP3__V_CMP_F_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_f_u32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_F_U32

    Inst_VOP3__V_CMP_F_U32::~Inst_VOP3__V_CMP_F_U32()
    {
    } // ~Inst_VOP3__V_CMP_F_U32

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_F_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LT_U32 class methods ---

    Inst_VOP3__V_CMP_LT_U32::Inst_VOP3__V_CMP_LT_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_lt_u32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_LT_U32

    Inst_VOP3__V_CMP_LT_U32::~Inst_VOP3__V_CMP_LT_U32()
    {
    } // ~Inst_VOP3__V_CMP_LT_U32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LT_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_EQ_U32 class methods ---

    Inst_VOP3__V_CMP_EQ_U32::Inst_VOP3__V_CMP_EQ_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_eq_u32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_EQ_U32

    Inst_VOP3__V_CMP_EQ_U32::~Inst_VOP3__V_CMP_EQ_U32()
    {
    } // ~Inst_VOP3__V_CMP_EQ_U32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_EQ_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LE_U32 class methods ---

    Inst_VOP3__V_CMP_LE_U32::Inst_VOP3__V_CMP_LE_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_le_u32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_LE_U32

    Inst_VOP3__V_CMP_LE_U32::~Inst_VOP3__V_CMP_LE_U32()
    {
    } // ~Inst_VOP3__V_CMP_LE_U32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GT_U32 class methods ---

    Inst_VOP3__V_CMP_GT_U32::Inst_VOP3__V_CMP_GT_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_gt_u32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_GT_U32

    Inst_VOP3__V_CMP_GT_U32::~Inst_VOP3__V_CMP_GT_U32()
    {
    } // ~Inst_VOP3__V_CMP_GT_U32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GT_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NE_U32 class methods ---

    Inst_VOP3__V_CMP_NE_U32::Inst_VOP3__V_CMP_NE_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ne_u32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_NE_U32

    Inst_VOP3__V_CMP_NE_U32::~Inst_VOP3__V_CMP_NE_U32()
    {
    } // ~Inst_VOP3__V_CMP_NE_U32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GE_U32 class methods ---

    Inst_VOP3__V_CMP_GE_U32::Inst_VOP3__V_CMP_GE_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ge_u32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_GE_U32

    Inst_VOP3__V_CMP_GE_U32::~Inst_VOP3__V_CMP_GE_U32()
    {
    } // ~Inst_VOP3__V_CMP_GE_U32

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_T_U32 class methods ---

    Inst_VOP3__V_CMP_T_U32::Inst_VOP3__V_CMP_T_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_t_u32", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_T_U32

    Inst_VOP3__V_CMP_T_U32::~Inst_VOP3__V_CMP_T_U32()
    {
    } // ~Inst_VOP3__V_CMP_T_U32

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_T_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_F_I32 class methods ---

    Inst_VOP3__V_CMPX_F_I32::Inst_VOP3__V_CMPX_F_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_f_i32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_F_I32

    Inst_VOP3__V_CMPX_F_I32::~Inst_VOP3__V_CMPX_F_I32()
    {
    } // ~Inst_VOP3__V_CMPX_F_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_F_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LT_I32 class methods ---

    Inst_VOP3__V_CMPX_LT_I32::Inst_VOP3__V_CMPX_LT_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_lt_i32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LT_I32

    Inst_VOP3__V_CMPX_LT_I32::~Inst_VOP3__V_CMPX_LT_I32()
    {
    } // ~Inst_VOP3__V_CMPX_LT_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_EQ_I32 class methods ---

    Inst_VOP3__V_CMPX_EQ_I32::Inst_VOP3__V_CMPX_EQ_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_eq_i32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_EQ_I32

    Inst_VOP3__V_CMPX_EQ_I32::~Inst_VOP3__V_CMPX_EQ_I32()
    {
    } // ~Inst_VOP3__V_CMPX_EQ_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_EQ_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LE_I32 class methods ---

    Inst_VOP3__V_CMPX_LE_I32::Inst_VOP3__V_CMPX_LE_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_le_i32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LE_I32

    Inst_VOP3__V_CMPX_LE_I32::~Inst_VOP3__V_CMPX_LE_I32()
    {
    } // ~Inst_VOP3__V_CMPX_LE_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GT_I32 class methods ---

    Inst_VOP3__V_CMPX_GT_I32::Inst_VOP3__V_CMPX_GT_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_gt_i32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GT_I32

    Inst_VOP3__V_CMPX_GT_I32::~Inst_VOP3__V_CMPX_GT_I32()
    {
    } // ~Inst_VOP3__V_CMPX_GT_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GT_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NE_I32 class methods ---

    Inst_VOP3__V_CMPX_NE_I32::Inst_VOP3__V_CMPX_NE_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ne_i32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NE_I32

    Inst_VOP3__V_CMPX_NE_I32::~Inst_VOP3__V_CMPX_NE_I32()
    {
    } // ~Inst_VOP3__V_CMPX_NE_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GE_I32 class methods ---

    Inst_VOP3__V_CMPX_GE_I32::Inst_VOP3__V_CMPX_GE_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ge_i32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GE_I32

    Inst_VOP3__V_CMPX_GE_I32::~Inst_VOP3__V_CMPX_GE_I32()
    {
    } // ~Inst_VOP3__V_CMPX_GE_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_T_I32 class methods ---

    Inst_VOP3__V_CMPX_T_I32::Inst_VOP3__V_CMPX_T_I32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_t_i32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_T_I32

    Inst_VOP3__V_CMPX_T_I32::~Inst_VOP3__V_CMPX_T_I32()
    {
    } // ~Inst_VOP3__V_CMPX_T_I32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_T_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_F_U32 class methods ---

    Inst_VOP3__V_CMPX_F_U32::Inst_VOP3__V_CMPX_F_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_f_u32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_F_U32

    Inst_VOP3__V_CMPX_F_U32::~Inst_VOP3__V_CMPX_F_U32()
    {
    } // ~Inst_VOP3__V_CMPX_F_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_F_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LT_U32 class methods ---

    Inst_VOP3__V_CMPX_LT_U32::Inst_VOP3__V_CMPX_LT_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_lt_u32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LT_U32

    Inst_VOP3__V_CMPX_LT_U32::~Inst_VOP3__V_CMPX_LT_U32()
    {
    } // ~Inst_VOP3__V_CMPX_LT_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LT_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_EQ_U32 class methods ---

    Inst_VOP3__V_CMPX_EQ_U32::Inst_VOP3__V_CMPX_EQ_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_eq_u32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_EQ_U32

    Inst_VOP3__V_CMPX_EQ_U32::~Inst_VOP3__V_CMPX_EQ_U32()
    {
    } // ~Inst_VOP3__V_CMPX_EQ_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_EQ_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LE_U32 class methods ---

    Inst_VOP3__V_CMPX_LE_U32::Inst_VOP3__V_CMPX_LE_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_le_u32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LE_U32

    Inst_VOP3__V_CMPX_LE_U32::~Inst_VOP3__V_CMPX_LE_U32()
    {
    } // ~Inst_VOP3__V_CMPX_LE_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GT_U32 class methods ---

    Inst_VOP3__V_CMPX_GT_U32::Inst_VOP3__V_CMPX_GT_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_gt_u32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GT_U32

    Inst_VOP3__V_CMPX_GT_U32::~Inst_VOP3__V_CMPX_GT_U32()
    {
    } // ~Inst_VOP3__V_CMPX_GT_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GT_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NE_U32 class methods ---

    Inst_VOP3__V_CMPX_NE_U32::Inst_VOP3__V_CMPX_NE_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ne_u32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NE_U32

    Inst_VOP3__V_CMPX_NE_U32::~Inst_VOP3__V_CMPX_NE_U32()
    {
    } // ~Inst_VOP3__V_CMPX_NE_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GE_U32 class methods ---

    Inst_VOP3__V_CMPX_GE_U32::Inst_VOP3__V_CMPX_GE_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ge_u32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GE_U32

    Inst_VOP3__V_CMPX_GE_U32::~Inst_VOP3__V_CMPX_GE_U32()
    {
    } // ~Inst_VOP3__V_CMPX_GE_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_T_U32 class methods ---

    Inst_VOP3__V_CMPX_T_U32::Inst_VOP3__V_CMPX_T_U32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_t_u32", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_T_U32

    Inst_VOP3__V_CMPX_T_U32::~Inst_VOP3__V_CMPX_T_U32()
    {
    } // ~Inst_VOP3__V_CMPX_T_U32

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_T_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_F_I64 class methods ---

    Inst_VOP3__V_CMP_F_I64::Inst_VOP3__V_CMP_F_I64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_f_i64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_F_I64

    Inst_VOP3__V_CMP_F_I64::~Inst_VOP3__V_CMP_F_I64()
    {
    } // ~Inst_VOP3__V_CMP_F_I64

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_F_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LT_I64 class methods ---

    Inst_VOP3__V_CMP_LT_I64::Inst_VOP3__V_CMP_LT_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_lt_i64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_LT_I64

    Inst_VOP3__V_CMP_LT_I64::~Inst_VOP3__V_CMP_LT_I64()
    {
    } // ~Inst_VOP3__V_CMP_LT_I64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LT_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_EQ_I64 class methods ---

    Inst_VOP3__V_CMP_EQ_I64::Inst_VOP3__V_CMP_EQ_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_eq_i64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_EQ_I64

    Inst_VOP3__V_CMP_EQ_I64::~Inst_VOP3__V_CMP_EQ_I64()
    {
    } // ~Inst_VOP3__V_CMP_EQ_I64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_EQ_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LE_I64 class methods ---

    Inst_VOP3__V_CMP_LE_I64::Inst_VOP3__V_CMP_LE_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_le_i64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_LE_I64

    Inst_VOP3__V_CMP_LE_I64::~Inst_VOP3__V_CMP_LE_I64()
    {
    } // ~Inst_VOP3__V_CMP_LE_I64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GT_I64 class methods ---

    Inst_VOP3__V_CMP_GT_I64::Inst_VOP3__V_CMP_GT_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_gt_i64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_GT_I64

    Inst_VOP3__V_CMP_GT_I64::~Inst_VOP3__V_CMP_GT_I64()
    {
    } // ~Inst_VOP3__V_CMP_GT_I64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GT_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NE_I64 class methods ---

    Inst_VOP3__V_CMP_NE_I64::Inst_VOP3__V_CMP_NE_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ne_i64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_NE_I64

    Inst_VOP3__V_CMP_NE_I64::~Inst_VOP3__V_CMP_NE_I64()
    {
    } // ~Inst_VOP3__V_CMP_NE_I64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GE_I64 class methods ---

    Inst_VOP3__V_CMP_GE_I64::Inst_VOP3__V_CMP_GE_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ge_i64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_GE_I64

    Inst_VOP3__V_CMP_GE_I64::~Inst_VOP3__V_CMP_GE_I64()
    {
    } // ~Inst_VOP3__V_CMP_GE_I64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_T_I64 class methods ---

    Inst_VOP3__V_CMP_T_I64::Inst_VOP3__V_CMP_T_I64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_t_i64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_T_I64

    Inst_VOP3__V_CMP_T_I64::~Inst_VOP3__V_CMP_T_I64()
    {
    } // ~Inst_VOP3__V_CMP_T_I64

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_T_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_F_U64 class methods ---

    Inst_VOP3__V_CMP_F_U64::Inst_VOP3__V_CMP_F_U64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_f_u64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_F_U64

    Inst_VOP3__V_CMP_F_U64::~Inst_VOP3__V_CMP_F_U64()
    {
    } // ~Inst_VOP3__V_CMP_F_U64

    // --- description from .arch file ---
    // D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_F_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LT_U64 class methods ---

    Inst_VOP3__V_CMP_LT_U64::Inst_VOP3__V_CMP_LT_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_lt_u64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_LT_U64

    Inst_VOP3__V_CMP_LT_U64::~Inst_VOP3__V_CMP_LT_U64()
    {
    } // ~Inst_VOP3__V_CMP_LT_U64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LT_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_EQ_U64 class methods ---

    Inst_VOP3__V_CMP_EQ_U64::Inst_VOP3__V_CMP_EQ_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_eq_u64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_EQ_U64

    Inst_VOP3__V_CMP_EQ_U64::~Inst_VOP3__V_CMP_EQ_U64()
    {
    } // ~Inst_VOP3__V_CMP_EQ_U64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_EQ_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_LE_U64 class methods ---

    Inst_VOP3__V_CMP_LE_U64::Inst_VOP3__V_CMP_LE_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_le_u64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_LE_U64

    Inst_VOP3__V_CMP_LE_U64::~Inst_VOP3__V_CMP_LE_U64()
    {
    } // ~Inst_VOP3__V_CMP_LE_U64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_LE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GT_U64 class methods ---

    Inst_VOP3__V_CMP_GT_U64::Inst_VOP3__V_CMP_GT_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_gt_u64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_GT_U64

    Inst_VOP3__V_CMP_GT_U64::~Inst_VOP3__V_CMP_GT_U64()
    {
    } // ~Inst_VOP3__V_CMP_GT_U64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GT_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_NE_U64 class methods ---

    Inst_VOP3__V_CMP_NE_U64::Inst_VOP3__V_CMP_NE_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ne_u64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_NE_U64

    Inst_VOP3__V_CMP_NE_U64::~Inst_VOP3__V_CMP_NE_U64()
    {
    } // ~Inst_VOP3__V_CMP_NE_U64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_NE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_GE_U64 class methods ---

    Inst_VOP3__V_CMP_GE_U64::Inst_VOP3__V_CMP_GE_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_ge_u64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_GE_U64

    Inst_VOP3__V_CMP_GE_U64::~Inst_VOP3__V_CMP_GE_U64()
    {
    } // ~Inst_VOP3__V_CMP_GE_U64

    // --- description from .arch file ---
    // D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_GE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMP_T_U64 class methods ---

    Inst_VOP3__V_CMP_T_U64::Inst_VOP3__V_CMP_T_U64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmp_t_u64", true)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CMP_T_U64

    Inst_VOP3__V_CMP_T_U64::~Inst_VOP3__V_CMP_T_U64()
    {
    } // ~Inst_VOP3__V_CMP_T_U64

    // --- description from .arch file ---
    // D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMP_T_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_F_I64 class methods ---

    Inst_VOP3__V_CMPX_F_I64::Inst_VOP3__V_CMPX_F_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_f_i64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_F_I64

    Inst_VOP3__V_CMPX_F_I64::~Inst_VOP3__V_CMPX_F_I64()
    {
    } // ~Inst_VOP3__V_CMPX_F_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_F_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LT_I64 class methods ---

    Inst_VOP3__V_CMPX_LT_I64::Inst_VOP3__V_CMPX_LT_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_lt_i64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LT_I64

    Inst_VOP3__V_CMPX_LT_I64::~Inst_VOP3__V_CMPX_LT_I64()
    {
    } // ~Inst_VOP3__V_CMPX_LT_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LT_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_EQ_I64 class methods ---

    Inst_VOP3__V_CMPX_EQ_I64::Inst_VOP3__V_CMPX_EQ_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_eq_i64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_EQ_I64

    Inst_VOP3__V_CMPX_EQ_I64::~Inst_VOP3__V_CMPX_EQ_I64()
    {
    } // ~Inst_VOP3__V_CMPX_EQ_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_EQ_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LE_I64 class methods ---

    Inst_VOP3__V_CMPX_LE_I64::Inst_VOP3__V_CMPX_LE_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_le_i64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LE_I64

    Inst_VOP3__V_CMPX_LE_I64::~Inst_VOP3__V_CMPX_LE_I64()
    {
    } // ~Inst_VOP3__V_CMPX_LE_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GT_I64 class methods ---

    Inst_VOP3__V_CMPX_GT_I64::Inst_VOP3__V_CMPX_GT_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_gt_i64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GT_I64

    Inst_VOP3__V_CMPX_GT_I64::~Inst_VOP3__V_CMPX_GT_I64()
    {
    } // ~Inst_VOP3__V_CMPX_GT_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GT_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NE_I64 class methods ---

    Inst_VOP3__V_CMPX_NE_I64::Inst_VOP3__V_CMPX_NE_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ne_i64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NE_I64

    Inst_VOP3__V_CMPX_NE_I64::~Inst_VOP3__V_CMPX_NE_I64()
    {
    } // ~Inst_VOP3__V_CMPX_NE_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GE_I64 class methods ---

    Inst_VOP3__V_CMPX_GE_I64::Inst_VOP3__V_CMPX_GE_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ge_i64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GE_I64

    Inst_VOP3__V_CMPX_GE_I64::~Inst_VOP3__V_CMPX_GE_I64()
    {
    } // ~Inst_VOP3__V_CMPX_GE_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GE_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_T_I64 class methods ---

    Inst_VOP3__V_CMPX_T_I64::Inst_VOP3__V_CMPX_T_I64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_t_i64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_T_I64

    Inst_VOP3__V_CMPX_T_I64::~Inst_VOP3__V_CMPX_T_I64()
    {
    } // ~Inst_VOP3__V_CMPX_T_I64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_T_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_F_U64 class methods ---

    Inst_VOP3__V_CMPX_F_U64::Inst_VOP3__V_CMPX_F_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_f_u64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_F_U64

    Inst_VOP3__V_CMPX_F_U64::~Inst_VOP3__V_CMPX_F_U64()
    {
    } // ~Inst_VOP3__V_CMPX_F_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 0; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_F_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LT_U64 class methods ---

    Inst_VOP3__V_CMPX_LT_U64::Inst_VOP3__V_CMPX_LT_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_lt_u64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LT_U64

    Inst_VOP3__V_CMPX_LT_U64::~Inst_VOP3__V_CMPX_LT_U64()
    {
    } // ~Inst_VOP3__V_CMPX_LT_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 < S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LT_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] < src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_EQ_U64 class methods ---

    Inst_VOP3__V_CMPX_EQ_U64::Inst_VOP3__V_CMPX_EQ_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_eq_u64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_EQ_U64

    Inst_VOP3__V_CMPX_EQ_U64::~Inst_VOP3__V_CMPX_EQ_U64()
    {
    } // ~Inst_VOP3__V_CMPX_EQ_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 == S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_EQ_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] == src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_LE_U64 class methods ---

    Inst_VOP3__V_CMPX_LE_U64::Inst_VOP3__V_CMPX_LE_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_le_u64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_LE_U64

    Inst_VOP3__V_CMPX_LE_U64::~Inst_VOP3__V_CMPX_LE_U64()
    {
    } // ~Inst_VOP3__V_CMPX_LE_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_LE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] <= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GT_U64 class methods ---

    Inst_VOP3__V_CMPX_GT_U64::Inst_VOP3__V_CMPX_GT_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_gt_u64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GT_U64

    Inst_VOP3__V_CMPX_GT_U64::~Inst_VOP3__V_CMPX_GT_U64()
    {
    } // ~Inst_VOP3__V_CMPX_GT_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 > S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GT_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_NE_U64 class methods ---

    Inst_VOP3__V_CMPX_NE_U64::Inst_VOP3__V_CMPX_NE_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ne_u64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_NE_U64

    Inst_VOP3__V_CMPX_NE_U64::~Inst_VOP3__V_CMPX_NE_U64()
    {
    } // ~Inst_VOP3__V_CMPX_NE_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 <> S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_NE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] != src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_GE_U64 class methods ---

    Inst_VOP3__V_CMPX_GE_U64::Inst_VOP3__V_CMPX_GE_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_ge_u64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_GE_U64

    Inst_VOP3__V_CMPX_GE_U64::~Inst_VOP3__V_CMPX_GE_U64()
    {
    } // ~Inst_VOP3__V_CMPX_GE_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = (S0 >= S1); D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_GE_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, src0[lane] >= src1[lane] ? 1 : 0);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CMPX_T_U64 class methods ---

    Inst_VOP3__V_CMPX_T_U64::Inst_VOP3__V_CMPX_T_U64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cmpx_t_u64", true)
    {
        setFlag(ALU);
        setFlag(WritesEXEC);
    } // Inst_VOP3__V_CMPX_T_U64

    Inst_VOP3__V_CMPX_T_U64::~Inst_VOP3__V_CMPX_T_U64()
    {
    } // ~Inst_VOP3__V_CMPX_T_U64

    // --- description from .arch file ---
    // EXEC,D.u64[threadID] = 1; D = VCC in VOPC encoding.
    void
    Inst_VOP3__V_CMPX_T_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ScalarOperandU64 sdst(gpuDynInst, instData.VDST);

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                sdst.setBit(lane, 1);
            }
        }

        wf->execMask() = sdst.rawData();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_CNDMASK_B32 class methods ---

    Inst_VOP3__V_CNDMASK_B32::Inst_VOP3__V_CNDMASK_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cndmask_b32", false)
    {
        setFlag(ALU);
        setFlag(ReadsVCC);
    } // Inst_VOP3__V_CNDMASK_B32

    Inst_VOP3__V_CNDMASK_B32::~Inst_VOP3__V_CNDMASK_B32()
    {
    } // ~Inst_VOP3__V_CNDMASK_B32

    // --- description from .arch file ---
    // D.u = (VCC[i] ? S1.u : S0.u) (i = threadID in wave); VOP3: specify VCC
    // as a scalar GPR in S2.
    void
    Inst_VOP3__V_CNDMASK_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstScalarOperandU64 vcc(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        vcc.read();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = bits(vcc.rawData(), lane)
                    ? src1[lane] : src0[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_ADD_F32 class methods ---

    Inst_VOP3__V_ADD_F32::Inst_VOP3__V_ADD_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_add_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_ADD_F32

    Inst_VOP3__V_ADD_F32::~Inst_VOP3__V_ADD_F32()
    {
    } // ~Inst_VOP3__V_ADD_F32

    // --- description from .arch file ---
    // D.f = S0.f + S1.f.
    void
    Inst_VOP3__V_ADD_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] + src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_SUB_F32 class methods ---

    Inst_VOP3__V_SUB_F32::Inst_VOP3__V_SUB_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_sub_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_SUB_F32

    Inst_VOP3__V_SUB_F32::~Inst_VOP3__V_SUB_F32()
    {
    } // ~Inst_VOP3__V_SUB_F32

    // --- description from .arch file ---
    // D.f = S0.f - S1.f.
    // SQ translates to V_ADD_F32.
    void
    Inst_VOP3__V_SUB_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] - src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_SUBREV_F32 class methods ---

    Inst_VOP3__V_SUBREV_F32::Inst_VOP3__V_SUBREV_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_subrev_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_SUBREV_F32

    Inst_VOP3__V_SUBREV_F32::~Inst_VOP3__V_SUBREV_F32()
    {
    } // ~Inst_VOP3__V_SUBREV_F32

    // --- description from .arch file ---
    // D.f = S1.f - S0.f.
    // SQ translates to V_ADD_F32.
    void
    Inst_VOP3__V_SUBREV_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] - src0[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MUL_LEGACY_F32 class methods ---

    Inst_VOP3__V_MUL_LEGACY_F32::Inst_VOP3__V_MUL_LEGACY_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mul_legacy_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_MUL_LEGACY_F32

    Inst_VOP3__V_MUL_LEGACY_F32::~Inst_VOP3__V_MUL_LEGACY_F32()
    {
    } // ~Inst_VOP3__V_MUL_LEGACY_F32

    // --- description from .arch file ---
    // D.f = S0.f * S1.f (DX9 rules, 0.0*x = 0.0).
    void
    Inst_VOP3__V_MUL_LEGACY_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isnan(src0[lane]) ||
                    std::isnan(src1[lane])) {
                    vdst[lane] = NAN;
                } else if ((std::fpclassify(src0[lane]) == FP_SUBNORMAL ||
                           std::fpclassify(src0[lane]) == FP_ZERO) &&
                           !std::signbit(src0[lane])) {
                    if (std::isinf(src1[lane])) {
                        vdst[lane] = NAN;
                    } else if (!std::signbit(src1[lane])) {
                        vdst[lane] = +0.0;
                    } else {
                        vdst[lane] = -0.0;
                    }
                } else if ((std::fpclassify(src0[lane]) == FP_SUBNORMAL ||
                           std::fpclassify(src0[lane]) == FP_ZERO) &&
                           std::signbit(src0[lane])) {
                    if (std::isinf(src1[lane])) {
                        vdst[lane] = NAN;
                    } else if (std::signbit(src1[lane])) {
                        vdst[lane] = +0.0;
                    } else {
                        vdst[lane] = -0.0;
                    }
                } else if (std::isinf(src0[lane]) &&
                           !std::signbit(src0[lane])) {
                    if (std::fpclassify(src1[lane]) == FP_SUBNORMAL ||
                        std::fpclassify(src1[lane]) == FP_ZERO) {
                        vdst[lane] = NAN;
                    } else if (!std::signbit(src1[lane])) {
                        vdst[lane] = +INFINITY;
                    } else {
                        vdst[lane] = -INFINITY;
                    }
                } else if (std::isinf(src0[lane]) &&
                           std::signbit(src0[lane])) {
                    if (std::fpclassify(src1[lane]) == FP_SUBNORMAL ||
                        std::fpclassify(src1[lane]) == FP_ZERO) {
                        vdst[lane] = NAN;
                    } else if (std::signbit(src1[lane])) {
                        vdst[lane] = +INFINITY;
                    } else {
                        vdst[lane] = -INFINITY;
                    }
                } else {
                    vdst[lane] = src0[lane] * src1[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MUL_F32 class methods ---

    Inst_VOP3__V_MUL_F32::Inst_VOP3__V_MUL_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mul_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_MUL_F32

    Inst_VOP3__V_MUL_F32::~Inst_VOP3__V_MUL_F32()
    {
    } // ~Inst_VOP3__V_MUL_F32

    // --- description from .arch file ---
    // D.f = S0.f * S1.f.
    void
    Inst_VOP3__V_MUL_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isnan(src0[lane]) ||
                    std::isnan(src1[lane])) {
                    vdst[lane] = NAN;
                } else if ((std::fpclassify(src0[lane]) == FP_SUBNORMAL ||
                           std::fpclassify(src0[lane]) == FP_ZERO) &&
                           !std::signbit(src0[lane])) {
                    if (std::isinf(src1[lane])) {
                        vdst[lane] = NAN;
                    } else if (!std::signbit(src1[lane])) {
                        vdst[lane] = +0.0;
                    } else {
                        vdst[lane] = -0.0;
                    }
                } else if ((std::fpclassify(src0[lane]) == FP_SUBNORMAL ||
                           std::fpclassify(src0[lane]) == FP_ZERO) &&
                           std::signbit(src0[lane])) {
                    if (std::isinf(src1[lane])) {
                        vdst[lane] = NAN;
                    } else if (std::signbit(src1[lane])) {
                        vdst[lane] = +0.0;
                    } else {
                        vdst[lane] = -0.0;
                    }
                } else if (std::isinf(src0[lane]) &&
                           !std::signbit(src0[lane])) {
                    if (std::fpclassify(src1[lane]) == FP_SUBNORMAL ||
                        std::fpclassify(src1[lane]) == FP_ZERO) {
                        vdst[lane] = NAN;
                    } else if (!std::signbit(src1[lane])) {
                        vdst[lane] = +INFINITY;
                    } else {
                        vdst[lane] = -INFINITY;
                    }
                } else if (std::isinf(src0[lane]) &&
                           std::signbit(src0[lane])) {
                    if (std::fpclassify(src1[lane]) == FP_SUBNORMAL ||
                        std::fpclassify(src1[lane]) == FP_ZERO) {
                        vdst[lane] = NAN;
                    } else if (std::signbit(src1[lane])) {
                        vdst[lane] = +INFINITY;
                    } else {
                        vdst[lane] = -INFINITY;
                    }
                } else {
                    vdst[lane] = src0[lane] * src1[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MUL_I32_I24 class methods ---

    Inst_VOP3__V_MUL_I32_I24::Inst_VOP3__V_MUL_I32_I24(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mul_i32_i24", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MUL_I32_I24

    Inst_VOP3__V_MUL_I32_I24::~Inst_VOP3__V_MUL_I32_I24()
    {
    } // ~Inst_VOP3__V_MUL_I32_I24

    // --- description from .arch file ---
    // D.i = S0.i[23:0] * S1.i[23:0].
    void
    Inst_VOP3__V_MUL_I32_I24::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = sext<24>(bits(src0[lane], 23, 0))
                    * sext<24>(bits(src1[lane], 23, 0));
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MUL_HI_I32_I24 class methods ---

    Inst_VOP3__V_MUL_HI_I32_I24::Inst_VOP3__V_MUL_HI_I32_I24(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mul_hi_i32_i24", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MUL_HI_I32_I24

    Inst_VOP3__V_MUL_HI_I32_I24::~Inst_VOP3__V_MUL_HI_I32_I24()
    {
    } // ~Inst_VOP3__V_MUL_HI_I32_I24

    // --- description from .arch file ---
    // D.i = (S0.i[23:0] * S1.i[23:0])>>32.
    void
    Inst_VOP3__V_MUL_HI_I32_I24::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemI64 tmp_src0
                    = (VecElemI64)sext<24>(bits(src0[lane], 23, 0));
                VecElemI64 tmp_src1
                    = (VecElemI64)sext<24>(bits(src1[lane], 23, 0));

                vdst[lane] = (VecElemI32)((tmp_src0 * tmp_src1) >> 32);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MUL_U32_U24 class methods ---

    Inst_VOP3__V_MUL_U32_U24::Inst_VOP3__V_MUL_U32_U24(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mul_u32_u24", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MUL_U32_U24

    Inst_VOP3__V_MUL_U32_U24::~Inst_VOP3__V_MUL_U32_U24()
    {
    } // ~Inst_VOP3__V_MUL_U32_U24

    // --- description from .arch file ---
    // D.u = S0.u[23:0] * S1.u[23:0].
    void
    Inst_VOP3__V_MUL_U32_U24::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = bits(src0[lane], 23, 0) * bits(src1[lane], 23, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MUL_HI_U32_U24 class methods ---

    Inst_VOP3__V_MUL_HI_U32_U24::Inst_VOP3__V_MUL_HI_U32_U24(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mul_hi_u32_u24", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MUL_HI_U32_U24

    Inst_VOP3__V_MUL_HI_U32_U24::~Inst_VOP3__V_MUL_HI_U32_U24()
    {
    } // ~Inst_VOP3__V_MUL_HI_U32_U24

    // --- description from .arch file ---
    // D.i = (S0.u[23:0] * S1.u[23:0])>>32.
    void
    Inst_VOP3__V_MUL_HI_U32_U24::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemU64 tmp_src0 = (VecElemU64)bits(src0[lane], 23, 0);
                VecElemU64 tmp_src1 = (VecElemU64)bits(src1[lane], 23, 0);
                vdst[lane] = (VecElemU32)((tmp_src0 * tmp_src1) >> 32);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MIN_F32 class methods ---

    Inst_VOP3__V_MIN_F32::Inst_VOP3__V_MIN_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_min_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_MIN_F32

    Inst_VOP3__V_MIN_F32::~Inst_VOP3__V_MIN_F32()
    {
    } // ~Inst_VOP3__V_MIN_F32

    // --- description from .arch file ---
    // D.f = (S0.f < S1.f ? S0.f : S1.f).
    void
    Inst_VOP3__V_MIN_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fmin(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAX_F32 class methods ---

    Inst_VOP3__V_MAX_F32::Inst_VOP3__V_MAX_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_max_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_MAX_F32

    Inst_VOP3__V_MAX_F32::~Inst_VOP3__V_MAX_F32()
    {
    } // ~Inst_VOP3__V_MAX_F32

    // --- description from .arch file ---
    // D.f = (S0.f >= S1.f ? S0.f : S1.f).
    void
    Inst_VOP3__V_MAX_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fmax(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MIN_I32 class methods ---

    Inst_VOP3__V_MIN_I32::Inst_VOP3__V_MIN_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_min_i32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MIN_I32

    Inst_VOP3__V_MIN_I32::~Inst_VOP3__V_MIN_I32()
    {
    } // ~Inst_VOP3__V_MIN_I32

    // --- description from .arch file ---
    // D.i = min(S0.i, S1.i).
    void
    Inst_VOP3__V_MIN_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::min(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAX_I32 class methods ---

    Inst_VOP3__V_MAX_I32::Inst_VOP3__V_MAX_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_max_i32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MAX_I32

    Inst_VOP3__V_MAX_I32::~Inst_VOP3__V_MAX_I32()
    {
    } // ~Inst_VOP3__V_MAX_I32

    // --- description from .arch file ---
    // D.i = max(S0.i, S1.i).
    void
    Inst_VOP3__V_MAX_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::max(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MIN_U32 class methods ---

    Inst_VOP3__V_MIN_U32::Inst_VOP3__V_MIN_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_min_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MIN_U32

    Inst_VOP3__V_MIN_U32::~Inst_VOP3__V_MIN_U32()
    {
    } // ~Inst_VOP3__V_MIN_U32

    // --- description from .arch file ---
    // D.u = min(S0.u, S1.u).
    void
    Inst_VOP3__V_MIN_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::min(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAX_U32 class methods ---

    Inst_VOP3__V_MAX_U32::Inst_VOP3__V_MAX_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_max_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MAX_U32

    Inst_VOP3__V_MAX_U32::~Inst_VOP3__V_MAX_U32()
    {
    } // ~Inst_VOP3__V_MAX_U32

    // --- description from .arch file ---
    // D.u = max(S0.u, S1.u).
    void
    Inst_VOP3__V_MAX_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::max(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LSHRREV_B32 class methods ---

    Inst_VOP3__V_LSHRREV_B32::Inst_VOP3__V_LSHRREV_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_lshrrev_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_LSHRREV_B32

    Inst_VOP3__V_LSHRREV_B32::~Inst_VOP3__V_LSHRREV_B32()
    {
    } // ~Inst_VOP3__V_LSHRREV_B32

    // --- description from .arch file ---
    // D.u = S1.u >> S0.u[4:0].
    // The vacated bits are set to zero.
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP3__V_LSHRREV_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] >> bits(src0[lane], 4, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_ASHRREV_I32 class methods ---

    Inst_VOP3__V_ASHRREV_I32::Inst_VOP3__V_ASHRREV_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_ashrrev_i32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_ASHRREV_I32

    Inst_VOP3__V_ASHRREV_I32::~Inst_VOP3__V_ASHRREV_I32()
    {
    } // ~Inst_VOP3__V_ASHRREV_I32

    // --- description from .arch file ---
    // D.i = signext(S1.i) >> S0.i[4:0].
    // The vacated bits are set to the sign bit of the input value.
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP3__V_ASHRREV_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] >> bits(src0[lane], 4, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LSHLREV_B32 class methods ---

    Inst_VOP3__V_LSHLREV_B32::Inst_VOP3__V_LSHLREV_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_lshlrev_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_LSHLREV_B32

    Inst_VOP3__V_LSHLREV_B32::~Inst_VOP3__V_LSHLREV_B32()
    {
    } // ~Inst_VOP3__V_LSHLREV_B32

    // --- description from .arch file ---
    // D.u = S1.u << S0.u[4:0].
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP3__V_LSHLREV_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] << bits(src0[lane], 4, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_AND_B32 class methods ---

    Inst_VOP3__V_AND_B32::Inst_VOP3__V_AND_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_and_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_AND_B32

    Inst_VOP3__V_AND_B32::~Inst_VOP3__V_AND_B32()
    {
    } // ~Inst_VOP3__V_AND_B32

    // --- description from .arch file ---
    // D.u = S0.u & S1.u.
    // Input and output modifiers not supported.
    void
    Inst_VOP3__V_AND_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] & src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_OR_B32 class methods ---

    Inst_VOP3__V_OR_B32::Inst_VOP3__V_OR_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_or_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_OR_B32

    Inst_VOP3__V_OR_B32::~Inst_VOP3__V_OR_B32()
    {
    } // ~Inst_VOP3__V_OR_B32

    // --- description from .arch file ---
    // D.u = S0.u | S1.u.
    // Input and output modifiers not supported.
    void
    Inst_VOP3__V_OR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] | src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_OR3_B32 class methods ---

    Inst_VOP3__V_OR3_B32::Inst_VOP3__V_OR3_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_or3_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_OR3_B32

    Inst_VOP3__V_OR3_B32::~Inst_VOP3__V_OR3_B32()
    {
    } // ~Inst_VOP3__V_OR3_B32

    // --- description from .arch file ---
    // D.u = S0.u | S1.u | S2.u.
    // Input and output modifiers not supported.
    void
    Inst_VOP3__V_OR3_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] | src1[lane] | src2[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_XOR_B32 class methods ---

    Inst_VOP3__V_XOR_B32::Inst_VOP3__V_XOR_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_xor_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_XOR_B32

    Inst_VOP3__V_XOR_B32::~Inst_VOP3__V_XOR_B32()
    {
    } // ~Inst_VOP3__V_XOR_B32

    // --- description from .arch file ---
    // D.u = S0.u ^ S1.u.
    // Input and output modifiers not supported.
    void
    Inst_VOP3__V_XOR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] ^ src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAC_F32 class methods ---

    Inst_VOP3__V_MAC_F32::Inst_VOP3__V_MAC_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mac_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(MAC);
    } // Inst_VOP3__V_MAC_F32

    Inst_VOP3__V_MAC_F32::~Inst_VOP3__V_MAC_F32()
    {
    } // ~Inst_VOP3__V_MAC_F32

    // --- description from .arch file ---
    // D.f = S0.f * S1.f + D.f.
    // SQ translates to V_MAD_F32.
    void
    Inst_VOP3__V_MAC_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        vdst.read();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fma(src0[lane], src1[lane], vdst[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_ADD_CO_U32 class methods ---

    Inst_VOP3__V_ADD_CO_U32::Inst_VOP3__V_ADD_CO_U32(InFmt_VOP3B *iFmt)
        : Inst_VOP3B(iFmt, "v_add_co_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
    } // Inst_VOP3__V_ADD_CO_U32

    Inst_VOP3__V_ADD_CO_U32::~Inst_VOP3__V_ADD_CO_U32()
    {
    } // ~Inst_VOP3__V_ADD_CO_U32

    // --- description from .arch file ---
    // D.u = S0.u + S1.u;
    // VCC[threadId] = (S0.u + S1.u >= 0x800000000ULL ? 1 : 0) is an UNSIGNED
    // ---  overflow or carry-out for V_ADDC_U32.
    // In VOP3 the VCC destination may be an arbitrary SGPR-pair.
    void
    Inst_VOP3__V_ADD_CO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        ScalarOperandU64 vcc(gpuDynInst, instData.SDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] + src1[lane];
                vcc.setBit(lane, ((VecElemU64)src0[lane]
                    + (VecElemU64)src1[lane]) >= 0x100000000ULL ? 1 : 0);
            }
        }

        vdst.write();
        vcc.write();
    } // execute
    // --- Inst_VOP3__V_SUB_CO_U32 class methods ---

    Inst_VOP3__V_SUB_CO_U32::Inst_VOP3__V_SUB_CO_U32(InFmt_VOP3B *iFmt)
        : Inst_VOP3B(iFmt, "v_sub_co_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
    } // Inst_VOP3__V_SUB_CO_U32

    Inst_VOP3__V_SUB_CO_U32::~Inst_VOP3__V_SUB_CO_U32()
    {
    } // ~Inst_VOP3__V_SUB_CO_U32

    // --- description from .arch file ---
    // D.u = S0.u - S1.u;
    // VCC[threadId] = (S1.u > S0.u ? 1 : 0) is an UNSIGNED overflow or
    // carry-out for V_SUBB_U32.
    // In VOP3 the VCC destination may be an arbitrary SGPR-pair.
    void
    Inst_VOP3__V_SUB_CO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        ScalarOperandU64 vcc(gpuDynInst, instData.SDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] - src1[lane];
                vcc.setBit(lane, src1[lane] > src0[lane] ? 1 : 0);
            }
        }

        vdst.write();
        vcc.write();
    } // execute
    // --- Inst_VOP3__V_SUBREV_CO_U32 class methods ---

    Inst_VOP3__V_SUBREV_CO_U32::Inst_VOP3__V_SUBREV_CO_U32(
          InFmt_VOP3B *iFmt)
        : Inst_VOP3B(iFmt, "v_subrev_co_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
    } // Inst_VOP3__V_SUBREV_CO_U32

    Inst_VOP3__V_SUBREV_CO_U32::~Inst_VOP3__V_SUBREV_CO_U32()
    {
    } // ~Inst_VOP3__V_SUBREV_CO_U32

    // --- description from .arch file ---
    // D.u = S1.u - S0.u;
    // VCC[threadId] = (S0.u > S1.u ? 1 : 0) is an UNSIGNED overflow or
    // carry-out for V_SUBB_U32.
    // In VOP3 the VCC destination may be an arbitrary SGPR-pair.
    // SQ translates this to V_SUB_U32 with reversed operands.
    void
    Inst_VOP3__V_SUBREV_CO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        ScalarOperandU64 vcc(gpuDynInst, instData.SDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] - src0[lane];
                vcc.setBit(lane, src0[lane] > src1[lane] ? 1 : 0);
            }
        }

        vdst.write();
        vcc.write();
    } // execute
    // --- Inst_VOP3__V_ADDC_CO_U32 class methods ---

    Inst_VOP3__V_ADDC_CO_U32::Inst_VOP3__V_ADDC_CO_U32(InFmt_VOP3B *iFmt)
        : Inst_VOP3B(iFmt, "v_addc_co_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
        setFlag(ReadsVCC);
    } // Inst_VOP3__V_ADDC_CO_U32

    Inst_VOP3__V_ADDC_CO_U32::~Inst_VOP3__V_ADDC_CO_U32()
    {
    } // ~Inst_VOP3__V_ADDC_CO_U32

    // --- description from .arch file ---
    // D.u = S0.u + S1.u + VCC[threadId];
    // VCC[threadId] = (S0.u + S1.u + VCC[threadId] >= 0x800000000ULL ? 1 : 0)
    // is an UNSIGNED overflow.
    // In VOP3 the VCC destination may be an arbitrary SGPR-pair, and the VCC
    // source comes from the SGPR-pair at S2.u.
    void
    Inst_VOP3__V_ADDC_CO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstScalarOperandU64 vcc(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);

        src0.readSrc();
        src1.readSrc();
        vcc.read();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] + src1[lane]
                    + bits(vcc.rawData(), lane);
                sdst.setBit(lane, ((VecElemU64)src0[lane]
                    + (VecElemU64)src1[lane]
                        + (VecElemU64)bits(vcc.rawData(), lane))
                            >= 0x100000000 ? 1 : 0);
            }
        }

        vdst.write();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_SUBB_CO_U32 class methods ---

    Inst_VOP3__V_SUBB_CO_U32::Inst_VOP3__V_SUBB_CO_U32(InFmt_VOP3B *iFmt)
        : Inst_VOP3B(iFmt, "v_subb_co_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
        setFlag(ReadsVCC);
    } // Inst_VOP3__V_SUBB_CO_U32

    Inst_VOP3__V_SUBB_CO_U32::~Inst_VOP3__V_SUBB_CO_U32()
    {
    } // ~Inst_VOP3__V_SUBB_CO_U32

    // --- description from .arch file ---
    // D.u = S0.u - S1.u - VCC[threadId];
    // VCC[threadId] = (S1.u + VCC[threadId] > S0.u ? 1 : 0) is an UNSIGNED
    // ---  overflow.
    // In VOP3 the VCC destination may be an arbitrary SGPR-pair, and the VCC
    // ---  source comes from the SGPR-pair at S2.u.
    void
    Inst_VOP3__V_SUBB_CO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstScalarOperandU64 vcc(gpuDynInst, extData.SRC2);
        ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        vcc.read();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] - src1[lane]
                    - bits(vcc.rawData(), lane);
                sdst.setBit(lane, (src1[lane] + bits(vcc.rawData(), lane))
                    > src0[lane] ? 1 : 0);
            }
        }

        vdst.write();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_SUBBREV_CO_U32 class methods ---

    Inst_VOP3__V_SUBBREV_CO_U32::Inst_VOP3__V_SUBBREV_CO_U32(
          InFmt_VOP3B *iFmt)
        : Inst_VOP3B(iFmt, "v_subbrev_co_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
        setFlag(ReadsVCC);
    } // Inst_VOP3__V_SUBBREV_CO_U32

    Inst_VOP3__V_SUBBREV_CO_U32::~Inst_VOP3__V_SUBBREV_CO_U32()
    {
    } // ~Inst_VOP3__V_SUBBREV_CO_U32

    // --- description from .arch file ---
    // D.u = S1.u - S0.u - VCC[threadId];
    // VCC[threadId] = (S1.u + VCC[threadId] > S0.u ? 1 : 0) is an UNSIGNED
    // overflow.
    // In VOP3 the VCC destination may be an arbitrary SGPR-pair, and the VCC
    // source comes from the SGPR-pair at S2.u. SQ translates to V_SUBB_U32.
    void
    Inst_VOP3__V_SUBBREV_CO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstScalarOperandU64 sdst(gpuDynInst, instData.SDST);
        ScalarOperandU64 vcc(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        vcc.read();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] - src0[lane]
                    - bits(vcc.rawData(), lane);
                sdst.setBit(lane, (src1[lane] + bits(vcc.rawData(), lane))
                    > src0[lane] ? 1 : 0);
            }
        }

        vdst.write();
        sdst.write();
    } // execute
    // --- Inst_VOP3__V_ADD_F16 class methods ---

    Inst_VOP3__V_ADD_F16::Inst_VOP3__V_ADD_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_add_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_ADD_F16

    Inst_VOP3__V_ADD_F16::~Inst_VOP3__V_ADD_F16()
    {
    } // ~Inst_VOP3__V_ADD_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 + S1.f16.
    // Supports denormals, round mode, exception flags, saturation.
    void
    Inst_VOP3__V_ADD_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_SUB_F16 class methods ---

    Inst_VOP3__V_SUB_F16::Inst_VOP3__V_SUB_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_sub_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_SUB_F16

    Inst_VOP3__V_SUB_F16::~Inst_VOP3__V_SUB_F16()
    {
    } // ~Inst_VOP3__V_SUB_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 - S1.f16.
    // Supports denormals, round mode, exception flags, saturation.
    // SQ translates to V_ADD_F16.
    void
    Inst_VOP3__V_SUB_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_SUBREV_F16 class methods ---

    Inst_VOP3__V_SUBREV_F16::Inst_VOP3__V_SUBREV_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_subrev_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_SUBREV_F16

    Inst_VOP3__V_SUBREV_F16::~Inst_VOP3__V_SUBREV_F16()
    {
    } // ~Inst_VOP3__V_SUBREV_F16

    // --- description from .arch file ---
    // D.f16 = S1.f16 - S0.f16.
    // Supports denormals, round mode, exception flags, saturation.
    // SQ translates to V_ADD_F16.
    void
    Inst_VOP3__V_SUBREV_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_MUL_F16 class methods ---

    Inst_VOP3__V_MUL_F16::Inst_VOP3__V_MUL_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mul_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_MUL_F16

    Inst_VOP3__V_MUL_F16::~Inst_VOP3__V_MUL_F16()
    {
    } // ~Inst_VOP3__V_MUL_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 * S1.f16.
    // Supports denormals, round mode, exception flags, saturation.
    void
    Inst_VOP3__V_MUL_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_MAC_F16 class methods ---

    Inst_VOP3__V_MAC_F16::Inst_VOP3__V_MAC_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mac_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(MAC);
    } // Inst_VOP3__V_MAC_F16

    Inst_VOP3__V_MAC_F16::~Inst_VOP3__V_MAC_F16()
    {
    } // ~Inst_VOP3__V_MAC_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 * S1.f16 + D.f16.
    // Supports round mode, exception flags, saturation.
    // SQ translates this to V_MAD_F16.
    void
    Inst_VOP3__V_MAC_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_ADD_U16 class methods ---

    Inst_VOP3__V_ADD_U16::Inst_VOP3__V_ADD_U16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_add_u16", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_ADD_U16

    Inst_VOP3__V_ADD_U16::~Inst_VOP3__V_ADD_U16()
    {
    } // ~Inst_VOP3__V_ADD_U16

    // --- description from .arch file ---
    // D.u16 = S0.u16 + S1.u16.
    // Supports saturation (unsigned 16-bit integer domain).
    void
    Inst_VOP3__V_ADD_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] + src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_SUB_U16 class methods ---

    Inst_VOP3__V_SUB_U16::Inst_VOP3__V_SUB_U16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_sub_u16", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_SUB_U16

    Inst_VOP3__V_SUB_U16::~Inst_VOP3__V_SUB_U16()
    {
    } // ~Inst_VOP3__V_SUB_U16

    // --- description from .arch file ---
    // D.u16 = S0.u16 - S1.u16.
    // Supports saturation (unsigned 16-bit integer domain).
    void
    Inst_VOP3__V_SUB_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] - src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_SUBREV_U16 class methods ---

    Inst_VOP3__V_SUBREV_U16::Inst_VOP3__V_SUBREV_U16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_subrev_u16", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_SUBREV_U16

    Inst_VOP3__V_SUBREV_U16::~Inst_VOP3__V_SUBREV_U16()
    {
    } // ~Inst_VOP3__V_SUBREV_U16

    // --- description from .arch file ---
    // D.u16 = S1.u16 - S0.u16.
    // Supports saturation (unsigned 16-bit integer domain).
    // SQ translates this to V_SUB_U16 with reversed operands.
    void
    Inst_VOP3__V_SUBREV_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] - src0[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MUL_LO_U16 class methods ---

    Inst_VOP3__V_MUL_LO_U16::Inst_VOP3__V_MUL_LO_U16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mul_lo_u16", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MUL_LO_U16

    Inst_VOP3__V_MUL_LO_U16::~Inst_VOP3__V_MUL_LO_U16()
    {
    } // ~Inst_VOP3__V_MUL_LO_U16

    // --- description from .arch file ---
    // D.u16 = S0.u16 * S1.u16.
    // Supports saturation (unsigned 16-bit integer domain).
    void
    Inst_VOP3__V_MUL_LO_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] * src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LSHLREV_B16 class methods ---

    Inst_VOP3__V_LSHLREV_B16::Inst_VOP3__V_LSHLREV_B16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_lshlrev_b16", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_LSHLREV_B16

    Inst_VOP3__V_LSHLREV_B16::~Inst_VOP3__V_LSHLREV_B16()
    {
    } // ~Inst_VOP3__V_LSHLREV_B16

    // --- description from .arch file ---
    // D.u[15:0] = S1.u[15:0] << S0.u[3:0].
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP3__V_LSHLREV_B16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] << bits(src0[lane], 3, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LSHRREV_B16 class methods ---

    Inst_VOP3__V_LSHRREV_B16::Inst_VOP3__V_LSHRREV_B16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_lshrrev_b16", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_LSHRREV_B16

    Inst_VOP3__V_LSHRREV_B16::~Inst_VOP3__V_LSHRREV_B16()
    {
    } // ~Inst_VOP3__V_LSHRREV_B16

    // --- description from .arch file ---
    // D.u[15:0] = S1.u[15:0] >> S0.u[3:0].
    // The vacated bits are set to zero.
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP3__V_LSHRREV_B16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] >> bits(src0[lane], 3, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_ASHRREV_I16 class methods ---

    Inst_VOP3__V_ASHRREV_I16::Inst_VOP3__V_ASHRREV_I16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_ashrrev_i16", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_ASHRREV_I16

    Inst_VOP3__V_ASHRREV_I16::~Inst_VOP3__V_ASHRREV_I16()
    {
    } // ~Inst_VOP3__V_ASHRREV_I16

    // --- description from .arch file ---
    // D.i[15:0] = signext(S1.i[15:0]) >> S0.i[3:0].
    // The vacated bits are set to the sign bit of the input value.
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP3__V_ASHRREV_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        VecOperandI16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] >> bits(src0[lane], 3, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAX_F16 class methods ---

    Inst_VOP3__V_MAX_F16::Inst_VOP3__V_MAX_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_max_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_MAX_F16

    Inst_VOP3__V_MAX_F16::~Inst_VOP3__V_MAX_F16()
    {
    } // ~Inst_VOP3__V_MAX_F16

    // --- description from .arch file ---
    // D.f16 = max(S0.f16, S1.f16).
    // IEEE compliant. Supports denormals, round mode, exception flags,
    // saturation.
    void
    Inst_VOP3__V_MAX_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_MIN_F16 class methods ---

    Inst_VOP3__V_MIN_F16::Inst_VOP3__V_MIN_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_min_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_MIN_F16

    Inst_VOP3__V_MIN_F16::~Inst_VOP3__V_MIN_F16()
    {
    } // ~Inst_VOP3__V_MIN_F16

    // --- description from .arch file ---
    // D.f16 = min(S0.f16, S1.f16).
    // IEEE compliant. Supports denormals, round mode, exception flags,
    // saturation.
    void
    Inst_VOP3__V_MIN_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_MAX_U16 class methods ---

    Inst_VOP3__V_MAX_U16::Inst_VOP3__V_MAX_U16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_max_u16", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MAX_U16

    Inst_VOP3__V_MAX_U16::~Inst_VOP3__V_MAX_U16()
    {
    } // ~Inst_VOP3__V_MAX_U16

    // --- description from .arch file ---
    // D.u[15:0] = max(S0.u[15:0], S1.u[15:0]).
    void
    Inst_VOP3__V_MAX_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::max(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAX_I16 class methods ---

    Inst_VOP3__V_MAX_I16::Inst_VOP3__V_MAX_I16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_max_i16", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MAX_I16

    Inst_VOP3__V_MAX_I16::~Inst_VOP3__V_MAX_I16()
    {
    } // ~Inst_VOP3__V_MAX_I16

    // --- description from .arch file ---
    // D.i[15:0] = max(S0.i[15:0], S1.i[15:0]).
    void
    Inst_VOP3__V_MAX_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        VecOperandI16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::max(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MIN_U16 class methods ---

    Inst_VOP3__V_MIN_U16::Inst_VOP3__V_MIN_U16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_min_u16", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MIN_U16

    Inst_VOP3__V_MIN_U16::~Inst_VOP3__V_MIN_U16()
    {
    } // ~Inst_VOP3__V_MIN_U16

    // --- description from .arch file ---
    // D.u[15:0] = min(S0.u[15:0], S1.u[15:0]).
    void
    Inst_VOP3__V_MIN_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::min(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MIN_I16 class methods ---

    Inst_VOP3__V_MIN_I16::Inst_VOP3__V_MIN_I16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_min_i16", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MIN_I16

    Inst_VOP3__V_MIN_I16::~Inst_VOP3__V_MIN_I16()
    {
    } // ~Inst_VOP3__V_MIN_I16

    // --- description from .arch file ---
    // D.i[15:0] = min(S0.i[15:0], S1.i[15:0]).
    void
    Inst_VOP3__V_MIN_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        VecOperandI16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::min(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LDEXP_F16 class methods ---

    Inst_VOP3__V_LDEXP_F16::Inst_VOP3__V_LDEXP_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_ldexp_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_LDEXP_F16

    Inst_VOP3__V_LDEXP_F16::~Inst_VOP3__V_LDEXP_F16()
    {
    } // ~Inst_VOP3__V_LDEXP_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 * (2 ** S1.i16).
    void
    Inst_VOP3__V_LDEXP_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_NOP class methods ---

    Inst_VOP3__V_NOP::Inst_VOP3__V_NOP(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_nop", false)
    {
        setFlag(Nop);
        setFlag(ALU);
    } // Inst_VOP3__V_NOP

    Inst_VOP3__V_NOP::~Inst_VOP3__V_NOP()
    {
    } // ~Inst_VOP3__V_NOP

    // --- description from .arch file ---
    // Do nothing.
    void
    Inst_VOP3__V_NOP::execute(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_VOP3__V_MOV_B32 class methods ---

    Inst_VOP3__V_MOV_B32::Inst_VOP3__V_MOV_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mov_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MOV_B32

    Inst_VOP3__V_MOV_B32::~Inst_VOP3__V_MOV_B32()
    {
    } // ~Inst_VOP3__V_MOV_B32

    // --- description from .arch file ---
    // D.u = S0.u.
    // Input and output modifiers not supported; this is an untyped operation.
    void
    Inst_VOP3__V_MOV_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, extData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_I32_F64 class methods ---

    Inst_VOP3__V_CVT_I32_F64::Inst_VOP3__V_CVT_I32_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_i32_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CVT_I32_F64

    Inst_VOP3__V_CVT_I32_F64::~Inst_VOP3__V_CVT_I32_F64()
    {
    } // ~Inst_VOP3__V_CVT_I32_F64

    // --- description from .arch file ---
    // D.i = (int)S0.d.
    // Out-of-range floating point values (including infinity) saturate. NaN is
    // ---  converted to 0.
    void
    Inst_VOP3__V_CVT_I32_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                int exp;
                std::frexp(src[lane],&exp);
                if (std::isnan(src[lane])) {
                    vdst[lane] = 0;
                } else if (std::isinf(src[lane]) || exp > 30) {
                    if (std::signbit(src[lane])) {
                        vdst[lane] = INT_MIN;
                    } else {
                        vdst[lane] = INT_MAX;
                    }
                } else {
                    vdst[lane] = (VecElemI32)src[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_F64_I32 class methods ---

    Inst_VOP3__V_CVT_F64_I32::Inst_VOP3__V_CVT_F64_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f64_i32", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CVT_F64_I32

    Inst_VOP3__V_CVT_F64_I32::~Inst_VOP3__V_CVT_F64_I32()
    {
    } // ~Inst_VOP3__V_CVT_F64_I32

    // --- description from .arch file ---
    // D.d = (double)S0.i.
    void
    Inst_VOP3__V_CVT_F64_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src(gpuDynInst, extData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF64)src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_F32_I32 class methods ---

    Inst_VOP3__V_CVT_F32_I32::Inst_VOP3__V_CVT_F32_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f32_i32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_F32_I32

    Inst_VOP3__V_CVT_F32_I32::~Inst_VOP3__V_CVT_F32_I32()
    {
    } // ~Inst_VOP3__V_CVT_F32_I32

    // --- description from .arch file ---
    // D.f = (float)S0.i.
    void
    Inst_VOP3__V_CVT_F32_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        VecOperandI32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_F32_U32 class methods ---

    Inst_VOP3__V_CVT_F32_U32::Inst_VOP3__V_CVT_F32_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f32_u32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_F32_U32

    Inst_VOP3__V_CVT_F32_U32::~Inst_VOP3__V_CVT_F32_U32()
    {
    } // ~Inst_VOP3__V_CVT_F32_U32

    // --- description from .arch file ---
    // D.f = (float)S0.u.
    void
    Inst_VOP3__V_CVT_F32_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_U32_F32 class methods ---

    Inst_VOP3__V_CVT_U32_F32::Inst_VOP3__V_CVT_U32_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_u32_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_U32_F32

    Inst_VOP3__V_CVT_U32_F32::~Inst_VOP3__V_CVT_U32_F32()
    {
    } // ~Inst_VOP3__V_CVT_U32_F32

    // --- description from .arch file ---
    // D.u = (unsigned)S0.f.
    // Out-of-range floating point values (including infinity) saturate. NaN is
    // ---  converted to 0.
    void
    Inst_VOP3__V_CVT_U32_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                int exp;
                std::frexp(src[lane],&exp);
                if (std::isnan(src[lane])) {
                    vdst[lane] = 0;
                } else if (std::isinf(src[lane])) {
                    if (std::signbit(src[lane])) {
                        vdst[lane] = 0;
                    } else {
                        vdst[lane] = UINT_MAX;
                    }
                } else if (exp > 31) {
                    vdst[lane] = UINT_MAX;
                } else {
                    vdst[lane] = (VecElemU32)src[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_I32_F32 class methods ---

    Inst_VOP3__V_CVT_I32_F32::Inst_VOP3__V_CVT_I32_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_i32_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_I32_F32

    Inst_VOP3__V_CVT_I32_F32::~Inst_VOP3__V_CVT_I32_F32()
    {
    } // ~Inst_VOP3__V_CVT_I32_F32

    // --- description from .arch file ---
    // D.i = (int)S0.f.
    // Out-of-range floating point values (including infinity) saturate. NaN is
    // ---  converted to 0.
    void
    Inst_VOP3__V_CVT_I32_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                int exp;
                std::frexp(src[lane],&exp);
                if (std::isnan(src[lane])) {
                    vdst[lane] = 0;
                } else if (std::isinf(src[lane]) || exp > 30) {
                    if (std::signbit(src[lane])) {
                        vdst[lane] = INT_MIN;
                    } else {
                        vdst[lane] = INT_MAX;
                    }
                } else {
                    vdst[lane] = (VecElemI32)src[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MOV_FED_B32 class methods ---

    Inst_VOP3__V_MOV_FED_B32::Inst_VOP3__V_MOV_FED_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mov_fed_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MOV_FED_B32

    Inst_VOP3__V_MOV_FED_B32::~Inst_VOP3__V_MOV_FED_B32()
    {
    } // ~Inst_VOP3__V_MOV_FED_B32

    // --- description from .arch file ---
    // D.u = S0.u;
    // Introduce EDC double error upon write to dest vgpr without causing an
    // ---  exception.
    // Input and output modifiers not supported; this is an untyped operation.
    void
    Inst_VOP3__V_MOV_FED_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_F16_F32 class methods ---

    Inst_VOP3__V_CVT_F16_F32::Inst_VOP3__V_CVT_F16_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f16_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_F16_F32

    Inst_VOP3__V_CVT_F16_F32::~Inst_VOP3__V_CVT_F16_F32()
    {
    } // ~Inst_VOP3__V_CVT_F16_F32

    // --- description from .arch file ---
    // D.f16 = flt32_to_flt16(S0.f).
    // Supports input modifiers and creates FP16 denormals when appropriate.
    void
    Inst_VOP3__V_CVT_F16_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_F32_F16 class methods ---

    Inst_VOP3__V_CVT_F32_F16::Inst_VOP3__V_CVT_F32_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f32_f16", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_F32_F16

    Inst_VOP3__V_CVT_F32_F16::~Inst_VOP3__V_CVT_F32_F16()
    {
    } // ~Inst_VOP3__V_CVT_F32_F16

    // --- description from .arch file ---
    // D.f = flt16_to_flt32(S0.f16).
    // FP16 denormal inputs are always accepted.
    void
    Inst_VOP3__V_CVT_F32_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_RPI_I32_F32 class methods ---

    Inst_VOP3__V_CVT_RPI_I32_F32::Inst_VOP3__V_CVT_RPI_I32_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_rpi_i32_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_RPI_I32_F32

    Inst_VOP3__V_CVT_RPI_I32_F32::~Inst_VOP3__V_CVT_RPI_I32_F32()
    {
    } // ~Inst_VOP3__V_CVT_RPI_I32_F32

    // --- description from .arch file ---
    // D.i = (int)floor(S0.f + 0.5).
    void
    Inst_VOP3__V_CVT_RPI_I32_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemI32)std::floor(src[lane] + 0.5);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_FLR_I32_F32 class methods ---

    Inst_VOP3__V_CVT_FLR_I32_F32::Inst_VOP3__V_CVT_FLR_I32_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_flr_i32_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_FLR_I32_F32

    Inst_VOP3__V_CVT_FLR_I32_F32::~Inst_VOP3__V_CVT_FLR_I32_F32()
    {
    } // ~Inst_VOP3__V_CVT_FLR_I32_F32

    // --- description from .arch file ---
    // D.i = (int)floor(S0.f).
    void
    Inst_VOP3__V_CVT_FLR_I32_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemI32)std::floor(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_OFF_F32_I4 class methods ---

    Inst_VOP3__V_CVT_OFF_F32_I4::Inst_VOP3__V_CVT_OFF_F32_I4(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_off_f32_i4", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_OFF_F32_I4

    Inst_VOP3__V_CVT_OFF_F32_I4::~Inst_VOP3__V_CVT_OFF_F32_I4()
    {
    } // ~Inst_VOP3__V_CVT_OFF_F32_I4

    // --- description from .arch file ---
    // 4-bit signed int to 32-bit float. Used for interpolation in shader.
    void
    Inst_VOP3__V_CVT_OFF_F32_I4::execute(GPUDynInstPtr gpuDynInst)
    {
        // Could not parse sq_uc.arch desc field
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_F32_F64 class methods ---

    Inst_VOP3__V_CVT_F32_F64::Inst_VOP3__V_CVT_F32_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f32_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CVT_F32_F64

    Inst_VOP3__V_CVT_F32_F64::~Inst_VOP3__V_CVT_F32_F64()
    {
    } // ~Inst_VOP3__V_CVT_F32_F64

    // --- description from .arch file ---
    // D.f = (float)S0.d.
    void
    Inst_VOP3__V_CVT_F32_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_F64_F32 class methods ---

    Inst_VOP3__V_CVT_F64_F32::Inst_VOP3__V_CVT_F64_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f64_f32", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CVT_F64_F32

    Inst_VOP3__V_CVT_F64_F32::~Inst_VOP3__V_CVT_F64_F32()
    {
    } // ~Inst_VOP3__V_CVT_F64_F32

    // --- description from .arch file ---
    // D.d = (double)S0.f.
    void
    Inst_VOP3__V_CVT_F64_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF64)src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_F32_UBYTE0 class methods ---

    Inst_VOP3__V_CVT_F32_UBYTE0::Inst_VOP3__V_CVT_F32_UBYTE0(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f32_ubyte0", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_F32_UBYTE0

    Inst_VOP3__V_CVT_F32_UBYTE0::~Inst_VOP3__V_CVT_F32_UBYTE0()
    {
    } // ~Inst_VOP3__V_CVT_F32_UBYTE0

    // --- description from .arch file ---
    // D.f = (float)(S0.u[7:0]).
    void
    Inst_VOP3__V_CVT_F32_UBYTE0::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)bits(src[lane], 7, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_F32_UBYTE1 class methods ---

    Inst_VOP3__V_CVT_F32_UBYTE1::Inst_VOP3__V_CVT_F32_UBYTE1(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f32_ubyte1", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_F32_UBYTE1

    Inst_VOP3__V_CVT_F32_UBYTE1::~Inst_VOP3__V_CVT_F32_UBYTE1()
    {
    } // ~Inst_VOP3__V_CVT_F32_UBYTE1

    // --- description from .arch file ---
    // D.f = (float)(S0.u[15:8]).
    void
    Inst_VOP3__V_CVT_F32_UBYTE1::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)bits(src[lane], 15, 8);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_F32_UBYTE2 class methods ---

    Inst_VOP3__V_CVT_F32_UBYTE2::Inst_VOP3__V_CVT_F32_UBYTE2(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f32_ubyte2", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_F32_UBYTE2

    Inst_VOP3__V_CVT_F32_UBYTE2::~Inst_VOP3__V_CVT_F32_UBYTE2()
    {
    } // ~Inst_VOP3__V_CVT_F32_UBYTE2

    // --- description from .arch file ---
    // D.f = (float)(S0.u[23:16]).
    void
    Inst_VOP3__V_CVT_F32_UBYTE2::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)bits(src[lane], 23, 16);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_F32_UBYTE3 class methods ---

    Inst_VOP3__V_CVT_F32_UBYTE3::Inst_VOP3__V_CVT_F32_UBYTE3(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f32_ubyte3", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_F32_UBYTE3

    Inst_VOP3__V_CVT_F32_UBYTE3::~Inst_VOP3__V_CVT_F32_UBYTE3()
    {
    } // ~Inst_VOP3__V_CVT_F32_UBYTE3

    // --- description from .arch file ---
    // D.f = (float)(S0.u[31:24]).
    void
    Inst_VOP3__V_CVT_F32_UBYTE3::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF32)bits(src[lane], 31, 24);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_U32_F64 class methods ---

    Inst_VOP3__V_CVT_U32_F64::Inst_VOP3__V_CVT_U32_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_u32_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CVT_U32_F64

    Inst_VOP3__V_CVT_U32_F64::~Inst_VOP3__V_CVT_U32_F64()
    {
    } // ~Inst_VOP3__V_CVT_U32_F64

    // --- description from .arch file ---
    // D.u = (unsigned)S0.d.
    // Out-of-range floating point values (including infinity) saturate. NaN is
    // ---  converted to 0.
    void
    Inst_VOP3__V_CVT_U32_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                int exp;
                std::frexp(src[lane],&exp);
                if (std::isnan(src[lane])) {
                    vdst[lane] = 0;
                } else if (std::isinf(src[lane])) {
                    if (std::signbit(src[lane])) {
                        vdst[lane] = 0;
                    } else {
                        vdst[lane] = UINT_MAX;
                    }
                } else if (exp > 31) {
                    vdst[lane] = UINT_MAX;
                } else {
                    vdst[lane] = (VecElemU32)src[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_F64_U32 class methods ---

    Inst_VOP3__V_CVT_F64_U32::Inst_VOP3__V_CVT_F64_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f64_u32", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CVT_F64_U32

    Inst_VOP3__V_CVT_F64_U32::~Inst_VOP3__V_CVT_F64_U32()
    {
    } // ~Inst_VOP3__V_CVT_F64_U32

    // --- description from .arch file ---
    // D.d = (double)S0.u.
    void
    Inst_VOP3__V_CVT_F64_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, extData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (VecElemF64)src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_TRUNC_F64 class methods ---

    Inst_VOP3__V_TRUNC_F64::Inst_VOP3__V_TRUNC_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_trunc_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_TRUNC_F64

    Inst_VOP3__V_TRUNC_F64::~Inst_VOP3__V_TRUNC_F64()
    {
    } // ~Inst_VOP3__V_TRUNC_F64

    // --- description from .arch file ---
    // D.d = trunc(S0.d), return integer part of S0.d.
    void
    Inst_VOP3__V_TRUNC_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::trunc(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CEIL_F64 class methods ---

    Inst_VOP3__V_CEIL_F64::Inst_VOP3__V_CEIL_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_ceil_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_CEIL_F64

    Inst_VOP3__V_CEIL_F64::~Inst_VOP3__V_CEIL_F64()
    {
    } // ~Inst_VOP3__V_CEIL_F64

    // --- description from .arch file ---
    // D.d = trunc(S0.d);
    // if(S0.d > 0.0 && S0.d != D.d) then D.d += 1.0.
    void
    Inst_VOP3__V_CEIL_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::ceil(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_RNDNE_F64 class methods ---

    Inst_VOP3__V_RNDNE_F64::Inst_VOP3__V_RNDNE_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_rndne_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_RNDNE_F64

    Inst_VOP3__V_RNDNE_F64::~Inst_VOP3__V_RNDNE_F64()
    {
    } // ~Inst_VOP3__V_RNDNE_F64

    // --- description from .arch file ---
    // D.d = round_nearest_even(S0.d).
    void
    Inst_VOP3__V_RNDNE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = roundNearestEven(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FLOOR_F64 class methods ---

    Inst_VOP3__V_FLOOR_F64::Inst_VOP3__V_FLOOR_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_floor_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_FLOOR_F64

    Inst_VOP3__V_FLOOR_F64::~Inst_VOP3__V_FLOOR_F64()
    {
    } // ~Inst_VOP3__V_FLOOR_F64

    // --- description from .arch file ---
    // D.d = trunc(S0.d);
    // if(S0.d < 0.0 && S0.d != D.d) then D.d += -1.0.
    void
    Inst_VOP3__V_FLOOR_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::floor(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FRACT_F32 class methods ---

    Inst_VOP3__V_FRACT_F32::Inst_VOP3__V_FRACT_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_fract_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_FRACT_F32

    Inst_VOP3__V_FRACT_F32::~Inst_VOP3__V_FRACT_F32()
    {
    } // ~Inst_VOP3__V_FRACT_F32

    // --- description from .arch file ---
    // D.f = S0.f - floor(S0.f).
    void
    Inst_VOP3__V_FRACT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemF32 int_part(0.0);
                vdst[lane] = std::modf(src[lane], &int_part);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_TRUNC_F32 class methods ---

    Inst_VOP3__V_TRUNC_F32::Inst_VOP3__V_TRUNC_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_trunc_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_TRUNC_F32

    Inst_VOP3__V_TRUNC_F32::~Inst_VOP3__V_TRUNC_F32()
    {
    } // ~Inst_VOP3__V_TRUNC_F32

    // --- description from .arch file ---
    // D.f = trunc(S0.f), return integer part of S0.f.
    void
    Inst_VOP3__V_TRUNC_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::trunc(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CEIL_F32 class methods ---

    Inst_VOP3__V_CEIL_F32::Inst_VOP3__V_CEIL_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_ceil_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CEIL_F32

    Inst_VOP3__V_CEIL_F32::~Inst_VOP3__V_CEIL_F32()
    {
    } // ~Inst_VOP3__V_CEIL_F32

    // --- description from .arch file ---
    // D.f = trunc(S0.f);
    // if(S0.f > 0.0 && S0.f != D.f) then D.f += 1.0.
    void
    Inst_VOP3__V_CEIL_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::ceil(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_RNDNE_F32 class methods ---

    Inst_VOP3__V_RNDNE_F32::Inst_VOP3__V_RNDNE_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_rndne_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_RNDNE_F32

    Inst_VOP3__V_RNDNE_F32::~Inst_VOP3__V_RNDNE_F32()
    {
    } // ~Inst_VOP3__V_RNDNE_F32

    // --- description from .arch file ---
    // D.f = round_nearest_even(S0.f).
    void
    Inst_VOP3__V_RNDNE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = roundNearestEven(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FLOOR_F32 class methods ---

    Inst_VOP3__V_FLOOR_F32::Inst_VOP3__V_FLOOR_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_floor_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_FLOOR_F32

    Inst_VOP3__V_FLOOR_F32::~Inst_VOP3__V_FLOOR_F32()
    {
    } // ~Inst_VOP3__V_FLOOR_F32

    // --- description from .arch file ---
    // D.f = trunc(S0.f);
    // if(S0.f < 0.0 && S0.f != D.f) then D.f += -1.0.
    void
    Inst_VOP3__V_FLOOR_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::floor(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_EXP_F32 class methods ---

    Inst_VOP3__V_EXP_F32::Inst_VOP3__V_EXP_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_exp_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_EXP_F32

    Inst_VOP3__V_EXP_F32::~Inst_VOP3__V_EXP_F32()
    {
    } // ~Inst_VOP3__V_EXP_F32

    // --- description from .arch file ---
    // D.f = pow(2.0, S0.f).
    void
    Inst_VOP3__V_EXP_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::pow(2.0, src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LOG_F32 class methods ---

    Inst_VOP3__V_LOG_F32::Inst_VOP3__V_LOG_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_log_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_LOG_F32

    Inst_VOP3__V_LOG_F32::~Inst_VOP3__V_LOG_F32()
    {
    } // ~Inst_VOP3__V_LOG_F32

    // --- description from .arch file ---
    // D.f = log2(S0.f). Base 2 logarithm.
    void
    Inst_VOP3__V_LOG_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::log2(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_RCP_F32 class methods ---

    Inst_VOP3__V_RCP_F32::Inst_VOP3__V_RCP_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_rcp_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_RCP_F32

    Inst_VOP3__V_RCP_F32::~Inst_VOP3__V_RCP_F32()
    {
    } // ~Inst_VOP3__V_RCP_F32

    // --- description from .arch file ---
    // D.f = 1.0 / S0.f. Reciprocal with IEEE rules and < 1ulp error.
    void
    Inst_VOP3__V_RCP_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = 1.0 / src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_RCP_IFLAG_F32 class methods ---

    Inst_VOP3__V_RCP_IFLAG_F32::Inst_VOP3__V_RCP_IFLAG_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_rcp_iflag_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_RCP_IFLAG_F32

    Inst_VOP3__V_RCP_IFLAG_F32::~Inst_VOP3__V_RCP_IFLAG_F32()
    {
    } // ~Inst_VOP3__V_RCP_IFLAG_F32

    // --- description from .arch file ---
    // D.f = 1.0 / S0.f. Reciprocal intended for integer division, can raise
    // ---  integer DIV_BY_ZERO exception but cannot raise floating-point
    // ---  exceptions.
    void
    Inst_VOP3__V_RCP_IFLAG_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = 1.0 / src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_RSQ_F32 class methods ---

    Inst_VOP3__V_RSQ_F32::Inst_VOP3__V_RSQ_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_rsq_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_RSQ_F32

    Inst_VOP3__V_RSQ_F32::~Inst_VOP3__V_RSQ_F32()
    {
    } // ~Inst_VOP3__V_RSQ_F32

    // --- description from .arch file ---
    // D.f = 1.0 / sqrt(S0.f). Reciprocal square root with IEEE rules.
    void
    Inst_VOP3__V_RSQ_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = 1.0 / std::sqrt(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_RCP_F64 class methods ---

    Inst_VOP3__V_RCP_F64::Inst_VOP3__V_RCP_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_rcp_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_RCP_F64

    Inst_VOP3__V_RCP_F64::~Inst_VOP3__V_RCP_F64()
    {
    } // ~Inst_VOP3__V_RCP_F64

    // --- description from .arch file ---
    // D.d = 1.0 / S0.d.
    void
    Inst_VOP3__V_RCP_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::fpclassify(src[lane]) == FP_ZERO) {
                    vdst[lane] = +INFINITY;
                } else if (std::isnan(src[lane])) {
                    vdst[lane] = NAN;
                } else if (std::isinf(src[lane])) {
                    if (std::signbit(src[lane])) {
                        vdst[lane] = -0.0;
                    } else {
                        vdst[lane] = 0.0;
                    }
                } else {
                    vdst[lane] = 1.0 / src[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_RSQ_F64 class methods ---

    Inst_VOP3__V_RSQ_F64::Inst_VOP3__V_RSQ_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_rsq_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_RSQ_F64

    Inst_VOP3__V_RSQ_F64::~Inst_VOP3__V_RSQ_F64()
    {
    } // ~Inst_VOP3__V_RSQ_F64

    // --- description from .arch file ---
    // D.d = 1.0 / sqrt(S0.d). See V_RSQ_F32.
    void
    Inst_VOP3__V_RSQ_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::fpclassify(src[lane]) == FP_ZERO) {
                    vdst[lane] = +INFINITY;
                } else if (std::isnan(src[lane])) {
                    vdst[lane] = NAN;
                } else if (std::isinf(src[lane]) && !std::signbit(src[lane])) {
                    vdst[lane] = 0.0;
                } else if (std::signbit(src[lane])) {
                    vdst[lane] = NAN;
                } else {
                    vdst[lane] = 1.0 / std::sqrt(src[lane]);
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_SQRT_F32 class methods ---

    Inst_VOP3__V_SQRT_F32::Inst_VOP3__V_SQRT_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_sqrt_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_SQRT_F32

    Inst_VOP3__V_SQRT_F32::~Inst_VOP3__V_SQRT_F32()
    {
    } // ~Inst_VOP3__V_SQRT_F32

    // --- description from .arch file ---
    // D.f = sqrt(S0.f).
    void
    Inst_VOP3__V_SQRT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::sqrt(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_SQRT_F64 class methods ---

    Inst_VOP3__V_SQRT_F64::Inst_VOP3__V_SQRT_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_sqrt_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_SQRT_F64

    Inst_VOP3__V_SQRT_F64::~Inst_VOP3__V_SQRT_F64()
    {
    } // ~Inst_VOP3__V_SQRT_F64

    // --- description from .arch file ---
    // D.d = sqrt(S0.d).
    void
    Inst_VOP3__V_SQRT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::sqrt(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_SIN_F32 class methods ---

    Inst_VOP3__V_SIN_F32::Inst_VOP3__V_SIN_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_sin_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_SIN_F32

    Inst_VOP3__V_SIN_F32::~Inst_VOP3__V_SIN_F32()
    {
    } // ~Inst_VOP3__V_SIN_F32

    // --- description from .arch file ---
    // D.f = sin(S0.f * 2 * PI).
    // Valid range of S0.f is [-256.0, +256.0]. Out of range input results in
    // float 0.0.
    void
    Inst_VOP3__V_SIN_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        ConstScalarOperandF32 pi(gpuDynInst, REG_PI);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();
        pi.read();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::sin(src[lane] * 2 * pi.rawData());
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_COS_F32 class methods ---

    Inst_VOP3__V_COS_F32::Inst_VOP3__V_COS_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cos_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_COS_F32

    Inst_VOP3__V_COS_F32::~Inst_VOP3__V_COS_F32()
    {
    } // ~Inst_VOP3__V_COS_F32

    // --- description from .arch file ---
    // D.f = cos(S0.f * 2 * PI).
    // Valid range of S0.f is [-256.0, +256.0]. Out of range input results in
    // float 1.0.
    void
    Inst_VOP3__V_COS_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        ConstScalarOperandF32 pi(gpuDynInst, REG_PI);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();
        pi.read();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::cos(src[lane] * 2 * pi.rawData());
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_NOT_B32 class methods ---

    Inst_VOP3__V_NOT_B32::Inst_VOP3__V_NOT_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_not_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_NOT_B32

    Inst_VOP3__V_NOT_B32::~Inst_VOP3__V_NOT_B32()
    {
    } // ~Inst_VOP3__V_NOT_B32

    // --- description from .arch file ---
    // D.u = ~S0.u.
    // Input and output modifiers not supported.
    void
    Inst_VOP3__V_NOT_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, extData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = ~src[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_BFREV_B32 class methods ---

    Inst_VOP3__V_BFREV_B32::Inst_VOP3__V_BFREV_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_bfrev_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_BFREV_B32

    Inst_VOP3__V_BFREV_B32::~Inst_VOP3__V_BFREV_B32()
    {
    } // ~Inst_VOP3__V_BFREV_B32

    // --- description from .arch file ---
    // D.u[31:0] = S0.u[0:31], bitfield reverse.
    // Input and output modifiers not supported.
    void
    Inst_VOP3__V_BFREV_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, extData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = reverseBits(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FFBH_U32 class methods ---

    Inst_VOP3__V_FFBH_U32::Inst_VOP3__V_FFBH_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_ffbh_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_FFBH_U32

    Inst_VOP3__V_FFBH_U32::~Inst_VOP3__V_FFBH_U32()
    {
    } // ~Inst_VOP3__V_FFBH_U32

    // --- description from .arch file ---
    // D.u = position of first 1 in S0.u from MSB;
    // D.u = 0xffffffff if S0.u == 0.
    void
    Inst_VOP3__V_FFBH_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, extData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = findFirstOneMsb(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FFBL_B32 class methods ---

    Inst_VOP3__V_FFBL_B32::Inst_VOP3__V_FFBL_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_ffbl_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_FFBL_B32

    Inst_VOP3__V_FFBL_B32::~Inst_VOP3__V_FFBL_B32()
    {
    } // ~Inst_VOP3__V_FFBL_B32

    // --- description from .arch file ---
    // D.u = position of first 1 in S0.u from LSB;
    // D.u = 0xffffffff if S0.u == 0.
    void
    Inst_VOP3__V_FFBL_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src(gpuDynInst, extData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = findFirstOne(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FFBH_I32 class methods ---

    Inst_VOP3__V_FFBH_I32::Inst_VOP3__V_FFBH_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_ffbh_i32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_FFBH_I32

    Inst_VOP3__V_FFBH_I32::~Inst_VOP3__V_FFBH_I32()
    {
    } // ~Inst_VOP3__V_FFBH_I32

    // --- description from .arch file ---
    // D.u = position of first bit different from sign bit in S0.i from MSB;
    // D.u = 0xffffffff if S0.i == 0 or S0.i == 0xffffffff.
    void
    Inst_VOP3__V_FFBH_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src(gpuDynInst, extData.SRC0);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = firstOppositeSignBit(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FREXP_EXP_I32_F64 class methods ---

    Inst_VOP3__V_FREXP_EXP_I32_F64::Inst_VOP3__V_FREXP_EXP_I32_F64(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_frexp_exp_i32_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_FREXP_EXP_I32_F64

    Inst_VOP3__V_FREXP_EXP_I32_F64::~Inst_VOP3__V_FREXP_EXP_I32_F64()
    {
    } // ~Inst_VOP3__V_FREXP_EXP_I32_F64

    // --- description from .arch file ---
    // See V_FREXP_EXP_I32_F32.
    void
    Inst_VOP3__V_FREXP_EXP_I32_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isinf(src[lane]) || std::isnan(src[lane])) {
                    vdst[lane] = 0;
                } else {
                    VecElemI32 exp(0);
                    std::frexp(src[lane], &exp);
                    vdst[lane] = exp;
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FREXP_MANT_F64 class methods ---

    Inst_VOP3__V_FREXP_MANT_F64::Inst_VOP3__V_FREXP_MANT_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_frexp_mant_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_FREXP_MANT_F64

    Inst_VOP3__V_FREXP_MANT_F64::~Inst_VOP3__V_FREXP_MANT_F64()
    {
    } // ~Inst_VOP3__V_FREXP_MANT_F64

    // --- description from .arch file ---
    // See V_FREXP_MANT_F32.
    void
    Inst_VOP3__V_FREXP_MANT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemI32 exp(0);
                vdst[lane] = std::frexp(src[lane], &exp);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FRACT_F64 class methods ---

    Inst_VOP3__V_FRACT_F64::Inst_VOP3__V_FRACT_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_fract_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_FRACT_F64

    Inst_VOP3__V_FRACT_F64::~Inst_VOP3__V_FRACT_F64()
    {
    } // ~Inst_VOP3__V_FRACT_F64

    // --- description from .arch file ---
    // See V_FRACT_F32.
    void
    Inst_VOP3__V_FRACT_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src(gpuDynInst, extData.SRC0);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemF32 int_part(0.0);
                vdst[lane] = std::modf(src[lane], &int_part);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FREXP_EXP_I32_F32 class methods ---

    Inst_VOP3__V_FREXP_EXP_I32_F32::Inst_VOP3__V_FREXP_EXP_I32_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_frexp_exp_i32_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_FREXP_EXP_I32_F32

    Inst_VOP3__V_FREXP_EXP_I32_F32::~Inst_VOP3__V_FREXP_EXP_I32_F32()
    {
    } // ~Inst_VOP3__V_FREXP_EXP_I32_F32

    // --- description from .arch file ---
    // if(S0.f == INF || S0.f == NAN) then D.i = 0;
    // else D.i = TwosComplement(Exponent(S0.f) - 127 + 1).
    // Returns exponent of single precision float input, such that S0.f =
    // significand * (2 ** exponent). See also FREXP_MANT_F32, which returns
    // the significand.
    void
    Inst_VOP3__V_FREXP_EXP_I32_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isinf(src[lane])|| std::isnan(src[lane])) {
                    vdst[lane] = 0;
                } else {
                    VecElemI32 exp(0);
                    std::frexp(src[lane], &exp);
                    vdst[lane] = exp;
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FREXP_MANT_F32 class methods ---

    Inst_VOP3__V_FREXP_MANT_F32::Inst_VOP3__V_FREXP_MANT_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_frexp_mant_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_FREXP_MANT_F32

    Inst_VOP3__V_FREXP_MANT_F32::~Inst_VOP3__V_FREXP_MANT_F32()
    {
    } // ~Inst_VOP3__V_FREXP_MANT_F32

    // --- description from .arch file ---
    // if(S0.f == INF || S0.f == NAN) then D.f = S0.f;
    // else D.f = Mantissa(S0.f).
    // Result range is in (-1.0,-0.5][0.5,1.0) in normal cases. Returns binary
    // ---  significand of single precision float input, such that S0.f =
    // ---  significand * (2 ** exponent). See also FREXP_EXP_I32_F32, which
    // ---  returns integer exponent.
    void
    Inst_VOP3__V_FREXP_MANT_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isinf(src[lane]) || std::isnan(src[lane])) {
                    vdst[lane] = src[lane];
                } else {
                    VecElemI32 exp(0);
                    vdst[lane] = std::frexp(src[lane], &exp);
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CLREXCP class methods ---

    Inst_VOP3__V_CLREXCP::Inst_VOP3__V_CLREXCP(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_clrexcp", false)
    {
    } // Inst_VOP3__V_CLREXCP

    Inst_VOP3__V_CLREXCP::~Inst_VOP3__V_CLREXCP()
    {
    } // ~Inst_VOP3__V_CLREXCP

    // --- description from .arch file ---
    // Clear wave's exception state in SIMD (SP).
    void
    Inst_VOP3__V_CLREXCP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_F16_U16 class methods ---

    Inst_VOP3__V_CVT_F16_U16::Inst_VOP3__V_CVT_F16_U16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f16_u16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CVT_F16_U16

    Inst_VOP3__V_CVT_F16_U16::~Inst_VOP3__V_CVT_F16_U16()
    {
    } // ~Inst_VOP3__V_CVT_F16_U16

    // --- description from .arch file ---
    // D.f16 = uint16_to_flt16(S.u16).
    // Supports denormals, rounding, exception flags and saturation.
    void
    Inst_VOP3__V_CVT_F16_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_F16_I16 class methods ---

    Inst_VOP3__V_CVT_F16_I16::Inst_VOP3__V_CVT_F16_I16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_f16_i16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CVT_F16_I16

    Inst_VOP3__V_CVT_F16_I16::~Inst_VOP3__V_CVT_F16_I16()
    {
    } // ~Inst_VOP3__V_CVT_F16_I16

    // --- description from .arch file ---
    // D.f16 = int16_to_flt16(S.i16).
    // Supports denormals, rounding, exception flags and saturation.
    void
    Inst_VOP3__V_CVT_F16_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_U16_F16 class methods ---

    Inst_VOP3__V_CVT_U16_F16::Inst_VOP3__V_CVT_U16_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_u16_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CVT_U16_F16

    Inst_VOP3__V_CVT_U16_F16::~Inst_VOP3__V_CVT_U16_F16()
    {
    } // ~Inst_VOP3__V_CVT_U16_F16

    // --- description from .arch file ---
    // D.u16 = flt16_to_uint16(S.f16).
    // Supports rounding, exception flags and saturation.
    void
    Inst_VOP3__V_CVT_U16_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_I16_F16 class methods ---

    Inst_VOP3__V_CVT_I16_F16::Inst_VOP3__V_CVT_I16_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_i16_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CVT_I16_F16

    Inst_VOP3__V_CVT_I16_F16::~Inst_VOP3__V_CVT_I16_F16()
    {
    } // ~Inst_VOP3__V_CVT_I16_F16

    // --- description from .arch file ---
    // D.i16 = flt16_to_int16(S.f16).
    // Supports rounding, exception flags and saturation.
    void
    Inst_VOP3__V_CVT_I16_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_RCP_F16 class methods ---

    Inst_VOP3__V_RCP_F16::Inst_VOP3__V_RCP_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_rcp_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_RCP_F16

    Inst_VOP3__V_RCP_F16::~Inst_VOP3__V_RCP_F16()
    {
    } // ~Inst_VOP3__V_RCP_F16

    // --- description from .arch file ---
    // if(S0.f16 == 1.0f)
    //     D.f16 = 1.0f;
    // else
    //     D.f16 = ApproximateRecip(S0.f16).
    void
    Inst_VOP3__V_RCP_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_SQRT_F16 class methods ---

    Inst_VOP3__V_SQRT_F16::Inst_VOP3__V_SQRT_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_sqrt_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_SQRT_F16

    Inst_VOP3__V_SQRT_F16::~Inst_VOP3__V_SQRT_F16()
    {
    } // ~Inst_VOP3__V_SQRT_F16

    // --- description from .arch file ---
    // if(S0.f16 == 1.0f)
    //     D.f16 = 1.0f;
    // else
    //     D.f16 = ApproximateSqrt(S0.f16).
    void
    Inst_VOP3__V_SQRT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_RSQ_F16 class methods ---

    Inst_VOP3__V_RSQ_F16::Inst_VOP3__V_RSQ_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_rsq_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_RSQ_F16

    Inst_VOP3__V_RSQ_F16::~Inst_VOP3__V_RSQ_F16()
    {
    } // ~Inst_VOP3__V_RSQ_F16

    // --- description from .arch file ---
    // if(S0.f16 == 1.0f)
    //     D.f16 = 1.0f;
    // else
    //     D.f16 = ApproximateRecipSqrt(S0.f16).
    void
    Inst_VOP3__V_RSQ_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_LOG_F16 class methods ---

    Inst_VOP3__V_LOG_F16::Inst_VOP3__V_LOG_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_log_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_LOG_F16

    Inst_VOP3__V_LOG_F16::~Inst_VOP3__V_LOG_F16()
    {
    } // ~Inst_VOP3__V_LOG_F16

    // --- description from .arch file ---
    // if(S0.f16 == 1.0f)
    //     D.f16 = 0.0f;
    // else
    //     D.f16 = ApproximateLog2(S0.f16).
    void
    Inst_VOP3__V_LOG_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_EXP_F16 class methods ---

    Inst_VOP3__V_EXP_F16::Inst_VOP3__V_EXP_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_exp_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_EXP_F16

    Inst_VOP3__V_EXP_F16::~Inst_VOP3__V_EXP_F16()
    {
    } // ~Inst_VOP3__V_EXP_F16

    // --- description from .arch file ---
    // if(S0.f16 == 0.0f)
    //     D.f16 = 1.0f;
    // else
    //     D.f16 = Approximate2ToX(S0.f16).
    void
    Inst_VOP3__V_EXP_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_FREXP_MANT_F16 class methods ---

    Inst_VOP3__V_FREXP_MANT_F16::Inst_VOP3__V_FREXP_MANT_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_frexp_mant_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_FREXP_MANT_F16

    Inst_VOP3__V_FREXP_MANT_F16::~Inst_VOP3__V_FREXP_MANT_F16()
    {
    } // ~Inst_VOP3__V_FREXP_MANT_F16

    // --- description from .arch file ---
    // if(S0.f16 == +-INF || S0.f16 == NAN)
    //     D.f16 = S0.f16;
    // else
    //     D.f16 = mantissa(S0.f16).
    // Result range is (-1.0,-0.5][0.5,1.0).
    // C math library frexp function.
    // Returns binary significand of half precision float input, such that the
    // original single float = significand * (2 ** exponent).
    void
    Inst_VOP3__V_FREXP_MANT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_FREXP_EXP_I16_F16 class methods ---

    Inst_VOP3__V_FREXP_EXP_I16_F16::Inst_VOP3__V_FREXP_EXP_I16_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_frexp_exp_i16_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_FREXP_EXP_I16_F16

    Inst_VOP3__V_FREXP_EXP_I16_F16::~Inst_VOP3__V_FREXP_EXP_I16_F16()
    {
    } // ~Inst_VOP3__V_FREXP_EXP_I16_F16

    // --- description from .arch file ---
    // if(S0.f16 == +-INF || S0.f16 == NAN)
    //     D.i16 = 0;
    // else
    //     D.i16 = 2s_complement(exponent(S0.f16) - 15 + 1).
    // C math library frexp function.
    // Returns exponent of half precision float input, such that the
    // original single float = significand * (2 ** exponent).
    void
    Inst_VOP3__V_FREXP_EXP_I16_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_FLOOR_F16 class methods ---

    Inst_VOP3__V_FLOOR_F16::Inst_VOP3__V_FLOOR_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_floor_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_FLOOR_F16

    Inst_VOP3__V_FLOOR_F16::~Inst_VOP3__V_FLOOR_F16()
    {
    } // ~Inst_VOP3__V_FLOOR_F16

    // --- description from .arch file ---
    // D.f16 = trunc(S0.f16);
    // if(S0.f16 < 0.0f && S0.f16 != D.f16) then D.f16 -= 1.0f.
    void
    Inst_VOP3__V_FLOOR_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CEIL_F16 class methods ---

    Inst_VOP3__V_CEIL_F16::Inst_VOP3__V_CEIL_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_ceil_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_CEIL_F16

    Inst_VOP3__V_CEIL_F16::~Inst_VOP3__V_CEIL_F16()
    {
    } // ~Inst_VOP3__V_CEIL_F16

    // --- description from .arch file ---
    // D.f16 = trunc(S0.f16);
    // if(S0.f16 > 0.0f && S0.f16 != D.f16) then D.f16 += 1.0f.
    void
    Inst_VOP3__V_CEIL_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_TRUNC_F16 class methods ---

    Inst_VOP3__V_TRUNC_F16::Inst_VOP3__V_TRUNC_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_trunc_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_TRUNC_F16

    Inst_VOP3__V_TRUNC_F16::~Inst_VOP3__V_TRUNC_F16()
    {
    } // ~Inst_VOP3__V_TRUNC_F16

    // --- description from .arch file ---
    // D.f16 = trunc(S0.f16).
    // Round-to-zero semantics.
    void
    Inst_VOP3__V_TRUNC_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_RNDNE_F16 class methods ---

    Inst_VOP3__V_RNDNE_F16::Inst_VOP3__V_RNDNE_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_rndne_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_RNDNE_F16

    Inst_VOP3__V_RNDNE_F16::~Inst_VOP3__V_RNDNE_F16()
    {
    } // ~Inst_VOP3__V_RNDNE_F16

    // --- description from .arch file ---
    // D.f16 = FLOOR(S0.f16 + 0.5f);
    // if(floor(S0.f16) is even && fract(S0.f16) == 0.5f) then D.f16 -= 1.0f.
    // Round-to-nearest-even semantics.
    void
    Inst_VOP3__V_RNDNE_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_FRACT_F16 class methods ---

    Inst_VOP3__V_FRACT_F16::Inst_VOP3__V_FRACT_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_fract_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_FRACT_F16

    Inst_VOP3__V_FRACT_F16::~Inst_VOP3__V_FRACT_F16()
    {
    } // ~Inst_VOP3__V_FRACT_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 + -floor(S0.f16).
    void
    Inst_VOP3__V_FRACT_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_SIN_F16 class methods ---

    Inst_VOP3__V_SIN_F16::Inst_VOP3__V_SIN_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_sin_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_SIN_F16

    Inst_VOP3__V_SIN_F16::~Inst_VOP3__V_SIN_F16()
    {
    } // ~Inst_VOP3__V_SIN_F16

    // --- description from .arch file ---
    // D.f16 = sin(S0.f16 * 2 * PI).
    void
    Inst_VOP3__V_SIN_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_COS_F16 class methods ---

    Inst_VOP3__V_COS_F16::Inst_VOP3__V_COS_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cos_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_COS_F16

    Inst_VOP3__V_COS_F16::~Inst_VOP3__V_COS_F16()
    {
    } // ~Inst_VOP3__V_COS_F16

    // --- description from .arch file ---
    // D.f16 = cos(S0.f16 * 2 * PI).
    void
    Inst_VOP3__V_COS_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_EXP_LEGACY_F32 class methods ---

    Inst_VOP3__V_EXP_LEGACY_F32::Inst_VOP3__V_EXP_LEGACY_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_exp_legacy_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_EXP_LEGACY_F32

    Inst_VOP3__V_EXP_LEGACY_F32::~Inst_VOP3__V_EXP_LEGACY_F32()
    {
    } // ~Inst_VOP3__V_EXP_LEGACY_F32

    // --- description from .arch file ---
    // D.f = pow(2.0, S0.f) with legacy semantics.
    void
    Inst_VOP3__V_EXP_LEGACY_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        if (instData.ABS & 0x1) {
            src.absModifier();
        }

        if (extData.NEG & 0x1) {
            src.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::pow(2.0, src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LOG_LEGACY_F32 class methods ---

    Inst_VOP3__V_LOG_LEGACY_F32::Inst_VOP3__V_LOG_LEGACY_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_log_legacy_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_LOG_LEGACY_F32

    Inst_VOP3__V_LOG_LEGACY_F32::~Inst_VOP3__V_LOG_LEGACY_F32()
    {
    } // ~Inst_VOP3__V_LOG_LEGACY_F32

    // --- description from .arch file ---
    // D.f = log2(S0.f). Base 2 logarithm with legacy semantics.
    void
    Inst_VOP3__V_LOG_LEGACY_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src(gpuDynInst, extData.SRC0);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::log2(src[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAD_LEGACY_F32 class methods ---

    Inst_VOP3__V_MAD_LEGACY_F32::Inst_VOP3__V_MAD_LEGACY_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mad_legacy_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(MAD);
    } // Inst_VOP3__V_MAD_LEGACY_F32

    Inst_VOP3__V_MAD_LEGACY_F32::~Inst_VOP3__V_MAD_LEGACY_F32()
    {
    } // ~Inst_VOP3__V_MAD_LEGACY_F32

    // --- description from .arch file ---
    // D.f = S0.f * S1.f + S2.f (DX9 rules, 0.0 * x = 0.0).
    void
    Inst_VOP3__V_MAD_LEGACY_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF32 src2(gpuDynInst, extData.SRC2);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (instData.ABS & 0x4) {
            src2.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fma(src0[lane], src1[lane], src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAD_F32 class methods ---

    Inst_VOP3__V_MAD_F32::Inst_VOP3__V_MAD_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mad_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(MAD);
    } // Inst_VOP3__V_MAD_F32

    Inst_VOP3__V_MAD_F32::~Inst_VOP3__V_MAD_F32()
    {
    } // ~Inst_VOP3__V_MAD_F32

    // --- description from .arch file ---
    // D.f = S0.f * S1.f + S2.f.
    void
    Inst_VOP3__V_MAD_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF32 src2(gpuDynInst, extData.SRC2);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (instData.ABS & 0x4) {
            src2.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fma(src0[lane], src1[lane], src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAD_I32_I24 class methods ---

    Inst_VOP3__V_MAD_I32_I24::Inst_VOP3__V_MAD_I32_I24(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mad_i32_i24", false)
    {
        setFlag(ALU);
        setFlag(MAD);
    } // Inst_VOP3__V_MAD_I32_I24

    Inst_VOP3__V_MAD_I32_I24::~Inst_VOP3__V_MAD_I32_I24()
    {
    } // ~Inst_VOP3__V_MAD_I32_I24

    // --- description from .arch file ---
    // D.i = S0.i[23:0] * S1.i[23:0] + S2.i.
    void
    Inst_VOP3__V_MAD_I32_I24::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandI32 src2(gpuDynInst, extData.SRC2);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = sext<24>(bits(src0[lane], 23, 0))
                    * sext<24>(bits(src1[lane], 23, 0)) + src2[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAD_U32_U24 class methods ---

    Inst_VOP3__V_MAD_U32_U24::Inst_VOP3__V_MAD_U32_U24(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mad_u32_u24", false)
    {
        setFlag(ALU);
        setFlag(MAD);
    } // Inst_VOP3__V_MAD_U32_U24

    Inst_VOP3__V_MAD_U32_U24::~Inst_VOP3__V_MAD_U32_U24()
    {
    } // ~Inst_VOP3__V_MAD_U32_U24

    // --- description from .arch file ---
    // D.u = S0.u[23:0] * S1.u[23:0] + S2.u.
    void
    Inst_VOP3__V_MAD_U32_U24::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = bits(src0[lane], 23, 0) * bits(src1[lane], 23, 0)
                    + src2[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CUBEID_F32 class methods ---

    Inst_VOP3__V_CUBEID_F32::Inst_VOP3__V_CUBEID_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cubeid_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CUBEID_F32

    Inst_VOP3__V_CUBEID_F32::~Inst_VOP3__V_CUBEID_F32()
    {
    } // ~Inst_VOP3__V_CUBEID_F32

    // --- description from .arch file ---
    // D.f = cubemap face ID ({0.0, 1.0, ..., 5.0}). XYZ coordinate is given in
    // ---  (S0.f, S1.f, S2.f).
    void
    Inst_VOP3__V_CUBEID_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CUBESC_F32 class methods ---

    Inst_VOP3__V_CUBESC_F32::Inst_VOP3__V_CUBESC_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cubesc_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CUBESC_F32

    Inst_VOP3__V_CUBESC_F32::~Inst_VOP3__V_CUBESC_F32()
    {
    } // ~Inst_VOP3__V_CUBESC_F32

    // --- description from .arch file ---
    // D.f = cubemap S coordinate. XYZ coordinate is given in (S0.f, S1.f,
    // S2.f).
    void
    Inst_VOP3__V_CUBESC_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CUBETC_F32 class methods ---

    Inst_VOP3__V_CUBETC_F32::Inst_VOP3__V_CUBETC_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cubetc_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CUBETC_F32

    Inst_VOP3__V_CUBETC_F32::~Inst_VOP3__V_CUBETC_F32()
    {
    } // ~Inst_VOP3__V_CUBETC_F32

    // --- description from .arch file ---
    // D.f = cubemap T coordinate. XYZ coordinate is given in (S0.f, S1.f,
    // S2.f).
    void
    Inst_VOP3__V_CUBETC_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CUBEMA_F32 class methods ---

    Inst_VOP3__V_CUBEMA_F32::Inst_VOP3__V_CUBEMA_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cubema_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CUBEMA_F32

    Inst_VOP3__V_CUBEMA_F32::~Inst_VOP3__V_CUBEMA_F32()
    {
    } // ~Inst_VOP3__V_CUBEMA_F32

    // --- description from .arch file ---
    // D.f = 2.0 * cubemap major axis. XYZ coordinate is given in (S0.f, S1.f,
    // ---  S2.f).
    void
    Inst_VOP3__V_CUBEMA_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_BFE_U32 class methods ---

    Inst_VOP3__V_BFE_U32::Inst_VOP3__V_BFE_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_bfe_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_BFE_U32

    Inst_VOP3__V_BFE_U32::~Inst_VOP3__V_BFE_U32()
    {
    } // ~Inst_VOP3__V_BFE_U32

    // --- description from .arch file ---
    // D.u = (S0.u>>S1.u[4:0]) & ((1<<S2.u[4:0])-1).
    // Bitfield extract with S0 = data, S1 = field_offset, S2 = field_width.
    void
    Inst_VOP3__V_BFE_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (src0[lane] >> bits(src1[lane], 4, 0))
                    & ((1 << bits(src2[lane], 4, 0)) - 1);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_BFE_I32 class methods ---

    Inst_VOP3__V_BFE_I32::Inst_VOP3__V_BFE_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_bfe_i32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_BFE_I32

    Inst_VOP3__V_BFE_I32::~Inst_VOP3__V_BFE_I32()
    {
    } // ~Inst_VOP3__V_BFE_I32

    // --- description from .arch file ---
    // D.i = (S0.i>>S1.u[4:0]) & ((1<<S2.u[4:0])-1).
    // Bitfield extract with S0 = data, S1 = field_offset, S2 = field_width.
    void
    Inst_VOP3__V_BFE_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (src0[lane] >> bits(src1[lane], 4, 0))
                    & ((1 << bits(src2[lane], 4, 0)) - 1);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_BFI_B32 class methods ---

    Inst_VOP3__V_BFI_B32::Inst_VOP3__V_BFI_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_bfi_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_BFI_B32

    Inst_VOP3__V_BFI_B32::~Inst_VOP3__V_BFI_B32()
    {
    } // ~Inst_VOP3__V_BFI_B32

    // --- description from .arch file ---
    // D.u = (S0.u & S1.u) | (~S0.u & S2.u); bitfield insert.
    void
    Inst_VOP3__V_BFI_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (src0[lane] & src1[lane]) | (~src0[lane]
                    & src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FMA_F32 class methods ---

    Inst_VOP3__V_FMA_F32::Inst_VOP3__V_FMA_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_fma_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
        setFlag(FMA);
    } // Inst_VOP3__V_FMA_F32

    Inst_VOP3__V_FMA_F32::~Inst_VOP3__V_FMA_F32()
    {
    } // ~Inst_VOP3__V_FMA_F32

    // --- description from .arch file ---
    // D.f = S0.f * S1.f + S2.f.
    void
    Inst_VOP3__V_FMA_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF32 src2(gpuDynInst, extData.SRC2);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (instData.ABS & 0x4) {
            src2.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fma(src0[lane], src1[lane], src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FMA_F64 class methods ---

    Inst_VOP3__V_FMA_F64::Inst_VOP3__V_FMA_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_fma_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
        setFlag(FMA);
    } // Inst_VOP3__V_FMA_F64

    Inst_VOP3__V_FMA_F64::~Inst_VOP3__V_FMA_F64()
    {
    } // ~Inst_VOP3__V_FMA_F64

    // --- description from .arch file ---
    // D.d = S0.d * S1.d + S2.d.
    void
    Inst_VOP3__V_FMA_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF64 src2(gpuDynInst, extData.SRC2);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (instData.ABS & 0x4) {
            src2.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fma(src0[lane], src1[lane], src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LERP_U8 class methods ---

    Inst_VOP3__V_LERP_U8::Inst_VOP3__V_LERP_U8(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_lerp_u8", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_LERP_U8

    Inst_VOP3__V_LERP_U8::~Inst_VOP3__V_LERP_U8()
    {
    } // ~Inst_VOP3__V_LERP_U8

    // --- description from .arch file ---
    // D.u = ((S0.u[31:24] + S1.u[31:24] + S2.u[24]) >> 1) << 24
    // D.u += ((S0.u[23:16] + S1.u[23:16] + S2.u[16]) >> 1) << 16;
    // D.u += ((S0.u[15:8] + S1.u[15:8] + S2.u[8]) >> 1) << 8;
    // D.u += ((S0.u[7:0] + S1.u[7:0] + S2.u[0]) >> 1).
    // Unsigned 8-bit pixel average on packed unsigned bytes (linear
    // ---  interpolation). S2 acts as a round mode; if set, 0.5 rounds up,
    // ---  otherwise 0.5 truncates.
    void
    Inst_VOP3__V_LERP_U8::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = ((bits(src0[lane], 31, 24)
                    + bits(src1[lane], 31, 24) + bits(src2[lane], 24)) >> 1)
                        << 24;
                vdst[lane] += ((bits(src0[lane], 23, 16)
                    + bits(src1[lane], 23, 16) + bits(src2[lane], 16)) >> 1)
                        << 16;
                vdst[lane] += ((bits(src0[lane], 15, 8)
                    + bits(src1[lane], 15, 8) + bits(src2[lane], 8)) >> 1)
                        << 8;
                vdst[lane] += ((bits(src0[lane], 7, 0) + bits(src1[lane], 7, 0)
                    + bits(src2[lane], 0)) >> 1);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_ALIGNBIT_B32 class methods ---

    Inst_VOP3__V_ALIGNBIT_B32::Inst_VOP3__V_ALIGNBIT_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_alignbit_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_ALIGNBIT_B32

    Inst_VOP3__V_ALIGNBIT_B32::~Inst_VOP3__V_ALIGNBIT_B32()
    {
    } // ~Inst_VOP3__V_ALIGNBIT_B32

    // --- description from .arch file ---
    // D.u = ({S0,S1} >> S2.u[4:0]) & 0xffffffff.
    void
    Inst_VOP3__V_ALIGNBIT_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemU64 src_0_1 = (((VecElemU64)src0[lane] << 32)
                    | (VecElemU64)src1[lane]);
                vdst[lane] = (VecElemU32)((src_0_1
                    >> (VecElemU64)bits(src2[lane], 4, 0)) & 0xffffffff);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_ALIGNBYTE_B32 class methods ---

    Inst_VOP3__V_ALIGNBYTE_B32::Inst_VOP3__V_ALIGNBYTE_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_alignbyte_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_ALIGNBYTE_B32

    Inst_VOP3__V_ALIGNBYTE_B32::~Inst_VOP3__V_ALIGNBYTE_B32()
    {
    } // ~Inst_VOP3__V_ALIGNBYTE_B32

    // --- description from .arch file ---
    // D.u = ({S0,S1} >> (8*S2.u[4:0])) & 0xffffffff.
    void
    Inst_VOP3__V_ALIGNBYTE_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemU64 src_0_1 = (((VecElemU64)src0[lane] << 32)
                    | (VecElemU64)src1[lane]);
                vdst[lane] = (VecElemU32)((src_0_1
                    >> (8ULL * (VecElemU64)bits(src2[lane], 4, 0)))
                        & 0xffffffff);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MIN3_F32 class methods ---

    Inst_VOP3__V_MIN3_F32::Inst_VOP3__V_MIN3_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_min3_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_MIN3_F32

    Inst_VOP3__V_MIN3_F32::~Inst_VOP3__V_MIN3_F32()
    {
    } // ~Inst_VOP3__V_MIN3_F32

    // --- description from .arch file ---
    // D.f = min(S0.f, S1.f, S2.f).
    void
    Inst_VOP3__V_MIN3_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF32 src2(gpuDynInst, extData.SRC2);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (instData.ABS & 0x4) {
            src2.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemF32 min_0_1 = std::fmin(src0[lane], src1[lane]);
                vdst[lane] = std::fmin(min_0_1, src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MIN3_I32 class methods ---

    Inst_VOP3__V_MIN3_I32::Inst_VOP3__V_MIN3_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_min3_i32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MIN3_I32

    Inst_VOP3__V_MIN3_I32::~Inst_VOP3__V_MIN3_I32()
    {
    } // ~Inst_VOP3__V_MIN3_I32

    // --- description from .arch file ---
    // D.i = min(S0.i, S1.i, S2.i).
    void
    Inst_VOP3__V_MIN3_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandI32 src2(gpuDynInst, extData.SRC2);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemI32 min_0_1 = std::min(src0[lane], src1[lane]);
                vdst[lane] = std::min(min_0_1, src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MIN3_U32 class methods ---

    Inst_VOP3__V_MIN3_U32::Inst_VOP3__V_MIN3_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_min3_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MIN3_U32

    Inst_VOP3__V_MIN3_U32::~Inst_VOP3__V_MIN3_U32()
    {
    } // ~Inst_VOP3__V_MIN3_U32

    // --- description from .arch file ---
    // D.u = min(S0.u, S1.u, S2.u).
    void
    Inst_VOP3__V_MIN3_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemU32 min_0_1 = std::min(src0[lane], src1[lane]);
                vdst[lane] = std::min(min_0_1, src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAX3_F32 class methods ---

    Inst_VOP3__V_MAX3_F32::Inst_VOP3__V_MAX3_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_max3_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_MAX3_F32

    Inst_VOP3__V_MAX3_F32::~Inst_VOP3__V_MAX3_F32()
    {
    } // ~Inst_VOP3__V_MAX3_F32

    // --- description from .arch file ---
    // D.f = max(S0.f, S1.f, S2.f).
    void
    Inst_VOP3__V_MAX3_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF32 src2(gpuDynInst, extData.SRC2);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (instData.ABS & 0x4) {
            src2.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemF32 max_0_1 = std::fmax(src0[lane], src1[lane]);
                vdst[lane] = std::fmax(max_0_1, src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAX3_I32 class methods ---

    Inst_VOP3__V_MAX3_I32::Inst_VOP3__V_MAX3_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_max3_i32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MAX3_I32

    Inst_VOP3__V_MAX3_I32::~Inst_VOP3__V_MAX3_I32()
    {
    } // ~Inst_VOP3__V_MAX3_I32

    // --- description from .arch file ---
    // D.i = max(S0.i, S1.i, S2.i).
    void
    Inst_VOP3__V_MAX3_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandI32 src2(gpuDynInst, extData.SRC2);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemI32 max_0_1 = std::max(src0[lane], src1[lane]);
                vdst[lane] = std::max(max_0_1, src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAX3_U32 class methods ---

    Inst_VOP3__V_MAX3_U32::Inst_VOP3__V_MAX3_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_max3_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MAX3_U32

    Inst_VOP3__V_MAX3_U32::~Inst_VOP3__V_MAX3_U32()
    {
    } // ~Inst_VOP3__V_MAX3_U32

    // --- description from .arch file ---
    // D.u = max(S0.u, S1.u, S2.u).
    void
    Inst_VOP3__V_MAX3_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemU32 max_0_1 = std::max(src0[lane], src1[lane]);
                vdst[lane] = std::max(max_0_1, src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MED3_F32 class methods ---

    Inst_VOP3__V_MED3_F32::Inst_VOP3__V_MED3_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_med3_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_MED3_F32

    Inst_VOP3__V_MED3_F32::~Inst_VOP3__V_MED3_F32()
    {
    } // ~Inst_VOP3__V_MED3_F32

    // --- description from .arch file ---
    // D.f = median(S0.f, S1.f, S2.f).
    void
    Inst_VOP3__V_MED3_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF32 src2(gpuDynInst, extData.SRC2);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (instData.ABS & 0x4) {
            src2.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = median(src0[lane], src1[lane], src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MED3_I32 class methods ---

    Inst_VOP3__V_MED3_I32::Inst_VOP3__V_MED3_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_med3_i32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MED3_I32

    Inst_VOP3__V_MED3_I32::~Inst_VOP3__V_MED3_I32()
    {
    } // ~Inst_VOP3__V_MED3_I32

    // --- description from .arch file ---
    // D.i = median(S0.i, S1.i, S2.i).
    void
    Inst_VOP3__V_MED3_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandI32 src2(gpuDynInst, extData.SRC2);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = median(src0[lane], src1[lane], src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MED3_U32 class methods ---

    Inst_VOP3__V_MED3_U32::Inst_VOP3__V_MED3_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_med3_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MED3_U32

    Inst_VOP3__V_MED3_U32::~Inst_VOP3__V_MED3_U32()
    {
    } // ~Inst_VOP3__V_MED3_U32

    // --- description from .arch file ---
    // D.u = median(S0.u, S1.u, S2.u).
    void
    Inst_VOP3__V_MED3_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = median(src0[lane], src1[lane], src2[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_SAD_U8 class methods ---

    Inst_VOP3__V_SAD_U8::Inst_VOP3__V_SAD_U8(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_sad_u8", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_SAD_U8

    Inst_VOP3__V_SAD_U8::~Inst_VOP3__V_SAD_U8()
    {
    } // ~Inst_VOP3__V_SAD_U8

    // --- description from .arch file ---
    // D.u = abs(S0.i[31:24] - S1.i[31:24]) + abs(S0.i[23:16] - S1.i[23:16]) +
    // abs(S0.i[15:8] - S1.i[15:8]) + abs(S0.i[7:0] - S1.i[7:0]) + S2.u.
    // Sum of absolute differences with accumulation, overflow into upper bits
    // is allowed.
    void
    Inst_VOP3__V_SAD_U8::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::abs(bits(src0[lane], 31, 24)
                    - bits(src1[lane], 31, 24))
                    + std::abs(bits(src0[lane], 23, 16)
                    - bits(src1[lane], 23, 16))
                    + std::abs(bits(src0[lane], 15, 8)
                    - bits(src1[lane], 15, 8))
                    + std::abs(bits(src0[lane], 7, 0)
                    - bits(src1[lane], 7, 0)) + src2[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_SAD_HI_U8 class methods ---

    Inst_VOP3__V_SAD_HI_U8::Inst_VOP3__V_SAD_HI_U8(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_sad_hi_u8", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_SAD_HI_U8

    Inst_VOP3__V_SAD_HI_U8::~Inst_VOP3__V_SAD_HI_U8()
    {
    } // ~Inst_VOP3__V_SAD_HI_U8

    // --- description from .arch file ---
    // D.u = (SAD_U8(S0, S1, 0) << 16) + S2.u.
    // Sum of absolute differences with accumulation, overflow is lost.
    void
    Inst_VOP3__V_SAD_HI_U8::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (((bits(src0[lane], 31, 24)
                    - bits(src1[lane], 31, 24)) + (bits(src0[lane], 23, 16)
                    - bits(src1[lane], 23, 16)) + (bits(src0[lane], 15, 8)
                    - bits(src1[lane], 15, 8)) + (bits(src0[lane], 7, 0)
                    - bits(src1[lane], 7, 0))) << 16) + src2[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_SAD_U16 class methods ---

    Inst_VOP3__V_SAD_U16::Inst_VOP3__V_SAD_U16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_sad_u16", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_SAD_U16

    Inst_VOP3__V_SAD_U16::~Inst_VOP3__V_SAD_U16()
    {
    } // ~Inst_VOP3__V_SAD_U16

    // --- description from .arch file ---
    // D.u = abs(S0.i[31:16] - S1.i[31:16]) + abs(S0.i[15:0] - S1.i[15:0])
    // + S2.u.
    // Word SAD with accumulation.
    void
    Inst_VOP3__V_SAD_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::abs(bits(src0[lane], 31, 16)
                    - bits(src1[lane], 31, 16))
                    + std::abs(bits(src0[lane], 15, 0)
                    - bits(src1[lane], 15, 0)) + src2[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_SAD_U32 class methods ---

    Inst_VOP3__V_SAD_U32::Inst_VOP3__V_SAD_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_sad_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_SAD_U32

    Inst_VOP3__V_SAD_U32::~Inst_VOP3__V_SAD_U32()
    {
    } // ~Inst_VOP3__V_SAD_U32

    // --- description from .arch file ---
    // D.u = abs(S0.i - S1.i) + S2.u.
    // Dword SAD with accumulation.
    void
    Inst_VOP3__V_SAD_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::abs(src0[lane] - src1[lane]) + src2[lane];
            } // if
        } // for

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_PK_U8_F32 class methods ---

    Inst_VOP3__V_CVT_PK_U8_F32::Inst_VOP3__V_CVT_PK_U8_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_pk_u8_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_PK_U8_F32

    Inst_VOP3__V_CVT_PK_U8_F32::~Inst_VOP3__V_CVT_PK_U8_F32()
    {
    } // ~Inst_VOP3__V_CVT_PK_U8_F32

    // --- description from .arch file ---
    // D.u = ((flt32_to_uint8(S0.f) & 0xff) << (8 * S1.u[1:0]))
    // | (S2.u & ~(0xff << (8 * S1.u[1:0]))).
    // Convert floating point value S0 to 8-bit unsigned integer and pack the
    // result into byte S1 of dword S2.
    void
    Inst_VOP3__V_CVT_PK_U8_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }


        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (((VecElemU8)src0[lane] & 0xff)
                    << (8 * bits(src1[lane], 1, 0)))
                    | (src2[lane] & ~(0xff << (8 * bits(src1[lane], 1, 0))));
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_DIV_FIXUP_F32 class methods ---

    Inst_VOP3__V_DIV_FIXUP_F32::Inst_VOP3__V_DIV_FIXUP_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_div_fixup_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_DIV_FIXUP_F32

    Inst_VOP3__V_DIV_FIXUP_F32::~Inst_VOP3__V_DIV_FIXUP_F32()
    {
    } // ~Inst_VOP3__V_DIV_FIXUP_F32

    // --- description from .arch file ---
    // D.f = Divide fixup and flags -- s0.f = Quotient, s1.f = Denominator,
    // s2.f = Numerator. This opcode generates exceptions resulting from the
    // division operation.
    void
    Inst_VOP3__V_DIV_FIXUP_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF32 src2(gpuDynInst, extData.SRC2);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (instData.ABS & 0x4) {
            src2.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::fpclassify(src1[lane]) == FP_ZERO) {
                    if (std::signbit(src1[lane])) {
                        vdst[lane] = -INFINITY;
                    } else {
                        vdst[lane] = +INFINITY;
                    }
                } else if (std::isnan(src2[lane]) || std::isnan(src1[lane])) {
                    vdst[lane] = NAN;
                } else if (std::isinf(src1[lane])) {
                    if (std::signbit(src1[lane])) {
                        vdst[lane] = -INFINITY;
                    } else {
                        vdst[lane] = +INFINITY;
                    }
                } else {
                    vdst[lane] = src2[lane] / src1[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_DIV_FIXUP_F64 class methods ---

    Inst_VOP3__V_DIV_FIXUP_F64::Inst_VOP3__V_DIV_FIXUP_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_div_fixup_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_DIV_FIXUP_F64

    Inst_VOP3__V_DIV_FIXUP_F64::~Inst_VOP3__V_DIV_FIXUP_F64()
    {
    } // ~Inst_VOP3__V_DIV_FIXUP_F64

    // --- description from .arch file ---
    // D.d = Divide fixup and flags -- s0.d = Quotient, s1.d = Denominator,
    // s2.d = Numerator. This opcode generates exceptions resulting from the
    // division operation.
    void
    Inst_VOP3__V_DIV_FIXUP_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF64 src2(gpuDynInst, extData.SRC2);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (instData.ABS & 0x4) {
            src2.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                int sign_out = std::signbit(src1[lane])
                              ^ std::signbit(src2[lane]);
                int exp1(0);
                int exp2(0);
                std::frexp(src1[lane], &exp1);
                std::frexp(src2[lane], &exp2);

                if (std::isnan(src1[lane]) || std::isnan(src2[lane])) {
                    vdst[lane] = std::numeric_limits<VecElemF64>::quiet_NaN();
                } else if (std::fpclassify(src1[lane]) == FP_ZERO
                           && std::fpclassify(src2[lane]) == FP_ZERO) {
                    vdst[lane]
                        = std::numeric_limits<VecElemF64>::signaling_NaN();
                } else if (std::isinf(src1[lane]) && std::isinf(src2[lane])) {
                    vdst[lane]
                        = std::numeric_limits<VecElemF64>::signaling_NaN();
                } else if (std::fpclassify(src1[lane]) == FP_ZERO
                           || std::isinf(src2[lane])) {
                    vdst[lane] = sign_out ? -INFINITY : +INFINITY;
                } else if (std::isinf(src1[lane])
                           || std::fpclassify(src2[lane]) == FP_ZERO) {
                    vdst[lane] = sign_out ? -0.0 : +0.0;
                } else if (exp2 - exp1 < -1075) {
                    vdst[lane] = src0[lane];
                } else if (exp1 == 2047) {
                    vdst[lane] = src0[lane];
                } else {
                    vdst[lane] = sign_out ? -std::fabs(src0[lane])
                        : std::fabs(src0[lane]);
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_DIV_SCALE_F32 class methods ---

    Inst_VOP3__V_DIV_SCALE_F32::Inst_VOP3__V_DIV_SCALE_F32(
          InFmt_VOP3B *iFmt)
        : Inst_VOP3B(iFmt, "v_div_scale_f32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
        setFlag(F32);
    } // Inst_VOP3__V_DIV_SCALE_F32

    Inst_VOP3__V_DIV_SCALE_F32::~Inst_VOP3__V_DIV_SCALE_F32()
    {
    } // ~Inst_VOP3__V_DIV_SCALE_F32

    // --- description from .arch file ---
    // {vcc,D.f} = Divide preop and flags -- s0.f = Quotient, s1.f =
    // Denominator, s2.f = Numerator -- s0 must equal s1 or s2. Given a
    // numerator and denominator, this opcode will appropriately scale inputs
    // for division to avoid subnormal terms during Newton-Raphson correction
    // algorithm. This opcode producses a VCC flag for post-scale of quotient.
    void
    Inst_VOP3__V_DIV_SCALE_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF32 src2(gpuDynInst, extData.SRC2);
        ScalarOperandU64 vcc(gpuDynInst, instData.SDST);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane];
                vcc.setBit(lane, 0);
            }
        }

        vcc.write();
        vdst.write();
    } // execute
    // --- Inst_VOP3__V_DIV_SCALE_F64 class methods ---

    Inst_VOP3__V_DIV_SCALE_F64::Inst_VOP3__V_DIV_SCALE_F64(
          InFmt_VOP3B *iFmt)
        : Inst_VOP3B(iFmt, "v_div_scale_f64")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
        setFlag(F64);
    } // Inst_VOP3__V_DIV_SCALE_F64

    Inst_VOP3__V_DIV_SCALE_F64::~Inst_VOP3__V_DIV_SCALE_F64()
    {
    } // ~Inst_VOP3__V_DIV_SCALE_F64

    // --- description from .arch file ---
    // {vcc,D.d} = Divide preop and flags -- s0.d = Quotient, s1.d =
    // Denominator, s2.d = Numerator -- s0 must equal s1 or s2. Given a
    // numerator and denominator, this opcode will appropriately scale inputs
    // for division to avoid subnormal terms during Newton-Raphson correction
    // algorithm. This opcode producses a VCC flag for post-scale of quotient.
    void
    Inst_VOP3__V_DIV_SCALE_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF64 src2(gpuDynInst, extData.SRC2);
        ScalarOperandU64 vcc(gpuDynInst, instData.SDST);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                int exp1(0);
                int exp2(0);
                std::frexp(src1[lane], &exp1);
                std::frexp(src2[lane], &exp2);
                vcc.setBit(lane, 0);

                if (std::fpclassify(src1[lane]) == FP_ZERO
                    || std::fpclassify(src2[lane]) == FP_ZERO) {
                    vdst[lane] = NAN;
                } else if (exp2 - exp1 >= 768) {
                    vcc.setBit(lane, 1);
                    if (src0[lane] == src1[lane]) {
                        vdst[lane] = std::ldexp(src0[lane], 128);
                    }
                } else if (std::fpclassify(src1[lane]) == FP_SUBNORMAL) {
                    vdst[lane] = std::ldexp(src0[lane], 128);
                } else if (std::fpclassify(1.0 / src1[lane]) == FP_SUBNORMAL
                           && std::fpclassify(src2[lane] / src1[lane])
                           == FP_SUBNORMAL) {
                    vcc.setBit(lane, 1);
                    if (src0[lane] == src1[lane]) {
                        vdst[lane] = std::ldexp(src0[lane], 128);
                    }
                } else if (std::fpclassify(1.0 / src1[lane]) == FP_SUBNORMAL) {
                    vdst[lane] = std::ldexp(src0[lane], -128);
                } else if (std::fpclassify(src2[lane] / src1[lane])
                           == FP_SUBNORMAL) {
                    vcc.setBit(lane, 1);
                    if (src0[lane] == src2[lane]) {
                        vdst[lane] = std::ldexp(src0[lane], 128);
                    }
                } else if (exp2 <= 53) {
                    vdst[lane] = std::ldexp(src0[lane], 128);
                }
            }
        }

        vcc.write();
        vdst.write();
    } // execute
    // --- Inst_VOP3__V_DIV_FMAS_F32 class methods ---

    Inst_VOP3__V_DIV_FMAS_F32::Inst_VOP3__V_DIV_FMAS_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_div_fmas_f32", false)
    {
        setFlag(ALU);
        setFlag(ReadsVCC);
        setFlag(F32);
        setFlag(FMA);
    } // Inst_VOP3__V_DIV_FMAS_F32

    Inst_VOP3__V_DIV_FMAS_F32::~Inst_VOP3__V_DIV_FMAS_F32()
    {
    } // ~Inst_VOP3__V_DIV_FMAS_F32

    // --- description from .arch file ---
    // D.f = Special case divide FMA with scale and flags(s0.f = Quotient,
    // s1.f = Denominator, s2.f = Numerator)
    void
    Inst_VOP3__V_DIV_FMAS_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF32 src2(gpuDynInst, extData.SRC2);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (instData.ABS & 0x4) {
            src2.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fma(src0[lane], src1[lane], src2[lane]);
            }
        }

        //vdst.write();
    } // execute
    // --- Inst_VOP3__V_DIV_FMAS_F64 class methods ---

    Inst_VOP3__V_DIV_FMAS_F64::Inst_VOP3__V_DIV_FMAS_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_div_fmas_f64", false)
    {
        setFlag(ALU);
        setFlag(ReadsVCC);
        setFlag(F64);
        setFlag(FMA);
    } // Inst_VOP3__V_DIV_FMAS_F64

    Inst_VOP3__V_DIV_FMAS_F64::~Inst_VOP3__V_DIV_FMAS_F64()
    {
    } // ~Inst_VOP3__V_DIV_FMAS_F64

    // --- description from .arch file ---
    // D.d = Special case divide FMA with scale and flags(s0.d = Quotient,
    // s1.d = Denominator, s2.d = Numerator)
    void
    Inst_VOP3__V_DIV_FMAS_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandF64 src2(gpuDynInst, extData.SRC2);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);
        ConstScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();
        vcc.read();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (instData.ABS & 0x4) {
            src2.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        if (extData.NEG & 0x4) {
            src2.negModifier();
        }

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (bits(vcc.rawData(), lane)) {
                    vdst[lane] = std::pow(2, 64)
                        * std::fma(src0[lane], src1[lane], src2[lane]);
                } else {
                    vdst[lane] = std::fma(src0[lane], src1[lane], src2[lane]);
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MSAD_U8 class methods ---

    Inst_VOP3__V_MSAD_U8::Inst_VOP3__V_MSAD_U8(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_msad_u8", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MSAD_U8

    Inst_VOP3__V_MSAD_U8::~Inst_VOP3__V_MSAD_U8()
    {
    } // ~Inst_VOP3__V_MSAD_U8

    // --- description from .arch file ---
    // D.u = Masked Byte SAD with accum_lo(S0.u, S1.u, S2.u).
    void
    Inst_VOP3__V_MSAD_U8::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_QSAD_PK_U16_U8 class methods ---

    Inst_VOP3__V_QSAD_PK_U16_U8::Inst_VOP3__V_QSAD_PK_U16_U8(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_qsad_pk_u16_u8", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_QSAD_PK_U16_U8

    Inst_VOP3__V_QSAD_PK_U16_U8::~Inst_VOP3__V_QSAD_PK_U16_U8()
    {
    } // ~Inst_VOP3__V_QSAD_PK_U16_U8

    // --- description from .arch file ---
    // D.u = Quad-Byte SAD with 16-bit packed accum_lo/hi(S0.u[63:0],
    // S1.u[31:0], S2.u[63:0])
    void
    Inst_VOP3__V_QSAD_PK_U16_U8::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_MQSAD_PK_U16_U8 class methods ---

    Inst_VOP3__V_MQSAD_PK_U16_U8::Inst_VOP3__V_MQSAD_PK_U16_U8(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mqsad_pk_u16_u8", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MQSAD_PK_U16_U8

    Inst_VOP3__V_MQSAD_PK_U16_U8::~Inst_VOP3__V_MQSAD_PK_U16_U8()
    {
    } // ~Inst_VOP3__V_MQSAD_PK_U16_U8

    // --- description from .arch file ---
    // D.u = Masked Quad-Byte SAD with 16-bit packed accum_lo/hi(S0.u[63:0],
    // ---  S1.u[31:0], S2.u[63:0])
    void
    Inst_VOP3__V_MQSAD_PK_U16_U8::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_MQSAD_U32_U8 class methods ---

    Inst_VOP3__V_MQSAD_U32_U8::Inst_VOP3__V_MQSAD_U32_U8(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mqsad_u32_u8", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MQSAD_U32_U8

    Inst_VOP3__V_MQSAD_U32_U8::~Inst_VOP3__V_MQSAD_U32_U8()
    {
    } // ~Inst_VOP3__V_MQSAD_U32_U8

    // --- description from .arch file ---
    // D.u128 = Masked Quad-Byte SAD with 32-bit accum_lo/hi(S0.u[63:0],
    // ---  S1.u[31:0], S2.u[127:0])
    void
    Inst_VOP3__V_MQSAD_U32_U8::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_MAD_U64_U32 class methods ---

    Inst_VOP3__V_MAD_U64_U32::Inst_VOP3__V_MAD_U64_U32(
          InFmt_VOP3B *iFmt)
        : Inst_VOP3B(iFmt, "v_mad_u64_u32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
        setFlag(MAD);
    } // Inst_VOP3__V_MAD_U64_U32

    Inst_VOP3__V_MAD_U64_U32::~Inst_VOP3__V_MAD_U64_U32()
    {
    } // ~Inst_VOP3__V_MAD_U64_U32

    // --- description from .arch file ---
    // {vcc_out,D.u64} = S0.u32 * S1.u32 + S2.u64.
    void
    Inst_VOP3__V_MAD_U64_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU64 src2(gpuDynInst, extData.SRC2);
        ScalarOperandU64 vcc(gpuDynInst, instData.SDST);
        VecOperandU64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();
        vdst.read();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, muladd(vdst[lane], src0[lane], src1[lane],
                    src2[lane]));
            }
        }

        vcc.write();
        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAD_I64_I32 class methods ---

    Inst_VOP3__V_MAD_I64_I32::Inst_VOP3__V_MAD_I64_I32(
          InFmt_VOP3B *iFmt)
        : Inst_VOP3B(iFmt, "v_mad_i64_i32")
    {
        setFlag(ALU);
        setFlag(WritesVCC);
        setFlag(MAD);
    } // Inst_VOP3__V_MAD_I64_I32

    Inst_VOP3__V_MAD_I64_I32::~Inst_VOP3__V_MAD_I64_I32()
    {
    } // ~Inst_VOP3__V_MAD_I64_I32

    // --- description from .arch file ---
    // {vcc_out,D.i64} = S0.i32 * S1.i32 + S2.i64.
    void
    Inst_VOP3__V_MAD_I64_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandI64 src2(gpuDynInst, extData.SRC2);
        ScalarOperandU64 vcc(gpuDynInst, instData.SDST);
        VecOperandI64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vcc.setBit(lane, muladd(vdst[lane], src0[lane], src1[lane],
                    src2[lane]));
            }
        }

        vcc.write();
        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LSHL_ADD_U32 class methods ---

    Inst_VOP3__V_LSHL_ADD_U32::Inst_VOP3__V_LSHL_ADD_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_lshl_add_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_LSHL_ADD_U32

    Inst_VOP3__V_LSHL_ADD_U32::~Inst_VOP3__V_LSHL_ADD_U32()
    {
    } // ~Inst_VOP3__V_LSHL_ADD_U32

    // --- description from .arch file ---
    // D.u = (S0.u << S1.u[4:0]) + S2.u.
    void
    Inst_VOP3__V_LSHL_ADD_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (src0[lane] << bits(src1[lane], 4, 0))
                           + src2[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_ADD_LSHL_U32 class methods ---

    Inst_VOP3__V_ADD_LSHL_U32::Inst_VOP3__V_ADD_LSHL_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_add_lshl_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_ADD_LSHL_U32

    Inst_VOP3__V_ADD_LSHL_U32::~Inst_VOP3__V_ADD_LSHL_U32()
    {
    } // ~Inst_VOP3__V_ADD_LSHL_U32

    // --- description from .arch file ---
    // D.u = (S0.u + S1.u) << S2.u[4:0].
    void
    Inst_VOP3__V_ADD_LSHL_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] =
                    (src0[lane] + src1[lane]) << bits(src2[lane], 4, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_ADD3_U32 class methods ---

    Inst_VOP3__V_ADD3_U32::Inst_VOP3__V_ADD3_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_add3_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_ADD3_U32

    Inst_VOP3__V_ADD3_U32::~Inst_VOP3__V_ADD3_U32()
    {
    } // ~Inst_VOP3__V_ADD3_U32

    // --- description from .arch file ---
    // D.u = S0.u + S1.u + S2.u.
    void
    Inst_VOP3__V_ADD3_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] + src1[lane] + src2[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LSHL_OR_B32 class methods ---

    Inst_VOP3__V_LSHL_OR_B32::Inst_VOP3__V_LSHL_OR_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_lshl_or_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_LSHL_OR_B32

    Inst_VOP3__V_LSHL_OR_B32::~Inst_VOP3__V_LSHL_OR_B32()
    {
    } // ~Inst_VOP3__V_LSHL_OR_B32

    // --- description from .arch file ---
    // D.u = (S0.u << S1.u[4:0]) | S2.u.
    void
    Inst_VOP3__V_LSHL_OR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = (src0[lane] << bits(src1[lane], 4, 0))
                           | src2[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAD_F16 class methods ---

    Inst_VOP3__V_MAD_F16::Inst_VOP3__V_MAD_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mad_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(MAD);
    } // Inst_VOP3__V_MAD_F16

    Inst_VOP3__V_MAD_F16::~Inst_VOP3__V_MAD_F16()
    {
    } // ~Inst_VOP3__V_MAD_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 * S1.f16 + S2.f16.
    // Supports round mode, exception flags, saturation.
    void
    Inst_VOP3__V_MAD_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_MAD_U16 class methods ---

    Inst_VOP3__V_MAD_U16::Inst_VOP3__V_MAD_U16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mad_u16", false)
    {
        setFlag(ALU);
        setFlag(MAD);
    } // Inst_VOP3__V_MAD_U16

    Inst_VOP3__V_MAD_U16::~Inst_VOP3__V_MAD_U16()
    {
    } // ~Inst_VOP3__V_MAD_U16

    // --- description from .arch file ---
    // D.u16 = S0.u16 * S1.u16 + S2.u16.
    // Supports saturation (unsigned 16-bit integer domain).
    void
    Inst_VOP3__V_MAD_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU16 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU16 src2(gpuDynInst, extData.SRC2);
        VecOperandU16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] * src1[lane] + src2[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAD_I16 class methods ---

    Inst_VOP3__V_MAD_I16::Inst_VOP3__V_MAD_I16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mad_i16", false)
    {
        setFlag(ALU);
        setFlag(MAD);
    } // Inst_VOP3__V_MAD_I16

    Inst_VOP3__V_MAD_I16::~Inst_VOP3__V_MAD_I16()
    {
    } // ~Inst_VOP3__V_MAD_I16

    // --- description from .arch file ---
    // D.i16 = S0.i16 * S1.i16 + S2.i16.
    // Supports saturation (signed 16-bit integer domain).
    void
    Inst_VOP3__V_MAD_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI16 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI16 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandI16 src2(gpuDynInst, extData.SRC2);
        VecOperandI16 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src0[lane] * src1[lane] + src2[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_PERM_B32 class methods ---

    Inst_VOP3__V_PERM_B32::Inst_VOP3__V_PERM_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_perm_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_PERM_B32

    Inst_VOP3__V_PERM_B32::~Inst_VOP3__V_PERM_B32()
    {
    } // ~Inst_VOP3__V_PERM_B32

    // --- description from .arch file ---
    // D.u[31:24] = permute({S0.u, S1.u}, S2.u[31:24]);
    // D.u[23:16] = permute({S0.u, S1.u}, S2.u[23:16]);
    // D.u[15:8] = permute({S0.u, S1.u}, S2.u[15:8]);
    // D.u[7:0] = permute({S0.u, S1.u}, S2.u[7:0]);
    // byte permute(byte in[8], byte sel) {
    //     if(sel>=13) then return 0xff;
    //     elsif(sel==12) then return 0x00;
    //     elsif(sel==11) then return in[7][7] * 0xff;
    //     elsif(sel==10) then return in[5][7] * 0xff;
    //     elsif(sel==9) then return in[3][7] * 0xff;
    //     elsif(sel==8) then return in[1][7] * 0xff;
    //     else return in[sel];
    //     }
    // Byte permute.
    void
    Inst_VOP3__V_PERM_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        ConstVecOperandU32 src2(gpuDynInst, extData.SRC2);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();
        src2.readSrc();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemU64 selector = (VecElemU64)src0[lane];
                selector = (selector << 32) | (VecElemU64)src1[lane];
                vdst[lane] = 0;

                DPRINTF(VEGA, "Executing v_perm_b32 src_0 0x%08x, src_1 "
                        "0x%08x, src_2 0x%08x, vdst 0x%08x\n", src0[lane],
                        src1[lane], src2[lane], vdst[lane]);
                DPRINTF(VEGA, "Selector: 0x%08x \n", selector);

                for (int i = 0; i < 4 ; ++i) {
                    VecElemU32 permuted_val = permute(selector, 0xFF
                        & ((VecElemU32)src2[lane] >> (8 * i)));
                    vdst[lane] |= (permuted_val << i);
                }

                DPRINTF(VEGA, "v_perm result: 0x%08x\n", vdst[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_FMA_F16 class methods ---

    Inst_VOP3__V_FMA_F16::Inst_VOP3__V_FMA_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_fma_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
        setFlag(FMA);
    } // Inst_VOP3__V_FMA_F16

    Inst_VOP3__V_FMA_F16::~Inst_VOP3__V_FMA_F16()
    {
    } // ~Inst_VOP3__V_FMA_F16

    // --- description from .arch file ---
    // D.f16 = S0.f16 * S1.f16 + S2.f16.
    // Fused half precision multiply add.
    void
    Inst_VOP3__V_FMA_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_DIV_FIXUP_F16 class methods ---

    Inst_VOP3__V_DIV_FIXUP_F16::Inst_VOP3__V_DIV_FIXUP_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_div_fixup_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_DIV_FIXUP_F16

    Inst_VOP3__V_DIV_FIXUP_F16::~Inst_VOP3__V_DIV_FIXUP_F16()
    {
    } // ~Inst_VOP3__V_DIV_FIXUP_F16

    // --- description from .arch file ---
    // sign_out =  sign(S1.f16)^sign(S2.f16);
    // if (S2.f16 == NAN)
    //     D.f16 = Quiet(S2.f16);
    // else if (S1.f16 == NAN)
    //     D.f16 = Quiet(S1.f16);
    // else if (S1.f16 == S2.f16 == 0)
    //     # 0/0
    //     D.f16 = pele_nan(0xfe00);
    // else if (abs(S1.f16) == abs(S2.f16) == +-INF)
    //     # inf/inf
    //     D.f16 = pele_nan(0xfe00);
    // else if (S1.f16 ==0 || abs(S2.f16) == +-INF)
    //     # x/0, or inf/y
    //     D.f16 = sign_out ? -INF : INF;
    // else if (abs(S1.f16) == +-INF || S2.f16 == 0)
    //     # x/inf, 0/y
    //     D.f16 = sign_out ? -0 : 0;
    // else if ((exp(S2.f16) - exp(S1.f16)) < -150)
    //     D.f16 = sign_out ? -underflow : underflow;
    // else if (exp(S1.f16) == 255)
    //     D.f16 = sign_out ? -overflow : overflow;
    // else
    //     D.f16 = sign_out ? -abs(S0.f16) : abs(S0.f16).
    // Half precision division fixup.
    // S0 = Quotient, S1 = Denominator, S3 = Numerator.
    // Given a numerator, denominator, and quotient from a divide, this opcode
    // will detect and apply special case numerics, touching up the quotient if
    // necessary. This opcode also generates invalid, denorm and divide by
    // zero exceptions caused by the division.
    void
    Inst_VOP3__V_DIV_FIXUP_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_PKACCUM_U8_F32 class methods ---

    Inst_VOP3__V_CVT_PKACCUM_U8_F32::Inst_VOP3__V_CVT_PKACCUM_U8_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_pkaccum_u8_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_PKACCUM_U8_F32

    Inst_VOP3__V_CVT_PKACCUM_U8_F32::~Inst_VOP3__V_CVT_PKACCUM_U8_F32()
    {
    } // ~Inst_VOP3__V_CVT_PKACCUM_U8_F32

    // --- description from .arch file ---
    // byte = S1.u[1:0]; bit = byte * 8;
    // D.u[bit+7:bit] = flt32_to_uint8(S0.f);
    // Pack converted value of S0.f into byte S1 of the destination.
    // SQ translates to V_CVT_PK_U8_F32.
    // Note: this opcode uses src_c to pass destination in as a source.
    void
    Inst_VOP3__V_CVT_PKACCUM_U8_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_INTERP_P1_F32 class methods ---

    Inst_VOP3__V_INTERP_P1_F32::Inst_VOP3__V_INTERP_P1_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_interp_p1_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_INTERP_P1_F32

    Inst_VOP3__V_INTERP_P1_F32::~Inst_VOP3__V_INTERP_P1_F32()
    {
    } // ~Inst_VOP3__V_INTERP_P1_F32

    // --- description from .arch file ---
    // D.f = P10 * S.f + P0; parameter interpolation (SQ translates to
    // V_MAD_F32 for SP).
    // CAUTION: when in HALF_LDS mode, D must not be the same GPR as S; if
    // D == S then data corruption will occur.
    // NOTE: In textual representations the I/J VGPR is the first source and
    // the attribute is the second source; however in the VOP3 encoding the
    // attribute is stored in the src0 field and the VGPR is stored in the
    // src1 field.
    void
    Inst_VOP3__V_INTERP_P1_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_INTERP_P2_F32 class methods ---

    Inst_VOP3__V_INTERP_P2_F32::Inst_VOP3__V_INTERP_P2_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_interp_p2_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_INTERP_P2_F32

    Inst_VOP3__V_INTERP_P2_F32::~Inst_VOP3__V_INTERP_P2_F32()
    {
    } // ~Inst_VOP3__V_INTERP_P2_F32

    // --- description from .arch file ---
    // D.f = P20 * S.f + D.f; parameter interpolation (SQ translates to
    // V_MAD_F32 for SP).
    // NOTE: In textual representations the I/J VGPR is the first source and
    // the attribute is the second source; however in the VOP3 encoding the
    // attribute is stored in the src0 field and the VGPR is stored in the
    // src1 field.
    void
    Inst_VOP3__V_INTERP_P2_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_INTERP_MOV_F32 class methods ---

    Inst_VOP3__V_INTERP_MOV_F32::Inst_VOP3__V_INTERP_MOV_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_interp_mov_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_INTERP_MOV_F32

    Inst_VOP3__V_INTERP_MOV_F32::~Inst_VOP3__V_INTERP_MOV_F32()
    {
    } // ~Inst_VOP3__V_INTERP_MOV_F32

    // --- description from .arch file ---
    // D.f = {P10,P20,P0}[S.u]; parameter load.
    void
    Inst_VOP3__V_INTERP_MOV_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_INTERP_P1LL_F16 class methods ---

    Inst_VOP3__V_INTERP_P1LL_F16::Inst_VOP3__V_INTERP_P1LL_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_interp_p1ll_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_INTERP_P1LL_F16

    Inst_VOP3__V_INTERP_P1LL_F16::~Inst_VOP3__V_INTERP_P1LL_F16()
    {
    } // ~Inst_VOP3__V_INTERP_P1LL_F16

    // --- description from .arch file ---
    // D.f32 = P10.f16 * S0.f32 + P0.f16.
    // 'LL' stands for 'two LDS arguments'.
    // attr_word selects the high or low half 16 bits of each LDS dword
    // accessed.
    // This opcode is available for 32-bank LDS only.
    // NOTE: In textual representations the I/J VGPR is the first source and
    // the attribute is the second source; however in the VOP3 encoding the
    // attribute is stored in the src0 field and the VGPR is stored in the
    // src1 field.
    void
    Inst_VOP3__V_INTERP_P1LL_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_INTERP_P1LV_F16 class methods ---

    Inst_VOP3__V_INTERP_P1LV_F16::Inst_VOP3__V_INTERP_P1LV_F16(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_interp_p1lv_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_INTERP_P1LV_F16

    Inst_VOP3__V_INTERP_P1LV_F16::~Inst_VOP3__V_INTERP_P1LV_F16()
    {
    } // ~Inst_VOP3__V_INTERP_P1LV_F16

    // --- description from .arch file ---
    // D.f32 = P10.f16 * S0.f32 + (S2.u32 >> (attr_word * 16)).f16.
    // 'LV' stands for 'One LDS and one VGPR argument'.
    // S2 holds two parameters, attr_word selects the high or low word of the
    // VGPR for this calculation, as well as the high or low half of the LDS
    // data.
    // Meant for use with 16-bank LDS.
    // NOTE: In textual representations the I/J VGPR is the first source and
    // the attribute is the second source; however in the VOP3 encoding the
    // attribute is stored in the src0 field and the VGPR is stored in the
    // src1 field.
    void
    Inst_VOP3__V_INTERP_P1LV_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_INTERP_P2_F16 class methods ---

    Inst_VOP3__V_INTERP_P2_F16::Inst_VOP3__V_INTERP_P2_F16(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_interp_p2_f16", false)
    {
        setFlag(ALU);
        setFlag(F16);
    } // Inst_VOP3__V_INTERP_P2_F16

    Inst_VOP3__V_INTERP_P2_F16::~Inst_VOP3__V_INTERP_P2_F16()
    {
    } // ~Inst_VOP3__V_INTERP_P2_F16

    // --- description from .arch file ---
    // D.f16 = P20.f16 * S0.f32 + S2.f32.
    // Final computation. attr_word selects LDS high or low 16bits. Used for
    // both 16- and 32-bank LDS.
    // Result is always written to the 16 LSBs of the destination VGPR.
    // NOTE: In textual representations the I/J VGPR is the first source and
    // the attribute is the second source; however in the VOP3 encoding the
    // attribute is stored in the src0 field and the VGPR is stored in the
    // src1 field.
    void
    Inst_VOP3__V_INTERP_P2_F16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_ADD_F64 class methods ---

    Inst_VOP3__V_ADD_F64::Inst_VOP3__V_ADD_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_add_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_ADD_F64

    Inst_VOP3__V_ADD_F64::~Inst_VOP3__V_ADD_F64()
    {
    } // ~Inst_VOP3__V_ADD_F64

    // --- description from .arch file ---
    // D.d = S0.d + S1.d.
    void
    Inst_VOP3__V_ADD_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isnan(src0[lane]) ||
                    std::isnan(src1[lane]) ) {
                        vdst[lane] = NAN;
                } else if (std::isinf(src0[lane]) &&
                           std::isinf(src1[lane])) {
                    if (std::signbit(src0[lane]) !=
                        std::signbit(src1[lane])) {
                        vdst[lane] = NAN;
                    } else {
                        vdst[lane] = src0[lane];
                    }
                } else if (std::isinf(src0[lane])) {
                    vdst[lane] = src0[lane];
                } else if (std::isinf(src1[lane])) {
                    vdst[lane] = src1[lane];
                } else if (std::fpclassify(src0[lane]) == FP_SUBNORMAL ||
                           std::fpclassify(src0[lane]) == FP_ZERO) {
                    if (std::fpclassify(src1[lane]) == FP_SUBNORMAL ||
                        std::fpclassify(src1[lane]) == FP_ZERO) {
                        if (std::signbit(src0[lane]) &&
                            std::signbit(src1[lane])) {
                            vdst[lane] = -0.0;
                        } else {
                            vdst[lane] = 0.0;
                        }
                    } else {
                        vdst[lane] = src1[lane];
                    }
                } else if (std::fpclassify(src1[lane]) == FP_SUBNORMAL ||
                           std::fpclassify(src1[lane]) == FP_ZERO) {
                    if (std::fpclassify(src0[lane]) == FP_SUBNORMAL ||
                        std::fpclassify(src0[lane]) == FP_ZERO) {
                        if (std::signbit(src0[lane]) &&
                            std::signbit(src1[lane])) {
                            vdst[lane] = -0.0;
                        } else {
                            vdst[lane] = 0.0;
                        }
                    } else {
                        vdst[lane] = src0[lane];
                    }
                } else {
                    vdst[lane] = src0[lane] + src1[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MUL_F64 class methods ---

    Inst_VOP3__V_MUL_F64::Inst_VOP3__V_MUL_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mul_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_MUL_F64

    Inst_VOP3__V_MUL_F64::~Inst_VOP3__V_MUL_F64()
    {
    } // ~Inst_VOP3__V_MUL_F64

    // --- description from .arch file ---
    // D.d = S0.d * S1.d.
    void
    Inst_VOP3__V_MUL_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isnan(src0[lane]) ||
                    std::isnan(src1[lane])) {
                    vdst[lane] = NAN;
                } else if ((std::fpclassify(src0[lane]) == FP_SUBNORMAL ||
                           std::fpclassify(src0[lane]) == FP_ZERO) &&
                           !std::signbit(src0[lane])) {
                    if (std::isinf(src1[lane])) {
                        vdst[lane] = NAN;
                    } else if (!std::signbit(src1[lane])) {
                        vdst[lane] = +0.0;
                    } else {
                        vdst[lane] = -0.0;
                    }
                } else if ((std::fpclassify(src0[lane]) == FP_SUBNORMAL ||
                           std::fpclassify(src0[lane]) == FP_ZERO) &&
                           std::signbit(src0[lane])) {
                    if (std::isinf(src1[lane])) {
                        vdst[lane] = NAN;
                    } else if (std::signbit(src1[lane])) {
                        vdst[lane] = +0.0;
                    } else {
                        vdst[lane] = -0.0;
                    }
                } else if (std::isinf(src0[lane]) &&
                           !std::signbit(src0[lane])) {
                    if (std::fpclassify(src1[lane]) == FP_SUBNORMAL ||
                        std::fpclassify(src1[lane]) == FP_ZERO) {
                        vdst[lane] = NAN;
                    } else if (!std::signbit(src1[lane])) {
                        vdst[lane] = +INFINITY;
                    } else {
                        vdst[lane] = -INFINITY;
                    }
                } else if (std::isinf(src0[lane]) &&
                           std::signbit(src0[lane])) {
                    if (std::fpclassify(src1[lane]) == FP_SUBNORMAL ||
                        std::fpclassify(src1[lane]) == FP_ZERO) {
                        vdst[lane] = NAN;
                    } else if (std::signbit(src1[lane])) {
                        vdst[lane] = +INFINITY;
                    } else {
                        vdst[lane] = -INFINITY;
                    }
                } else {
                    vdst[lane] = src0[lane] * src1[lane];
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MIN_F64 class methods ---

    Inst_VOP3__V_MIN_F64::Inst_VOP3__V_MIN_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_min_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_MIN_F64

    Inst_VOP3__V_MIN_F64::~Inst_VOP3__V_MIN_F64()
    {
    } // ~Inst_VOP3__V_MIN_F64

    // --- description from .arch file ---
    // D.d = min(S0.d, S1.d).
    void
    Inst_VOP3__V_MIN_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fmin(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MAX_F64 class methods ---

    Inst_VOP3__V_MAX_F64::Inst_VOP3__V_MAX_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_max_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_MAX_F64

    Inst_VOP3__V_MAX_F64::~Inst_VOP3__V_MAX_F64()
    {
    } // ~Inst_VOP3__V_MAX_F64

    // --- description from .arch file ---
    // D.d = max(S0.d, S1.d).
    void
    Inst_VOP3__V_MAX_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandF64 src1(gpuDynInst, extData.SRC1);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (instData.ABS & 0x2) {
            src1.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        if (extData.NEG & 0x2) {
            src1.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::fmax(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LDEXP_F64 class methods ---

    Inst_VOP3__V_LDEXP_F64::Inst_VOP3__V_LDEXP_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_ldexp_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_LDEXP_F64

    Inst_VOP3__V_LDEXP_F64::~Inst_VOP3__V_LDEXP_F64()
    {
    } // ~Inst_VOP3__V_LDEXP_F64

    // --- description from .arch file ---
    // D.d = pow(S0.d, S1.i[31:0]).
    void
    Inst_VOP3__V_LDEXP_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF64 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandF64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        if (instData.ABS & 0x1) {
            src0.absModifier();
        }

        if (extData.NEG & 0x1) {
            src0.negModifier();
        }

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                if (std::isnan(src0[lane]) || std::isinf(src0[lane])) {
                    vdst[lane] = src0[lane];
                } else if (std::fpclassify(src0[lane]) == FP_SUBNORMAL
                           || std::fpclassify(src0[lane]) == FP_ZERO) {
                    if (std::signbit(src0[lane])) {
                        vdst[lane] = -0.0;
                    } else {
                        vdst[lane] = +0.0;
                    }
                } else {
                    vdst[lane] = std::ldexp(src0[lane], src1[lane]);
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MUL_LO_U32 class methods ---

    Inst_VOP3__V_MUL_LO_U32::Inst_VOP3__V_MUL_LO_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mul_lo_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MUL_LO_U32

    Inst_VOP3__V_MUL_LO_U32::~Inst_VOP3__V_MUL_LO_U32()
    {
    } // ~Inst_VOP3__V_MUL_LO_U32

    // --- description from .arch file ---
    // D.u = S0.u * S1.u.
    void
    Inst_VOP3__V_MUL_LO_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemI64 s0 = (VecElemI64)src0[lane];
                VecElemI64 s1 = (VecElemI64)src1[lane];
                vdst[lane] = (VecElemU32)((s0 * s1) & 0xffffffffLL);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MUL_HI_U32 class methods ---

    Inst_VOP3__V_MUL_HI_U32::Inst_VOP3__V_MUL_HI_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mul_hi_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MUL_HI_U32

    Inst_VOP3__V_MUL_HI_U32::~Inst_VOP3__V_MUL_HI_U32()
    {
    } // ~Inst_VOP3__V_MUL_HI_U32

    // --- description from .arch file ---
    // D.u = (S0.u * S1.u) >> 32.
    void
    Inst_VOP3__V_MUL_HI_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemI64 s0 = (VecElemI64)src0[lane];
                VecElemI64 s1 = (VecElemI64)src1[lane];
                vdst[lane]
                    = (VecElemU32)(((s0 * s1) >> 32) & 0xffffffffLL);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MUL_HI_I32 class methods ---

    Inst_VOP3__V_MUL_HI_I32::Inst_VOP3__V_MUL_HI_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mul_hi_i32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MUL_HI_I32

    Inst_VOP3__V_MUL_HI_I32::~Inst_VOP3__V_MUL_HI_I32()
    {
    } // ~Inst_VOP3__V_MUL_HI_I32

    // --- description from .arch file ---
    // D.i = (S0.i * S1.i) >> 32.
    void
    Inst_VOP3__V_MUL_HI_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandI32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        VecOperandI32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                VecElemI64 s0 = (VecElemI64)src0[lane];
                VecElemI64 s1 = (VecElemI64)src1[lane];
                vdst[lane]
                    = (VecElemI32)(((s0 * s1) >> 32LL) & 0xffffffffLL);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LDEXP_F32 class methods ---

    Inst_VOP3__V_LDEXP_F32::Inst_VOP3__V_LDEXP_F32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_ldexp_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_LDEXP_F32

    Inst_VOP3__V_LDEXP_F32::~Inst_VOP3__V_LDEXP_F32()
    {
    } // ~Inst_VOP3__V_LDEXP_F32

    // --- description from .arch file ---
    // D.f = pow(S0.f, S1.i)
    void
    Inst_VOP3__V_LDEXP_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandF32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI32 src1(gpuDynInst, extData.SRC1);
        VecOperandF32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = std::ldexp(src0[lane], src1[lane]);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_READLANE_B32 class methods ---

    Inst_VOP3__V_READLANE_B32::Inst_VOP3__V_READLANE_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_readlane_b32", true)
    {
        setFlag(ALU);
        setFlag(IgnoreExec);
    } // Inst_VOP3__V_READLANE_B32

    Inst_VOP3__V_READLANE_B32::~Inst_VOP3__V_READLANE_B32()
    {
    } // ~Inst_VOP3__V_READLANE_B32

    // --- description from .arch file ---
    // Copy one VGPR value to one SGPR. D = SGPR-dest, S0 = Source Data (VGPR#
    // or M0(lds-direct)), S1 = Lane Select (SGPR or M0). Ignores exec mask.
    // Input and output modifiers not supported; this is an untyped operation.
    void
    Inst_VOP3__V_READLANE_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstScalarOperandU32 src1(gpuDynInst, extData.SRC1);
        ScalarOperandU32 sdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.read();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        sdst = src0[src1.rawData() & 0x3f];

        sdst.write();
    } // execute
    // --- Inst_VOP3__V_WRITELANE_B32 class methods ---

    Inst_VOP3__V_WRITELANE_B32::Inst_VOP3__V_WRITELANE_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_writelane_b32", false)
    {
        setFlag(ALU);
        setFlag(IgnoreExec);
    } // Inst_VOP3__V_WRITELANE_B32

    Inst_VOP3__V_WRITELANE_B32::~Inst_VOP3__V_WRITELANE_B32()
    {
    } // ~Inst_VOP3__V_WRITELANE_B32

    // --- description from .arch file ---
    // Write value into one VGPR in one lane. D = VGPR-dest, S0 = Source Data
    // (sgpr, m0, exec or constants), S1 = Lane Select (SGPR or M0). Ignores
    // exec mask.
    // Input and output modifiers not supported; this is an untyped operation.
    // SQ translates to V_MOV_B32.
    void
    Inst_VOP3__V_WRITELANE_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        ConstScalarOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstScalarOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.read();
        src1.read();
        vdst.read();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        vdst[src1.rawData() & 0x3f] = src0.rawData();

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_BCNT_U32_B32 class methods ---

    Inst_VOP3__V_BCNT_U32_B32::Inst_VOP3__V_BCNT_U32_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_bcnt_u32_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_BCNT_U32_B32

    Inst_VOP3__V_BCNT_U32_B32::~Inst_VOP3__V_BCNT_U32_B32()
    {
    } // ~Inst_VOP3__V_BCNT_U32_B32

    // --- description from .arch file ---
    // D.u = CountOneBits(S0.u) + S1.u. Bit count.
    void
    Inst_VOP3__V_BCNT_U32_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = popCount(src0[lane]) + src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MBCNT_LO_U32_B32 class methods ---

    Inst_VOP3__V_MBCNT_LO_U32_B32::Inst_VOP3__V_MBCNT_LO_U32_B32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mbcnt_lo_u32_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MBCNT_LO_U32_B32

    Inst_VOP3__V_MBCNT_LO_U32_B32::~Inst_VOP3__V_MBCNT_LO_U32_B32()
    {
    } // ~Inst_VOP3__V_MBCNT_LO_U32_B32

    // --- description from .arch file ---
    // ThreadMask = (1 << ThreadPosition) - 1;
    // D.u = CountOneBits(S0.u & ThreadMask[31:0]) + S1.u.
    // Masked bit count, ThreadPosition is the position of this thread in the
    // ---  wavefront (in 0..63).
    void
    Inst_VOP3__V_MBCNT_LO_U32_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        uint64_t threadMask = 0;

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                threadMask = ((1LL << lane) - 1LL);
                vdst[lane] = popCount(src0[lane] & bits(threadMask, 31, 0)) +
                             src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_MBCNT_HI_U32_B32 class methods ---

    Inst_VOP3__V_MBCNT_HI_U32_B32::Inst_VOP3__V_MBCNT_HI_U32_B32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_mbcnt_hi_u32_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_MBCNT_HI_U32_B32

    Inst_VOP3__V_MBCNT_HI_U32_B32::~Inst_VOP3__V_MBCNT_HI_U32_B32()
    {
    } // ~Inst_VOP3__V_MBCNT_HI_U32_B32

    // --- description from .arch file ---
    // ThreadMask = (1 << ThreadPosition) - 1;
    // D.u = CountOneBits(S0.u & ThreadMask[63:32]) + S1.u.
    // Masked bit count, ThreadPosition is the position of this thread in the
    // ---  wavefront (in 0..63).
    void
    Inst_VOP3__V_MBCNT_HI_U32_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);
        uint64_t threadMask = 0;

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                threadMask = ((1LL << lane) - 1LL);
                vdst[lane] = popCount(src0[lane] & bits(threadMask, 63, 32)) +
                             src1[lane];
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LSHLREV_B64 class methods ---

    Inst_VOP3__V_LSHLREV_B64::Inst_VOP3__V_LSHLREV_B64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_lshlrev_b64", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_LSHLREV_B64

    Inst_VOP3__V_LSHLREV_B64::~Inst_VOP3__V_LSHLREV_B64()
    {
    } // ~Inst_VOP3__V_LSHLREV_B64

    // --- description from .arch file ---
    // D.u64 = S1.u64 << S0.u[5:0].
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP3__V_LSHLREV_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        VecOperandU64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] << bits(src0[lane], 5, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_LSHRREV_B64 class methods ---

    Inst_VOP3__V_LSHRREV_B64::Inst_VOP3__V_LSHRREV_B64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_lshrrev_b64", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_LSHRREV_B64

    Inst_VOP3__V_LSHRREV_B64::~Inst_VOP3__V_LSHRREV_B64()
    {
    } // ~Inst_VOP3__V_LSHRREV_B64

    // --- description from .arch file ---
    // D.u64 = S1.u64 >> S0.u[5:0].
    // The vacated bits are set to zero.
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP3__V_LSHRREV_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU64 src1(gpuDynInst, extData.SRC1);
        VecOperandU64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = src1[lane] >> bits(src0[lane], 5, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_ASHRREV_I64 class methods ---

    Inst_VOP3__V_ASHRREV_I64::Inst_VOP3__V_ASHRREV_I64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_ashrrev_i64", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_ASHRREV_I64

    Inst_VOP3__V_ASHRREV_I64::~Inst_VOP3__V_ASHRREV_I64()
    {
    } // ~Inst_VOP3__V_ASHRREV_I64

    // --- description from .arch file ---
    // D.u64 = signext(S1.u64) >> S0.u[5:0].
    // The vacated bits are set to the sign bit of the input value.
    // SQ translates this to an internal SP opcode.
    void
    Inst_VOP3__V_ASHRREV_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandI64 src1(gpuDynInst, extData.SRC1);
        VecOperandU64 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane]
                    = src1[lane] >> bits(src0[lane], 5, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_TRIG_PREOP_F64 class methods ---

    Inst_VOP3__V_TRIG_PREOP_F64::Inst_VOP3__V_TRIG_PREOP_F64(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_trig_preop_f64", false)
    {
        setFlag(ALU);
        setFlag(F64);
    } // Inst_VOP3__V_TRIG_PREOP_F64

    Inst_VOP3__V_TRIG_PREOP_F64::~Inst_VOP3__V_TRIG_PREOP_F64()
    {
    } // ~Inst_VOP3__V_TRIG_PREOP_F64

    // --- description from .arch file ---
    // D.d = Look Up 2/PI (S0.d) with segment select S1.u[4:0]. This operation
    // returns an aligned, double precision segment of 2/PI needed to do range
    // reduction on S0.d (double-precision value). Multiple segments can be
    // specified through S1.u[4:0]. Rounding is always round-to-zero. Large
    // inputs (exp > 1968) are scaled to avoid loss of precision through
    // denormalization.
    void
    Inst_VOP3__V_TRIG_PREOP_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_BFM_B32 class methods ---

    Inst_VOP3__V_BFM_B32::Inst_VOP3__V_BFM_B32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_bfm_b32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_BFM_B32

    Inst_VOP3__V_BFM_B32::~Inst_VOP3__V_BFM_B32()
    {
    } // ~Inst_VOP3__V_BFM_B32

    // --- description from .arch file ---
    // D.u = ((1<<S0.u[4:0])-1) << S1.u[4:0]; S0 is the bitfield width and S1
    // is the bitfield offset.
    void
    Inst_VOP3__V_BFM_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        ConstVecOperandU32 src0(gpuDynInst, extData.SRC0);
        ConstVecOperandU32 src1(gpuDynInst, extData.SRC1);
        VecOperandU32 vdst(gpuDynInst, instData.VDST);

        src0.readSrc();
        src1.readSrc();

        /**
         * input modifiers are supported by FP operations only
         */
        assert(!(instData.ABS & 0x1));
        assert(!(instData.ABS & 0x2));
        assert(!(instData.ABS & 0x4));
        assert(!(extData.NEG & 0x1));
        assert(!(extData.NEG & 0x2));
        assert(!(extData.NEG & 0x4));

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (wf->execMask(lane)) {
                vdst[lane] = ((1 << bits(src0[lane], 4, 0)) - 1)
                    << bits(src1[lane], 4, 0);
            }
        }

        vdst.write();
    } // execute
    // --- Inst_VOP3__V_CVT_PKNORM_I16_F32 class methods ---

    Inst_VOP3__V_CVT_PKNORM_I16_F32::Inst_VOP3__V_CVT_PKNORM_I16_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_pknorm_i16_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_PKNORM_I16_F32

    Inst_VOP3__V_CVT_PKNORM_I16_F32::~Inst_VOP3__V_CVT_PKNORM_I16_F32()
    {
    } // ~Inst_VOP3__V_CVT_PKNORM_I16_F32

    // --- description from .arch file ---
    // D = {(snorm)S1.f, (snorm)S0.f}.
    void
    Inst_VOP3__V_CVT_PKNORM_I16_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_PKNORM_U16_F32 class methods ---

    Inst_VOP3__V_CVT_PKNORM_U16_F32::Inst_VOP3__V_CVT_PKNORM_U16_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_pknorm_u16_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_PKNORM_U16_F32

    Inst_VOP3__V_CVT_PKNORM_U16_F32::~Inst_VOP3__V_CVT_PKNORM_U16_F32()
    {
    } // ~Inst_VOP3__V_CVT_PKNORM_U16_F32

    // --- description from .arch file ---
    // D = {(unorm)S1.f, (unorm)S0.f}.
    void
    Inst_VOP3__V_CVT_PKNORM_U16_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_PKRTZ_F16_F32 class methods ---

    Inst_VOP3__V_CVT_PKRTZ_F16_F32::Inst_VOP3__V_CVT_PKRTZ_F16_F32(
          InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_pkrtz_f16_f32", false)
    {
        setFlag(ALU);
        setFlag(F32);
    } // Inst_VOP3__V_CVT_PKRTZ_F16_F32

    Inst_VOP3__V_CVT_PKRTZ_F16_F32::~Inst_VOP3__V_CVT_PKRTZ_F16_F32()
    {
    } // ~Inst_VOP3__V_CVT_PKRTZ_F16_F32

    // --- description from .arch file ---
    // D = {flt32_to_flt16(S1.f),flt32_to_flt16(S0.f)}, with round-toward-zero
    // ---  regardless of current round mode setting in hardware.
    // This opcode is intended for use with 16-bit compressed exports.
    // See V_CVT_F16_F32 for a version that respects the current rounding mode.
    void
    Inst_VOP3__V_CVT_PKRTZ_F16_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_PK_U16_U32 class methods ---

    Inst_VOP3__V_CVT_PK_U16_U32::Inst_VOP3__V_CVT_PK_U16_U32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_pk_u16_u32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CVT_PK_U16_U32

    Inst_VOP3__V_CVT_PK_U16_U32::~Inst_VOP3__V_CVT_PK_U16_U32()
    {
    } // ~Inst_VOP3__V_CVT_PK_U16_U32

    // --- description from .arch file ---
    // D = {uint32_to_uint16(S1.u), uint32_to_uint16(S0.u)}.
    void
    Inst_VOP3__V_CVT_PK_U16_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_VOP3__V_CVT_PK_I16_I32 class methods ---

    Inst_VOP3__V_CVT_PK_I16_I32::Inst_VOP3__V_CVT_PK_I16_I32(InFmt_VOP3A *iFmt)
        : Inst_VOP3A(iFmt, "v_cvt_pk_i16_i32", false)
    {
        setFlag(ALU);
    } // Inst_VOP3__V_CVT_PK_I16_I32

    Inst_VOP3__V_CVT_PK_I16_I32::~Inst_VOP3__V_CVT_PK_I16_I32()
    {
    } // ~Inst_VOP3__V_CVT_PK_I16_I32

    // --- description from .arch file ---
    // D = {int32_to_int16(S1.i), int32_to_int16(S0.i)}.
    void
    Inst_VOP3__V_CVT_PK_I16_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_ADD_U32 class methods ---

    Inst_DS__DS_ADD_U32::Inst_DS__DS_ADD_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_add_u32")
    {
    } // Inst_DS__DS_ADD_U32

    Inst_DS__DS_ADD_U32::~Inst_DS__DS_ADD_U32()
    {
    } // ~Inst_DS__DS_ADD_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] += DATA;
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_ADD_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_SUB_U32 class methods ---

    Inst_DS__DS_SUB_U32::Inst_DS__DS_SUB_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_sub_u32")
    {
    } // Inst_DS__DS_SUB_U32

    Inst_DS__DS_SUB_U32::~Inst_DS__DS_SUB_U32()
    {
    } // ~Inst_DS__DS_SUB_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_SUB_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_RSUB_U32 class methods ---

    Inst_DS__DS_RSUB_U32::Inst_DS__DS_RSUB_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_rsub_u32")
    {
    } // Inst_DS__DS_RSUB_U32

    Inst_DS__DS_RSUB_U32::~Inst_DS__DS_RSUB_U32()
    {
    } // ~Inst_DS__DS_RSUB_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = DATA - MEM[ADDR];
    // RETURN_DATA = tmp.
    // Subtraction with reversed operands.
    void
    Inst_DS__DS_RSUB_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_INC_U32 class methods ---

    Inst_DS__DS_INC_U32::Inst_DS__DS_INC_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_inc_u32")
    {
    } // Inst_DS__DS_INC_U32

    Inst_DS__DS_INC_U32::~Inst_DS__DS_INC_U32()
    {
    } // ~Inst_DS__DS_INC_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp >= DATA) ? 0 : tmp + 1 (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_INC_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_DEC_U32 class methods ---

    Inst_DS__DS_DEC_U32::Inst_DS__DS_DEC_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_dec_u32")
    {
    } // Inst_DS__DS_DEC_U32

    Inst_DS__DS_DEC_U32::~Inst_DS__DS_DEC_U32()
    {
    } // ~Inst_DS__DS_DEC_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp == 0 || tmp > DATA) ? DATA : tmp - 1
    // (unsigned compare); RETURN_DATA = tmp.
    void
    Inst_DS__DS_DEC_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_I32 class methods ---

    Inst_DS__DS_MIN_I32::Inst_DS__DS_MIN_I32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_i32")
    {
    } // Inst_DS__DS_MIN_I32

    Inst_DS__DS_MIN_I32::~Inst_DS__DS_MIN_I32()
    {
    } // ~Inst_DS__DS_MIN_I32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA < tmp) ? DATA : tmp (signed compare);
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_MIN_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_I32 class methods ---

    Inst_DS__DS_MAX_I32::Inst_DS__DS_MAX_I32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_i32")
    {
    } // Inst_DS__DS_MAX_I32

    Inst_DS__DS_MAX_I32::~Inst_DS__DS_MAX_I32()
    {
    } // ~Inst_DS__DS_MAX_I32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA > tmp) ? DATA : tmp (signed compare);
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_MAX_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_U32 class methods ---

    Inst_DS__DS_MIN_U32::Inst_DS__DS_MIN_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_u32")
    {
    } // Inst_DS__DS_MIN_U32

    Inst_DS__DS_MIN_U32::~Inst_DS__DS_MIN_U32()
    {
    } // ~Inst_DS__DS_MIN_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA < tmp) ? DATA : tmp (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_MIN_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_U32 class methods ---

    Inst_DS__DS_MAX_U32::Inst_DS__DS_MAX_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_u32")
    {
    } // Inst_DS__DS_MAX_U32

    Inst_DS__DS_MAX_U32::~Inst_DS__DS_MAX_U32()
    {
    } // ~Inst_DS__DS_MAX_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA > tmp) ? DATA : tmp (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_MAX_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_AND_B32 class methods ---

    Inst_DS__DS_AND_B32::Inst_DS__DS_AND_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_and_b32")
    {
    } // Inst_DS__DS_AND_B32

    Inst_DS__DS_AND_B32::~Inst_DS__DS_AND_B32()
    {
    } // ~Inst_DS__DS_AND_B32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] &= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_AND_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_OR_B32 class methods ---

    Inst_DS__DS_OR_B32::Inst_DS__DS_OR_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_or_b32")
    {
    } // Inst_DS__DS_OR_B32

    Inst_DS__DS_OR_B32::~Inst_DS__DS_OR_B32()
    {
    } // ~Inst_DS__DS_OR_B32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] |= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_OR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_XOR_B32 class methods ---

    Inst_DS__DS_XOR_B32::Inst_DS__DS_XOR_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_xor_b32")
    {
    } // Inst_DS__DS_XOR_B32

    Inst_DS__DS_XOR_B32::~Inst_DS__DS_XOR_B32()
    {
    } // ~Inst_DS__DS_XOR_B32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] ^= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_XOR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MSKOR_B32 class methods ---

    Inst_DS__DS_MSKOR_B32::Inst_DS__DS_MSKOR_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_mskor_b32")
    {
    } // Inst_DS__DS_MSKOR_B32

    Inst_DS__DS_MSKOR_B32::~Inst_DS__DS_MSKOR_B32()
    {
    } // ~Inst_DS__DS_MSKOR_B32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (MEM_ADDR[ADDR] & ~DATA) | DATA2;
    // RETURN_DATA = tmp.
    // Masked dword OR, D0 contains the mask and D1 contains the new value.
    void
    Inst_DS__DS_MSKOR_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRITE_B32 class methods ---

    Inst_DS__DS_WRITE_B32::Inst_DS__DS_WRITE_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_write_b32")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_DS__DS_WRITE_B32

    Inst_DS__DS_WRITE_B32::~Inst_DS__DS_WRITE_B32()
    {
    } // ~Inst_DS__DS_WRITE_B32

    // --- description from .arch file ---
    // 32b:
    // MEM[ADDR] = DATA.
    // Write dword.
    void
    Inst_DS__DS_WRITE_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU32 data(gpuDynInst, extData.DATA0);

        addr.read();
        data.read();

        calcAddr(gpuDynInst, addr);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane]
                    = data[lane];
            }
        }

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_WRITE_B32::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0;
        Addr offset1 = instData.OFFSET1;
        Addr offset = (offset1 << 8) | offset0;

        initMemWrite<VecElemU32>(gpuDynInst, offset);
    } // initiateAcc

    void
    Inst_DS__DS_WRITE_B32::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_DS__DS_WRITE2_B32 class methods ---

    Inst_DS__DS_WRITE2_B32::Inst_DS__DS_WRITE2_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_write2_b32")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_DS__DS_WRITE2_B32

    Inst_DS__DS_WRITE2_B32::~Inst_DS__DS_WRITE2_B32()
    {
    } // ~Inst_DS__DS_WRITE2_B32

    // --- description from .arch file ---
    // 32b:
    // MEM[ADDR_BASE + OFFSET0 * 4] = DATA;
    // MEM[ADDR_BASE + OFFSET1 * 4] = DATA2.
    // Write 2 dwords.
    void
    Inst_DS__DS_WRITE2_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU32 data0(gpuDynInst, extData.DATA0);
        ConstVecOperandU32 data1(gpuDynInst, extData.DATA1);

        addr.read();
        data0.read();
        data1.read();

        calcAddr(gpuDynInst, addr);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane * 2]
                    = data0[lane];
                (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 2 + 1] = data1[lane];
            }
        }

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_WRITE2_B32::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0 * 4;
        Addr offset1 = instData.OFFSET1 * 4;

        initDualMemWrite<VecElemU32>(gpuDynInst, offset0, offset1);
    }

    void
    Inst_DS__DS_WRITE2_B32::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    }
    // --- Inst_DS__DS_WRITE2ST64_B32 class methods ---

    Inst_DS__DS_WRITE2ST64_B32::Inst_DS__DS_WRITE2ST64_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_write2st64_b32")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_DS__DS_WRITE2ST64_B32

    Inst_DS__DS_WRITE2ST64_B32::~Inst_DS__DS_WRITE2ST64_B32()
    {
    } // ~Inst_DS__DS_WRITE2ST64_B32

    // --- description from .arch file ---
    // 32b:
    // MEM[ADDR_BASE + OFFSET0 * 4 * 64] = DATA;
    // MEM[ADDR_BASE + OFFSET1 * 4 * 64] = DATA2;
    // Write 2 dwords.
    void
    Inst_DS__DS_WRITE2ST64_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU32 data0(gpuDynInst, extData.DATA0);
        ConstVecOperandU32 data1(gpuDynInst, extData.DATA1);

        addr.read();
        data0.read();
        data1.read();

        calcAddr(gpuDynInst, addr);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane * 2]
                    = data0[lane];
                (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 2 + 1] = data1[lane];
            }
        }

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_WRITE2ST64_B32::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0 * 4 * 64;
        Addr offset1 = instData.OFFSET1 * 4 * 64;

        initDualMemWrite<VecElemU32>(gpuDynInst, offset0, offset1);
    }

    void
    Inst_DS__DS_WRITE2ST64_B32::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    }
    // --- Inst_DS__DS_CMPST_B32 class methods ---

    Inst_DS__DS_CMPST_B32::Inst_DS__DS_CMPST_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_cmpst_b32")
    {
    } // Inst_DS__DS_CMPST_B32

    Inst_DS__DS_CMPST_B32::~Inst_DS__DS_CMPST_B32()
    {
    } // ~Inst_DS__DS_CMPST_B32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // src = DATA2;
    // cmp = DATA;
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0] = tmp.
    // Compare and store.
    // Caution, the order of src and cmp are the *opposite* of the
    // ---  BUFFER_ATOMIC_CMPSWAP opcode.
    void
    Inst_DS__DS_CMPST_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_CMPST_F32 class methods ---

    Inst_DS__DS_CMPST_F32::Inst_DS__DS_CMPST_F32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_cmpst_f32")
    {
        setFlag(F32);
    } // Inst_DS__DS_CMPST_F32

    Inst_DS__DS_CMPST_F32::~Inst_DS__DS_CMPST_F32()
    {
    } // ~Inst_DS__DS_CMPST_F32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // src = DATA2;
    // cmp = DATA;
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0] = tmp.
    // Floating point compare and store that handles NaN/INF/denormal values.
    // Caution, the order of src and cmp are the *opposite* of the
    // ---  BUFFER_ATOMIC_FCMPSWAP opcode.
    void
    Inst_DS__DS_CMPST_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_F32 class methods ---

    Inst_DS__DS_MIN_F32::Inst_DS__DS_MIN_F32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_f32")
    {
        setFlag(F32);
    } // Inst_DS__DS_MIN_F32

    Inst_DS__DS_MIN_F32::~Inst_DS__DS_MIN_F32()
    {
    } // ~Inst_DS__DS_MIN_F32

    // --- description from .arch file ---
    // 32b.
    // tmp = MEM[ADDR];
    // src = DATA;
    // cmp = DATA2;
    // MEM[ADDR] = (cmp < tmp) ? src : tmp.
    // Floating point minimum that handles NaN/INF/denormal values.
    // Note that this opcode is slightly more general-purpose than
    // ---  BUFFER_ATOMIC_FMIN.
    void
    Inst_DS__DS_MIN_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_F32 class methods ---

    Inst_DS__DS_MAX_F32::Inst_DS__DS_MAX_F32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_f32")
    {
        setFlag(F32);
    } // Inst_DS__DS_MAX_F32

    Inst_DS__DS_MAX_F32::~Inst_DS__DS_MAX_F32()
    {
    } // ~Inst_DS__DS_MAX_F32

    // --- description from .arch file ---
    // 32b.
    // tmp = MEM[ADDR];
    // src = DATA;
    // cmp = DATA2;
    // MEM[ADDR] = (tmp > cmp) ? src : tmp.
    // Floating point maximum that handles NaN/INF/denormal values.
    // Note that this opcode is slightly more general-purpose than
    // ---  BUFFER_ATOMIC_FMAX.
    void
    Inst_DS__DS_MAX_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_NOP class methods ---

    Inst_DS__DS_NOP::Inst_DS__DS_NOP(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_nop")
    {
        setFlag(Nop);
    } // Inst_DS__DS_NOP

    Inst_DS__DS_NOP::~Inst_DS__DS_NOP()
    {
    } // ~Inst_DS__DS_NOP

    // --- description from .arch file ---
    // Do nothing.
    void
    Inst_DS__DS_NOP::execute(GPUDynInstPtr gpuDynInst)
    {
        gpuDynInst->wavefront()->decLGKMInstsIssued();
    } // execute
    // --- Inst_DS__DS_ADD_F32 class methods ---

    Inst_DS__DS_ADD_F32::Inst_DS__DS_ADD_F32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_add_f32")
    {
        setFlag(F32);
    } // Inst_DS__DS_ADD_F32

    Inst_DS__DS_ADD_F32::~Inst_DS__DS_ADD_F32()
    {
    } // ~Inst_DS__DS_ADD_F32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] += DATA;
    // RETURN_DATA = tmp.
    // Floating point add that handles NaN/INF/denormal values.
    void
    Inst_DS__DS_ADD_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRITE_B8 class methods ---

    Inst_DS__DS_WRITE_B8::Inst_DS__DS_WRITE_B8(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_write_b8")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_DS__DS_WRITE_B8

    Inst_DS__DS_WRITE_B8::~Inst_DS__DS_WRITE_B8()
    {
    } // ~Inst_DS__DS_WRITE_B8

    // --- description from .arch file ---
    // MEM[ADDR] = DATA[7:0].
    // Byte write.
    void
    Inst_DS__DS_WRITE_B8::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU8 data(gpuDynInst, extData.DATA0);

        addr.read();
        data.read();

        calcAddr(gpuDynInst, addr);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU8*>(gpuDynInst->d_data))[lane]
                    = data[lane];
            }
        }

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_WRITE_B8::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0;
        Addr offset1 = instData.OFFSET1;
        Addr offset = (offset1 << 8) | offset0;

        initMemWrite<VecElemU8>(gpuDynInst, offset);
    } // initiateAcc

    void
    Inst_DS__DS_WRITE_B8::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_DS__DS_WRITE_B16 class methods ---

    Inst_DS__DS_WRITE_B16::Inst_DS__DS_WRITE_B16(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_write_b16")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_DS__DS_WRITE_B16

    Inst_DS__DS_WRITE_B16::~Inst_DS__DS_WRITE_B16()
    {
    } // ~Inst_DS__DS_WRITE_B16

    // --- description from .arch file ---
    // MEM[ADDR] = DATA[15:0]
    // Short write.
    void
    Inst_DS__DS_WRITE_B16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU16 data(gpuDynInst, extData.DATA0);

        addr.read();
        data.read();

        calcAddr(gpuDynInst, addr);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU16*>(gpuDynInst->d_data))[lane]
                    = data[lane];
            }
        }

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_WRITE_B16::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0;
        Addr offset1 = instData.OFFSET1;
        Addr offset = (offset1 << 8) | offset0;

        initMemWrite<VecElemU16>(gpuDynInst, offset);
    } // initiateAcc

    void
    Inst_DS__DS_WRITE_B16::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_DS__DS_ADD_RTN_U32 class methods ---

    Inst_DS__DS_ADD_RTN_U32::Inst_DS__DS_ADD_RTN_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_add_rtn_u32")
    {
    } // Inst_DS__DS_ADD_RTN_U32

    Inst_DS__DS_ADD_RTN_U32::~Inst_DS__DS_ADD_RTN_U32()
    {
    } // ~Inst_DS__DS_ADD_RTN_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] += DATA;
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_ADD_RTN_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_SUB_RTN_U32 class methods ---

    Inst_DS__DS_SUB_RTN_U32::Inst_DS__DS_SUB_RTN_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_sub_rtn_u32")
    {
    } // Inst_DS__DS_SUB_RTN_U32

    Inst_DS__DS_SUB_RTN_U32::~Inst_DS__DS_SUB_RTN_U32()
    {
    } // ~Inst_DS__DS_SUB_RTN_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_SUB_RTN_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_RSUB_RTN_U32 class methods ---

    Inst_DS__DS_RSUB_RTN_U32::Inst_DS__DS_RSUB_RTN_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_rsub_rtn_u32")
    {
    } // Inst_DS__DS_RSUB_RTN_U32

    Inst_DS__DS_RSUB_RTN_U32::~Inst_DS__DS_RSUB_RTN_U32()
    {
    } // ~Inst_DS__DS_RSUB_RTN_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = DATA - MEM[ADDR];
    // RETURN_DATA = tmp.
    // Subtraction with reversed operands.
    void
    Inst_DS__DS_RSUB_RTN_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_INC_RTN_U32 class methods ---

    Inst_DS__DS_INC_RTN_U32::Inst_DS__DS_INC_RTN_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_inc_rtn_u32")
    {
    } // Inst_DS__DS_INC_RTN_U32

    Inst_DS__DS_INC_RTN_U32::~Inst_DS__DS_INC_RTN_U32()
    {
    } // ~Inst_DS__DS_INC_RTN_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp >= DATA) ? 0 : tmp + 1 (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_INC_RTN_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_DEC_RTN_U32 class methods ---

    Inst_DS__DS_DEC_RTN_U32::Inst_DS__DS_DEC_RTN_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_dec_rtn_u32")
    {
    } // Inst_DS__DS_DEC_RTN_U32

    Inst_DS__DS_DEC_RTN_U32::~Inst_DS__DS_DEC_RTN_U32()
    {
    } // ~Inst_DS__DS_DEC_RTN_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp == 0 || tmp > DATA) ? DATA : tmp - 1
    // (unsigned compare); RETURN_DATA = tmp.
    void
    Inst_DS__DS_DEC_RTN_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_RTN_I32 class methods ---

    Inst_DS__DS_MIN_RTN_I32::Inst_DS__DS_MIN_RTN_I32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_rtn_i32")
    {
    } // Inst_DS__DS_MIN_RTN_I32

    Inst_DS__DS_MIN_RTN_I32::~Inst_DS__DS_MIN_RTN_I32()
    {
    } // ~Inst_DS__DS_MIN_RTN_I32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA < tmp) ? DATA : tmp (signed compare);
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_MIN_RTN_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_RTN_I32 class methods ---

    Inst_DS__DS_MAX_RTN_I32::Inst_DS__DS_MAX_RTN_I32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_rtn_i32")
    {
    } // Inst_DS__DS_MAX_RTN_I32

    Inst_DS__DS_MAX_RTN_I32::~Inst_DS__DS_MAX_RTN_I32()
    {
    } // ~Inst_DS__DS_MAX_RTN_I32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA > tmp) ? DATA : tmp (signed compare);
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_MAX_RTN_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_RTN_U32 class methods ---

    Inst_DS__DS_MIN_RTN_U32::Inst_DS__DS_MIN_RTN_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_rtn_u32")
    {
    } // Inst_DS__DS_MIN_RTN_U32

    Inst_DS__DS_MIN_RTN_U32::~Inst_DS__DS_MIN_RTN_U32()
    {
    } // ~Inst_DS__DS_MIN_RTN_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA < tmp) ? DATA : tmp (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_MIN_RTN_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_RTN_U32 class methods ---

    Inst_DS__DS_MAX_RTN_U32::Inst_DS__DS_MAX_RTN_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_rtn_u32")
    {
    } // Inst_DS__DS_MAX_RTN_U32

    Inst_DS__DS_MAX_RTN_U32::~Inst_DS__DS_MAX_RTN_U32()
    {
    } // ~Inst_DS__DS_MAX_RTN_U32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA > tmp) ? DATA : tmp (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_MAX_RTN_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_AND_RTN_B32 class methods ---

    Inst_DS__DS_AND_RTN_B32::Inst_DS__DS_AND_RTN_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_and_rtn_b32")
    {
    } // Inst_DS__DS_AND_RTN_B32

    Inst_DS__DS_AND_RTN_B32::~Inst_DS__DS_AND_RTN_B32()
    {
    } // ~Inst_DS__DS_AND_RTN_B32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] &= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_AND_RTN_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_OR_RTN_B32 class methods ---

    Inst_DS__DS_OR_RTN_B32::Inst_DS__DS_OR_RTN_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_or_rtn_b32")
    {
    } // Inst_DS__DS_OR_RTN_B32

    Inst_DS__DS_OR_RTN_B32::~Inst_DS__DS_OR_RTN_B32()
    {
    } // ~Inst_DS__DS_OR_RTN_B32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] |= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_OR_RTN_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_XOR_RTN_B32 class methods ---

    Inst_DS__DS_XOR_RTN_B32::Inst_DS__DS_XOR_RTN_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_xor_rtn_b32")
    {
    } // Inst_DS__DS_XOR_RTN_B32

    Inst_DS__DS_XOR_RTN_B32::~Inst_DS__DS_XOR_RTN_B32()
    {
    } // ~Inst_DS__DS_XOR_RTN_B32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] ^= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_XOR_RTN_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MSKOR_RTN_B32 class methods ---

    Inst_DS__DS_MSKOR_RTN_B32::Inst_DS__DS_MSKOR_RTN_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_mskor_rtn_b32")
    {
    } // Inst_DS__DS_MSKOR_RTN_B32

    Inst_DS__DS_MSKOR_RTN_B32::~Inst_DS__DS_MSKOR_RTN_B32()
    {
    } // ~Inst_DS__DS_MSKOR_RTN_B32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (MEM_ADDR[ADDR] & ~DATA) | DATA2;
    // RETURN_DATA = tmp.
    // Masked dword OR, D0 contains the mask and D1 contains the new value.
    void
    Inst_DS__DS_MSKOR_RTN_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRXCHG_RTN_B32 class methods ---

    Inst_DS__DS_WRXCHG_RTN_B32::Inst_DS__DS_WRXCHG_RTN_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_wrxchg_rtn_b32")
    {
    } // Inst_DS__DS_WRXCHG_RTN_B32

    Inst_DS__DS_WRXCHG_RTN_B32::~Inst_DS__DS_WRXCHG_RTN_B32()
    {
    } // ~Inst_DS__DS_WRXCHG_RTN_B32

    // --- description from .arch file ---
    // tmp = MEM[ADDR];
    // MEM[ADDR] = DATA;
    // RETURN_DATA = tmp.
    // Write-exchange operation.
    void
    Inst_DS__DS_WRXCHG_RTN_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRXCHG2_RTN_B32 class methods ---

    Inst_DS__DS_WRXCHG2_RTN_B32::Inst_DS__DS_WRXCHG2_RTN_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_wrxchg2_rtn_b32")
    {
    } // Inst_DS__DS_WRXCHG2_RTN_B32

    Inst_DS__DS_WRXCHG2_RTN_B32::~Inst_DS__DS_WRXCHG2_RTN_B32()
    {
    } // ~Inst_DS__DS_WRXCHG2_RTN_B32

    // --- description from .arch file ---
    // Write-exchange 2 separate dwords.
    void
    Inst_DS__DS_WRXCHG2_RTN_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRXCHG2ST64_RTN_B32 class methods ---

    Inst_DS__DS_WRXCHG2ST64_RTN_B32::Inst_DS__DS_WRXCHG2ST64_RTN_B32(
          InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_wrxchg2st64_rtn_b32")
    {
    } // Inst_DS__DS_WRXCHG2ST64_RTN_B32

    Inst_DS__DS_WRXCHG2ST64_RTN_B32::~Inst_DS__DS_WRXCHG2ST64_RTN_B32()
    {
    } // ~Inst_DS__DS_WRXCHG2ST64_RTN_B32

    // --- description from .arch file ---
    // Write-exchange 2 separate dwords with a stride of 64 dwords.
    void
    Inst_DS__DS_WRXCHG2ST64_RTN_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_CMPST_RTN_B32 class methods ---

    Inst_DS__DS_CMPST_RTN_B32::Inst_DS__DS_CMPST_RTN_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_cmpst_rtn_b32")
    {
    } // Inst_DS__DS_CMPST_RTN_B32

    Inst_DS__DS_CMPST_RTN_B32::~Inst_DS__DS_CMPST_RTN_B32()
    {
    } // ~Inst_DS__DS_CMPST_RTN_B32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // src = DATA2;
    // cmp = DATA;
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0] = tmp.
    // Compare and store.
    // Caution, the order of src and cmp are the *opposite* of the
    // ---  BUFFER_ATOMIC_CMPSWAP opcode.
    void
    Inst_DS__DS_CMPST_RTN_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_CMPST_RTN_F32 class methods ---

    Inst_DS__DS_CMPST_RTN_F32::Inst_DS__DS_CMPST_RTN_F32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_cmpst_rtn_f32")
    {
        setFlag(F32);
    } // Inst_DS__DS_CMPST_RTN_F32

    Inst_DS__DS_CMPST_RTN_F32::~Inst_DS__DS_CMPST_RTN_F32()
    {
    } // ~Inst_DS__DS_CMPST_RTN_F32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // src = DATA2;
    // cmp = DATA;
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0] = tmp.
    // Floating point compare and store that handles NaN/INF/denormal values.
    // Caution, the order of src and cmp are the *opposite* of the
    // ---  BUFFER_ATOMIC_FCMPSWAP opcode.
    void
    Inst_DS__DS_CMPST_RTN_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_RTN_F32 class methods ---

    Inst_DS__DS_MIN_RTN_F32::Inst_DS__DS_MIN_RTN_F32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_rtn_f32")
    {
        setFlag(F32);
    } // Inst_DS__DS_MIN_RTN_F32

    Inst_DS__DS_MIN_RTN_F32::~Inst_DS__DS_MIN_RTN_F32()
    {
    } // ~Inst_DS__DS_MIN_RTN_F32

    // --- description from .arch file ---
    // 32b.
    // tmp = MEM[ADDR];
    // src = DATA;
    // cmp = DATA2;
    // MEM[ADDR] = (cmp < tmp) ? src : tmp.
    // Floating point minimum that handles NaN/INF/denormal values.
    // Note that this opcode is slightly more general-purpose than
    // ---  BUFFER_ATOMIC_FMIN.
    void
    Inst_DS__DS_MIN_RTN_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_RTN_F32 class methods ---

    Inst_DS__DS_MAX_RTN_F32::Inst_DS__DS_MAX_RTN_F32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_rtn_f32")
    {
        setFlag(F32);
    } // Inst_DS__DS_MAX_RTN_F32

    Inst_DS__DS_MAX_RTN_F32::~Inst_DS__DS_MAX_RTN_F32()
    {
    } // ~Inst_DS__DS_MAX_RTN_F32

    // --- description from .arch file ---
    // 32b.
    // tmp = MEM[ADDR];
    // src = DATA;
    // cmp = DATA2;
    // MEM[ADDR] = (tmp > cmp) ? src : tmp.
    // Floating point maximum that handles NaN/INF/denormal values.
    // Note that this opcode is slightly more general-purpose than
    // ---  BUFFER_ATOMIC_FMAX.
    void
    Inst_DS__DS_MAX_RTN_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRAP_RTN_B32 class methods ---

    Inst_DS__DS_WRAP_RTN_B32::Inst_DS__DS_WRAP_RTN_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_wrap_rtn_b32")
    {
    } // Inst_DS__DS_WRAP_RTN_B32

    Inst_DS__DS_WRAP_RTN_B32::~Inst_DS__DS_WRAP_RTN_B32()
    {
    } // ~Inst_DS__DS_WRAP_RTN_B32

    // --- description from .arch file ---
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp >= DATA) ? tmp - DATA : tmp + DATA2;
    // RETURN_DATA = tmp.
    void
    Inst_DS__DS_WRAP_RTN_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_ADD_RTN_F32 class methods ---

    Inst_DS__DS_ADD_RTN_F32::Inst_DS__DS_ADD_RTN_F32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_add_rtn_f32")
    {
        setFlag(F32);
    } // Inst_DS__DS_ADD_RTN_F32

    Inst_DS__DS_ADD_RTN_F32::~Inst_DS__DS_ADD_RTN_F32()
    {
    } // ~Inst_DS__DS_ADD_RTN_F32

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] += DATA;
    // RETURN_DATA = tmp.
    // Floating point add that handles NaN/INF/denormal values.
    void
    Inst_DS__DS_ADD_RTN_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_READ_B32 class methods ---

    Inst_DS__DS_READ_B32::Inst_DS__DS_READ_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_read_b32")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_DS__DS_READ_B32

    Inst_DS__DS_READ_B32::~Inst_DS__DS_READ_B32()
    {
    } // ~Inst_DS__DS_READ_B32

    // --- description from .arch file ---
    // RETURN_DATA = MEM[ADDR].
    // Dword read.
    void
    Inst_DS__DS_READ_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr);

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_READ_B32::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0;
        Addr offset1 = instData.OFFSET1;
        Addr offset = (offset1 << 8) | offset0;

        initMemRead<VecElemU32>(gpuDynInst, offset);
    } // initiateAcc

    void
    Inst_DS__DS_READ_B32::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst(gpuDynInst, extData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst[lane] = (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane];
            }
        }

        vdst.write();
    } // completeAcc
    // --- Inst_DS__DS_READ2_B32 class methods ---

    Inst_DS__DS_READ2_B32::Inst_DS__DS_READ2_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_read2_b32")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_DS__DS_READ2_B32

    Inst_DS__DS_READ2_B32::~Inst_DS__DS_READ2_B32()
    {
    } // ~Inst_DS__DS_READ2_B32

    // --- description from .arch file ---
    // RETURN_DATA[0] = MEM[ADDR_BASE + OFFSET0 * 4];
    // RETURN_DATA[1] = MEM[ADDR_BASE + OFFSET1 * 4].
    // Read 2 dwords.
    void
    Inst_DS__DS_READ2_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr);

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_READ2_B32::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0 * 4;
        Addr offset1 = instData.OFFSET1 * 4;

        initDualMemRead<VecElemU32>(gpuDynInst, offset0, offset1);
    } // initiateAcc

    void
    Inst_DS__DS_READ2_B32::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst0(gpuDynInst, extData.VDST);
        VecOperandU32 vdst1(gpuDynInst, extData.VDST + 1);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst0[lane] = (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 2];
                vdst1[lane] = (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 2 + 1];
            }
        }

        vdst0.write();
        vdst1.write();
    } // completeAcc
    // --- Inst_DS__DS_READ2ST64_B32 class methods ---

    Inst_DS__DS_READ2ST64_B32::Inst_DS__DS_READ2ST64_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_read2st64_b32")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_DS__DS_READ2ST64_B32

    Inst_DS__DS_READ2ST64_B32::~Inst_DS__DS_READ2ST64_B32()
    {
    } // ~Inst_DS__DS_READ2ST64_B32

    // --- description from .arch file ---
    // RETURN_DATA[0] = MEM[ADDR_BASE + OFFSET0 * 4 * 64];
    // RETURN_DATA[1] = MEM[ADDR_BASE + OFFSET1 * 4 * 64].
    // Read 2 dwords.
    void
    Inst_DS__DS_READ2ST64_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr);

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_READ2ST64_B32::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = (instData.OFFSET0 * 4 * 64);
        Addr offset1 = (instData.OFFSET1 * 4 * 64);

        initDualMemRead<VecElemU32>(gpuDynInst, offset0, offset1);
    }

    void
    Inst_DS__DS_READ2ST64_B32::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst0(gpuDynInst, extData.VDST);
        VecOperandU32 vdst1(gpuDynInst, extData.VDST + 2);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst0[lane] = (reinterpret_cast<VecElemU64*>(
                    gpuDynInst->d_data))[lane * 2];
                vdst1[lane] = (reinterpret_cast<VecElemU64*>(
                    gpuDynInst->d_data))[lane * 2 + 1];
            }
        }

        vdst0.write();
        vdst1.write();
    }
    // --- Inst_DS__DS_READ_I8 class methods ---

    Inst_DS__DS_READ_I8::Inst_DS__DS_READ_I8(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_read_i8")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_DS__DS_READ_I8

    Inst_DS__DS_READ_I8::~Inst_DS__DS_READ_I8()
    {
    } // ~Inst_DS__DS_READ_I8

    // --- description from .arch file ---
    // RETURN_DATA = signext(MEM[ADDR][7:0]).
    // Signed byte read.
    void
    Inst_DS__DS_READ_I8::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_READ_U8 class methods ---

    Inst_DS__DS_READ_U8::Inst_DS__DS_READ_U8(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_read_u8")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_DS__DS_READ_U8

    Inst_DS__DS_READ_U8::~Inst_DS__DS_READ_U8()
    {
    } // ~Inst_DS__DS_READ_U8

    // --- description from .arch file ---
    // RETURN_DATA = {24'h0,MEM[ADDR][7:0]}.
    // Unsigned byte read.
    void
    Inst_DS__DS_READ_U8::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr);

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_READ_U8::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0;
        Addr offset1 = instData.OFFSET1;
        Addr offset = (offset1 << 8) | offset0;

        initMemRead<VecElemU8>(gpuDynInst, offset);
    } // initiateAcc

    void
    Inst_DS__DS_READ_U8::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst(gpuDynInst, extData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst[lane] = (VecElemU32)(reinterpret_cast<VecElemU8*>(
                    gpuDynInst->d_data))[lane];
            }
        }

        vdst.write();
    } // completeAcc
    // --- Inst_DS__DS_READ_I16 class methods ---

    Inst_DS__DS_READ_I16::Inst_DS__DS_READ_I16(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_read_i16")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_DS__DS_READ_I16

    Inst_DS__DS_READ_I16::~Inst_DS__DS_READ_I16()
    {
    } // ~Inst_DS__DS_READ_I16

    // --- description from .arch file ---
    // RETURN_DATA = signext(MEM[ADDR][15:0]).
    // Signed short read.
    void
    Inst_DS__DS_READ_I16::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_READ_U16 class methods ---

    Inst_DS__DS_READ_U16::Inst_DS__DS_READ_U16(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_read_u16")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_DS__DS_READ_U16

    Inst_DS__DS_READ_U16::~Inst_DS__DS_READ_U16()
    {
    } // ~Inst_DS__DS_READ_U16

    // --- description from .arch file ---
    // RETURN_DATA = {16'h0,MEM[ADDR][15:0]}.
    // Unsigned short read.
    void
    Inst_DS__DS_READ_U16::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr);

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute
    void
    Inst_DS__DS_READ_U16::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0;
        Addr offset1 = instData.OFFSET1;
        Addr offset = (offset1 << 8) | offset0;

        initMemRead<VecElemU16>(gpuDynInst, offset);
    } // initiateAcc

    void
    Inst_DS__DS_READ_U16::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst(gpuDynInst, extData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst[lane] = (VecElemU32)(reinterpret_cast<VecElemU16*>(
                    gpuDynInst->d_data))[lane];
            }
        }

        vdst.write();
    } // completeAcc
    // --- Inst_DS__DS_SWIZZLE_B32 class methods ---

    Inst_DS__DS_SWIZZLE_B32::Inst_DS__DS_SWIZZLE_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_swizzle_b32")
    {
        /**
         * While this operation doesn't actually use DS storage we classify
         * it as a load here because it does a writeback to a VGPR, which
         * fits in better with the LDS pipeline logic.
         */
         setFlag(Load);
    } // Inst_DS__DS_SWIZZLE_B32

    Inst_DS__DS_SWIZZLE_B32::~Inst_DS__DS_SWIZZLE_B32()
    {
    } // ~Inst_DS__DS_SWIZZLE_B32

    // --- description from .arch file ---
    // RETURN_DATA = swizzle(vgpr_data, offset1:offset0).
    // Dword swizzle, no data is written to LDS memory; See ds_opcodes.docx for
    // ---  details.
    void
    Inst_DS__DS_SWIZZLE_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        wf->decLGKMInstsIssued();

        if (gpuDynInst->exec_mask.none()) {
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()
                                ->cyclesToTicks(Cycles(24)));

        ConstVecOperandU32 data(gpuDynInst, extData.DATA0);
        VecOperandU32 vdst(gpuDynInst, extData.VDST);
        /**
         * The "DS pattern" is comprised of both offset fields. That is, the
         * swizzle pattern between lanes. Bit 15 of the DS pattern dictates
         * which swizzle mode to use. There are two different swizzle
         * patterns: 1) QDMode and 2) Bit-masks mode. If bit 15 is set use
         * QDMode else use Bit-masks mode. The remaining bits dictate how to
         * swizzle the lanes.
         *
         * QDMode:      Chunks the lanes into 4s and swizzles among them.
         *              Bits 7:6 dictate where lane 3 (of the current chunk)
         *              gets its date, 5:4 lane 2, etc.
         *
         * Bit-mask:    This mode breaks bits 14:0 into 3 equal-sized chunks.
         *              14:10 is the xor_mask, 9:5 is the or_mask, and 4:0
         *              is the and_mask. Each lane is swizzled by performing
         *              the appropriate operation using these masks.
         */
        VecElemU16 ds_pattern = ((instData.OFFSET1 << 8) | instData.OFFSET0);

        data.read();

        if (bits(ds_pattern, 15)) {
            // QDMode
            for (int lane = 0; lane < NumVecElemPerVecReg; lane += 4) {
                /**
                 * This operation allows data sharing between groups
                 * of four consecutive threads. Note the increment by
                 * 4 in the for loop.
                 */
                if (gpuDynInst->exec_mask[lane]) {
                    int index0 = lane + bits(ds_pattern, 1, 0);
                    panic_if(index0 >= NumVecElemPerVecReg, "%s: index0 (%d) "
                             "is out of bounds.\n", gpuDynInst->disassemble(),
                             index0);
                    vdst[lane]
                        = gpuDynInst->exec_mask[index0] ? data[index0]: 0;
                }
                if (gpuDynInst->exec_mask[lane + 1]) {
                    int index1 = lane + bits(ds_pattern, 3, 2);
                    panic_if(index1 >= NumVecElemPerVecReg, "%s: index1 (%d) "
                             "is out of bounds.\n", gpuDynInst->disassemble(),
                             index1);
                    vdst[lane + 1]
                        = gpuDynInst->exec_mask[index1] ? data[index1]: 0;
                }
                if (gpuDynInst->exec_mask[lane + 2]) {
                    int index2 = lane + bits(ds_pattern, 5, 4);
                    panic_if(index2 >= NumVecElemPerVecReg, "%s: index2 (%d) "
                             "is out of bounds.\n", gpuDynInst->disassemble(),
                             index2);
                    vdst[lane + 2]
                        = gpuDynInst->exec_mask[index2] ? data[index2]: 0;
                }
                if (gpuDynInst->exec_mask[lane + 3]) {
                    int index3 = lane + bits(ds_pattern, 7, 6);
                    panic_if(index3 >= NumVecElemPerVecReg, "%s: index3 (%d) "
                             "is out of bounds.\n", gpuDynInst->disassemble(),
                             index3);
                    vdst[lane + 3]
                        = gpuDynInst->exec_mask[index3] ? data[index3]: 0;
                }
            }
        } else {
            // Bit Mode
            int and_mask = bits(ds_pattern, 4, 0);
            int or_mask = bits(ds_pattern, 9, 5);
            int xor_mask = bits(ds_pattern, 14, 10);
            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (gpuDynInst->exec_mask[lane]) {
                    int index = (((lane & and_mask) | or_mask) ^ xor_mask);
                    // Adjust for the next 32 lanes.
                    if (lane > 31) {
                        index += 32;
                    }
                    panic_if(index >= NumVecElemPerVecReg, "%s: index (%d) is "
                             "out of bounds.\n", gpuDynInst->disassemble(),
                             index);
                    vdst[lane]
                        = gpuDynInst->exec_mask[index] ? data[index] : 0;
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_DS__DS_PERMUTE_B32 class methods ---

    Inst_DS__DS_PERMUTE_B32::Inst_DS__DS_PERMUTE_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_permute_b32")
    {
        setFlag(MemoryRef);
        /**
         * While this operation doesn't actually use DS storage we classify
         * it as a load here because it does a writeback to a VGPR, which
         * fits in better with the LDS pipeline logic.
         */
         setFlag(Load);
    } // Inst_DS__DS_PERMUTE_B32

    Inst_DS__DS_PERMUTE_B32::~Inst_DS__DS_PERMUTE_B32()
    {
    } // ~Inst_DS__DS_PERMUTE_B32

    // --- description from .arch file ---
    // Forward permute.
    void
    Inst_DS__DS_PERMUTE_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        wf->decLGKMInstsIssued();

        if (gpuDynInst->exec_mask.none()) {
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()
                                ->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU32 data(gpuDynInst, extData.DATA0);
        VecOperandU32 vdst(gpuDynInst, extData.VDST);

        addr.read();
        data.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                /**
                 * One of the offset fields can be used for the index.
                 * It is assumed OFFSET0 would be used, as OFFSET1 is
                 * typically only used for DS ops that operate on two
                 * disparate pieces of data.
                 */
                assert(!instData.OFFSET1);
                /**
                 * The address provided is a byte address, but VGPRs are
                 * 4 bytes, so we must divide by 4 to get the actual VGPR
                 * index. Additionally, the index is calculated modulo the
                 * WF size, 64 in this case, so we simply extract bits 7-2.
                 */
                int index = bits(addr[lane] + instData.OFFSET0, 7, 2);
                panic_if(index >= NumVecElemPerVecReg, "%s: index (%d) is out "
                         "of bounds.\n", gpuDynInst->disassemble(), index);
                /**
                 * If the shuffled index corresponds to a lane that is
                 * inactive then this instruction writes a 0 to the active
                 * lane in VDST.
                 */
                if (wf->execMask(index)) {
                    vdst[index] = data[lane];
                } else {
                    vdst[index] = 0;
                }
            }
        }

        vdst.write();
    } // execute
    // --- Inst_DS__DS_BPERMUTE_B32 class methods ---

    Inst_DS__DS_BPERMUTE_B32::Inst_DS__DS_BPERMUTE_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_bpermute_b32")
    {
        setFlag(MemoryRef);
        /**
         * While this operation doesn't actually use DS storage we classify
         * it as a load here because it does a writeback to a VGPR, which
         * fits in better with the LDS pipeline logic.
         */
        setFlag(Load);
    } // Inst_DS__DS_BPERMUTE_B32

    Inst_DS__DS_BPERMUTE_B32::~Inst_DS__DS_BPERMUTE_B32()
    {
    } // ~Inst_DS__DS_BPERMUTE_B32

    // --- description from .arch file ---
    // Backward permute.
    void
    Inst_DS__DS_BPERMUTE_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();
        wf->decLGKMInstsIssued();

        if (gpuDynInst->exec_mask.none()) {
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()
                                ->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU32 data(gpuDynInst, extData.DATA0);
        VecOperandU32 vdst(gpuDynInst, extData.VDST);

        addr.read();
        data.read();

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                /**
                 * One of the offset fields can be used for the index.
                 * It is assumed OFFSET0 would be used, as OFFSET1 is
                 * typically only used for DS ops that operate on two
                 * disparate pieces of data.
                 */
                assert(!instData.OFFSET1);
                /**
                 * The address provided is a byte address, but VGPRs are
                 * 4 bytes, so we must divide by 4 to get the actual VGPR
                 * index. Additionally, the index is calculated modulo the
                 * WF size, 64 in this case, so we simply extract bits 7-2.
                 */
                int index = bits(addr[lane] + instData.OFFSET0, 7, 2);
                panic_if(index >= NumVecElemPerVecReg, "%s: index (%d) is out "
                         "of bounds.\n", gpuDynInst->disassemble(), index);
                /**
                 * If the shuffled index corresponds to a lane that is
                 * inactive then this instruction writes a 0 to the active
                 * lane in VDST.
                 */
                if (wf->execMask(index)) {
                    vdst[lane] = data[index];
                } else {
                    vdst[lane] = 0;
                }
            }
        }

        vdst.write();
    } // execute

    // --- Inst_DS__DS_ADD_U64 class methods ---

    Inst_DS__DS_ADD_U64::Inst_DS__DS_ADD_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_add_u64")
    {
    } // Inst_DS__DS_ADD_U64

    Inst_DS__DS_ADD_U64::~Inst_DS__DS_ADD_U64()
    {
    } // ~Inst_DS__DS_ADD_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] += DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_ADD_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_SUB_U64 class methods ---

    Inst_DS__DS_SUB_U64::Inst_DS__DS_SUB_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_sub_u64")
    {
    } // Inst_DS__DS_SUB_U64

    Inst_DS__DS_SUB_U64::~Inst_DS__DS_SUB_U64()
    {
    } // ~Inst_DS__DS_SUB_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_SUB_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_RSUB_U64 class methods ---

    Inst_DS__DS_RSUB_U64::Inst_DS__DS_RSUB_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_rsub_u64")
    {
    } // Inst_DS__DS_RSUB_U64

    Inst_DS__DS_RSUB_U64::~Inst_DS__DS_RSUB_U64()
    {
    } // ~Inst_DS__DS_RSUB_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = DATA - MEM[ADDR];
    // RETURN_DATA = tmp.
    // Subtraction with reversed operands.
    void
    Inst_DS__DS_RSUB_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_INC_U64 class methods ---

    Inst_DS__DS_INC_U64::Inst_DS__DS_INC_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_inc_u64")
    {
    } // Inst_DS__DS_INC_U64

    Inst_DS__DS_INC_U64::~Inst_DS__DS_INC_U64()
    {
    } // ~Inst_DS__DS_INC_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp >= DATA[0:1]) ? 0 : tmp + 1 (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_INC_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_DEC_U64 class methods ---

    Inst_DS__DS_DEC_U64::Inst_DS__DS_DEC_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_dec_u64")
    {
    } // Inst_DS__DS_DEC_U64

    Inst_DS__DS_DEC_U64::~Inst_DS__DS_DEC_U64()
    {
    } // ~Inst_DS__DS_DEC_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp == 0 || tmp > DATA[0:1]) ? DATA[0:1] : tmp - 1
    // (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_DEC_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_I64 class methods ---

    Inst_DS__DS_MIN_I64::Inst_DS__DS_MIN_I64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_i64")
    {
    } // Inst_DS__DS_MIN_I64

    Inst_DS__DS_MIN_I64::~Inst_DS__DS_MIN_I64()
    {
    } // ~Inst_DS__DS_MIN_I64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] < tmp) ? DATA[0:1] : tmp (signed compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_MIN_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_I64 class methods ---

    Inst_DS__DS_MAX_I64::Inst_DS__DS_MAX_I64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_i64")
    {
    } // Inst_DS__DS_MAX_I64

    Inst_DS__DS_MAX_I64::~Inst_DS__DS_MAX_I64()
    {
    } // ~Inst_DS__DS_MAX_I64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] > tmp) ? DATA[0:1] : tmp (signed compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_MAX_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_U64 class methods ---

    Inst_DS__DS_MIN_U64::Inst_DS__DS_MIN_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_u64")
    {
    } // Inst_DS__DS_MIN_U64

    Inst_DS__DS_MIN_U64::~Inst_DS__DS_MIN_U64()
    {
    } // ~Inst_DS__DS_MIN_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] < tmp) ? DATA[0:1] : tmp (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_MIN_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_U64 class methods ---

    Inst_DS__DS_MAX_U64::Inst_DS__DS_MAX_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_u64")
    {
    } // Inst_DS__DS_MAX_U64

    Inst_DS__DS_MAX_U64::~Inst_DS__DS_MAX_U64()
    {
    } // ~Inst_DS__DS_MAX_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] > tmp) ? DATA[0:1] : tmp (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_MAX_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_AND_B64 class methods ---

    Inst_DS__DS_AND_B64::Inst_DS__DS_AND_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_and_b64")
    {
    } // Inst_DS__DS_AND_B64

    Inst_DS__DS_AND_B64::~Inst_DS__DS_AND_B64()
    {
    } // ~Inst_DS__DS_AND_B64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] &= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_AND_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_OR_B64 class methods ---

    Inst_DS__DS_OR_B64::Inst_DS__DS_OR_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_or_b64")
    {
    } // Inst_DS__DS_OR_B64

    Inst_DS__DS_OR_B64::~Inst_DS__DS_OR_B64()
    {
    } // ~Inst_DS__DS_OR_B64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] |= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_OR_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_XOR_B64 class methods ---

    Inst_DS__DS_XOR_B64::Inst_DS__DS_XOR_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_xor_b64")
    {
    } // Inst_DS__DS_XOR_B64

    Inst_DS__DS_XOR_B64::~Inst_DS__DS_XOR_B64()
    {
    } // ~Inst_DS__DS_XOR_B64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] ^= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_XOR_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MSKOR_B64 class methods ---

    Inst_DS__DS_MSKOR_B64::Inst_DS__DS_MSKOR_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_mskor_b64")
    {
    } // Inst_DS__DS_MSKOR_B64

    Inst_DS__DS_MSKOR_B64::~Inst_DS__DS_MSKOR_B64()
    {
    } // ~Inst_DS__DS_MSKOR_B64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (MEM_ADDR[ADDR] & ~DATA) | DATA2;
    // RETURN_DATA = tmp.
    // Masked dword OR, D0 contains the mask and D1 contains the new value.
    void
    Inst_DS__DS_MSKOR_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRITE_B64 class methods ---

    Inst_DS__DS_WRITE_B64::Inst_DS__DS_WRITE_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_write_b64")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_DS__DS_WRITE_B64

    Inst_DS__DS_WRITE_B64::~Inst_DS__DS_WRITE_B64()
    {
    } // ~Inst_DS__DS_WRITE_B64

    // --- description from .arch file ---
    // 64b:
    // MEM[ADDR] = DATA.
    // Write qword.
    void
    Inst_DS__DS_WRITE_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU64 data(gpuDynInst, extData.DATA0);

        addr.read();
        data.read();

        calcAddr(gpuDynInst, addr);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU64*>(gpuDynInst->d_data))[lane]
                    = data[lane];
            }
        }

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_WRITE_B64::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0;
        Addr offset1 = instData.OFFSET1;
        Addr offset = (offset1 << 8) | offset0;

        initMemWrite<VecElemU64>(gpuDynInst, offset);
    } // initiateAcc

    void
    Inst_DS__DS_WRITE_B64::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_DS__DS_WRITE2_B64 class methods ---

    Inst_DS__DS_WRITE2_B64::Inst_DS__DS_WRITE2_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_write2_b64")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_DS__DS_WRITE2_B64

    Inst_DS__DS_WRITE2_B64::~Inst_DS__DS_WRITE2_B64()
    {
    } // ~Inst_DS__DS_WRITE2_B64

    // --- description from .arch file ---
    // 64b:
    // MEM[ADDR_BASE + OFFSET0 * 8] = DATA;
    // MEM[ADDR_BASE + OFFSET1 * 8] = DATA2.
    // Write 2 qwords.
    void
    Inst_DS__DS_WRITE2_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU64 data0(gpuDynInst, extData.DATA0);
        ConstVecOperandU64 data1(gpuDynInst, extData.DATA1);

        addr.read();
        data0.read();
        data1.read();

        calcAddr(gpuDynInst, addr);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU64*>(
                    gpuDynInst->d_data))[lane * 2] = data0[lane];
                (reinterpret_cast<VecElemU64*>(
                    gpuDynInst->d_data))[lane * 2 + 1] = data1[lane];
            }
        }

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_WRITE2_B64::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0 * 8;
        Addr offset1 = instData.OFFSET1 * 8;

        initDualMemWrite<VecElemU64>(gpuDynInst, offset0, offset1);
    }

    void
    Inst_DS__DS_WRITE2_B64::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    }
    // --- Inst_DS__DS_WRITE2ST64_B64 class methods ---

    Inst_DS__DS_WRITE2ST64_B64::Inst_DS__DS_WRITE2ST64_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_write2st64_b64")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_DS__DS_WRITE2ST64_B64

    Inst_DS__DS_WRITE2ST64_B64::~Inst_DS__DS_WRITE2ST64_B64()
    {
    } // ~Inst_DS__DS_WRITE2ST64_B64

    // --- description from .arch file ---
    // 64b:
    // MEM[ADDR_BASE + OFFSET0 * 8 * 64] = DATA;
    // MEM[ADDR_BASE + OFFSET1 * 8 * 64] = DATA2;
    // Write 2 qwords.
    void
    Inst_DS__DS_WRITE2ST64_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_CMPST_B64 class methods ---

    Inst_DS__DS_CMPST_B64::Inst_DS__DS_CMPST_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_cmpst_b64")
    {
    } // Inst_DS__DS_CMPST_B64

    Inst_DS__DS_CMPST_B64::~Inst_DS__DS_CMPST_B64()
    {
    } // ~Inst_DS__DS_CMPST_B64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // src = DATA2;
    // cmp = DATA;
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0] = tmp.
    // Compare and store.
    // Caution, the order of src and cmp are the *opposite* of the
    // ---  BUFFER_ATOMIC_CMPSWAP_X2 opcode.
    void
    Inst_DS__DS_CMPST_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_CMPST_F64 class methods ---

    Inst_DS__DS_CMPST_F64::Inst_DS__DS_CMPST_F64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_cmpst_f64")
    {
        setFlag(F64);
    } // Inst_DS__DS_CMPST_F64

    Inst_DS__DS_CMPST_F64::~Inst_DS__DS_CMPST_F64()
    {
    } // ~Inst_DS__DS_CMPST_F64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // src = DATA2;
    // cmp = DATA;
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0] = tmp.
    // Floating point compare and store that handles NaN/INF/denormal values.
    // Caution, the order of src and cmp are the *opposite* of the
    // ---  BUFFER_ATOMIC_FCMPSWAP_X2 opcode.
    void
    Inst_DS__DS_CMPST_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_F64 class methods ---

    Inst_DS__DS_MIN_F64::Inst_DS__DS_MIN_F64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_f64")
    {
        setFlag(F64);
    } // Inst_DS__DS_MIN_F64

    Inst_DS__DS_MIN_F64::~Inst_DS__DS_MIN_F64()
    {
    } // ~Inst_DS__DS_MIN_F64

    // --- description from .arch file ---
    // 64b.
    // tmp = MEM[ADDR];
    // src = DATA;
    // cmp = DATA2;
    // MEM[ADDR] = (cmp < tmp) ? src : tmp.
    // Floating point minimum that handles NaN/INF/denormal values.
    // Note that this opcode is slightly more general-purpose than
    // ---  BUFFER_ATOMIC_FMIN_X2.
    void
    Inst_DS__DS_MIN_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_F64 class methods ---

    Inst_DS__DS_MAX_F64::Inst_DS__DS_MAX_F64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_f64")
    {
        setFlag(F64);
    } // Inst_DS__DS_MAX_F64

    Inst_DS__DS_MAX_F64::~Inst_DS__DS_MAX_F64()
    {
    } // ~Inst_DS__DS_MAX_F64

    // --- description from .arch file ---
    // 64b.
    // tmp = MEM[ADDR];
    // src = DATA;
    // cmp = DATA2;
    // MEM[ADDR] = (tmp > cmp) ? src : tmp.
    // Floating point maximum that handles NaN/INF/denormal values.
    // Note that this opcode is slightly more general-purpose than
    // ---  BUFFER_ATOMIC_FMAX_X2.
    void
    Inst_DS__DS_MAX_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_ADD_RTN_U64 class methods ---

    Inst_DS__DS_ADD_RTN_U64::Inst_DS__DS_ADD_RTN_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_add_rtn_u64")
    {
    } // Inst_DS__DS_ADD_RTN_U64

    Inst_DS__DS_ADD_RTN_U64::~Inst_DS__DS_ADD_RTN_U64()
    {
    } // ~Inst_DS__DS_ADD_RTN_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] += DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_ADD_RTN_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_SUB_RTN_U64 class methods ---

    Inst_DS__DS_SUB_RTN_U64::Inst_DS__DS_SUB_RTN_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_sub_rtn_u64")
    {
    } // Inst_DS__DS_SUB_RTN_U64

    Inst_DS__DS_SUB_RTN_U64::~Inst_DS__DS_SUB_RTN_U64()
    {
    } // ~Inst_DS__DS_SUB_RTN_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_SUB_RTN_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_RSUB_RTN_U64 class methods ---

    Inst_DS__DS_RSUB_RTN_U64::Inst_DS__DS_RSUB_RTN_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_rsub_rtn_u64")
    {
    } // Inst_DS__DS_RSUB_RTN_U64

    Inst_DS__DS_RSUB_RTN_U64::~Inst_DS__DS_RSUB_RTN_U64()
    {
    } // ~Inst_DS__DS_RSUB_RTN_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = DATA - MEM[ADDR];
    // RETURN_DATA = tmp.
    // Subtraction with reversed operands.
    void
    Inst_DS__DS_RSUB_RTN_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_INC_RTN_U64 class methods ---

    Inst_DS__DS_INC_RTN_U64::Inst_DS__DS_INC_RTN_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_inc_rtn_u64")
    {
    } // Inst_DS__DS_INC_RTN_U64

    Inst_DS__DS_INC_RTN_U64::~Inst_DS__DS_INC_RTN_U64()
    {
    } // ~Inst_DS__DS_INC_RTN_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp >= DATA[0:1]) ? 0 : tmp + 1 (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_INC_RTN_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_DEC_RTN_U64 class methods ---

    Inst_DS__DS_DEC_RTN_U64::Inst_DS__DS_DEC_RTN_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_dec_rtn_u64")
    {
    } // Inst_DS__DS_DEC_RTN_U64

    Inst_DS__DS_DEC_RTN_U64::~Inst_DS__DS_DEC_RTN_U64()
    {
    } // ~Inst_DS__DS_DEC_RTN_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp == 0 || tmp > DATA[0:1]) ? DATA[0:1] : tmp - 1
    // (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_DEC_RTN_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_RTN_I64 class methods ---

    Inst_DS__DS_MIN_RTN_I64::Inst_DS__DS_MIN_RTN_I64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_rtn_i64")
    {
    } // Inst_DS__DS_MIN_RTN_I64

    Inst_DS__DS_MIN_RTN_I64::~Inst_DS__DS_MIN_RTN_I64()
    {
    } // ~Inst_DS__DS_MIN_RTN_I64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] < tmp) ? DATA[0:1] : tmp (signed compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_MIN_RTN_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_RTN_I64 class methods ---

    Inst_DS__DS_MAX_RTN_I64::Inst_DS__DS_MAX_RTN_I64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_rtn_i64")
    {
    } // Inst_DS__DS_MAX_RTN_I64

    Inst_DS__DS_MAX_RTN_I64::~Inst_DS__DS_MAX_RTN_I64()
    {
    } // ~Inst_DS__DS_MAX_RTN_I64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] > tmp) ? DATA[0:1] : tmp (signed compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_MAX_RTN_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_RTN_U64 class methods ---

    Inst_DS__DS_MIN_RTN_U64::Inst_DS__DS_MIN_RTN_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_rtn_u64")
    {
    } // Inst_DS__DS_MIN_RTN_U64

    Inst_DS__DS_MIN_RTN_U64::~Inst_DS__DS_MIN_RTN_U64()
    {
    } // ~Inst_DS__DS_MIN_RTN_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] < tmp) ? DATA[0:1] : tmp (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_MIN_RTN_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_RTN_U64 class methods ---

    Inst_DS__DS_MAX_RTN_U64::Inst_DS__DS_MAX_RTN_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_rtn_u64")
    {
    } // Inst_DS__DS_MAX_RTN_U64

    Inst_DS__DS_MAX_RTN_U64::~Inst_DS__DS_MAX_RTN_U64()
    {
    } // ~Inst_DS__DS_MAX_RTN_U64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] > tmp) ? DATA[0:1] : tmp (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_MAX_RTN_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_AND_RTN_B64 class methods ---

    Inst_DS__DS_AND_RTN_B64::Inst_DS__DS_AND_RTN_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_and_rtn_b64")
    {
    } // Inst_DS__DS_AND_RTN_B64

    Inst_DS__DS_AND_RTN_B64::~Inst_DS__DS_AND_RTN_B64()
    {
    } // ~Inst_DS__DS_AND_RTN_B64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] &= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_AND_RTN_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_OR_RTN_B64 class methods ---

    Inst_DS__DS_OR_RTN_B64::Inst_DS__DS_OR_RTN_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_or_rtn_b64")
    {
    } // Inst_DS__DS_OR_RTN_B64

    Inst_DS__DS_OR_RTN_B64::~Inst_DS__DS_OR_RTN_B64()
    {
    } // ~Inst_DS__DS_OR_RTN_B64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] |= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_OR_RTN_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_XOR_RTN_B64 class methods ---

    Inst_DS__DS_XOR_RTN_B64::Inst_DS__DS_XOR_RTN_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_xor_rtn_b64")
    {
    } // Inst_DS__DS_XOR_RTN_B64

    Inst_DS__DS_XOR_RTN_B64::~Inst_DS__DS_XOR_RTN_B64()
    {
    } // ~Inst_DS__DS_XOR_RTN_B64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] ^= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_DS__DS_XOR_RTN_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MSKOR_RTN_B64 class methods ---

    Inst_DS__DS_MSKOR_RTN_B64::Inst_DS__DS_MSKOR_RTN_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_mskor_rtn_b64")
    {
    } // Inst_DS__DS_MSKOR_RTN_B64

    Inst_DS__DS_MSKOR_RTN_B64::~Inst_DS__DS_MSKOR_RTN_B64()
    {
    } // ~Inst_DS__DS_MSKOR_RTN_B64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (MEM_ADDR[ADDR] & ~DATA) | DATA2;
    // RETURN_DATA = tmp.
    // Masked dword OR, D0 contains the mask and D1 contains the new value.
    void
    Inst_DS__DS_MSKOR_RTN_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRXCHG_RTN_B64 class methods ---

    Inst_DS__DS_WRXCHG_RTN_B64::Inst_DS__DS_WRXCHG_RTN_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_wrxchg_rtn_b64")
    {
    } // Inst_DS__DS_WRXCHG_RTN_B64

    Inst_DS__DS_WRXCHG_RTN_B64::~Inst_DS__DS_WRXCHG_RTN_B64()
    {
    } // ~Inst_DS__DS_WRXCHG_RTN_B64

    // --- description from .arch file ---
    // tmp = MEM[ADDR];
    // MEM[ADDR] = DATA;
    // RETURN_DATA = tmp.
    // Write-exchange operation.
    void
    Inst_DS__DS_WRXCHG_RTN_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRXCHG2_RTN_B64 class methods ---

    Inst_DS__DS_WRXCHG2_RTN_B64::Inst_DS__DS_WRXCHG2_RTN_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_wrxchg2_rtn_b64")
    {
    } // Inst_DS__DS_WRXCHG2_RTN_B64

    Inst_DS__DS_WRXCHG2_RTN_B64::~Inst_DS__DS_WRXCHG2_RTN_B64()
    {
    } // ~Inst_DS__DS_WRXCHG2_RTN_B64

    // --- description from .arch file ---
    // Write-exchange 2 separate qwords.
    void
    Inst_DS__DS_WRXCHG2_RTN_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRXCHG2ST64_RTN_B64 class methods ---

    Inst_DS__DS_WRXCHG2ST64_RTN_B64::Inst_DS__DS_WRXCHG2ST64_RTN_B64(
          InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_wrxchg2st64_rtn_b64")
    {
    } // Inst_DS__DS_WRXCHG2ST64_RTN_B64

    Inst_DS__DS_WRXCHG2ST64_RTN_B64::~Inst_DS__DS_WRXCHG2ST64_RTN_B64()
    {
    } // ~Inst_DS__DS_WRXCHG2ST64_RTN_B64

    // --- description from .arch file ---
    // Write-exchange 2 qwords with a stride of 64 qwords.
    void
    Inst_DS__DS_WRXCHG2ST64_RTN_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_CMPST_RTN_B64 class methods ---

    Inst_DS__DS_CMPST_RTN_B64::Inst_DS__DS_CMPST_RTN_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_cmpst_rtn_b64")
    {
    } // Inst_DS__DS_CMPST_RTN_B64

    Inst_DS__DS_CMPST_RTN_B64::~Inst_DS__DS_CMPST_RTN_B64()
    {
    } // ~Inst_DS__DS_CMPST_RTN_B64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // src = DATA2;
    // cmp = DATA;
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0] = tmp.
    // Compare and store.
    // Caution, the order of src and cmp are the *opposite* of the
    // ---  BUFFER_ATOMIC_CMPSWAP_X2 opcode.
    void
    Inst_DS__DS_CMPST_RTN_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_CMPST_RTN_F64 class methods ---

    Inst_DS__DS_CMPST_RTN_F64::Inst_DS__DS_CMPST_RTN_F64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_cmpst_rtn_f64")
    {
        setFlag(F64);
    } // Inst_DS__DS_CMPST_RTN_F64

    Inst_DS__DS_CMPST_RTN_F64::~Inst_DS__DS_CMPST_RTN_F64()
    {
    } // ~Inst_DS__DS_CMPST_RTN_F64

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // src = DATA2;
    // cmp = DATA;
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0] = tmp.
    // Floating point compare and store that handles NaN/INF/denormal values.
    // Caution, the order of src and cmp are the *opposite* of the
    // ---  BUFFER_ATOMIC_FCMPSWAP_X2 opcode.
    void
    Inst_DS__DS_CMPST_RTN_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_RTN_F64 class methods ---

    Inst_DS__DS_MIN_RTN_F64::Inst_DS__DS_MIN_RTN_F64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_rtn_f64")
    {
        setFlag(F64);
    } // Inst_DS__DS_MIN_RTN_F64

    Inst_DS__DS_MIN_RTN_F64::~Inst_DS__DS_MIN_RTN_F64()
    {
    } // ~Inst_DS__DS_MIN_RTN_F64

    // --- description from .arch file ---
    // 64b.
    // tmp = MEM[ADDR];
    // src = DATA;
    // cmp = DATA2;
    // MEM[ADDR] = (cmp < tmp) ? src : tmp.
    // Floating point minimum that handles NaN/INF/denormal values.
    // Note that this opcode is slightly more general-purpose than
    // ---  BUFFER_ATOMIC_FMIN_X2.
    void
    Inst_DS__DS_MIN_RTN_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_RTN_F64 class methods ---

    Inst_DS__DS_MAX_RTN_F64::Inst_DS__DS_MAX_RTN_F64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_rtn_f64")
    {
        setFlag(F64);
    } // Inst_DS__DS_MAX_RTN_F64

    Inst_DS__DS_MAX_RTN_F64::~Inst_DS__DS_MAX_RTN_F64()
    {
    } // ~Inst_DS__DS_MAX_RTN_F64

    // --- description from .arch file ---
    // 64b.
    // tmp = MEM[ADDR];
    // src = DATA;
    // cmp = DATA2;
    // MEM[ADDR] = (tmp > cmp) ? src : tmp.
    // Floating point maximum that handles NaN/INF/denormal values.
    // Note that this opcode is slightly more general-purpose than
    // ---  BUFFER_ATOMIC_FMAX_X2.
    void
    Inst_DS__DS_MAX_RTN_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_READ_B64 class methods ---

    Inst_DS__DS_READ_B64::Inst_DS__DS_READ_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_read_b64")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_DS__DS_READ_B64

    Inst_DS__DS_READ_B64::~Inst_DS__DS_READ_B64()
    {
    } // ~Inst_DS__DS_READ_B64

    // --- description from .arch file ---
    // RETURN_DATA = MEM[ADDR].
    // Read 1 qword.
    void
    Inst_DS__DS_READ_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr);

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_READ_B64::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0;
        Addr offset1 = instData.OFFSET1;
        Addr offset = (offset1 << 8) | offset0;

        initMemRead<VecElemU64>(gpuDynInst, offset);
    } // initiateAcc

    void
    Inst_DS__DS_READ_B64::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU64 vdst(gpuDynInst, extData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst[lane] = (reinterpret_cast<VecElemU64*>(
                    gpuDynInst->d_data))[lane];
            }
        }

        vdst.write();
    } // completeAcc
    // --- Inst_DS__DS_READ2_B64 class methods ---

    Inst_DS__DS_READ2_B64::Inst_DS__DS_READ2_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_read2_b64")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_DS__DS_READ2_B64

    Inst_DS__DS_READ2_B64::~Inst_DS__DS_READ2_B64()
    {
    } // ~Inst_DS__DS_READ2_B64

    // --- description from .arch file ---
    // RETURN_DATA[0] = MEM[ADDR_BASE + OFFSET0 * 8];
    // RETURN_DATA[1] = MEM[ADDR_BASE + OFFSET1 * 8].
    // Read 2 qwords.
    void
    Inst_DS__DS_READ2_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr);

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_READ2_B64::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = instData.OFFSET0 * 8;
        Addr offset1 = instData.OFFSET1 * 8;

        initDualMemRead<VecElemU64>(gpuDynInst, offset0, offset1);
    } // initiateAcc

    void
    Inst_DS__DS_READ2_B64::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU64 vdst0(gpuDynInst, extData.VDST);
        VecOperandU64 vdst1(gpuDynInst, extData.VDST + 2);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst0[lane] = (reinterpret_cast<VecElemU64*>(
                    gpuDynInst->d_data))[lane * 2];
                vdst1[lane] = (reinterpret_cast<VecElemU64*>(
                    gpuDynInst->d_data))[lane * 2 + 1];
            }
        }

        vdst0.write();
        vdst1.write();
    } // completeAcc
    // --- Inst_DS__DS_READ2ST64_B64 class methods ---

    Inst_DS__DS_READ2ST64_B64::Inst_DS__DS_READ2ST64_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_read2st64_b64")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_DS__DS_READ2ST64_B64

    Inst_DS__DS_READ2ST64_B64::~Inst_DS__DS_READ2ST64_B64()
    {
    } // ~Inst_DS__DS_READ2ST64_B64

    // --- description from .arch file ---
    // RETURN_DATA[0] = MEM[ADDR_BASE + OFFSET0 * 8 * 64];
    // RETURN_DATA[1] = MEM[ADDR_BASE + OFFSET1 * 8 * 64].
    // Read 2 qwords.
    void
    Inst_DS__DS_READ2ST64_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(
                gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24)));
        ConstVecOperandU32 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr);

        gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_DS__DS_READ2ST64_B64::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        Addr offset0 = (instData.OFFSET0 * 8 * 64);
        Addr offset1 = (instData.OFFSET1 * 8 * 64);

        initDualMemRead<VecElemU64>(gpuDynInst, offset0, offset1);
    }

    void
    Inst_DS__DS_READ2ST64_B64::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU64 vdst0(gpuDynInst, extData.VDST);
        VecOperandU64 vdst1(gpuDynInst, extData.VDST + 2);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst0[lane] = (reinterpret_cast<VecElemU64*>(
                    gpuDynInst->d_data))[lane * 2];
                vdst1[lane] = (reinterpret_cast<VecElemU64*>(
                    gpuDynInst->d_data))[lane * 2 + 1];
            }
        }

        vdst0.write();
        vdst1.write();
    }
    // --- Inst_DS__DS_CONDXCHG32_RTN_B64 class methods ---

    Inst_DS__DS_CONDXCHG32_RTN_B64::Inst_DS__DS_CONDXCHG32_RTN_B64(
          InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_condxchg32_rtn_b64")
    {
    } // Inst_DS__DS_CONDXCHG32_RTN_B64

    Inst_DS__DS_CONDXCHG32_RTN_B64::~Inst_DS__DS_CONDXCHG32_RTN_B64()
    {
    } // ~Inst_DS__DS_CONDXCHG32_RTN_B64

    // --- description from .arch file ---
    // Conditional write exchange.
    void
    Inst_DS__DS_CONDXCHG32_RTN_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_ADD_SRC2_U32 class methods ---

    Inst_DS__DS_ADD_SRC2_U32::Inst_DS__DS_ADD_SRC2_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_add_src2_u32")
    {
    } // Inst_DS__DS_ADD_SRC2_U32

    Inst_DS__DS_ADD_SRC2_U32::~Inst_DS__DS_ADD_SRC2_U32()
    {
    } // ~Inst_DS__DS_ADD_SRC2_U32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[A] + MEM[B].
    void
    Inst_DS__DS_ADD_SRC2_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_SUB_SRC2_U32 class methods ---

    Inst_DS__DS_SUB_SRC2_U32::Inst_DS__DS_SUB_SRC2_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_sub_src2_u32")
    {
    } // Inst_DS__DS_SUB_SRC2_U32

    Inst_DS__DS_SUB_SRC2_U32::~Inst_DS__DS_SUB_SRC2_U32()
    {
    } // ~Inst_DS__DS_SUB_SRC2_U32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[A] - MEM[B].
    void
    Inst_DS__DS_SUB_SRC2_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_RSUB_SRC2_U32 class methods ---

    Inst_DS__DS_RSUB_SRC2_U32::Inst_DS__DS_RSUB_SRC2_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_rsub_src2_u32")
    {
    } // Inst_DS__DS_RSUB_SRC2_U32

    Inst_DS__DS_RSUB_SRC2_U32::~Inst_DS__DS_RSUB_SRC2_U32()
    {
    } // ~Inst_DS__DS_RSUB_SRC2_U32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[B] - MEM[A].
    void
    Inst_DS__DS_RSUB_SRC2_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_INC_SRC2_U32 class methods ---

    Inst_DS__DS_INC_SRC2_U32::Inst_DS__DS_INC_SRC2_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_inc_src2_u32")
    {
    } // Inst_DS__DS_INC_SRC2_U32

    Inst_DS__DS_INC_SRC2_U32::~Inst_DS__DS_INC_SRC2_U32()
    {
    } // ~Inst_DS__DS_INC_SRC2_U32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = (MEM[A] >= MEM[B] ? 0 : MEM[A] + 1).
    void
    Inst_DS__DS_INC_SRC2_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_DEC_SRC2_U32 class methods ---

    Inst_DS__DS_DEC_SRC2_U32::Inst_DS__DS_DEC_SRC2_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_dec_src2_u32")
    {
    } // Inst_DS__DS_DEC_SRC2_U32

    Inst_DS__DS_DEC_SRC2_U32::~Inst_DS__DS_DEC_SRC2_U32()
    {
    } // ~Inst_DS__DS_DEC_SRC2_U32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = (MEM[A] == 0 || MEM[A] > MEM[B] ? MEM[B] : MEM[A] - 1).
    // Uint decrement.
    void
    Inst_DS__DS_DEC_SRC2_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_SRC2_I32 class methods ---

    Inst_DS__DS_MIN_SRC2_I32::Inst_DS__DS_MIN_SRC2_I32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_src2_i32")
    {
    } // Inst_DS__DS_MIN_SRC2_I32

    Inst_DS__DS_MIN_SRC2_I32::~Inst_DS__DS_MIN_SRC2_I32()
    {
    } // ~Inst_DS__DS_MIN_SRC2_I32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = min(MEM[A], MEM[B]).
    void
    Inst_DS__DS_MIN_SRC2_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_SRC2_I32 class methods ---

    Inst_DS__DS_MAX_SRC2_I32::Inst_DS__DS_MAX_SRC2_I32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_src2_i32")
    {
    } // Inst_DS__DS_MAX_SRC2_I32

    Inst_DS__DS_MAX_SRC2_I32::~Inst_DS__DS_MAX_SRC2_I32()
    {
    } // ~Inst_DS__DS_MAX_SRC2_I32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = max(MEM[A], MEM[B]).
    void
    Inst_DS__DS_MAX_SRC2_I32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_SRC2_U32 class methods ---

    Inst_DS__DS_MIN_SRC2_U32::Inst_DS__DS_MIN_SRC2_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_src2_u32")
    {
    } // Inst_DS__DS_MIN_SRC2_U32

    Inst_DS__DS_MIN_SRC2_U32::~Inst_DS__DS_MIN_SRC2_U32()
    {
    } // ~Inst_DS__DS_MIN_SRC2_U32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = min(MEM[A], MEM[B]).
    void
    Inst_DS__DS_MIN_SRC2_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_SRC2_U32 class methods ---

    Inst_DS__DS_MAX_SRC2_U32::Inst_DS__DS_MAX_SRC2_U32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_src2_u32")
    {
    } // Inst_DS__DS_MAX_SRC2_U32

    Inst_DS__DS_MAX_SRC2_U32::~Inst_DS__DS_MAX_SRC2_U32()
    {
    } // ~Inst_DS__DS_MAX_SRC2_U32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = max(MEM[A], MEM[B]).
    void
    Inst_DS__DS_MAX_SRC2_U32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_AND_SRC2_B32 class methods ---

    Inst_DS__DS_AND_SRC2_B32::Inst_DS__DS_AND_SRC2_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_and_src2_b32")
    {
    } // Inst_DS__DS_AND_SRC2_B32

    Inst_DS__DS_AND_SRC2_B32::~Inst_DS__DS_AND_SRC2_B32()
    {
    } // ~Inst_DS__DS_AND_SRC2_B32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[A] & MEM[B].
    void
    Inst_DS__DS_AND_SRC2_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_OR_SRC2_B32 class methods ---

    Inst_DS__DS_OR_SRC2_B32::Inst_DS__DS_OR_SRC2_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_or_src2_b32")
    {
    } // Inst_DS__DS_OR_SRC2_B32

    Inst_DS__DS_OR_SRC2_B32::~Inst_DS__DS_OR_SRC2_B32()
    {
    } // ~Inst_DS__DS_OR_SRC2_B32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[A] | MEM[B].
    void
    Inst_DS__DS_OR_SRC2_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_XOR_SRC2_B32 class methods ---

    Inst_DS__DS_XOR_SRC2_B32::Inst_DS__DS_XOR_SRC2_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_xor_src2_b32")
    {
    } // Inst_DS__DS_XOR_SRC2_B32

    Inst_DS__DS_XOR_SRC2_B32::~Inst_DS__DS_XOR_SRC2_B32()
    {
    } // ~Inst_DS__DS_XOR_SRC2_B32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[A] ^ MEM[B].
    void
    Inst_DS__DS_XOR_SRC2_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRITE_SRC2_B32 class methods ---

    Inst_DS__DS_WRITE_SRC2_B32::Inst_DS__DS_WRITE_SRC2_B32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_write_src2_b32")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_DS__DS_WRITE_SRC2_B32

    Inst_DS__DS_WRITE_SRC2_B32::~Inst_DS__DS_WRITE_SRC2_B32()
    {
    } // ~Inst_DS__DS_WRITE_SRC2_B32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[B].
    // Write dword.
    void
    Inst_DS__DS_WRITE_SRC2_B32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_SRC2_F32 class methods ---

    Inst_DS__DS_MIN_SRC2_F32::Inst_DS__DS_MIN_SRC2_F32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_src2_f32")
    {
        setFlag(F32);
    } // Inst_DS__DS_MIN_SRC2_F32

    Inst_DS__DS_MIN_SRC2_F32::~Inst_DS__DS_MIN_SRC2_F32()
    {
    } // ~Inst_DS__DS_MIN_SRC2_F32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = (MEM[B] < MEM[A]) ? MEM[B] : MEM[A].
    // Float, handles NaN/INF/denorm.
    void
    Inst_DS__DS_MIN_SRC2_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_SRC2_F32 class methods ---

    Inst_DS__DS_MAX_SRC2_F32::Inst_DS__DS_MAX_SRC2_F32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_src2_f32")
    {
        setFlag(F32);
    } // Inst_DS__DS_MAX_SRC2_F32

    Inst_DS__DS_MAX_SRC2_F32::~Inst_DS__DS_MAX_SRC2_F32()
    {
    } // ~Inst_DS__DS_MAX_SRC2_F32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = (MEM[B] > MEM[A]) ? MEM[B] : MEM[A].
    // Float, handles NaN/INF/denorm.
    void
    Inst_DS__DS_MAX_SRC2_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_ADD_SRC2_F32 class methods ---

    Inst_DS__DS_ADD_SRC2_F32::Inst_DS__DS_ADD_SRC2_F32(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_add_src2_f32")
    {
        setFlag(F32);
    } // Inst_DS__DS_ADD_SRC2_F32

    Inst_DS__DS_ADD_SRC2_F32::~Inst_DS__DS_ADD_SRC2_F32()
    {
    } // ~Inst_DS__DS_ADD_SRC2_F32

    // --- description from .arch file ---
    // 32b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[B] + MEM[A].
    // Float, handles NaN/INF/denorm.
    void
    Inst_DS__DS_ADD_SRC2_F32::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_GWS_SEMA_RELEASE_ALL class methods ---

    Inst_DS__DS_GWS_SEMA_RELEASE_ALL::Inst_DS__DS_GWS_SEMA_RELEASE_ALL(
          InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_gws_sema_release_all")
    {
    } // Inst_DS__DS_GWS_SEMA_RELEASE_ALL

    Inst_DS__DS_GWS_SEMA_RELEASE_ALL::~Inst_DS__DS_GWS_SEMA_RELEASE_ALL()
    {
    } // ~Inst_DS__DS_GWS_SEMA_RELEASE_ALL

    // --- description from .arch file ---
    // GDS Only: The GWS resource (rid) indicated will process this opcode by
    // updating the counter and labeling the specified resource as a semaphore.
    // //Determine the GWS resource to work on
    // rid[5:0] = SH_SX_EXPCMD.gds_base[5:0] + offset0[5:0];
    // //Incr the state counter of the resource
    // state.counter[rid] = state.wave_in_queue;
    // state.type = SEMAPHORE;
    // return rd_done; //release calling wave
    // This action will release ALL queued waves; it Will have no effect if no
    // ---  waves are present.
    void
    Inst_DS__DS_GWS_SEMA_RELEASE_ALL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_GWS_INIT class methods ---

    Inst_DS__DS_GWS_INIT::Inst_DS__DS_GWS_INIT(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_gws_init")
    {
    } // Inst_DS__DS_GWS_INIT

    Inst_DS__DS_GWS_INIT::~Inst_DS__DS_GWS_INIT()
    {
    } // ~Inst_DS__DS_GWS_INIT

    // --- description from .arch file ---
    // GDS Only: Initialize a barrier or semaphore resource.
    // //Determine the GWS resource to work on
    // rid[5:0] = SH_SX_EXPCMD.gds_base[5:0] + offset0[5:0];
    // //Get the value to use in init
    // index = find_first_valid(vector mask)
    // value = DATA[thread: index]
    // //Set the state of the resource
    // state.counter[rid] = lsb(value); //limit #waves
    // state.flag[rid] = 0;
    // return rd_done; //release calling wave
    void
    Inst_DS__DS_GWS_INIT::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_GWS_SEMA_V class methods ---

    Inst_DS__DS_GWS_SEMA_V::Inst_DS__DS_GWS_SEMA_V(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_gws_sema_v")
    {
    } // Inst_DS__DS_GWS_SEMA_V

    Inst_DS__DS_GWS_SEMA_V::~Inst_DS__DS_GWS_SEMA_V()
    {
    } // ~Inst_DS__DS_GWS_SEMA_V

    // --- description from .arch file ---
    // GDS Only: The GWS resource indicated will process this opcode by
    // updating the counter and labeling the resource as a semaphore.
    // //Determine the GWS resource to work on
    // rid[5:0] = SH_SX_EXPCMD.gds_base[5:0] + offset0[5:0];
    // //Incr the state counter of the resource
    // state.counter[rid]++;
    // state.type = SEMAPHORE;
    // return rd_done; //release calling wave
    // This action will release one waved if any are queued in this resource.
    void
    Inst_DS__DS_GWS_SEMA_V::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_GWS_SEMA_BR class methods ---

    Inst_DS__DS_GWS_SEMA_BR::Inst_DS__DS_GWS_SEMA_BR(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_gws_sema_br")
    {
    } // Inst_DS__DS_GWS_SEMA_BR

    Inst_DS__DS_GWS_SEMA_BR::~Inst_DS__DS_GWS_SEMA_BR()
    {
    } // ~Inst_DS__DS_GWS_SEMA_BR

    // --- description from .arch file ---
    // GDS Only: The GWS resource indicated will process this opcode by
    // updating the counter by the bulk release delivered count and labeling
    // the resource as a semaphore.
    // //Determine the GWS resource to work on
    // rid[5:0] = SH_SX_EXPCMD.gds_base[5:0] + offset0[5:0];
    // index =  find first valid (vector mask)
    // count = DATA[thread: index];
    // //Add count to the resource state counter
    // state.counter[rid] += count;
    // state.type = SEMAPHORE;
    // return rd_done; //release calling wave
    // This action will release count number of waves, immediately if queued,
    // or as they arrive from the noted resource.
    void
    Inst_DS__DS_GWS_SEMA_BR::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_GWS_SEMA_P class methods ---

    Inst_DS__DS_GWS_SEMA_P::Inst_DS__DS_GWS_SEMA_P(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_gws_sema_p")
    {
    } // Inst_DS__DS_GWS_SEMA_P

    Inst_DS__DS_GWS_SEMA_P::~Inst_DS__DS_GWS_SEMA_P()
    {
    } // ~Inst_DS__DS_GWS_SEMA_P

    // --- description from .arch file ---
    // GDS Only: The GWS resource indicated will process this opcode by
    // queueing it until counter enables a release and then decrementing the
    // counter of the resource as a semaphore.
    // //Determine the GWS resource to work on
    // rid[5:0] = SH_SX_EXPCMD.gds_base[5:0] + offset0[5:0];
    // state.type = SEMAPHORE;
    // ENQUEUE until(state[rid].counter > 0)
    // state[rid].counter--;
    // return rd_done
    void
    Inst_DS__DS_GWS_SEMA_P::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_GWS_BARRIER class methods ---

    Inst_DS__DS_GWS_BARRIER::Inst_DS__DS_GWS_BARRIER(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_gws_barrier")
    {
    } // Inst_DS__DS_GWS_BARRIER

    Inst_DS__DS_GWS_BARRIER::~Inst_DS__DS_GWS_BARRIER()
    {
    } // ~Inst_DS__DS_GWS_BARRIER

    // --- description from .arch file ---
    // GDS Only: The GWS resource indicated will process this opcode by
    // queueing it until barrier is satisfied. The number of waves needed is
    // passed in as DATA of first valid thread.
    // //Determine the GWS resource to work on
    // rid[5:0] = SH_SX_EXPCMD.gds_base[5:0] + OFFSET0[5:0];
    // index =  find first valid (vector mask);
    // value = DATA[thread: index];
    // // Input Decision Machine
    // state.type[rid] = BARRIER;
    // if(state[rid].counter <= 0) {
    //     thread[rid].flag = state[rid].flag;
    //     ENQUEUE;
    //     state[rid].flag = !state.flag;
    //     state[rid].counter = value;
    //     return rd_done;
    // } else {
    //     state[rid].counter--;
    //     thread.flag = state[rid].flag;
    //     ENQUEUE;
    // }
    // Since the waves deliver the count for the next barrier, this function
    // can have a different size barrier for each occurrence.
    // // Release Machine
    // if(state.type == BARRIER) {
    //     if(state.flag != thread.flag) {
    //         return rd_done;
    //     }
    // }
    void
    Inst_DS__DS_GWS_BARRIER::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_CONSUME class methods ---

    Inst_DS__DS_CONSUME::Inst_DS__DS_CONSUME(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_consume")
    {
    } // Inst_DS__DS_CONSUME

    Inst_DS__DS_CONSUME::~Inst_DS__DS_CONSUME()
    {
    } // ~Inst_DS__DS_CONSUME

    // --- description from .arch file ---
    // LDS & GDS. Subtract (count_bits(exec_mask)) from the value stored in DS
    // memory at (M0.base + instr_offset). Return the pre-operation value to
    // VGPRs.
    void
    Inst_DS__DS_CONSUME::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_APPEND class methods ---

    Inst_DS__DS_APPEND::Inst_DS__DS_APPEND(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_append")
    {
    } // Inst_DS__DS_APPEND

    Inst_DS__DS_APPEND::~Inst_DS__DS_APPEND()
    {
    } // ~Inst_DS__DS_APPEND

    // --- description from .arch file ---
    // LDS & GDS. Add (count_bits(exec_mask)) to the value stored in DS memory
    // at (M0.base + instr_offset). Return the pre-operation value to VGPRs.
    void
    Inst_DS__DS_APPEND::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_ORDERED_COUNT class methods ---

    Inst_DS__DS_ORDERED_COUNT::Inst_DS__DS_ORDERED_COUNT(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_ordered_count")
    {
    } // Inst_DS__DS_ORDERED_COUNT

    Inst_DS__DS_ORDERED_COUNT::~Inst_DS__DS_ORDERED_COUNT()
    {
    } // ~Inst_DS__DS_ORDERED_COUNT

    // --- description from .arch file ---
    // GDS-only. Add (count_bits(exec_mask)) to one of 4 dedicated
    // ordered-count counters (aka 'packers'). Additional bits of instr.offset
    // field are overloaded to hold packer-id, 'last'.
    void
    Inst_DS__DS_ORDERED_COUNT::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_ADD_SRC2_U64 class methods ---

    Inst_DS__DS_ADD_SRC2_U64::Inst_DS__DS_ADD_SRC2_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_add_src2_u64")
    {
    } // Inst_DS__DS_ADD_SRC2_U64

    Inst_DS__DS_ADD_SRC2_U64::~Inst_DS__DS_ADD_SRC2_U64()
    {
    } // ~Inst_DS__DS_ADD_SRC2_U64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[A] + MEM[B].
    void
    Inst_DS__DS_ADD_SRC2_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_SUB_SRC2_U64 class methods ---

    Inst_DS__DS_SUB_SRC2_U64::Inst_DS__DS_SUB_SRC2_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_sub_src2_u64")
    {
    } // Inst_DS__DS_SUB_SRC2_U64

    Inst_DS__DS_SUB_SRC2_U64::~Inst_DS__DS_SUB_SRC2_U64()
    {
    } // ~Inst_DS__DS_SUB_SRC2_U64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[A] - MEM[B].
    void
    Inst_DS__DS_SUB_SRC2_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_RSUB_SRC2_U64 class methods ---

    Inst_DS__DS_RSUB_SRC2_U64::Inst_DS__DS_RSUB_SRC2_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_rsub_src2_u64")
    {
    } // Inst_DS__DS_RSUB_SRC2_U64

    Inst_DS__DS_RSUB_SRC2_U64::~Inst_DS__DS_RSUB_SRC2_U64()
    {
    } // ~Inst_DS__DS_RSUB_SRC2_U64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[B] - MEM[A].
    void
    Inst_DS__DS_RSUB_SRC2_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_INC_SRC2_U64 class methods ---

    Inst_DS__DS_INC_SRC2_U64::Inst_DS__DS_INC_SRC2_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_inc_src2_u64")
    {
    } // Inst_DS__DS_INC_SRC2_U64

    Inst_DS__DS_INC_SRC2_U64::~Inst_DS__DS_INC_SRC2_U64()
    {
    } // ~Inst_DS__DS_INC_SRC2_U64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = (MEM[A] >= MEM[B] ? 0 : MEM[A] + 1).
    void
    Inst_DS__DS_INC_SRC2_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_DEC_SRC2_U64 class methods ---

    Inst_DS__DS_DEC_SRC2_U64::Inst_DS__DS_DEC_SRC2_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_dec_src2_u64")
    {
    } // Inst_DS__DS_DEC_SRC2_U64

    Inst_DS__DS_DEC_SRC2_U64::~Inst_DS__DS_DEC_SRC2_U64()
    {
    } // ~Inst_DS__DS_DEC_SRC2_U64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = (MEM[A] == 0 || MEM[A] > MEM[B] ? MEM[B] : MEM[A] - 1).
    // Uint decrement.
    void
    Inst_DS__DS_DEC_SRC2_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_SRC2_I64 class methods ---

    Inst_DS__DS_MIN_SRC2_I64::Inst_DS__DS_MIN_SRC2_I64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_src2_i64")
    {
    } // Inst_DS__DS_MIN_SRC2_I64

    Inst_DS__DS_MIN_SRC2_I64::~Inst_DS__DS_MIN_SRC2_I64()
    {
    } // ~Inst_DS__DS_MIN_SRC2_I64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = min(MEM[A], MEM[B]).
    void
    Inst_DS__DS_MIN_SRC2_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_SRC2_I64 class methods ---

    Inst_DS__DS_MAX_SRC2_I64::Inst_DS__DS_MAX_SRC2_I64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_src2_i64")
    {
    } // Inst_DS__DS_MAX_SRC2_I64

    Inst_DS__DS_MAX_SRC2_I64::~Inst_DS__DS_MAX_SRC2_I64()
    {
    } // ~Inst_DS__DS_MAX_SRC2_I64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = max(MEM[A], MEM[B]).
    void
    Inst_DS__DS_MAX_SRC2_I64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_SRC2_U64 class methods ---

    Inst_DS__DS_MIN_SRC2_U64::Inst_DS__DS_MIN_SRC2_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_src2_u64")
    {
    } // Inst_DS__DS_MIN_SRC2_U64

    Inst_DS__DS_MIN_SRC2_U64::~Inst_DS__DS_MIN_SRC2_U64()
    {
    } // ~Inst_DS__DS_MIN_SRC2_U64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = min(MEM[A], MEM[B]).
    void
    Inst_DS__DS_MIN_SRC2_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_SRC2_U64 class methods ---

    Inst_DS__DS_MAX_SRC2_U64::Inst_DS__DS_MAX_SRC2_U64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_src2_u64")
    {
    } // Inst_DS__DS_MAX_SRC2_U64

    Inst_DS__DS_MAX_SRC2_U64::~Inst_DS__DS_MAX_SRC2_U64()
    {
    } // ~Inst_DS__DS_MAX_SRC2_U64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = max(MEM[A], MEM[B]).
    void
    Inst_DS__DS_MAX_SRC2_U64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_AND_SRC2_B64 class methods ---

    Inst_DS__DS_AND_SRC2_B64::Inst_DS__DS_AND_SRC2_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_and_src2_b64")
    {
    } // Inst_DS__DS_AND_SRC2_B64

    Inst_DS__DS_AND_SRC2_B64::~Inst_DS__DS_AND_SRC2_B64()
    {
    } // ~Inst_DS__DS_AND_SRC2_B64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[A] & MEM[B].
    void
    Inst_DS__DS_AND_SRC2_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_OR_SRC2_B64 class methods ---

    Inst_DS__DS_OR_SRC2_B64::Inst_DS__DS_OR_SRC2_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_or_src2_b64")
    {
    } // Inst_DS__DS_OR_SRC2_B64

    Inst_DS__DS_OR_SRC2_B64::~Inst_DS__DS_OR_SRC2_B64()
    {
    } // ~Inst_DS__DS_OR_SRC2_B64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[A] | MEM[B].
    void
    Inst_DS__DS_OR_SRC2_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_XOR_SRC2_B64 class methods ---

    Inst_DS__DS_XOR_SRC2_B64::Inst_DS__DS_XOR_SRC2_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_xor_src2_b64")
    {
    } // Inst_DS__DS_XOR_SRC2_B64

    Inst_DS__DS_XOR_SRC2_B64::~Inst_DS__DS_XOR_SRC2_B64()
    {
    } // ~Inst_DS__DS_XOR_SRC2_B64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[A] ^ MEM[B].
    void
    Inst_DS__DS_XOR_SRC2_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRITE_SRC2_B64 class methods ---

    Inst_DS__DS_WRITE_SRC2_B64::Inst_DS__DS_WRITE_SRC2_B64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_write_src2_b64")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_DS__DS_WRITE_SRC2_B64

    Inst_DS__DS_WRITE_SRC2_B64::~Inst_DS__DS_WRITE_SRC2_B64()
    {
    } // ~Inst_DS__DS_WRITE_SRC2_B64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = MEM[B].
    // Write qword.
    void
    Inst_DS__DS_WRITE_SRC2_B64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MIN_SRC2_F64 class methods ---

    Inst_DS__DS_MIN_SRC2_F64::Inst_DS__DS_MIN_SRC2_F64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_min_src2_f64")
    {
        setFlag(F64);
    } // Inst_DS__DS_MIN_SRC2_F64

    Inst_DS__DS_MIN_SRC2_F64::~Inst_DS__DS_MIN_SRC2_F64()
    {
    } // ~Inst_DS__DS_MIN_SRC2_F64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = (MEM[B] < MEM[A]) ? MEM[B] : MEM[A].
    // Float, handles NaN/INF/denorm.
    void
    Inst_DS__DS_MIN_SRC2_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_MAX_SRC2_F64 class methods ---

    Inst_DS__DS_MAX_SRC2_F64::Inst_DS__DS_MAX_SRC2_F64(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_max_src2_f64")
    {
        setFlag(F64);
    } // Inst_DS__DS_MAX_SRC2_F64

    Inst_DS__DS_MAX_SRC2_F64::~Inst_DS__DS_MAX_SRC2_F64()
    {
    } // ~Inst_DS__DS_MAX_SRC2_F64

    // --- description from .arch file ---
    // 64b:
    // A = ADDR_BASE;
    // B = A + 4*(offset1[7] ? {A[31],A[31:17]} :
    // ---  {offset1[6],offset1[6:0],offset0});
    // MEM[A] = (MEM[B] > MEM[A]) ? MEM[B] : MEM[A].
    // Float, handles NaN/INF/denorm.
    void
    Inst_DS__DS_MAX_SRC2_F64::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRITE_B96 class methods ---

    Inst_DS__DS_WRITE_B96::Inst_DS__DS_WRITE_B96(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_write_b96")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_DS__DS_WRITE_B96

    Inst_DS__DS_WRITE_B96::~Inst_DS__DS_WRITE_B96()
    {
    } // ~Inst_DS__DS_WRITE_B96

    // --- description from .arch file ---
    // {MEM[ADDR + 8], MEM[ADDR + 4], MEM[ADDR]} = DATA[95:0].
    // Tri-dword write.
    void
    Inst_DS__DS_WRITE_B96::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_WRITE_B128 class methods ---

    Inst_DS__DS_WRITE_B128::Inst_DS__DS_WRITE_B128(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_write_b128")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_DS__DS_WRITE_B128

    Inst_DS__DS_WRITE_B128::~Inst_DS__DS_WRITE_B128()
    {
    } // ~Inst_DS__DS_WRITE_B128

    // --- description from .arch file ---
    // {MEM[ADDR + 12], MEM[ADDR + 8], MEM[ADDR + 4], MEM[ADDR]} = DATA[127:0].
    // Qword write.
    void
    Inst_DS__DS_WRITE_B128::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_READ_B96 class methods ---

    Inst_DS__DS_READ_B96::Inst_DS__DS_READ_B96(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_read_b96")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_DS__DS_READ_B96

    Inst_DS__DS_READ_B96::~Inst_DS__DS_READ_B96()
    {
    } // ~Inst_DS__DS_READ_B96

    // --- description from .arch file ---
    // Tri-dword read.
    void
    Inst_DS__DS_READ_B96::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_DS__DS_READ_B128 class methods ---

    Inst_DS__DS_READ_B128::Inst_DS__DS_READ_B128(InFmt_DS *iFmt)
        : Inst_DS(iFmt, "ds_read_b128")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_DS__DS_READ_B128

    Inst_DS__DS_READ_B128::~Inst_DS__DS_READ_B128()
    {
    } // ~Inst_DS__DS_READ_B128

    // --- description from .arch file ---
    // Qword read.
    void
    Inst_DS__DS_READ_B128::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_LOAD_FORMAT_X class methods ---

    Inst_MUBUF__BUFFER_LOAD_FORMAT_X
        ::Inst_MUBUF__BUFFER_LOAD_FORMAT_X(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_format_x")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_LOAD_FORMAT_X

    Inst_MUBUF__BUFFER_LOAD_FORMAT_X::~Inst_MUBUF__BUFFER_LOAD_FORMAT_X()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_FORMAT_X

    // --- description from .arch file ---
    // Untyped buffer load 1 dword with format conversion.
    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_X::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_X::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_X::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_LOAD_FORMAT_XY class methods ---

    Inst_MUBUF__BUFFER_LOAD_FORMAT_XY
        ::Inst_MUBUF__BUFFER_LOAD_FORMAT_XY(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_format_xy")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_LOAD_FORMAT_XY

    Inst_MUBUF__BUFFER_LOAD_FORMAT_XY::~Inst_MUBUF__BUFFER_LOAD_FORMAT_XY()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_FORMAT_XY

    // --- description from .arch file ---
    // Untyped buffer load 2 dwords with format conversion.
    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_XY::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_XY::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_XY::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZ class methods ---

    Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZ
        ::Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZ(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_format_xyz")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZ

    Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZ::~Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZ()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZ

    // --- description from .arch file ---
    // Untyped buffer load 3 dwords with format conversion.
    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZ::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZ::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZ::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZW class methods ---

    Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZW
        ::Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZW(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_format_xyzw")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZW

    Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZW::~Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZW()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZW

    // --- description from .arch file ---
    // Untyped buffer load 4 dwords with format conversion.
    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZW::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZW::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_XYZW::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_STORE_FORMAT_X class methods ---

    Inst_MUBUF__BUFFER_STORE_FORMAT_X
        ::Inst_MUBUF__BUFFER_STORE_FORMAT_X(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_format_x")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_STORE_FORMAT_X

    Inst_MUBUF__BUFFER_STORE_FORMAT_X::~Inst_MUBUF__BUFFER_STORE_FORMAT_X()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_FORMAT_X

    // --- description from .arch file ---
    // Untyped buffer store 1 dword with format conversion.
    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_X::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_X::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_X::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_STORE_FORMAT_XY class methods ---

    Inst_MUBUF__BUFFER_STORE_FORMAT_XY
        ::Inst_MUBUF__BUFFER_STORE_FORMAT_XY(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_format_xy")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_STORE_FORMAT_XY

    Inst_MUBUF__BUFFER_STORE_FORMAT_XY::~Inst_MUBUF__BUFFER_STORE_FORMAT_XY()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_FORMAT_XY

    // --- description from .arch file ---
    // Untyped buffer store 2 dwords with format conversion.
    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_XY::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_XY::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_XY::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_STORE_FORMAT_XYZ class methods ---

    Inst_MUBUF__BUFFER_STORE_FORMAT_XYZ
        ::Inst_MUBUF__BUFFER_STORE_FORMAT_XYZ(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_format_xyz")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_STORE_FORMAT_XYZ

    Inst_MUBUF__BUFFER_STORE_FORMAT_XYZ::~Inst_MUBUF__BUFFER_STORE_FORMAT_XYZ()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_FORMAT_XYZ

    // --- description from .arch file ---
    // Untyped buffer store 3 dwords with format conversion.
    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_XYZ::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_XYZ::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_XYZ::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_STORE_FORMAT_XYZW class methods ---

    Inst_MUBUF__BUFFER_STORE_FORMAT_XYZW
        ::Inst_MUBUF__BUFFER_STORE_FORMAT_XYZW(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_format_xyzw")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_STORE_FORMAT_XYZW

    Inst_MUBUF__BUFFER_STORE_FORMAT_XYZW
        ::~Inst_MUBUF__BUFFER_STORE_FORMAT_XYZW()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_FORMAT_XYZW

    // --- description from .arch file ---
    // Untyped buffer store 4 dwords with format conversion.
    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_XYZW::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_XYZW::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_XYZW::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_X class methods ---

    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_X
        ::Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_X(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_format_d16_x")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_X

    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_X
        ::~Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_X()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_X

    // --- description from .arch file ---
    // Untyped buffer load 1 dword with format conversion.
    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_X::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_X::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_X::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XY class methods ---

    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XY
        ::Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XY(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_format_d16_xy")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XY

    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XY
        ::~Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XY()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XY

    // --- description from .arch file ---
    // Untyped buffer load 2 dwords with format conversion.
    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XY::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XY::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XY::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZ class methods ---

    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZ
        ::Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZ(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_format_d16_xyz")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZ

    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZ
        ::~Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZ()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZ

    // --- description from .arch file ---
    // Untyped buffer load 3 dwords with format conversion.
    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZ::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZ::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZ::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZW class methods ---

    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZW
        ::Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZW(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_format_d16_xyzw")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZW

    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZW
        ::~Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZW()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZW

    // --- description from .arch file ---
    // Untyped buffer load 4 dwords with format conversion.
    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZW::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZW::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_FORMAT_D16_XYZW::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_STORE_FORMAT_D16_X class methods ---

    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_X
        ::Inst_MUBUF__BUFFER_STORE_FORMAT_D16_X(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_format_d16_x")
    {
        setFlag(Store);
    } // Inst_MUBUF__BUFFER_STORE_FORMAT_D16_X

    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_X
        ::~Inst_MUBUF__BUFFER_STORE_FORMAT_D16_X()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_FORMAT_D16_X

    // --- description from .arch file ---
    // Untyped buffer store 1 dword with format conversion.
    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_X::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_X::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_X::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XY class methods ---

    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XY
        ::Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XY(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_format_d16_xy")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XY

    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XY
        ::~Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XY()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XY

    // --- description from .arch file ---
    // Untyped buffer store 2 dwords with format conversion.
    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XY::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XY::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XY::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZ class methods ---

    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZ
        ::Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZ(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_format_d16_xyz")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZ

    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZ
        ::~Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZ()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZ

    // --- description from .arch file ---
    // Untyped buffer store 3 dwords with format conversion.
    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZ::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZ::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZ::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZW class methods ---

    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZW
        ::Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZW(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_format_d16_xyzw")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZW

    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZW
        ::~Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZW()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZW

    // --- description from .arch file ---
    // Untyped buffer store 4 dwords with format conversion.
    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZW::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZW::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_FORMAT_D16_XYZW::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_LOAD_UBYTE class methods ---

    Inst_MUBUF__BUFFER_LOAD_UBYTE
        ::Inst_MUBUF__BUFFER_LOAD_UBYTE(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_ubyte")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        if (instData.LDS) {
            setFlag(GroupSegment);
        } else {
            setFlag(GlobalSegment);
        }
    } // Inst_MUBUF__BUFFER_LOAD_UBYTE

    Inst_MUBUF__BUFFER_LOAD_UBYTE::~Inst_MUBUF__BUFFER_LOAD_UBYTE()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_UBYTE

    // --- description from .arch file ---
    // Untyped buffer load unsigned byte (zero extend to VGPR destination).
    void
    Inst_MUBUF__BUFFER_LOAD_UBYTE::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU32 addr0(gpuDynInst, extData.VADDR);
        ConstVecOperandU32 addr1(gpuDynInst, extData.VADDR + 1);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, extData.SRSRC * 4);
        ConstScalarOperandU32 offset(gpuDynInst, extData.SOFFSET);

        rsrcDesc.read();
        offset.read();

        int inst_offset = instData.OFFSET;

        if (!instData.IDXEN && !instData.OFFEN) {
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (!instData.IDXEN && instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (instData.IDXEN && !instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        } else {
            addr0.read();
            addr1.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        }

        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_UBYTE::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<VecElemU8>(gpuDynInst);
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_UBYTE::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst(gpuDynInst, extData.VDATA);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                if (!oobMask[lane]) {
                    vdst[lane] = (VecElemU32)((reinterpret_cast<VecElemU8*>(
                        gpuDynInst->d_data))[lane]);
                } else {
                    vdst[lane] = 0;
                }
            }
        }

        vdst.write();
    } // execute

    // --- Inst_MUBUF__BUFFER_LOAD_SBYTE class methods ---

    Inst_MUBUF__BUFFER_LOAD_SBYTE
        ::Inst_MUBUF__BUFFER_LOAD_SBYTE(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_sbyte")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_LOAD_SBYTE

    Inst_MUBUF__BUFFER_LOAD_SBYTE::~Inst_MUBUF__BUFFER_LOAD_SBYTE()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_SBYTE

    // --- description from .arch file ---
    // Untyped buffer load signed byte (sign extend to VGPR destination).
    void
    Inst_MUBUF__BUFFER_LOAD_SBYTE::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_SBYTE::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_SBYTE::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_LOAD_USHORT class methods ---

    Inst_MUBUF__BUFFER_LOAD_USHORT
        ::Inst_MUBUF__BUFFER_LOAD_USHORT(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_ushort")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        if (instData.LDS) {
            setFlag(GroupSegment);
        } else {
            setFlag(GlobalSegment);
        }
    } // Inst_MUBUF__BUFFER_LOAD_USHORT

    Inst_MUBUF__BUFFER_LOAD_USHORT::~Inst_MUBUF__BUFFER_LOAD_USHORT()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_USHORT

    // --- description from .arch file ---
    // Untyped buffer load unsigned short (zero extend to VGPR destination).
    void
    Inst_MUBUF__BUFFER_LOAD_USHORT::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU32 addr0(gpuDynInst, extData.VADDR);
        ConstVecOperandU32 addr1(gpuDynInst, extData.VADDR + 1);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, extData.SRSRC * 4);
        ConstScalarOperandU32 offset(gpuDynInst, extData.SOFFSET);

        rsrcDesc.read();
        offset.read();

        int inst_offset = instData.OFFSET;

        if (!instData.IDXEN && !instData.OFFEN) {
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (!instData.IDXEN && instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (instData.IDXEN && !instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        } else {
            addr0.read();
            addr1.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        }

        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_USHORT::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<VecElemU16>(gpuDynInst);
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_USHORT::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst(gpuDynInst, extData.VDATA);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                if (!oobMask[lane]) {
                    vdst[lane] = (VecElemU32)((reinterpret_cast<VecElemU16*>(
                        gpuDynInst->d_data))[lane]);
                } else {
                    vdst[lane] = 0;
                }
            }
        }

        vdst.write();
    } // execute

    // --- Inst_MUBUF__BUFFER_LOAD_SSHORT class methods ---

    Inst_MUBUF__BUFFER_LOAD_SSHORT
        ::Inst_MUBUF__BUFFER_LOAD_SSHORT(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_sshort")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_LOAD_SSHORT

    Inst_MUBUF__BUFFER_LOAD_SSHORT::~Inst_MUBUF__BUFFER_LOAD_SSHORT()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_SSHORT

    // --- description from .arch file ---
    // Untyped buffer load signed short (sign extend to VGPR destination).
    void
    Inst_MUBUF__BUFFER_LOAD_SSHORT::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_SSHORT::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_SSHORT::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_LOAD_DWORD class methods ---

    Inst_MUBUF__BUFFER_LOAD_DWORD
        ::Inst_MUBUF__BUFFER_LOAD_DWORD(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_dword")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        if (instData.LDS) {
            setFlag(GroupSegment);
        } else {
            setFlag(GlobalSegment);
        }
    } // Inst_MUBUF__BUFFER_LOAD_DWORD

    Inst_MUBUF__BUFFER_LOAD_DWORD::~Inst_MUBUF__BUFFER_LOAD_DWORD()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_DWORD

    // --- description from .arch file ---
    // Untyped buffer load dword.
    void
    Inst_MUBUF__BUFFER_LOAD_DWORD::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU32 addr0(gpuDynInst, extData.VADDR);
        ConstVecOperandU32 addr1(gpuDynInst, extData.VADDR + 1);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, extData.SRSRC * 4);
        ConstScalarOperandU32 offset(gpuDynInst, extData.SOFFSET);

        rsrcDesc.read();
        offset.read();

        int inst_offset = instData.OFFSET;

        if (!instData.IDXEN && !instData.OFFEN) {
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (!instData.IDXEN && instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (instData.IDXEN && !instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        } else {
            addr0.read();
            addr1.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        }

        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_DWORD::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<VecElemU32>(gpuDynInst);
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_DWORD::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst(gpuDynInst, extData.VDATA);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                if (!oobMask[lane]) {
                    vdst[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane];
                } else {
                    vdst[lane] = 0;
                }
            }
        }

        vdst.write();
    } // completeAcc
    // --- Inst_MUBUF__BUFFER_LOAD_DWORDX2 class methods ---

    Inst_MUBUF__BUFFER_LOAD_DWORDX2
        ::Inst_MUBUF__BUFFER_LOAD_DWORDX2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_dwordx2")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        if (instData.LDS) {
            setFlag(GroupSegment);
        } else {
            setFlag(GlobalSegment);
        }
    } // Inst_MUBUF__BUFFER_LOAD_DWORDX2

    Inst_MUBUF__BUFFER_LOAD_DWORDX2::~Inst_MUBUF__BUFFER_LOAD_DWORDX2()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_DWORDX2

    // --- description from .arch file ---
    // Untyped buffer load 2 dwords.
    void
    Inst_MUBUF__BUFFER_LOAD_DWORDX2::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU32 addr0(gpuDynInst, extData.VADDR);
        ConstVecOperandU32 addr1(gpuDynInst, extData.VADDR + 1);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, extData.SRSRC * 4);
        ConstScalarOperandU32 offset(gpuDynInst, extData.SOFFSET);

        rsrcDesc.read();
        offset.read();

        int inst_offset = instData.OFFSET;

        if (!instData.IDXEN && !instData.OFFEN) {
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (!instData.IDXEN && instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (instData.IDXEN && !instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        } else {
            addr0.read();
            addr1.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        }

        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_DWORDX2::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<2>(gpuDynInst);
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_DWORDX2::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst0(gpuDynInst, extData.VDATA);
        VecOperandU32 vdst1(gpuDynInst, extData.VDATA + 1);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                if (!oobMask[lane]) {
                    vdst0[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane * 2];
                    vdst1[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane * 2 + 1];
                } else {
                    vdst0[lane] = 0;
                    vdst1[lane] = 0;
                }
            }
        }

        vdst0.write();
        vdst1.write();
    } // completeAcc
    // --- Inst_MUBUF__BUFFER_LOAD_DWORDX3 class methods ---

    Inst_MUBUF__BUFFER_LOAD_DWORDX3
        ::Inst_MUBUF__BUFFER_LOAD_DWORDX3(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_dwordx3")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        if (instData.LDS) {
            setFlag(GroupSegment);
        } else {
            setFlag(GlobalSegment);
        }
    } // Inst_MUBUF__BUFFER_LOAD_DWORDX3

    Inst_MUBUF__BUFFER_LOAD_DWORDX3::~Inst_MUBUF__BUFFER_LOAD_DWORDX3()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_DWORDX3

    // --- description from .arch file ---
    // Untyped buffer load 3 dwords.
    void
    Inst_MUBUF__BUFFER_LOAD_DWORDX3::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU32 addr0(gpuDynInst, extData.VADDR);
        ConstVecOperandU32 addr1(gpuDynInst, extData.VADDR + 1);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, extData.SRSRC * 4);
        ConstScalarOperandU32 offset(gpuDynInst, extData.SOFFSET);

        rsrcDesc.read();
        offset.read();

        int inst_offset = instData.OFFSET;

        if (!instData.IDXEN && !instData.OFFEN) {
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (!instData.IDXEN && instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (instData.IDXEN && !instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        } else {
            addr0.read();
            addr1.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        }

        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_DWORDX3::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<3>(gpuDynInst);
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_DWORDX3::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst0(gpuDynInst, extData.VDATA);
        VecOperandU32 vdst1(gpuDynInst, extData.VDATA + 1);
        VecOperandU32 vdst2(gpuDynInst, extData.VDATA + 2);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                if (!oobMask[lane]) {
                    vdst0[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane * 3];
                    vdst1[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane * 3 + 1];
                    vdst2[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane * 3 + 2];
                } else {
                    vdst0[lane] = 0;
                    vdst1[lane] = 0;
                    vdst2[lane] = 0;
                }
            }
        }

        vdst0.write();
        vdst1.write();
        vdst2.write();
    } // completeAcc
    // --- Inst_MUBUF__BUFFER_LOAD_DWORDX4 class methods ---

    Inst_MUBUF__BUFFER_LOAD_DWORDX4
        ::Inst_MUBUF__BUFFER_LOAD_DWORDX4(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_load_dwordx4")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        if (instData.LDS) {
            setFlag(GroupSegment);
        } else {
            setFlag(GlobalSegment);
        }
    } // Inst_MUBUF__BUFFER_LOAD_DWORDX4

    Inst_MUBUF__BUFFER_LOAD_DWORDX4::~Inst_MUBUF__BUFFER_LOAD_DWORDX4()
    {
    } // ~Inst_MUBUF__BUFFER_LOAD_DWORDX4

    // --- description from .arch file ---
    // Untyped buffer load 4 dwords.
    void
    Inst_MUBUF__BUFFER_LOAD_DWORDX4::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU32 addr0(gpuDynInst, extData.VADDR);
        ConstVecOperandU32 addr1(gpuDynInst, extData.VADDR + 1);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, extData.SRSRC * 4);
        ConstScalarOperandU32 offset(gpuDynInst, extData.SOFFSET);

        rsrcDesc.read();
        offset.read();

        int inst_offset = instData.OFFSET;

        if (!instData.IDXEN && !instData.OFFEN) {
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (!instData.IDXEN && instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (instData.IDXEN && !instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        } else {
            addr0.read();
            addr1.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        }

        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_MUBUF__BUFFER_LOAD_DWORDX4::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<4>(gpuDynInst);
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_LOAD_DWORDX4::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst0(gpuDynInst, extData.VDATA);
        VecOperandU32 vdst1(gpuDynInst, extData.VDATA + 1);
        VecOperandU32 vdst2(gpuDynInst, extData.VDATA + 2);
        VecOperandU32 vdst3(gpuDynInst, extData.VDATA + 3);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                if (!oobMask[lane]) {
                    vdst0[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane * 4];
                    vdst1[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane * 4 + 1];
                    vdst2[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane * 4 + 2];
                    vdst3[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane * 4 + 3];
                } else {
                    vdst0[lane] = 0;
                    vdst1[lane] = 0;
                    vdst2[lane] = 0;
                    vdst3[lane] = 0;
                }
            }
        }

        vdst0.write();
        vdst1.write();
        vdst2.write();
        vdst3.write();
    } // completeAcc
    // --- Inst_MUBUF__BUFFER_STORE_BYTE class methods ---

    Inst_MUBUF__BUFFER_STORE_BYTE
        ::Inst_MUBUF__BUFFER_STORE_BYTE(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_byte")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        if (instData.LDS) {
            setFlag(GroupSegment);
        } else {
            setFlag(GlobalSegment);
        }
    } // Inst_MUBUF__BUFFER_STORE_BYTE

    Inst_MUBUF__BUFFER_STORE_BYTE::~Inst_MUBUF__BUFFER_STORE_BYTE()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_BYTE

    // --- description from .arch file ---
    // Untyped buffer store byte.
    void
    Inst_MUBUF__BUFFER_STORE_BYTE::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            wf->decExpInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU32 addr0(gpuDynInst, extData.VADDR);
        ConstVecOperandU32 addr1(gpuDynInst, extData.VADDR + 1);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, extData.SRSRC * 4);
        ConstScalarOperandU32 offset(gpuDynInst, extData.SOFFSET);
        ConstVecOperandI8 data(gpuDynInst, extData.VDATA);

        rsrcDesc.read();
        offset.read();
        data.read();

        int inst_offset = instData.OFFSET;

        if (!instData.IDXEN && !instData.OFFEN) {
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (!instData.IDXEN && instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (instData.IDXEN && !instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        } else {
            addr0.read();
            addr1.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        }

       gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemI8*>(gpuDynInst->d_data))[lane]
                    = data[lane];
            }
        }
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_BYTE::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<VecElemI8>(gpuDynInst);
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_BYTE::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_STORE_SHORT class methods ---

    Inst_MUBUF__BUFFER_STORE_SHORT
        ::Inst_MUBUF__BUFFER_STORE_SHORT(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_short")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        if (instData.LDS) {
            setFlag(GroupSegment);
        } else {
            setFlag(GlobalSegment);
        }
    } // Inst_MUBUF__BUFFER_STORE_SHORT

    Inst_MUBUF__BUFFER_STORE_SHORT::~Inst_MUBUF__BUFFER_STORE_SHORT()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_SHORT

    // --- description from .arch file ---
    // Untyped buffer store short.
    void
    Inst_MUBUF__BUFFER_STORE_SHORT::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            wf->decExpInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU32 addr0(gpuDynInst, extData.VADDR);
        ConstVecOperandU32 addr1(gpuDynInst, extData.VADDR + 1);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, extData.SRSRC * 4);
        ConstScalarOperandU32 offset(gpuDynInst, extData.SOFFSET);
        ConstVecOperandI16 data(gpuDynInst, extData.VDATA);

        rsrcDesc.read();
        offset.read();
        data.read();

        int inst_offset = instData.OFFSET;

        if (!instData.IDXEN && !instData.OFFEN) {
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (!instData.IDXEN && instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (instData.IDXEN && !instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        } else {
            addr0.read();
            addr1.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        }

        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemI16*>(gpuDynInst->d_data))[lane]
                    = data[lane];
            }
        }
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_SHORT::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<VecElemI16>(gpuDynInst);
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_SHORT::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MUBUF__BUFFER_STORE_DWORD class methods ---

    Inst_MUBUF__BUFFER_STORE_DWORD::
        Inst_MUBUF__BUFFER_STORE_DWORD(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_dword")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        if (instData.LDS) {
            setFlag(GroupSegment);
        } else {
            setFlag(GlobalSegment);
        }
    } // Inst_MUBUF__BUFFER_STORE_DWORD

    Inst_MUBUF__BUFFER_STORE_DWORD::~Inst_MUBUF__BUFFER_STORE_DWORD()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_DWORD

    // --- description from .arch file ---
    // Untyped buffer store dword.
    void
    Inst_MUBUF__BUFFER_STORE_DWORD::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            wf->decExpInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU32 addr0(gpuDynInst, extData.VADDR);
        ConstVecOperandU32 addr1(gpuDynInst, extData.VADDR + 1);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, extData.SRSRC * 4);
        ConstScalarOperandU32 offset(gpuDynInst, extData.SOFFSET);
        ConstVecOperandU32 data(gpuDynInst, extData.VDATA);

        rsrcDesc.read();
        offset.read();
        data.read();

        int inst_offset = instData.OFFSET;

        if (!instData.IDXEN && !instData.OFFEN) {
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (!instData.IDXEN && instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (instData.IDXEN && !instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        } else {
            addr0.read();
            addr1.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        }

        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane]
                    = data[lane];
            }
        }
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_DWORD::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<VecElemU32>(gpuDynInst);
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_DWORD::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_MUBUF__BUFFER_STORE_DWORDX2 class methods ---

    Inst_MUBUF__BUFFER_STORE_DWORDX2
        ::Inst_MUBUF__BUFFER_STORE_DWORDX2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_dwordx2")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        if (instData.LDS) {
            setFlag(GroupSegment);
        } else {
            setFlag(GlobalSegment);
        }
    } // Inst_MUBUF__BUFFER_STORE_DWORDX2

    Inst_MUBUF__BUFFER_STORE_DWORDX2::~Inst_MUBUF__BUFFER_STORE_DWORDX2()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_DWORDX2

    // --- description from .arch file ---
    // Untyped buffer store 2 dwords.
    void
    Inst_MUBUF__BUFFER_STORE_DWORDX2::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            wf->decExpInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU32 addr0(gpuDynInst, extData.VADDR);
        ConstVecOperandU32 addr1(gpuDynInst, extData.VADDR + 1);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, extData.SRSRC * 4);
        ConstScalarOperandU32 offset(gpuDynInst, extData.SOFFSET);
        ConstVecOperandU32 data0(gpuDynInst, extData.VDATA);
        ConstVecOperandU32 data1(gpuDynInst, extData.VDATA + 1);

        rsrcDesc.read();
        offset.read();
        data0.read();
        data1.read();

        int inst_offset = instData.OFFSET;

        if (!instData.IDXEN && !instData.OFFEN) {
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (!instData.IDXEN && instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (instData.IDXEN && !instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        } else {
            addr0.read();
            addr1.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        }

        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane * 4]
                    = data0[lane];
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane*4 + 1]
                    = data1[lane];
            }
        }
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_DWORDX2::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<2>(gpuDynInst);
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_DWORDX2::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_MUBUF__BUFFER_STORE_DWORDX3 class methods ---

    Inst_MUBUF__BUFFER_STORE_DWORDX3
        ::Inst_MUBUF__BUFFER_STORE_DWORDX3(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_dwordx3")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        if (instData.LDS) {
            setFlag(GroupSegment);
        } else {
            setFlag(GlobalSegment);
        }
    } // Inst_MUBUF__BUFFER_STORE_DWORDX3

    Inst_MUBUF__BUFFER_STORE_DWORDX3::~Inst_MUBUF__BUFFER_STORE_DWORDX3()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_DWORDX3

    // --- description from .arch file ---
    // Untyped buffer store 3 dwords.
    void
    Inst_MUBUF__BUFFER_STORE_DWORDX3::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            wf->decExpInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU32 addr0(gpuDynInst, extData.VADDR);
        ConstVecOperandU32 addr1(gpuDynInst, extData.VADDR + 1);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, extData.SRSRC * 4);
        ConstScalarOperandU32 offset(gpuDynInst, extData.SOFFSET);
        ConstVecOperandU32 data0(gpuDynInst, extData.VDATA);
        ConstVecOperandU32 data1(gpuDynInst, extData.VDATA + 1);
        ConstVecOperandU32 data2(gpuDynInst, extData.VDATA + 2);

        rsrcDesc.read();
        offset.read();
        data0.read();
        data1.read();
        data2.read();

        int inst_offset = instData.OFFSET;

        if (!instData.IDXEN && !instData.OFFEN) {
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (!instData.IDXEN && instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (instData.IDXEN && !instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        } else {
            addr0.read();
            addr1.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        }

        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane * 4]
                    = data0[lane];
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane*4 + 1]
                    = data1[lane];
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane*4 + 2]
                    = data2[lane];
            }
        }
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_DWORDX3::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<3>(gpuDynInst);
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_DWORDX3::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_MUBUF__BUFFER_STORE_DWORDX4 class methods ---

    Inst_MUBUF__BUFFER_STORE_DWORDX4
        ::Inst_MUBUF__BUFFER_STORE_DWORDX4(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_dwordx4")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        if (instData.LDS) {
            setFlag(GroupSegment);
        } else {
            setFlag(GlobalSegment);
        }
    } // Inst_MUBUF__BUFFER_STORE_DWORDX4

    Inst_MUBUF__BUFFER_STORE_DWORDX4::~Inst_MUBUF__BUFFER_STORE_DWORDX4()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_DWORDX4

    // --- description from .arch file ---
    // Untyped buffer store 4 dwords.
    void
    Inst_MUBUF__BUFFER_STORE_DWORDX4::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            wf->decExpInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU32 addr0(gpuDynInst, extData.VADDR);
        ConstVecOperandU32 addr1(gpuDynInst, extData.VADDR + 1);
        ConstScalarOperandU128 rsrcDesc(gpuDynInst, extData.SRSRC * 4);
        ConstScalarOperandU32 offset(gpuDynInst, extData.SOFFSET);
        ConstVecOperandU32 data0(gpuDynInst, extData.VDATA);
        ConstVecOperandU32 data1(gpuDynInst, extData.VDATA + 1);
        ConstVecOperandU32 data2(gpuDynInst, extData.VDATA + 2);
        ConstVecOperandU32 data3(gpuDynInst, extData.VDATA + 3);

        rsrcDesc.read();
        offset.read();
        data0.read();
        data1.read();
        data2.read();
        data3.read();

        int inst_offset = instData.OFFSET;

        if (!instData.IDXEN && !instData.OFFEN) {
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (!instData.IDXEN && instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr0, addr1, rsrcDesc, offset, inst_offset);
        } else if (instData.IDXEN && !instData.OFFEN) {
            addr0.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        } else {
            addr0.read();
            addr1.read();
            calcAddr<ConstVecOperandU32, ConstVecOperandU32,
                ConstScalarOperandU128, ConstScalarOperandU32>(gpuDynInst,
                    addr1, addr0, rsrcDesc, offset, inst_offset);
        }

        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane * 4]
                    = data0[lane];
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane*4 + 1]
                    = data1[lane];
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane*4 + 2]
                    = data2[lane];
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane*4 + 3]
                    = data3[lane];
            }
        }
    } // execute

    void
    Inst_MUBUF__BUFFER_STORE_DWORDX4::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<4>(gpuDynInst);
    } // initiateAcc

    void
    Inst_MUBUF__BUFFER_STORE_DWORDX4::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_MUBUF__BUFFER_STORE_LDS_DWORD class methods ---

    Inst_MUBUF__BUFFER_STORE_LDS_DWORD
        ::Inst_MUBUF__BUFFER_STORE_LDS_DWORD(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_store_lds_dword")
    {
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_STORE_LDS_DWORD

    Inst_MUBUF__BUFFER_STORE_LDS_DWORD::~Inst_MUBUF__BUFFER_STORE_LDS_DWORD()
    {
    } // ~Inst_MUBUF__BUFFER_STORE_LDS_DWORD

    // --- description from .arch file ---
    // Store one DWORD from LDS memory to system memory without utilizing
    // VGPRs.
    void
    Inst_MUBUF__BUFFER_STORE_LDS_DWORD::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_WBINVL1 class methods ---

    Inst_MUBUF__BUFFER_WBINVL1::Inst_MUBUF__BUFFER_WBINVL1(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_wbinvl1")
    {
        setFlag(MemoryRef);
        setFlag(GPUStaticInst::MemSync);
        setFlag(GlobalSegment);
        setFlag(MemSync);
    } // Inst_MUBUF__BUFFER_WBINVL1

    Inst_MUBUF__BUFFER_WBINVL1::~Inst_MUBUF__BUFFER_WBINVL1()
    {
    } // ~Inst_MUBUF__BUFFER_WBINVL1

    // --- description from .arch file ---
    // Write back and invalidate the shader L1.
    // Always returns ACK to shader.
    void
    Inst_MUBUF__BUFFER_WBINVL1::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);
    } // execute

    void
    Inst_MUBUF__BUFFER_WBINVL1::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        // TODO: Fix it for gfx10. Once we have the new gfx10 cache model, we
        // need to precisely communicate the writeback-invalidate operation to
        // the new gfx10 coalescer rather than sending AcquireRelease markers.
        // The SICoalescer would need to be updated appropriately as well.
        injectGlobalMemFence(gpuDynInst);
    } // initiateAcc
    void
    Inst_MUBUF__BUFFER_WBINVL1::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_MUBUF__BUFFER_WBINVL1_VOL class methods ---

    Inst_MUBUF__BUFFER_WBINVL1_VOL
        ::Inst_MUBUF__BUFFER_WBINVL1_VOL(InFmt_MUBUF*iFmt)
        : Inst_MUBUF(iFmt, "buffer_wbinvl1_vol") {
        // This instruction is same as buffer_wbinvl1 instruction except this
        // instruction only invalidate L1 shader line with MTYPE SC and GC.
        // Since Hermes L1 (TCP) do not differentiate between its cache lines,
        // this instruction currently behaves (and implemented ) exactly like
        // buffer_wbinvl1 instruction.
        setFlag(MemoryRef);
        setFlag(GPUStaticInst::MemSync);
        setFlag(GlobalSegment);
        setFlag(MemSync);
    } // Inst_MUBUF__BUFFER_WBINVL1_VOL

    Inst_MUBUF__BUFFER_WBINVL1_VOL::~Inst_MUBUF__BUFFER_WBINVL1_VOL()
    {
    } // ~Inst_MUBUF__BUFFER_WBINVL1_VOL

    // --- description from .arch file ---
    // Write back and invalidate the shader L1 only for lines that are marked
    // ---  volatile.
    // Always returns ACK to shader.
    void
    Inst_MUBUF__BUFFER_WBINVL1_VOL::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none()) {
            wf->decVMemInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
        gpuDynInst->computeUnit()->globalMemoryPipe.issueRequest(gpuDynInst);
    } // execute
    void
    Inst_MUBUF__BUFFER_WBINVL1_VOL::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        injectGlobalMemFence(gpuDynInst);
    } // initiateAcc
    void
    Inst_MUBUF__BUFFER_WBINVL1_VOL::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_MUBUF__BUFFER_ATOMIC_SWAP class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_SWAP
        ::Inst_MUBUF__BUFFER_ATOMIC_SWAP(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_swap")
    {
        setFlag(AtomicExch);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_SWAP

    Inst_MUBUF__BUFFER_ATOMIC_SWAP::~Inst_MUBUF__BUFFER_ATOMIC_SWAP()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_SWAP

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = DATA;
    // RETURN_DATA = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_SWAP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP
        ::Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_cmpswap")
    {
        setFlag(AtomicCAS);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP

    Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP::~Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // src = DATA[0];
    // cmp = DATA[1];
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_ADD class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_ADD
        ::Inst_MUBUF__BUFFER_ATOMIC_ADD(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_add")
    {
        setFlag(AtomicAdd);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_ADD

    Inst_MUBUF__BUFFER_ATOMIC_ADD::~Inst_MUBUF__BUFFER_ATOMIC_ADD()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_ADD

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] += DATA;
    // RETURN_DATA = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_ADD::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_SUB class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_SUB
        ::Inst_MUBUF__BUFFER_ATOMIC_SUB(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_sub")
    {
        setFlag(AtomicSub);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_SUB

    Inst_MUBUF__BUFFER_ATOMIC_SUB::~Inst_MUBUF__BUFFER_ATOMIC_SUB()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_SUB

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_SUB::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_SMIN class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_SMIN
        ::Inst_MUBUF__BUFFER_ATOMIC_SMIN(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_smin")
    {
        setFlag(AtomicMin);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_SMIN

    Inst_MUBUF__BUFFER_ATOMIC_SMIN::~Inst_MUBUF__BUFFER_ATOMIC_SMIN()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_SMIN

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA < tmp) ? DATA : tmp (signed compare);
    // RETURN_DATA = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_SMIN::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_UMIN class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_UMIN
        ::Inst_MUBUF__BUFFER_ATOMIC_UMIN(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_umin")
    {
        setFlag(AtomicMin);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_UMIN

    Inst_MUBUF__BUFFER_ATOMIC_UMIN::~Inst_MUBUF__BUFFER_ATOMIC_UMIN()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_UMIN

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA < tmp) ? DATA : tmp (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_UMIN::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_SMAX class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_SMAX
        ::Inst_MUBUF__BUFFER_ATOMIC_SMAX(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_smax")
    {
        setFlag(AtomicMax);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_SMAX

    Inst_MUBUF__BUFFER_ATOMIC_SMAX::~Inst_MUBUF__BUFFER_ATOMIC_SMAX()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_SMAX

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA > tmp) ? DATA : tmp (signed compare);
    // RETURN_DATA = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_SMAX::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_UMAX class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_UMAX
        ::Inst_MUBUF__BUFFER_ATOMIC_UMAX(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_umax")
    {
        setFlag(AtomicMax);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_UMAX

    Inst_MUBUF__BUFFER_ATOMIC_UMAX::~Inst_MUBUF__BUFFER_ATOMIC_UMAX()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_UMAX

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA > tmp) ? DATA : tmp (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_UMAX::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_AND class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_AND
        ::Inst_MUBUF__BUFFER_ATOMIC_AND(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_and")
    {
        setFlag(AtomicAnd);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_AND

    Inst_MUBUF__BUFFER_ATOMIC_AND::~Inst_MUBUF__BUFFER_ATOMIC_AND()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_AND

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] &= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_AND::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_OR class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_OR
        ::Inst_MUBUF__BUFFER_ATOMIC_OR(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_or")
    {
        setFlag(AtomicOr);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_OR

    Inst_MUBUF__BUFFER_ATOMIC_OR::~Inst_MUBUF__BUFFER_ATOMIC_OR()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_OR

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] |= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_OR::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_XOR class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_XOR
        ::Inst_MUBUF__BUFFER_ATOMIC_XOR(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_xor")
    {
        setFlag(AtomicXor);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_XOR

    Inst_MUBUF__BUFFER_ATOMIC_XOR::~Inst_MUBUF__BUFFER_ATOMIC_XOR()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_XOR

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] ^= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_XOR::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_INC class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_INC
        ::Inst_MUBUF__BUFFER_ATOMIC_INC(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_inc")
    {
        setFlag(AtomicInc);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_INC

    Inst_MUBUF__BUFFER_ATOMIC_INC::~Inst_MUBUF__BUFFER_ATOMIC_INC()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_INC

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp >= DATA) ? 0 : tmp + 1 (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_INC::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_DEC class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_DEC
        ::Inst_MUBUF__BUFFER_ATOMIC_DEC(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_dec")
    {
        setFlag(AtomicDec);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_DEC

    Inst_MUBUF__BUFFER_ATOMIC_DEC::~Inst_MUBUF__BUFFER_ATOMIC_DEC()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_DEC

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp == 0 || tmp > DATA) ? DATA : tmp - 1
    // (unsigned compare); RETURN_DATA = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_DEC::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_SWAP_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_SWAP_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_SWAP_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_swap_x2")
    {
        setFlag(AtomicExch);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_SWAP_X2

    Inst_MUBUF__BUFFER_ATOMIC_SWAP_X2::~Inst_MUBUF__BUFFER_ATOMIC_SWAP_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_SWAP_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_SWAP_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_cmpswap_x2")
    {
        setFlag(AtomicCAS);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP_X2

    Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP_X2
        ::~Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // src = DATA[0:1];
    // cmp = DATA[2:3];
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_CMPSWAP_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_ADD_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_ADD_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_ADD_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_add_x2")
    {
        setFlag(AtomicAdd);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_ADD_X2

    Inst_MUBUF__BUFFER_ATOMIC_ADD_X2::~Inst_MUBUF__BUFFER_ATOMIC_ADD_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_ADD_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] += DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_ADD_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_SUB_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_SUB_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_SUB_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_sub_x2")
    {
        setFlag(AtomicSub);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_SUB_X2

    Inst_MUBUF__BUFFER_ATOMIC_SUB_X2::~Inst_MUBUF__BUFFER_ATOMIC_SUB_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_SUB_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_SUB_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_SMIN_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_SMIN_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_SMIN_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_smin_x2")
    {
        setFlag(AtomicMin);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_SMIN_X2

    Inst_MUBUF__BUFFER_ATOMIC_SMIN_X2::~Inst_MUBUF__BUFFER_ATOMIC_SMIN_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_SMIN_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] < tmp) ? DATA[0:1] : tmp (signed compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_SMIN_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_UMIN_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_UMIN_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_UMIN_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_umin_x2")
    {
        setFlag(AtomicMin);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_UMIN_X2

    Inst_MUBUF__BUFFER_ATOMIC_UMIN_X2::~Inst_MUBUF__BUFFER_ATOMIC_UMIN_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_UMIN_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] < tmp) ? DATA[0:1] : tmp (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_UMIN_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_SMAX_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_SMAX_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_SMAX_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_smax_x2")
    {
        setFlag(AtomicMax);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_SMAX_X2

    Inst_MUBUF__BUFFER_ATOMIC_SMAX_X2::~Inst_MUBUF__BUFFER_ATOMIC_SMAX_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_SMAX_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] > tmp) ? DATA[0:1] : tmp (signed compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_SMAX_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_UMAX_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_UMAX_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_UMAX_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_umax_x2")
    {
        setFlag(AtomicMax);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_UMAX_X2

    Inst_MUBUF__BUFFER_ATOMIC_UMAX_X2::~Inst_MUBUF__BUFFER_ATOMIC_UMAX_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_UMAX_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] > tmp) ? DATA[0:1] : tmp (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_UMAX_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_AND_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_AND_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_AND_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_and_x2")
    {
        setFlag(AtomicAnd);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_AND_X2

    Inst_MUBUF__BUFFER_ATOMIC_AND_X2::~Inst_MUBUF__BUFFER_ATOMIC_AND_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_AND_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] &= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_AND_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_OR_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_OR_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_OR_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_or_x2")
    {
        setFlag(AtomicOr);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
    } // Inst_MUBUF__BUFFER_ATOMIC_OR_X2

    Inst_MUBUF__BUFFER_ATOMIC_OR_X2::~Inst_MUBUF__BUFFER_ATOMIC_OR_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_OR_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] |= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_OR_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_XOR_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_XOR_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_XOR_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_xor_x2")
    {
        setFlag(AtomicXor);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_XOR_X2

    Inst_MUBUF__BUFFER_ATOMIC_XOR_X2::~Inst_MUBUF__BUFFER_ATOMIC_XOR_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_XOR_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] ^= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_XOR_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_INC_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_INC_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_INC_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_inc_x2")
    {
        setFlag(AtomicInc);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_INC_X2

    Inst_MUBUF__BUFFER_ATOMIC_INC_X2::~Inst_MUBUF__BUFFER_ATOMIC_INC_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_INC_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp >= DATA[0:1]) ? 0 : tmp + 1 (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_INC_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MUBUF__BUFFER_ATOMIC_DEC_X2 class methods ---

    Inst_MUBUF__BUFFER_ATOMIC_DEC_X2
        ::Inst_MUBUF__BUFFER_ATOMIC_DEC_X2(InFmt_MUBUF *iFmt)
        : Inst_MUBUF(iFmt, "buffer_atomic_dec_x2")
    {
        setFlag(AtomicDec);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MUBUF__BUFFER_ATOMIC_DEC_X2

    Inst_MUBUF__BUFFER_ATOMIC_DEC_X2::~Inst_MUBUF__BUFFER_ATOMIC_DEC_X2()
    {
    } // ~Inst_MUBUF__BUFFER_ATOMIC_DEC_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp == 0 || tmp > DATA[0:1]) ? DATA[0:1] : tmp - 1
    // (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_MUBUF__BUFFER_ATOMIC_DEC_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MTBUF__TBUFFER_LOAD_FORMAT_X class methods ---

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_X
        ::Inst_MTBUF__TBUFFER_LOAD_FORMAT_X(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_load_format_x")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_LOAD_FORMAT_X

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_X::~Inst_MTBUF__TBUFFER_LOAD_FORMAT_X()
    {
    } // ~Inst_MTBUF__TBUFFER_LOAD_FORMAT_X

    // --- description from .arch file ---
    // Typed buffer load 1 dword with format conversion.
    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_X::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_X::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_X::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_LOAD_FORMAT_XY class methods ---

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XY
        ::Inst_MTBUF__TBUFFER_LOAD_FORMAT_XY(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_load_format_xy")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_LOAD_FORMAT_XY

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XY::~Inst_MTBUF__TBUFFER_LOAD_FORMAT_XY()
    {
    } // ~Inst_MTBUF__TBUFFER_LOAD_FORMAT_XY

    // --- description from .arch file ---
    // Typed buffer load 2 dwords with format conversion.
    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XY::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XY::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XY::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZ class methods ---

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZ
        ::Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZ(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_load_format_xyz")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZ

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZ::~Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZ()
    {
    } // ~Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZ

    // --- description from .arch file ---
    // Typed buffer load 3 dwords with format conversion.
    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZ::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZ::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZ::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZW class methods ---

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZW
        ::Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZW(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_load_format_xyzw")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZW

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZW
        ::~Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZW()
    {
    } // ~Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZW

    // --- description from .arch file ---
    // Typed buffer load 4 dwords with format conversion.
    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZW::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZW::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_XYZW::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_STORE_FORMAT_X class methods ---

    Inst_MTBUF__TBUFFER_STORE_FORMAT_X
        ::Inst_MTBUF__TBUFFER_STORE_FORMAT_X(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_store_format_x")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_STORE_FORMAT_X

    Inst_MTBUF__TBUFFER_STORE_FORMAT_X::~Inst_MTBUF__TBUFFER_STORE_FORMAT_X()
    {
    } // ~Inst_MTBUF__TBUFFER_STORE_FORMAT_X

    // --- description from .arch file ---
    // Typed buffer store 1 dword with format conversion.
    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_X::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_X::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_X::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_STORE_FORMAT_XY class methods ---

    Inst_MTBUF__TBUFFER_STORE_FORMAT_XY
        ::Inst_MTBUF__TBUFFER_STORE_FORMAT_XY(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_store_format_xy")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_STORE_FORMAT_XY

    Inst_MTBUF__TBUFFER_STORE_FORMAT_XY::~Inst_MTBUF__TBUFFER_STORE_FORMAT_XY()
    {
    } // ~Inst_MTBUF__TBUFFER_STORE_FORMAT_XY

    // --- description from .arch file ---
    // Typed buffer store 2 dwords with format conversion.
    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_XY::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_XY::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_XY::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZ class methods ---

    Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZ
        ::Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZ(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_store_format_xyz")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZ

    Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZ
        ::~Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZ()
    {
    } // ~Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZ

    // --- description from .arch file ---
    // Typed buffer store 3 dwords with format conversion.
    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZ::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZ::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZ::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZW class methods ---

    Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZW
        ::Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZW(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_store_format_xyzw")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZW

    Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZW
        ::~Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZW()
    {
    } // ~Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZW

    // --- description from .arch file ---
    // Typed buffer store 4 dwords with format conversion.
    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZW::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZW::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_XYZW::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_X class methods ---

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_X
        ::Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_X(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_load_format_d16_x")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_X

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_X::
        ~Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_X()
    {
    } // ~Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_X

    // --- description from .arch file ---
    // Typed buffer load 1 dword with format conversion.
    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_X::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_X::initiateAcc(
          GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_X::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XY class methods ---

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XY
        ::Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XY(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_load_format_d16_xy")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XY

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XY
        ::~Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XY()
    {
    } // ~Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XY

    // --- description from .arch file ---
    // Typed buffer load 2 dwords with format conversion.
    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XY::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XY::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XY::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZ class methods ---

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZ
        ::Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZ(
          InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_load_format_d16_xyz")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZ

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZ
        ::~Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZ()
    {
    } // ~Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZ

    // --- description from .arch file ---
    // Typed buffer load 3 dwords with format conversion.
    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZ::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZ::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZ::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZW class methods ---

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZW
        ::Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZW(
          InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_load_format_d16_xyzw")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZW

    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZW
        ::~Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZW()
    {
    } // ~Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZW

    // --- description from .arch file ---
    // Typed buffer load 4 dwords with format conversion.
    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZW::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZW::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_LOAD_FORMAT_D16_XYZW::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_X class methods ---

    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_X
        ::Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_X(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_store_format_d16_x")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_X

    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_X
        ::~Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_X()
    {
    } // ~Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_X

    // --- description from .arch file ---
    // Typed buffer store 1 dword with format conversion.
    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_X::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_X::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_X::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XY class methods ---

    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XY
        ::Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XY(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_store_format_d16_xy")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XY

    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XY
        ::~Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XY()
    {
    } // ~Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XY

    // --- description from .arch file ---
    // Typed buffer store 2 dwords with format conversion.
    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XY::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XY::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XY::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZ class methods ---

    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZ
        ::Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZ(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_store_format_d16_xyz")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZ

    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZ
        ::~Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZ()
    {
    } // ~Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZ

    // --- description from .arch file ---
    // Typed buffer store 3 dwords with format conversion.
    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZ::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZ::initiateAcc(
          GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZ::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZW class methods ---

    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZW
        ::Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZW(InFmt_MTBUF *iFmt)
        : Inst_MTBUF(iFmt, "tbuffer_store_format_d16_xyzw")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZW

    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZW
        ::~Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZW()
    {
    } // ~Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZW

    // --- description from .arch file ---
    // Typed buffer store 4 dwords with format conversion.
    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZW::execute(
        GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZW::initiateAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MTBUF__TBUFFER_STORE_FORMAT_D16_XYZW::completeAcc(
        GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MIMG__IMAGE_LOAD class methods ---

    Inst_MIMG__IMAGE_LOAD::Inst_MIMG__IMAGE_LOAD(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_load")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_LOAD

    Inst_MIMG__IMAGE_LOAD::~Inst_MIMG__IMAGE_LOAD()
    {
    } // ~Inst_MIMG__IMAGE_LOAD

    // --- description from .arch file ---
    // Image memory load with format conversion specified in T#. No sampler.
    void
    Inst_MIMG__IMAGE_LOAD::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MIMG__IMAGE_LOAD::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MIMG__IMAGE_LOAD::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MIMG__IMAGE_LOAD_MIP class methods ---

    Inst_MIMG__IMAGE_LOAD_MIP::Inst_MIMG__IMAGE_LOAD_MIP(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_load_mip")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_LOAD_MIP

    Inst_MIMG__IMAGE_LOAD_MIP::~Inst_MIMG__IMAGE_LOAD_MIP()
    {
    } // ~Inst_MIMG__IMAGE_LOAD_MIP

    // --- description from .arch file ---
    // Image memory load with user-supplied mip level. No sampler.
    void
    Inst_MIMG__IMAGE_LOAD_MIP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MIMG__IMAGE_LOAD_MIP::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MIMG__IMAGE_LOAD_MIP::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MIMG__IMAGE_LOAD_PCK class methods ---

    Inst_MIMG__IMAGE_LOAD_PCK::Inst_MIMG__IMAGE_LOAD_PCK(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_load_pck")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_LOAD_PCK

    Inst_MIMG__IMAGE_LOAD_PCK::~Inst_MIMG__IMAGE_LOAD_PCK()
    {
    } // ~Inst_MIMG__IMAGE_LOAD_PCK

    // --- description from .arch file ---
    // Image memory load with no format conversion. No sampler.
    void
    Inst_MIMG__IMAGE_LOAD_PCK::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MIMG__IMAGE_LOAD_PCK::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MIMG__IMAGE_LOAD_PCK::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MIMG__IMAGE_LOAD_PCK_SGN class methods ---

    Inst_MIMG__IMAGE_LOAD_PCK_SGN::Inst_MIMG__IMAGE_LOAD_PCK_SGN(
        InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_load_pck_sgn")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_LOAD_PCK_SGN

    Inst_MIMG__IMAGE_LOAD_PCK_SGN::~Inst_MIMG__IMAGE_LOAD_PCK_SGN()
    {
    } // ~Inst_MIMG__IMAGE_LOAD_PCK_SGN

    // --- description from .arch file ---
    // Image memory load with with no format conversion and sign extension. No
    // ---  sampler.
    void
    Inst_MIMG__IMAGE_LOAD_PCK_SGN::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MIMG__IMAGE_LOAD_PCK_SGN::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MIMG__IMAGE_LOAD_PCK_SGN::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MIMG__IMAGE_LOAD_MIP_PCK class methods ---

    Inst_MIMG__IMAGE_LOAD_MIP_PCK::Inst_MIMG__IMAGE_LOAD_MIP_PCK(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_load_mip_pck")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_LOAD_MIP_PCK

    Inst_MIMG__IMAGE_LOAD_MIP_PCK::~Inst_MIMG__IMAGE_LOAD_MIP_PCK()
    {
    } // ~Inst_MIMG__IMAGE_LOAD_MIP_PCK

    // --- description from .arch file ---
    // Image memory load with user-supplied mip level, no format conversion. No
    // ---  sampler.
    void
    Inst_MIMG__IMAGE_LOAD_MIP_PCK::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MIMG__IMAGE_LOAD_MIP_PCK::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MIMG__IMAGE_LOAD_MIP_PCK::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MIMG__IMAGE_LOAD_MIP_PCK_SGN class methods ---

    Inst_MIMG__IMAGE_LOAD_MIP_PCK_SGN::Inst_MIMG__IMAGE_LOAD_MIP_PCK_SGN(
        InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_load_mip_pck_sgn")
    {
        setFlag(MemoryRef);
        setFlag(Load);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_LOAD_MIP_PCK_SGN

    Inst_MIMG__IMAGE_LOAD_MIP_PCK_SGN::~Inst_MIMG__IMAGE_LOAD_MIP_PCK_SGN()
    {
    } // ~Inst_MIMG__IMAGE_LOAD_MIP_PCK_SGN

    // --- description from .arch file ---
    // Image memory load with user-supplied mip level, no format conversion and
    // ---  with sign extension. No sampler.
    void
    Inst_MIMG__IMAGE_LOAD_MIP_PCK_SGN::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MIMG__IMAGE_LOAD_MIP_PCK_SGN::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MIMG__IMAGE_LOAD_MIP_PCK_SGN::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MIMG__IMAGE_STORE class methods ---

    Inst_MIMG__IMAGE_STORE::Inst_MIMG__IMAGE_STORE(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_store")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_STORE

    Inst_MIMG__IMAGE_STORE::~Inst_MIMG__IMAGE_STORE()
    {
    } // ~Inst_MIMG__IMAGE_STORE

    // --- description from .arch file ---
    // Image memory store with format conversion specified in T#. No sampler.
    void
    Inst_MIMG__IMAGE_STORE::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MIMG__IMAGE_STORE::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MIMG__IMAGE_STORE::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MIMG__IMAGE_STORE_MIP class methods ---

    Inst_MIMG__IMAGE_STORE_MIP::Inst_MIMG__IMAGE_STORE_MIP(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_store_mip")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_STORE_MIP

    Inst_MIMG__IMAGE_STORE_MIP::~Inst_MIMG__IMAGE_STORE_MIP()
    {
    } // ~Inst_MIMG__IMAGE_STORE_MIP

    // --- description from .arch file ---
    // Image memory store with format conversion specified in T# to user
    // specified mip level. No sampler.
    void
    Inst_MIMG__IMAGE_STORE_MIP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MIMG__IMAGE_STORE_MIP::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MIMG__IMAGE_STORE_MIP::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MIMG__IMAGE_STORE_PCK class methods ---

    Inst_MIMG__IMAGE_STORE_PCK::Inst_MIMG__IMAGE_STORE_PCK(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_store_pck")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_STORE_PCK

    Inst_MIMG__IMAGE_STORE_PCK::~Inst_MIMG__IMAGE_STORE_PCK()
    {
    } // ~Inst_MIMG__IMAGE_STORE_PCK

    // --- description from .arch file ---
    // Image memory store of packed data without format conversion. No sampler.
    void
    Inst_MIMG__IMAGE_STORE_PCK::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MIMG__IMAGE_STORE_PCK::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MIMG__IMAGE_STORE_PCK::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MIMG__IMAGE_STORE_MIP_PCK class methods ---

    Inst_MIMG__IMAGE_STORE_MIP_PCK::Inst_MIMG__IMAGE_STORE_MIP_PCK(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_store_mip_pck")
    {
        setFlag(MemoryRef);
        setFlag(Store);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_STORE_MIP_PCK

    Inst_MIMG__IMAGE_STORE_MIP_PCK::~Inst_MIMG__IMAGE_STORE_MIP_PCK()
    {
    } // ~Inst_MIMG__IMAGE_STORE_MIP_PCK

    // --- description from .arch file ---
    // Image memory store of packed data without format conversion to
    // user-supplied mip level. No sampler.
    void
    Inst_MIMG__IMAGE_STORE_MIP_PCK::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_MIMG__IMAGE_STORE_MIP_PCK::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_MIMG__IMAGE_STORE_MIP_PCK::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_MIMG__IMAGE_GET_RESINFO class methods ---

    Inst_MIMG__IMAGE_GET_RESINFO::Inst_MIMG__IMAGE_GET_RESINFO(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_get_resinfo")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GET_RESINFO

    Inst_MIMG__IMAGE_GET_RESINFO::~Inst_MIMG__IMAGE_GET_RESINFO()
    {
    } // ~Inst_MIMG__IMAGE_GET_RESINFO

    // --- description from .arch file ---
    // return resource info for a given mip level specified in the address
    // vgpr. No sampler. Returns 4 integer values into VGPRs 3-0:
    // {num_mip_levels, depth, height, width}.
    void
    Inst_MIMG__IMAGE_GET_RESINFO::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_SWAP class methods ---

    Inst_MIMG__IMAGE_ATOMIC_SWAP::Inst_MIMG__IMAGE_ATOMIC_SWAP(
        InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_swap")
    {
        setFlag(AtomicExch);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_SWAP

    Inst_MIMG__IMAGE_ATOMIC_SWAP::~Inst_MIMG__IMAGE_ATOMIC_SWAP()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_SWAP

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = DATA;
    // RETURN_DATA = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_SWAP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_CMPSWAP class methods ---

    Inst_MIMG__IMAGE_ATOMIC_CMPSWAP::Inst_MIMG__IMAGE_ATOMIC_CMPSWAP(
        InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_cmpswap")
    {
        setFlag(AtomicCAS);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_CMPSWAP

    Inst_MIMG__IMAGE_ATOMIC_CMPSWAP::~Inst_MIMG__IMAGE_ATOMIC_CMPSWAP()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_CMPSWAP

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // src = DATA[0];
    // cmp = DATA[1];
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0] = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_CMPSWAP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_ADD class methods ---

    Inst_MIMG__IMAGE_ATOMIC_ADD::Inst_MIMG__IMAGE_ATOMIC_ADD(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_add")
    {
        setFlag(AtomicAdd);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_ADD

    Inst_MIMG__IMAGE_ATOMIC_ADD::~Inst_MIMG__IMAGE_ATOMIC_ADD()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_ADD

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] += DATA;
    // RETURN_DATA = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_ADD::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_SUB class methods ---

    Inst_MIMG__IMAGE_ATOMIC_SUB::Inst_MIMG__IMAGE_ATOMIC_SUB(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_sub")
    {
        setFlag(AtomicSub);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_SUB

    Inst_MIMG__IMAGE_ATOMIC_SUB::~Inst_MIMG__IMAGE_ATOMIC_SUB()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_SUB

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_SUB::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_SMIN class methods ---

    Inst_MIMG__IMAGE_ATOMIC_SMIN::Inst_MIMG__IMAGE_ATOMIC_SMIN(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_smin")
    {
        setFlag(AtomicMin);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_SMIN

    Inst_MIMG__IMAGE_ATOMIC_SMIN::~Inst_MIMG__IMAGE_ATOMIC_SMIN()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_SMIN

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA < tmp) ? DATA : tmp (signed compare);
    // RETURN_DATA = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_SMIN::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_UMIN class methods ---

    Inst_MIMG__IMAGE_ATOMIC_UMIN::Inst_MIMG__IMAGE_ATOMIC_UMIN(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_umin")
    {
        setFlag(AtomicMin);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_UMIN

    Inst_MIMG__IMAGE_ATOMIC_UMIN::~Inst_MIMG__IMAGE_ATOMIC_UMIN()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_UMIN

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA < tmp) ? DATA : tmp (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_UMIN::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_SMAX class methods ---

    Inst_MIMG__IMAGE_ATOMIC_SMAX::Inst_MIMG__IMAGE_ATOMIC_SMAX(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_smax")
    {
        setFlag(AtomicMax);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_SMAX

    Inst_MIMG__IMAGE_ATOMIC_SMAX::~Inst_MIMG__IMAGE_ATOMIC_SMAX()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_SMAX

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA > tmp) ? DATA : tmp (signed compare);
    // RETURN_DATA = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_SMAX::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_UMAX class methods ---

    Inst_MIMG__IMAGE_ATOMIC_UMAX::Inst_MIMG__IMAGE_ATOMIC_UMAX(
        InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_umax")
    {
        setFlag(AtomicMax);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_UMAX

    Inst_MIMG__IMAGE_ATOMIC_UMAX::~Inst_MIMG__IMAGE_ATOMIC_UMAX()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_UMAX

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA > tmp) ? DATA : tmp (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_UMAX::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_AND class methods ---

    Inst_MIMG__IMAGE_ATOMIC_AND::Inst_MIMG__IMAGE_ATOMIC_AND(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_and")
    {
        setFlag(AtomicAnd);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_AND

    Inst_MIMG__IMAGE_ATOMIC_AND::~Inst_MIMG__IMAGE_ATOMIC_AND()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_AND

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] &= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_AND::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_OR class methods ---

    Inst_MIMG__IMAGE_ATOMIC_OR::Inst_MIMG__IMAGE_ATOMIC_OR(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_or")
    {
        setFlag(AtomicOr);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_OR

    Inst_MIMG__IMAGE_ATOMIC_OR::~Inst_MIMG__IMAGE_ATOMIC_OR()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_OR

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] |= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_OR::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_XOR class methods ---

    Inst_MIMG__IMAGE_ATOMIC_XOR::Inst_MIMG__IMAGE_ATOMIC_XOR(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_xor")
    {
        setFlag(AtomicXor);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_XOR

    Inst_MIMG__IMAGE_ATOMIC_XOR::~Inst_MIMG__IMAGE_ATOMIC_XOR()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_XOR

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] ^= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_XOR::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_INC class methods ---

    Inst_MIMG__IMAGE_ATOMIC_INC::Inst_MIMG__IMAGE_ATOMIC_INC(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_inc")
    {
        setFlag(AtomicInc);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_INC

    Inst_MIMG__IMAGE_ATOMIC_INC::~Inst_MIMG__IMAGE_ATOMIC_INC()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_INC

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp >= DATA) ? 0 : tmp + 1 (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_INC::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_ATOMIC_DEC class methods ---

    Inst_MIMG__IMAGE_ATOMIC_DEC::Inst_MIMG__IMAGE_ATOMIC_DEC(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_atomic_dec")
    {
        setFlag(AtomicDec);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_ATOMIC_DEC

    Inst_MIMG__IMAGE_ATOMIC_DEC::~Inst_MIMG__IMAGE_ATOMIC_DEC()
    {
    } // ~Inst_MIMG__IMAGE_ATOMIC_DEC

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp == 0 || tmp > DATA) ? DATA : tmp - 1
    // (unsigned compare); RETURN_DATA = tmp.
    void
    Inst_MIMG__IMAGE_ATOMIC_DEC::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE class methods ---

    Inst_MIMG__IMAGE_SAMPLE::Inst_MIMG__IMAGE_SAMPLE(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample")
    {
    } // Inst_MIMG__IMAGE_SAMPLE

    Inst_MIMG__IMAGE_SAMPLE::~Inst_MIMG__IMAGE_SAMPLE()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE

    // --- description from .arch file ---
    // sample texture map.
    void
    Inst_MIMG__IMAGE_SAMPLE::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_CL class methods ---

    Inst_MIMG__IMAGE_SAMPLE_CL::Inst_MIMG__IMAGE_SAMPLE_CL(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_cl")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_CL

    Inst_MIMG__IMAGE_SAMPLE_CL::~Inst_MIMG__IMAGE_SAMPLE_CL()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_CL

    // --- description from .arch file ---
    // sample texture map, with LOD clamp specified in shader.
    void
    Inst_MIMG__IMAGE_SAMPLE_CL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_D class methods ---

    Inst_MIMG__IMAGE_SAMPLE_D::Inst_MIMG__IMAGE_SAMPLE_D(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_d")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_D

    Inst_MIMG__IMAGE_SAMPLE_D::~Inst_MIMG__IMAGE_SAMPLE_D()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_D

    // --- description from .arch file ---
    // sample texture map, with user derivatives
    void
    Inst_MIMG__IMAGE_SAMPLE_D::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_D_CL class methods ---

    Inst_MIMG__IMAGE_SAMPLE_D_CL::Inst_MIMG__IMAGE_SAMPLE_D_CL(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_d_cl")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_D_CL

    Inst_MIMG__IMAGE_SAMPLE_D_CL::~Inst_MIMG__IMAGE_SAMPLE_D_CL()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_D_CL

    // --- description from .arch file ---
    // sample texture map, with LOD clamp specified in shader, with user
    // ---  derivatives.
    void
    Inst_MIMG__IMAGE_SAMPLE_D_CL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_L class methods ---

    Inst_MIMG__IMAGE_SAMPLE_L::Inst_MIMG__IMAGE_SAMPLE_L(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_l")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_L

    Inst_MIMG__IMAGE_SAMPLE_L::~Inst_MIMG__IMAGE_SAMPLE_L()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_L

    // --- description from .arch file ---
    // sample texture map, with user LOD.
    void
    Inst_MIMG__IMAGE_SAMPLE_L::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_B class methods ---

    Inst_MIMG__IMAGE_SAMPLE_B::Inst_MIMG__IMAGE_SAMPLE_B(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_b")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_B

    Inst_MIMG__IMAGE_SAMPLE_B::~Inst_MIMG__IMAGE_SAMPLE_B()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_B

    // --- description from .arch file ---
    // sample texture map, with lod bias.
    void
    Inst_MIMG__IMAGE_SAMPLE_B::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_B_CL class methods ---

    Inst_MIMG__IMAGE_SAMPLE_B_CL::Inst_MIMG__IMAGE_SAMPLE_B_CL(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_b_cl")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_B_CL

    Inst_MIMG__IMAGE_SAMPLE_B_CL::~Inst_MIMG__IMAGE_SAMPLE_B_CL()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_B_CL

    // --- description from .arch file ---
    // sample texture map, with LOD clamp specified in shader, with lod bias.
    void
    Inst_MIMG__IMAGE_SAMPLE_B_CL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_LZ class methods ---

    Inst_MIMG__IMAGE_SAMPLE_LZ::Inst_MIMG__IMAGE_SAMPLE_LZ(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_lz")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_LZ

    Inst_MIMG__IMAGE_SAMPLE_LZ::~Inst_MIMG__IMAGE_SAMPLE_LZ()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_LZ

    // --- description from .arch file ---
    // sample texture map, from level 0.
    void
    Inst_MIMG__IMAGE_SAMPLE_LZ::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C::Inst_MIMG__IMAGE_SAMPLE_C(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C

    Inst_MIMG__IMAGE_SAMPLE_C::~Inst_MIMG__IMAGE_SAMPLE_C()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C

    // --- description from .arch file ---
    // sample texture map, with PCF.
    void
    Inst_MIMG__IMAGE_SAMPLE_C::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_CL class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_CL::Inst_MIMG__IMAGE_SAMPLE_C_CL(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_cl")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_CL

    Inst_MIMG__IMAGE_SAMPLE_C_CL::~Inst_MIMG__IMAGE_SAMPLE_C_CL()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_CL

    // --- description from .arch file ---
    // SAMPLE_C, with LOD clamp specified in shader.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_CL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_D class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_D::Inst_MIMG__IMAGE_SAMPLE_C_D(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_d")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_D

    Inst_MIMG__IMAGE_SAMPLE_C_D::~Inst_MIMG__IMAGE_SAMPLE_C_D()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_D

    // --- description from .arch file ---
    // SAMPLE_C, with user derivatives.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_D::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_D_CL class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_D_CL::Inst_MIMG__IMAGE_SAMPLE_C_D_CL(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_d_cl")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_D_CL

    Inst_MIMG__IMAGE_SAMPLE_C_D_CL::~Inst_MIMG__IMAGE_SAMPLE_C_D_CL()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_D_CL

    // --- description from .arch file ---
    // SAMPLE_C, with LOD clamp specified in shader, with user derivatives.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_D_CL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_L class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_L::Inst_MIMG__IMAGE_SAMPLE_C_L(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_l")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_L

    Inst_MIMG__IMAGE_SAMPLE_C_L::~Inst_MIMG__IMAGE_SAMPLE_C_L()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_L

    // --- description from .arch file ---
    // SAMPLE_C, with user LOD.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_L::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_B class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_B::Inst_MIMG__IMAGE_SAMPLE_C_B(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_b")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_B

    Inst_MIMG__IMAGE_SAMPLE_C_B::~Inst_MIMG__IMAGE_SAMPLE_C_B()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_B

    // --- description from .arch file ---
    // SAMPLE_C, with lod bias.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_B::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_B_CL class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_B_CL::Inst_MIMG__IMAGE_SAMPLE_C_B_CL(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_b_cl")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_B_CL

    Inst_MIMG__IMAGE_SAMPLE_C_B_CL::~Inst_MIMG__IMAGE_SAMPLE_C_B_CL()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_B_CL

    // --- description from .arch file ---
    // SAMPLE_C, with LOD clamp specified in shader, with lod bias.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_B_CL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_LZ class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_LZ::Inst_MIMG__IMAGE_SAMPLE_C_LZ(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_lz")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_LZ

    Inst_MIMG__IMAGE_SAMPLE_C_LZ::~Inst_MIMG__IMAGE_SAMPLE_C_LZ()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_LZ

    // --- description from .arch file ---
    // SAMPLE_C, from level 0.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_LZ::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_O::Inst_MIMG__IMAGE_SAMPLE_O(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_O

    Inst_MIMG__IMAGE_SAMPLE_O::~Inst_MIMG__IMAGE_SAMPLE_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_O

    // --- description from .arch file ---
    // sample texture map, with user offsets.
    void
    Inst_MIMG__IMAGE_SAMPLE_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_CL_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_CL_O::Inst_MIMG__IMAGE_SAMPLE_CL_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_cl_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_CL_O

    Inst_MIMG__IMAGE_SAMPLE_CL_O::~Inst_MIMG__IMAGE_SAMPLE_CL_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_CL_O

    // --- description from .arch file ---
    // SAMPLE_O with LOD clamp specified in shader.
    void
    Inst_MIMG__IMAGE_SAMPLE_CL_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_D_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_D_O::Inst_MIMG__IMAGE_SAMPLE_D_O(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_d_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_D_O

    Inst_MIMG__IMAGE_SAMPLE_D_O::~Inst_MIMG__IMAGE_SAMPLE_D_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_D_O

    // --- description from .arch file ---
    // SAMPLE_O, with user derivatives.
    void
    Inst_MIMG__IMAGE_SAMPLE_D_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_D_CL_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_D_CL_O::Inst_MIMG__IMAGE_SAMPLE_D_CL_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_d_cl_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_D_CL_O

    Inst_MIMG__IMAGE_SAMPLE_D_CL_O::~Inst_MIMG__IMAGE_SAMPLE_D_CL_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_D_CL_O

    // --- description from .arch file ---
    // SAMPLE_O, with LOD clamp specified in shader, with user derivatives.
    void
    Inst_MIMG__IMAGE_SAMPLE_D_CL_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_L_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_L_O::Inst_MIMG__IMAGE_SAMPLE_L_O(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_l_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_L_O

    Inst_MIMG__IMAGE_SAMPLE_L_O::~Inst_MIMG__IMAGE_SAMPLE_L_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_L_O

    // --- description from .arch file ---
    // SAMPLE_O, with user LOD.
    void
    Inst_MIMG__IMAGE_SAMPLE_L_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_B_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_B_O::Inst_MIMG__IMAGE_SAMPLE_B_O(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_b_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_B_O

    Inst_MIMG__IMAGE_SAMPLE_B_O::~Inst_MIMG__IMAGE_SAMPLE_B_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_B_O

    // --- description from .arch file ---
    // SAMPLE_O, with lod bias.
    void
    Inst_MIMG__IMAGE_SAMPLE_B_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_B_CL_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_B_CL_O::Inst_MIMG__IMAGE_SAMPLE_B_CL_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_b_cl_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_B_CL_O

    Inst_MIMG__IMAGE_SAMPLE_B_CL_O::~Inst_MIMG__IMAGE_SAMPLE_B_CL_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_B_CL_O

    // --- description from .arch file ---
    // SAMPLE_O, with LOD clamp specified in shader, with lod bias.
    void
    Inst_MIMG__IMAGE_SAMPLE_B_CL_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_LZ_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_LZ_O::Inst_MIMG__IMAGE_SAMPLE_LZ_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_lz_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_LZ_O

    Inst_MIMG__IMAGE_SAMPLE_LZ_O::~Inst_MIMG__IMAGE_SAMPLE_LZ_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_LZ_O

    // --- description from .arch file ---
    // SAMPLE_O, from level 0.
    void
    Inst_MIMG__IMAGE_SAMPLE_LZ_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_O::Inst_MIMG__IMAGE_SAMPLE_C_O(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_O

    Inst_MIMG__IMAGE_SAMPLE_C_O::~Inst_MIMG__IMAGE_SAMPLE_C_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_O

    // --- description from .arch file ---
    // SAMPLE_C with user specified offsets.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_CL_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_CL_O::Inst_MIMG__IMAGE_SAMPLE_C_CL_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_cl_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_CL_O

    Inst_MIMG__IMAGE_SAMPLE_C_CL_O::~Inst_MIMG__IMAGE_SAMPLE_C_CL_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_CL_O

    // --- description from .arch file ---
    // SAMPLE_C_O, with LOD clamp specified in shader.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_CL_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_D_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_D_O::Inst_MIMG__IMAGE_SAMPLE_C_D_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_d_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_D_O

    Inst_MIMG__IMAGE_SAMPLE_C_D_O::~Inst_MIMG__IMAGE_SAMPLE_C_D_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_D_O

    // --- description from .arch file ---
    // SAMPLE_C_O, with user derivatives.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_D_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_D_CL_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_D_CL_O::Inst_MIMG__IMAGE_SAMPLE_C_D_CL_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_d_cl_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_D_CL_O

    Inst_MIMG__IMAGE_SAMPLE_C_D_CL_O::~Inst_MIMG__IMAGE_SAMPLE_C_D_CL_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_D_CL_O

    // --- description from .arch file ---
    // SAMPLE_C_O, with LOD clamp specified in shader, with user derivatives.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_D_CL_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_L_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_L_O::Inst_MIMG__IMAGE_SAMPLE_C_L_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_l_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_L_O

    Inst_MIMG__IMAGE_SAMPLE_C_L_O::~Inst_MIMG__IMAGE_SAMPLE_C_L_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_L_O

    // --- description from .arch file ---
    // SAMPLE_C_O, with user LOD.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_L_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_B_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_B_O::Inst_MIMG__IMAGE_SAMPLE_C_B_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_b_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_B_O

    Inst_MIMG__IMAGE_SAMPLE_C_B_O::~Inst_MIMG__IMAGE_SAMPLE_C_B_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_B_O

    // --- description from .arch file ---
    // SAMPLE_C_O, with lod bias.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_B_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_B_CL_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_B_CL_O::Inst_MIMG__IMAGE_SAMPLE_C_B_CL_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_b_cl_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_B_CL_O

    Inst_MIMG__IMAGE_SAMPLE_C_B_CL_O::~Inst_MIMG__IMAGE_SAMPLE_C_B_CL_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_B_CL_O

    // --- description from .arch file ---
    // SAMPLE_C_O, with LOD clamp specified in shader, with lod bias.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_B_CL_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_LZ_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_LZ_O::Inst_MIMG__IMAGE_SAMPLE_C_LZ_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_lz_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_LZ_O

    Inst_MIMG__IMAGE_SAMPLE_C_LZ_O::~Inst_MIMG__IMAGE_SAMPLE_C_LZ_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_LZ_O

    // --- description from .arch file ---
    // SAMPLE_C_O, from level 0.
    void
    Inst_MIMG__IMAGE_SAMPLE_C_LZ_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4 class methods ---

    Inst_MIMG__IMAGE_GATHER4::Inst_MIMG__IMAGE_GATHER4(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4

    Inst_MIMG__IMAGE_GATHER4::~Inst_MIMG__IMAGE_GATHER4()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4

    // --- description from .arch file ---
    // gather 4 single component elements (2x2).
    void
    Inst_MIMG__IMAGE_GATHER4::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_CL class methods ---

    Inst_MIMG__IMAGE_GATHER4_CL::Inst_MIMG__IMAGE_GATHER4_CL(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_cl")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_CL

    Inst_MIMG__IMAGE_GATHER4_CL::~Inst_MIMG__IMAGE_GATHER4_CL()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_CL

    // --- description from .arch file ---
    // gather 4 single component elements (2x2) with user LOD clamp.
    void
    Inst_MIMG__IMAGE_GATHER4_CL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_L class methods ---

    Inst_MIMG__IMAGE_GATHER4_L::Inst_MIMG__IMAGE_GATHER4_L(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_l")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_L

    Inst_MIMG__IMAGE_GATHER4_L::~Inst_MIMG__IMAGE_GATHER4_L()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_L

    // --- description from .arch file ---
    // gather 4 single component elements (2x2) with user LOD.
    void
    Inst_MIMG__IMAGE_GATHER4_L::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_B class methods ---

    Inst_MIMG__IMAGE_GATHER4_B::Inst_MIMG__IMAGE_GATHER4_B(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_b")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_B

    Inst_MIMG__IMAGE_GATHER4_B::~Inst_MIMG__IMAGE_GATHER4_B()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_B

    // --- description from .arch file ---
    // gather 4 single component elements (2x2) with user bias.
    void
    Inst_MIMG__IMAGE_GATHER4_B::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_B_CL class methods ---

    Inst_MIMG__IMAGE_GATHER4_B_CL::Inst_MIMG__IMAGE_GATHER4_B_CL(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_b_cl")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_B_CL

    Inst_MIMG__IMAGE_GATHER4_B_CL::~Inst_MIMG__IMAGE_GATHER4_B_CL()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_B_CL

    // --- description from .arch file ---
    // gather 4 single component elements (2x2) with user bias and clamp.
    void
    Inst_MIMG__IMAGE_GATHER4_B_CL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_LZ class methods ---

    Inst_MIMG__IMAGE_GATHER4_LZ::Inst_MIMG__IMAGE_GATHER4_LZ(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_lz")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_LZ

    Inst_MIMG__IMAGE_GATHER4_LZ::~Inst_MIMG__IMAGE_GATHER4_LZ()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_LZ

    // --- description from .arch file ---
    // gather 4 single component elements (2x2) at level 0.
    void
    Inst_MIMG__IMAGE_GATHER4_LZ::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_C class methods ---

    Inst_MIMG__IMAGE_GATHER4_C::Inst_MIMG__IMAGE_GATHER4_C(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_c")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_C

    Inst_MIMG__IMAGE_GATHER4_C::~Inst_MIMG__IMAGE_GATHER4_C()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_C

    // --- description from .arch file ---
    // gather 4 single component elements (2x2) with PCF.
    void
    Inst_MIMG__IMAGE_GATHER4_C::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_C_CL class methods ---

    Inst_MIMG__IMAGE_GATHER4_C_CL::Inst_MIMG__IMAGE_GATHER4_C_CL(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_c_cl")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_C_CL

    Inst_MIMG__IMAGE_GATHER4_C_CL::~Inst_MIMG__IMAGE_GATHER4_C_CL()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_C_CL

    // --- description from .arch file ---
    // gather 4 single component elements (2x2) with user LOD clamp and PCF.
    void
    Inst_MIMG__IMAGE_GATHER4_C_CL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_C_L class methods ---

    Inst_MIMG__IMAGE_GATHER4_C_L::Inst_MIMG__IMAGE_GATHER4_C_L(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_c_l")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_C_L

    Inst_MIMG__IMAGE_GATHER4_C_L::~Inst_MIMG__IMAGE_GATHER4_C_L()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_C_L

    // --- description from .arch file ---
    // gather 4 single component elements (2x2) with user LOD and PCF.
    void
    Inst_MIMG__IMAGE_GATHER4_C_L::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_C_B class methods ---

    Inst_MIMG__IMAGE_GATHER4_C_B::Inst_MIMG__IMAGE_GATHER4_C_B(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_c_b")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_C_B

    Inst_MIMG__IMAGE_GATHER4_C_B::~Inst_MIMG__IMAGE_GATHER4_C_B()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_C_B

    // --- description from .arch file ---
    // gather 4 single component elements (2x2) with user bias and PCF.
    void
    Inst_MIMG__IMAGE_GATHER4_C_B::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_C_B_CL class methods ---

    Inst_MIMG__IMAGE_GATHER4_C_B_CL::Inst_MIMG__IMAGE_GATHER4_C_B_CL(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_c_b_cl")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_C_B_CL

    Inst_MIMG__IMAGE_GATHER4_C_B_CL::~Inst_MIMG__IMAGE_GATHER4_C_B_CL()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_C_B_CL

    // --- description from .arch file ---
    // gather 4 single component elements (2x2) with user bias, clamp and PCF.
    void
    Inst_MIMG__IMAGE_GATHER4_C_B_CL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_C_LZ class methods ---

    Inst_MIMG__IMAGE_GATHER4_C_LZ::Inst_MIMG__IMAGE_GATHER4_C_LZ(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_c_lz")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_C_LZ

    Inst_MIMG__IMAGE_GATHER4_C_LZ::~Inst_MIMG__IMAGE_GATHER4_C_LZ()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_C_LZ

    // --- description from .arch file ---
    // gather 4 single component elements (2x2) at level 0, with PCF.
    void
    Inst_MIMG__IMAGE_GATHER4_C_LZ::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_O class methods ---

    Inst_MIMG__IMAGE_GATHER4_O::Inst_MIMG__IMAGE_GATHER4_O(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_O

    Inst_MIMG__IMAGE_GATHER4_O::~Inst_MIMG__IMAGE_GATHER4_O()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_O

    // --- description from .arch file ---
    // GATHER4, with user offsets.
    void
    Inst_MIMG__IMAGE_GATHER4_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_CL_O class methods ---

    Inst_MIMG__IMAGE_GATHER4_CL_O::Inst_MIMG__IMAGE_GATHER4_CL_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_cl_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_CL_O

    Inst_MIMG__IMAGE_GATHER4_CL_O::~Inst_MIMG__IMAGE_GATHER4_CL_O()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_CL_O

    // --- description from .arch file ---
    // GATHER4_CL, with user offsets.
    void
    Inst_MIMG__IMAGE_GATHER4_CL_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_L_O class methods ---

    Inst_MIMG__IMAGE_GATHER4_L_O::Inst_MIMG__IMAGE_GATHER4_L_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_l_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_L_O

    Inst_MIMG__IMAGE_GATHER4_L_O::~Inst_MIMG__IMAGE_GATHER4_L_O()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_L_O

    // --- description from .arch file ---
    // GATHER4_L, with user offsets.
    void
    Inst_MIMG__IMAGE_GATHER4_L_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_B_O class methods ---

    Inst_MIMG__IMAGE_GATHER4_B_O::Inst_MIMG__IMAGE_GATHER4_B_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_b_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_B_O

    Inst_MIMG__IMAGE_GATHER4_B_O::~Inst_MIMG__IMAGE_GATHER4_B_O()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_B_O

    // --- description from .arch file ---
    // GATHER4_B, with user offsets.
    void
    Inst_MIMG__IMAGE_GATHER4_B_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_B_CL_O class methods ---

    Inst_MIMG__IMAGE_GATHER4_B_CL_O::Inst_MIMG__IMAGE_GATHER4_B_CL_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_b_cl_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_B_CL_O

    Inst_MIMG__IMAGE_GATHER4_B_CL_O::~Inst_MIMG__IMAGE_GATHER4_B_CL_O()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_B_CL_O

    // --- description from .arch file ---
    // GATHER4_B_CL, with user offsets.
    void
    Inst_MIMG__IMAGE_GATHER4_B_CL_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_LZ_O class methods ---

    Inst_MIMG__IMAGE_GATHER4_LZ_O::Inst_MIMG__IMAGE_GATHER4_LZ_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_lz_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_LZ_O

    Inst_MIMG__IMAGE_GATHER4_LZ_O::~Inst_MIMG__IMAGE_GATHER4_LZ_O()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_LZ_O

    // --- description from .arch file ---
    // GATHER4_LZ, with user offsets.
    void
    Inst_MIMG__IMAGE_GATHER4_LZ_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_C_O class methods ---

    Inst_MIMG__IMAGE_GATHER4_C_O::Inst_MIMG__IMAGE_GATHER4_C_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_c_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_C_O

    Inst_MIMG__IMAGE_GATHER4_C_O::~Inst_MIMG__IMAGE_GATHER4_C_O()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_C_O

    // --- description from .arch file ---
    // GATHER4_C, with user offsets.
    void
    Inst_MIMG__IMAGE_GATHER4_C_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_C_CL_O class methods ---

    Inst_MIMG__IMAGE_GATHER4_C_CL_O::Inst_MIMG__IMAGE_GATHER4_C_CL_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_c_cl_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_C_CL_O

    Inst_MIMG__IMAGE_GATHER4_C_CL_O::~Inst_MIMG__IMAGE_GATHER4_C_CL_O()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_C_CL_O

    // --- description from .arch file ---
    // GATHER4_C_CL, with user offsets.
    void
    Inst_MIMG__IMAGE_GATHER4_C_CL_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_C_L_O class methods ---

    Inst_MIMG__IMAGE_GATHER4_C_L_O::Inst_MIMG__IMAGE_GATHER4_C_L_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_c_l_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_C_L_O

    Inst_MIMG__IMAGE_GATHER4_C_L_O::~Inst_MIMG__IMAGE_GATHER4_C_L_O()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_C_L_O

    // --- description from .arch file ---
    // GATHER4_C_L, with user offsets.
    void
    Inst_MIMG__IMAGE_GATHER4_C_L_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_C_B_O class methods ---

    Inst_MIMG__IMAGE_GATHER4_C_B_O::Inst_MIMG__IMAGE_GATHER4_C_B_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_c_b_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_C_B_O

    Inst_MIMG__IMAGE_GATHER4_C_B_O::~Inst_MIMG__IMAGE_GATHER4_C_B_O()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_C_B_O

    // --- description from .arch file ---
    // GATHER4_B, with user offsets.
    void
    Inst_MIMG__IMAGE_GATHER4_C_B_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_C_B_CL_O class methods ---

    Inst_MIMG__IMAGE_GATHER4_C_B_CL_O::Inst_MIMG__IMAGE_GATHER4_C_B_CL_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_c_b_cl_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_C_B_CL_O

    Inst_MIMG__IMAGE_GATHER4_C_B_CL_O::~Inst_MIMG__IMAGE_GATHER4_C_B_CL_O()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_C_B_CL_O

    // --- description from .arch file ---
    // GATHER4_B_CL, with user offsets.
    void
    Inst_MIMG__IMAGE_GATHER4_C_B_CL_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GATHER4_C_LZ_O class methods ---

    Inst_MIMG__IMAGE_GATHER4_C_LZ_O::Inst_MIMG__IMAGE_GATHER4_C_LZ_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_gather4_c_lz_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GATHER4_C_LZ_O

    Inst_MIMG__IMAGE_GATHER4_C_LZ_O::~Inst_MIMG__IMAGE_GATHER4_C_LZ_O()
    {
    } // ~Inst_MIMG__IMAGE_GATHER4_C_LZ_O

    // --- description from .arch file ---
    // GATHER4_C_LZ, with user offsets.
    void
    Inst_MIMG__IMAGE_GATHER4_C_LZ_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_GET_LOD class methods ---

    Inst_MIMG__IMAGE_GET_LOD::Inst_MIMG__IMAGE_GET_LOD(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_get_lod")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_GET_LOD

    Inst_MIMG__IMAGE_GET_LOD::~Inst_MIMG__IMAGE_GET_LOD()
    {
    } // ~Inst_MIMG__IMAGE_GET_LOD

    // --- description from .arch file ---
    // Return calculated LOD. Vdata gets 2 32bit integer values: { rawLOD,
    // ---  clampedLOD }.
    void
    Inst_MIMG__IMAGE_GET_LOD::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_CD class methods ---

    Inst_MIMG__IMAGE_SAMPLE_CD::Inst_MIMG__IMAGE_SAMPLE_CD(InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_cd")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_CD

    Inst_MIMG__IMAGE_SAMPLE_CD::~Inst_MIMG__IMAGE_SAMPLE_CD()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_CD

    // --- description from .arch file ---
    // sample texture map, with user derivatives (LOD per quad)
    void
    Inst_MIMG__IMAGE_SAMPLE_CD::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_CD_CL class methods ---

    Inst_MIMG__IMAGE_SAMPLE_CD_CL::Inst_MIMG__IMAGE_SAMPLE_CD_CL(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_cd_cl")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_CD_CL

    Inst_MIMG__IMAGE_SAMPLE_CD_CL::~Inst_MIMG__IMAGE_SAMPLE_CD_CL()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_CD_CL

    // --- description from .arch file ---
    // sample texture map, with LOD clamp specified in shader, with user
    // ---  derivatives (LOD per quad).
    void
    Inst_MIMG__IMAGE_SAMPLE_CD_CL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_CD class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_CD::Inst_MIMG__IMAGE_SAMPLE_C_CD(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_cd")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_CD

    Inst_MIMG__IMAGE_SAMPLE_C_CD::~Inst_MIMG__IMAGE_SAMPLE_C_CD()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_CD

    // --- description from .arch file ---
    // SAMPLE_C, with user derivatives (LOD per quad).
    void
    Inst_MIMG__IMAGE_SAMPLE_C_CD::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_CD_CL class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_CD_CL::Inst_MIMG__IMAGE_SAMPLE_C_CD_CL(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_cd_cl")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_CD_CL

    Inst_MIMG__IMAGE_SAMPLE_C_CD_CL::~Inst_MIMG__IMAGE_SAMPLE_C_CD_CL()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_CD_CL

    // --- description from .arch file ---
    // SAMPLE_C, with LOD clamp specified in shader, with user derivatives
    // (LOD per quad).
    void
    Inst_MIMG__IMAGE_SAMPLE_C_CD_CL::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_CD_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_CD_O::Inst_MIMG__IMAGE_SAMPLE_CD_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_cd_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_CD_O

    Inst_MIMG__IMAGE_SAMPLE_CD_O::~Inst_MIMG__IMAGE_SAMPLE_CD_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_CD_O

    // --- description from .arch file ---
    // SAMPLE_O, with user derivatives (LOD per quad).
    void
    Inst_MIMG__IMAGE_SAMPLE_CD_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_CD_CL_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_CD_CL_O::Inst_MIMG__IMAGE_SAMPLE_CD_CL_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_cd_cl_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_CD_CL_O

    Inst_MIMG__IMAGE_SAMPLE_CD_CL_O::~Inst_MIMG__IMAGE_SAMPLE_CD_CL_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_CD_CL_O

    // --- description from .arch file ---
    // SAMPLE_O, with LOD clamp specified in shader, with user derivatives
    // (LOD per quad).
    void
    Inst_MIMG__IMAGE_SAMPLE_CD_CL_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_CD_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_CD_O::Inst_MIMG__IMAGE_SAMPLE_C_CD_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_cd_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_CD_O

    Inst_MIMG__IMAGE_SAMPLE_C_CD_O::~Inst_MIMG__IMAGE_SAMPLE_C_CD_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_CD_O

    // --- description from .arch file ---
    // SAMPLE_C_O, with user derivatives (LOD per quad).
    void
    Inst_MIMG__IMAGE_SAMPLE_C_CD_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_MIMG__IMAGE_SAMPLE_C_CD_CL_O class methods ---

    Inst_MIMG__IMAGE_SAMPLE_C_CD_CL_O::Inst_MIMG__IMAGE_SAMPLE_C_CD_CL_O(
          InFmt_MIMG *iFmt)
        : Inst_MIMG(iFmt, "image_sample_c_cd_cl_o")
    {
        setFlag(GlobalSegment);
    } // Inst_MIMG__IMAGE_SAMPLE_C_CD_CL_O

    Inst_MIMG__IMAGE_SAMPLE_C_CD_CL_O::~Inst_MIMG__IMAGE_SAMPLE_C_CD_CL_O()
    {
    } // ~Inst_MIMG__IMAGE_SAMPLE_C_CD_CL_O

    // --- description from .arch file ---
    // SAMPLE_C_O, with LOD clamp specified in shader, with user derivatives
    // (LOD per quad).
    void
    Inst_MIMG__IMAGE_SAMPLE_C_CD_CL_O::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_EXP__EXP class methods ---

    Inst_EXP__EXP::Inst_EXP__EXP(InFmt_EXP *iFmt)
        : Inst_EXP(iFmt, "exp")
    {
    } // Inst_EXP__EXP

    Inst_EXP__EXP::~Inst_EXP__EXP()
    {
    } // ~Inst_EXP__EXP

    // --- description from .arch file ---
    // Export through SX.
    void
    Inst_EXP__EXP::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_LOAD_UBYTE class methods ---

    Inst_FLAT__FLAT_LOAD_UBYTE::Inst_FLAT__FLAT_LOAD_UBYTE(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_load_ubyte")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_FLAT__FLAT_LOAD_UBYTE

    Inst_FLAT__FLAT_LOAD_UBYTE::~Inst_FLAT__FLAT_LOAD_UBYTE()
    {
    } // ~Inst_FLAT__FLAT_LOAD_UBYTE

    // --- description from .arch file ---
    // Untyped buffer load unsigned byte (zero extend to VGPR destination).
    void
    Inst_FLAT__FLAT_LOAD_UBYTE::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_LOAD_UBYTE::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<VecElemU8>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_LOAD_UBYTE::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst(gpuDynInst, extData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst[lane] = (VecElemU32)((reinterpret_cast<VecElemU8*>(
                    gpuDynInst->d_data))[lane]);
            }
        }
        vdst.write();
    } // execute
    // --- Inst_FLAT__FLAT_LOAD_SBYTE class methods ---

    Inst_FLAT__FLAT_LOAD_SBYTE::Inst_FLAT__FLAT_LOAD_SBYTE(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_load_sbyte")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_FLAT__FLAT_LOAD_SBYTE

    Inst_FLAT__FLAT_LOAD_SBYTE::~Inst_FLAT__FLAT_LOAD_SBYTE()
    {
    } // ~Inst_FLAT__FLAT_LOAD_SBYTE

    // --- description from .arch file ---
    // Untyped buffer load signed byte (sign extend to VGPR destination).
    void
    Inst_FLAT__FLAT_LOAD_SBYTE::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_FLAT__FLAT_LOAD_SBYTE::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_FLAT__FLAT_LOAD_SBYTE::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_FLAT__FLAT_LOAD_USHORT class methods ---

    Inst_FLAT__FLAT_LOAD_USHORT::Inst_FLAT__FLAT_LOAD_USHORT(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_load_ushort")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_FLAT__FLAT_LOAD_USHORT

    Inst_FLAT__FLAT_LOAD_USHORT::~Inst_FLAT__FLAT_LOAD_USHORT()
    {
    } // ~Inst_FLAT__FLAT_LOAD_USHORT

    // --- description from .arch file ---
    // Untyped buffer load unsigned short (zero extend to VGPR destination).
    void
    Inst_FLAT__FLAT_LOAD_USHORT::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_LOAD_USHORT::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<VecElemU16>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_LOAD_USHORT::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst(gpuDynInst, extData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst[lane] = (VecElemU32)((reinterpret_cast<VecElemU16*>(
                    gpuDynInst->d_data))[lane]);
            }
        }
        vdst.write();
    } // execute

    // --- Inst_FLAT__FLAT_LOAD_SSHORT class methods ---

    Inst_FLAT__FLAT_LOAD_SSHORT::Inst_FLAT__FLAT_LOAD_SSHORT(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_load_sshort")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_FLAT__FLAT_LOAD_SSHORT

    Inst_FLAT__FLAT_LOAD_SSHORT::~Inst_FLAT__FLAT_LOAD_SSHORT()
    {
    } // ~Inst_FLAT__FLAT_LOAD_SSHORT

    // --- description from .arch file ---
    // Untyped buffer load signed short (sign extend to VGPR destination).
    void
    Inst_FLAT__FLAT_LOAD_SSHORT::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute

    void
    Inst_FLAT__FLAT_LOAD_SSHORT::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
    } // initiateAcc

    void
    Inst_FLAT__FLAT_LOAD_SSHORT::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_FLAT__FLAT_LOAD_DWORD class methods ---

    Inst_FLAT__FLAT_LOAD_DWORD::Inst_FLAT__FLAT_LOAD_DWORD(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_load_dword")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_FLAT__FLAT_LOAD_DWORD

    Inst_FLAT__FLAT_LOAD_DWORD::~Inst_FLAT__FLAT_LOAD_DWORD()
    {
    } // ~Inst_FLAT__FLAT_LOAD_DWORD

    // --- description from .arch file ---
    // Untyped buffer load dword.
    void
    Inst_FLAT__FLAT_LOAD_DWORD::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_LOAD_DWORD::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<VecElemU32>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_LOAD_DWORD::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst(gpuDynInst, extData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst[lane] = (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane];
            }
        }
        vdst.write();
    } // completeAcc
    // --- Inst_FLAT__FLAT_LOAD_DWORDX2 class methods ---

    Inst_FLAT__FLAT_LOAD_DWORDX2::Inst_FLAT__FLAT_LOAD_DWORDX2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_load_dwordx2")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_FLAT__FLAT_LOAD_DWORDX2

    Inst_FLAT__FLAT_LOAD_DWORDX2::~Inst_FLAT__FLAT_LOAD_DWORDX2()
    {
    } // ~Inst_FLAT__FLAT_LOAD_DWORDX2

    // --- description from .arch file ---
    // Untyped buffer load 2 dwords.
    void
    Inst_FLAT__FLAT_LOAD_DWORDX2::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_LOAD_DWORDX2::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<VecElemU64>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_LOAD_DWORDX2::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU64 vdst(gpuDynInst, extData.VDST);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst[lane] = (reinterpret_cast<VecElemU64*>(
                    gpuDynInst->d_data))[lane];
            }
        }
        vdst.write();
    } // completeAcc
    // --- Inst_FLAT__FLAT_LOAD_DWORDX3 class methods ---

    Inst_FLAT__FLAT_LOAD_DWORDX3::Inst_FLAT__FLAT_LOAD_DWORDX3(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_load_dwordx3")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_FLAT__FLAT_LOAD_DWORDX3

    Inst_FLAT__FLAT_LOAD_DWORDX3::~Inst_FLAT__FLAT_LOAD_DWORDX3()
    {
    } // ~Inst_FLAT__FLAT_LOAD_DWORDX3

    // --- description from .arch file ---
    // Untyped buffer load 3 dwords.
    void
    Inst_FLAT__FLAT_LOAD_DWORDX3::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_LOAD_DWORDX3::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<3>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_LOAD_DWORDX3::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst0(gpuDynInst, extData.VDST);
        VecOperandU32 vdst1(gpuDynInst, extData.VDST + 1);
        VecOperandU32 vdst2(gpuDynInst, extData.VDST + 2);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst0[lane] = (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 3];
                vdst1[lane] = (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 3 + 1];
                vdst2[lane] = (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 3 + 2];
            }
        }

        vdst0.write();
        vdst1.write();
        vdst2.write();
    } // completeAcc
    // --- Inst_FLAT__FLAT_LOAD_DWORDX4 class methods ---

    Inst_FLAT__FLAT_LOAD_DWORDX4::Inst_FLAT__FLAT_LOAD_DWORDX4(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_load_dwordx4")
    {
        setFlag(MemoryRef);
        setFlag(Load);
    } // Inst_FLAT__FLAT_LOAD_DWORDX4

    Inst_FLAT__FLAT_LOAD_DWORDX4::~Inst_FLAT__FLAT_LOAD_DWORDX4()
    {
    } // ~Inst_FLAT__FLAT_LOAD_DWORDX4

    // --- description from .arch file ---
    // Untyped buffer load 4 dwords.
    void
    Inst_FLAT__FLAT_LOAD_DWORDX4::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);

        addr.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_LOAD_DWORDX4::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemRead<4>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_LOAD_DWORDX4::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        VecOperandU32 vdst0(gpuDynInst, extData.VDST);
        VecOperandU32 vdst1(gpuDynInst, extData.VDST + 1);
        VecOperandU32 vdst2(gpuDynInst, extData.VDST + 2);
        VecOperandU32 vdst3(gpuDynInst, extData.VDST + 3);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                vdst0[lane] = (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 4];
                vdst1[lane] = (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 4 + 1];
                vdst2[lane] = (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 4 + 2];
                vdst3[lane] = (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 4 + 3];
            }
        }

        vdst0.write();
        vdst1.write();
        vdst2.write();
        vdst3.write();
    } // completeAcc
    // --- Inst_FLAT__FLAT_STORE_BYTE class methods ---

    Inst_FLAT__FLAT_STORE_BYTE::Inst_FLAT__FLAT_STORE_BYTE(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_store_byte")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_FLAT__FLAT_STORE_BYTE

    Inst_FLAT__FLAT_STORE_BYTE::~Inst_FLAT__FLAT_STORE_BYTE()
    {
    } // ~Inst_FLAT__FLAT_STORE_BYTE

    // --- description from .arch file ---
    // Untyped buffer store byte.
    void
    Inst_FLAT__FLAT_STORE_BYTE::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            wf->decExpInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU8 data(gpuDynInst, extData.DATA);

        addr.read();
        data.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU8*>(gpuDynInst->d_data))[lane]
                    = data[lane];
            }
        }

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_STORE_BYTE::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<VecElemU8>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_STORE_BYTE::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // execute
    // --- Inst_FLAT__FLAT_STORE_SHORT class methods ---

    Inst_FLAT__FLAT_STORE_SHORT::Inst_FLAT__FLAT_STORE_SHORT(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_store_short")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_FLAT__FLAT_STORE_SHORT

    Inst_FLAT__FLAT_STORE_SHORT::~Inst_FLAT__FLAT_STORE_SHORT()
    {
    } // ~Inst_FLAT__FLAT_STORE_SHORT

    // --- description from .arch file ---
    // Untyped buffer store short.
    void
    Inst_FLAT__FLAT_STORE_SHORT::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            wf->decExpInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU16 data(gpuDynInst, extData.DATA);

        addr.read();
        data.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU16*>(gpuDynInst->d_data))[lane]
                    = data[lane];
            }
        }

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_STORE_SHORT::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<VecElemU16>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_STORE_SHORT::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_FLAT__FLAT_STORE_DWORD class methods ---

    Inst_FLAT__FLAT_STORE_DWORD::Inst_FLAT__FLAT_STORE_DWORD(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_store_dword")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_FLAT__FLAT_STORE_DWORD

    Inst_FLAT__FLAT_STORE_DWORD::~Inst_FLAT__FLAT_STORE_DWORD()
    {
    } // ~Inst_FLAT__FLAT_STORE_DWORD

    // --- description from .arch file ---
    // Untyped buffer store dword.
    void
    Inst_FLAT__FLAT_STORE_DWORD::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            wf->decExpInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU32 data(gpuDynInst, extData.DATA);

        addr.read();
        data.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(gpuDynInst->d_data))[lane]
                    = data[lane];
            }
        }

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_STORE_DWORD::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<VecElemU32>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_STORE_DWORD::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_FLAT__FLAT_STORE_DWORDX2 class methods ---

    Inst_FLAT__FLAT_STORE_DWORDX2::Inst_FLAT__FLAT_STORE_DWORDX2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_store_dwordx2")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_FLAT__FLAT_STORE_DWORDX2

    Inst_FLAT__FLAT_STORE_DWORDX2::~Inst_FLAT__FLAT_STORE_DWORDX2()
    {
    } // ~Inst_FLAT__FLAT_STORE_DWORDX2

    // --- description from .arch file ---
    // Untyped buffer store 2 dwords.
    void
    Inst_FLAT__FLAT_STORE_DWORDX2::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            wf->decExpInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU64 data(gpuDynInst, extData.DATA);

        addr.read();
        data.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU64*>(gpuDynInst->d_data))[lane]
                    = data[lane];
            }
        }

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_STORE_DWORDX2::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<VecElemU64>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_STORE_DWORDX2::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_FLAT__FLAT_STORE_DWORDX3 class methods ---

    Inst_FLAT__FLAT_STORE_DWORDX3::Inst_FLAT__FLAT_STORE_DWORDX3(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_store_dwordx3")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_FLAT__FLAT_STORE_DWORDX3

    Inst_FLAT__FLAT_STORE_DWORDX3::~Inst_FLAT__FLAT_STORE_DWORDX3()
    {
    } // ~Inst_FLAT__FLAT_STORE_DWORDX3

    // --- description from .arch file ---
    // Untyped buffer store 3 dwords.
    void
    Inst_FLAT__FLAT_STORE_DWORDX3::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            wf->decExpInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU32 data0(gpuDynInst, extData.DATA);
        ConstVecOperandU32 data1(gpuDynInst, extData.DATA + 1);
        ConstVecOperandU32 data2(gpuDynInst, extData.DATA + 2);

        addr.read();
        data0.read();
        data1.read();
        data2.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 3] = data0[lane];
                (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 3 + 1] = data1[lane];
                (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 3 + 2] = data2[lane];
            }
        }

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_STORE_DWORDX3::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<3>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_STORE_DWORDX3::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_FLAT__FLAT_STORE_DWORDX4 class methods ---

    Inst_FLAT__FLAT_STORE_DWORDX4::Inst_FLAT__FLAT_STORE_DWORDX4(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_store_dwordx4")
    {
        setFlag(MemoryRef);
        setFlag(Store);
    } // Inst_FLAT__FLAT_STORE_DWORDX4

    Inst_FLAT__FLAT_STORE_DWORDX4::~Inst_FLAT__FLAT_STORE_DWORDX4()
    {
    } // ~Inst_FLAT__FLAT_STORE_DWORDX4

    // --- description from .arch file ---
    // Untyped buffer store 4 dwords.
    void
    Inst_FLAT__FLAT_STORE_DWORDX4::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            wf->decExpInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU32 data0(gpuDynInst, extData.DATA);
        ConstVecOperandU32 data1(gpuDynInst, extData.DATA + 1);
        ConstVecOperandU32 data2(gpuDynInst, extData.DATA + 2);
        ConstVecOperandU32 data3(gpuDynInst, extData.DATA + 3);

        addr.read();
        data0.read();
        data1.read();
        data2.read();
        data3.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 4] = data0[lane];
                (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 4 + 1] = data1[lane];
                (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 4 + 2] = data2[lane];
                (reinterpret_cast<VecElemU32*>(
                    gpuDynInst->d_data))[lane * 4 + 3] = data3[lane];
            }
        }

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_STORE_DWORDX4::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initMemWrite<4>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_STORE_DWORDX4::completeAcc(GPUDynInstPtr gpuDynInst)
    {
    } // completeAcc
    // --- Inst_FLAT__FLAT_ATOMIC_SWAP class methods ---

    Inst_FLAT__FLAT_ATOMIC_SWAP::Inst_FLAT__FLAT_ATOMIC_SWAP(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_swap")
    {
        setFlag(AtomicExch);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_SWAP

    Inst_FLAT__FLAT_ATOMIC_SWAP::~Inst_FLAT__FLAT_ATOMIC_SWAP()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_SWAP

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = DATA;
    // RETURN_DATA = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_SWAP::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU32 data(gpuDynInst, extData.DATA);

        addr.read();
        data.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(gpuDynInst->a_data))[lane]
                    = data[lane];
            }
        }

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_ATOMIC_SWAP::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initAtomicAccess<VecElemU32>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_ATOMIC_SWAP::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        if (isAtomicRet()) {
            VecOperandU32 vdst(gpuDynInst, extData.VDST);

            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (gpuDynInst->exec_mask[lane]) {
                    vdst[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane];
                }
            }

            vdst.write();
        }
    } // completeAcc

    // --- Inst_FLAT__FLAT_ATOMIC_CMPSWAP class methods ---

    Inst_FLAT__FLAT_ATOMIC_CMPSWAP
        ::Inst_FLAT__FLAT_ATOMIC_CMPSWAP(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_cmpswap")
    {
        setFlag(AtomicCAS);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_CMPSWAP

    Inst_FLAT__FLAT_ATOMIC_CMPSWAP::~Inst_FLAT__FLAT_ATOMIC_CMPSWAP()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_CMPSWAP

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // src = DATA[0];
    // cmp = DATA[1];
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_CMPSWAP::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU32 data(gpuDynInst, extData.DATA);
        ConstVecOperandU32 cmp(gpuDynInst, extData.DATA + 1);

        addr.read();
        data.read();
        cmp.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(gpuDynInst->x_data))[lane]
                    = data[lane];
                (reinterpret_cast<VecElemU32*>(gpuDynInst->a_data))[lane]
                    = cmp[lane];
            }
        }

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_ATOMIC_CMPSWAP::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initAtomicAccess<VecElemU32>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_ATOMIC_CMPSWAP::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        if (isAtomicRet()) {
            VecOperandU32 vdst(gpuDynInst, extData.VDST);

            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (gpuDynInst->exec_mask[lane]) {
                    vdst[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane];
                }
            }

            vdst.write();
        }
    } // completeAcc
    // --- Inst_FLAT__FLAT_ATOMIC_ADD class methods ---

    Inst_FLAT__FLAT_ATOMIC_ADD::Inst_FLAT__FLAT_ATOMIC_ADD(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_add")
    {
        setFlag(AtomicAdd);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_ADD

    Inst_FLAT__FLAT_ATOMIC_ADD::~Inst_FLAT__FLAT_ATOMIC_ADD()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_ADD

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] += DATA;
    // RETURN_DATA = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_ADD::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU32 data(gpuDynInst, extData.DATA);

        addr.read();
        data.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU32*>(gpuDynInst->a_data))[lane]
                    = data[lane];
            }
        }

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_ATOMIC_ADD::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initAtomicAccess<VecElemU32>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_ATOMIC_ADD::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        if (isAtomicRet()) {
            VecOperandU32 vdst(gpuDynInst, extData.VDST);

            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (gpuDynInst->exec_mask[lane]) {
                    vdst[lane] = (reinterpret_cast<VecElemU32*>(
                        gpuDynInst->d_data))[lane];
                }
            }

            vdst.write();
        }
    } // completeAcc
    // --- Inst_FLAT__FLAT_ATOMIC_SUB class methods ---

    Inst_FLAT__FLAT_ATOMIC_SUB::Inst_FLAT__FLAT_ATOMIC_SUB(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_sub")
    {
        setFlag(AtomicSub);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_SUB

    Inst_FLAT__FLAT_ATOMIC_SUB::~Inst_FLAT__FLAT_ATOMIC_SUB()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_SUB

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_SUB::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_SMIN class methods ---

    Inst_FLAT__FLAT_ATOMIC_SMIN::Inst_FLAT__FLAT_ATOMIC_SMIN(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_smin")
    {
        setFlag(AtomicMin);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_SMIN

    Inst_FLAT__FLAT_ATOMIC_SMIN::~Inst_FLAT__FLAT_ATOMIC_SMIN()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_SMIN

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA < tmp) ? DATA : tmp (signed compare);
    // RETURN_DATA = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_SMIN::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_UMIN class methods ---

    Inst_FLAT__FLAT_ATOMIC_UMIN::Inst_FLAT__FLAT_ATOMIC_UMIN(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_umin")
    {
        setFlag(AtomicMin);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_UMIN

    Inst_FLAT__FLAT_ATOMIC_UMIN::~Inst_FLAT__FLAT_ATOMIC_UMIN()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_UMIN

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA < tmp) ? DATA : tmp (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_UMIN::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_SMAX class methods ---

    Inst_FLAT__FLAT_ATOMIC_SMAX::Inst_FLAT__FLAT_ATOMIC_SMAX(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_smax")
    {
        setFlag(AtomicMax);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_SMAX

    Inst_FLAT__FLAT_ATOMIC_SMAX::~Inst_FLAT__FLAT_ATOMIC_SMAX()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_SMAX

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA > tmp) ? DATA : tmp (signed compare);
    // RETURN_DATA = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_SMAX::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_UMAX class methods ---

    Inst_FLAT__FLAT_ATOMIC_UMAX::Inst_FLAT__FLAT_ATOMIC_UMAX(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_umax")
    {
        setFlag(AtomicMax);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_UMAX

    Inst_FLAT__FLAT_ATOMIC_UMAX::~Inst_FLAT__FLAT_ATOMIC_UMAX()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_UMAX

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (DATA > tmp) ? DATA : tmp (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_UMAX::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_AND class methods ---

    Inst_FLAT__FLAT_ATOMIC_AND::Inst_FLAT__FLAT_ATOMIC_AND(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_and")
    {
        setFlag(AtomicAnd);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_AND

    Inst_FLAT__FLAT_ATOMIC_AND::~Inst_FLAT__FLAT_ATOMIC_AND()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_AND

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] &= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_AND::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_OR class methods ---

    Inst_FLAT__FLAT_ATOMIC_OR::Inst_FLAT__FLAT_ATOMIC_OR(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_or")
    {
        setFlag(AtomicOr);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_OR

    Inst_FLAT__FLAT_ATOMIC_OR::~Inst_FLAT__FLAT_ATOMIC_OR()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_OR

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] |= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_OR::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_XOR class methods ---

    Inst_FLAT__FLAT_ATOMIC_XOR::Inst_FLAT__FLAT_ATOMIC_XOR(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_xor")
    {
        setFlag(AtomicXor);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_XOR

    Inst_FLAT__FLAT_ATOMIC_XOR::~Inst_FLAT__FLAT_ATOMIC_XOR()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_XOR

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] ^= DATA;
    // RETURN_DATA = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_XOR::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_INC class methods ---

    Inst_FLAT__FLAT_ATOMIC_INC::Inst_FLAT__FLAT_ATOMIC_INC(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_inc")
    {
        setFlag(AtomicInc);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_INC

    Inst_FLAT__FLAT_ATOMIC_INC::~Inst_FLAT__FLAT_ATOMIC_INC()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_INC

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp >= DATA) ? 0 : tmp + 1 (unsigned compare);
    // RETURN_DATA = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_INC::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_DEC class methods ---

    Inst_FLAT__FLAT_ATOMIC_DEC::Inst_FLAT__FLAT_ATOMIC_DEC(InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_dec")
    {
        setFlag(AtomicDec);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_DEC

    Inst_FLAT__FLAT_ATOMIC_DEC::~Inst_FLAT__FLAT_ATOMIC_DEC()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_DEC

    // --- description from .arch file ---
    // 32b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp == 0 || tmp > DATA) ? DATA : tmp - 1
    // (unsigned compare); RETURN_DATA = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_DEC::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_SWAP_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_SWAP_X2::Inst_FLAT__FLAT_ATOMIC_SWAP_X2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_swap_x2")
    {
        setFlag(AtomicExch);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_SWAP_X2

    Inst_FLAT__FLAT_ATOMIC_SWAP_X2::~Inst_FLAT__FLAT_ATOMIC_SWAP_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_SWAP_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_SWAP_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_CMPSWAP_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_CMPSWAP_X2::Inst_FLAT__FLAT_ATOMIC_CMPSWAP_X2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_cmpswap_x2")
    {
        setFlag(AtomicCAS);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_CMPSWAP_X2

    Inst_FLAT__FLAT_ATOMIC_CMPSWAP_X2::~Inst_FLAT__FLAT_ATOMIC_CMPSWAP_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_CMPSWAP_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // src = DATA[0:1];
    // cmp = DATA[2:3];
    // MEM[ADDR] = (tmp == cmp) ? src : tmp;
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_CMPSWAP_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU64 data(gpuDynInst, extData.DATA);
        ConstVecOperandU64 cmp(gpuDynInst, extData.DATA + 2);

        addr.read();
        data.read();
        cmp.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU64*>(gpuDynInst->x_data))[lane]
                    = data[lane];
                (reinterpret_cast<VecElemU64*>(gpuDynInst->a_data))[lane]
                    = cmp[lane];
            }
        }

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_ATOMIC_CMPSWAP_X2::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initAtomicAccess<VecElemU64>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_ATOMIC_CMPSWAP_X2::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        if (isAtomicRet()) {
            VecOperandU64 vdst(gpuDynInst, extData.VDST);

            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (gpuDynInst->exec_mask[lane]) {
                    vdst[lane] = (reinterpret_cast<VecElemU64*>(
                        gpuDynInst->d_data))[lane];
                }
            }

            vdst.write();
        }
    } // completeAcc
    // --- Inst_FLAT__FLAT_ATOMIC_ADD_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_ADD_X2::Inst_FLAT__FLAT_ATOMIC_ADD_X2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_add_x2")
    {
        setFlag(AtomicAdd);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_ADD_X2

    Inst_FLAT__FLAT_ATOMIC_ADD_X2::~Inst_FLAT__FLAT_ATOMIC_ADD_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_ADD_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] += DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_ADD_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        Wavefront *wf = gpuDynInst->wavefront();

        if (gpuDynInst->exec_mask.none() && isFlat()) {
            wf->decVMemInstsIssued();
            wf->decLGKMInstsIssued();
            return;
        }

        gpuDynInst->execUnitId = wf->execUnitId;
        gpuDynInst->latency.init(gpuDynInst->computeUnit());
        gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());

        ConstVecOperandU64 addr(gpuDynInst, extData.ADDR);
        ConstVecOperandU64 data(gpuDynInst, extData.DATA);

        addr.read();
        data.read();

        calcAddr(gpuDynInst, addr, extData.SADDR, instData.OFFSET);

        for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
            if (gpuDynInst->exec_mask[lane]) {
                (reinterpret_cast<VecElemU64*>(gpuDynInst->a_data))[lane]
                    = data[lane];
            }
        }

        issueRequestHelper(gpuDynInst);
    } // execute

    void
    Inst_FLAT__FLAT_ATOMIC_ADD_X2::initiateAcc(GPUDynInstPtr gpuDynInst)
    {
        initAtomicAccess<VecElemU64>(gpuDynInst);
    } // initiateAcc

    void
    Inst_FLAT__FLAT_ATOMIC_ADD_X2::completeAcc(GPUDynInstPtr gpuDynInst)
    {
        if (isAtomicRet()) {
            VecOperandU64 vdst(gpuDynInst, extData.VDST);


            for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                if (gpuDynInst->exec_mask[lane]) {
                    vdst[lane] = (reinterpret_cast<VecElemU64*>(
                        gpuDynInst->d_data))[lane];
                }
            }

            vdst.write();
        }
    } // completeAcc
    // --- Inst_FLAT__FLAT_ATOMIC_SUB_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_SUB_X2::Inst_FLAT__FLAT_ATOMIC_SUB_X2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_sub_x2")
    {
        setFlag(AtomicSub);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_SUB_X2

    Inst_FLAT__FLAT_ATOMIC_SUB_X2::~Inst_FLAT__FLAT_ATOMIC_SUB_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_SUB_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_SUB_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_SMIN_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_SMIN_X2::Inst_FLAT__FLAT_ATOMIC_SMIN_X2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_smin_x2")
    {
        setFlag(AtomicMin);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_SMIN_X2

    Inst_FLAT__FLAT_ATOMIC_SMIN_X2::~Inst_FLAT__FLAT_ATOMIC_SMIN_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_SMIN_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] < tmp) ? DATA[0:1] : tmp (signed compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_SMIN_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_UMIN_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_UMIN_X2::Inst_FLAT__FLAT_ATOMIC_UMIN_X2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_umin_x2")
    {
        setFlag(AtomicMin);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_UMIN_X2

    Inst_FLAT__FLAT_ATOMIC_UMIN_X2::~Inst_FLAT__FLAT_ATOMIC_UMIN_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_UMIN_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] < tmp) ? DATA[0:1] : tmp (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_UMIN_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_SMAX_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_SMAX_X2::Inst_FLAT__FLAT_ATOMIC_SMAX_X2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_smax_x2")
    {
        setFlag(AtomicMax);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_SMAX_X2

    Inst_FLAT__FLAT_ATOMIC_SMAX_X2::~Inst_FLAT__FLAT_ATOMIC_SMAX_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_SMAX_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] > tmp) ? DATA[0:1] : tmp (signed compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_SMAX_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_UMAX_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_UMAX_X2::Inst_FLAT__FLAT_ATOMIC_UMAX_X2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_umax_x2")
    {
        setFlag(AtomicMax);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_UMAX_X2

    Inst_FLAT__FLAT_ATOMIC_UMAX_X2::~Inst_FLAT__FLAT_ATOMIC_UMAX_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_UMAX_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] -= (DATA[0:1] > tmp) ? DATA[0:1] : tmp (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_UMAX_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_AND_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_AND_X2::Inst_FLAT__FLAT_ATOMIC_AND_X2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_and_x2")
    {
        setFlag(AtomicAnd);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_AND_X2

    Inst_FLAT__FLAT_ATOMIC_AND_X2::~Inst_FLAT__FLAT_ATOMIC_AND_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_AND_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] &= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_AND_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_OR_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_OR_X2::Inst_FLAT__FLAT_ATOMIC_OR_X2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_or_x2")
    {
        setFlag(AtomicOr);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_OR_X2

    Inst_FLAT__FLAT_ATOMIC_OR_X2::~Inst_FLAT__FLAT_ATOMIC_OR_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_OR_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] |= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_OR_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_XOR_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_XOR_X2::Inst_FLAT__FLAT_ATOMIC_XOR_X2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_xor_x2")
    {
        setFlag(AtomicXor);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_XOR_X2

    Inst_FLAT__FLAT_ATOMIC_XOR_X2::~Inst_FLAT__FLAT_ATOMIC_XOR_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_XOR_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] ^= DATA[0:1];
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_XOR_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_INC_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_INC_X2::Inst_FLAT__FLAT_ATOMIC_INC_X2(
          InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_inc_x2")
    {
        setFlag(AtomicInc);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_INC_X2

    Inst_FLAT__FLAT_ATOMIC_INC_X2::~Inst_FLAT__FLAT_ATOMIC_INC_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_INC_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp >= DATA[0:1]) ? 0 : tmp + 1 (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_INC_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
    // --- Inst_FLAT__FLAT_ATOMIC_DEC_X2 class methods ---

    Inst_FLAT__FLAT_ATOMIC_DEC_X2::Inst_FLAT__FLAT_ATOMIC_DEC_X2(
        InFmt_FLAT *iFmt)
        : Inst_FLAT(iFmt, "flat_atomic_dec_x2")
    {
        setFlag(AtomicDec);
        if (instData.GLC) {
            setFlag(AtomicReturn);
        } else {
            setFlag(AtomicNoReturn);
        }
        setFlag(MemoryRef);
    } // Inst_FLAT__FLAT_ATOMIC_DEC_X2

    Inst_FLAT__FLAT_ATOMIC_DEC_X2::~Inst_FLAT__FLAT_ATOMIC_DEC_X2()
    {
    } // ~Inst_FLAT__FLAT_ATOMIC_DEC_X2

    // --- description from .arch file ---
    // 64b:
    // tmp = MEM[ADDR];
    // MEM[ADDR] = (tmp == 0 || tmp > DATA[0:1]) ? DATA[0:1] : tmp - 1
    // (unsigned compare);
    // RETURN_DATA[0:1] = tmp.
    void
    Inst_FLAT__FLAT_ATOMIC_DEC_X2::execute(GPUDynInstPtr gpuDynInst)
    {
        panicUnimplemented();
    } // execute
} // namespace VegaISA
} // namespace gem5
