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

#ifndef __ARCH_GCN3_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_t<Condition, const DataType>
        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_t<Condition, DataType&>
        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_t<Condition, DataType>
        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) {
                    ScalarRegU64 new_exec_mask_val
                        = wf->execMask().to_ullong();
                    if (NumDwords == 1) {
                        std::memcpy((void*)&new_exec_mask_val,
                            (void*)srfData.data(), sizeof(VecElemU32));
                    } else if (NumDwords == 2) {
                        std::memcpy((void*)&new_exec_mask_val,
                            (void*)srfData.data(), sizeof(VecElemU64));
                    } else {
                        panic("Trying to write more than 2 DWORDS to EXEC\n");
                    }
                    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 if (_opIdx == REG_EXEC_HI) {
                    /**
                     * If we're writing only the upper half of the EXEC mask
                     * this ought to be a single dword operand.
                     */
                    assert(NumDwords == 1);
                    ScalarRegU32 new_exec_mask_hi_val(0);
                    ScalarRegU64 new_exec_mask_val
                        = wf->execMask().to_ullong();
                    std::memcpy((void*)&new_exec_mask_hi_val,
                        (void*)srfData.data(), sizeof(new_exec_mask_hi_val));
                    replaceBits(new_exec_mask_val, 63, 32,
                                new_exec_mask_hi_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_t<Condition, void>
        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_t<Condition, ScalarOperand&>
        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:
                {
                    if (NumDwords == 1) {
                        ScalarRegU32 exec_mask = _gpuDynInst->wavefront()->
                            execMask().to_ulong();
                        std::memcpy((void*)srfData.data(), (void*)&exec_mask,
                            sizeof(exec_mask));
                        DPRINTF(GPUSRF, "Read EXEC\n");
                        DPRINTF(GPUSRF, "EXEC = %#x\n", exec_mask);
                    } else {
                        assert(NumDwords == 2);
                        ScalarRegU64 exec_mask = _gpuDynInst->wavefront()->
                            execMask().to_ullong();
                        std::memcpy((void*)srfData.data(), (void*)&exec_mask,
                            sizeof(exec_mask));
                        DPRINTF(GPUSRF, "Read EXEC\n");
                        DPRINTF(GPUSRF, "EXEC = %#x\n", exec_mask);
                    }
                }
                break;
              case REG_EXEC_HI:
                {
                    /**
                     * If we're reading only the upper half of the EXEC mask
                     * this ought to be a single dword operand.
                     */
                    assert(NumDwords == 1);
                    ScalarRegU64 exec_mask = _gpuDynInst->wavefront()
                        ->execMask().to_ullong();

                    ScalarRegU32 exec_mask_hi = bits(exec_mask, 63, 32);
                    std::memcpy((void*)srfData.data(), (void*)&exec_mask_hi,
                                sizeof(exec_mask_hi));
                    DPRINTF(GPUSRF, "Read EXEC_HI\n");
                    DPRINTF(GPUSRF, "EXEC_HI = %#x\n", exec_mask_hi);
                }
                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(pos_half));

                }
                break;
              case REG_NEG_HALF:
                {
                    typename OpTraits<DataType>::FloatT neg_half = -0.5;
                    std::memcpy((void*)srfData.data(), (void*)&neg_half,
                        sizeof(neg_half));
                }
                break;
              case REG_POS_ONE:
                {
                    typename OpTraits<DataType>::FloatT pos_one = 1.0;
                    std::memcpy(srfData.data(), &pos_one, sizeof(pos_one));
                }
                break;
              case REG_NEG_ONE:
                {
                    typename OpTraits<DataType>::FloatT neg_one = -1.0;
                    std::memcpy(srfData.data(), &neg_one, sizeof(neg_one));
                }
                break;
              case REG_POS_TWO:
                {
                    typename OpTraits<DataType>::FloatT pos_two = 2.0;
                    std::memcpy(srfData.data(), &pos_two, sizeof(pos_two));
                }
                break;
              case REG_NEG_TWO:
                {
                    typename OpTraits<DataType>::FloatT neg_two = -2.0;
                    std::memcpy(srfData.data(), &neg_two, sizeof(neg_two));
                }
                break;
              case REG_POS_FOUR:
                {
                    typename OpTraits<DataType>::FloatT pos_four = 4.0;
                    std::memcpy(srfData.data(), &pos_four, sizeof(pos_four));
                }
                break;
              case REG_NEG_FOUR:
                {
                    typename OpTraits<DataType>::FloatT neg_four = -4.0;
                    std::memcpy((void*)srfData.data(), (void*)&neg_four ,
                        sizeof(neg_four));
                }
                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(pi_u64));
                    } else {
                        std::memcpy((void*)srfData.data(),
                            (void*)&pi_u32, sizeof(pi_u32));
                    }
                }
                break;
              default:
                {
                    assert(sizeof(DataType) <= sizeof(srfData));
                    DataType misc_val(0);
                    if (isConstVal(_opIdx)) {
                        misc_val = (DataType)_gpuDynInst
                            ->readConstVal<DataType>(_opIdx);
                    } else {
                        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__
