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

#ifndef __ARCH_GCN3_OPERAND_HH__
#define __ARCH_GCN3_OPERAND_HH__

#include <array>

#include "arch/gcn3/registers.hh"
#include "arch/generic/vec_reg.hh"
#include "gpu-compute/scalar_register_file.hh"
#include "gpu-compute/vector_register_file.hh"
#include "gpu-compute/wavefront.hh"

/**
 * classes that represnt vector/scalar operands in GCN3 ISA. these classes
 * wrap the generic vector register type (i.e., src/arch/generic/vec_reg.hh)
 * and allow them to be manipulated in ways that are unique to GCN3 insts.
 */

namespace Gcn3ISA
{
    /**
     * convenience traits so we can automatically infer the correct FP type
     * without looking at the number of dwords (i.e., to determine if we
     * need a float or a double when creating FP constants).
     */
    template<typename T> struct OpTraits { typedef float FloatT; };
    template<> struct OpTraits<ScalarRegF64> { typedef double FloatT; };
    template<> struct OpTraits<ScalarRegU64> { typedef double FloatT; };

    class Operand
    {
      public:
        Operand() = delete;

        Operand(GPUDynInstPtr gpuDynInst, int opIdx)
            : _gpuDynInst(gpuDynInst), _opIdx(opIdx)
        {
            assert(_gpuDynInst);
            assert(_opIdx >= 0);
        }

        /**
         * read from and write to the underlying register(s) that
         * this operand is referring to.
         */
        virtual void read() = 0;
        virtual void write() = 0;

      protected:
        /**
         * instruction object that owns this operand
         */
        GPUDynInstPtr _gpuDynInst;
        /**
         * op selector value for this operand. note that this is not
         * the same as the register file index, be it scalar or vector.
         * this could refer to inline constants, system regs, or even
         * special values.
         */
        int _opIdx;
    };

    template<typename DataType, bool Const, size_t NumDwords>
    class ScalarOperand;

    template<typename DataType, bool Const,
        size_t NumDwords = sizeof(DataType) / sizeof(VecElemU32)>
    class VecOperand final : public Operand
    {
      static_assert(NumDwords >= 1 && NumDwords <= MaxOperandDwords,
            "Incorrect number of DWORDS for GCN3 operand.");

      public:
        VecOperand() = delete;

        VecOperand(GPUDynInstPtr gpuDynInst, int opIdx)
            : Operand(gpuDynInst, opIdx), scalar(false), absMod(false),
              negMod(false), scRegData(gpuDynInst, _opIdx),
              vrfData{{ nullptr }}
        {
            vecReg.zero();
        }

        ~VecOperand()
        {
        }

        /**
         * certain vector operands can read from the vrf/srf or constants.
         * we use this method to first determine the type of the operand,
         * then we read from the appropriate source. if vector we read
         * directly from the vrf. if scalar, we read in the data through
         * the scalar operand component. this should only be used for VSRC
         * operands.
         */
        void
        readSrc()
        {
            if (isVectorReg(_opIdx)) {
                _opIdx = opSelectorToRegIdx(_opIdx, _gpuDynInst->wavefront()
                    ->reservedScalarRegs);
                read();
            } else {
                readScalar();
            }
        }

