111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2012-2015 Advanced Micro Devices, Inc.
311308Santhony.gutierrez@amd.com * All rights reserved.
411308Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only
611308Santhony.gutierrez@amd.com *
711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met:
911308Santhony.gutierrez@amd.com *
1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice,
1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer.
1211308Santhony.gutierrez@amd.com *
1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice,
1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation
1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution.
1611308Santhony.gutierrez@amd.com *
1711308Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its contributors
1811308Santhony.gutierrez@amd.com * may be used to endorse or promote products derived from this software
1911308Santhony.gutierrez@amd.com * without specific prior written permission.
2011308Santhony.gutierrez@amd.com *
2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE.
3211308Santhony.gutierrez@amd.com *
3311308Santhony.gutierrez@amd.com * Author: Steve Reinhardt
3411308Santhony.gutierrez@amd.com */
3511308Santhony.gutierrez@amd.com
3611308Santhony.gutierrez@amd.com#ifndef __ARCH_HSAIL_INSTS_DECL_HH__
3711308Santhony.gutierrez@amd.com#define __ARCH_HSAIL_INSTS_DECL_HH__
3811308Santhony.gutierrez@amd.com
3911308Santhony.gutierrez@amd.com#include <cmath>
4011308Santhony.gutierrez@amd.com
4111308Santhony.gutierrez@amd.com#include "arch/hsail/insts/gpu_static_inst.hh"
4211308Santhony.gutierrez@amd.com#include "arch/hsail/operand.hh"
4311308Santhony.gutierrez@amd.com#include "debug/HSAIL.hh"
4411308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_dyn_inst.hh"
4511308Santhony.gutierrez@amd.com#include "gpu-compute/shader.hh"
4611308Santhony.gutierrez@amd.com
4711308Santhony.gutierrez@amd.comnamespace HsailISA
4811308Santhony.gutierrez@amd.com{
4911308Santhony.gutierrez@amd.com    template<typename _DestOperand, typename _SrcOperand>
5011308Santhony.gutierrez@amd.com    class HsailOperandType
5111308Santhony.gutierrez@amd.com    {
5211308Santhony.gutierrez@amd.com      public:
5311308Santhony.gutierrez@amd.com        typedef _DestOperand DestOperand;
5411308Santhony.gutierrez@amd.com        typedef _SrcOperand SrcOperand;
5511308Santhony.gutierrez@amd.com    };
5611308Santhony.gutierrez@amd.com
5711308Santhony.gutierrez@amd.com    typedef HsailOperandType<CRegOperand, CRegOrImmOperand> CRegOperandType;
5811308Santhony.gutierrez@amd.com    typedef HsailOperandType<SRegOperand, SRegOrImmOperand> SRegOperandType;
5911308Santhony.gutierrez@amd.com    typedef HsailOperandType<DRegOperand, DRegOrImmOperand> DRegOperandType;
6011308Santhony.gutierrez@amd.com
6111308Santhony.gutierrez@amd.com    // The IsBits parameter serves only to disambiguate tbhe B* types from
6211308Santhony.gutierrez@amd.com    // the U* types, which otherwise would be identical (and
6311308Santhony.gutierrez@amd.com    // indistinguishable).
6411308Santhony.gutierrez@amd.com    template<typename _OperandType, typename _CType, Enums::MemType _memType,
6511308Santhony.gutierrez@amd.com             vgpr_type _vgprType, int IsBits=0>
6611308Santhony.gutierrez@amd.com    class HsailDataType
6711308Santhony.gutierrez@amd.com    {
6811308Santhony.gutierrez@amd.com      public:
6911308Santhony.gutierrez@amd.com        typedef _OperandType OperandType;
7011308Santhony.gutierrez@amd.com        typedef _CType CType;
7111308Santhony.gutierrez@amd.com        static const Enums::MemType memType = _memType;
7211308Santhony.gutierrez@amd.com        static const vgpr_type vgprType = _vgprType;
7311308Santhony.gutierrez@amd.com        static const char *label;
7411308Santhony.gutierrez@amd.com    };
7511308Santhony.gutierrez@amd.com
7611308Santhony.gutierrez@amd.com    typedef HsailDataType<CRegOperandType, bool, Enums::M_U8, VT_32, 1> B1;
7711308Santhony.gutierrez@amd.com    typedef HsailDataType<SRegOperandType, uint8_t, Enums::M_U8, VT_32, 1> B8;
7811308Santhony.gutierrez@amd.com
7911308Santhony.gutierrez@amd.com    typedef HsailDataType<SRegOperandType, uint16_t,
8011308Santhony.gutierrez@amd.com                          Enums::M_U16, VT_32, 1> B16;
8111308Santhony.gutierrez@amd.com
8211308Santhony.gutierrez@amd.com    typedef HsailDataType<SRegOperandType, uint32_t,
8311308Santhony.gutierrez@amd.com                          Enums::M_U32, VT_32, 1> B32;
8411308Santhony.gutierrez@amd.com
8511308Santhony.gutierrez@amd.com    typedef HsailDataType<DRegOperandType, uint64_t,
8611308Santhony.gutierrez@amd.com                          Enums::M_U64, VT_64, 1> B64;
8711308Santhony.gutierrez@amd.com
8811308Santhony.gutierrez@amd.com    typedef HsailDataType<SRegOperandType, int8_t, Enums::M_S8, VT_32> S8;
8911308Santhony.gutierrez@amd.com    typedef HsailDataType<SRegOperandType, int16_t, Enums::M_S16, VT_32> S16;
9011308Santhony.gutierrez@amd.com    typedef HsailDataType<SRegOperandType, int32_t, Enums::M_S32, VT_32> S32;
9111308Santhony.gutierrez@amd.com    typedef HsailDataType<DRegOperandType, int64_t, Enums::M_S64, VT_64> S64;
9211308Santhony.gutierrez@amd.com
9311308Santhony.gutierrez@amd.com    typedef HsailDataType<SRegOperandType, uint8_t, Enums::M_U8, VT_32> U8;
9411308Santhony.gutierrez@amd.com    typedef HsailDataType<SRegOperandType, uint16_t, Enums::M_U16, VT_32> U16;
9511308Santhony.gutierrez@amd.com    typedef HsailDataType<SRegOperandType, uint32_t, Enums::M_U32, VT_32> U32;
9611308Santhony.gutierrez@amd.com    typedef HsailDataType<DRegOperandType, uint64_t, Enums::M_U64, VT_64> U64;
9711308Santhony.gutierrez@amd.com
9811308Santhony.gutierrez@amd.com    typedef HsailDataType<SRegOperandType, float, Enums::M_F32, VT_32> F32;
9911308Santhony.gutierrez@amd.com    typedef HsailDataType<DRegOperandType, double, Enums::M_F64, VT_64> F64;
10011308Santhony.gutierrez@amd.com
10111308Santhony.gutierrez@amd.com    template<typename DestOperandType, typename SrcOperandType,
10211308Santhony.gutierrez@amd.com             int NumSrcOperands>
10311308Santhony.gutierrez@amd.com    class CommonInstBase : public HsailGPUStaticInst
10411308Santhony.gutierrez@amd.com    {
10511308Santhony.gutierrez@amd.com      protected:
10611308Santhony.gutierrez@amd.com        typename DestOperandType::DestOperand dest;
10711308Santhony.gutierrez@amd.com        typename SrcOperandType::SrcOperand src[NumSrcOperands];
10811308Santhony.gutierrez@amd.com
10911308Santhony.gutierrez@amd.com        void
11011308Santhony.gutierrez@amd.com        generateDisassembly()
11111308Santhony.gutierrez@amd.com        {
11211308Santhony.gutierrez@amd.com            disassembly = csprintf("%s%s %s", opcode, opcode_suffix(),
11311308Santhony.gutierrez@amd.com                                   dest.disassemble());
11411308Santhony.gutierrez@amd.com
11511308Santhony.gutierrez@amd.com            for (int i = 0; i < NumSrcOperands; ++i) {
11611308Santhony.gutierrez@amd.com                disassembly += ",";
11711308Santhony.gutierrez@amd.com                disassembly += src[i].disassemble();
11811308Santhony.gutierrez@amd.com            }
11911308Santhony.gutierrez@amd.com        }
12011308Santhony.gutierrez@amd.com
12111308Santhony.gutierrez@amd.com        virtual std::string opcode_suffix() = 0;
12211308Santhony.gutierrez@amd.com
12311308Santhony.gutierrez@amd.com      public:
12411308Santhony.gutierrez@amd.com        CommonInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj,
12511308Santhony.gutierrez@amd.com                       const char *opcode)
12611308Santhony.gutierrez@amd.com            : HsailGPUStaticInst(obj, opcode)
12711308Santhony.gutierrez@amd.com        {
12811692Santhony.gutierrez@amd.com            setFlag(ALU);
12911692Santhony.gutierrez@amd.com
13011308Santhony.gutierrez@amd.com            unsigned op_offs = obj->getOperandPtr(ib->operands, 0);
13111308Santhony.gutierrez@amd.com
13211308Santhony.gutierrez@amd.com            dest.init(op_offs, obj);
13311308Santhony.gutierrez@amd.com
13411308Santhony.gutierrez@amd.com            for (int i = 0; i < NumSrcOperands; ++i) {
13511308Santhony.gutierrez@amd.com                op_offs = obj->getOperandPtr(ib->operands, i + 1);
13611308Santhony.gutierrez@amd.com                src[i].init(op_offs, obj);
13711308Santhony.gutierrez@amd.com            }
13811308Santhony.gutierrez@amd.com        }
13911308Santhony.gutierrez@amd.com
14011308Santhony.gutierrez@amd.com        bool isVectorRegister(int operandIndex) {
14111308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
14211308Santhony.gutierrez@amd.com            if (operandIndex < NumSrcOperands)
14311308Santhony.gutierrez@amd.com                return src[operandIndex].isVectorRegister();
14411308Santhony.gutierrez@amd.com            else
14511308Santhony.gutierrez@amd.com                return dest.isVectorRegister();
14611308Santhony.gutierrez@amd.com        }
14711308Santhony.gutierrez@amd.com        bool isCondRegister(int operandIndex) {
14811308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
14911308Santhony.gutierrez@amd.com            if (operandIndex < NumSrcOperands)
15011308Santhony.gutierrez@amd.com                return src[operandIndex].isCondRegister();
15111308Santhony.gutierrez@amd.com            else
15211308Santhony.gutierrez@amd.com                return dest.isCondRegister();
15311308Santhony.gutierrez@amd.com        }
15411308Santhony.gutierrez@amd.com        bool isScalarRegister(int operandIndex) {
15511308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
15611308Santhony.gutierrez@amd.com            if (operandIndex < NumSrcOperands)
15711308Santhony.gutierrez@amd.com                return src[operandIndex].isScalarRegister();
15811308Santhony.gutierrez@amd.com            else
15911308Santhony.gutierrez@amd.com                return dest.isScalarRegister();
16011308Santhony.gutierrez@amd.com        }
16111308Santhony.gutierrez@amd.com        bool isSrcOperand(int operandIndex) {
16211308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
16311308Santhony.gutierrez@amd.com            if (operandIndex < NumSrcOperands)
16411308Santhony.gutierrez@amd.com                return true;
16511308Santhony.gutierrez@amd.com            return false;
16611308Santhony.gutierrez@amd.com        }
16711308Santhony.gutierrez@amd.com
16811308Santhony.gutierrez@amd.com        bool isDstOperand(int operandIndex) {
16911308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
17011308Santhony.gutierrez@amd.com            if (operandIndex >= NumSrcOperands)
17111308Santhony.gutierrez@amd.com                return true;
17211308Santhony.gutierrez@amd.com            return false;
17311308Santhony.gutierrez@amd.com        }
17411308Santhony.gutierrez@amd.com        int getOperandSize(int operandIndex) {
17511308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
17611308Santhony.gutierrez@amd.com            if (operandIndex < NumSrcOperands)
17711308Santhony.gutierrez@amd.com                return src[operandIndex].opSize();
17811308Santhony.gutierrez@amd.com            else
17911308Santhony.gutierrez@amd.com                return dest.opSize();
18011308Santhony.gutierrez@amd.com        }
18111699Santhony.gutierrez@amd.com        int
18211699Santhony.gutierrez@amd.com        getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst)
18311699Santhony.gutierrez@amd.com        {
18411308Santhony.gutierrez@amd.com            assert(operandIndex >= 0 && operandIndex < getNumOperands());
18511308Santhony.gutierrez@amd.com
18611308Santhony.gutierrez@amd.com            if (operandIndex < NumSrcOperands)
18711308Santhony.gutierrez@amd.com                return src[operandIndex].regIndex();
18811308Santhony.gutierrez@amd.com            else
18911308Santhony.gutierrez@amd.com                return dest.regIndex();
19011308Santhony.gutierrez@amd.com        }
19111308Santhony.gutierrez@amd.com        int numSrcRegOperands() {
19211308Santhony.gutierrez@amd.com            int operands = 0;
19311308Santhony.gutierrez@amd.com            for (int i = 0; i < NumSrcOperands; i++) {
19411325Ssteve.reinhardt@amd.com                if (src[i].isVectorRegister()) {
19511308Santhony.gutierrez@amd.com                    operands++;
19611308Santhony.gutierrez@amd.com                }
19711308Santhony.gutierrez@amd.com            }
19811308Santhony.gutierrez@amd.com            return operands;
19911308Santhony.gutierrez@amd.com        }
20011308Santhony.gutierrez@amd.com        int numDstRegOperands() { return dest.isVectorRegister(); }
20111308Santhony.gutierrez@amd.com        int getNumOperands() { return NumSrcOperands + 1; }
20211308Santhony.gutierrez@amd.com    };
20311308Santhony.gutierrez@amd.com
20411308Santhony.gutierrez@amd.com    template<typename DataType, int NumSrcOperands>
20511308Santhony.gutierrez@amd.com    class ArithInst : public CommonInstBase<typename DataType::OperandType,
20611308Santhony.gutierrez@amd.com                                            typename DataType::OperandType,
20711308Santhony.gutierrez@amd.com                                            NumSrcOperands>
20811308Santhony.gutierrez@amd.com    {
20911308Santhony.gutierrez@amd.com      public:
21011308Santhony.gutierrez@amd.com        std::string opcode_suffix() { return csprintf("_%s", DataType::label); }
21111308Santhony.gutierrez@amd.com
21211308Santhony.gutierrez@amd.com        ArithInst(const Brig::BrigInstBase *ib, const BrigObject *obj,
21311308Santhony.gutierrez@amd.com                  const char *opcode)
21411308Santhony.gutierrez@amd.com            : CommonInstBase<typename DataType::OperandType,
21511308Santhony.gutierrez@amd.com                             typename DataType::OperandType,
21611308Santhony.gutierrez@amd.com                             NumSrcOperands>(ib, obj, opcode)
21711308Santhony.gutierrez@amd.com        {
21811308Santhony.gutierrez@amd.com        }
21911308Santhony.gutierrez@amd.com    };
22011308Santhony.gutierrez@amd.com
22111308Santhony.gutierrez@amd.com    template<typename DestOperandType, typename Src0OperandType,
22211308Santhony.gutierrez@amd.com             typename Src1OperandType, typename Src2OperandType>
22311308Santhony.gutierrez@amd.com    class ThreeNonUniformSourceInstBase : public HsailGPUStaticInst
22411308Santhony.gutierrez@amd.com    {
22511308Santhony.gutierrez@amd.com      protected:
22611308Santhony.gutierrez@amd.com        typename DestOperandType::DestOperand dest;
22711308Santhony.gutierrez@amd.com        typename Src0OperandType::SrcOperand  src0;
22811308Santhony.gutierrez@amd.com        typename Src1OperandType::SrcOperand  src1;
22911308Santhony.gutierrez@amd.com        typename Src2OperandType::SrcOperand  src2;
23011308Santhony.gutierrez@amd.com
23111308Santhony.gutierrez@amd.com        void
23211308Santhony.gutierrez@amd.com        generateDisassembly()
23311308Santhony.gutierrez@amd.com        {
23411308Santhony.gutierrez@amd.com            disassembly = csprintf("%s %s,%s,%s,%s", opcode, dest.disassemble(),
23511308Santhony.gutierrez@amd.com                                   src0.disassemble(), src1.disassemble(),
23611308Santhony.gutierrez@amd.com                                   src2.disassemble());
23711308Santhony.gutierrez@amd.com        }
23811308Santhony.gutierrez@amd.com
23911308Santhony.gutierrez@amd.com      public:
24011308Santhony.gutierrez@amd.com        ThreeNonUniformSourceInstBase(const Brig::BrigInstBase *ib,
24111308Santhony.gutierrez@amd.com                                      const BrigObject *obj,
24211308Santhony.gutierrez@amd.com                                      const char *opcode)
24311308Santhony.gutierrez@amd.com            : HsailGPUStaticInst(obj, opcode)
24411308Santhony.gutierrez@amd.com        {
24511692Santhony.gutierrez@amd.com            setFlag(ALU);
24611692Santhony.gutierrez@amd.com
24711308Santhony.gutierrez@amd.com            unsigned op_offs = obj->getOperandPtr(ib->operands, 0);
24811308Santhony.gutierrez@amd.com            dest.init(op_offs, obj);
24911308Santhony.gutierrez@amd.com
25011308Santhony.gutierrez@amd.com            op_offs = obj->getOperandPtr(ib->operands, 1);
25111308Santhony.gutierrez@amd.com            src0.init(op_offs, obj);
25211308Santhony.gutierrez@amd.com
25311308Santhony.gutierrez@amd.com            op_offs = obj->getOperandPtr(ib->operands, 2);
25411308Santhony.gutierrez@amd.com            src1.init(op_offs, obj);
25511308Santhony.gutierrez@amd.com
25611308Santhony.gutierrez@amd.com            op_offs = obj->getOperandPtr(ib->operands, 3);
25711308Santhony.gutierrez@amd.com            src2.init(op_offs, obj);
25811308Santhony.gutierrez@amd.com        }
25911308Santhony.gutierrez@amd.com
26011308Santhony.gutierrez@amd.com        bool isVectorRegister(int operandIndex) {
26111308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
26211308Santhony.gutierrez@amd.com            if (!operandIndex)
26311308Santhony.gutierrez@amd.com                return src0.isVectorRegister();
26411308Santhony.gutierrez@amd.com            else if (operandIndex == 1)
26511308Santhony.gutierrez@amd.com                return src1.isVectorRegister();
26611308Santhony.gutierrez@amd.com            else if (operandIndex == 2)
26711308Santhony.gutierrez@amd.com                return src2.isVectorRegister();
26811308Santhony.gutierrez@amd.com            else
26911308Santhony.gutierrez@amd.com                return dest.isVectorRegister();
27011308Santhony.gutierrez@amd.com        }
27111308Santhony.gutierrez@amd.com        bool isCondRegister(int operandIndex) {
27211308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
27311308Santhony.gutierrez@amd.com            if (!operandIndex)
27411308Santhony.gutierrez@amd.com                return src0.isCondRegister();
27511308Santhony.gutierrez@amd.com            else if (operandIndex == 1)
27611308Santhony.gutierrez@amd.com                return src1.isCondRegister();
27711308Santhony.gutierrez@amd.com            else if (operandIndex == 2)
27811308Santhony.gutierrez@amd.com                return src2.isCondRegister();
27911308Santhony.gutierrez@amd.com            else
28011308Santhony.gutierrez@amd.com                return dest.isCondRegister();
28111308Santhony.gutierrez@amd.com        }
28211308Santhony.gutierrez@amd.com        bool isScalarRegister(int operandIndex) {
28311308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
28411308Santhony.gutierrez@amd.com            if (!operandIndex)
28511308Santhony.gutierrez@amd.com                return src0.isScalarRegister();
28611308Santhony.gutierrez@amd.com            else if (operandIndex == 1)
28711308Santhony.gutierrez@amd.com                return src1.isScalarRegister();
28811308Santhony.gutierrez@amd.com            else if (operandIndex == 2)
28911308Santhony.gutierrez@amd.com                return src2.isScalarRegister();
29011308Santhony.gutierrez@amd.com            else
29111308Santhony.gutierrez@amd.com                return dest.isScalarRegister();
29211308Santhony.gutierrez@amd.com        }
29311308Santhony.gutierrez@amd.com        bool isSrcOperand(int operandIndex) {
29411308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
29511308Santhony.gutierrez@amd.com            if (operandIndex < 3)
29611308Santhony.gutierrez@amd.com                return true;
29711308Santhony.gutierrez@amd.com            else
29811308Santhony.gutierrez@amd.com                return false;
29911308Santhony.gutierrez@amd.com        }
30011308Santhony.gutierrez@amd.com        bool isDstOperand(int operandIndex) {
30111308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
30211308Santhony.gutierrez@amd.com            if (operandIndex >= 3)
30311308Santhony.gutierrez@amd.com                return true;
30411308Santhony.gutierrez@amd.com            else
30511308Santhony.gutierrez@amd.com                return false;
30611308Santhony.gutierrez@amd.com        }
30711308Santhony.gutierrez@amd.com        int getOperandSize(int operandIndex) {
30811308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
30911308Santhony.gutierrez@amd.com            if (!operandIndex)
31011308Santhony.gutierrez@amd.com                return src0.opSize();
31111308Santhony.gutierrez@amd.com            else if (operandIndex == 1)
31211308Santhony.gutierrez@amd.com                return src1.opSize();
31311308Santhony.gutierrez@amd.com            else if (operandIndex == 2)
31411308Santhony.gutierrez@amd.com                return src2.opSize();
31511308Santhony.gutierrez@amd.com            else
31611308Santhony.gutierrez@amd.com                return dest.opSize();
31711308Santhony.gutierrez@amd.com        }
31811699Santhony.gutierrez@amd.com
31911699Santhony.gutierrez@amd.com        int
32011699Santhony.gutierrez@amd.com        getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst)
32111699Santhony.gutierrez@amd.com        {
32211308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
32311308Santhony.gutierrez@amd.com            if (!operandIndex)
32411308Santhony.gutierrez@amd.com                return src0.regIndex();
32511308Santhony.gutierrez@amd.com            else if (operandIndex == 1)
32611308Santhony.gutierrez@amd.com                return src1.regIndex();
32711308Santhony.gutierrez@amd.com            else if (operandIndex == 2)
32811308Santhony.gutierrez@amd.com                return src2.regIndex();
32911308Santhony.gutierrez@amd.com            else
33011308Santhony.gutierrez@amd.com                return dest.regIndex();
33111308Santhony.gutierrez@amd.com        }
33211308Santhony.gutierrez@amd.com
33311308Santhony.gutierrez@amd.com        int numSrcRegOperands() {
33411308Santhony.gutierrez@amd.com            int operands = 0;
33511325Ssteve.reinhardt@amd.com            if (src0.isVectorRegister()) {
33611308Santhony.gutierrez@amd.com                operands++;
33711308Santhony.gutierrez@amd.com            }
33811325Ssteve.reinhardt@amd.com            if (src1.isVectorRegister()) {
33911308Santhony.gutierrez@amd.com                operands++;
34011308Santhony.gutierrez@amd.com            }
34111325Ssteve.reinhardt@amd.com            if (src2.isVectorRegister()) {
34211308Santhony.gutierrez@amd.com                operands++;
34311308Santhony.gutierrez@amd.com            }
34411308Santhony.gutierrez@amd.com            return operands;
34511308Santhony.gutierrez@amd.com        }
34611308Santhony.gutierrez@amd.com        int numDstRegOperands() { return dest.isVectorRegister(); }
34711308Santhony.gutierrez@amd.com        int getNumOperands() { return 4; }
34811308Santhony.gutierrez@amd.com    };
34911308Santhony.gutierrez@amd.com
35011308Santhony.gutierrez@amd.com    template<typename DestDataType, typename Src0DataType,
35111308Santhony.gutierrez@amd.com             typename Src1DataType, typename Src2DataType>
35211308Santhony.gutierrez@amd.com    class ThreeNonUniformSourceInst :
35311308Santhony.gutierrez@amd.com        public ThreeNonUniformSourceInstBase<typename DestDataType::OperandType,
35411308Santhony.gutierrez@amd.com                                             typename Src0DataType::OperandType,
35511308Santhony.gutierrez@amd.com                                             typename Src1DataType::OperandType,
35611308Santhony.gutierrez@amd.com                                             typename Src2DataType::OperandType>
35711308Santhony.gutierrez@amd.com    {
35811308Santhony.gutierrez@amd.com      public:
35911308Santhony.gutierrez@amd.com        typedef typename DestDataType::CType DestCType;
36011308Santhony.gutierrez@amd.com        typedef typename Src0DataType::CType Src0CType;
36111308Santhony.gutierrez@amd.com        typedef typename Src1DataType::CType Src1CType;
36211308Santhony.gutierrez@amd.com        typedef typename Src2DataType::CType Src2CType;
36311308Santhony.gutierrez@amd.com
36411308Santhony.gutierrez@amd.com        ThreeNonUniformSourceInst(const Brig::BrigInstBase *ib,
36511308Santhony.gutierrez@amd.com                                  const BrigObject *obj, const char *opcode)
36611308Santhony.gutierrez@amd.com            : ThreeNonUniformSourceInstBase<typename DestDataType::OperandType,
36711308Santhony.gutierrez@amd.com                                         typename Src0DataType::OperandType,
36811308Santhony.gutierrez@amd.com                                         typename Src1DataType::OperandType,
36911308Santhony.gutierrez@amd.com                                         typename Src2DataType::OperandType>(ib,
37011308Santhony.gutierrez@amd.com                                                                    obj, opcode)
37111308Santhony.gutierrez@amd.com        {
37211308Santhony.gutierrez@amd.com        }
37311308Santhony.gutierrez@amd.com    };
37411308Santhony.gutierrez@amd.com
37511308Santhony.gutierrez@amd.com    template<typename DataType>
37611308Santhony.gutierrez@amd.com    class CmovInst : public ThreeNonUniformSourceInst<DataType, B1,
37711308Santhony.gutierrez@amd.com                                                      DataType, DataType>
37811308Santhony.gutierrez@amd.com    {
37911308Santhony.gutierrez@amd.com      public:
38011308Santhony.gutierrez@amd.com        CmovInst(const Brig::BrigInstBase *ib, const BrigObject *obj,
38111308Santhony.gutierrez@amd.com                 const char *opcode)
38211308Santhony.gutierrez@amd.com            : ThreeNonUniformSourceInst<DataType, B1, DataType,
38311308Santhony.gutierrez@amd.com                                        DataType>(ib, obj, opcode)
38411308Santhony.gutierrez@amd.com        {
38511308Santhony.gutierrez@amd.com        }
38611308Santhony.gutierrez@amd.com    };
38711308Santhony.gutierrez@amd.com
38811308Santhony.gutierrez@amd.com    template<typename DataType>
38911308Santhony.gutierrez@amd.com    class ExtractInsertInst : public ThreeNonUniformSourceInst<DataType,
39011308Santhony.gutierrez@amd.com                                                               DataType, U32,
39111308Santhony.gutierrez@amd.com                                                               U32>
39211308Santhony.gutierrez@amd.com    {
39311308Santhony.gutierrez@amd.com      public:
39411308Santhony.gutierrez@amd.com        ExtractInsertInst(const Brig::BrigInstBase *ib, const BrigObject *obj,
39511308Santhony.gutierrez@amd.com                          const char *opcode)
39611308Santhony.gutierrez@amd.com            : ThreeNonUniformSourceInst<DataType, DataType, U32,
39711308Santhony.gutierrez@amd.com                                        U32>(ib, obj, opcode)
39811308Santhony.gutierrez@amd.com        {
39911308Santhony.gutierrez@amd.com        }
40011308Santhony.gutierrez@amd.com    };
40111308Santhony.gutierrez@amd.com
40211308Santhony.gutierrez@amd.com    template<typename DestOperandType, typename Src0OperandType,
40311308Santhony.gutierrez@amd.com             typename Src1OperandType>
40411308Santhony.gutierrez@amd.com    class TwoNonUniformSourceInstBase : public HsailGPUStaticInst
40511308Santhony.gutierrez@amd.com    {
40611308Santhony.gutierrez@amd.com      protected:
40711308Santhony.gutierrez@amd.com        typename DestOperandType::DestOperand dest;
40811308Santhony.gutierrez@amd.com        typename Src0OperandType::SrcOperand src0;
40911308Santhony.gutierrez@amd.com        typename Src1OperandType::SrcOperand src1;
41011308Santhony.gutierrez@amd.com
41111308Santhony.gutierrez@amd.com        void
41211308Santhony.gutierrez@amd.com        generateDisassembly()
41311308Santhony.gutierrez@amd.com        {
41411308Santhony.gutierrez@amd.com            disassembly = csprintf("%s %s,%s,%s", opcode, dest.disassemble(),
41511308Santhony.gutierrez@amd.com                                   src0.disassemble(), src1.disassemble());
41611308Santhony.gutierrez@amd.com        }
41711308Santhony.gutierrez@amd.com
41811308Santhony.gutierrez@amd.com
41911308Santhony.gutierrez@amd.com      public:
42011308Santhony.gutierrez@amd.com        TwoNonUniformSourceInstBase(const Brig::BrigInstBase *ib,
42111308Santhony.gutierrez@amd.com                                    const BrigObject *obj, const char *opcode)
42211308Santhony.gutierrez@amd.com            : HsailGPUStaticInst(obj, opcode)
42311308Santhony.gutierrez@amd.com        {
42411692Santhony.gutierrez@amd.com            setFlag(ALU);
42511692Santhony.gutierrez@amd.com
42611308Santhony.gutierrez@amd.com            unsigned op_offs = obj->getOperandPtr(ib->operands, 0);
42711308Santhony.gutierrez@amd.com            dest.init(op_offs, obj);
42811308Santhony.gutierrez@amd.com
42911308Santhony.gutierrez@amd.com            op_offs = obj->getOperandPtr(ib->operands, 1);
43011308Santhony.gutierrez@amd.com            src0.init(op_offs, obj);
43111308Santhony.gutierrez@amd.com
43211308Santhony.gutierrez@amd.com            op_offs = obj->getOperandPtr(ib->operands, 2);
43311308Santhony.gutierrez@amd.com            src1.init(op_offs, obj);
43411308Santhony.gutierrez@amd.com        }
43511308Santhony.gutierrez@amd.com        bool isVectorRegister(int operandIndex) {
43611308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
43711308Santhony.gutierrez@amd.com            if (!operandIndex)
43811308Santhony.gutierrez@amd.com                return src0.isVectorRegister();
43911308Santhony.gutierrez@amd.com            else if (operandIndex == 1)
44011308Santhony.gutierrez@amd.com                return src1.isVectorRegister();
44111308Santhony.gutierrez@amd.com            else
44211308Santhony.gutierrez@amd.com                return dest.isVectorRegister();
44311308Santhony.gutierrez@amd.com        }
44411308Santhony.gutierrez@amd.com        bool isCondRegister(int operandIndex) {
44511308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
44611308Santhony.gutierrez@amd.com            if (!operandIndex)
44711308Santhony.gutierrez@amd.com                return src0.isCondRegister();
44811308Santhony.gutierrez@amd.com            else if (operandIndex == 1)
44911308Santhony.gutierrez@amd.com                return src1.isCondRegister();
45011308Santhony.gutierrez@amd.com            else
45111308Santhony.gutierrez@amd.com                return dest.isCondRegister();
45211308Santhony.gutierrez@amd.com        }
45311308Santhony.gutierrez@amd.com        bool isScalarRegister(int operandIndex) {
45411308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
45511308Santhony.gutierrez@amd.com            if (!operandIndex)
45611308Santhony.gutierrez@amd.com                return src0.isScalarRegister();
45711308Santhony.gutierrez@amd.com            else if (operandIndex == 1)
45811308Santhony.gutierrez@amd.com                return src1.isScalarRegister();
45911308Santhony.gutierrez@amd.com            else
46011308Santhony.gutierrez@amd.com                return dest.isScalarRegister();
46111308Santhony.gutierrez@amd.com        }
46211308Santhony.gutierrez@amd.com        bool isSrcOperand(int operandIndex) {
46311308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
46411308Santhony.gutierrez@amd.com            if (operandIndex < 2)
46511308Santhony.gutierrez@amd.com                return true;
46611308Santhony.gutierrez@amd.com            else
46711308Santhony.gutierrez@amd.com                return false;
46811308Santhony.gutierrez@amd.com        }
46911308Santhony.gutierrez@amd.com        bool isDstOperand(int operandIndex) {
47011308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
47111308Santhony.gutierrez@amd.com            if (operandIndex >= 2)
47211308Santhony.gutierrez@amd.com                return true;
47311308Santhony.gutierrez@amd.com            else
47411308Santhony.gutierrez@amd.com                return false;
47511308Santhony.gutierrez@amd.com        }
47611308Santhony.gutierrez@amd.com        int getOperandSize(int operandIndex) {
47711308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
47811308Santhony.gutierrez@amd.com            if (!operandIndex)
47911308Santhony.gutierrez@amd.com                return src0.opSize();
48011308Santhony.gutierrez@amd.com            else if (operandIndex == 1)
48111308Santhony.gutierrez@amd.com                return src1.opSize();
48211308Santhony.gutierrez@amd.com            else
48311308Santhony.gutierrez@amd.com                return dest.opSize();
48411308Santhony.gutierrez@amd.com        }
48511699Santhony.gutierrez@amd.com
48611699Santhony.gutierrez@amd.com        int
48711699Santhony.gutierrez@amd.com        getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst)
48811699Santhony.gutierrez@amd.com        {
48911308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
49011308Santhony.gutierrez@amd.com            if (!operandIndex)
49111308Santhony.gutierrez@amd.com                return src0.regIndex();
49211308Santhony.gutierrez@amd.com            else if (operandIndex == 1)
49311308Santhony.gutierrez@amd.com                return src1.regIndex();
49411308Santhony.gutierrez@amd.com            else
49511308Santhony.gutierrez@amd.com                return dest.regIndex();
49611308Santhony.gutierrez@amd.com        }
49711308Santhony.gutierrez@amd.com
49811308Santhony.gutierrez@amd.com        int numSrcRegOperands() {
49911308Santhony.gutierrez@amd.com            int operands = 0;
50011325Ssteve.reinhardt@amd.com            if (src0.isVectorRegister()) {
50111308Santhony.gutierrez@amd.com                operands++;
50211308Santhony.gutierrez@amd.com            }
50311325Ssteve.reinhardt@amd.com            if (src1.isVectorRegister()) {
50411308Santhony.gutierrez@amd.com                operands++;
50511308Santhony.gutierrez@amd.com            }
50611308Santhony.gutierrez@amd.com            return operands;
50711308Santhony.gutierrez@amd.com        }
50811308Santhony.gutierrez@amd.com        int numDstRegOperands() { return dest.isVectorRegister(); }
50911308Santhony.gutierrez@amd.com        int getNumOperands() { return 3; }
51011308Santhony.gutierrez@amd.com    };
51111308Santhony.gutierrez@amd.com
51211308Santhony.gutierrez@amd.com    template<typename DestDataType, typename Src0DataType,
51311308Santhony.gutierrez@amd.com             typename Src1DataType>
51411308Santhony.gutierrez@amd.com    class TwoNonUniformSourceInst :
51511308Santhony.gutierrez@amd.com        public TwoNonUniformSourceInstBase<typename DestDataType::OperandType,
51611308Santhony.gutierrez@amd.com                                           typename Src0DataType::OperandType,
51711308Santhony.gutierrez@amd.com                                           typename Src1DataType::OperandType>
51811308Santhony.gutierrez@amd.com    {
51911308Santhony.gutierrez@amd.com      public:
52011308Santhony.gutierrez@amd.com        typedef typename DestDataType::CType DestCType;
52111308Santhony.gutierrez@amd.com        typedef typename Src0DataType::CType Src0CType;
52211308Santhony.gutierrez@amd.com        typedef typename Src1DataType::CType Src1CType;
52311308Santhony.gutierrez@amd.com
52411308Santhony.gutierrez@amd.com        TwoNonUniformSourceInst(const Brig::BrigInstBase *ib,
52511308Santhony.gutierrez@amd.com                                const BrigObject *obj, const char *opcode)
52611308Santhony.gutierrez@amd.com            : TwoNonUniformSourceInstBase<typename DestDataType::OperandType,
52711308Santhony.gutierrez@amd.com                                         typename Src0DataType::OperandType,
52811308Santhony.gutierrez@amd.com                                         typename Src1DataType::OperandType>(ib,
52911308Santhony.gutierrez@amd.com                                                                    obj, opcode)
53011308Santhony.gutierrez@amd.com        {
53111308Santhony.gutierrez@amd.com        }
53211308Santhony.gutierrez@amd.com    };
53311308Santhony.gutierrez@amd.com
53411308Santhony.gutierrez@amd.com    // helper function for ClassInst
53511308Santhony.gutierrez@amd.com    template<typename T>
53611308Santhony.gutierrez@amd.com    bool
53711308Santhony.gutierrez@amd.com    fpclassify(T src0, uint32_t src1)
53811308Santhony.gutierrez@amd.com    {
53911308Santhony.gutierrez@amd.com        int fpclass = std::fpclassify(src0);
54011308Santhony.gutierrez@amd.com
54111308Santhony.gutierrez@amd.com        if ((src1 & 0x3) && (fpclass == FP_NAN)) {
54211308Santhony.gutierrez@amd.com            return true;
54311308Santhony.gutierrez@amd.com        }
54411308Santhony.gutierrez@amd.com
54511308Santhony.gutierrez@amd.com        if (src0 <= -0.0) {
54611308Santhony.gutierrez@amd.com            if ((src1 & 0x4) && fpclass == FP_INFINITE)
54711308Santhony.gutierrez@amd.com                return true;
54811308Santhony.gutierrez@amd.com            if ((src1 & 0x8) && fpclass == FP_NORMAL)
54911308Santhony.gutierrez@amd.com                return true;
55011308Santhony.gutierrez@amd.com            if ((src1 & 0x10) && fpclass == FP_SUBNORMAL)
55111308Santhony.gutierrez@amd.com                return true;
55211308Santhony.gutierrez@amd.com            if ((src1 & 0x20) && fpclass == FP_ZERO)
55311308Santhony.gutierrez@amd.com                return true;
55411308Santhony.gutierrez@amd.com        } else {
55511308Santhony.gutierrez@amd.com            if ((src1 & 0x40) && fpclass == FP_ZERO)
55611308Santhony.gutierrez@amd.com                return true;
55711308Santhony.gutierrez@amd.com            if ((src1 & 0x80) && fpclass == FP_SUBNORMAL)
55811308Santhony.gutierrez@amd.com                return true;
55911308Santhony.gutierrez@amd.com            if ((src1 & 0x100) && fpclass == FP_NORMAL)
56011308Santhony.gutierrez@amd.com                return true;
56111308Santhony.gutierrez@amd.com            if ((src1 & 0x200) && fpclass == FP_INFINITE)
56211308Santhony.gutierrez@amd.com                return true;
56311308Santhony.gutierrez@amd.com        }
56411308Santhony.gutierrez@amd.com        return false;
56511308Santhony.gutierrez@amd.com    }
56611308Santhony.gutierrez@amd.com
56711308Santhony.gutierrez@amd.com    template<typename DataType>
56811308Santhony.gutierrez@amd.com    class ClassInst : public TwoNonUniformSourceInst<B1, DataType, U32>
56911308Santhony.gutierrez@amd.com    {
57011308Santhony.gutierrez@amd.com      public:
57111308Santhony.gutierrez@amd.com        ClassInst(const Brig::BrigInstBase *ib, const BrigObject *obj,
57211308Santhony.gutierrez@amd.com                  const char *opcode)
57311308Santhony.gutierrez@amd.com            : TwoNonUniformSourceInst<B1, DataType, U32>(ib, obj, opcode)
57411308Santhony.gutierrez@amd.com        {
57511308Santhony.gutierrez@amd.com        }
57611308Santhony.gutierrez@amd.com    };
57711308Santhony.gutierrez@amd.com
57811308Santhony.gutierrez@amd.com    template<typename DataType>
57911308Santhony.gutierrez@amd.com    class ShiftInst : public TwoNonUniformSourceInst<DataType, DataType, U32>
58011308Santhony.gutierrez@amd.com    {
58111308Santhony.gutierrez@amd.com      public:
58211308Santhony.gutierrez@amd.com        ShiftInst(const Brig::BrigInstBase *ib, const BrigObject *obj,
58311308Santhony.gutierrez@amd.com                  const char *opcode)
58411308Santhony.gutierrez@amd.com            : TwoNonUniformSourceInst<DataType, DataType, U32>(ib, obj, opcode)
58511308Santhony.gutierrez@amd.com        {
58611308Santhony.gutierrez@amd.com        }
58711308Santhony.gutierrez@amd.com    };
58811308Santhony.gutierrez@amd.com
58911308Santhony.gutierrez@amd.com    // helper function for CmpInst
59011308Santhony.gutierrez@amd.com    template<typename T>
59111308Santhony.gutierrez@amd.com    bool
59211308Santhony.gutierrez@amd.com    compare(T src0, T src1, Brig::BrigCompareOperation cmpOp)
59311308Santhony.gutierrez@amd.com    {
59411308Santhony.gutierrez@amd.com        using namespace Brig;
59511308Santhony.gutierrez@amd.com
59611308Santhony.gutierrez@amd.com        switch (cmpOp) {
59711308Santhony.gutierrez@amd.com          case BRIG_COMPARE_EQ:
59811308Santhony.gutierrez@amd.com          case BRIG_COMPARE_EQU:
59911308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SEQ:
60011308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SEQU:
60111308Santhony.gutierrez@amd.com            return (src0 == src1);
60211308Santhony.gutierrez@amd.com
60311308Santhony.gutierrez@amd.com          case BRIG_COMPARE_NE:
60411308Santhony.gutierrez@amd.com          case BRIG_COMPARE_NEU:
60511308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SNE:
60611308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SNEU:
60711308Santhony.gutierrez@amd.com            return (src0 != src1);
60811308Santhony.gutierrez@amd.com
60911308Santhony.gutierrez@amd.com          case BRIG_COMPARE_LT:
61011308Santhony.gutierrez@amd.com          case BRIG_COMPARE_LTU:
61111308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SLT:
61211308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SLTU:
61311308Santhony.gutierrez@amd.com            return (src0 < src1);
61411308Santhony.gutierrez@amd.com
61511308Santhony.gutierrez@amd.com          case BRIG_COMPARE_LE:
61611308Santhony.gutierrez@amd.com          case BRIG_COMPARE_LEU:
61711308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SLE:
61811308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SLEU:
61911308Santhony.gutierrez@amd.com            return (src0 <= src1);
62011308Santhony.gutierrez@amd.com
62111308Santhony.gutierrez@amd.com          case BRIG_COMPARE_GT:
62211308Santhony.gutierrez@amd.com          case BRIG_COMPARE_GTU:
62311308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SGT:
62411308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SGTU:
62511308Santhony.gutierrez@amd.com            return (src0 > src1);
62611308Santhony.gutierrez@amd.com
62711308Santhony.gutierrez@amd.com          case BRIG_COMPARE_GE:
62811308Santhony.gutierrez@amd.com          case BRIG_COMPARE_GEU:
62911308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SGE:
63011308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SGEU:
63111308Santhony.gutierrez@amd.com            return (src0 >= src1);
63211308Santhony.gutierrez@amd.com
63311308Santhony.gutierrez@amd.com          case BRIG_COMPARE_NUM:
63411308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SNUM:
63511308Santhony.gutierrez@amd.com            return (src0 == src0) || (src1 == src1);
63611308Santhony.gutierrez@amd.com
63711308Santhony.gutierrez@amd.com          case BRIG_COMPARE_NAN:
63811308Santhony.gutierrez@amd.com          case BRIG_COMPARE_SNAN:
63911308Santhony.gutierrez@amd.com            return (src0 != src0) || (src1 != src1);
64011308Santhony.gutierrez@amd.com
64111308Santhony.gutierrez@amd.com          default:
64211308Santhony.gutierrez@amd.com            fatal("Bad cmpOp value %d\n", (int)cmpOp);
64311308Santhony.gutierrez@amd.com        }
64411308Santhony.gutierrez@amd.com    }
64511308Santhony.gutierrez@amd.com
64611308Santhony.gutierrez@amd.com    template<typename T>
64711308Santhony.gutierrez@amd.com    int32_t
64811308Santhony.gutierrez@amd.com    firstbit(T src0)
64911308Santhony.gutierrez@amd.com    {
65011308Santhony.gutierrez@amd.com        if (!src0)
65111308Santhony.gutierrez@amd.com            return -1;
65211308Santhony.gutierrez@amd.com
65311308Santhony.gutierrez@amd.com        //handle positive and negative numbers
65411699Santhony.gutierrez@amd.com        T tmp = ((int64_t)src0 < 0) ? (~src0) : (src0);
65511308Santhony.gutierrez@amd.com
65611308Santhony.gutierrez@amd.com        //the starting pos is MSB
65711308Santhony.gutierrez@amd.com        int pos = 8 * sizeof(T) - 1;
65811308Santhony.gutierrez@amd.com        int cnt = 0;
65911308Santhony.gutierrez@amd.com
66011308Santhony.gutierrez@amd.com        //search the first bit set to 1
66111308Santhony.gutierrez@amd.com        while (!(tmp & (1 << pos))) {
66211308Santhony.gutierrez@amd.com            ++cnt;
66311308Santhony.gutierrez@amd.com            --pos;
66411308Santhony.gutierrez@amd.com        }
66511308Santhony.gutierrez@amd.com        return cnt;
66611308Santhony.gutierrez@amd.com    }
66711308Santhony.gutierrez@amd.com
66811308Santhony.gutierrez@amd.com    const char* cmpOpToString(Brig::BrigCompareOperation cmpOp);
66911308Santhony.gutierrez@amd.com
67011308Santhony.gutierrez@amd.com    template<typename DestOperandType, typename SrcOperandType>
67111308Santhony.gutierrez@amd.com    class CmpInstBase : public CommonInstBase<DestOperandType, SrcOperandType,
67211308Santhony.gutierrez@amd.com                                              2>
67311308Santhony.gutierrez@amd.com    {
67411308Santhony.gutierrez@amd.com      protected:
67511308Santhony.gutierrez@amd.com        Brig::BrigCompareOperation cmpOp;
67611308Santhony.gutierrez@amd.com
67711308Santhony.gutierrez@amd.com      public:
67811308Santhony.gutierrez@amd.com        CmpInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj,
67911308Santhony.gutierrez@amd.com                    const char *_opcode)
68011308Santhony.gutierrez@amd.com            : CommonInstBase<DestOperandType, SrcOperandType, 2>(ib, obj,
68111308Santhony.gutierrez@amd.com                                                                 _opcode)
68211308Santhony.gutierrez@amd.com        {
68311308Santhony.gutierrez@amd.com            assert(ib->base.kind == Brig::BRIG_KIND_INST_CMP);
68411308Santhony.gutierrez@amd.com            Brig::BrigInstCmp *i = (Brig::BrigInstCmp*)ib;
68511308Santhony.gutierrez@amd.com            cmpOp = (Brig::BrigCompareOperation)i->compare;
68611308Santhony.gutierrez@amd.com        }
68711308Santhony.gutierrez@amd.com    };
68811308Santhony.gutierrez@amd.com
68911308Santhony.gutierrez@amd.com    template<typename DestDataType, typename SrcDataType>
69011308Santhony.gutierrez@amd.com    class CmpInst : public CmpInstBase<typename DestDataType::OperandType,
69111308Santhony.gutierrez@amd.com                                       typename SrcDataType::OperandType>
69211308Santhony.gutierrez@amd.com    {
69311308Santhony.gutierrez@amd.com      public:
69411308Santhony.gutierrez@amd.com        std::string
69511308Santhony.gutierrez@amd.com        opcode_suffix()
69611308Santhony.gutierrez@amd.com        {
69711308Santhony.gutierrez@amd.com            return csprintf("_%s_%s_%s", cmpOpToString(this->cmpOp),
69811308Santhony.gutierrez@amd.com                            DestDataType::label, SrcDataType::label);
69911308Santhony.gutierrez@amd.com        }
70011308Santhony.gutierrez@amd.com
70111308Santhony.gutierrez@amd.com        CmpInst(const Brig::BrigInstBase *ib, const BrigObject *obj,
70211308Santhony.gutierrez@amd.com                const char *_opcode)
70311308Santhony.gutierrez@amd.com            : CmpInstBase<typename DestDataType::OperandType,
70411308Santhony.gutierrez@amd.com                          typename SrcDataType::OperandType>(ib, obj, _opcode)
70511308Santhony.gutierrez@amd.com        {
70611308Santhony.gutierrez@amd.com        }
70711308Santhony.gutierrez@amd.com    };
70811308Santhony.gutierrez@amd.com
70911308Santhony.gutierrez@amd.com    template<typename DestDataType, typename SrcDataType>
71011308Santhony.gutierrez@amd.com    class CvtInst : public CommonInstBase<typename DestDataType::OperandType,
71111308Santhony.gutierrez@amd.com                                          typename SrcDataType::OperandType, 1>
71211308Santhony.gutierrez@amd.com    {
71311308Santhony.gutierrez@amd.com      public:
71411308Santhony.gutierrez@amd.com        std::string opcode_suffix()
71511308Santhony.gutierrez@amd.com        {
71611308Santhony.gutierrez@amd.com            return csprintf("_%s_%s", DestDataType::label, SrcDataType::label);
71711308Santhony.gutierrez@amd.com        }
71811308Santhony.gutierrez@amd.com
71911308Santhony.gutierrez@amd.com        CvtInst(const Brig::BrigInstBase *ib, const BrigObject *obj,
72011308Santhony.gutierrez@amd.com                const char *_opcode)
72111308Santhony.gutierrez@amd.com            : CommonInstBase<typename DestDataType::OperandType,
72211308Santhony.gutierrez@amd.com                             typename SrcDataType::OperandType,
72311308Santhony.gutierrez@amd.com                             1>(ib, obj, _opcode)
72411308Santhony.gutierrez@amd.com        {
72511308Santhony.gutierrez@amd.com        }
72611308Santhony.gutierrez@amd.com    };
72711308Santhony.gutierrez@amd.com
72811737Sbrandon.potter@amd.com    template<typename DestDataType, typename SrcDataType>
72911737Sbrandon.potter@amd.com    class PopcountInst :
73011737Sbrandon.potter@amd.com        public CommonInstBase<typename DestDataType::OperandType,
73111737Sbrandon.potter@amd.com                              typename SrcDataType::OperandType, 1>
73211737Sbrandon.potter@amd.com    {
73311737Sbrandon.potter@amd.com      public:
73411737Sbrandon.potter@amd.com        std::string opcode_suffix()
73511737Sbrandon.potter@amd.com        {
73611737Sbrandon.potter@amd.com            return csprintf("_%s_%s", DestDataType::label, SrcDataType::label);
73711737Sbrandon.potter@amd.com        }
73811737Sbrandon.potter@amd.com
73911737Sbrandon.potter@amd.com        PopcountInst(const Brig::BrigInstBase *ib, const BrigObject *obj,
74011737Sbrandon.potter@amd.com                     const char *_opcode)
74111737Sbrandon.potter@amd.com            : CommonInstBase<typename DestDataType::OperandType,
74211737Sbrandon.potter@amd.com                             typename SrcDataType::OperandType,
74311737Sbrandon.potter@amd.com                             1>(ib, obj, _opcode)
74411737Sbrandon.potter@amd.com        {
74511737Sbrandon.potter@amd.com        }
74611737Sbrandon.potter@amd.com    };
74711737Sbrandon.potter@amd.com
74811738Sbrandon.potter@amd.com    class Stub : public HsailGPUStaticInst
74911738Sbrandon.potter@amd.com    {
75011738Sbrandon.potter@amd.com      public:
75111738Sbrandon.potter@amd.com        Stub(const Brig::BrigInstBase *ib, const BrigObject *obj,
75211738Sbrandon.potter@amd.com             const char *_opcode)
75311738Sbrandon.potter@amd.com            : HsailGPUStaticInst(obj, _opcode)
75411738Sbrandon.potter@amd.com        {
75511738Sbrandon.potter@amd.com        }
75611738Sbrandon.potter@amd.com
75711738Sbrandon.potter@amd.com        void generateDisassembly() override
75811738Sbrandon.potter@amd.com        {
75911738Sbrandon.potter@amd.com            disassembly = csprintf("%s", opcode);
76011738Sbrandon.potter@amd.com        }
76111738Sbrandon.potter@amd.com
76211738Sbrandon.potter@amd.com        bool isVectorRegister(int operandIndex) override { return false; }
76311738Sbrandon.potter@amd.com        bool isCondRegister(int operandIndex) override { return false; }
76411738Sbrandon.potter@amd.com        bool isScalarRegister(int operandIndex) override { return false; }
76511738Sbrandon.potter@amd.com        bool isSrcOperand(int operandIndex) override { return false; }
76611738Sbrandon.potter@amd.com        bool isDstOperand(int operandIndex) override { return false; }
76711738Sbrandon.potter@amd.com        int getOperandSize(int operandIndex) override { return 0; }
76811738Sbrandon.potter@amd.com
76911738Sbrandon.potter@amd.com        int
77011738Sbrandon.potter@amd.com        getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) override
77111738Sbrandon.potter@amd.com        {
77211738Sbrandon.potter@amd.com            return -1;
77311738Sbrandon.potter@amd.com        }
77411738Sbrandon.potter@amd.com
77511738Sbrandon.potter@amd.com        int numSrcRegOperands() override { return 0; }
77611738Sbrandon.potter@amd.com        int numDstRegOperands() override { return 0; }
77711738Sbrandon.potter@amd.com        int getNumOperands() override { return 0; }
77811738Sbrandon.potter@amd.com    };
77911738Sbrandon.potter@amd.com
78011308Santhony.gutierrez@amd.com    class SpecialInstNoSrcNoDest : public HsailGPUStaticInst
78111308Santhony.gutierrez@amd.com    {
78211308Santhony.gutierrez@amd.com      public:
78311308Santhony.gutierrez@amd.com        SpecialInstNoSrcNoDest(const Brig::BrigInstBase *ib,
78411308Santhony.gutierrez@amd.com                               const BrigObject *obj, const char *_opcode)
78511308Santhony.gutierrez@amd.com            : HsailGPUStaticInst(obj, _opcode)
78611308Santhony.gutierrez@amd.com        {
78711308Santhony.gutierrez@amd.com        }
78811308Santhony.gutierrez@amd.com
78911738Sbrandon.potter@amd.com        bool isVectorRegister(int operandIndex) override { return false; }
79011738Sbrandon.potter@amd.com        bool isCondRegister(int operandIndex) override { return false; }
79111738Sbrandon.potter@amd.com        bool isScalarRegister(int operandIndex) override { return false; }
79211738Sbrandon.potter@amd.com        bool isSrcOperand(int operandIndex) override { return false; }
79311738Sbrandon.potter@amd.com        bool isDstOperand(int operandIndex) override { return false; }
79411738Sbrandon.potter@amd.com        int getOperandSize(int operandIndex) override { return 0; }
79511699Santhony.gutierrez@amd.com
79611699Santhony.gutierrez@amd.com        int
79711738Sbrandon.potter@amd.com        getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) override
79811699Santhony.gutierrez@amd.com        {
79911699Santhony.gutierrez@amd.com            return -1;
80011699Santhony.gutierrez@amd.com        }
80111308Santhony.gutierrez@amd.com
80211738Sbrandon.potter@amd.com        int numSrcRegOperands() override { return 0; }
80311738Sbrandon.potter@amd.com        int numDstRegOperands() override { return 0; }
80411738Sbrandon.potter@amd.com        int getNumOperands() override { return 0; }
80511308Santhony.gutierrez@amd.com    };
80611308Santhony.gutierrez@amd.com
80711308Santhony.gutierrez@amd.com    template<typename DestOperandType>
80811308Santhony.gutierrez@amd.com    class SpecialInstNoSrcBase : public HsailGPUStaticInst
80911308Santhony.gutierrez@amd.com    {
81011308Santhony.gutierrez@amd.com      protected:
81111308Santhony.gutierrez@amd.com        typename DestOperandType::DestOperand dest;
81211308Santhony.gutierrez@amd.com
81311308Santhony.gutierrez@amd.com        void generateDisassembly()
81411308Santhony.gutierrez@amd.com        {
81511308Santhony.gutierrez@amd.com            disassembly = csprintf("%s %s", opcode, dest.disassemble());
81611308Santhony.gutierrez@amd.com        }
81711308Santhony.gutierrez@amd.com
81811308Santhony.gutierrez@amd.com      public:
81911308Santhony.gutierrez@amd.com        SpecialInstNoSrcBase(const Brig::BrigInstBase *ib,
82011308Santhony.gutierrez@amd.com                             const BrigObject *obj, const char *_opcode)
82111308Santhony.gutierrez@amd.com            : HsailGPUStaticInst(obj, _opcode)
82211308Santhony.gutierrez@amd.com        {
82311308Santhony.gutierrez@amd.com            unsigned op_offs = obj->getOperandPtr(ib->operands, 0);
82411308Santhony.gutierrez@amd.com            dest.init(op_offs, obj);
82511308Santhony.gutierrez@amd.com        }
82611308Santhony.gutierrez@amd.com
82711308Santhony.gutierrez@amd.com        bool isVectorRegister(int operandIndex) {
82811308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
82911308Santhony.gutierrez@amd.com            return dest.isVectorRegister();
83011308Santhony.gutierrez@amd.com        }
83111308Santhony.gutierrez@amd.com        bool isCondRegister(int operandIndex) {
83211308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
83311308Santhony.gutierrez@amd.com            return dest.isCondRegister();
83411308Santhony.gutierrez@amd.com        }
83511308Santhony.gutierrez@amd.com        bool isScalarRegister(int operandIndex) {
83611308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
83711308Santhony.gutierrez@amd.com            return dest.isScalarRegister();
83811308Santhony.gutierrez@amd.com        }
83911308Santhony.gutierrez@amd.com        bool isSrcOperand(int operandIndex) { return false; }
84011308Santhony.gutierrez@amd.com        bool isDstOperand(int operandIndex) { return true; }
84111308Santhony.gutierrez@amd.com        int getOperandSize(int operandIndex) {
84211308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
84311308Santhony.gutierrez@amd.com            return dest.opSize();
84411308Santhony.gutierrez@amd.com        }
84511699Santhony.gutierrez@amd.com
84611699Santhony.gutierrez@amd.com        int
84711699Santhony.gutierrez@amd.com        getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst)
84811699Santhony.gutierrez@amd.com        {
84911308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
85011308Santhony.gutierrez@amd.com            return dest.regIndex();
85111308Santhony.gutierrez@amd.com        }
85211699Santhony.gutierrez@amd.com
85311308Santhony.gutierrez@amd.com        int numSrcRegOperands() { return 0; }
85411308Santhony.gutierrez@amd.com        int numDstRegOperands() { return dest.isVectorRegister(); }
85511308Santhony.gutierrez@amd.com        int getNumOperands() { return 1; }
85611308Santhony.gutierrez@amd.com    };
85711308Santhony.gutierrez@amd.com
85811308Santhony.gutierrez@amd.com    template<typename DestDataType>
85911308Santhony.gutierrez@amd.com    class SpecialInstNoSrc :
86011308Santhony.gutierrez@amd.com        public SpecialInstNoSrcBase<typename DestDataType::OperandType>
86111308Santhony.gutierrez@amd.com    {
86211308Santhony.gutierrez@amd.com      public:
86311308Santhony.gutierrez@amd.com        typedef typename DestDataType::CType DestCType;
86411308Santhony.gutierrez@amd.com
86511308Santhony.gutierrez@amd.com        SpecialInstNoSrc(const Brig::BrigInstBase *ib, const BrigObject *obj,
86611308Santhony.gutierrez@amd.com                         const char *_opcode)
86711308Santhony.gutierrez@amd.com            : SpecialInstNoSrcBase<typename DestDataType::OperandType>(ib, obj,
86811308Santhony.gutierrez@amd.com                                                                       _opcode)
86911308Santhony.gutierrez@amd.com        {
87011308Santhony.gutierrez@amd.com        }
87111308Santhony.gutierrez@amd.com    };
87211308Santhony.gutierrez@amd.com
87311308Santhony.gutierrez@amd.com    template<typename DestOperandType>
87411308Santhony.gutierrez@amd.com    class SpecialInst1SrcBase : public HsailGPUStaticInst
87511308Santhony.gutierrez@amd.com    {
87611308Santhony.gutierrez@amd.com      protected:
87711308Santhony.gutierrez@amd.com        typedef int SrcCType;  // used in execute() template
87811308Santhony.gutierrez@amd.com
87911308Santhony.gutierrez@amd.com        typename DestOperandType::DestOperand dest;
88011308Santhony.gutierrez@amd.com        ImmOperand<SrcCType> src0;
88111308Santhony.gutierrez@amd.com
88211308Santhony.gutierrez@amd.com        void
88311308Santhony.gutierrez@amd.com        generateDisassembly()
88411308Santhony.gutierrez@amd.com        {
88511308Santhony.gutierrez@amd.com            disassembly = csprintf("%s %s,%s", opcode, dest.disassemble(),
88611308Santhony.gutierrez@amd.com                                   src0.disassemble());
88711308Santhony.gutierrez@amd.com        }
88811308Santhony.gutierrez@amd.com
88911308Santhony.gutierrez@amd.com      public:
89011308Santhony.gutierrez@amd.com        SpecialInst1SrcBase(const Brig::BrigInstBase *ib,
89111308Santhony.gutierrez@amd.com                            const BrigObject *obj, const char *_opcode)
89211308Santhony.gutierrez@amd.com            : HsailGPUStaticInst(obj, _opcode)
89311308Santhony.gutierrez@amd.com        {
89411692Santhony.gutierrez@amd.com            setFlag(ALU);
89511692Santhony.gutierrez@amd.com
89611308Santhony.gutierrez@amd.com            unsigned op_offs = obj->getOperandPtr(ib->operands, 0);
89711308Santhony.gutierrez@amd.com            dest.init(op_offs, obj);
89811308Santhony.gutierrez@amd.com
89911308Santhony.gutierrez@amd.com            op_offs = obj->getOperandPtr(ib->operands, 1);
90011308Santhony.gutierrez@amd.com            src0.init(op_offs, obj);
90111308Santhony.gutierrez@amd.com        }
90211308Santhony.gutierrez@amd.com        bool isVectorRegister(int operandIndex) {
90311308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
90411308Santhony.gutierrez@amd.com            return dest.isVectorRegister();
90511308Santhony.gutierrez@amd.com        }
90611308Santhony.gutierrez@amd.com        bool isCondRegister(int operandIndex) {
90711308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
90811308Santhony.gutierrez@amd.com            return dest.isCondRegister();
90911308Santhony.gutierrez@amd.com        }
91011308Santhony.gutierrez@amd.com        bool isScalarRegister(int operandIndex) {
91111308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
91211308Santhony.gutierrez@amd.com            return dest.isScalarRegister();
91311308Santhony.gutierrez@amd.com        }
91411308Santhony.gutierrez@amd.com        bool isSrcOperand(int operandIndex) { return false; }
91511308Santhony.gutierrez@amd.com        bool isDstOperand(int operandIndex) { return true; }
91611308Santhony.gutierrez@amd.com        int getOperandSize(int operandIndex) {
91711308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
91811308Santhony.gutierrez@amd.com            return dest.opSize();
91911308Santhony.gutierrez@amd.com        }
92011699Santhony.gutierrez@amd.com
92111699Santhony.gutierrez@amd.com        int
92211699Santhony.gutierrez@amd.com        getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst)
92311699Santhony.gutierrez@amd.com        {
92411308Santhony.gutierrez@amd.com            assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
92511308Santhony.gutierrez@amd.com            return dest.regIndex();
92611308Santhony.gutierrez@amd.com        }
92711699Santhony.gutierrez@amd.com
92811308Santhony.gutierrez@amd.com        int numSrcRegOperands() { return 0; }
92911308Santhony.gutierrez@amd.com        int numDstRegOperands() { return dest.isVectorRegister(); }
93011308Santhony.gutierrez@amd.com        int getNumOperands() { return 1; }
93111308Santhony.gutierrez@amd.com    };
93211308Santhony.gutierrez@amd.com
93311308Santhony.gutierrez@amd.com    template<typename DestDataType>
93411308Santhony.gutierrez@amd.com    class SpecialInst1Src :
93511308Santhony.gutierrez@amd.com        public SpecialInst1SrcBase<typename DestDataType::OperandType>
93611308Santhony.gutierrez@amd.com    {
93711308Santhony.gutierrez@amd.com      public:
93811308Santhony.gutierrez@amd.com        typedef typename DestDataType::CType DestCType;
93911308Santhony.gutierrez@amd.com
94011308Santhony.gutierrez@amd.com        SpecialInst1Src(const Brig::BrigInstBase *ib, const BrigObject *obj,
94111308Santhony.gutierrez@amd.com                        const char *_opcode)
94211308Santhony.gutierrez@amd.com            : SpecialInst1SrcBase<typename DestDataType::OperandType>(ib, obj,
94311308Santhony.gutierrez@amd.com                                                                      _opcode)
94411308Santhony.gutierrez@amd.com        {
94511308Santhony.gutierrez@amd.com        }
94611308Santhony.gutierrez@amd.com    };
94711308Santhony.gutierrez@amd.com
94811308Santhony.gutierrez@amd.com    class Ret : public SpecialInstNoSrcNoDest
94911308Santhony.gutierrez@amd.com    {
95011308Santhony.gutierrez@amd.com      public:
95111308Santhony.gutierrez@amd.com        typedef SpecialInstNoSrcNoDest Base;
95211308Santhony.gutierrez@amd.com
95311308Santhony.gutierrez@amd.com        Ret(const Brig::BrigInstBase *ib, const BrigObject *obj)
95411308Santhony.gutierrez@amd.com           : Base(ib, obj, "ret")
95511308Santhony.gutierrez@amd.com        {
95611692Santhony.gutierrez@amd.com            setFlag(GPUStaticInst::Return);
95711308Santhony.gutierrez@amd.com        }
95811308Santhony.gutierrez@amd.com
95911308Santhony.gutierrez@amd.com        void execute(GPUDynInstPtr gpuDynInst);
96011308Santhony.gutierrez@amd.com    };
96111308Santhony.gutierrez@amd.com
96211308Santhony.gutierrez@amd.com    class Barrier : public SpecialInstNoSrcNoDest
96311308Santhony.gutierrez@amd.com    {
96411308Santhony.gutierrez@amd.com      public:
96511308Santhony.gutierrez@amd.com        typedef SpecialInstNoSrcNoDest Base;
96611308Santhony.gutierrez@amd.com        uint8_t width;
96711308Santhony.gutierrez@amd.com
96811308Santhony.gutierrez@amd.com        Barrier(const Brig::BrigInstBase *ib, const BrigObject *obj)
96911308Santhony.gutierrez@amd.com            : Base(ib, obj, "barrier")
97011308Santhony.gutierrez@amd.com        {
97111692Santhony.gutierrez@amd.com            setFlag(GPUStaticInst::MemBarrier);
97211308Santhony.gutierrez@amd.com            assert(ib->base.kind == Brig::BRIG_KIND_INST_BR);
97311308Santhony.gutierrez@amd.com            width = (uint8_t)((Brig::BrigInstBr*)ib)->width;
97411308Santhony.gutierrez@amd.com        }
97511308Santhony.gutierrez@amd.com
97611308Santhony.gutierrez@amd.com        void execute(GPUDynInstPtr gpuDynInst);
97711308Santhony.gutierrez@amd.com    };
97811308Santhony.gutierrez@amd.com
97911308Santhony.gutierrez@amd.com    class MemFence : public SpecialInstNoSrcNoDest
98011308Santhony.gutierrez@amd.com    {
98111308Santhony.gutierrez@amd.com      public:
98211308Santhony.gutierrez@amd.com        typedef SpecialInstNoSrcNoDest Base;
98311308Santhony.gutierrez@amd.com
98411308Santhony.gutierrez@amd.com        Brig::BrigMemoryOrder memFenceMemOrder;
98511308Santhony.gutierrez@amd.com        Brig::BrigMemoryScope memFenceScopeSegGroup;
98611308Santhony.gutierrez@amd.com        Brig::BrigMemoryScope memFenceScopeSegGlobal;
98711308Santhony.gutierrez@amd.com        Brig::BrigMemoryScope memFenceScopeSegImage;
98811308Santhony.gutierrez@amd.com
98911308Santhony.gutierrez@amd.com        MemFence(const Brig::BrigInstBase *ib, const BrigObject *obj)
99011308Santhony.gutierrez@amd.com            : Base(ib, obj, "memfence")
99111308Santhony.gutierrez@amd.com        {
99211308Santhony.gutierrez@amd.com            assert(ib->base.kind == Brig::BRIG_KIND_INST_MEM_FENCE);
99311308Santhony.gutierrez@amd.com
99411308Santhony.gutierrez@amd.com            memFenceScopeSegGlobal = (Brig::BrigMemoryScope)
99511308Santhony.gutierrez@amd.com                ((Brig::BrigInstMemFence*)ib)->globalSegmentMemoryScope;
99611308Santhony.gutierrez@amd.com
99711308Santhony.gutierrez@amd.com            memFenceScopeSegGroup = (Brig::BrigMemoryScope)
99811308Santhony.gutierrez@amd.com                ((Brig::BrigInstMemFence*)ib)->groupSegmentMemoryScope;
99911308Santhony.gutierrez@amd.com
100011308Santhony.gutierrez@amd.com            memFenceScopeSegImage = (Brig::BrigMemoryScope)
100111308Santhony.gutierrez@amd.com                ((Brig::BrigInstMemFence*)ib)->imageSegmentMemoryScope;
100211308Santhony.gutierrez@amd.com
100311308Santhony.gutierrez@amd.com            memFenceMemOrder = (Brig::BrigMemoryOrder)
100411308Santhony.gutierrez@amd.com                ((Brig::BrigInstMemFence*)ib)->memoryOrder;
100511308Santhony.gutierrez@amd.com
100611692Santhony.gutierrez@amd.com            setFlag(MemoryRef);
100711692Santhony.gutierrez@amd.com            setFlag(GPUStaticInst::MemFence);
100811692Santhony.gutierrez@amd.com
100911692Santhony.gutierrez@amd.com            switch (memFenceMemOrder) {
101011692Santhony.gutierrez@amd.com              case Brig::BRIG_MEMORY_ORDER_NONE:
101111692Santhony.gutierrez@amd.com                setFlag(NoOrder);
101211692Santhony.gutierrez@amd.com                break;
101311692Santhony.gutierrez@amd.com              case Brig::BRIG_MEMORY_ORDER_RELAXED:
101411692Santhony.gutierrez@amd.com                setFlag(RelaxedOrder);
101511692Santhony.gutierrez@amd.com                break;
101611692Santhony.gutierrez@amd.com              case Brig::BRIG_MEMORY_ORDER_SC_ACQUIRE:
101711692Santhony.gutierrez@amd.com                setFlag(Acquire);
101811692Santhony.gutierrez@amd.com                break;
101911692Santhony.gutierrez@amd.com              case Brig::BRIG_MEMORY_ORDER_SC_RELEASE:
102011692Santhony.gutierrez@amd.com                setFlag(Release);
102111692Santhony.gutierrez@amd.com                break;
102211692Santhony.gutierrez@amd.com              case Brig::BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE:
102311692Santhony.gutierrez@amd.com                setFlag(AcquireRelease);
102411692Santhony.gutierrez@amd.com                break;
102511692Santhony.gutierrez@amd.com              default:
102611692Santhony.gutierrez@amd.com                fatal("MemInst has bad BrigMemoryOrder\n");
102711692Santhony.gutierrez@amd.com            }
102811692Santhony.gutierrez@amd.com
102911692Santhony.gutierrez@amd.com            // set inst flags based on scopes
103011308Santhony.gutierrez@amd.com            if (memFenceScopeSegGlobal != Brig::BRIG_MEMORY_SCOPE_NONE &&
103111308Santhony.gutierrez@amd.com                memFenceScopeSegGroup != Brig::BRIG_MEMORY_SCOPE_NONE) {
103211692Santhony.gutierrez@amd.com                setFlag(GPUStaticInst::GlobalSegment);
103311692Santhony.gutierrez@amd.com
103411692Santhony.gutierrez@amd.com                /**
103511692Santhony.gutierrez@amd.com                 * A memory fence that has scope for
103611692Santhony.gutierrez@amd.com                 * both segments will use the global
103711692Santhony.gutierrez@amd.com                 * segment, and be executed in the
103811692Santhony.gutierrez@amd.com                 * global memory pipeline, therefore,
103911692Santhony.gutierrez@amd.com                 * we set the segment to match the
104011692Santhony.gutierrez@amd.com                 * global scope only
104111692Santhony.gutierrez@amd.com                 */
104211692Santhony.gutierrez@amd.com                switch (memFenceScopeSegGlobal) {
104311692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_NONE:
104411692Santhony.gutierrez@amd.com                    setFlag(NoScope);
104511692Santhony.gutierrez@amd.com                    break;
104611692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_WORKITEM:
104711692Santhony.gutierrez@amd.com                    setFlag(WorkitemScope);
104811692Santhony.gutierrez@amd.com                    break;
104911692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_WORKGROUP:
105011692Santhony.gutierrez@amd.com                    setFlag(WorkgroupScope);
105111692Santhony.gutierrez@amd.com                    break;
105211692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_AGENT:
105311692Santhony.gutierrez@amd.com                    setFlag(DeviceScope);
105411692Santhony.gutierrez@amd.com                    break;
105511692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_SYSTEM:
105611692Santhony.gutierrez@amd.com                    setFlag(SystemScope);
105711692Santhony.gutierrez@amd.com                    break;
105811692Santhony.gutierrez@amd.com                  default:
105911692Santhony.gutierrez@amd.com                    fatal("MemFence has bad global scope type\n");
106011692Santhony.gutierrez@amd.com                }
106111308Santhony.gutierrez@amd.com            } else if (memFenceScopeSegGlobal != Brig::BRIG_MEMORY_SCOPE_NONE) {
106211692Santhony.gutierrez@amd.com                setFlag(GPUStaticInst::GlobalSegment);
106311692Santhony.gutierrez@amd.com
106411692Santhony.gutierrez@amd.com                switch (memFenceScopeSegGlobal) {
106511692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_NONE:
106611692Santhony.gutierrez@amd.com                    setFlag(NoScope);
106711692Santhony.gutierrez@amd.com                    break;
106811692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_WORKITEM:
106911692Santhony.gutierrez@amd.com                    setFlag(WorkitemScope);
107011692Santhony.gutierrez@amd.com                    break;
107111692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_WORKGROUP:
107211692Santhony.gutierrez@amd.com                    setFlag(WorkgroupScope);
107311692Santhony.gutierrez@amd.com                    break;
107411692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_AGENT:
107511692Santhony.gutierrez@amd.com                    setFlag(DeviceScope);
107611692Santhony.gutierrez@amd.com                    break;
107711692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_SYSTEM:
107811692Santhony.gutierrez@amd.com                    setFlag(SystemScope);
107911692Santhony.gutierrez@amd.com                    break;
108011692Santhony.gutierrez@amd.com                  default:
108111692Santhony.gutierrez@amd.com                    fatal("MemFence has bad global scope type\n");
108211692Santhony.gutierrez@amd.com                }
108311308Santhony.gutierrez@amd.com            } else if (memFenceScopeSegGroup != Brig::BRIG_MEMORY_SCOPE_NONE) {
108411692Santhony.gutierrez@amd.com                setFlag(GPUStaticInst::GroupSegment);
108511692Santhony.gutierrez@amd.com
108611692Santhony.gutierrez@amd.com                switch (memFenceScopeSegGroup) {
108711692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_NONE:
108811692Santhony.gutierrez@amd.com                    setFlag(NoScope);
108911692Santhony.gutierrez@amd.com                    break;
109011692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_WORKITEM:
109111692Santhony.gutierrez@amd.com                    setFlag(WorkitemScope);
109211692Santhony.gutierrez@amd.com                    break;
109311692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_WORKGROUP:
109411692Santhony.gutierrez@amd.com                    setFlag(WorkgroupScope);
109511692Santhony.gutierrez@amd.com                    break;
109611692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_AGENT:
109711692Santhony.gutierrez@amd.com                    setFlag(DeviceScope);
109811692Santhony.gutierrez@amd.com                    break;
109911692Santhony.gutierrez@amd.com                  case Brig::BRIG_MEMORY_SCOPE_SYSTEM:
110011692Santhony.gutierrez@amd.com                    setFlag(SystemScope);
110111692Santhony.gutierrez@amd.com                    break;
110211692Santhony.gutierrez@amd.com                  default:
110311692Santhony.gutierrez@amd.com                    fatal("MemFence has bad group scope type\n");
110411692Santhony.gutierrez@amd.com                }
110511308Santhony.gutierrez@amd.com            } else {
110611308Santhony.gutierrez@amd.com                fatal("MemFence constructor: bad scope specifiers\n");
110711308Santhony.gutierrez@amd.com            }
110811308Santhony.gutierrez@amd.com        }
110911308Santhony.gutierrez@amd.com
111011308Santhony.gutierrez@amd.com        void
111111308Santhony.gutierrez@amd.com        initiateAcc(GPUDynInstPtr gpuDynInst)
111211308Santhony.gutierrez@amd.com        {
111311308Santhony.gutierrez@amd.com            Wavefront *wave = gpuDynInst->wavefront();
111411308Santhony.gutierrez@amd.com            wave->computeUnit->injectGlobalMemFence(gpuDynInst);
111511308Santhony.gutierrez@amd.com        }
111611308Santhony.gutierrez@amd.com
111711308Santhony.gutierrez@amd.com        void
111811308Santhony.gutierrez@amd.com        execute(GPUDynInstPtr gpuDynInst)
111911308Santhony.gutierrez@amd.com        {
112011308Santhony.gutierrez@amd.com            Wavefront *w = gpuDynInst->wavefront();
112111308Santhony.gutierrez@amd.com            // 2 cases:
112211308Santhony.gutierrez@amd.com            //   * memfence to a sequentially consistent memory (e.g., LDS).
112311308Santhony.gutierrez@amd.com            //     These can be handled as no-ops.
112411308Santhony.gutierrez@amd.com            //   * memfence to a relaxed consistency cache (e.g., Hermes, Viper,
112511308Santhony.gutierrez@amd.com            //     etc.). We send a packet, tagged with the memory order and
112611308Santhony.gutierrez@amd.com            //     scope, and let the GPU coalescer handle it.
112711308Santhony.gutierrez@amd.com
112811692Santhony.gutierrez@amd.com            if (isGlobalSeg()) {
112911308Santhony.gutierrez@amd.com                gpuDynInst->simdId = w->simdId;
113011308Santhony.gutierrez@amd.com                gpuDynInst->wfSlotId = w->wfSlotId;
113111308Santhony.gutierrez@amd.com                gpuDynInst->wfDynId = w->wfDynId;
113211639Salexandru.dutu@amd.com                gpuDynInst->kern_id = w->kernId;
113311308Santhony.gutierrez@amd.com                gpuDynInst->cu_id = w->computeUnit->cu_id;
113411308Santhony.gutierrez@amd.com
113511308Santhony.gutierrez@amd.com                gpuDynInst->useContinuation = false;
113611308Santhony.gutierrez@amd.com                GlobalMemPipeline* gmp = &(w->computeUnit->globalMemoryPipe);
113711700Santhony.gutierrez@amd.com                gmp->issueRequest(gpuDynInst);
113811308Santhony.gutierrez@amd.com
113911639Salexandru.dutu@amd.com                w->wrGmReqsInPipe--;
114011639Salexandru.dutu@amd.com                w->rdGmReqsInPipe--;
114111639Salexandru.dutu@amd.com                w->memReqsInPipe--;
114211639Salexandru.dutu@amd.com                w->outstandingReqs++;
114311692Santhony.gutierrez@amd.com            } else if (isGroupSeg()) {
114411308Santhony.gutierrez@amd.com                // no-op
114511308Santhony.gutierrez@amd.com            } else {
114611692Santhony.gutierrez@amd.com                fatal("MemFence execute: bad op type\n");
114711308Santhony.gutierrez@amd.com            }
114811308Santhony.gutierrez@amd.com        }
114911308Santhony.gutierrez@amd.com    };
115011308Santhony.gutierrez@amd.com
115111308Santhony.gutierrez@amd.com    class Call : public HsailGPUStaticInst
115211308Santhony.gutierrez@amd.com    {
115311308Santhony.gutierrez@amd.com      public:
115411308Santhony.gutierrez@amd.com        // private helper functions
115511308Santhony.gutierrez@amd.com        void calcAddr(Wavefront* w, GPUDynInstPtr m);
115611308Santhony.gutierrez@amd.com
115711308Santhony.gutierrez@amd.com        void
115811308Santhony.gutierrez@amd.com        generateDisassembly()
115911308Santhony.gutierrez@amd.com        {
116011308Santhony.gutierrez@amd.com            if (dest.disassemble() == "") {
116111308Santhony.gutierrez@amd.com                disassembly = csprintf("%s %s (%s)", opcode, src0.disassemble(),
116211308Santhony.gutierrez@amd.com                                       src1.disassemble());
116311308Santhony.gutierrez@amd.com            } else {
116411308Santhony.gutierrez@amd.com                disassembly = csprintf("%s %s (%s) (%s)", opcode,
116511308Santhony.gutierrez@amd.com                                       src0.disassemble(), dest.disassemble(),
116611308Santhony.gutierrez@amd.com                                       src1.disassemble());
116711308Santhony.gutierrez@amd.com            }
116811308Santhony.gutierrez@amd.com        }
116911308Santhony.gutierrez@amd.com
117011308Santhony.gutierrez@amd.com        bool
117111308Santhony.gutierrez@amd.com        isPseudoOp()
117211308Santhony.gutierrez@amd.com        {
117311308Santhony.gutierrez@amd.com            std::string func_name = src0.disassemble();
117411308Santhony.gutierrez@amd.com            if (func_name.find("__gem5_hsail_op") != std::string::npos) {
117511308Santhony.gutierrez@amd.com                return true;
117611308Santhony.gutierrez@amd.com            }
117711308Santhony.gutierrez@amd.com            return false;
117811308Santhony.gutierrez@amd.com        }
117911308Santhony.gutierrez@amd.com
118011308Santhony.gutierrez@amd.com        // member variables
118111308Santhony.gutierrez@amd.com        ListOperand dest;
118211308Santhony.gutierrez@amd.com        FunctionRefOperand src0;
118311308Santhony.gutierrez@amd.com        ListOperand src1;
118411308Santhony.gutierrez@amd.com        HsailCode *func_ptr;
118511308Santhony.gutierrez@amd.com
118611308Santhony.gutierrez@amd.com        // exec function for pseudo instructions mapped on top of call opcode
118711308Santhony.gutierrez@amd.com        void execPseudoInst(Wavefront *w, GPUDynInstPtr gpuDynInst);
118811308Santhony.gutierrez@amd.com
118911308Santhony.gutierrez@amd.com        // user-defined pseudo instructions
119011308Santhony.gutierrez@amd.com        void MagicPrintLane(Wavefront *w);
119111308Santhony.gutierrez@amd.com        void MagicPrintLane64(Wavefront *w);
119211308Santhony.gutierrez@amd.com        void MagicPrintWF32(Wavefront *w);
119311308Santhony.gutierrez@amd.com        void MagicPrintWF64(Wavefront *w);
119411308Santhony.gutierrez@amd.com        void MagicPrintWFFloat(Wavefront *w);
119511308Santhony.gutierrez@amd.com        void MagicSimBreak(Wavefront *w);
119611308Santhony.gutierrez@amd.com        void MagicPrefixSum(Wavefront *w);
119711308Santhony.gutierrez@amd.com        void MagicReduction(Wavefront *w);
119811308Santhony.gutierrez@amd.com        void MagicMaskLower(Wavefront *w);
119911308Santhony.gutierrez@amd.com        void MagicMaskUpper(Wavefront *w);
120011308Santhony.gutierrez@amd.com        void MagicJoinWFBar(Wavefront *w);
120111308Santhony.gutierrez@amd.com        void MagicWaitWFBar(Wavefront *w);
120211308Santhony.gutierrez@amd.com        void MagicPanic(Wavefront *w);
120311308Santhony.gutierrez@amd.com
120411308Santhony.gutierrez@amd.com        void MagicAtomicNRAddGlobalU32Reg(Wavefront *w,
120511308Santhony.gutierrez@amd.com                                          GPUDynInstPtr gpuDynInst);
120611308Santhony.gutierrez@amd.com
120711308Santhony.gutierrez@amd.com        void MagicAtomicNRAddGroupU32Reg(Wavefront *w,
120811308Santhony.gutierrez@amd.com                                         GPUDynInstPtr gpuDynInst);
120911308Santhony.gutierrez@amd.com
121011308Santhony.gutierrez@amd.com        void MagicLoadGlobalU32Reg(Wavefront *w, GPUDynInstPtr gpuDynInst);
121111308Santhony.gutierrez@amd.com
121211308Santhony.gutierrez@amd.com        void MagicXactCasLd(Wavefront *w);
121311308Santhony.gutierrez@amd.com        void MagicMostSigThread(Wavefront *w);
121411308Santhony.gutierrez@amd.com        void MagicMostSigBroadcast(Wavefront *w);
121511308Santhony.gutierrez@amd.com
121611308Santhony.gutierrez@amd.com        void MagicPrintWF32ID(Wavefront *w);
121711308Santhony.gutierrez@amd.com        void MagicPrintWFID64(Wavefront *w);
121811308Santhony.gutierrez@amd.com
121911308Santhony.gutierrez@amd.com        Call(const Brig::BrigInstBase *ib, const BrigObject *obj)
122011308Santhony.gutierrez@amd.com            : HsailGPUStaticInst(obj, "call")
122111308Santhony.gutierrez@amd.com        {
122211692Santhony.gutierrez@amd.com            setFlag(ALU);
122311308Santhony.gutierrez@amd.com            unsigned op_offs = obj->getOperandPtr(ib->operands, 0);
122411308Santhony.gutierrez@amd.com            dest.init(op_offs, obj);
122511308Santhony.gutierrez@amd.com            op_offs = obj->getOperandPtr(ib->operands, 1);
122611308Santhony.gutierrez@amd.com            src0.init(op_offs, obj);
122711308Santhony.gutierrez@amd.com
122811308Santhony.gutierrez@amd.com            func_ptr = nullptr;
122911308Santhony.gutierrez@amd.com            std::string func_name = src0.disassemble();
123011308Santhony.gutierrez@amd.com            if (!isPseudoOp()) {
123111308Santhony.gutierrez@amd.com                func_ptr = dynamic_cast<HsailCode*>(obj->
123211308Santhony.gutierrez@amd.com                                                    getFunction(func_name));
123311308Santhony.gutierrez@amd.com
123411308Santhony.gutierrez@amd.com                if (!func_ptr)
123511308Santhony.gutierrez@amd.com                    fatal("call::exec cannot find function: %s\n", func_name);
123611308Santhony.gutierrez@amd.com            }
123711308Santhony.gutierrez@amd.com
123811308Santhony.gutierrez@amd.com            op_offs = obj->getOperandPtr(ib->operands, 2);
123911308Santhony.gutierrez@amd.com            src1.init(op_offs, obj);
124011308Santhony.gutierrez@amd.com        }
124111308Santhony.gutierrez@amd.com
124211308Santhony.gutierrez@amd.com        bool isVectorRegister(int operandIndex) { return false; }
124311308Santhony.gutierrez@amd.com        bool isCondRegister(int operandIndex) { return false; }
124411308Santhony.gutierrez@amd.com        bool isScalarRegister(int operandIndex) { return false; }
124511308Santhony.gutierrez@amd.com        bool isSrcOperand(int operandIndex) { return false; }
124611308Santhony.gutierrez@amd.com        bool isDstOperand(int operandIndex) { return false; }
124711699Santhony.gutierrez@amd.com        int getOperandSize(int operandIndex) { return 0; }
124811699Santhony.gutierrez@amd.com
124911699Santhony.gutierrez@amd.com        int
125011699Santhony.gutierrez@amd.com        getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst)
125111699Santhony.gutierrez@amd.com        {
125211699Santhony.gutierrez@amd.com            return -1;
125311699Santhony.gutierrez@amd.com        }
125411308Santhony.gutierrez@amd.com
125511308Santhony.gutierrez@amd.com        void
125611308Santhony.gutierrez@amd.com        execute(GPUDynInstPtr gpuDynInst)
125711308Santhony.gutierrez@amd.com        {
125811308Santhony.gutierrez@amd.com            Wavefront *w = gpuDynInst->wavefront();
125911308Santhony.gutierrez@amd.com
126011308Santhony.gutierrez@amd.com            std::string func_name = src0.disassemble();
126111308Santhony.gutierrez@amd.com            if (isPseudoOp()) {
126211308Santhony.gutierrez@amd.com                execPseudoInst(w, gpuDynInst);
126311308Santhony.gutierrez@amd.com            } else {
126411308Santhony.gutierrez@amd.com                fatal("Native HSAIL functions are not yet implemented: %s\n",
126511308Santhony.gutierrez@amd.com                      func_name);
126611308Santhony.gutierrez@amd.com            }
126711308Santhony.gutierrez@amd.com        }
126811308Santhony.gutierrez@amd.com        int numSrcRegOperands() { return 0; }
126911308Santhony.gutierrez@amd.com        int numDstRegOperands() { return 0; }
127011308Santhony.gutierrez@amd.com        int getNumOperands() { return 2; }
127111308Santhony.gutierrez@amd.com    };
127211308Santhony.gutierrez@amd.com
127311308Santhony.gutierrez@amd.com    template<typename T> T heynot(T arg) { return ~arg; }
127411308Santhony.gutierrez@amd.com    template<> inline bool heynot<bool>(bool arg) { return !arg; }
127512032Sandreas.sandberg@arm.com
127612032Sandreas.sandberg@arm.com
127712032Sandreas.sandberg@arm.com    /* Explicitly declare template static member variables to avoid
127812032Sandreas.sandberg@arm.com     * warnings in some clang versions
127912032Sandreas.sandberg@arm.com     */
128012032Sandreas.sandberg@arm.com    template<> const char *B1::label;
128112032Sandreas.sandberg@arm.com    template<> const char *B8::label;
128212032Sandreas.sandberg@arm.com    template<> const char *B16::label;
128312032Sandreas.sandberg@arm.com    template<> const char *B32::label;
128412032Sandreas.sandberg@arm.com    template<> const char *B64::label;
128512032Sandreas.sandberg@arm.com    template<> const char *S8::label;
128612032Sandreas.sandberg@arm.com    template<> const char *S16::label;
128712032Sandreas.sandberg@arm.com    template<> const char *S32::label;
128812032Sandreas.sandberg@arm.com    template<> const char *S64::label;
128912032Sandreas.sandberg@arm.com    template<> const char *U8::label;
129012032Sandreas.sandberg@arm.com    template<> const char *U16::label;
129112032Sandreas.sandberg@arm.com    template<> const char *U32::label;
129212032Sandreas.sandberg@arm.com    template<> const char *U64::label;
129312032Sandreas.sandberg@arm.com    template<> const char *F32::label;
129412032Sandreas.sandberg@arm.com    template<> const char *F64::label;
129512032Sandreas.sandberg@arm.com
129611308Santhony.gutierrez@amd.com} // namespace HsailISA
129711308Santhony.gutierrez@amd.com
129811308Santhony.gutierrez@amd.com#endif // __ARCH_HSAIL_INSTS_DECL_HH__
1299