/*
 * Copyright (c) 2016-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/op_encodings.hh"

#include <iomanip>

namespace gem5
{

namespace VegaISA
{
    // --- Inst_SOP2 base class methods ---

    Inst_SOP2::Inst_SOP2(InFmt_SOP2 *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        setFlag(Scalar);

        // copy first instruction DWORD
        instData = iFmt[0];
        if (hasSecondDword(iFmt)) {
            // copy second instruction DWORD into union
            extData = ((MachInst)iFmt)[1];
            _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);
            varSize = 4 + 4;
        } else {
            varSize = 4;
        } // if
    } // Inst_SOP2

    void
    Inst_SOP2::initOperandInfo()
    {
        int opNum = 0;

        // Needed because can't take addr of bitfield
        int reg = instData.SSRC0;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              isScalarReg(instData.SSRC0), false, false);
        opNum++;

        reg = instData.SSRC1;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              isScalarReg(instData.SSRC1), false, false);
        opNum++;

        reg = instData.SDST;
        dstOps.emplace_back(reg, getOperandSize(opNum), false,
                              isScalarReg(instData.SDST), false, false);

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_SOP2::instSize() const
    {
        return varSize;
    } // instSize

    bool
    Inst_SOP2::hasSecondDword(InFmt_SOP2 *iFmt)
    {
        if (iFmt->SSRC0 == REG_SRC_LITERAL)
            return true;

        if (iFmt->SSRC1 == REG_SRC_LITERAL)
            return true;

        return false;
    }

    void
    Inst_SOP2::generateDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode << " ";
        dis_stream << opSelectorToRegSym(instData.SDST) << ", ";

        if (instData.SSRC0 == REG_SRC_LITERAL) {
            dis_stream << "0x" << std::hex << std::setfill('0') << std::setw(8)
                       << _srcLiteral << ", ";
        } else {
            dis_stream << opSelectorToRegSym(instData.SSRC0) << ", ";
        }

        if (instData.SSRC1 == REG_SRC_LITERAL) {
            dis_stream << "0x" << std::hex << std::setfill('0') << std::setw(8)
                       << _srcLiteral;
        } else {
            dis_stream << opSelectorToRegSym(instData.SSRC1);
        }

        disassembly = dis_stream.str();
    }

    // --- Inst_SOPK base class methods ---

    Inst_SOPK::Inst_SOPK(InFmt_SOPK *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        setFlag(Scalar);

        // copy first instruction DWORD
        instData = iFmt[0];
        if (hasSecondDword(iFmt)) {
            // copy second instruction DWORD into union
            extData = ((MachInst)iFmt)[1];
            _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);
            varSize = 4 + 4;
        } else {
            varSize = 4;
        } // if
    } // Inst_SOPK

    Inst_SOPK::~Inst_SOPK()
    {
    } // ~Inst_SOPK

    void
    Inst_SOPK::initOperandInfo()
    {
        int opNum = 0;

        // Needed because can't take addr of bitfield
        int reg = instData.SDST;
        if (numSrcRegOperands() == getNumOperands()) {
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                isScalarReg(reg), false, false);
            opNum++;
        }

        reg = instData.SIMM16;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              false, false, true);
        opNum++;

        if (numDstRegOperands()) {
            reg = instData.SDST;
            dstOps.emplace_back(reg, getOperandSize(opNum), false,
                                  isScalarReg(reg), false, false);
        }

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_SOPK::instSize() const
    {
        return varSize;
    } // instSize

    bool
    Inst_SOPK::hasSecondDword(InFmt_SOPK *iFmt)
    {
        /*
          SOPK can be a 64-bit instruction, i.e., have a second dword:
          S_SETREG_IMM32_B32 writes some or all of the LSBs of a 32-bit
          literal constant into a hardware register;
          the way to detect such special case is to explicitly check the
          opcode (20/0x14)
        */
        if (iFmt->OP == 0x14)
            return true;

        return false;
    }


    void
    Inst_SOPK::generateDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode << " ";

        // S_SETREG_IMM32_B32 is a 64-bit instruction, using a
        // 32-bit literal constant
        if (instData.OP == 0x14) {
            dis_stream << "0x" << std::hex << std::setfill('0')
                    << std::setw(8) << extData.imm_u32 << ", ";
        } else {
            dis_stream << opSelectorToRegSym(instData.SDST) << ", ";
        }

        dis_stream << "0x" << std::hex << std::setfill('0') << std::setw(4)
                     << instData.SIMM16;

        disassembly = dis_stream.str();
    }

    // --- Inst_SOP1 base class methods ---

    Inst_SOP1::Inst_SOP1(InFmt_SOP1 *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        setFlag(Scalar);

        // copy first instruction DWORD
        instData = iFmt[0];
        if (hasSecondDword(iFmt)) {
            // copy second instruction DWORD into union
            extData = ((MachInst)iFmt)[1];
            _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);
            varSize = 4 + 4;
        } else {
            varSize = 4;
        } // if
    } // Inst_SOP1

    Inst_SOP1::~Inst_SOP1()
    {
    } // ~Inst_SOP1

    void
    Inst_SOP1::initOperandInfo()
    {
        int opNum = 0;

        // Needed because can't take addr of bitfield
        int reg = instData.SSRC0;
        if (instData.OP != 0x1C) {
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                  isScalarReg(instData.SSRC0), false, false);
            opNum++;
        }

        reg = instData.SDST;
        dstOps.emplace_back(reg, getOperandSize(opNum), false,
                              isScalarReg(instData.SDST), false, false);

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_SOP1::instSize() const
    {
        return varSize;
    } // instSize

    bool
    Inst_SOP1::hasSecondDword(InFmt_SOP1 *iFmt)
    {
        if (iFmt->SSRC0 == REG_SRC_LITERAL)
            return true;

        return false;
    }

    void
    Inst_SOP1::generateDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode << " ";
        dis_stream << opSelectorToRegSym(instData.SDST) << ", ";

        if (instData.SSRC0 == REG_SRC_LITERAL) {
            dis_stream << "0x" << std::hex << std::setfill('0') << std::setw(8)
                       << extData.imm_u32;
        } else {
            dis_stream << opSelectorToRegSym(instData.SSRC0);
        }

        disassembly = dis_stream.str();
    }

    // --- Inst_SOPC base class methods ---

    Inst_SOPC::Inst_SOPC(InFmt_SOPC *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        setFlag(Scalar);

        // copy first instruction DWORD
        instData = iFmt[0];
        if (hasSecondDword(iFmt)) {
            // copy second instruction DWORD into union
            extData = ((MachInst)iFmt)[1];
            _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);
            varSize = 4 + 4;
        } else {
            varSize = 4;
        } // if
    } // Inst_SOPC

    Inst_SOPC::~Inst_SOPC()
    {
    } // ~Inst_SOPC

    void
    Inst_SOPC::initOperandInfo()
    {
        int opNum = 0;

        // Needed because can't take addr of bitfield
        int reg = instData.SSRC0;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              isScalarReg(instData.SSRC0), false, false);
        opNum++;

        reg = instData.SSRC1;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              isScalarReg(instData.SSRC1), false, false);

    }

    int
    Inst_SOPC::instSize() const
    {
        return varSize;
    } // instSize

    bool
    Inst_SOPC::hasSecondDword(InFmt_SOPC *iFmt)
    {
        if (iFmt->SSRC0 == REG_SRC_LITERAL)
            return true;

        if (iFmt->SSRC1 == REG_SRC_LITERAL)
            return true;

        return false;
    }

    void
    Inst_SOPC::generateDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode << " ";

        if (instData.SSRC0 == REG_SRC_LITERAL) {
            dis_stream << "0x" << std::hex << std::setfill('0') << std::setw(8)
                       << extData.imm_u32;
        } else {
            dis_stream << opSelectorToRegSym(instData.SSRC0) << ", ";
        }

        if (instData.SSRC1 == REG_SRC_LITERAL) {
            dis_stream << "0x" << std::hex << std::setfill('0') << std::setw(8)
                       << extData.imm_u32;
        } else {
            dis_stream << opSelectorToRegSym(instData.SSRC1);
        }

        disassembly = dis_stream.str();
    }

    // --- Inst_SOPP base class methods ---

    Inst_SOPP::Inst_SOPP(InFmt_SOPP *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        setFlag(Scalar);

        // copy first instruction DWORD
        instData = iFmt[0];
    } // Inst_SOPP

    Inst_SOPP::~Inst_SOPP()
    {
    } // ~Inst_SOPP

    void
    Inst_SOPP::initOperandInfo()
    {
        int opNum = 0;


        if (numSrcRegOperands()) {
            // Needed because can't take addr of bitfield
            int reg = instData.SIMM16;
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                  false, false, true);

            opNum++;

            if (readsVCC()) {
                srcOps.emplace_back(REG_VCC_LO, getOperandSize(opNum), true,
                                      true, false, false);
                opNum++;
            }
        }
        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_SOPP::instSize() const
    {
        return 4;
    } // instSize

    void
    Inst_SOPP::generateDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode;

        switch (instData.OP) {
          case 8:
            {
                dis_stream << " ";
                int dest = 4 * instData.SIMM16 + 4;
                dis_stream << "label_" << std::hex << dest;
            }
             break;
          case 12:
            {
                dis_stream << " ";

                int vm_cnt = 0;
                int exp_cnt = 0;
                int lgkm_cnt = 0;

                vm_cnt = bits<uint16_t>(instData.SIMM16, 3, 0);
                exp_cnt = bits<uint16_t>(instData.SIMM16, 6, 4);
                lgkm_cnt = bits<uint16_t>(instData.SIMM16, 11, 8);

                // if the counts are not maxed out, then we
                // print out the count value
                if (vm_cnt != 0xf) {
                    dis_stream << "vmcnt(" << vm_cnt << ")";
                }

                if (lgkm_cnt != 0xf) {
                    if (vm_cnt != 0xf)
                        dis_stream << " & ";

                    dis_stream << "lgkmcnt(" << lgkm_cnt << ")";
                }

                if (exp_cnt != 0x7) {
                    if (vm_cnt != 0xf || lgkm_cnt != 0xf)
                        dis_stream << " & ";

                    dis_stream << "expcnt(" << exp_cnt << ")";
                }
            }
            break;
          default:
            break;
        }

        disassembly = dis_stream.str();
    }

    // --- Inst_SMEM base class methods ---

    Inst_SMEM::Inst_SMEM(InFmt_SMEM *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        setFlag(Scalar);
        setFlag(GlobalSegment);

        // copy first instruction DWORD
        instData = iFmt[0];
        // copy second instruction DWORD
        extData = ((InFmt_SMEM_1 *)iFmt)[1];
        _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);

        if (instData.GLC)
            setFlag(GloballyCoherent);
    } // Inst_SMEM

    Inst_SMEM::~Inst_SMEM()
    {
    } // ~Inst_SMEM

    void
    Inst_SMEM::initOperandInfo()
    {
        // Formats:
        // 0 src + 0 dst
        // 3 src + 0 dst
        // 2 src + 1 dst
        // 0 src + 1 dst
        int opNum = 0;
        // Needed because can't take addr of bitfield
        int reg = 0;

        if (numSrcRegOperands()) {
            reg = instData.SDATA;
            if (numSrcRegOperands() == getNumOperands()) {
                srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                      isScalarReg(reg), false, false);
                opNum++;
            }

            reg = instData.SBASE;
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                  true, false, false);
            opNum++;

            reg = extData.OFFSET;
            if (instData.IMM) {
                srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                      false, false, true);
            } else {
                srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                      isScalarReg(reg), false, false);
            }
            opNum++;
        }

        if (numDstRegOperands()) {
            reg = instData.SDATA;
            dstOps.emplace_back(reg, getOperandSize(opNum), false,
                                  isScalarReg(reg), false, false);
        }

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_SMEM::instSize() const
    {
        return 8;
    } // instSize

    void
    Inst_SMEM::generateDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode << " ";
        if (numDstRegOperands()) {
            if (getOperandSize(getNumOperands() - 1) > 4) {
                dis_stream << "s[" << instData.SDATA << ":"
                    << instData.SDATA + getOperandSize(getNumOperands() - 1) /
                    4 - 1 << "], ";
            } else {
                dis_stream << "s" << instData.SDATA << ", ";
            }
        }

        // SBASE has an implied LSB of 0, so we need
        // to shift by one to get the actual value
        dis_stream << "s[" << (instData.SBASE << 1) << ":"
               << ((instData.SBASE << 1) + 1) << "], ";

        if (instData.IMM) {
            // IMM == 1 implies OFFSET should be
            // used as the offset
            dis_stream << "0x" << std::hex << std::setfill('0') << std::setw(2)
                       << extData.OFFSET;
        } else {
            // IMM == 0 implies OFFSET should be
            // used to specify SGRP in which the
            // offset is held
            dis_stream << "s" << extData.OFFSET;
        }

        disassembly = dis_stream.str();
    }

    // --- Inst_VOP2 base class methods ---

    Inst_VOP2::Inst_VOP2(InFmt_VOP2 *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        // copy first instruction DWORD
        instData = iFmt[0];
        if (hasSecondDword(iFmt)) {
            // copy second instruction DWORD into union
            extData = ((MachInst)iFmt)[1];
            _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);
            varSize = 4 + 4;
            if (iFmt->SRC0 == REG_SRC_DPP) {
                setFlag(IsDPP);
            } else if (iFmt->SRC0 == REG_SRC_SWDA) {
                setFlag(IsSDWA);
            }
        } else {
            varSize = 4;
        } // if
    } // Inst_VOP2

    Inst_VOP2::~Inst_VOP2()
    {
    } // ~Inst_VOP2

    void
    Inst_VOP2::initOperandInfo()
    {
        int opNum = 0;

        // Needed because can't take addr of bitfield
        int reg = instData.SRC0;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              isScalarReg(reg), isVectorReg(reg), false);
        opNum++;

        reg = instData.VSRC1;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              false, true, false);
        opNum++;

        // VCC read
        if (readsVCC()) {
            srcOps.emplace_back(REG_VCC_LO, getOperandSize(opNum), true,
                                  true, false, false);
            opNum++;
        }

        // VDST
        reg = instData.VDST;
        dstOps.emplace_back(reg, getOperandSize(opNum), false,
                              false, true, false);
        opNum++;

        // VCC write
        if (writesVCC()) {
            dstOps.emplace_back(REG_VCC_LO, getOperandSize(opNum), false,
                                  true, false, false);
        }

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_VOP2::instSize() const
    {
        return varSize;
    } // instSize

    bool
    Inst_VOP2::hasSecondDword(InFmt_VOP2 *iFmt)
    {
        /*
          There are a few cases where VOP2 instructions have a second dword:

            1.  SRC0 is a literal
            2.  SRC0 is being used to add a data parallel primitive (DPP)
            operation to the instruction.
            3.  SRC0 is being used for sub d-word addressing (SDWA) of the
            operands in the instruction.
            4.  VOP2 instructions also have four special opcodes:',
            V_MADMK_{F16, F32} (0x24, 0x17), and V_MADAK_{F16, F32}',
            (0x25, 0x18), that are always 64b. the only way to',
            detect these special cases is to explicitly check,',
            the opcodes',
        */
        if (iFmt->SRC0 == REG_SRC_LITERAL || (iFmt->SRC0 == REG_SRC_DPP) ||
            (iFmt->SRC0 == REG_SRC_SWDA) || iFmt->OP == 0x17 ||
            iFmt->OP == 0x18 || iFmt->OP == 0x24 || iFmt->OP == 0x25)
            return true;

        return false;
    }

    void
    Inst_VOP2::generateDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode << " ";
        dis_stream << "v" << instData.VDST << ", ";

        if (writesVCC())
            dis_stream << "vcc, ";

        if ((instData.SRC0 == REG_SRC_LITERAL) ||
            (instData.SRC0 == REG_SRC_DPP) ||
            (instData.SRC0 == REG_SRC_SWDA)) {
            dis_stream << "0x" << std::hex << std::setfill('0') << std::setw(8)
                       << _srcLiteral << ", ";
        } else {
            dis_stream << opSelectorToRegSym(instData.SRC0) << ", ";
        }

        // VOP2 instructions have four special opcodes:',
        // V_MADMK_{F16, F32} (0x24, 0x17), and V_MADAK_{F16, F32}',
        // (0x25, 0x18), that are always 64b. the only way to',
        // detect these special cases is to explicitly check,',
        // the opcodes',
        if (instData.OP == 0x17 || instData.OP == 0x18 || instData.OP == 0x24
            || instData.OP == 0x25) {
            dis_stream << "0x" << std::hex << std::setfill('0') << std::setw(8)
                       << extData.imm_u32 << ", ";
        }

        dis_stream << std::resetiosflags(std::ios_base::basefield) << "v"
            << instData.VSRC1;

        if (readsVCC())
            dis_stream << ", vcc";

        disassembly = dis_stream.str();
    }

    // --- Inst_VOP1 base class methods ---

    Inst_VOP1::Inst_VOP1(InFmt_VOP1 *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        // copy first instruction DWORD
        instData = iFmt[0];
        if (hasSecondDword(iFmt)) {
            // copy second instruction DWORD into union
            extData = ((MachInst)iFmt)[1];
            _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);
            varSize = 4 + 4;
            if (iFmt->SRC0 == REG_SRC_DPP) {
                setFlag(IsDPP);
            } else if (iFmt->SRC0 == REG_SRC_SWDA) {
                setFlag(IsSDWA);
            }
        } else {
            varSize = 4;
        } // if
    } // Inst_VOP1

    Inst_VOP1::~Inst_VOP1()
    {
    } // ~Inst_VOP1

    void
    Inst_VOP1::initOperandInfo()
    {
        int opNum = 0;
        // Needed because can't take addr of bitfield
        int reg = instData.SRC0;

        if (numSrcRegOperands()) {
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                  isScalarReg(reg), isVectorReg(reg), false);
            opNum++;
        }

        if (numDstRegOperands()) {
            reg = instData.VDST;
            dstOps.emplace_back(reg, getOperandSize(opNum), false,
                                  false, true, false);
        }

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_VOP1::instSize() const
    {
        return varSize;
    } // instSize

    bool
    Inst_VOP1::hasSecondDword(InFmt_VOP1 *iFmt)
    {
        /*
          There are several cases where VOP1 instructions have a second dword:

            1.  SRC0 is a literal.
            2.  SRC0 is being used to add a data parallel primitive (DPP)
            operation to the instruction.
            3.  SRC0 is being used for sub d-word addressing (SDWA) of the
            operands in the instruction.
        */
        if ((iFmt->SRC0 == REG_SRC_LITERAL) || (iFmt->SRC0 == REG_SRC_DPP) ||
            (iFmt->SRC0 == REG_SRC_SWDA))
            return true;

        return false;
    }

    void
    Inst_VOP1::generateDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode << " ";
        dis_stream << "v" << instData.VDST << ", ";

        if ((instData.SRC0 == REG_SRC_LITERAL) ||
            (instData.SRC0 == REG_SRC_DPP) ||
            (instData.SRC0 == REG_SRC_SWDA)) {
            dis_stream << "0x" << std::hex << std::setfill('0') << std::setw(8)
                       << _srcLiteral;
        } else {
            dis_stream << opSelectorToRegSym(instData.SRC0);
        }

        disassembly = dis_stream.str();
    }

    // --- Inst_VOPC base class methods ---

    Inst_VOPC::Inst_VOPC(InFmt_VOPC *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        setFlag(WritesVCC);
        // copy first instruction DWORD
        instData = iFmt[0];
        if (hasSecondDword(iFmt)) {
            // copy second instruction DWORD into union
            extData = ((MachInst)iFmt)[1];
            _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);
            varSize = 4 + 4;
            if (iFmt->SRC0 == REG_SRC_DPP) {
                setFlag(IsDPP);
            } else if (iFmt->SRC0 == REG_SRC_SWDA) {
                setFlag(IsSDWA);
            }
        } else {
            varSize = 4;
        } // if
    } // Inst_VOPC

    Inst_VOPC::~Inst_VOPC()
    {
    } // ~Inst_VOPC

    void
    Inst_VOPC::initOperandInfo()
    {
        int opNum = 0;

        // Needed because can't take addr of bitfield
        int reg = instData.SRC0;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              isScalarReg(reg), isVectorReg(reg), false);
        opNum++;

        reg = instData.VSRC1;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              false, true, false);
        opNum++;

        assert(writesVCC());
        dstOps.emplace_back(REG_VCC_LO, getOperandSize(opNum), false,
                              true, false, false);

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_VOPC::instSize() const
    {
        return varSize;
    } // instSize

    bool
    Inst_VOPC::hasSecondDword(InFmt_VOPC *iFmt)
    {
        /*
          There are several cases where VOPC instructions have a second dword:

            1.  SRC0 is a literal.
            2.  SRC0 is being used to add a data parallel primitive (DPP)
            operation to the instruction.
            3.  SRC0 is being used for sub d-word addressing (SDWA) of the
            operands in the instruction.
        */
        if ((iFmt->SRC0 == REG_SRC_LITERAL) || (iFmt->SRC0 == REG_SRC_DPP) ||
            (iFmt->SRC0 == REG_SRC_SWDA))
            return true;

        return false;
    }

    void
    Inst_VOPC::generateDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode << " vcc, ";

        dis_stream << opSelectorToRegSym(instData.SRC0) << ", ";
        dis_stream << "v" << instData.VSRC1;

        disassembly = dis_stream.str();
    }

    // --- Inst_VINTRP base class methods ---

    Inst_VINTRP::Inst_VINTRP(InFmt_VINTRP *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        // copy first instruction DWORD
        instData = iFmt[0];
    } // Inst_VINTRP

    Inst_VINTRP::~Inst_VINTRP()
    {
    } // ~Inst_VINTRP

    int
    Inst_VINTRP::instSize() const
    {
        return 4;
    } // instSize

    // --- Inst_VOP3A base class methods ---

    Inst_VOP3A::Inst_VOP3A(InFmt_VOP3A *iFmt, const std::string &opcode,
                         bool sgpr_dst)
        : VEGAGPUStaticInst(opcode), sgprDst(sgpr_dst)
    {
        // copy first instruction DWORD
        instData = iFmt[0];
        // copy second instruction DWORD
        extData = ((InFmt_VOP3_1 *)iFmt)[1];
        _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);
    } // Inst_VOP3A

    Inst_VOP3A::~Inst_VOP3A()
    {
    } // ~Inst_VOP3A

    void
    Inst_VOP3A::initOperandInfo()
    {
        // Also takes care of bitfield addr issue
        unsigned int srcs[3] = {extData.SRC0, extData.SRC1, extData.SRC2};

        int opNum = 0;

        int numSrc = numSrcRegOperands() - readsVCC();
        int numDst = numDstRegOperands() - writesVCC();

        for (opNum = 0; opNum < numSrc; opNum++) {
            srcOps.emplace_back(srcs[opNum], getOperandSize(opNum), true,
                                  isScalarReg(srcs[opNum]),
                                  isVectorReg(srcs[opNum]), false);
        }

        if (readsVCC()) {
            srcOps.emplace_back(REG_VCC_LO, getOperandSize(opNum), true,
                                  true, false, false);
            opNum++;
        }

        if (numDst) {
            // Needed because can't take addr of bitfield
            int reg = instData.VDST;
            dstOps.emplace_back(reg, getOperandSize(opNum), false,
                                  sgprDst, !sgprDst, false);
            opNum++;
        }

        if (writesVCC()) {
            dstOps.emplace_back(REG_VCC_LO, getOperandSize(opNum), false,
                                  true, false, false);
        }

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_VOP3A::instSize() const
    {
        return 8;
    } // instSize

    void
    Inst_VOP3A::generateDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode << " ";
        int num_regs = 0;

        if (getOperandSize(getNumOperands() - 1) > 4) {
            num_regs = getOperandSize(getNumOperands() - 1) / 4;
            if (sgprDst)
                dis_stream << "s[";
            else
                dis_stream << "v[";
            dis_stream << instData.VDST << ":" << instData.VDST +
                          num_regs - 1 << "], ";
        } else {
            if (sgprDst)
                dis_stream << "s";
            else
                dis_stream << "v";
            dis_stream << instData.VDST << ", ";
        }

        num_regs = getOperandSize(0) / 4;

        if (extData.NEG & 0x1) {
            dis_stream << "-" << opSelectorToRegSym(extData.SRC0, num_regs);
        } else {
            dis_stream << opSelectorToRegSym(extData.SRC0, num_regs);
        }

        if (numSrcRegOperands() > 1) {
            num_regs = getOperandSize(1) / 4;

            if (extData.NEG & 0x2) {
                dis_stream << ", -"
                    << opSelectorToRegSym(extData.SRC1, num_regs);
            } else {
                dis_stream << ", "
                    << opSelectorToRegSym(extData.SRC1, num_regs);
            }
        }

        if (numSrcRegOperands() > 2) {
            num_regs = getOperandSize(2) / 4;

            if (extData.NEG & 0x4) {
                dis_stream << ", -"
                    << opSelectorToRegSym(extData.SRC2, num_regs);
            } else {
                dis_stream << ", "
                    << opSelectorToRegSym(extData.SRC2, num_regs);
            }
        }

        disassembly = dis_stream.str();
    }

    // --- Inst_VOP3B base class methods ---

    Inst_VOP3B::Inst_VOP3B(InFmt_VOP3B *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        // copy first instruction DWORD
        instData = iFmt[0];
        // copy second instruction DWORD
        extData = ((InFmt_VOP3_1 *)iFmt)[1];
        _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);
    } // Inst_VOP3B

    Inst_VOP3B::~Inst_VOP3B()
    {
    } // ~Inst_VOP3B

    void
    Inst_VOP3B::initOperandInfo()
    {
        // Also takes care of bitfield addr issue
        unsigned int srcs[3] = {extData.SRC0, extData.SRC1, extData.SRC2};

        int opNum = 0;

        int numSrc = numSrcRegOperands() - readsVCC();
        int numDst = numDstRegOperands() - writesVCC();

        for (opNum = 0; opNum < numSrc; opNum++) {
            srcOps.emplace_back(srcs[opNum], getOperandSize(opNum), true,
                                  isScalarReg(srcs[opNum]),
                                  isVectorReg(srcs[opNum]), false);
        }

        if (readsVCC()) {
            srcOps.emplace_back(REG_VCC_LO, getOperandSize(opNum), true,
                                  true, false, false);
            opNum++;
        }

        if (numDst) {
            // Needed because can't take addr of bitfield
            int reg = instData.VDST;
            dstOps.emplace_back(reg, getOperandSize(opNum), false,
                                  false, true, false);
            opNum++;
        }

        if (writesVCC()) {
            dstOps.emplace_back(REG_VCC_LO, getOperandSize(opNum), false,
                                  true, false, false);
        }

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_VOP3B::instSize() const
    {
        return 8;
    } // instSize

    void
    Inst_VOP3B::generateDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode << " ";

        dis_stream << "v" << instData.VDST << ", ";

        if (numDstRegOperands() == 2) {
            if (getOperandSize(getNumOperands() - 1) > 4) {
                int num_regs = getOperandSize(getNumOperands() - 1) / 4;
                dis_stream << opSelectorToRegSym(instData.SDST, num_regs)
                    << ", ";
            } else {
                dis_stream << opSelectorToRegSym(instData.SDST) << ", ";
            }
        }

        if (extData.NEG & 0x1) {
            dis_stream << "-" << opSelectorToRegSym(extData.SRC0) << ", ";
        } else {
            dis_stream << opSelectorToRegSym(extData.SRC0) << ", ";
        }

        if (extData.NEG & 0x2) {
            dis_stream << "-" << opSelectorToRegSym(extData.SRC1);
        } else {
            dis_stream << opSelectorToRegSym(extData.SRC1);
        }

        if (numSrcRegOperands() == 3) {
            if (extData.NEG & 0x4) {
                dis_stream << ", -" << opSelectorToRegSym(extData.SRC2);
            } else {
                dis_stream << ", " << opSelectorToRegSym(extData.SRC2);
            }
        }

        if (readsVCC())
            dis_stream << ", vcc";

        disassembly = dis_stream.str();
    }

    // --- Inst_DS base class methods ---

    Inst_DS::Inst_DS(InFmt_DS *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        setFlag(GroupSegment);

        // copy first instruction DWORD
        instData = iFmt[0];
        // copy second instruction DWORD
        extData = ((InFmt_DS_1 *)iFmt)[1];
        _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);
    } // Inst_DS

    Inst_DS::~Inst_DS()
    {
    } // ~Inst_DS

    void
    Inst_DS::initOperandInfo()
    {
        unsigned int srcs[3] = {extData.ADDR, extData.DATA0, extData.DATA1};

        int opIdx = 0;

        for (opIdx = 0; opIdx < numSrcRegOperands(); opIdx++){
            srcOps.emplace_back(srcs[opIdx], getOperandSize(opIdx), true,
                                  false, true, false);
        }

        if (numDstRegOperands()) {
            // Needed because can't take addr of bitfield
            int reg = extData.VDST;
            dstOps.emplace_back(reg, getOperandSize(opIdx), false,
                                  false, true, false);
        }

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_DS::instSize() const
    {
        return 8;
    } // instSize

    void
    Inst_DS::generateDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode << " ";

        if (numDstRegOperands())
            dis_stream << "v" << extData.VDST << ", ";

        dis_stream << "v" << extData.ADDR;

        if (numSrcRegOperands() > 1)
            dis_stream << ", v" << extData.DATA0;

        if (numSrcRegOperands() > 2)
            dis_stream << ", v" << extData.DATA1;

        uint16_t offset = 0;

        if (instData.OFFSET1) {
            offset += instData.OFFSET1;
            offset <<= 8;
        }

        if (instData.OFFSET0)
            offset += instData.OFFSET0;

        if (offset)
            dis_stream << " offset:" << offset;

        disassembly = dis_stream.str();
    }

    // --- Inst_MUBUF base class methods ---

    Inst_MUBUF::Inst_MUBUF(InFmt_MUBUF *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        // copy first instruction DWORD
        instData = iFmt[0];
        // copy second instruction DWORD
        extData = ((InFmt_MUBUF_1 *)iFmt)[1];
        _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);

        if (instData.GLC)
            setFlag(GloballyCoherent);

        if (instData.SLC)
            setFlag(SystemCoherent);
    } // Inst_MUBUF

    Inst_MUBUF::~Inst_MUBUF()
    {
    } // ~Inst_MUBUF

    void
    Inst_MUBUF::initOperandInfo()
    {
        // Currently there are three formats:
        // 0 src + 0 dst
        // 3 src + 1 dst
        // 4 src + 0 dst
        int opNum = 0;

        // Needed because can't take addr of bitfield;
        int reg = 0;

        if (numSrcRegOperands()) {
            if (numSrcRegOperands() == getNumOperands()) {
                reg = extData.VDATA;
                srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                      false, true, false);
                opNum++;
            }

            reg = extData.VADDR;
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                  false, true, false);
            opNum++;

            reg = extData.SRSRC;
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                  true, false, false);
            opNum++;

            reg = extData.SOFFSET;
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                  true, false, false);
            opNum++;
        }

        // extData.VDATA moves in the reg list depending on the instruction
        if (numDstRegOperands()) {
            reg = extData.VDATA;
            dstOps.emplace_back(reg, getOperandSize(opNum), false,
                                  false, true, false);
        }

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_MUBUF::instSize() const
    {
        return 8;
    } // instSize

    void
    Inst_MUBUF::generateDisassembly()
    {
        // SRSRC is always in units of 4 SGPRs
        int srsrc_val = extData.SRSRC * 4;
        std::stringstream dis_stream;
        dis_stream << _opcode << " ";
        dis_stream << "v" << extData.VDATA << ", v" << extData.VADDR << ", ";
        dis_stream << "s[" << srsrc_val << ":"
                   << srsrc_val + 3 << "], ";
        dis_stream << "s" << extData.SOFFSET;

        if (instData.OFFSET)
            dis_stream << ", offset:" << instData.OFFSET;

        disassembly = dis_stream.str();
    }

    // --- Inst_MTBUF base class methods ---

    Inst_MTBUF::Inst_MTBUF(InFmt_MTBUF *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        // copy first instruction DWORD
        instData = iFmt[0];
        // copy second instruction DWORD
        extData = ((InFmt_MTBUF_1 *)iFmt)[1];
        _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);

        if (instData.GLC)
            setFlag(GloballyCoherent);

        if (extData.SLC)
            setFlag(SystemCoherent);
    } // Inst_MTBUF

    Inst_MTBUF::~Inst_MTBUF()
    {
    } // ~Inst_MTBUF

    void
    Inst_MTBUF::initOperandInfo()
    {
        // Currently there are two formats:
        // 3 src + 1 dst
        // 4 src + 0 dst
        int opNum = 0;

        // Needed because can't take addr of bitfield
        int reg = 0;

        if (numSrcRegOperands() == getNumOperands()) {
            reg = extData.VDATA;
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                  false, true, false);
            opNum++;
        }

        reg = extData.VADDR;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              false, true, false);
        opNum++;

        reg = extData.SRSRC;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              true, false, false);
        opNum++;

        reg = extData.SOFFSET;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              true, false, false);
        opNum++;

        // extData.VDATA moves in the reg list depending on the instruction
        if (numDstRegOperands()) {
            reg = extData.VDATA;
            dstOps.emplace_back(reg, getOperandSize(opNum), false,
                                  false, true, false);
        }

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_MTBUF::instSize() const
    {
        return 8;
    } // instSize

    // --- Inst_MIMG base class methods ---

    Inst_MIMG::Inst_MIMG(InFmt_MIMG *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        // copy first instruction DWORD
        instData = iFmt[0];
        // copy second instruction DWORD
        extData = ((InFmt_MIMG_1 *)iFmt)[1];
        _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);

        if (instData.GLC)
            setFlag(GloballyCoherent);

        if (instData.SLC)
            setFlag(SystemCoherent);
    } // Inst_MIMG

    Inst_MIMG::~Inst_MIMG()
    {
    } // ~Inst_MIMG

    void
    Inst_MIMG::initOperandInfo()
    {
        // Three formats:
        // 1 dst + 2 src : s,s,d
        // 0 dst + 3 src : s,s,s
        // 1 dst + 3 src : s,s,s,d
        int opNum = 0;

        // Needed because can't take addr of bitfield
        int reg = 0;

        if (numSrcRegOperands() == getNumOperands()) {
            reg = extData.VDATA;
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                  false, true, false);
            opNum++;
        }

        reg = extData.VADDR;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              false, true, false);
        opNum++;

        reg = extData.SRSRC;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              true, false, false);
        opNum++;

        if (getNumOperands() == 4) {
            reg = extData.SSAMP;
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                  true, false, false);
            opNum++;
        }

        // extData.VDATA moves in the reg list depending on the instruction
        if (numDstRegOperands()) {
            reg = extData.VDATA;
            dstOps.emplace_back(reg, getOperandSize(opNum), false,
                                  false, true, false);
        }

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_MIMG::instSize() const
    {
        return 8;
    } // instSize

    // --- Inst_EXP base class methods ---

    Inst_EXP::Inst_EXP(InFmt_EXP *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        // copy first instruction DWORD
        instData = iFmt[0];
        // copy second instruction DWORD
        extData = ((InFmt_EXP_1 *)iFmt)[1];
        _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);
    } // Inst_EXP

    Inst_EXP::~Inst_EXP()
    {
    } // ~Inst_EXP

    void
    Inst_EXP::initOperandInfo()
    {
        // Only 1 instruction, 1 format: 1 dst + 4 src
        int opNum = 0;

        // Avoids taking addr of bitfield
        unsigned int srcs[4] = {extData.VSRC0, extData.VSRC1,
                                extData.VSRC2, extData.VSRC3};

        for (opNum = 0; opNum < 4; opNum++) {
            srcOps.emplace_back(srcs[opNum], getOperandSize(opNum), true,
                                  false, true, false);
        }

        //TODO: Add the dst operand, don't know what it is right now
    }

    int
    Inst_EXP::instSize() const
    {
        return 8;
    } // instSize

    // --- Inst_FLAT base class methods ---

    Inst_FLAT::Inst_FLAT(InFmt_FLAT *iFmt, const std::string &opcode)
        : VEGAGPUStaticInst(opcode)
    {
        // The SEG field specifies FLAT(0) SCRATCH(1) or GLOBAL(2)
        if (iFmt->SEG == 0) {
            setFlag(Flat);
        } else if (iFmt->SEG == 2) {
            setFlag(FlatGlobal);
        } else {
            panic("Unknown flat segment: %d\n", iFmt->SEG);
        }

        // copy first instruction DWORD
        instData = iFmt[0];
        // copy second instruction DWORD
        extData = ((InFmt_FLAT_1 *)iFmt)[1];
        _srcLiteral = *reinterpret_cast<uint32_t*>(&iFmt[1]);

        if (instData.GLC)
            setFlag(GloballyCoherent);

        if (instData.SLC)
            setFlag(SystemCoherent);
    } // Inst_FLAT

    Inst_FLAT::~Inst_FLAT()
    {
    } // ~Inst_FLAT

    void
    Inst_FLAT::initOperandInfo()
    {
        // One of the flat subtypes should be specified via flags
        assert(isFlat() ^ isFlatGlobal());

        if (isFlat()) {
            initFlatOperandInfo();
        } else if (isFlatGlobal()) {
            initGlobalOperandInfo();
        } else {
            panic("Unknown flat subtype!\n");
        }
    }

    void
    Inst_FLAT::initFlatOperandInfo()
    {
        //3 formats:
        // 1 dst + 1 src (load)
        // 0 dst + 2 src (store)
        // 1 dst + 2 src (atomic)
        int opNum = 0;

        // Needed because can't take addr of bitfield
        int reg = 0;

        if (getNumOperands() > 2)
            assert(isAtomic());

        reg = extData.ADDR;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              false, true, false);
        opNum++;

        if (numSrcRegOperands() == 2) {
            reg = extData.DATA;
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                  false, true, false);
            opNum++;
        }

        if (numDstRegOperands()) {
            reg = extData.VDST;
            dstOps.emplace_back(reg, getOperandSize(opNum), false,
                                  false, true, false);
        }

        assert(srcOps.size() == numSrcRegOperands());
        assert(dstOps.size() == numDstRegOperands());
    }

    void
    Inst_FLAT::initGlobalOperandInfo()
    {
        //3 formats:
        // 1 dst + 2 src (load)
        // 0 dst + 3 src (store)
        // 1 dst + 3 src (atomic)
        int opNum = 0;

        // Needed because can't take addr of bitfield
        int reg = 0;

        if (getNumOperands() > 3)
            assert(isAtomic());

        reg = extData.ADDR;
        srcOps.emplace_back(reg, getOperandSize(opNum), true,
                              false, true, false);
        opNum++;

        if (numSrcRegOperands() == 2) {
            reg = extData.SADDR;
            // 0x7f (off) means the sgpr is not used. Don't read it
            if (reg != 0x7f) {
                srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                      true, false, false);
            }
            opNum++;
        }

        if (numSrcRegOperands() == 3) {
            reg = extData.DATA;
            srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                  false, true, false);
            opNum++;

            reg = extData.SADDR;
            // 0x7f (off) means the sgpr is not used. Don't read it
            if (reg != 0x7f) {
                srcOps.emplace_back(reg, getOperandSize(opNum), true,
                                      true, false, false);
            }
            opNum++;
        }

        if (numDstRegOperands()) {
            reg = extData.VDST;
            dstOps.emplace_back(reg, getOperandSize(opNum), false,
                                  false, true, false);
        }

        reg = extData.SADDR;
        if (reg != 0x7f) {
            assert(srcOps.size() == numSrcRegOperands());
        } else {
            assert(srcOps.size() == numSrcRegOperands() - 1);
        }
        assert(dstOps.size() == numDstRegOperands());
    }

    int
    Inst_FLAT::instSize() const
    {
        return 8;
    } // instSize

    void
    Inst_FLAT::generateDisassembly()
    {
        // One of the flat subtypes should be specified via flags
        assert(isFlat() ^ isFlatGlobal());

        if (isFlat()) {
            generateFlatDisassembly();
        } else if (isFlatGlobal()) {
            generateGlobalDisassembly();
        } else {
            panic("Unknown flat subtype!\n");
        }
    }

    void
    Inst_FLAT::generateFlatDisassembly()
    {
        std::stringstream dis_stream;
        dis_stream << _opcode << " ";

        if (isLoad())
            dis_stream << "v" << extData.VDST << ", ";

        dis_stream << "v[" << extData.ADDR << ":" << extData.ADDR + 1 << "]";

        if (isStore())
            dis_stream << ", v" << extData.DATA;

        disassembly = dis_stream.str();
    }

    void
    Inst_FLAT::generateGlobalDisassembly()
    {
        // Replace flat_ with global_ in assembly string
        std::string global_opcode = _opcode;
        global_opcode.replace(0, 4, "global");

        std::stringstream dis_stream;
        dis_stream << global_opcode << " ";

        if (isLoad())
            dis_stream << "v" << extData.VDST << ", ";

        dis_stream << "v[" << extData.ADDR << ":" << extData.ADDR + 1 << "]";

        if (isStore())
            dis_stream << ", v" << extData.DATA;

        if (extData.SADDR == 0x7f)
            dis_stream << ", off";
        else
            dis_stream << ", " << extData.SADDR;

        disassembly = dis_stream.str();
    }
} // namespace VegaISA
} // namespace gem5