        /**
         * read from the vrf. this should only be used by vector inst
         * source operands that are explicitly vector (i.e., VSRC).
         */
        void
        read() override
        {
            assert(_gpuDynInst);
            assert(_gpuDynInst->wavefront());
            assert(_gpuDynInst->computeUnit());
            Wavefront *wf = _gpuDynInst->wavefront();
            ComputeUnit *cu = _gpuDynInst->computeUnit();

            for (auto i = 0; i < NumDwords; ++i) {
                int vgprIdx = cu->registerManager.mapVgpr(wf, _opIdx + i);
                vrfData[i] = &cu->vrf[wf->simdId]->readWriteable(vgprIdx);

                DPRINTF(GPUVRF, "Read v[%d]\n", vgprIdx);
                cu->vrf[wf->simdId]->printReg(wf, vgprIdx);
            }

            if (NumDwords == 1) {
                assert(vrfData[0]);
                auto vgpr = vecReg.template as<DataType>();
                auto reg_file_vgpr = vrfData[0]->template as<VecElemU32>();
                for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                    std::memcpy((void*)&vgpr[lane],
                        (void*)&reg_file_vgpr[lane], sizeof(DataType));
                }
            } else if (NumDwords == 2) {
                assert(vrfData[0]);
                assert(vrfData[1]);
                auto vgpr = vecReg.template as<VecElemU64>();
                auto reg_file_vgpr0 = vrfData[0]->template as<VecElemU32>();
                auto reg_file_vgpr1 = vrfData[1]->template as<VecElemU32>();

                for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                    VecElemU64 tmp_val(0);
                    ((VecElemU32*)&tmp_val)[0] = reg_file_vgpr0[lane];
                    ((VecElemU32*)&tmp_val)[1] = reg_file_vgpr1[lane];
                    vgpr[lane] = tmp_val;
                }
            }
        }

        /**
         * write to the vrf. we maintain a copy of the underlying vector
         * reg(s) for this operand (i.e., vrfData/scRegData), as well as a
         * temporary vector register representation (i.e., vecReg) of the
         * vector register, which allows the execute() methods of instructions
         * to easily write their operand data using operator[] regardless of
         * their size. after the result is calculated we use write() to write
         * the data to the actual register file storage. this allows us to do
         * type conversion, etc., in a single call as opposed to doing it
         * in each execute() method.
         */
        void
        write() override
        {
            assert(_gpuDynInst);
            assert(_gpuDynInst->wavefront());
            assert(_gpuDynInst->computeUnit());
            Wavefront *wf = _gpuDynInst->wavefront();
            ComputeUnit *cu = _gpuDynInst->computeUnit();
            VectorMask &exec_mask = _gpuDynInst->isLoad()
                ? _gpuDynInst->exec_mask : wf->execMask();

            if (NumDwords == 1) {
                int vgprIdx = cu->registerManager.mapVgpr(wf, _opIdx);
                vrfData[0] = &cu->vrf[wf->simdId]->readWriteable(vgprIdx);
                assert(vrfData[0]);
                auto reg_file_vgpr = vrfData[0]->template as<VecElemU32>();
                auto vgpr = vecReg.template as<DataType>();

                for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                    if (exec_mask[lane] || _gpuDynInst->ignoreExec()) {
                        std::memcpy((void*)&reg_file_vgpr[lane],
                            (void*)&vgpr[lane], sizeof(DataType));
                    }
                }

                DPRINTF(GPUVRF, "Write v[%d]\n", vgprIdx);
                cu->vrf[wf->simdId]->printReg(wf, vgprIdx);
            } else if (NumDwords == 2) {
                int vgprIdx0 = cu->registerManager.mapVgpr(wf, _opIdx);
                int vgprIdx1 = cu->registerManager.mapVgpr(wf, _opIdx + 1);
                vrfData[0] = &cu->vrf[wf->simdId]->readWriteable(vgprIdx0);
                vrfData[1] = &cu->vrf[wf->simdId]->readWriteable(vgprIdx1);
                assert(vrfData[0]);
                assert(vrfData[1]);
                auto reg_file_vgpr0 = vrfData[0]->template as<VecElemU32>();
                auto reg_file_vgpr1 = vrfData[1]->template as<VecElemU32>();
                auto vgpr = vecReg.template as<VecElemU64>();

                for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
                    if (exec_mask[lane] || _gpuDynInst->ignoreExec()) {
                        reg_file_vgpr0[lane] = ((VecElemU32*)&vgpr[lane])[0];
                        reg_file_vgpr1[lane] = ((VecElemU32*)&vgpr[lane])[1];
                    }
                }

                DPRINTF(GPUVRF, "Write v[%d:%d]\n", vgprIdx0, vgprIdx1);
                cu->vrf[wf->simdId]->printReg(wf, vgprIdx0);
                cu->vrf[wf->simdId]->printReg(wf, vgprIdx1);
            }
        }

        void
        negModifier()
        {
            negMod = true;
        }

        void
        absModifier()
        {
            absMod = true;
        }

        /**
         * getter [] operator. only enable if this operand is constant
         * (i.e, a source operand) and if it can be represented using
         * primitive types (i.e., 8b to 64b primitives).
         */
        template<bool Condition = (NumDwords == 1 || NumDwords == 2) && Const>
        typename std::enable_if<Condition, const DataType>::type
        operator[](size_t idx) const
        {
            assert(idx < NumVecElemPerVecReg);

            if (scalar) {
                DataType ret_val = scRegData.rawData();

                if (absMod) {
                    assert(std::is_floating_point<DataType>::value);
                    ret_val = std::fabs(ret_val);
                }

                if (negMod) {
                    assert(std::is_floating_point<DataType>::value);
                    ret_val = -ret_val;
                }

                return ret_val;
            } else {
                auto vgpr = vecReg.template as<DataType>();
                DataType ret_val = vgpr[idx];

                if (absMod) {
                    assert(std::is_floating_point<DataType>::value);
                    ret_val = std::fabs(ret_val);
                }

                if (negMod) {
                    assert(std::is_floating_point<DataType>::value);
                    ret_val = -ret_val;
                }

                return ret_val;
            }
        }

        /**
         * setter [] operator. only enable if this operand is non-constant
         * (i.e, a destination operand) and if it can be represented using
         * primitive types (i.e., 8b to 64b primitives).
         */
        template<bool Condition = (NumDwords == 1 || NumDwords == 2) && !Const>
        typename std::enable_if<Condition, DataType&>::type
        operator[](size_t idx)
        {
            assert(!scalar);
            assert(idx < NumVecElemPerVecReg);

            return vecReg.template as<DataType>()[idx];
        }

        private:
          /**
           * if we determine that this operand is a scalar (reg or constant)
           * then we read the scalar data into the scalar operand data member.
           */
          void
          readScalar()
          {
              scalar = true;
              scRegData.read();
          }

          using VecRegCont = typename std::conditional<NumDwords == 2,
              VecRegContainerU64, typename std::conditional<sizeof(DataType)
                  == sizeof(VecElemU16), VecRegContainerU16,
                      typename std::conditional<sizeof(DataType)
                          == sizeof(VecElemU8), VecRegContainerU8,
                              VecRegContainerU32>::type>::type>::type;

          /**
           * whether this operand a scalar or not.
           */
          bool scalar;
          /**
           * absolute value and negative modifiers. VOP3 instructions
           * may indicate that their input/output operands must be
           * modified, either by taking the absolute value or negating
           * them. these bools indicate which modifier, if any, to use.
           */
          bool absMod;
          bool negMod;
          /**
           * this holds all the operand data in a single vector register
           * object (i.e., if an operand is 64b, this will hold the data
           * from both registers the operand is using).
           */
          VecRegCont vecReg;
          /**
           * for src operands that read scalars (i.e., scalar regs or
           * a scalar constant).
           */
          ScalarOperand<DataType, Const, NumDwords> scRegData;
          /**
           * pointers to the underlyding registers (i.e., the actual
           * registers in the register file).
           */
          std::array<VecRegContainerU32*, NumDwords> vrfData;
    };

    template<typename DataType, bool Const,
        size_t NumDwords = sizeof(DataType) / sizeof(ScalarRegU32)>
    class ScalarOperand final : public Operand
    {
      static_assert(NumDwords >= 1 && NumDwords <= MaxOperandDwords,
            "Incorrect number of DWORDS for GCN3 operand.");
      public:
        ScalarOperand() = delete;

        ScalarOperand(GPUDynInstPtr gpuDynInst, int opIdx)
            : Operand(gpuDynInst, opIdx)
        {
            std::memset(srfData.data(), 0, NumDwords * sizeof(ScalarRegU32));
        }

        ~ScalarOperand()
        {
        }

        /**
         * we store scalar data in a std::array, however if we need the
         * full operand data we use this method to copy all elements of
         * the scalar operand data to a single primitive container. only
         * useful for 8b to 64b primitive types, as they are the only types
         * that we need to perform computation on.
         */
        template<bool Condition = NumDwords == 1 || NumDwords == 2>
        typename std::enable_if<Condition, DataType>::type
        rawData() const
        {
            assert(sizeof(DataType) <= sizeof(srfData));
            DataType raw_data((DataType)0);
            std::memcpy((void*)&raw_data, (void*)srfData.data(),
                sizeof(DataType));

            return raw_data;
        }

        void*
        rawDataPtr()
        {
            return (void*)srfData.data();
        }

        void
        read() override
        {
            Wavefront *wf = _gpuDynInst->wavefront();
            ComputeUnit *cu = _gpuDynInst->computeUnit();

            if (!isScalarReg(_opIdx)) {
                readSpecialVal();
            } else {
                for (auto i = 0; i < NumDwords; ++i) {
                    int sgprIdx = regIdx(i);
                    srfData[i] = cu->srf[wf->simdId]->read(sgprIdx);
                    DPRINTF(GPUSRF, "Read s[%d]\n", sgprIdx);
                    cu->srf[wf->simdId]->printReg(wf, sgprIdx);
                }
            }
        }

        void
        write() override
        {
            Wavefront *wf = _gpuDynInst->wavefront();
            ComputeUnit *cu = _gpuDynInst->computeUnit();

            if (!isScalarReg(_opIdx)) {
                if (_opIdx == REG_EXEC_LO) {
                    uint64_t new_exec_mask_val(0);
                    std::memcpy((void*)&new_exec_mask_val,
                        (void*)srfData.data(), sizeof(new_exec_mask_val));
                    VectorMask new_exec_mask(new_exec_mask_val);
                    wf->execMask() = new_exec_mask;
                    DPRINTF(GPUSRF, "Write EXEC\n");
                    DPRINTF(GPUSRF, "EXEC = %#x\n", new_exec_mask_val);
                } else {
                    _gpuDynInst->writeMiscReg(_opIdx, srfData[0]);
                }
            } else {
                for (auto i = 0; i < NumDwords; ++i) {
                    int sgprIdx = regIdx(i);
                    auto &sgpr = cu->srf[wf->simdId]->readWriteable(sgprIdx);
                    if (_gpuDynInst->isLoad()) {
                        assert(sizeof(DataType) <= sizeof(ScalarRegU64));
                        sgpr = reinterpret_cast<ScalarRegU32*>(
                            _gpuDynInst->scalar_data)[i];
                    } else {
                        sgpr = srfData[i];
                    }
                    DPRINTF(GPUSRF, "Write s[%d]\n", sgprIdx);
                    cu->srf[wf->simdId]->printReg(wf, sgprIdx);
                }
            }
        }

        /**
         * bit access to scalar data. primarily used for setting vcc bits.
         */
        template<bool Condition = NumDwords == 1 || NumDwords == 2>
        typename std::enable_if<Condition, void>::type
        setBit(int bit, int bit_val)
        {
            DataType &sgpr = *((DataType*)srfData.data());
            replaceBits(sgpr, bit, bit_val);
        }

        template<bool Condition = (NumDwords == 1 || NumDwords == 2) && !Const>
        typename std::enable_if<Condition, ScalarOperand&>::type
        operator=(DataType rhs)
        {
            std::memcpy((void*)srfData.data(), (void*)&rhs, sizeof(DataType));
            return *this;
        }

      private:
        /**
         * we have determined that we are not reading our scalar operand data
         * from the register file, so here we figure out which special value
         * we are reading (i.e., float constant, int constant, inline
         * constant, or various other system registers (e.g., exec mask).
         */
        void
        readSpecialVal()
        {
            assert(NumDwords == 1 || NumDwords == 2);

            switch(_opIdx) {
              case REG_EXEC_LO:
                {
                    assert(NumDwords == 2);
                    ScalarRegU64 exec_mask = _gpuDynInst->wavefront()->
                        execMask().to_ullong();
                    std::memcpy((void*)srfData.data(), (void*)&exec_mask,
                        sizeof(srfData));
                    DPRINTF(GPUSRF, "Read EXEC\n");
                    DPRINTF(GPUSRF, "EXEC = %#x\n", exec_mask);
                }
                break;
              case REG_SRC_SWDA:
              case REG_SRC_DPP:
              case REG_SRC_LITERAL:
                assert(NumDwords == 1);
                srfData[0] = _gpuDynInst->srcLiteral();
                break;
              case REG_POS_HALF:
                {
                    typename OpTraits<DataType>::FloatT pos_half = 0.5;
                    std::memcpy((void*)srfData.data(), (void*)&pos_half,
                        sizeof(srfData));

                }
                break;
              case REG_NEG_HALF:
                {
                    typename OpTraits<DataType>::FloatT neg_half = -0.5;
                    std::memcpy((void*)srfData.data(), (void*)&neg_half,
                        sizeof(srfData));
                }
                break;
              case REG_POS_ONE:
                {
                    typename OpTraits<DataType>::FloatT pos_one = 1.0;
                    std::memcpy(srfData.data(), &pos_one, sizeof(srfData));
                }
                break;
              case REG_NEG_ONE:
                {
                    typename OpTraits<DataType>::FloatT neg_one = -1.0;
                    std::memcpy(srfData.data(), &neg_one, sizeof(srfData));
                }
                break;
              case REG_POS_TWO:
                {
                    typename OpTraits<DataType>::FloatT pos_two = 2.0;
                    std::memcpy(srfData.data(), &pos_two, sizeof(srfData));
                }
                break;
              case REG_NEG_TWO:
                {
                    typename OpTraits<DataType>::FloatT neg_two = -2.0;
                    std::memcpy(srfData.data(), &neg_two, sizeof(srfData));
                }
                break;
              case REG_POS_FOUR:
                {
                    typename OpTraits<DataType>::FloatT pos_four = 4.0;
                    std::memcpy(srfData.data(), &pos_four, sizeof(srfData));
                }
                break;
              case REG_NEG_FOUR:
                {
                    typename OpTraits<DataType>::FloatT neg_four = -4.0;
                    std::memcpy((void*)srfData.data(), (void*)&neg_four ,
                        sizeof(srfData));
                }
                break;
                case REG_PI:
                {
                    assert(sizeof(DataType) == sizeof(ScalarRegF64)
                        || sizeof(DataType) == sizeof(ScalarRegF32));

                    const ScalarRegU32 pi_u32(0x3e22f983UL);
                    const ScalarRegU64 pi_u64(0x3fc45f306dc9c882ULL);

                    if (sizeof(DataType) == sizeof(ScalarRegF64)) {
                        std::memcpy((void*)srfData.data(),
                            (void*)&pi_u64, sizeof(srfData));
                    } else {
                        std::memcpy((void*)srfData.data(),
                            (void*)&pi_u32, sizeof(srfData));
                    }
                }
                break;
              default:
                {
                    assert(sizeof(DataType) <= sizeof(srfData));
                    DataType misc_val
                        = (DataType)_gpuDynInst->readMiscReg(_opIdx);
                    std::memcpy((void*)srfData.data(), (void*)&misc_val,
                        sizeof(DataType));
                }
            }
        }

        /**
         * for scalars we need to do some extra work to figure out how to
         * map the op selector to the sgpr idx because some op selectors
         * do not map directly to the srf (i.e., vcc/flat_scratch).
         */
        int
        regIdx(int dword) const
        {
            Wavefront *wf = _gpuDynInst->wavefront();
            ComputeUnit *cu = _gpuDynInst->computeUnit();
            int sgprIdx(-1);

            if (_opIdx == REG_VCC_LO) {
                sgprIdx = cu->registerManager
                    .mapSgpr(wf, wf->reservedScalarRegs - 2 + dword);
            } else if (_opIdx == REG_FLAT_SCRATCH_HI) {
                sgprIdx = cu->registerManager
                    .mapSgpr(wf, wf->reservedScalarRegs - 3 + dword);
            } else if (_opIdx == REG_FLAT_SCRATCH_LO) {
                assert(NumDwords == 1);
                sgprIdx = cu->registerManager
                    .mapSgpr(wf, wf->reservedScalarRegs - 4 + dword);
            } else {
                sgprIdx = cu->registerManager.mapSgpr(wf, _opIdx + dword);
            }

            assert(sgprIdx > -1);

            return sgprIdx;
        }

        /**
         * in GCN3 each register is represented as a 32b unsigned value,
         * however operands may require up to 16 registers, so we store
         * all the individual 32b components here. for sub-dword operand
         * we still consider them to be 1 dword because the minimum size
         * of a register is 1 dword. this class will take care to do the
         * proper packing/unpacking of sub-dword operands.
         */
        std::array<ScalarRegU32, NumDwords> srfData;
    };

    // typedefs for the various sizes/types of scalar operands
    using ScalarOperandU8 = ScalarOperand<ScalarRegU8, false, 1>;
    using ScalarOperandI8 = ScalarOperand<ScalarRegI8, false, 1>;
    using ScalarOperandU16 = ScalarOperand<ScalarRegU16, false, 1>;
    using ScalarOperandI16 = ScalarOperand<ScalarRegI16, false, 1>;
    using ScalarOperandU32 = ScalarOperand<ScalarRegU32, false>;
    using ScalarOperandI32 = ScalarOperand<ScalarRegI32, false>;
    using ScalarOperandF32 = ScalarOperand<ScalarRegF32, false>;
    using ScalarOperandU64 = ScalarOperand<ScalarRegU64, false>;
    using ScalarOperandI64 = ScalarOperand<ScalarRegI64, false>;
    using ScalarOperandF64 = ScalarOperand<ScalarRegF64, false>;
    using ScalarOperandU128 = ScalarOperand<ScalarRegU32, false, 4>;
    using ScalarOperandU256 = ScalarOperand<ScalarRegU32, false, 8>;
    using ScalarOperandU512 = ScalarOperand<ScalarRegU32, false, 16>;
    // non-writeable versions of scalar operands
    using ConstScalarOperandU8 = ScalarOperand<ScalarRegU8, true, 1>;
    using ConstScalarOperandI8 = ScalarOperand<ScalarRegI8, true, 1>;
    using ConstScalarOperandU16 = ScalarOperand<ScalarRegU16, true, 1>;
    using ConstScalarOperandI16 = ScalarOperand<ScalarRegI16, true, 1>;
    using ConstScalarOperandU32 = ScalarOperand<ScalarRegU32, true>;
    using ConstScalarOperandI32 = ScalarOperand<ScalarRegI32, true>;
    using ConstScalarOperandF32 = ScalarOperand<ScalarRegF32, true>;
    using ConstScalarOperandU64 = ScalarOperand<ScalarRegU64, true>;
    using ConstScalarOperandI64 = ScalarOperand<ScalarRegI64, true>;
    using ConstScalarOperandF64 = ScalarOperand<ScalarRegF64, true>;
    using ConstScalarOperandU128 = ScalarOperand<ScalarRegU32, true, 4>;
    using ConstScalarOperandU256 = ScalarOperand<ScalarRegU32, true, 8>;
    using ConstScalarOperandU512 = ScalarOperand<ScalarRegU32, true, 16>;
    // typedefs for the various sizes/types of vector operands
    using VecOperandU8 = VecOperand<VecElemU8, false, 1>;
    using VecOperandI8 = VecOperand<VecElemI8, false, 1>;
    using VecOperandU16 = VecOperand<VecElemU16, false, 1>;
    using VecOperandI16 = VecOperand<VecElemI16, false, 1>;
    using VecOperandU32 = VecOperand<VecElemU32, false>;
    using VecOperandI32 = VecOperand<VecElemI32, false>;
    using VecOperandF32 = VecOperand<VecElemF32, false>;
    using VecOperandU64 = VecOperand<VecElemU64, false>;
    using VecOperandF64 = VecOperand<VecElemF64, false>;
    using VecOperandI64 = VecOperand<VecElemI64, false>;
    using VecOperandU96 = VecOperand<VecElemU32, false, 3>;
    using VecOperandU128 = VecOperand<VecElemU32, false, 4>;
    using VecOperandU256 = VecOperand<VecElemU32, false, 8>;
    using VecOperandU512 = VecOperand<VecElemU32, false, 16>;
    // non-writeable versions of vector operands
    using ConstVecOperandU8 = VecOperand<VecElemU8, true, 1>;
    using ConstVecOperandI8 = VecOperand<VecElemI8, true, 1>;
    using ConstVecOperandU16 = VecOperand<VecElemU16, true, 1>;
    using ConstVecOperandI16 = VecOperand<VecElemI16, true, 1>;
    using ConstVecOperandU32 = VecOperand<VecElemU32, true>;
    using ConstVecOperandI32 = VecOperand<VecElemI32, true>;
    using ConstVecOperandF32 = VecOperand<VecElemF32, true>;
    using ConstVecOperandU64 = VecOperand<VecElemU64, true>;
    using ConstVecOperandI64 = VecOperand<VecElemI64, true>;
    using ConstVecOperandF64 = VecOperand<VecElemF64, true>;
    using ConstVecOperandU96 = VecOperand<VecElemU32, true, 3>;
    using ConstVecOperandU128 = VecOperand<VecElemU32, true, 4>;
    using ConstVecOperandU256 = VecOperand<VecElemU32, true, 8>;
    using ConstVecOperandU512 = VecOperand<VecElemU32, true, 16>;
}

#endif // __ARCH_GCN3_OPERAND_HH__
