decl.hh revision 11325
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/generic_types.hh" 4211308Santhony.gutierrez@amd.com#include "arch/hsail/insts/gpu_static_inst.hh" 4311308Santhony.gutierrez@amd.com#include "arch/hsail/operand.hh" 4411308Santhony.gutierrez@amd.com#include "debug/HSAIL.hh" 4511308Santhony.gutierrez@amd.com#include "enums/OpType.hh" 4611308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_dyn_inst.hh" 4711308Santhony.gutierrez@amd.com#include "gpu-compute/shader.hh" 4811308Santhony.gutierrez@amd.com 4911308Santhony.gutierrez@amd.comnamespace HsailISA 5011308Santhony.gutierrez@amd.com{ 5111308Santhony.gutierrez@amd.com template<typename _DestOperand, typename _SrcOperand> 5211308Santhony.gutierrez@amd.com class HsailOperandType 5311308Santhony.gutierrez@amd.com { 5411308Santhony.gutierrez@amd.com public: 5511308Santhony.gutierrez@amd.com typedef _DestOperand DestOperand; 5611308Santhony.gutierrez@amd.com typedef _SrcOperand SrcOperand; 5711308Santhony.gutierrez@amd.com }; 5811308Santhony.gutierrez@amd.com 5911308Santhony.gutierrez@amd.com typedef HsailOperandType<CRegOperand, CRegOrImmOperand> CRegOperandType; 6011308Santhony.gutierrez@amd.com typedef HsailOperandType<SRegOperand, SRegOrImmOperand> SRegOperandType; 6111308Santhony.gutierrez@amd.com typedef HsailOperandType<DRegOperand, DRegOrImmOperand> DRegOperandType; 6211308Santhony.gutierrez@amd.com 6311308Santhony.gutierrez@amd.com // The IsBits parameter serves only to disambiguate tbhe B* types from 6411308Santhony.gutierrez@amd.com // the U* types, which otherwise would be identical (and 6511308Santhony.gutierrez@amd.com // indistinguishable). 6611308Santhony.gutierrez@amd.com template<typename _OperandType, typename _CType, Enums::MemType _memType, 6711308Santhony.gutierrez@amd.com vgpr_type _vgprType, int IsBits=0> 6811308Santhony.gutierrez@amd.com class HsailDataType 6911308Santhony.gutierrez@amd.com { 7011308Santhony.gutierrez@amd.com public: 7111308Santhony.gutierrez@amd.com typedef _OperandType OperandType; 7211308Santhony.gutierrez@amd.com typedef _CType CType; 7311308Santhony.gutierrez@amd.com static const Enums::MemType memType = _memType; 7411308Santhony.gutierrez@amd.com static const vgpr_type vgprType = _vgprType; 7511308Santhony.gutierrez@amd.com static const char *label; 7611308Santhony.gutierrez@amd.com }; 7711308Santhony.gutierrez@amd.com 7811308Santhony.gutierrez@amd.com typedef HsailDataType<CRegOperandType, bool, Enums::M_U8, VT_32, 1> B1; 7911308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, uint8_t, Enums::M_U8, VT_32, 1> B8; 8011308Santhony.gutierrez@amd.com 8111308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, uint16_t, 8211308Santhony.gutierrez@amd.com Enums::M_U16, VT_32, 1> B16; 8311308Santhony.gutierrez@amd.com 8411308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, uint32_t, 8511308Santhony.gutierrez@amd.com Enums::M_U32, VT_32, 1> B32; 8611308Santhony.gutierrez@amd.com 8711308Santhony.gutierrez@amd.com typedef HsailDataType<DRegOperandType, uint64_t, 8811308Santhony.gutierrez@amd.com Enums::M_U64, VT_64, 1> B64; 8911308Santhony.gutierrez@amd.com 9011308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, int8_t, Enums::M_S8, VT_32> S8; 9111308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, int16_t, Enums::M_S16, VT_32> S16; 9211308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, int32_t, Enums::M_S32, VT_32> S32; 9311308Santhony.gutierrez@amd.com typedef HsailDataType<DRegOperandType, int64_t, Enums::M_S64, VT_64> S64; 9411308Santhony.gutierrez@amd.com 9511308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, uint8_t, Enums::M_U8, VT_32> U8; 9611308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, uint16_t, Enums::M_U16, VT_32> U16; 9711308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, uint32_t, Enums::M_U32, VT_32> U32; 9811308Santhony.gutierrez@amd.com typedef HsailDataType<DRegOperandType, uint64_t, Enums::M_U64, VT_64> U64; 9911308Santhony.gutierrez@amd.com 10011308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, float, Enums::M_F32, VT_32> F32; 10111308Santhony.gutierrez@amd.com typedef HsailDataType<DRegOperandType, double, Enums::M_F64, VT_64> F64; 10211308Santhony.gutierrez@amd.com 10311308Santhony.gutierrez@amd.com template<typename DestOperandType, typename SrcOperandType, 10411308Santhony.gutierrez@amd.com int NumSrcOperands> 10511308Santhony.gutierrez@amd.com class CommonInstBase : public HsailGPUStaticInst 10611308Santhony.gutierrez@amd.com { 10711308Santhony.gutierrez@amd.com protected: 10811308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 10911308Santhony.gutierrez@amd.com typename SrcOperandType::SrcOperand src[NumSrcOperands]; 11011308Santhony.gutierrez@amd.com 11111308Santhony.gutierrez@amd.com void 11211308Santhony.gutierrez@amd.com generateDisassembly() 11311308Santhony.gutierrez@amd.com { 11411308Santhony.gutierrez@amd.com disassembly = csprintf("%s%s %s", opcode, opcode_suffix(), 11511308Santhony.gutierrez@amd.com dest.disassemble()); 11611308Santhony.gutierrez@amd.com 11711308Santhony.gutierrez@amd.com for (int i = 0; i < NumSrcOperands; ++i) { 11811308Santhony.gutierrez@amd.com disassembly += ","; 11911308Santhony.gutierrez@amd.com disassembly += src[i].disassemble(); 12011308Santhony.gutierrez@amd.com } 12111308Santhony.gutierrez@amd.com } 12211308Santhony.gutierrez@amd.com 12311308Santhony.gutierrez@amd.com virtual std::string opcode_suffix() = 0; 12411308Santhony.gutierrez@amd.com 12511308Santhony.gutierrez@amd.com public: 12611308Santhony.gutierrez@amd.com CommonInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, 12711308Santhony.gutierrez@amd.com const char *opcode) 12811308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, opcode) 12911308Santhony.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 } 18111308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { 18211308Santhony.gutierrez@amd.com assert(operandIndex >= 0 && operandIndex < getNumOperands()); 18311308Santhony.gutierrez@amd.com 18411308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 18511308Santhony.gutierrez@amd.com return src[operandIndex].regIndex(); 18611308Santhony.gutierrez@amd.com else 18711308Santhony.gutierrez@amd.com return dest.regIndex(); 18811308Santhony.gutierrez@amd.com } 18911308Santhony.gutierrez@amd.com int numSrcRegOperands() { 19011308Santhony.gutierrez@amd.com int operands = 0; 19111308Santhony.gutierrez@amd.com for (int i = 0; i < NumSrcOperands; i++) { 19211325Ssteve.reinhardt@amd.com if (src[i].isVectorRegister()) { 19311308Santhony.gutierrez@amd.com operands++; 19411308Santhony.gutierrez@amd.com } 19511308Santhony.gutierrez@amd.com } 19611308Santhony.gutierrez@amd.com return operands; 19711308Santhony.gutierrez@amd.com } 19811308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 19911308Santhony.gutierrez@amd.com int getNumOperands() { return NumSrcOperands + 1; } 20011308Santhony.gutierrez@amd.com }; 20111308Santhony.gutierrez@amd.com 20211308Santhony.gutierrez@amd.com template<typename DataType, int NumSrcOperands> 20311308Santhony.gutierrez@amd.com class ArithInst : public CommonInstBase<typename DataType::OperandType, 20411308Santhony.gutierrez@amd.com typename DataType::OperandType, 20511308Santhony.gutierrez@amd.com NumSrcOperands> 20611308Santhony.gutierrez@amd.com { 20711308Santhony.gutierrez@amd.com public: 20811308Santhony.gutierrez@amd.com std::string opcode_suffix() { return csprintf("_%s", DataType::label); } 20911308Santhony.gutierrez@amd.com 21011308Santhony.gutierrez@amd.com ArithInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 21111308Santhony.gutierrez@amd.com const char *opcode) 21211308Santhony.gutierrez@amd.com : CommonInstBase<typename DataType::OperandType, 21311308Santhony.gutierrez@amd.com typename DataType::OperandType, 21411308Santhony.gutierrez@amd.com NumSrcOperands>(ib, obj, opcode) 21511308Santhony.gutierrez@amd.com { 21611308Santhony.gutierrez@amd.com } 21711308Santhony.gutierrez@amd.com }; 21811308Santhony.gutierrez@amd.com 21911308Santhony.gutierrez@amd.com template<typename DestOperandType, typename Src0OperandType, 22011308Santhony.gutierrez@amd.com typename Src1OperandType, typename Src2OperandType> 22111308Santhony.gutierrez@amd.com class ThreeNonUniformSourceInstBase : public HsailGPUStaticInst 22211308Santhony.gutierrez@amd.com { 22311308Santhony.gutierrez@amd.com protected: 22411308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 22511308Santhony.gutierrez@amd.com typename Src0OperandType::SrcOperand src0; 22611308Santhony.gutierrez@amd.com typename Src1OperandType::SrcOperand src1; 22711308Santhony.gutierrez@amd.com typename Src2OperandType::SrcOperand src2; 22811308Santhony.gutierrez@amd.com 22911308Santhony.gutierrez@amd.com void 23011308Santhony.gutierrez@amd.com generateDisassembly() 23111308Santhony.gutierrez@amd.com { 23211308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s,%s,%s,%s", opcode, dest.disassemble(), 23311308Santhony.gutierrez@amd.com src0.disassemble(), src1.disassemble(), 23411308Santhony.gutierrez@amd.com src2.disassemble()); 23511308Santhony.gutierrez@amd.com } 23611308Santhony.gutierrez@amd.com 23711308Santhony.gutierrez@amd.com public: 23811308Santhony.gutierrez@amd.com ThreeNonUniformSourceInstBase(const Brig::BrigInstBase *ib, 23911308Santhony.gutierrez@amd.com const BrigObject *obj, 24011308Santhony.gutierrez@amd.com const char *opcode) 24111308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, opcode) 24211308Santhony.gutierrez@amd.com { 24311308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 24411308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 24511308Santhony.gutierrez@amd.com 24611308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 24711308Santhony.gutierrez@amd.com src0.init(op_offs, obj); 24811308Santhony.gutierrez@amd.com 24911308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 2); 25011308Santhony.gutierrez@amd.com src1.init(op_offs, obj); 25111308Santhony.gutierrez@amd.com 25211308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 3); 25311308Santhony.gutierrez@amd.com src2.init(op_offs, obj); 25411308Santhony.gutierrez@amd.com } 25511308Santhony.gutierrez@amd.com 25611308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { 25711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 25811308Santhony.gutierrez@amd.com if (!operandIndex) 25911308Santhony.gutierrez@amd.com return src0.isVectorRegister(); 26011308Santhony.gutierrez@amd.com else if (operandIndex == 1) 26111308Santhony.gutierrez@amd.com return src1.isVectorRegister(); 26211308Santhony.gutierrez@amd.com else if (operandIndex == 2) 26311308Santhony.gutierrez@amd.com return src2.isVectorRegister(); 26411308Santhony.gutierrez@amd.com else 26511308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 26611308Santhony.gutierrez@amd.com } 26711308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { 26811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 26911308Santhony.gutierrez@amd.com if (!operandIndex) 27011308Santhony.gutierrez@amd.com return src0.isCondRegister(); 27111308Santhony.gutierrez@amd.com else if (operandIndex == 1) 27211308Santhony.gutierrez@amd.com return src1.isCondRegister(); 27311308Santhony.gutierrez@amd.com else if (operandIndex == 2) 27411308Santhony.gutierrez@amd.com return src2.isCondRegister(); 27511308Santhony.gutierrez@amd.com else 27611308Santhony.gutierrez@amd.com return dest.isCondRegister(); 27711308Santhony.gutierrez@amd.com } 27811308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { 27911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 28011308Santhony.gutierrez@amd.com if (!operandIndex) 28111308Santhony.gutierrez@amd.com return src0.isScalarRegister(); 28211308Santhony.gutierrez@amd.com else if (operandIndex == 1) 28311308Santhony.gutierrez@amd.com return src1.isScalarRegister(); 28411308Santhony.gutierrez@amd.com else if (operandIndex == 2) 28511308Santhony.gutierrez@amd.com return src2.isScalarRegister(); 28611308Santhony.gutierrez@amd.com else 28711308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 28811308Santhony.gutierrez@amd.com } 28911308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { 29011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 29111308Santhony.gutierrez@amd.com if (operandIndex < 3) 29211308Santhony.gutierrez@amd.com return true; 29311308Santhony.gutierrez@amd.com else 29411308Santhony.gutierrez@amd.com return false; 29511308Santhony.gutierrez@amd.com } 29611308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { 29711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 29811308Santhony.gutierrez@amd.com if (operandIndex >= 3) 29911308Santhony.gutierrez@amd.com return true; 30011308Santhony.gutierrez@amd.com else 30111308Santhony.gutierrez@amd.com return false; 30211308Santhony.gutierrez@amd.com } 30311308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { 30411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 30511308Santhony.gutierrez@amd.com if (!operandIndex) 30611308Santhony.gutierrez@amd.com return src0.opSize(); 30711308Santhony.gutierrez@amd.com else if (operandIndex == 1) 30811308Santhony.gutierrez@amd.com return src1.opSize(); 30911308Santhony.gutierrez@amd.com else if (operandIndex == 2) 31011308Santhony.gutierrez@amd.com return src2.opSize(); 31111308Santhony.gutierrez@amd.com else 31211308Santhony.gutierrez@amd.com return dest.opSize(); 31311308Santhony.gutierrez@amd.com } 31411308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { 31511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 31611308Santhony.gutierrez@amd.com if (!operandIndex) 31711308Santhony.gutierrez@amd.com return src0.regIndex(); 31811308Santhony.gutierrez@amd.com else if (operandIndex == 1) 31911308Santhony.gutierrez@amd.com return src1.regIndex(); 32011308Santhony.gutierrez@amd.com else if (operandIndex == 2) 32111308Santhony.gutierrez@amd.com return src2.regIndex(); 32211308Santhony.gutierrez@amd.com else 32311308Santhony.gutierrez@amd.com return dest.regIndex(); 32411308Santhony.gutierrez@amd.com } 32511308Santhony.gutierrez@amd.com 32611308Santhony.gutierrez@amd.com int numSrcRegOperands() { 32711308Santhony.gutierrez@amd.com int operands = 0; 32811325Ssteve.reinhardt@amd.com if (src0.isVectorRegister()) { 32911308Santhony.gutierrez@amd.com operands++; 33011308Santhony.gutierrez@amd.com } 33111325Ssteve.reinhardt@amd.com if (src1.isVectorRegister()) { 33211308Santhony.gutierrez@amd.com operands++; 33311308Santhony.gutierrez@amd.com } 33411325Ssteve.reinhardt@amd.com if (src2.isVectorRegister()) { 33511308Santhony.gutierrez@amd.com operands++; 33611308Santhony.gutierrez@amd.com } 33711308Santhony.gutierrez@amd.com return operands; 33811308Santhony.gutierrez@amd.com } 33911308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 34011308Santhony.gutierrez@amd.com int getNumOperands() { return 4; } 34111308Santhony.gutierrez@amd.com }; 34211308Santhony.gutierrez@amd.com 34311308Santhony.gutierrez@amd.com template<typename DestDataType, typename Src0DataType, 34411308Santhony.gutierrez@amd.com typename Src1DataType, typename Src2DataType> 34511308Santhony.gutierrez@amd.com class ThreeNonUniformSourceInst : 34611308Santhony.gutierrez@amd.com public ThreeNonUniformSourceInstBase<typename DestDataType::OperandType, 34711308Santhony.gutierrez@amd.com typename Src0DataType::OperandType, 34811308Santhony.gutierrez@amd.com typename Src1DataType::OperandType, 34911308Santhony.gutierrez@amd.com typename Src2DataType::OperandType> 35011308Santhony.gutierrez@amd.com { 35111308Santhony.gutierrez@amd.com public: 35211308Santhony.gutierrez@amd.com typedef typename DestDataType::CType DestCType; 35311308Santhony.gutierrez@amd.com typedef typename Src0DataType::CType Src0CType; 35411308Santhony.gutierrez@amd.com typedef typename Src1DataType::CType Src1CType; 35511308Santhony.gutierrez@amd.com typedef typename Src2DataType::CType Src2CType; 35611308Santhony.gutierrez@amd.com 35711308Santhony.gutierrez@amd.com ThreeNonUniformSourceInst(const Brig::BrigInstBase *ib, 35811308Santhony.gutierrez@amd.com const BrigObject *obj, const char *opcode) 35911308Santhony.gutierrez@amd.com : ThreeNonUniformSourceInstBase<typename DestDataType::OperandType, 36011308Santhony.gutierrez@amd.com typename Src0DataType::OperandType, 36111308Santhony.gutierrez@amd.com typename Src1DataType::OperandType, 36211308Santhony.gutierrez@amd.com typename Src2DataType::OperandType>(ib, 36311308Santhony.gutierrez@amd.com obj, opcode) 36411308Santhony.gutierrez@amd.com { 36511308Santhony.gutierrez@amd.com } 36611308Santhony.gutierrez@amd.com }; 36711308Santhony.gutierrez@amd.com 36811308Santhony.gutierrez@amd.com template<typename DataType> 36911308Santhony.gutierrez@amd.com class CmovInst : public ThreeNonUniformSourceInst<DataType, B1, 37011308Santhony.gutierrez@amd.com DataType, DataType> 37111308Santhony.gutierrez@amd.com { 37211308Santhony.gutierrez@amd.com public: 37311308Santhony.gutierrez@amd.com CmovInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 37411308Santhony.gutierrez@amd.com const char *opcode) 37511308Santhony.gutierrez@amd.com : ThreeNonUniformSourceInst<DataType, B1, DataType, 37611308Santhony.gutierrez@amd.com DataType>(ib, obj, opcode) 37711308Santhony.gutierrez@amd.com { 37811308Santhony.gutierrez@amd.com } 37911308Santhony.gutierrez@amd.com }; 38011308Santhony.gutierrez@amd.com 38111308Santhony.gutierrez@amd.com template<typename DataType> 38211308Santhony.gutierrez@amd.com class ExtractInsertInst : public ThreeNonUniformSourceInst<DataType, 38311308Santhony.gutierrez@amd.com DataType, U32, 38411308Santhony.gutierrez@amd.com U32> 38511308Santhony.gutierrez@amd.com { 38611308Santhony.gutierrez@amd.com public: 38711308Santhony.gutierrez@amd.com ExtractInsertInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 38811308Santhony.gutierrez@amd.com const char *opcode) 38911308Santhony.gutierrez@amd.com : ThreeNonUniformSourceInst<DataType, DataType, U32, 39011308Santhony.gutierrez@amd.com U32>(ib, obj, opcode) 39111308Santhony.gutierrez@amd.com { 39211308Santhony.gutierrez@amd.com } 39311308Santhony.gutierrez@amd.com }; 39411308Santhony.gutierrez@amd.com 39511308Santhony.gutierrez@amd.com template<typename DestOperandType, typename Src0OperandType, 39611308Santhony.gutierrez@amd.com typename Src1OperandType> 39711308Santhony.gutierrez@amd.com class TwoNonUniformSourceInstBase : public HsailGPUStaticInst 39811308Santhony.gutierrez@amd.com { 39911308Santhony.gutierrez@amd.com protected: 40011308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 40111308Santhony.gutierrez@amd.com typename Src0OperandType::SrcOperand src0; 40211308Santhony.gutierrez@amd.com typename Src1OperandType::SrcOperand src1; 40311308Santhony.gutierrez@amd.com 40411308Santhony.gutierrez@amd.com void 40511308Santhony.gutierrez@amd.com generateDisassembly() 40611308Santhony.gutierrez@amd.com { 40711308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s,%s,%s", opcode, dest.disassemble(), 40811308Santhony.gutierrez@amd.com src0.disassemble(), src1.disassemble()); 40911308Santhony.gutierrez@amd.com } 41011308Santhony.gutierrez@amd.com 41111308Santhony.gutierrez@amd.com 41211308Santhony.gutierrez@amd.com public: 41311308Santhony.gutierrez@amd.com TwoNonUniformSourceInstBase(const Brig::BrigInstBase *ib, 41411308Santhony.gutierrez@amd.com const BrigObject *obj, const char *opcode) 41511308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, opcode) 41611308Santhony.gutierrez@amd.com { 41711308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 41811308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 41911308Santhony.gutierrez@amd.com 42011308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 42111308Santhony.gutierrez@amd.com src0.init(op_offs, obj); 42211308Santhony.gutierrez@amd.com 42311308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 2); 42411308Santhony.gutierrez@amd.com src1.init(op_offs, obj); 42511308Santhony.gutierrez@amd.com } 42611308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { 42711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 42811308Santhony.gutierrez@amd.com if (!operandIndex) 42911308Santhony.gutierrez@amd.com return src0.isVectorRegister(); 43011308Santhony.gutierrez@amd.com else if (operandIndex == 1) 43111308Santhony.gutierrez@amd.com return src1.isVectorRegister(); 43211308Santhony.gutierrez@amd.com else 43311308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 43411308Santhony.gutierrez@amd.com } 43511308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { 43611308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 43711308Santhony.gutierrez@amd.com if (!operandIndex) 43811308Santhony.gutierrez@amd.com return src0.isCondRegister(); 43911308Santhony.gutierrez@amd.com else if (operandIndex == 1) 44011308Santhony.gutierrez@amd.com return src1.isCondRegister(); 44111308Santhony.gutierrez@amd.com else 44211308Santhony.gutierrez@amd.com return dest.isCondRegister(); 44311308Santhony.gutierrez@amd.com } 44411308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { 44511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 44611308Santhony.gutierrez@amd.com if (!operandIndex) 44711308Santhony.gutierrez@amd.com return src0.isScalarRegister(); 44811308Santhony.gutierrez@amd.com else if (operandIndex == 1) 44911308Santhony.gutierrez@amd.com return src1.isScalarRegister(); 45011308Santhony.gutierrez@amd.com else 45111308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 45211308Santhony.gutierrez@amd.com } 45311308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { 45411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 45511308Santhony.gutierrez@amd.com if (operandIndex < 2) 45611308Santhony.gutierrez@amd.com return true; 45711308Santhony.gutierrez@amd.com else 45811308Santhony.gutierrez@amd.com return false; 45911308Santhony.gutierrez@amd.com } 46011308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { 46111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 46211308Santhony.gutierrez@amd.com if (operandIndex >= 2) 46311308Santhony.gutierrez@amd.com return true; 46411308Santhony.gutierrez@amd.com else 46511308Santhony.gutierrez@amd.com return false; 46611308Santhony.gutierrez@amd.com } 46711308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { 46811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 46911308Santhony.gutierrez@amd.com if (!operandIndex) 47011308Santhony.gutierrez@amd.com return src0.opSize(); 47111308Santhony.gutierrez@amd.com else if (operandIndex == 1) 47211308Santhony.gutierrez@amd.com return src1.opSize(); 47311308Santhony.gutierrez@amd.com else 47411308Santhony.gutierrez@amd.com return dest.opSize(); 47511308Santhony.gutierrez@amd.com } 47611308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { 47711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 47811308Santhony.gutierrez@amd.com if (!operandIndex) 47911308Santhony.gutierrez@amd.com return src0.regIndex(); 48011308Santhony.gutierrez@amd.com else if (operandIndex == 1) 48111308Santhony.gutierrez@amd.com return src1.regIndex(); 48211308Santhony.gutierrez@amd.com else 48311308Santhony.gutierrez@amd.com return dest.regIndex(); 48411308Santhony.gutierrez@amd.com } 48511308Santhony.gutierrez@amd.com 48611308Santhony.gutierrez@amd.com int numSrcRegOperands() { 48711308Santhony.gutierrez@amd.com int operands = 0; 48811325Ssteve.reinhardt@amd.com if (src0.isVectorRegister()) { 48911308Santhony.gutierrez@amd.com operands++; 49011308Santhony.gutierrez@amd.com } 49111325Ssteve.reinhardt@amd.com if (src1.isVectorRegister()) { 49211308Santhony.gutierrez@amd.com operands++; 49311308Santhony.gutierrez@amd.com } 49411308Santhony.gutierrez@amd.com return operands; 49511308Santhony.gutierrez@amd.com } 49611308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 49711308Santhony.gutierrez@amd.com int getNumOperands() { return 3; } 49811308Santhony.gutierrez@amd.com }; 49911308Santhony.gutierrez@amd.com 50011308Santhony.gutierrez@amd.com template<typename DestDataType, typename Src0DataType, 50111308Santhony.gutierrez@amd.com typename Src1DataType> 50211308Santhony.gutierrez@amd.com class TwoNonUniformSourceInst : 50311308Santhony.gutierrez@amd.com public TwoNonUniformSourceInstBase<typename DestDataType::OperandType, 50411308Santhony.gutierrez@amd.com typename Src0DataType::OperandType, 50511308Santhony.gutierrez@amd.com typename Src1DataType::OperandType> 50611308Santhony.gutierrez@amd.com { 50711308Santhony.gutierrez@amd.com public: 50811308Santhony.gutierrez@amd.com typedef typename DestDataType::CType DestCType; 50911308Santhony.gutierrez@amd.com typedef typename Src0DataType::CType Src0CType; 51011308Santhony.gutierrez@amd.com typedef typename Src1DataType::CType Src1CType; 51111308Santhony.gutierrez@amd.com 51211308Santhony.gutierrez@amd.com TwoNonUniformSourceInst(const Brig::BrigInstBase *ib, 51311308Santhony.gutierrez@amd.com const BrigObject *obj, const char *opcode) 51411308Santhony.gutierrez@amd.com : TwoNonUniformSourceInstBase<typename DestDataType::OperandType, 51511308Santhony.gutierrez@amd.com typename Src0DataType::OperandType, 51611308Santhony.gutierrez@amd.com typename Src1DataType::OperandType>(ib, 51711308Santhony.gutierrez@amd.com obj, opcode) 51811308Santhony.gutierrez@amd.com { 51911308Santhony.gutierrez@amd.com } 52011308Santhony.gutierrez@amd.com }; 52111308Santhony.gutierrez@amd.com 52211308Santhony.gutierrez@amd.com // helper function for ClassInst 52311308Santhony.gutierrez@amd.com template<typename T> 52411308Santhony.gutierrez@amd.com bool 52511308Santhony.gutierrez@amd.com fpclassify(T src0, uint32_t src1) 52611308Santhony.gutierrez@amd.com { 52711308Santhony.gutierrez@amd.com int fpclass = std::fpclassify(src0); 52811308Santhony.gutierrez@amd.com 52911308Santhony.gutierrez@amd.com if ((src1 & 0x3) && (fpclass == FP_NAN)) { 53011308Santhony.gutierrez@amd.com return true; 53111308Santhony.gutierrez@amd.com } 53211308Santhony.gutierrez@amd.com 53311308Santhony.gutierrez@amd.com if (src0 <= -0.0) { 53411308Santhony.gutierrez@amd.com if ((src1 & 0x4) && fpclass == FP_INFINITE) 53511308Santhony.gutierrez@amd.com return true; 53611308Santhony.gutierrez@amd.com if ((src1 & 0x8) && fpclass == FP_NORMAL) 53711308Santhony.gutierrez@amd.com return true; 53811308Santhony.gutierrez@amd.com if ((src1 & 0x10) && fpclass == FP_SUBNORMAL) 53911308Santhony.gutierrez@amd.com return true; 54011308Santhony.gutierrez@amd.com if ((src1 & 0x20) && fpclass == FP_ZERO) 54111308Santhony.gutierrez@amd.com return true; 54211308Santhony.gutierrez@amd.com } else { 54311308Santhony.gutierrez@amd.com if ((src1 & 0x40) && fpclass == FP_ZERO) 54411308Santhony.gutierrez@amd.com return true; 54511308Santhony.gutierrez@amd.com if ((src1 & 0x80) && fpclass == FP_SUBNORMAL) 54611308Santhony.gutierrez@amd.com return true; 54711308Santhony.gutierrez@amd.com if ((src1 & 0x100) && fpclass == FP_NORMAL) 54811308Santhony.gutierrez@amd.com return true; 54911308Santhony.gutierrez@amd.com if ((src1 & 0x200) && fpclass == FP_INFINITE) 55011308Santhony.gutierrez@amd.com return true; 55111308Santhony.gutierrez@amd.com } 55211308Santhony.gutierrez@amd.com return false; 55311308Santhony.gutierrez@amd.com } 55411308Santhony.gutierrez@amd.com 55511308Santhony.gutierrez@amd.com template<typename DataType> 55611308Santhony.gutierrez@amd.com class ClassInst : public TwoNonUniformSourceInst<B1, DataType, U32> 55711308Santhony.gutierrez@amd.com { 55811308Santhony.gutierrez@amd.com public: 55911308Santhony.gutierrez@amd.com ClassInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 56011308Santhony.gutierrez@amd.com const char *opcode) 56111308Santhony.gutierrez@amd.com : TwoNonUniformSourceInst<B1, DataType, U32>(ib, obj, opcode) 56211308Santhony.gutierrez@amd.com { 56311308Santhony.gutierrez@amd.com } 56411308Santhony.gutierrez@amd.com }; 56511308Santhony.gutierrez@amd.com 56611308Santhony.gutierrez@amd.com template<typename DataType> 56711308Santhony.gutierrez@amd.com class ShiftInst : public TwoNonUniformSourceInst<DataType, DataType, U32> 56811308Santhony.gutierrez@amd.com { 56911308Santhony.gutierrez@amd.com public: 57011308Santhony.gutierrez@amd.com ShiftInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 57111308Santhony.gutierrez@amd.com const char *opcode) 57211308Santhony.gutierrez@amd.com : TwoNonUniformSourceInst<DataType, DataType, U32>(ib, obj, opcode) 57311308Santhony.gutierrez@amd.com { 57411308Santhony.gutierrez@amd.com } 57511308Santhony.gutierrez@amd.com }; 57611308Santhony.gutierrez@amd.com 57711308Santhony.gutierrez@amd.com // helper function for CmpInst 57811308Santhony.gutierrez@amd.com template<typename T> 57911308Santhony.gutierrez@amd.com bool 58011308Santhony.gutierrez@amd.com compare(T src0, T src1, Brig::BrigCompareOperation cmpOp) 58111308Santhony.gutierrez@amd.com { 58211308Santhony.gutierrez@amd.com using namespace Brig; 58311308Santhony.gutierrez@amd.com 58411308Santhony.gutierrez@amd.com switch (cmpOp) { 58511308Santhony.gutierrez@amd.com case BRIG_COMPARE_EQ: 58611308Santhony.gutierrez@amd.com case BRIG_COMPARE_EQU: 58711308Santhony.gutierrez@amd.com case BRIG_COMPARE_SEQ: 58811308Santhony.gutierrez@amd.com case BRIG_COMPARE_SEQU: 58911308Santhony.gutierrez@amd.com return (src0 == src1); 59011308Santhony.gutierrez@amd.com 59111308Santhony.gutierrez@amd.com case BRIG_COMPARE_NE: 59211308Santhony.gutierrez@amd.com case BRIG_COMPARE_NEU: 59311308Santhony.gutierrez@amd.com case BRIG_COMPARE_SNE: 59411308Santhony.gutierrez@amd.com case BRIG_COMPARE_SNEU: 59511308Santhony.gutierrez@amd.com return (src0 != src1); 59611308Santhony.gutierrez@amd.com 59711308Santhony.gutierrez@amd.com case BRIG_COMPARE_LT: 59811308Santhony.gutierrez@amd.com case BRIG_COMPARE_LTU: 59911308Santhony.gutierrez@amd.com case BRIG_COMPARE_SLT: 60011308Santhony.gutierrez@amd.com case BRIG_COMPARE_SLTU: 60111308Santhony.gutierrez@amd.com return (src0 < src1); 60211308Santhony.gutierrez@amd.com 60311308Santhony.gutierrez@amd.com case BRIG_COMPARE_LE: 60411308Santhony.gutierrez@amd.com case BRIG_COMPARE_LEU: 60511308Santhony.gutierrez@amd.com case BRIG_COMPARE_SLE: 60611308Santhony.gutierrez@amd.com case BRIG_COMPARE_SLEU: 60711308Santhony.gutierrez@amd.com return (src0 <= src1); 60811308Santhony.gutierrez@amd.com 60911308Santhony.gutierrez@amd.com case BRIG_COMPARE_GT: 61011308Santhony.gutierrez@amd.com case BRIG_COMPARE_GTU: 61111308Santhony.gutierrez@amd.com case BRIG_COMPARE_SGT: 61211308Santhony.gutierrez@amd.com case BRIG_COMPARE_SGTU: 61311308Santhony.gutierrez@amd.com return (src0 > src1); 61411308Santhony.gutierrez@amd.com 61511308Santhony.gutierrez@amd.com case BRIG_COMPARE_GE: 61611308Santhony.gutierrez@amd.com case BRIG_COMPARE_GEU: 61711308Santhony.gutierrez@amd.com case BRIG_COMPARE_SGE: 61811308Santhony.gutierrez@amd.com case BRIG_COMPARE_SGEU: 61911308Santhony.gutierrez@amd.com return (src0 >= src1); 62011308Santhony.gutierrez@amd.com 62111308Santhony.gutierrez@amd.com case BRIG_COMPARE_NUM: 62211308Santhony.gutierrez@amd.com case BRIG_COMPARE_SNUM: 62311308Santhony.gutierrez@amd.com return (src0 == src0) || (src1 == src1); 62411308Santhony.gutierrez@amd.com 62511308Santhony.gutierrez@amd.com case BRIG_COMPARE_NAN: 62611308Santhony.gutierrez@amd.com case BRIG_COMPARE_SNAN: 62711308Santhony.gutierrez@amd.com return (src0 != src0) || (src1 != src1); 62811308Santhony.gutierrez@amd.com 62911308Santhony.gutierrez@amd.com default: 63011308Santhony.gutierrez@amd.com fatal("Bad cmpOp value %d\n", (int)cmpOp); 63111308Santhony.gutierrez@amd.com } 63211308Santhony.gutierrez@amd.com } 63311308Santhony.gutierrez@amd.com 63411308Santhony.gutierrez@amd.com template<typename T> 63511308Santhony.gutierrez@amd.com int32_t 63611308Santhony.gutierrez@amd.com firstbit(T src0) 63711308Santhony.gutierrez@amd.com { 63811308Santhony.gutierrez@amd.com if (!src0) 63911308Santhony.gutierrez@amd.com return -1; 64011308Santhony.gutierrez@amd.com 64111308Santhony.gutierrez@amd.com //handle positive and negative numbers 64211308Santhony.gutierrez@amd.com T tmp = (src0 < 0) ? (~src0) : (src0); 64311308Santhony.gutierrez@amd.com 64411308Santhony.gutierrez@amd.com //the starting pos is MSB 64511308Santhony.gutierrez@amd.com int pos = 8 * sizeof(T) - 1; 64611308Santhony.gutierrez@amd.com int cnt = 0; 64711308Santhony.gutierrez@amd.com 64811308Santhony.gutierrez@amd.com //search the first bit set to 1 64911308Santhony.gutierrez@amd.com while (!(tmp & (1 << pos))) { 65011308Santhony.gutierrez@amd.com ++cnt; 65111308Santhony.gutierrez@amd.com --pos; 65211308Santhony.gutierrez@amd.com } 65311308Santhony.gutierrez@amd.com return cnt; 65411308Santhony.gutierrez@amd.com } 65511308Santhony.gutierrez@amd.com 65611308Santhony.gutierrez@amd.com const char* cmpOpToString(Brig::BrigCompareOperation cmpOp); 65711308Santhony.gutierrez@amd.com 65811308Santhony.gutierrez@amd.com template<typename DestOperandType, typename SrcOperandType> 65911308Santhony.gutierrez@amd.com class CmpInstBase : public CommonInstBase<DestOperandType, SrcOperandType, 66011308Santhony.gutierrez@amd.com 2> 66111308Santhony.gutierrez@amd.com { 66211308Santhony.gutierrez@amd.com protected: 66311308Santhony.gutierrez@amd.com Brig::BrigCompareOperation cmpOp; 66411308Santhony.gutierrez@amd.com 66511308Santhony.gutierrez@amd.com public: 66611308Santhony.gutierrez@amd.com CmpInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, 66711308Santhony.gutierrez@amd.com const char *_opcode) 66811308Santhony.gutierrez@amd.com : CommonInstBase<DestOperandType, SrcOperandType, 2>(ib, obj, 66911308Santhony.gutierrez@amd.com _opcode) 67011308Santhony.gutierrez@amd.com { 67111308Santhony.gutierrez@amd.com assert(ib->base.kind == Brig::BRIG_KIND_INST_CMP); 67211308Santhony.gutierrez@amd.com Brig::BrigInstCmp *i = (Brig::BrigInstCmp*)ib; 67311308Santhony.gutierrez@amd.com cmpOp = (Brig::BrigCompareOperation)i->compare; 67411308Santhony.gutierrez@amd.com } 67511308Santhony.gutierrez@amd.com }; 67611308Santhony.gutierrez@amd.com 67711308Santhony.gutierrez@amd.com template<typename DestDataType, typename SrcDataType> 67811308Santhony.gutierrez@amd.com class CmpInst : public CmpInstBase<typename DestDataType::OperandType, 67911308Santhony.gutierrez@amd.com typename SrcDataType::OperandType> 68011308Santhony.gutierrez@amd.com { 68111308Santhony.gutierrez@amd.com public: 68211308Santhony.gutierrez@amd.com std::string 68311308Santhony.gutierrez@amd.com opcode_suffix() 68411308Santhony.gutierrez@amd.com { 68511308Santhony.gutierrez@amd.com return csprintf("_%s_%s_%s", cmpOpToString(this->cmpOp), 68611308Santhony.gutierrez@amd.com DestDataType::label, SrcDataType::label); 68711308Santhony.gutierrez@amd.com } 68811308Santhony.gutierrez@amd.com 68911308Santhony.gutierrez@amd.com CmpInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 69011308Santhony.gutierrez@amd.com const char *_opcode) 69111308Santhony.gutierrez@amd.com : CmpInstBase<typename DestDataType::OperandType, 69211308Santhony.gutierrez@amd.com typename SrcDataType::OperandType>(ib, obj, _opcode) 69311308Santhony.gutierrez@amd.com { 69411308Santhony.gutierrez@amd.com } 69511308Santhony.gutierrez@amd.com }; 69611308Santhony.gutierrez@amd.com 69711308Santhony.gutierrez@amd.com template<typename DestDataType, typename SrcDataType> 69811308Santhony.gutierrez@amd.com class CvtInst : public CommonInstBase<typename DestDataType::OperandType, 69911308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 1> 70011308Santhony.gutierrez@amd.com { 70111308Santhony.gutierrez@amd.com public: 70211308Santhony.gutierrez@amd.com std::string opcode_suffix() 70311308Santhony.gutierrez@amd.com { 70411308Santhony.gutierrez@amd.com return csprintf("_%s_%s", DestDataType::label, SrcDataType::label); 70511308Santhony.gutierrez@amd.com } 70611308Santhony.gutierrez@amd.com 70711308Santhony.gutierrez@amd.com CvtInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 70811308Santhony.gutierrez@amd.com const char *_opcode) 70911308Santhony.gutierrez@amd.com : CommonInstBase<typename DestDataType::OperandType, 71011308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 71111308Santhony.gutierrez@amd.com 1>(ib, obj, _opcode) 71211308Santhony.gutierrez@amd.com { 71311308Santhony.gutierrez@amd.com } 71411308Santhony.gutierrez@amd.com }; 71511308Santhony.gutierrez@amd.com 71611308Santhony.gutierrez@amd.com class SpecialInstNoSrcNoDest : public HsailGPUStaticInst 71711308Santhony.gutierrez@amd.com { 71811308Santhony.gutierrez@amd.com public: 71911308Santhony.gutierrez@amd.com SpecialInstNoSrcNoDest(const Brig::BrigInstBase *ib, 72011308Santhony.gutierrez@amd.com const BrigObject *obj, const char *_opcode) 72111308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 72211308Santhony.gutierrez@amd.com { 72311308Santhony.gutierrez@amd.com } 72411308Santhony.gutierrez@amd.com 72511308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { return false; } 72611308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { return false; } 72711308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { return false; } 72811308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { return false; } 72911308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { return false; } 73011308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { return 0; } 73111308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { return -1; } 73211308Santhony.gutierrez@amd.com 73311308Santhony.gutierrez@amd.com int numSrcRegOperands() { return 0; } 73411308Santhony.gutierrez@amd.com int numDstRegOperands() { return 0; } 73511308Santhony.gutierrez@amd.com int getNumOperands() { return 0; } 73611308Santhony.gutierrez@amd.com }; 73711308Santhony.gutierrez@amd.com 73811308Santhony.gutierrez@amd.com template<typename DestOperandType> 73911308Santhony.gutierrez@amd.com class SpecialInstNoSrcBase : public HsailGPUStaticInst 74011308Santhony.gutierrez@amd.com { 74111308Santhony.gutierrez@amd.com protected: 74211308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 74311308Santhony.gutierrez@amd.com 74411308Santhony.gutierrez@amd.com void generateDisassembly() 74511308Santhony.gutierrez@amd.com { 74611308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s", opcode, dest.disassemble()); 74711308Santhony.gutierrez@amd.com } 74811308Santhony.gutierrez@amd.com 74911308Santhony.gutierrez@amd.com public: 75011308Santhony.gutierrez@amd.com SpecialInstNoSrcBase(const Brig::BrigInstBase *ib, 75111308Santhony.gutierrez@amd.com const BrigObject *obj, const char *_opcode) 75211308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 75311308Santhony.gutierrez@amd.com { 75411308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 75511308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 75611308Santhony.gutierrez@amd.com } 75711308Santhony.gutierrez@amd.com 75811308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { 75911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 76011308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 76111308Santhony.gutierrez@amd.com } 76211308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { 76311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 76411308Santhony.gutierrez@amd.com return dest.isCondRegister(); 76511308Santhony.gutierrez@amd.com } 76611308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { 76711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 76811308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 76911308Santhony.gutierrez@amd.com } 77011308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { return false; } 77111308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { return true; } 77211308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { 77311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 77411308Santhony.gutierrez@amd.com return dest.opSize(); 77511308Santhony.gutierrez@amd.com } 77611308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { 77711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 77811308Santhony.gutierrez@amd.com return dest.regIndex(); 77911308Santhony.gutierrez@amd.com } 78011308Santhony.gutierrez@amd.com int numSrcRegOperands() { return 0; } 78111308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 78211308Santhony.gutierrez@amd.com int getNumOperands() { return 1; } 78311308Santhony.gutierrez@amd.com }; 78411308Santhony.gutierrez@amd.com 78511308Santhony.gutierrez@amd.com template<typename DestDataType> 78611308Santhony.gutierrez@amd.com class SpecialInstNoSrc : 78711308Santhony.gutierrez@amd.com public SpecialInstNoSrcBase<typename DestDataType::OperandType> 78811308Santhony.gutierrez@amd.com { 78911308Santhony.gutierrez@amd.com public: 79011308Santhony.gutierrez@amd.com typedef typename DestDataType::CType DestCType; 79111308Santhony.gutierrez@amd.com 79211308Santhony.gutierrez@amd.com SpecialInstNoSrc(const Brig::BrigInstBase *ib, const BrigObject *obj, 79311308Santhony.gutierrez@amd.com const char *_opcode) 79411308Santhony.gutierrez@amd.com : SpecialInstNoSrcBase<typename DestDataType::OperandType>(ib, obj, 79511308Santhony.gutierrez@amd.com _opcode) 79611308Santhony.gutierrez@amd.com { 79711308Santhony.gutierrez@amd.com } 79811308Santhony.gutierrez@amd.com }; 79911308Santhony.gutierrez@amd.com 80011308Santhony.gutierrez@amd.com template<typename DestOperandType> 80111308Santhony.gutierrez@amd.com class SpecialInst1SrcBase : public HsailGPUStaticInst 80211308Santhony.gutierrez@amd.com { 80311308Santhony.gutierrez@amd.com protected: 80411308Santhony.gutierrez@amd.com typedef int SrcCType; // used in execute() template 80511308Santhony.gutierrez@amd.com 80611308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 80711308Santhony.gutierrez@amd.com ImmOperand<SrcCType> src0; 80811308Santhony.gutierrez@amd.com 80911308Santhony.gutierrez@amd.com void 81011308Santhony.gutierrez@amd.com generateDisassembly() 81111308Santhony.gutierrez@amd.com { 81211308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s,%s", opcode, dest.disassemble(), 81311308Santhony.gutierrez@amd.com src0.disassemble()); 81411308Santhony.gutierrez@amd.com } 81511308Santhony.gutierrez@amd.com 81611308Santhony.gutierrez@amd.com public: 81711308Santhony.gutierrez@amd.com SpecialInst1SrcBase(const Brig::BrigInstBase *ib, 81811308Santhony.gutierrez@amd.com const BrigObject *obj, const char *_opcode) 81911308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 82011308Santhony.gutierrez@amd.com { 82111308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 82211308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 82311308Santhony.gutierrez@amd.com 82411308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 82511308Santhony.gutierrez@amd.com src0.init(op_offs, obj); 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 } 84511308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { 84611308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 84711308Santhony.gutierrez@amd.com return dest.regIndex(); 84811308Santhony.gutierrez@amd.com } 84911308Santhony.gutierrez@amd.com int numSrcRegOperands() { return 0; } 85011308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 85111308Santhony.gutierrez@amd.com int getNumOperands() { return 1; } 85211308Santhony.gutierrez@amd.com }; 85311308Santhony.gutierrez@amd.com 85411308Santhony.gutierrez@amd.com template<typename DestDataType> 85511308Santhony.gutierrez@amd.com class SpecialInst1Src : 85611308Santhony.gutierrez@amd.com public SpecialInst1SrcBase<typename DestDataType::OperandType> 85711308Santhony.gutierrez@amd.com { 85811308Santhony.gutierrez@amd.com public: 85911308Santhony.gutierrez@amd.com typedef typename DestDataType::CType DestCType; 86011308Santhony.gutierrez@amd.com 86111308Santhony.gutierrez@amd.com SpecialInst1Src(const Brig::BrigInstBase *ib, const BrigObject *obj, 86211308Santhony.gutierrez@amd.com const char *_opcode) 86311308Santhony.gutierrez@amd.com : SpecialInst1SrcBase<typename DestDataType::OperandType>(ib, obj, 86411308Santhony.gutierrez@amd.com _opcode) 86511308Santhony.gutierrez@amd.com { 86611308Santhony.gutierrez@amd.com } 86711308Santhony.gutierrez@amd.com }; 86811308Santhony.gutierrez@amd.com 86911308Santhony.gutierrez@amd.com class Ret : public SpecialInstNoSrcNoDest 87011308Santhony.gutierrez@amd.com { 87111308Santhony.gutierrez@amd.com public: 87211308Santhony.gutierrez@amd.com typedef SpecialInstNoSrcNoDest Base; 87311308Santhony.gutierrez@amd.com 87411308Santhony.gutierrez@amd.com Ret(const Brig::BrigInstBase *ib, const BrigObject *obj) 87511308Santhony.gutierrez@amd.com : Base(ib, obj, "ret") 87611308Santhony.gutierrez@amd.com { 87711308Santhony.gutierrez@amd.com o_type = Enums::OT_RET; 87811308Santhony.gutierrez@amd.com } 87911308Santhony.gutierrez@amd.com 88011308Santhony.gutierrez@amd.com void execute(GPUDynInstPtr gpuDynInst); 88111308Santhony.gutierrez@amd.com }; 88211308Santhony.gutierrez@amd.com 88311308Santhony.gutierrez@amd.com class Barrier : public SpecialInstNoSrcNoDest 88411308Santhony.gutierrez@amd.com { 88511308Santhony.gutierrez@amd.com public: 88611308Santhony.gutierrez@amd.com typedef SpecialInstNoSrcNoDest Base; 88711308Santhony.gutierrez@amd.com uint8_t width; 88811308Santhony.gutierrez@amd.com 88911308Santhony.gutierrez@amd.com Barrier(const Brig::BrigInstBase *ib, const BrigObject *obj) 89011308Santhony.gutierrez@amd.com : Base(ib, obj, "barrier") 89111308Santhony.gutierrez@amd.com { 89211308Santhony.gutierrez@amd.com o_type = Enums::OT_BARRIER; 89311308Santhony.gutierrez@amd.com assert(ib->base.kind == Brig::BRIG_KIND_INST_BR); 89411308Santhony.gutierrez@amd.com width = (uint8_t)((Brig::BrigInstBr*)ib)->width; 89511308Santhony.gutierrez@amd.com } 89611308Santhony.gutierrez@amd.com 89711308Santhony.gutierrez@amd.com void execute(GPUDynInstPtr gpuDynInst); 89811308Santhony.gutierrez@amd.com }; 89911308Santhony.gutierrez@amd.com 90011308Santhony.gutierrez@amd.com class MemFence : public SpecialInstNoSrcNoDest 90111308Santhony.gutierrez@amd.com { 90211308Santhony.gutierrez@amd.com public: 90311308Santhony.gutierrez@amd.com typedef SpecialInstNoSrcNoDest Base; 90411308Santhony.gutierrez@amd.com 90511308Santhony.gutierrez@amd.com Brig::BrigMemoryOrder memFenceMemOrder; 90611308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memFenceScopeSegGroup; 90711308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memFenceScopeSegGlobal; 90811308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memFenceScopeSegImage; 90911308Santhony.gutierrez@amd.com 91011308Santhony.gutierrez@amd.com MemFence(const Brig::BrigInstBase *ib, const BrigObject *obj) 91111308Santhony.gutierrez@amd.com : Base(ib, obj, "memfence") 91211308Santhony.gutierrez@amd.com { 91311308Santhony.gutierrez@amd.com assert(ib->base.kind == Brig::BRIG_KIND_INST_MEM_FENCE); 91411308Santhony.gutierrez@amd.com 91511308Santhony.gutierrez@amd.com memFenceScopeSegGlobal = (Brig::BrigMemoryScope) 91611308Santhony.gutierrez@amd.com ((Brig::BrigInstMemFence*)ib)->globalSegmentMemoryScope; 91711308Santhony.gutierrez@amd.com 91811308Santhony.gutierrez@amd.com memFenceScopeSegGroup = (Brig::BrigMemoryScope) 91911308Santhony.gutierrez@amd.com ((Brig::BrigInstMemFence*)ib)->groupSegmentMemoryScope; 92011308Santhony.gutierrez@amd.com 92111308Santhony.gutierrez@amd.com memFenceScopeSegImage = (Brig::BrigMemoryScope) 92211308Santhony.gutierrez@amd.com ((Brig::BrigInstMemFence*)ib)->imageSegmentMemoryScope; 92311308Santhony.gutierrez@amd.com 92411308Santhony.gutierrez@amd.com memFenceMemOrder = (Brig::BrigMemoryOrder) 92511308Santhony.gutierrez@amd.com ((Brig::BrigInstMemFence*)ib)->memoryOrder; 92611308Santhony.gutierrez@amd.com 92711308Santhony.gutierrez@amd.com // set o_type based on scopes 92811308Santhony.gutierrez@amd.com if (memFenceScopeSegGlobal != Brig::BRIG_MEMORY_SCOPE_NONE && 92911308Santhony.gutierrez@amd.com memFenceScopeSegGroup != Brig::BRIG_MEMORY_SCOPE_NONE) { 93011308Santhony.gutierrez@amd.com o_type = Enums::OT_BOTH_MEMFENCE; 93111308Santhony.gutierrez@amd.com } else if (memFenceScopeSegGlobal != Brig::BRIG_MEMORY_SCOPE_NONE) { 93211308Santhony.gutierrez@amd.com o_type = Enums::OT_GLOBAL_MEMFENCE; 93311308Santhony.gutierrez@amd.com } else if (memFenceScopeSegGroup != Brig::BRIG_MEMORY_SCOPE_NONE) { 93411308Santhony.gutierrez@amd.com o_type = Enums::OT_SHARED_MEMFENCE; 93511308Santhony.gutierrez@amd.com } else { 93611308Santhony.gutierrez@amd.com fatal("MemFence constructor: bad scope specifiers\n"); 93711308Santhony.gutierrez@amd.com } 93811308Santhony.gutierrez@amd.com } 93911308Santhony.gutierrez@amd.com 94011308Santhony.gutierrez@amd.com void 94111308Santhony.gutierrez@amd.com initiateAcc(GPUDynInstPtr gpuDynInst) 94211308Santhony.gutierrez@amd.com { 94311308Santhony.gutierrez@amd.com Wavefront *wave = gpuDynInst->wavefront(); 94411308Santhony.gutierrez@amd.com wave->computeUnit->injectGlobalMemFence(gpuDynInst); 94511308Santhony.gutierrez@amd.com } 94611308Santhony.gutierrez@amd.com 94711308Santhony.gutierrez@amd.com void 94811308Santhony.gutierrez@amd.com execute(GPUDynInstPtr gpuDynInst) 94911308Santhony.gutierrez@amd.com { 95011308Santhony.gutierrez@amd.com Wavefront *w = gpuDynInst->wavefront(); 95111308Santhony.gutierrez@amd.com // 2 cases: 95211308Santhony.gutierrez@amd.com // * memfence to a sequentially consistent memory (e.g., LDS). 95311308Santhony.gutierrez@amd.com // These can be handled as no-ops. 95411308Santhony.gutierrez@amd.com // * memfence to a relaxed consistency cache (e.g., Hermes, Viper, 95511308Santhony.gutierrez@amd.com // etc.). We send a packet, tagged with the memory order and 95611308Santhony.gutierrez@amd.com // scope, and let the GPU coalescer handle it. 95711308Santhony.gutierrez@amd.com 95811308Santhony.gutierrez@amd.com if (o_type == Enums::OT_GLOBAL_MEMFENCE || 95911308Santhony.gutierrez@amd.com o_type == Enums::OT_BOTH_MEMFENCE) { 96011308Santhony.gutierrez@amd.com gpuDynInst->simdId = w->simdId; 96111308Santhony.gutierrez@amd.com gpuDynInst->wfSlotId = w->wfSlotId; 96211308Santhony.gutierrez@amd.com gpuDynInst->wfDynId = w->wfDynId; 96311308Santhony.gutierrez@amd.com gpuDynInst->kern_id = w->kern_id; 96411308Santhony.gutierrez@amd.com gpuDynInst->cu_id = w->computeUnit->cu_id; 96511308Santhony.gutierrez@amd.com 96611308Santhony.gutierrez@amd.com gpuDynInst->memoryOrder = 96711308Santhony.gutierrez@amd.com getGenericMemoryOrder(memFenceMemOrder); 96811308Santhony.gutierrez@amd.com gpuDynInst->scope = 96911308Santhony.gutierrez@amd.com getGenericMemoryScope(memFenceScopeSegGlobal); 97011308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 97111308Santhony.gutierrez@amd.com GlobalMemPipeline* gmp = &(w->computeUnit->globalMemoryPipe); 97211308Santhony.gutierrez@amd.com gmp->getGMReqFIFO().push(gpuDynInst); 97311308Santhony.gutierrez@amd.com 97411308Santhony.gutierrez@amd.com w->wr_gm_reqs_in_pipe--; 97511308Santhony.gutierrez@amd.com w->rd_gm_reqs_in_pipe--; 97611308Santhony.gutierrez@amd.com w->mem_reqs_in_pipe--; 97711308Santhony.gutierrez@amd.com w->outstanding_reqs++; 97811308Santhony.gutierrez@amd.com } else if (o_type == Enums::OT_SHARED_MEMFENCE) { 97911308Santhony.gutierrez@amd.com // no-op 98011308Santhony.gutierrez@amd.com } else { 98111308Santhony.gutierrez@amd.com fatal("MemFence execute: bad o_type\n"); 98211308Santhony.gutierrez@amd.com } 98311308Santhony.gutierrez@amd.com } 98411308Santhony.gutierrez@amd.com }; 98511308Santhony.gutierrez@amd.com 98611308Santhony.gutierrez@amd.com class Call : public HsailGPUStaticInst 98711308Santhony.gutierrez@amd.com { 98811308Santhony.gutierrez@amd.com public: 98911308Santhony.gutierrez@amd.com // private helper functions 99011308Santhony.gutierrez@amd.com void calcAddr(Wavefront* w, GPUDynInstPtr m); 99111308Santhony.gutierrez@amd.com 99211308Santhony.gutierrez@amd.com void 99311308Santhony.gutierrez@amd.com generateDisassembly() 99411308Santhony.gutierrez@amd.com { 99511308Santhony.gutierrez@amd.com if (dest.disassemble() == "") { 99611308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s (%s)", opcode, src0.disassemble(), 99711308Santhony.gutierrez@amd.com src1.disassemble()); 99811308Santhony.gutierrez@amd.com } else { 99911308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s (%s) (%s)", opcode, 100011308Santhony.gutierrez@amd.com src0.disassemble(), dest.disassemble(), 100111308Santhony.gutierrez@amd.com src1.disassemble()); 100211308Santhony.gutierrez@amd.com } 100311308Santhony.gutierrez@amd.com } 100411308Santhony.gutierrez@amd.com 100511308Santhony.gutierrez@amd.com bool 100611308Santhony.gutierrez@amd.com isPseudoOp() 100711308Santhony.gutierrez@amd.com { 100811308Santhony.gutierrez@amd.com std::string func_name = src0.disassemble(); 100911308Santhony.gutierrez@amd.com if (func_name.find("__gem5_hsail_op") != std::string::npos) { 101011308Santhony.gutierrez@amd.com return true; 101111308Santhony.gutierrez@amd.com } 101211308Santhony.gutierrez@amd.com return false; 101311308Santhony.gutierrez@amd.com } 101411308Santhony.gutierrez@amd.com 101511308Santhony.gutierrez@amd.com // member variables 101611308Santhony.gutierrez@amd.com ListOperand dest; 101711308Santhony.gutierrez@amd.com FunctionRefOperand src0; 101811308Santhony.gutierrez@amd.com ListOperand src1; 101911308Santhony.gutierrez@amd.com HsailCode *func_ptr; 102011308Santhony.gutierrez@amd.com 102111308Santhony.gutierrez@amd.com // exec function for pseudo instructions mapped on top of call opcode 102211308Santhony.gutierrez@amd.com void execPseudoInst(Wavefront *w, GPUDynInstPtr gpuDynInst); 102311308Santhony.gutierrez@amd.com 102411308Santhony.gutierrez@amd.com // user-defined pseudo instructions 102511308Santhony.gutierrez@amd.com void MagicPrintLane(Wavefront *w); 102611308Santhony.gutierrez@amd.com void MagicPrintLane64(Wavefront *w); 102711308Santhony.gutierrez@amd.com void MagicPrintWF32(Wavefront *w); 102811308Santhony.gutierrez@amd.com void MagicPrintWF64(Wavefront *w); 102911308Santhony.gutierrez@amd.com void MagicPrintWFFloat(Wavefront *w); 103011308Santhony.gutierrez@amd.com void MagicSimBreak(Wavefront *w); 103111308Santhony.gutierrez@amd.com void MagicPrefixSum(Wavefront *w); 103211308Santhony.gutierrez@amd.com void MagicReduction(Wavefront *w); 103311308Santhony.gutierrez@amd.com void MagicMaskLower(Wavefront *w); 103411308Santhony.gutierrez@amd.com void MagicMaskUpper(Wavefront *w); 103511308Santhony.gutierrez@amd.com void MagicJoinWFBar(Wavefront *w); 103611308Santhony.gutierrez@amd.com void MagicWaitWFBar(Wavefront *w); 103711308Santhony.gutierrez@amd.com void MagicPanic(Wavefront *w); 103811308Santhony.gutierrez@amd.com 103911308Santhony.gutierrez@amd.com void MagicAtomicNRAddGlobalU32Reg(Wavefront *w, 104011308Santhony.gutierrez@amd.com GPUDynInstPtr gpuDynInst); 104111308Santhony.gutierrez@amd.com 104211308Santhony.gutierrez@amd.com void MagicAtomicNRAddGroupU32Reg(Wavefront *w, 104311308Santhony.gutierrez@amd.com GPUDynInstPtr gpuDynInst); 104411308Santhony.gutierrez@amd.com 104511308Santhony.gutierrez@amd.com void MagicLoadGlobalU32Reg(Wavefront *w, GPUDynInstPtr gpuDynInst); 104611308Santhony.gutierrez@amd.com 104711308Santhony.gutierrez@amd.com void MagicXactCasLd(Wavefront *w); 104811308Santhony.gutierrez@amd.com void MagicMostSigThread(Wavefront *w); 104911308Santhony.gutierrez@amd.com void MagicMostSigBroadcast(Wavefront *w); 105011308Santhony.gutierrez@amd.com 105111308Santhony.gutierrez@amd.com void MagicPrintWF32ID(Wavefront *w); 105211308Santhony.gutierrez@amd.com void MagicPrintWFID64(Wavefront *w); 105311308Santhony.gutierrez@amd.com 105411308Santhony.gutierrez@amd.com Call(const Brig::BrigInstBase *ib, const BrigObject *obj) 105511308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, "call") 105611308Santhony.gutierrez@amd.com { 105711308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 105811308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 105911308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 106011308Santhony.gutierrez@amd.com src0.init(op_offs, obj); 106111308Santhony.gutierrez@amd.com 106211308Santhony.gutierrez@amd.com func_ptr = nullptr; 106311308Santhony.gutierrez@amd.com std::string func_name = src0.disassemble(); 106411308Santhony.gutierrez@amd.com if (!isPseudoOp()) { 106511308Santhony.gutierrez@amd.com func_ptr = dynamic_cast<HsailCode*>(obj-> 106611308Santhony.gutierrez@amd.com getFunction(func_name)); 106711308Santhony.gutierrez@amd.com 106811308Santhony.gutierrez@amd.com if (!func_ptr) 106911308Santhony.gutierrez@amd.com fatal("call::exec cannot find function: %s\n", func_name); 107011308Santhony.gutierrez@amd.com } 107111308Santhony.gutierrez@amd.com 107211308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 2); 107311308Santhony.gutierrez@amd.com src1.init(op_offs, obj); 107411308Santhony.gutierrez@amd.com } 107511308Santhony.gutierrez@amd.com 107611308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { return false; } 107711308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { return false; } 107811308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { return false; } 107911308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { return false; } 108011308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { return false; } 108111308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { return 0; } 108211308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { return -1; } 108311308Santhony.gutierrez@amd.com 108411308Santhony.gutierrez@amd.com void 108511308Santhony.gutierrez@amd.com execute(GPUDynInstPtr gpuDynInst) 108611308Santhony.gutierrez@amd.com { 108711308Santhony.gutierrez@amd.com Wavefront *w = gpuDynInst->wavefront(); 108811308Santhony.gutierrez@amd.com 108911308Santhony.gutierrez@amd.com std::string func_name = src0.disassemble(); 109011308Santhony.gutierrez@amd.com if (isPseudoOp()) { 109111308Santhony.gutierrez@amd.com execPseudoInst(w, gpuDynInst); 109211308Santhony.gutierrez@amd.com } else { 109311308Santhony.gutierrez@amd.com fatal("Native HSAIL functions are not yet implemented: %s\n", 109411308Santhony.gutierrez@amd.com func_name); 109511308Santhony.gutierrez@amd.com } 109611308Santhony.gutierrez@amd.com } 109711308Santhony.gutierrez@amd.com int numSrcRegOperands() { return 0; } 109811308Santhony.gutierrez@amd.com int numDstRegOperands() { return 0; } 109911308Santhony.gutierrez@amd.com int getNumOperands() { return 2; } 110011308Santhony.gutierrez@amd.com }; 110111308Santhony.gutierrez@amd.com 110211308Santhony.gutierrez@amd.com template<typename T> T heynot(T arg) { return ~arg; } 110311308Santhony.gutierrez@amd.com template<> inline bool heynot<bool>(bool arg) { return !arg; } 110411308Santhony.gutierrez@amd.com} // namespace HsailISA 110511308Santhony.gutierrez@amd.com 110611308Santhony.gutierrez@amd.com#endif // __ARCH_HSAIL_INSTS_DECL_HH__ 1107