decl.hh revision 11692
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 } 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 { 24311692Santhony.gutierrez@amd.com setFlag(ALU); 24411692Santhony.gutierrez@amd.com 24511308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 24611308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 24711308Santhony.gutierrez@amd.com 24811308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 24911308Santhony.gutierrez@amd.com src0.init(op_offs, obj); 25011308Santhony.gutierrez@amd.com 25111308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 2); 25211308Santhony.gutierrez@amd.com src1.init(op_offs, obj); 25311308Santhony.gutierrez@amd.com 25411308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 3); 25511308Santhony.gutierrez@amd.com src2.init(op_offs, obj); 25611308Santhony.gutierrez@amd.com } 25711308Santhony.gutierrez@amd.com 25811308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { 25911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 26011308Santhony.gutierrez@amd.com if (!operandIndex) 26111308Santhony.gutierrez@amd.com return src0.isVectorRegister(); 26211308Santhony.gutierrez@amd.com else if (operandIndex == 1) 26311308Santhony.gutierrez@amd.com return src1.isVectorRegister(); 26411308Santhony.gutierrez@amd.com else if (operandIndex == 2) 26511308Santhony.gutierrez@amd.com return src2.isVectorRegister(); 26611308Santhony.gutierrez@amd.com else 26711308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 26811308Santhony.gutierrez@amd.com } 26911308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { 27011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 27111308Santhony.gutierrez@amd.com if (!operandIndex) 27211308Santhony.gutierrez@amd.com return src0.isCondRegister(); 27311308Santhony.gutierrez@amd.com else if (operandIndex == 1) 27411308Santhony.gutierrez@amd.com return src1.isCondRegister(); 27511308Santhony.gutierrez@amd.com else if (operandIndex == 2) 27611308Santhony.gutierrez@amd.com return src2.isCondRegister(); 27711308Santhony.gutierrez@amd.com else 27811308Santhony.gutierrez@amd.com return dest.isCondRegister(); 27911308Santhony.gutierrez@amd.com } 28011308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { 28111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 28211308Santhony.gutierrez@amd.com if (!operandIndex) 28311308Santhony.gutierrez@amd.com return src0.isScalarRegister(); 28411308Santhony.gutierrez@amd.com else if (operandIndex == 1) 28511308Santhony.gutierrez@amd.com return src1.isScalarRegister(); 28611308Santhony.gutierrez@amd.com else if (operandIndex == 2) 28711308Santhony.gutierrez@amd.com return src2.isScalarRegister(); 28811308Santhony.gutierrez@amd.com else 28911308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 29011308Santhony.gutierrez@amd.com } 29111308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { 29211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 29311308Santhony.gutierrez@amd.com if (operandIndex < 3) 29411308Santhony.gutierrez@amd.com return true; 29511308Santhony.gutierrez@amd.com else 29611308Santhony.gutierrez@amd.com return false; 29711308Santhony.gutierrez@amd.com } 29811308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { 29911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 30011308Santhony.gutierrez@amd.com if (operandIndex >= 3) 30111308Santhony.gutierrez@amd.com return true; 30211308Santhony.gutierrez@amd.com else 30311308Santhony.gutierrez@amd.com return false; 30411308Santhony.gutierrez@amd.com } 30511308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { 30611308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 30711308Santhony.gutierrez@amd.com if (!operandIndex) 30811308Santhony.gutierrez@amd.com return src0.opSize(); 30911308Santhony.gutierrez@amd.com else if (operandIndex == 1) 31011308Santhony.gutierrez@amd.com return src1.opSize(); 31111308Santhony.gutierrez@amd.com else if (operandIndex == 2) 31211308Santhony.gutierrez@amd.com return src2.opSize(); 31311308Santhony.gutierrez@amd.com else 31411308Santhony.gutierrez@amd.com return dest.opSize(); 31511308Santhony.gutierrez@amd.com } 31611308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { 31711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 31811308Santhony.gutierrez@amd.com if (!operandIndex) 31911308Santhony.gutierrez@amd.com return src0.regIndex(); 32011308Santhony.gutierrez@amd.com else if (operandIndex == 1) 32111308Santhony.gutierrez@amd.com return src1.regIndex(); 32211308Santhony.gutierrez@amd.com else if (operandIndex == 2) 32311308Santhony.gutierrez@amd.com return src2.regIndex(); 32411308Santhony.gutierrez@amd.com else 32511308Santhony.gutierrez@amd.com return dest.regIndex(); 32611308Santhony.gutierrez@amd.com } 32711308Santhony.gutierrez@amd.com 32811308Santhony.gutierrez@amd.com int numSrcRegOperands() { 32911308Santhony.gutierrez@amd.com int operands = 0; 33011325Ssteve.reinhardt@amd.com if (src0.isVectorRegister()) { 33111308Santhony.gutierrez@amd.com operands++; 33211308Santhony.gutierrez@amd.com } 33311325Ssteve.reinhardt@amd.com if (src1.isVectorRegister()) { 33411308Santhony.gutierrez@amd.com operands++; 33511308Santhony.gutierrez@amd.com } 33611325Ssteve.reinhardt@amd.com if (src2.isVectorRegister()) { 33711308Santhony.gutierrez@amd.com operands++; 33811308Santhony.gutierrez@amd.com } 33911308Santhony.gutierrez@amd.com return operands; 34011308Santhony.gutierrez@amd.com } 34111308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 34211308Santhony.gutierrez@amd.com int getNumOperands() { return 4; } 34311308Santhony.gutierrez@amd.com }; 34411308Santhony.gutierrez@amd.com 34511308Santhony.gutierrez@amd.com template<typename DestDataType, typename Src0DataType, 34611308Santhony.gutierrez@amd.com typename Src1DataType, typename Src2DataType> 34711308Santhony.gutierrez@amd.com class ThreeNonUniformSourceInst : 34811308Santhony.gutierrez@amd.com public ThreeNonUniformSourceInstBase<typename DestDataType::OperandType, 34911308Santhony.gutierrez@amd.com typename Src0DataType::OperandType, 35011308Santhony.gutierrez@amd.com typename Src1DataType::OperandType, 35111308Santhony.gutierrez@amd.com typename Src2DataType::OperandType> 35211308Santhony.gutierrez@amd.com { 35311308Santhony.gutierrez@amd.com public: 35411308Santhony.gutierrez@amd.com typedef typename DestDataType::CType DestCType; 35511308Santhony.gutierrez@amd.com typedef typename Src0DataType::CType Src0CType; 35611308Santhony.gutierrez@amd.com typedef typename Src1DataType::CType Src1CType; 35711308Santhony.gutierrez@amd.com typedef typename Src2DataType::CType Src2CType; 35811308Santhony.gutierrez@amd.com 35911308Santhony.gutierrez@amd.com ThreeNonUniformSourceInst(const Brig::BrigInstBase *ib, 36011308Santhony.gutierrez@amd.com const BrigObject *obj, const char *opcode) 36111308Santhony.gutierrez@amd.com : ThreeNonUniformSourceInstBase<typename DestDataType::OperandType, 36211308Santhony.gutierrez@amd.com typename Src0DataType::OperandType, 36311308Santhony.gutierrez@amd.com typename Src1DataType::OperandType, 36411308Santhony.gutierrez@amd.com typename Src2DataType::OperandType>(ib, 36511308Santhony.gutierrez@amd.com obj, opcode) 36611308Santhony.gutierrez@amd.com { 36711308Santhony.gutierrez@amd.com } 36811308Santhony.gutierrez@amd.com }; 36911308Santhony.gutierrez@amd.com 37011308Santhony.gutierrez@amd.com template<typename DataType> 37111308Santhony.gutierrez@amd.com class CmovInst : public ThreeNonUniformSourceInst<DataType, B1, 37211308Santhony.gutierrez@amd.com DataType, DataType> 37311308Santhony.gutierrez@amd.com { 37411308Santhony.gutierrez@amd.com public: 37511308Santhony.gutierrez@amd.com CmovInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 37611308Santhony.gutierrez@amd.com const char *opcode) 37711308Santhony.gutierrez@amd.com : ThreeNonUniformSourceInst<DataType, B1, DataType, 37811308Santhony.gutierrez@amd.com DataType>(ib, obj, opcode) 37911308Santhony.gutierrez@amd.com { 38011308Santhony.gutierrez@amd.com } 38111308Santhony.gutierrez@amd.com }; 38211308Santhony.gutierrez@amd.com 38311308Santhony.gutierrez@amd.com template<typename DataType> 38411308Santhony.gutierrez@amd.com class ExtractInsertInst : public ThreeNonUniformSourceInst<DataType, 38511308Santhony.gutierrez@amd.com DataType, U32, 38611308Santhony.gutierrez@amd.com U32> 38711308Santhony.gutierrez@amd.com { 38811308Santhony.gutierrez@amd.com public: 38911308Santhony.gutierrez@amd.com ExtractInsertInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 39011308Santhony.gutierrez@amd.com const char *opcode) 39111308Santhony.gutierrez@amd.com : ThreeNonUniformSourceInst<DataType, DataType, U32, 39211308Santhony.gutierrez@amd.com U32>(ib, obj, opcode) 39311308Santhony.gutierrez@amd.com { 39411308Santhony.gutierrez@amd.com } 39511308Santhony.gutierrez@amd.com }; 39611308Santhony.gutierrez@amd.com 39711308Santhony.gutierrez@amd.com template<typename DestOperandType, typename Src0OperandType, 39811308Santhony.gutierrez@amd.com typename Src1OperandType> 39911308Santhony.gutierrez@amd.com class TwoNonUniformSourceInstBase : public HsailGPUStaticInst 40011308Santhony.gutierrez@amd.com { 40111308Santhony.gutierrez@amd.com protected: 40211308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 40311308Santhony.gutierrez@amd.com typename Src0OperandType::SrcOperand src0; 40411308Santhony.gutierrez@amd.com typename Src1OperandType::SrcOperand src1; 40511308Santhony.gutierrez@amd.com 40611308Santhony.gutierrez@amd.com void 40711308Santhony.gutierrez@amd.com generateDisassembly() 40811308Santhony.gutierrez@amd.com { 40911308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s,%s,%s", opcode, dest.disassemble(), 41011308Santhony.gutierrez@amd.com src0.disassemble(), src1.disassemble()); 41111308Santhony.gutierrez@amd.com } 41211308Santhony.gutierrez@amd.com 41311308Santhony.gutierrez@amd.com 41411308Santhony.gutierrez@amd.com public: 41511308Santhony.gutierrez@amd.com TwoNonUniformSourceInstBase(const Brig::BrigInstBase *ib, 41611308Santhony.gutierrez@amd.com const BrigObject *obj, const char *opcode) 41711308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, opcode) 41811308Santhony.gutierrez@amd.com { 41911692Santhony.gutierrez@amd.com setFlag(ALU); 42011692Santhony.gutierrez@amd.com 42111308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 42211308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 42311308Santhony.gutierrez@amd.com 42411308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 42511308Santhony.gutierrez@amd.com src0.init(op_offs, obj); 42611308Santhony.gutierrez@amd.com 42711308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 2); 42811308Santhony.gutierrez@amd.com src1.init(op_offs, obj); 42911308Santhony.gutierrez@amd.com } 43011308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { 43111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 43211308Santhony.gutierrez@amd.com if (!operandIndex) 43311308Santhony.gutierrez@amd.com return src0.isVectorRegister(); 43411308Santhony.gutierrez@amd.com else if (operandIndex == 1) 43511308Santhony.gutierrez@amd.com return src1.isVectorRegister(); 43611308Santhony.gutierrez@amd.com else 43711308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 43811308Santhony.gutierrez@amd.com } 43911308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { 44011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 44111308Santhony.gutierrez@amd.com if (!operandIndex) 44211308Santhony.gutierrez@amd.com return src0.isCondRegister(); 44311308Santhony.gutierrez@amd.com else if (operandIndex == 1) 44411308Santhony.gutierrez@amd.com return src1.isCondRegister(); 44511308Santhony.gutierrez@amd.com else 44611308Santhony.gutierrez@amd.com return dest.isCondRegister(); 44711308Santhony.gutierrez@amd.com } 44811308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { 44911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 45011308Santhony.gutierrez@amd.com if (!operandIndex) 45111308Santhony.gutierrez@amd.com return src0.isScalarRegister(); 45211308Santhony.gutierrez@amd.com else if (operandIndex == 1) 45311308Santhony.gutierrez@amd.com return src1.isScalarRegister(); 45411308Santhony.gutierrez@amd.com else 45511308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 45611308Santhony.gutierrez@amd.com } 45711308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { 45811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 45911308Santhony.gutierrez@amd.com if (operandIndex < 2) 46011308Santhony.gutierrez@amd.com return true; 46111308Santhony.gutierrez@amd.com else 46211308Santhony.gutierrez@amd.com return false; 46311308Santhony.gutierrez@amd.com } 46411308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { 46511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 46611308Santhony.gutierrez@amd.com if (operandIndex >= 2) 46711308Santhony.gutierrez@amd.com return true; 46811308Santhony.gutierrez@amd.com else 46911308Santhony.gutierrez@amd.com return false; 47011308Santhony.gutierrez@amd.com } 47111308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { 47211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 47311308Santhony.gutierrez@amd.com if (!operandIndex) 47411308Santhony.gutierrez@amd.com return src0.opSize(); 47511308Santhony.gutierrez@amd.com else if (operandIndex == 1) 47611308Santhony.gutierrez@amd.com return src1.opSize(); 47711308Santhony.gutierrez@amd.com else 47811308Santhony.gutierrez@amd.com return dest.opSize(); 47911308Santhony.gutierrez@amd.com } 48011308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { 48111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 48211308Santhony.gutierrez@amd.com if (!operandIndex) 48311308Santhony.gutierrez@amd.com return src0.regIndex(); 48411308Santhony.gutierrez@amd.com else if (operandIndex == 1) 48511308Santhony.gutierrez@amd.com return src1.regIndex(); 48611308Santhony.gutierrez@amd.com else 48711308Santhony.gutierrez@amd.com return dest.regIndex(); 48811308Santhony.gutierrez@amd.com } 48911308Santhony.gutierrez@amd.com 49011308Santhony.gutierrez@amd.com int numSrcRegOperands() { 49111308Santhony.gutierrez@amd.com int operands = 0; 49211325Ssteve.reinhardt@amd.com if (src0.isVectorRegister()) { 49311308Santhony.gutierrez@amd.com operands++; 49411308Santhony.gutierrez@amd.com } 49511325Ssteve.reinhardt@amd.com if (src1.isVectorRegister()) { 49611308Santhony.gutierrez@amd.com operands++; 49711308Santhony.gutierrez@amd.com } 49811308Santhony.gutierrez@amd.com return operands; 49911308Santhony.gutierrez@amd.com } 50011308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 50111308Santhony.gutierrez@amd.com int getNumOperands() { return 3; } 50211308Santhony.gutierrez@amd.com }; 50311308Santhony.gutierrez@amd.com 50411308Santhony.gutierrez@amd.com template<typename DestDataType, typename Src0DataType, 50511308Santhony.gutierrez@amd.com typename Src1DataType> 50611308Santhony.gutierrez@amd.com class TwoNonUniformSourceInst : 50711308Santhony.gutierrez@amd.com public TwoNonUniformSourceInstBase<typename DestDataType::OperandType, 50811308Santhony.gutierrez@amd.com typename Src0DataType::OperandType, 50911308Santhony.gutierrez@amd.com typename Src1DataType::OperandType> 51011308Santhony.gutierrez@amd.com { 51111308Santhony.gutierrez@amd.com public: 51211308Santhony.gutierrez@amd.com typedef typename DestDataType::CType DestCType; 51311308Santhony.gutierrez@amd.com typedef typename Src0DataType::CType Src0CType; 51411308Santhony.gutierrez@amd.com typedef typename Src1DataType::CType Src1CType; 51511308Santhony.gutierrez@amd.com 51611308Santhony.gutierrez@amd.com TwoNonUniformSourceInst(const Brig::BrigInstBase *ib, 51711308Santhony.gutierrez@amd.com const BrigObject *obj, const char *opcode) 51811308Santhony.gutierrez@amd.com : TwoNonUniformSourceInstBase<typename DestDataType::OperandType, 51911308Santhony.gutierrez@amd.com typename Src0DataType::OperandType, 52011308Santhony.gutierrez@amd.com typename Src1DataType::OperandType>(ib, 52111308Santhony.gutierrez@amd.com obj, opcode) 52211308Santhony.gutierrez@amd.com { 52311308Santhony.gutierrez@amd.com } 52411308Santhony.gutierrez@amd.com }; 52511308Santhony.gutierrez@amd.com 52611308Santhony.gutierrez@amd.com // helper function for ClassInst 52711308Santhony.gutierrez@amd.com template<typename T> 52811308Santhony.gutierrez@amd.com bool 52911308Santhony.gutierrez@amd.com fpclassify(T src0, uint32_t src1) 53011308Santhony.gutierrez@amd.com { 53111308Santhony.gutierrez@amd.com int fpclass = std::fpclassify(src0); 53211308Santhony.gutierrez@amd.com 53311308Santhony.gutierrez@amd.com if ((src1 & 0x3) && (fpclass == FP_NAN)) { 53411308Santhony.gutierrez@amd.com return true; 53511308Santhony.gutierrez@amd.com } 53611308Santhony.gutierrez@amd.com 53711308Santhony.gutierrez@amd.com if (src0 <= -0.0) { 53811308Santhony.gutierrez@amd.com if ((src1 & 0x4) && fpclass == FP_INFINITE) 53911308Santhony.gutierrez@amd.com return true; 54011308Santhony.gutierrez@amd.com if ((src1 & 0x8) && fpclass == FP_NORMAL) 54111308Santhony.gutierrez@amd.com return true; 54211308Santhony.gutierrez@amd.com if ((src1 & 0x10) && fpclass == FP_SUBNORMAL) 54311308Santhony.gutierrez@amd.com return true; 54411308Santhony.gutierrez@amd.com if ((src1 & 0x20) && fpclass == FP_ZERO) 54511308Santhony.gutierrez@amd.com return true; 54611308Santhony.gutierrez@amd.com } else { 54711308Santhony.gutierrez@amd.com if ((src1 & 0x40) && fpclass == FP_ZERO) 54811308Santhony.gutierrez@amd.com return true; 54911308Santhony.gutierrez@amd.com if ((src1 & 0x80) && fpclass == FP_SUBNORMAL) 55011308Santhony.gutierrez@amd.com return true; 55111308Santhony.gutierrez@amd.com if ((src1 & 0x100) && fpclass == FP_NORMAL) 55211308Santhony.gutierrez@amd.com return true; 55311308Santhony.gutierrez@amd.com if ((src1 & 0x200) && fpclass == FP_INFINITE) 55411308Santhony.gutierrez@amd.com return true; 55511308Santhony.gutierrez@amd.com } 55611308Santhony.gutierrez@amd.com return false; 55711308Santhony.gutierrez@amd.com } 55811308Santhony.gutierrez@amd.com 55911308Santhony.gutierrez@amd.com template<typename DataType> 56011308Santhony.gutierrez@amd.com class ClassInst : public TwoNonUniformSourceInst<B1, DataType, U32> 56111308Santhony.gutierrez@amd.com { 56211308Santhony.gutierrez@amd.com public: 56311308Santhony.gutierrez@amd.com ClassInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 56411308Santhony.gutierrez@amd.com const char *opcode) 56511308Santhony.gutierrez@amd.com : TwoNonUniformSourceInst<B1, DataType, U32>(ib, obj, opcode) 56611308Santhony.gutierrez@amd.com { 56711308Santhony.gutierrez@amd.com } 56811308Santhony.gutierrez@amd.com }; 56911308Santhony.gutierrez@amd.com 57011308Santhony.gutierrez@amd.com template<typename DataType> 57111308Santhony.gutierrez@amd.com class ShiftInst : public TwoNonUniformSourceInst<DataType, DataType, U32> 57211308Santhony.gutierrez@amd.com { 57311308Santhony.gutierrez@amd.com public: 57411308Santhony.gutierrez@amd.com ShiftInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 57511308Santhony.gutierrez@amd.com const char *opcode) 57611308Santhony.gutierrez@amd.com : TwoNonUniformSourceInst<DataType, DataType, U32>(ib, obj, opcode) 57711308Santhony.gutierrez@amd.com { 57811308Santhony.gutierrez@amd.com } 57911308Santhony.gutierrez@amd.com }; 58011308Santhony.gutierrez@amd.com 58111308Santhony.gutierrez@amd.com // helper function for CmpInst 58211308Santhony.gutierrez@amd.com template<typename T> 58311308Santhony.gutierrez@amd.com bool 58411308Santhony.gutierrez@amd.com compare(T src0, T src1, Brig::BrigCompareOperation cmpOp) 58511308Santhony.gutierrez@amd.com { 58611308Santhony.gutierrez@amd.com using namespace Brig; 58711308Santhony.gutierrez@amd.com 58811308Santhony.gutierrez@amd.com switch (cmpOp) { 58911308Santhony.gutierrez@amd.com case BRIG_COMPARE_EQ: 59011308Santhony.gutierrez@amd.com case BRIG_COMPARE_EQU: 59111308Santhony.gutierrez@amd.com case BRIG_COMPARE_SEQ: 59211308Santhony.gutierrez@amd.com case BRIG_COMPARE_SEQU: 59311308Santhony.gutierrez@amd.com return (src0 == src1); 59411308Santhony.gutierrez@amd.com 59511308Santhony.gutierrez@amd.com case BRIG_COMPARE_NE: 59611308Santhony.gutierrez@amd.com case BRIG_COMPARE_NEU: 59711308Santhony.gutierrez@amd.com case BRIG_COMPARE_SNE: 59811308Santhony.gutierrez@amd.com case BRIG_COMPARE_SNEU: 59911308Santhony.gutierrez@amd.com return (src0 != src1); 60011308Santhony.gutierrez@amd.com 60111308Santhony.gutierrez@amd.com case BRIG_COMPARE_LT: 60211308Santhony.gutierrez@amd.com case BRIG_COMPARE_LTU: 60311308Santhony.gutierrez@amd.com case BRIG_COMPARE_SLT: 60411308Santhony.gutierrez@amd.com case BRIG_COMPARE_SLTU: 60511308Santhony.gutierrez@amd.com return (src0 < src1); 60611308Santhony.gutierrez@amd.com 60711308Santhony.gutierrez@amd.com case BRIG_COMPARE_LE: 60811308Santhony.gutierrez@amd.com case BRIG_COMPARE_LEU: 60911308Santhony.gutierrez@amd.com case BRIG_COMPARE_SLE: 61011308Santhony.gutierrez@amd.com case BRIG_COMPARE_SLEU: 61111308Santhony.gutierrez@amd.com return (src0 <= src1); 61211308Santhony.gutierrez@amd.com 61311308Santhony.gutierrez@amd.com case BRIG_COMPARE_GT: 61411308Santhony.gutierrez@amd.com case BRIG_COMPARE_GTU: 61511308Santhony.gutierrez@amd.com case BRIG_COMPARE_SGT: 61611308Santhony.gutierrez@amd.com case BRIG_COMPARE_SGTU: 61711308Santhony.gutierrez@amd.com return (src0 > src1); 61811308Santhony.gutierrez@amd.com 61911308Santhony.gutierrez@amd.com case BRIG_COMPARE_GE: 62011308Santhony.gutierrez@amd.com case BRIG_COMPARE_GEU: 62111308Santhony.gutierrez@amd.com case BRIG_COMPARE_SGE: 62211308Santhony.gutierrez@amd.com case BRIG_COMPARE_SGEU: 62311308Santhony.gutierrez@amd.com return (src0 >= src1); 62411308Santhony.gutierrez@amd.com 62511308Santhony.gutierrez@amd.com case BRIG_COMPARE_NUM: 62611308Santhony.gutierrez@amd.com case BRIG_COMPARE_SNUM: 62711308Santhony.gutierrez@amd.com return (src0 == src0) || (src1 == src1); 62811308Santhony.gutierrez@amd.com 62911308Santhony.gutierrez@amd.com case BRIG_COMPARE_NAN: 63011308Santhony.gutierrez@amd.com case BRIG_COMPARE_SNAN: 63111308Santhony.gutierrez@amd.com return (src0 != src0) || (src1 != src1); 63211308Santhony.gutierrez@amd.com 63311308Santhony.gutierrez@amd.com default: 63411308Santhony.gutierrez@amd.com fatal("Bad cmpOp value %d\n", (int)cmpOp); 63511308Santhony.gutierrez@amd.com } 63611308Santhony.gutierrez@amd.com } 63711308Santhony.gutierrez@amd.com 63811308Santhony.gutierrez@amd.com template<typename T> 63911308Santhony.gutierrez@amd.com int32_t 64011308Santhony.gutierrez@amd.com firstbit(T src0) 64111308Santhony.gutierrez@amd.com { 64211308Santhony.gutierrez@amd.com if (!src0) 64311308Santhony.gutierrez@amd.com return -1; 64411308Santhony.gutierrez@amd.com 64511308Santhony.gutierrez@amd.com //handle positive and negative numbers 64611308Santhony.gutierrez@amd.com T tmp = (src0 < 0) ? (~src0) : (src0); 64711308Santhony.gutierrez@amd.com 64811308Santhony.gutierrez@amd.com //the starting pos is MSB 64911308Santhony.gutierrez@amd.com int pos = 8 * sizeof(T) - 1; 65011308Santhony.gutierrez@amd.com int cnt = 0; 65111308Santhony.gutierrez@amd.com 65211308Santhony.gutierrez@amd.com //search the first bit set to 1 65311308Santhony.gutierrez@amd.com while (!(tmp & (1 << pos))) { 65411308Santhony.gutierrez@amd.com ++cnt; 65511308Santhony.gutierrez@amd.com --pos; 65611308Santhony.gutierrez@amd.com } 65711308Santhony.gutierrez@amd.com return cnt; 65811308Santhony.gutierrez@amd.com } 65911308Santhony.gutierrez@amd.com 66011308Santhony.gutierrez@amd.com const char* cmpOpToString(Brig::BrigCompareOperation cmpOp); 66111308Santhony.gutierrez@amd.com 66211308Santhony.gutierrez@amd.com template<typename DestOperandType, typename SrcOperandType> 66311308Santhony.gutierrez@amd.com class CmpInstBase : public CommonInstBase<DestOperandType, SrcOperandType, 66411308Santhony.gutierrez@amd.com 2> 66511308Santhony.gutierrez@amd.com { 66611308Santhony.gutierrez@amd.com protected: 66711308Santhony.gutierrez@amd.com Brig::BrigCompareOperation cmpOp; 66811308Santhony.gutierrez@amd.com 66911308Santhony.gutierrez@amd.com public: 67011308Santhony.gutierrez@amd.com CmpInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, 67111308Santhony.gutierrez@amd.com const char *_opcode) 67211308Santhony.gutierrez@amd.com : CommonInstBase<DestOperandType, SrcOperandType, 2>(ib, obj, 67311308Santhony.gutierrez@amd.com _opcode) 67411308Santhony.gutierrez@amd.com { 67511308Santhony.gutierrez@amd.com assert(ib->base.kind == Brig::BRIG_KIND_INST_CMP); 67611308Santhony.gutierrez@amd.com Brig::BrigInstCmp *i = (Brig::BrigInstCmp*)ib; 67711308Santhony.gutierrez@amd.com cmpOp = (Brig::BrigCompareOperation)i->compare; 67811308Santhony.gutierrez@amd.com } 67911308Santhony.gutierrez@amd.com }; 68011308Santhony.gutierrez@amd.com 68111308Santhony.gutierrez@amd.com template<typename DestDataType, typename SrcDataType> 68211308Santhony.gutierrez@amd.com class CmpInst : public CmpInstBase<typename DestDataType::OperandType, 68311308Santhony.gutierrez@amd.com typename SrcDataType::OperandType> 68411308Santhony.gutierrez@amd.com { 68511308Santhony.gutierrez@amd.com public: 68611308Santhony.gutierrez@amd.com std::string 68711308Santhony.gutierrez@amd.com opcode_suffix() 68811308Santhony.gutierrez@amd.com { 68911308Santhony.gutierrez@amd.com return csprintf("_%s_%s_%s", cmpOpToString(this->cmpOp), 69011308Santhony.gutierrez@amd.com DestDataType::label, SrcDataType::label); 69111308Santhony.gutierrez@amd.com } 69211308Santhony.gutierrez@amd.com 69311308Santhony.gutierrez@amd.com CmpInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 69411308Santhony.gutierrez@amd.com const char *_opcode) 69511308Santhony.gutierrez@amd.com : CmpInstBase<typename DestDataType::OperandType, 69611308Santhony.gutierrez@amd.com typename SrcDataType::OperandType>(ib, obj, _opcode) 69711308Santhony.gutierrez@amd.com { 69811308Santhony.gutierrez@amd.com } 69911308Santhony.gutierrez@amd.com }; 70011308Santhony.gutierrez@amd.com 70111308Santhony.gutierrez@amd.com template<typename DestDataType, typename SrcDataType> 70211308Santhony.gutierrez@amd.com class CvtInst : public CommonInstBase<typename DestDataType::OperandType, 70311308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 1> 70411308Santhony.gutierrez@amd.com { 70511308Santhony.gutierrez@amd.com public: 70611308Santhony.gutierrez@amd.com std::string opcode_suffix() 70711308Santhony.gutierrez@amd.com { 70811308Santhony.gutierrez@amd.com return csprintf("_%s_%s", DestDataType::label, SrcDataType::label); 70911308Santhony.gutierrez@amd.com } 71011308Santhony.gutierrez@amd.com 71111308Santhony.gutierrez@amd.com CvtInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 71211308Santhony.gutierrez@amd.com const char *_opcode) 71311308Santhony.gutierrez@amd.com : CommonInstBase<typename DestDataType::OperandType, 71411308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 71511308Santhony.gutierrez@amd.com 1>(ib, obj, _opcode) 71611308Santhony.gutierrez@amd.com { 71711308Santhony.gutierrez@amd.com } 71811308Santhony.gutierrez@amd.com }; 71911308Santhony.gutierrez@amd.com 72011308Santhony.gutierrez@amd.com class SpecialInstNoSrcNoDest : public HsailGPUStaticInst 72111308Santhony.gutierrez@amd.com { 72211308Santhony.gutierrez@amd.com public: 72311308Santhony.gutierrez@amd.com SpecialInstNoSrcNoDest(const Brig::BrigInstBase *ib, 72411308Santhony.gutierrez@amd.com const BrigObject *obj, const char *_opcode) 72511308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 72611308Santhony.gutierrez@amd.com { 72711308Santhony.gutierrez@amd.com } 72811308Santhony.gutierrez@amd.com 72911308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { return false; } 73011308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { return false; } 73111308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { return false; } 73211308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { return false; } 73311308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { return false; } 73411308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { return 0; } 73511308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { return -1; } 73611308Santhony.gutierrez@amd.com 73711308Santhony.gutierrez@amd.com int numSrcRegOperands() { return 0; } 73811308Santhony.gutierrez@amd.com int numDstRegOperands() { return 0; } 73911308Santhony.gutierrez@amd.com int getNumOperands() { return 0; } 74011308Santhony.gutierrez@amd.com }; 74111308Santhony.gutierrez@amd.com 74211308Santhony.gutierrez@amd.com template<typename DestOperandType> 74311308Santhony.gutierrez@amd.com class SpecialInstNoSrcBase : public HsailGPUStaticInst 74411308Santhony.gutierrez@amd.com { 74511308Santhony.gutierrez@amd.com protected: 74611308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 74711308Santhony.gutierrez@amd.com 74811308Santhony.gutierrez@amd.com void generateDisassembly() 74911308Santhony.gutierrez@amd.com { 75011308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s", opcode, dest.disassemble()); 75111308Santhony.gutierrez@amd.com } 75211308Santhony.gutierrez@amd.com 75311308Santhony.gutierrez@amd.com public: 75411308Santhony.gutierrez@amd.com SpecialInstNoSrcBase(const Brig::BrigInstBase *ib, 75511308Santhony.gutierrez@amd.com const BrigObject *obj, const char *_opcode) 75611308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 75711308Santhony.gutierrez@amd.com { 75811308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 75911308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 76011308Santhony.gutierrez@amd.com } 76111308Santhony.gutierrez@amd.com 76211308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { 76311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 76411308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 76511308Santhony.gutierrez@amd.com } 76611308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { 76711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 76811308Santhony.gutierrez@amd.com return dest.isCondRegister(); 76911308Santhony.gutierrez@amd.com } 77011308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { 77111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 77211308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 77311308Santhony.gutierrez@amd.com } 77411308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { return false; } 77511308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { return true; } 77611308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { 77711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 77811308Santhony.gutierrez@amd.com return dest.opSize(); 77911308Santhony.gutierrez@amd.com } 78011308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { 78111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 78211308Santhony.gutierrez@amd.com return dest.regIndex(); 78311308Santhony.gutierrez@amd.com } 78411308Santhony.gutierrez@amd.com int numSrcRegOperands() { return 0; } 78511308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 78611308Santhony.gutierrez@amd.com int getNumOperands() { return 1; } 78711308Santhony.gutierrez@amd.com }; 78811308Santhony.gutierrez@amd.com 78911308Santhony.gutierrez@amd.com template<typename DestDataType> 79011308Santhony.gutierrez@amd.com class SpecialInstNoSrc : 79111308Santhony.gutierrez@amd.com public SpecialInstNoSrcBase<typename DestDataType::OperandType> 79211308Santhony.gutierrez@amd.com { 79311308Santhony.gutierrez@amd.com public: 79411308Santhony.gutierrez@amd.com typedef typename DestDataType::CType DestCType; 79511308Santhony.gutierrez@amd.com 79611308Santhony.gutierrez@amd.com SpecialInstNoSrc(const Brig::BrigInstBase *ib, const BrigObject *obj, 79711308Santhony.gutierrez@amd.com const char *_opcode) 79811308Santhony.gutierrez@amd.com : SpecialInstNoSrcBase<typename DestDataType::OperandType>(ib, obj, 79911308Santhony.gutierrez@amd.com _opcode) 80011308Santhony.gutierrez@amd.com { 80111308Santhony.gutierrez@amd.com } 80211308Santhony.gutierrez@amd.com }; 80311308Santhony.gutierrez@amd.com 80411308Santhony.gutierrez@amd.com template<typename DestOperandType> 80511308Santhony.gutierrez@amd.com class SpecialInst1SrcBase : public HsailGPUStaticInst 80611308Santhony.gutierrez@amd.com { 80711308Santhony.gutierrez@amd.com protected: 80811308Santhony.gutierrez@amd.com typedef int SrcCType; // used in execute() template 80911308Santhony.gutierrez@amd.com 81011308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 81111308Santhony.gutierrez@amd.com ImmOperand<SrcCType> src0; 81211308Santhony.gutierrez@amd.com 81311308Santhony.gutierrez@amd.com void 81411308Santhony.gutierrez@amd.com generateDisassembly() 81511308Santhony.gutierrez@amd.com { 81611308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s,%s", opcode, dest.disassemble(), 81711308Santhony.gutierrez@amd.com src0.disassemble()); 81811308Santhony.gutierrez@amd.com } 81911308Santhony.gutierrez@amd.com 82011308Santhony.gutierrez@amd.com public: 82111308Santhony.gutierrez@amd.com SpecialInst1SrcBase(const Brig::BrigInstBase *ib, 82211308Santhony.gutierrez@amd.com const BrigObject *obj, const char *_opcode) 82311308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 82411308Santhony.gutierrez@amd.com { 82511692Santhony.gutierrez@amd.com setFlag(ALU); 82611692Santhony.gutierrez@amd.com 82711308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 82811308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 82911308Santhony.gutierrez@amd.com 83011308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 83111308Santhony.gutierrez@amd.com src0.init(op_offs, obj); 83211308Santhony.gutierrez@amd.com } 83311308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { 83411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 83511308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 83611308Santhony.gutierrez@amd.com } 83711308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { 83811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 83911308Santhony.gutierrez@amd.com return dest.isCondRegister(); 84011308Santhony.gutierrez@amd.com } 84111308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { 84211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 84311308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 84411308Santhony.gutierrez@amd.com } 84511308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { return false; } 84611308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { return true; } 84711308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { 84811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 84911308Santhony.gutierrez@amd.com return dest.opSize(); 85011308Santhony.gutierrez@amd.com } 85111308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { 85211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 85311308Santhony.gutierrez@amd.com return dest.regIndex(); 85411308Santhony.gutierrez@amd.com } 85511308Santhony.gutierrez@amd.com int numSrcRegOperands() { return 0; } 85611308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 85711308Santhony.gutierrez@amd.com int getNumOperands() { return 1; } 85811308Santhony.gutierrez@amd.com }; 85911308Santhony.gutierrez@amd.com 86011308Santhony.gutierrez@amd.com template<typename DestDataType> 86111308Santhony.gutierrez@amd.com class SpecialInst1Src : 86211308Santhony.gutierrez@amd.com public SpecialInst1SrcBase<typename DestDataType::OperandType> 86311308Santhony.gutierrez@amd.com { 86411308Santhony.gutierrez@amd.com public: 86511308Santhony.gutierrez@amd.com typedef typename DestDataType::CType DestCType; 86611308Santhony.gutierrez@amd.com 86711308Santhony.gutierrez@amd.com SpecialInst1Src(const Brig::BrigInstBase *ib, const BrigObject *obj, 86811308Santhony.gutierrez@amd.com const char *_opcode) 86911308Santhony.gutierrez@amd.com : SpecialInst1SrcBase<typename DestDataType::OperandType>(ib, obj, 87011308Santhony.gutierrez@amd.com _opcode) 87111308Santhony.gutierrez@amd.com { 87211308Santhony.gutierrez@amd.com } 87311308Santhony.gutierrez@amd.com }; 87411308Santhony.gutierrez@amd.com 87511308Santhony.gutierrez@amd.com class Ret : public SpecialInstNoSrcNoDest 87611308Santhony.gutierrez@amd.com { 87711308Santhony.gutierrez@amd.com public: 87811308Santhony.gutierrez@amd.com typedef SpecialInstNoSrcNoDest Base; 87911308Santhony.gutierrez@amd.com 88011308Santhony.gutierrez@amd.com Ret(const Brig::BrigInstBase *ib, const BrigObject *obj) 88111308Santhony.gutierrez@amd.com : Base(ib, obj, "ret") 88211308Santhony.gutierrez@amd.com { 88311692Santhony.gutierrez@amd.com setFlag(GPUStaticInst::Return); 88411308Santhony.gutierrez@amd.com } 88511308Santhony.gutierrez@amd.com 88611308Santhony.gutierrez@amd.com void execute(GPUDynInstPtr gpuDynInst); 88711308Santhony.gutierrez@amd.com }; 88811308Santhony.gutierrez@amd.com 88911308Santhony.gutierrez@amd.com class Barrier : public SpecialInstNoSrcNoDest 89011308Santhony.gutierrez@amd.com { 89111308Santhony.gutierrez@amd.com public: 89211308Santhony.gutierrez@amd.com typedef SpecialInstNoSrcNoDest Base; 89311308Santhony.gutierrez@amd.com uint8_t width; 89411308Santhony.gutierrez@amd.com 89511308Santhony.gutierrez@amd.com Barrier(const Brig::BrigInstBase *ib, const BrigObject *obj) 89611308Santhony.gutierrez@amd.com : Base(ib, obj, "barrier") 89711308Santhony.gutierrez@amd.com { 89811692Santhony.gutierrez@amd.com setFlag(GPUStaticInst::MemBarrier); 89911308Santhony.gutierrez@amd.com assert(ib->base.kind == Brig::BRIG_KIND_INST_BR); 90011308Santhony.gutierrez@amd.com width = (uint8_t)((Brig::BrigInstBr*)ib)->width; 90111308Santhony.gutierrez@amd.com } 90211308Santhony.gutierrez@amd.com 90311308Santhony.gutierrez@amd.com void execute(GPUDynInstPtr gpuDynInst); 90411308Santhony.gutierrez@amd.com }; 90511308Santhony.gutierrez@amd.com 90611308Santhony.gutierrez@amd.com class MemFence : public SpecialInstNoSrcNoDest 90711308Santhony.gutierrez@amd.com { 90811308Santhony.gutierrez@amd.com public: 90911308Santhony.gutierrez@amd.com typedef SpecialInstNoSrcNoDest Base; 91011308Santhony.gutierrez@amd.com 91111308Santhony.gutierrez@amd.com Brig::BrigMemoryOrder memFenceMemOrder; 91211308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memFenceScopeSegGroup; 91311308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memFenceScopeSegGlobal; 91411308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memFenceScopeSegImage; 91511308Santhony.gutierrez@amd.com 91611308Santhony.gutierrez@amd.com MemFence(const Brig::BrigInstBase *ib, const BrigObject *obj) 91711308Santhony.gutierrez@amd.com : Base(ib, obj, "memfence") 91811308Santhony.gutierrez@amd.com { 91911308Santhony.gutierrez@amd.com assert(ib->base.kind == Brig::BRIG_KIND_INST_MEM_FENCE); 92011308Santhony.gutierrez@amd.com 92111308Santhony.gutierrez@amd.com memFenceScopeSegGlobal = (Brig::BrigMemoryScope) 92211308Santhony.gutierrez@amd.com ((Brig::BrigInstMemFence*)ib)->globalSegmentMemoryScope; 92311308Santhony.gutierrez@amd.com 92411308Santhony.gutierrez@amd.com memFenceScopeSegGroup = (Brig::BrigMemoryScope) 92511308Santhony.gutierrez@amd.com ((Brig::BrigInstMemFence*)ib)->groupSegmentMemoryScope; 92611308Santhony.gutierrez@amd.com 92711308Santhony.gutierrez@amd.com memFenceScopeSegImage = (Brig::BrigMemoryScope) 92811308Santhony.gutierrez@amd.com ((Brig::BrigInstMemFence*)ib)->imageSegmentMemoryScope; 92911308Santhony.gutierrez@amd.com 93011308Santhony.gutierrez@amd.com memFenceMemOrder = (Brig::BrigMemoryOrder) 93111308Santhony.gutierrez@amd.com ((Brig::BrigInstMemFence*)ib)->memoryOrder; 93211308Santhony.gutierrez@amd.com 93311692Santhony.gutierrez@amd.com setFlag(MemoryRef); 93411692Santhony.gutierrez@amd.com setFlag(GPUStaticInst::MemFence); 93511692Santhony.gutierrez@amd.com 93611692Santhony.gutierrez@amd.com switch (memFenceMemOrder) { 93711692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_ORDER_NONE: 93811692Santhony.gutierrez@amd.com setFlag(NoOrder); 93911692Santhony.gutierrez@amd.com break; 94011692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_ORDER_RELAXED: 94111692Santhony.gutierrez@amd.com setFlag(RelaxedOrder); 94211692Santhony.gutierrez@amd.com break; 94311692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_ORDER_SC_ACQUIRE: 94411692Santhony.gutierrez@amd.com setFlag(Acquire); 94511692Santhony.gutierrez@amd.com break; 94611692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_ORDER_SC_RELEASE: 94711692Santhony.gutierrez@amd.com setFlag(Release); 94811692Santhony.gutierrez@amd.com break; 94911692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE: 95011692Santhony.gutierrez@amd.com setFlag(AcquireRelease); 95111692Santhony.gutierrez@amd.com break; 95211692Santhony.gutierrez@amd.com default: 95311692Santhony.gutierrez@amd.com fatal("MemInst has bad BrigMemoryOrder\n"); 95411692Santhony.gutierrez@amd.com } 95511692Santhony.gutierrez@amd.com 95611692Santhony.gutierrez@amd.com // set inst flags based on scopes 95711308Santhony.gutierrez@amd.com if (memFenceScopeSegGlobal != Brig::BRIG_MEMORY_SCOPE_NONE && 95811308Santhony.gutierrez@amd.com memFenceScopeSegGroup != Brig::BRIG_MEMORY_SCOPE_NONE) { 95911692Santhony.gutierrez@amd.com setFlag(GPUStaticInst::GlobalSegment); 96011692Santhony.gutierrez@amd.com 96111692Santhony.gutierrez@amd.com /** 96211692Santhony.gutierrez@amd.com * A memory fence that has scope for 96311692Santhony.gutierrez@amd.com * both segments will use the global 96411692Santhony.gutierrez@amd.com * segment, and be executed in the 96511692Santhony.gutierrez@amd.com * global memory pipeline, therefore, 96611692Santhony.gutierrez@amd.com * we set the segment to match the 96711692Santhony.gutierrez@amd.com * global scope only 96811692Santhony.gutierrez@amd.com */ 96911692Santhony.gutierrez@amd.com switch (memFenceScopeSegGlobal) { 97011692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_NONE: 97111692Santhony.gutierrez@amd.com setFlag(NoScope); 97211692Santhony.gutierrez@amd.com break; 97311692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_WORKITEM: 97411692Santhony.gutierrez@amd.com setFlag(WorkitemScope); 97511692Santhony.gutierrez@amd.com break; 97611692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_WORKGROUP: 97711692Santhony.gutierrez@amd.com setFlag(WorkgroupScope); 97811692Santhony.gutierrez@amd.com break; 97911692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_AGENT: 98011692Santhony.gutierrez@amd.com setFlag(DeviceScope); 98111692Santhony.gutierrez@amd.com break; 98211692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_SYSTEM: 98311692Santhony.gutierrez@amd.com setFlag(SystemScope); 98411692Santhony.gutierrez@amd.com break; 98511692Santhony.gutierrez@amd.com default: 98611692Santhony.gutierrez@amd.com fatal("MemFence has bad global scope type\n"); 98711692Santhony.gutierrez@amd.com } 98811308Santhony.gutierrez@amd.com } else if (memFenceScopeSegGlobal != Brig::BRIG_MEMORY_SCOPE_NONE) { 98911692Santhony.gutierrez@amd.com setFlag(GPUStaticInst::GlobalSegment); 99011692Santhony.gutierrez@amd.com 99111692Santhony.gutierrez@amd.com switch (memFenceScopeSegGlobal) { 99211692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_NONE: 99311692Santhony.gutierrez@amd.com setFlag(NoScope); 99411692Santhony.gutierrez@amd.com break; 99511692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_WORKITEM: 99611692Santhony.gutierrez@amd.com setFlag(WorkitemScope); 99711692Santhony.gutierrez@amd.com break; 99811692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_WORKGROUP: 99911692Santhony.gutierrez@amd.com setFlag(WorkgroupScope); 100011692Santhony.gutierrez@amd.com break; 100111692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_AGENT: 100211692Santhony.gutierrez@amd.com setFlag(DeviceScope); 100311692Santhony.gutierrez@amd.com break; 100411692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_SYSTEM: 100511692Santhony.gutierrez@amd.com setFlag(SystemScope); 100611692Santhony.gutierrez@amd.com break; 100711692Santhony.gutierrez@amd.com default: 100811692Santhony.gutierrez@amd.com fatal("MemFence has bad global scope type\n"); 100911692Santhony.gutierrez@amd.com } 101011308Santhony.gutierrez@amd.com } else if (memFenceScopeSegGroup != Brig::BRIG_MEMORY_SCOPE_NONE) { 101111692Santhony.gutierrez@amd.com setFlag(GPUStaticInst::GroupSegment); 101211692Santhony.gutierrez@amd.com 101311692Santhony.gutierrez@amd.com switch (memFenceScopeSegGroup) { 101411692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_NONE: 101511692Santhony.gutierrez@amd.com setFlag(NoScope); 101611692Santhony.gutierrez@amd.com break; 101711692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_WORKITEM: 101811692Santhony.gutierrez@amd.com setFlag(WorkitemScope); 101911692Santhony.gutierrez@amd.com break; 102011692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_WORKGROUP: 102111692Santhony.gutierrez@amd.com setFlag(WorkgroupScope); 102211692Santhony.gutierrez@amd.com break; 102311692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_AGENT: 102411692Santhony.gutierrez@amd.com setFlag(DeviceScope); 102511692Santhony.gutierrez@amd.com break; 102611692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_SYSTEM: 102711692Santhony.gutierrez@amd.com setFlag(SystemScope); 102811692Santhony.gutierrez@amd.com break; 102911692Santhony.gutierrez@amd.com default: 103011692Santhony.gutierrez@amd.com fatal("MemFence has bad group scope type\n"); 103111692Santhony.gutierrez@amd.com } 103211308Santhony.gutierrez@amd.com } else { 103311308Santhony.gutierrez@amd.com fatal("MemFence constructor: bad scope specifiers\n"); 103411308Santhony.gutierrez@amd.com } 103511308Santhony.gutierrez@amd.com } 103611308Santhony.gutierrez@amd.com 103711308Santhony.gutierrez@amd.com void 103811308Santhony.gutierrez@amd.com initiateAcc(GPUDynInstPtr gpuDynInst) 103911308Santhony.gutierrez@amd.com { 104011308Santhony.gutierrez@amd.com Wavefront *wave = gpuDynInst->wavefront(); 104111308Santhony.gutierrez@amd.com wave->computeUnit->injectGlobalMemFence(gpuDynInst); 104211308Santhony.gutierrez@amd.com } 104311308Santhony.gutierrez@amd.com 104411308Santhony.gutierrez@amd.com void 104511308Santhony.gutierrez@amd.com execute(GPUDynInstPtr gpuDynInst) 104611308Santhony.gutierrez@amd.com { 104711308Santhony.gutierrez@amd.com Wavefront *w = gpuDynInst->wavefront(); 104811308Santhony.gutierrez@amd.com // 2 cases: 104911308Santhony.gutierrez@amd.com // * memfence to a sequentially consistent memory (e.g., LDS). 105011308Santhony.gutierrez@amd.com // These can be handled as no-ops. 105111308Santhony.gutierrez@amd.com // * memfence to a relaxed consistency cache (e.g., Hermes, Viper, 105211308Santhony.gutierrez@amd.com // etc.). We send a packet, tagged with the memory order and 105311308Santhony.gutierrez@amd.com // scope, and let the GPU coalescer handle it. 105411308Santhony.gutierrez@amd.com 105511692Santhony.gutierrez@amd.com if (isGlobalSeg()) { 105611308Santhony.gutierrez@amd.com gpuDynInst->simdId = w->simdId; 105711308Santhony.gutierrez@amd.com gpuDynInst->wfSlotId = w->wfSlotId; 105811308Santhony.gutierrez@amd.com gpuDynInst->wfDynId = w->wfDynId; 105911639Salexandru.dutu@amd.com gpuDynInst->kern_id = w->kernId; 106011308Santhony.gutierrez@amd.com gpuDynInst->cu_id = w->computeUnit->cu_id; 106111308Santhony.gutierrez@amd.com 106211308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 106311308Santhony.gutierrez@amd.com GlobalMemPipeline* gmp = &(w->computeUnit->globalMemoryPipe); 106411308Santhony.gutierrez@amd.com gmp->getGMReqFIFO().push(gpuDynInst); 106511308Santhony.gutierrez@amd.com 106611639Salexandru.dutu@amd.com w->wrGmReqsInPipe--; 106711639Salexandru.dutu@amd.com w->rdGmReqsInPipe--; 106811639Salexandru.dutu@amd.com w->memReqsInPipe--; 106911639Salexandru.dutu@amd.com w->outstandingReqs++; 107011692Santhony.gutierrez@amd.com } else if (isGroupSeg()) { 107111308Santhony.gutierrez@amd.com // no-op 107211308Santhony.gutierrez@amd.com } else { 107311692Santhony.gutierrez@amd.com fatal("MemFence execute: bad op type\n"); 107411308Santhony.gutierrez@amd.com } 107511308Santhony.gutierrez@amd.com } 107611308Santhony.gutierrez@amd.com }; 107711308Santhony.gutierrez@amd.com 107811308Santhony.gutierrez@amd.com class Call : public HsailGPUStaticInst 107911308Santhony.gutierrez@amd.com { 108011308Santhony.gutierrez@amd.com public: 108111308Santhony.gutierrez@amd.com // private helper functions 108211308Santhony.gutierrez@amd.com void calcAddr(Wavefront* w, GPUDynInstPtr m); 108311308Santhony.gutierrez@amd.com 108411308Santhony.gutierrez@amd.com void 108511308Santhony.gutierrez@amd.com generateDisassembly() 108611308Santhony.gutierrez@amd.com { 108711308Santhony.gutierrez@amd.com if (dest.disassemble() == "") { 108811308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s (%s)", opcode, src0.disassemble(), 108911308Santhony.gutierrez@amd.com src1.disassemble()); 109011308Santhony.gutierrez@amd.com } else { 109111308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s (%s) (%s)", opcode, 109211308Santhony.gutierrez@amd.com src0.disassemble(), dest.disassemble(), 109311308Santhony.gutierrez@amd.com src1.disassemble()); 109411308Santhony.gutierrez@amd.com } 109511308Santhony.gutierrez@amd.com } 109611308Santhony.gutierrez@amd.com 109711308Santhony.gutierrez@amd.com bool 109811308Santhony.gutierrez@amd.com isPseudoOp() 109911308Santhony.gutierrez@amd.com { 110011308Santhony.gutierrez@amd.com std::string func_name = src0.disassemble(); 110111308Santhony.gutierrez@amd.com if (func_name.find("__gem5_hsail_op") != std::string::npos) { 110211308Santhony.gutierrez@amd.com return true; 110311308Santhony.gutierrez@amd.com } 110411308Santhony.gutierrez@amd.com return false; 110511308Santhony.gutierrez@amd.com } 110611308Santhony.gutierrez@amd.com 110711308Santhony.gutierrez@amd.com // member variables 110811308Santhony.gutierrez@amd.com ListOperand dest; 110911308Santhony.gutierrez@amd.com FunctionRefOperand src0; 111011308Santhony.gutierrez@amd.com ListOperand src1; 111111308Santhony.gutierrez@amd.com HsailCode *func_ptr; 111211308Santhony.gutierrez@amd.com 111311308Santhony.gutierrez@amd.com // exec function for pseudo instructions mapped on top of call opcode 111411308Santhony.gutierrez@amd.com void execPseudoInst(Wavefront *w, GPUDynInstPtr gpuDynInst); 111511308Santhony.gutierrez@amd.com 111611308Santhony.gutierrez@amd.com // user-defined pseudo instructions 111711308Santhony.gutierrez@amd.com void MagicPrintLane(Wavefront *w); 111811308Santhony.gutierrez@amd.com void MagicPrintLane64(Wavefront *w); 111911308Santhony.gutierrez@amd.com void MagicPrintWF32(Wavefront *w); 112011308Santhony.gutierrez@amd.com void MagicPrintWF64(Wavefront *w); 112111308Santhony.gutierrez@amd.com void MagicPrintWFFloat(Wavefront *w); 112211308Santhony.gutierrez@amd.com void MagicSimBreak(Wavefront *w); 112311308Santhony.gutierrez@amd.com void MagicPrefixSum(Wavefront *w); 112411308Santhony.gutierrez@amd.com void MagicReduction(Wavefront *w); 112511308Santhony.gutierrez@amd.com void MagicMaskLower(Wavefront *w); 112611308Santhony.gutierrez@amd.com void MagicMaskUpper(Wavefront *w); 112711308Santhony.gutierrez@amd.com void MagicJoinWFBar(Wavefront *w); 112811308Santhony.gutierrez@amd.com void MagicWaitWFBar(Wavefront *w); 112911308Santhony.gutierrez@amd.com void MagicPanic(Wavefront *w); 113011308Santhony.gutierrez@amd.com 113111308Santhony.gutierrez@amd.com void MagicAtomicNRAddGlobalU32Reg(Wavefront *w, 113211308Santhony.gutierrez@amd.com GPUDynInstPtr gpuDynInst); 113311308Santhony.gutierrez@amd.com 113411308Santhony.gutierrez@amd.com void MagicAtomicNRAddGroupU32Reg(Wavefront *w, 113511308Santhony.gutierrez@amd.com GPUDynInstPtr gpuDynInst); 113611308Santhony.gutierrez@amd.com 113711308Santhony.gutierrez@amd.com void MagicLoadGlobalU32Reg(Wavefront *w, GPUDynInstPtr gpuDynInst); 113811308Santhony.gutierrez@amd.com 113911308Santhony.gutierrez@amd.com void MagicXactCasLd(Wavefront *w); 114011308Santhony.gutierrez@amd.com void MagicMostSigThread(Wavefront *w); 114111308Santhony.gutierrez@amd.com void MagicMostSigBroadcast(Wavefront *w); 114211308Santhony.gutierrez@amd.com 114311308Santhony.gutierrez@amd.com void MagicPrintWF32ID(Wavefront *w); 114411308Santhony.gutierrez@amd.com void MagicPrintWFID64(Wavefront *w); 114511308Santhony.gutierrez@amd.com 114611308Santhony.gutierrez@amd.com Call(const Brig::BrigInstBase *ib, const BrigObject *obj) 114711308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, "call") 114811308Santhony.gutierrez@amd.com { 114911692Santhony.gutierrez@amd.com setFlag(ALU); 115011308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 115111308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 115211308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 115311308Santhony.gutierrez@amd.com src0.init(op_offs, obj); 115411308Santhony.gutierrez@amd.com 115511308Santhony.gutierrez@amd.com func_ptr = nullptr; 115611308Santhony.gutierrez@amd.com std::string func_name = src0.disassemble(); 115711308Santhony.gutierrez@amd.com if (!isPseudoOp()) { 115811308Santhony.gutierrez@amd.com func_ptr = dynamic_cast<HsailCode*>(obj-> 115911308Santhony.gutierrez@amd.com getFunction(func_name)); 116011308Santhony.gutierrez@amd.com 116111308Santhony.gutierrez@amd.com if (!func_ptr) 116211308Santhony.gutierrez@amd.com fatal("call::exec cannot find function: %s\n", func_name); 116311308Santhony.gutierrez@amd.com } 116411308Santhony.gutierrez@amd.com 116511308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 2); 116611308Santhony.gutierrez@amd.com src1.init(op_offs, obj); 116711308Santhony.gutierrez@amd.com } 116811308Santhony.gutierrez@amd.com 116911308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { return false; } 117011308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { return false; } 117111308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { return false; } 117211308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { return false; } 117311308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { return false; } 117411308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { return 0; } 117511308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) { return -1; } 117611308Santhony.gutierrez@amd.com 117711308Santhony.gutierrez@amd.com void 117811308Santhony.gutierrez@amd.com execute(GPUDynInstPtr gpuDynInst) 117911308Santhony.gutierrez@amd.com { 118011308Santhony.gutierrez@amd.com Wavefront *w = gpuDynInst->wavefront(); 118111308Santhony.gutierrez@amd.com 118211308Santhony.gutierrez@amd.com std::string func_name = src0.disassemble(); 118311308Santhony.gutierrez@amd.com if (isPseudoOp()) { 118411308Santhony.gutierrez@amd.com execPseudoInst(w, gpuDynInst); 118511308Santhony.gutierrez@amd.com } else { 118611308Santhony.gutierrez@amd.com fatal("Native HSAIL functions are not yet implemented: %s\n", 118711308Santhony.gutierrez@amd.com func_name); 118811308Santhony.gutierrez@amd.com } 118911308Santhony.gutierrez@amd.com } 119011308Santhony.gutierrez@amd.com int numSrcRegOperands() { return 0; } 119111308Santhony.gutierrez@amd.com int numDstRegOperands() { return 0; } 119211308Santhony.gutierrez@amd.com int getNumOperands() { return 2; } 119311308Santhony.gutierrez@amd.com }; 119411308Santhony.gutierrez@amd.com 119511308Santhony.gutierrez@amd.com template<typename T> T heynot(T arg) { return ~arg; } 119611308Santhony.gutierrez@amd.com template<> inline bool heynot<bool>(bool arg) { return !arg; } 119711308Santhony.gutierrez@amd.com} // namespace HsailISA 119811308Santhony.gutierrez@amd.com 119911308Santhony.gutierrez@amd.com#endif // __ARCH_HSAIL_INSTS_DECL_HH__ 1200