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