decl.hh revision 11699
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2012-2015 Advanced Micro Devices, Inc. 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only 611308Santhony.gutierrez@amd.com * 711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met: 911308Santhony.gutierrez@amd.com * 1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice, 1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer. 1211308Santhony.gutierrez@amd.com * 1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice, 1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation 1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution. 1611308Santhony.gutierrez@amd.com * 1711308Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its contributors 1811308Santhony.gutierrez@amd.com * may be used to endorse or promote products derived from this software 1911308Santhony.gutierrez@amd.com * without specific prior written permission. 2011308Santhony.gutierrez@amd.com * 2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE. 3211308Santhony.gutierrez@amd.com * 3311308Santhony.gutierrez@amd.com * Author: Steve Reinhardt 3411308Santhony.gutierrez@amd.com */ 3511308Santhony.gutierrez@amd.com 3611308Santhony.gutierrez@amd.com#ifndef __ARCH_HSAIL_INSTS_DECL_HH__ 3711308Santhony.gutierrez@amd.com#define __ARCH_HSAIL_INSTS_DECL_HH__ 3811308Santhony.gutierrez@amd.com 3911308Santhony.gutierrez@amd.com#include <cmath> 4011308Santhony.gutierrez@amd.com 4111308Santhony.gutierrez@amd.com#include "arch/hsail/insts/gpu_static_inst.hh" 4211308Santhony.gutierrez@amd.com#include "arch/hsail/operand.hh" 4311308Santhony.gutierrez@amd.com#include "debug/HSAIL.hh" 4411308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_dyn_inst.hh" 4511308Santhony.gutierrez@amd.com#include "gpu-compute/shader.hh" 4611308Santhony.gutierrez@amd.com 4711308Santhony.gutierrez@amd.comnamespace HsailISA 4811308Santhony.gutierrez@amd.com{ 4911308Santhony.gutierrez@amd.com template<typename _DestOperand, typename _SrcOperand> 5011308Santhony.gutierrez@amd.com class HsailOperandType 5111308Santhony.gutierrez@amd.com { 5211308Santhony.gutierrez@amd.com public: 5311308Santhony.gutierrez@amd.com typedef _DestOperand DestOperand; 5411308Santhony.gutierrez@amd.com typedef _SrcOperand SrcOperand; 5511308Santhony.gutierrez@amd.com }; 5611308Santhony.gutierrez@amd.com 5711308Santhony.gutierrez@amd.com typedef HsailOperandType<CRegOperand, CRegOrImmOperand> CRegOperandType; 5811308Santhony.gutierrez@amd.com typedef HsailOperandType<SRegOperand, SRegOrImmOperand> SRegOperandType; 5911308Santhony.gutierrez@amd.com typedef HsailOperandType<DRegOperand, DRegOrImmOperand> DRegOperandType; 6011308Santhony.gutierrez@amd.com 6111308Santhony.gutierrez@amd.com // The IsBits parameter serves only to disambiguate tbhe B* types from 6211308Santhony.gutierrez@amd.com // the U* types, which otherwise would be identical (and 6311308Santhony.gutierrez@amd.com // indistinguishable). 6411308Santhony.gutierrez@amd.com template<typename _OperandType, typename _CType, Enums::MemType _memType, 6511308Santhony.gutierrez@amd.com vgpr_type _vgprType, int IsBits=0> 6611308Santhony.gutierrez@amd.com class HsailDataType 6711308Santhony.gutierrez@amd.com { 6811308Santhony.gutierrez@amd.com public: 6911308Santhony.gutierrez@amd.com typedef _OperandType OperandType; 7011308Santhony.gutierrez@amd.com typedef _CType CType; 7111308Santhony.gutierrez@amd.com static const Enums::MemType memType = _memType; 7211308Santhony.gutierrez@amd.com static const vgpr_type vgprType = _vgprType; 7311308Santhony.gutierrez@amd.com static const char *label; 7411308Santhony.gutierrez@amd.com }; 7511308Santhony.gutierrez@amd.com 7611308Santhony.gutierrez@amd.com typedef HsailDataType<CRegOperandType, bool, Enums::M_U8, VT_32, 1> B1; 7711308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, uint8_t, Enums::M_U8, VT_32, 1> B8; 7811308Santhony.gutierrez@amd.com 7911308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, uint16_t, 8011308Santhony.gutierrez@amd.com Enums::M_U16, VT_32, 1> B16; 8111308Santhony.gutierrez@amd.com 8211308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, uint32_t, 8311308Santhony.gutierrez@amd.com Enums::M_U32, VT_32, 1> B32; 8411308Santhony.gutierrez@amd.com 8511308Santhony.gutierrez@amd.com typedef HsailDataType<DRegOperandType, uint64_t, 8611308Santhony.gutierrez@amd.com Enums::M_U64, VT_64, 1> B64; 8711308Santhony.gutierrez@amd.com 8811308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, int8_t, Enums::M_S8, VT_32> S8; 8911308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, int16_t, Enums::M_S16, VT_32> S16; 9011308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, int32_t, Enums::M_S32, VT_32> S32; 9111308Santhony.gutierrez@amd.com typedef HsailDataType<DRegOperandType, int64_t, Enums::M_S64, VT_64> S64; 9211308Santhony.gutierrez@amd.com 9311308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, uint8_t, Enums::M_U8, VT_32> U8; 9411308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, uint16_t, Enums::M_U16, VT_32> U16; 9511308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, uint32_t, Enums::M_U32, VT_32> U32; 9611308Santhony.gutierrez@amd.com typedef HsailDataType<DRegOperandType, uint64_t, Enums::M_U64, VT_64> U64; 9711308Santhony.gutierrez@amd.com 9811308Santhony.gutierrez@amd.com typedef HsailDataType<SRegOperandType, float, Enums::M_F32, VT_32> F32; 9911308Santhony.gutierrez@amd.com typedef HsailDataType<DRegOperandType, double, Enums::M_F64, VT_64> F64; 10011308Santhony.gutierrez@amd.com 10111308Santhony.gutierrez@amd.com template<typename DestOperandType, typename SrcOperandType, 10211308Santhony.gutierrez@amd.com int NumSrcOperands> 10311308Santhony.gutierrez@amd.com class CommonInstBase : public HsailGPUStaticInst 10411308Santhony.gutierrez@amd.com { 10511308Santhony.gutierrez@amd.com protected: 10611308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 10711308Santhony.gutierrez@amd.com typename SrcOperandType::SrcOperand src[NumSrcOperands]; 10811308Santhony.gutierrez@amd.com 10911308Santhony.gutierrez@amd.com void 11011308Santhony.gutierrez@amd.com generateDisassembly() 11111308Santhony.gutierrez@amd.com { 11211308Santhony.gutierrez@amd.com disassembly = csprintf("%s%s %s", opcode, opcode_suffix(), 11311308Santhony.gutierrez@amd.com dest.disassemble()); 11411308Santhony.gutierrez@amd.com 11511308Santhony.gutierrez@amd.com for (int i = 0; i < NumSrcOperands; ++i) { 11611308Santhony.gutierrez@amd.com disassembly += ","; 11711308Santhony.gutierrez@amd.com disassembly += src[i].disassemble(); 11811308Santhony.gutierrez@amd.com } 11911308Santhony.gutierrez@amd.com } 12011308Santhony.gutierrez@amd.com 12111308Santhony.gutierrez@amd.com virtual std::string opcode_suffix() = 0; 12211308Santhony.gutierrez@amd.com 12311308Santhony.gutierrez@amd.com public: 12411308Santhony.gutierrez@amd.com CommonInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, 12511308Santhony.gutierrez@amd.com const char *opcode) 12611308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, opcode) 12711308Santhony.gutierrez@amd.com { 12811692Santhony.gutierrez@amd.com setFlag(ALU); 12911692Santhony.gutierrez@amd.com 13011308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 13111308Santhony.gutierrez@amd.com 13211308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 13311308Santhony.gutierrez@amd.com 13411308Santhony.gutierrez@amd.com for (int i = 0; i < NumSrcOperands; ++i) { 13511308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, i + 1); 13611308Santhony.gutierrez@amd.com src[i].init(op_offs, obj); 13711308Santhony.gutierrez@amd.com } 13811308Santhony.gutierrez@amd.com } 13911308Santhony.gutierrez@amd.com 14011308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { 14111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 14211308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 14311308Santhony.gutierrez@amd.com return src[operandIndex].isVectorRegister(); 14411308Santhony.gutierrez@amd.com else 14511308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 14611308Santhony.gutierrez@amd.com } 14711308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { 14811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 14911308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 15011308Santhony.gutierrez@amd.com return src[operandIndex].isCondRegister(); 15111308Santhony.gutierrez@amd.com else 15211308Santhony.gutierrez@amd.com return dest.isCondRegister(); 15311308Santhony.gutierrez@amd.com } 15411308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { 15511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 15611308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 15711308Santhony.gutierrez@amd.com return src[operandIndex].isScalarRegister(); 15811308Santhony.gutierrez@amd.com else 15911308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 16011308Santhony.gutierrez@amd.com } 16111308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { 16211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 16311308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 16411308Santhony.gutierrez@amd.com return true; 16511308Santhony.gutierrez@amd.com return false; 16611308Santhony.gutierrez@amd.com } 16711308Santhony.gutierrez@amd.com 16811308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { 16911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 17011308Santhony.gutierrez@amd.com if (operandIndex >= NumSrcOperands) 17111308Santhony.gutierrez@amd.com return true; 17211308Santhony.gutierrez@amd.com return false; 17311308Santhony.gutierrez@amd.com } 17411308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { 17511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 17611308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 17711308Santhony.gutierrez@amd.com return src[operandIndex].opSize(); 17811308Santhony.gutierrez@amd.com else 17911308Santhony.gutierrez@amd.com return dest.opSize(); 18011308Santhony.gutierrez@amd.com } 18111699Santhony.gutierrez@amd.com int 18211699Santhony.gutierrez@amd.com getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) 18311699Santhony.gutierrez@amd.com { 18411308Santhony.gutierrez@amd.com assert(operandIndex >= 0 && operandIndex < getNumOperands()); 18511308Santhony.gutierrez@amd.com 18611308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 18711308Santhony.gutierrez@amd.com return src[operandIndex].regIndex(); 18811308Santhony.gutierrez@amd.com else 18911308Santhony.gutierrez@amd.com return dest.regIndex(); 19011308Santhony.gutierrez@amd.com } 19111308Santhony.gutierrez@amd.com int numSrcRegOperands() { 19211308Santhony.gutierrez@amd.com int operands = 0; 19311308Santhony.gutierrez@amd.com for (int i = 0; i < NumSrcOperands; i++) { 19411325Ssteve.reinhardt@amd.com if (src[i].isVectorRegister()) { 19511308Santhony.gutierrez@amd.com operands++; 19611308Santhony.gutierrez@amd.com } 19711308Santhony.gutierrez@amd.com } 19811308Santhony.gutierrez@amd.com return operands; 19911308Santhony.gutierrez@amd.com } 20011308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 20111308Santhony.gutierrez@amd.com int getNumOperands() { return NumSrcOperands + 1; } 20211308Santhony.gutierrez@amd.com }; 20311308Santhony.gutierrez@amd.com 20411308Santhony.gutierrez@amd.com template<typename DataType, int NumSrcOperands> 20511308Santhony.gutierrez@amd.com class ArithInst : public CommonInstBase<typename DataType::OperandType, 20611308Santhony.gutierrez@amd.com typename DataType::OperandType, 20711308Santhony.gutierrez@amd.com NumSrcOperands> 20811308Santhony.gutierrez@amd.com { 20911308Santhony.gutierrez@amd.com public: 21011308Santhony.gutierrez@amd.com std::string opcode_suffix() { return csprintf("_%s", DataType::label); } 21111308Santhony.gutierrez@amd.com 21211308Santhony.gutierrez@amd.com ArithInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 21311308Santhony.gutierrez@amd.com const char *opcode) 21411308Santhony.gutierrez@amd.com : CommonInstBase<typename DataType::OperandType, 21511308Santhony.gutierrez@amd.com typename DataType::OperandType, 21611308Santhony.gutierrez@amd.com NumSrcOperands>(ib, obj, opcode) 21711308Santhony.gutierrez@amd.com { 21811308Santhony.gutierrez@amd.com } 21911308Santhony.gutierrez@amd.com }; 22011308Santhony.gutierrez@amd.com 22111308Santhony.gutierrez@amd.com template<typename DestOperandType, typename Src0OperandType, 22211308Santhony.gutierrez@amd.com typename Src1OperandType, typename Src2OperandType> 22311308Santhony.gutierrez@amd.com class ThreeNonUniformSourceInstBase : public HsailGPUStaticInst 22411308Santhony.gutierrez@amd.com { 22511308Santhony.gutierrez@amd.com protected: 22611308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 22711308Santhony.gutierrez@amd.com typename Src0OperandType::SrcOperand src0; 22811308Santhony.gutierrez@amd.com typename Src1OperandType::SrcOperand src1; 22911308Santhony.gutierrez@amd.com typename Src2OperandType::SrcOperand src2; 23011308Santhony.gutierrez@amd.com 23111308Santhony.gutierrez@amd.com void 23211308Santhony.gutierrez@amd.com generateDisassembly() 23311308Santhony.gutierrez@amd.com { 23411308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s,%s,%s,%s", opcode, dest.disassemble(), 23511308Santhony.gutierrez@amd.com src0.disassemble(), src1.disassemble(), 23611308Santhony.gutierrez@amd.com src2.disassemble()); 23711308Santhony.gutierrez@amd.com } 23811308Santhony.gutierrez@amd.com 23911308Santhony.gutierrez@amd.com public: 24011308Santhony.gutierrez@amd.com ThreeNonUniformSourceInstBase(const Brig::BrigInstBase *ib, 24111308Santhony.gutierrez@amd.com const BrigObject *obj, 24211308Santhony.gutierrez@amd.com const char *opcode) 24311308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, opcode) 24411308Santhony.gutierrez@amd.com { 24511692Santhony.gutierrez@amd.com setFlag(ALU); 24611692Santhony.gutierrez@amd.com 24711308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 24811308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 24911308Santhony.gutierrez@amd.com 25011308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 25111308Santhony.gutierrez@amd.com src0.init(op_offs, obj); 25211308Santhony.gutierrez@amd.com 25311308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 2); 25411308Santhony.gutierrez@amd.com src1.init(op_offs, obj); 25511308Santhony.gutierrez@amd.com 25611308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 3); 25711308Santhony.gutierrez@amd.com src2.init(op_offs, obj); 25811308Santhony.gutierrez@amd.com } 25911308Santhony.gutierrez@amd.com 26011308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { 26111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 26211308Santhony.gutierrez@amd.com if (!operandIndex) 26311308Santhony.gutierrez@amd.com return src0.isVectorRegister(); 26411308Santhony.gutierrez@amd.com else if (operandIndex == 1) 26511308Santhony.gutierrez@amd.com return src1.isVectorRegister(); 26611308Santhony.gutierrez@amd.com else if (operandIndex == 2) 26711308Santhony.gutierrez@amd.com return src2.isVectorRegister(); 26811308Santhony.gutierrez@amd.com else 26911308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 27011308Santhony.gutierrez@amd.com } 27111308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { 27211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 27311308Santhony.gutierrez@amd.com if (!operandIndex) 27411308Santhony.gutierrez@amd.com return src0.isCondRegister(); 27511308Santhony.gutierrez@amd.com else if (operandIndex == 1) 27611308Santhony.gutierrez@amd.com return src1.isCondRegister(); 27711308Santhony.gutierrez@amd.com else if (operandIndex == 2) 27811308Santhony.gutierrez@amd.com return src2.isCondRegister(); 27911308Santhony.gutierrez@amd.com else 28011308Santhony.gutierrez@amd.com return dest.isCondRegister(); 28111308Santhony.gutierrez@amd.com } 28211308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { 28311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 28411308Santhony.gutierrez@amd.com if (!operandIndex) 28511308Santhony.gutierrez@amd.com return src0.isScalarRegister(); 28611308Santhony.gutierrez@amd.com else if (operandIndex == 1) 28711308Santhony.gutierrez@amd.com return src1.isScalarRegister(); 28811308Santhony.gutierrez@amd.com else if (operandIndex == 2) 28911308Santhony.gutierrez@amd.com return src2.isScalarRegister(); 29011308Santhony.gutierrez@amd.com else 29111308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 29211308Santhony.gutierrez@amd.com } 29311308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { 29411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 29511308Santhony.gutierrez@amd.com if (operandIndex < 3) 29611308Santhony.gutierrez@amd.com return true; 29711308Santhony.gutierrez@amd.com else 29811308Santhony.gutierrez@amd.com return false; 29911308Santhony.gutierrez@amd.com } 30011308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { 30111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 30211308Santhony.gutierrez@amd.com if (operandIndex >= 3) 30311308Santhony.gutierrez@amd.com return true; 30411308Santhony.gutierrez@amd.com else 30511308Santhony.gutierrez@amd.com return false; 30611308Santhony.gutierrez@amd.com } 30711308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { 30811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 30911308Santhony.gutierrez@amd.com if (!operandIndex) 31011308Santhony.gutierrez@amd.com return src0.opSize(); 31111308Santhony.gutierrez@amd.com else if (operandIndex == 1) 31211308Santhony.gutierrez@amd.com return src1.opSize(); 31311308Santhony.gutierrez@amd.com else if (operandIndex == 2) 31411308Santhony.gutierrez@amd.com return src2.opSize(); 31511308Santhony.gutierrez@amd.com else 31611308Santhony.gutierrez@amd.com return dest.opSize(); 31711308Santhony.gutierrez@amd.com } 31811699Santhony.gutierrez@amd.com 31911699Santhony.gutierrez@amd.com int 32011699Santhony.gutierrez@amd.com getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) 32111699Santhony.gutierrez@amd.com { 32211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 32311308Santhony.gutierrez@amd.com if (!operandIndex) 32411308Santhony.gutierrez@amd.com return src0.regIndex(); 32511308Santhony.gutierrez@amd.com else if (operandIndex == 1) 32611308Santhony.gutierrez@amd.com return src1.regIndex(); 32711308Santhony.gutierrez@amd.com else if (operandIndex == 2) 32811308Santhony.gutierrez@amd.com return src2.regIndex(); 32911308Santhony.gutierrez@amd.com else 33011308Santhony.gutierrez@amd.com return dest.regIndex(); 33111308Santhony.gutierrez@amd.com } 33211308Santhony.gutierrez@amd.com 33311308Santhony.gutierrez@amd.com int numSrcRegOperands() { 33411308Santhony.gutierrez@amd.com int operands = 0; 33511325Ssteve.reinhardt@amd.com if (src0.isVectorRegister()) { 33611308Santhony.gutierrez@amd.com operands++; 33711308Santhony.gutierrez@amd.com } 33811325Ssteve.reinhardt@amd.com if (src1.isVectorRegister()) { 33911308Santhony.gutierrez@amd.com operands++; 34011308Santhony.gutierrez@amd.com } 34111325Ssteve.reinhardt@amd.com if (src2.isVectorRegister()) { 34211308Santhony.gutierrez@amd.com operands++; 34311308Santhony.gutierrez@amd.com } 34411308Santhony.gutierrez@amd.com return operands; 34511308Santhony.gutierrez@amd.com } 34611308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 34711308Santhony.gutierrez@amd.com int getNumOperands() { return 4; } 34811308Santhony.gutierrez@amd.com }; 34911308Santhony.gutierrez@amd.com 35011308Santhony.gutierrez@amd.com template<typename DestDataType, typename Src0DataType, 35111308Santhony.gutierrez@amd.com typename Src1DataType, typename Src2DataType> 35211308Santhony.gutierrez@amd.com class ThreeNonUniformSourceInst : 35311308Santhony.gutierrez@amd.com public ThreeNonUniformSourceInstBase<typename DestDataType::OperandType, 35411308Santhony.gutierrez@amd.com typename Src0DataType::OperandType, 35511308Santhony.gutierrez@amd.com typename Src1DataType::OperandType, 35611308Santhony.gutierrez@amd.com typename Src2DataType::OperandType> 35711308Santhony.gutierrez@amd.com { 35811308Santhony.gutierrez@amd.com public: 35911308Santhony.gutierrez@amd.com typedef typename DestDataType::CType DestCType; 36011308Santhony.gutierrez@amd.com typedef typename Src0DataType::CType Src0CType; 36111308Santhony.gutierrez@amd.com typedef typename Src1DataType::CType Src1CType; 36211308Santhony.gutierrez@amd.com typedef typename Src2DataType::CType Src2CType; 36311308Santhony.gutierrez@amd.com 36411308Santhony.gutierrez@amd.com ThreeNonUniformSourceInst(const Brig::BrigInstBase *ib, 36511308Santhony.gutierrez@amd.com const BrigObject *obj, const char *opcode) 36611308Santhony.gutierrez@amd.com : ThreeNonUniformSourceInstBase<typename DestDataType::OperandType, 36711308Santhony.gutierrez@amd.com typename Src0DataType::OperandType, 36811308Santhony.gutierrez@amd.com typename Src1DataType::OperandType, 36911308Santhony.gutierrez@amd.com typename Src2DataType::OperandType>(ib, 37011308Santhony.gutierrez@amd.com obj, opcode) 37111308Santhony.gutierrez@amd.com { 37211308Santhony.gutierrez@amd.com } 37311308Santhony.gutierrez@amd.com }; 37411308Santhony.gutierrez@amd.com 37511308Santhony.gutierrez@amd.com template<typename DataType> 37611308Santhony.gutierrez@amd.com class CmovInst : public ThreeNonUniformSourceInst<DataType, B1, 37711308Santhony.gutierrez@amd.com DataType, DataType> 37811308Santhony.gutierrez@amd.com { 37911308Santhony.gutierrez@amd.com public: 38011308Santhony.gutierrez@amd.com CmovInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 38111308Santhony.gutierrez@amd.com const char *opcode) 38211308Santhony.gutierrez@amd.com : ThreeNonUniformSourceInst<DataType, B1, DataType, 38311308Santhony.gutierrez@amd.com DataType>(ib, obj, opcode) 38411308Santhony.gutierrez@amd.com { 38511308Santhony.gutierrez@amd.com } 38611308Santhony.gutierrez@amd.com }; 38711308Santhony.gutierrez@amd.com 38811308Santhony.gutierrez@amd.com template<typename DataType> 38911308Santhony.gutierrez@amd.com class ExtractInsertInst : public ThreeNonUniformSourceInst<DataType, 39011308Santhony.gutierrez@amd.com DataType, U32, 39111308Santhony.gutierrez@amd.com U32> 39211308Santhony.gutierrez@amd.com { 39311308Santhony.gutierrez@amd.com public: 39411308Santhony.gutierrez@amd.com ExtractInsertInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 39511308Santhony.gutierrez@amd.com const char *opcode) 39611308Santhony.gutierrez@amd.com : ThreeNonUniformSourceInst<DataType, DataType, U32, 39711308Santhony.gutierrez@amd.com U32>(ib, obj, opcode) 39811308Santhony.gutierrez@amd.com { 39911308Santhony.gutierrez@amd.com } 40011308Santhony.gutierrez@amd.com }; 40111308Santhony.gutierrez@amd.com 40211308Santhony.gutierrez@amd.com template<typename DestOperandType, typename Src0OperandType, 40311308Santhony.gutierrez@amd.com typename Src1OperandType> 40411308Santhony.gutierrez@amd.com class TwoNonUniformSourceInstBase : public HsailGPUStaticInst 40511308Santhony.gutierrez@amd.com { 40611308Santhony.gutierrez@amd.com protected: 40711308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 40811308Santhony.gutierrez@amd.com typename Src0OperandType::SrcOperand src0; 40911308Santhony.gutierrez@amd.com typename Src1OperandType::SrcOperand src1; 41011308Santhony.gutierrez@amd.com 41111308Santhony.gutierrez@amd.com void 41211308Santhony.gutierrez@amd.com generateDisassembly() 41311308Santhony.gutierrez@amd.com { 41411308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s,%s,%s", opcode, dest.disassemble(), 41511308Santhony.gutierrez@amd.com src0.disassemble(), src1.disassemble()); 41611308Santhony.gutierrez@amd.com } 41711308Santhony.gutierrez@amd.com 41811308Santhony.gutierrez@amd.com 41911308Santhony.gutierrez@amd.com public: 42011308Santhony.gutierrez@amd.com TwoNonUniformSourceInstBase(const Brig::BrigInstBase *ib, 42111308Santhony.gutierrez@amd.com const BrigObject *obj, const char *opcode) 42211308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, opcode) 42311308Santhony.gutierrez@amd.com { 42411692Santhony.gutierrez@amd.com setFlag(ALU); 42511692Santhony.gutierrez@amd.com 42611308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 42711308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 42811308Santhony.gutierrez@amd.com 42911308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 43011308Santhony.gutierrez@amd.com src0.init(op_offs, obj); 43111308Santhony.gutierrez@amd.com 43211308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 2); 43311308Santhony.gutierrez@amd.com src1.init(op_offs, obj); 43411308Santhony.gutierrez@amd.com } 43511308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { 43611308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 43711308Santhony.gutierrez@amd.com if (!operandIndex) 43811308Santhony.gutierrez@amd.com return src0.isVectorRegister(); 43911308Santhony.gutierrez@amd.com else if (operandIndex == 1) 44011308Santhony.gutierrez@amd.com return src1.isVectorRegister(); 44111308Santhony.gutierrez@amd.com else 44211308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 44311308Santhony.gutierrez@amd.com } 44411308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { 44511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 44611308Santhony.gutierrez@amd.com if (!operandIndex) 44711308Santhony.gutierrez@amd.com return src0.isCondRegister(); 44811308Santhony.gutierrez@amd.com else if (operandIndex == 1) 44911308Santhony.gutierrez@amd.com return src1.isCondRegister(); 45011308Santhony.gutierrez@amd.com else 45111308Santhony.gutierrez@amd.com return dest.isCondRegister(); 45211308Santhony.gutierrez@amd.com } 45311308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { 45411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 45511308Santhony.gutierrez@amd.com if (!operandIndex) 45611308Santhony.gutierrez@amd.com return src0.isScalarRegister(); 45711308Santhony.gutierrez@amd.com else if (operandIndex == 1) 45811308Santhony.gutierrez@amd.com return src1.isScalarRegister(); 45911308Santhony.gutierrez@amd.com else 46011308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 46111308Santhony.gutierrez@amd.com } 46211308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { 46311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 46411308Santhony.gutierrez@amd.com if (operandIndex < 2) 46511308Santhony.gutierrez@amd.com return true; 46611308Santhony.gutierrez@amd.com else 46711308Santhony.gutierrez@amd.com return false; 46811308Santhony.gutierrez@amd.com } 46911308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { 47011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 47111308Santhony.gutierrez@amd.com if (operandIndex >= 2) 47211308Santhony.gutierrez@amd.com return true; 47311308Santhony.gutierrez@amd.com else 47411308Santhony.gutierrez@amd.com return false; 47511308Santhony.gutierrez@amd.com } 47611308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { 47711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 47811308Santhony.gutierrez@amd.com if (!operandIndex) 47911308Santhony.gutierrez@amd.com return src0.opSize(); 48011308Santhony.gutierrez@amd.com else if (operandIndex == 1) 48111308Santhony.gutierrez@amd.com return src1.opSize(); 48211308Santhony.gutierrez@amd.com else 48311308Santhony.gutierrez@amd.com return dest.opSize(); 48411308Santhony.gutierrez@amd.com } 48511699Santhony.gutierrez@amd.com 48611699Santhony.gutierrez@amd.com int 48711699Santhony.gutierrez@amd.com getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) 48811699Santhony.gutierrez@amd.com { 48911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 49011308Santhony.gutierrez@amd.com if (!operandIndex) 49111308Santhony.gutierrez@amd.com return src0.regIndex(); 49211308Santhony.gutierrez@amd.com else if (operandIndex == 1) 49311308Santhony.gutierrez@amd.com return src1.regIndex(); 49411308Santhony.gutierrez@amd.com else 49511308Santhony.gutierrez@amd.com return dest.regIndex(); 49611308Santhony.gutierrez@amd.com } 49711308Santhony.gutierrez@amd.com 49811308Santhony.gutierrez@amd.com int numSrcRegOperands() { 49911308Santhony.gutierrez@amd.com int operands = 0; 50011325Ssteve.reinhardt@amd.com if (src0.isVectorRegister()) { 50111308Santhony.gutierrez@amd.com operands++; 50211308Santhony.gutierrez@amd.com } 50311325Ssteve.reinhardt@amd.com if (src1.isVectorRegister()) { 50411308Santhony.gutierrez@amd.com operands++; 50511308Santhony.gutierrez@amd.com } 50611308Santhony.gutierrez@amd.com return operands; 50711308Santhony.gutierrez@amd.com } 50811308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 50911308Santhony.gutierrez@amd.com int getNumOperands() { return 3; } 51011308Santhony.gutierrez@amd.com }; 51111308Santhony.gutierrez@amd.com 51211308Santhony.gutierrez@amd.com template<typename DestDataType, typename Src0DataType, 51311308Santhony.gutierrez@amd.com typename Src1DataType> 51411308Santhony.gutierrez@amd.com class TwoNonUniformSourceInst : 51511308Santhony.gutierrez@amd.com public TwoNonUniformSourceInstBase<typename DestDataType::OperandType, 51611308Santhony.gutierrez@amd.com typename Src0DataType::OperandType, 51711308Santhony.gutierrez@amd.com typename Src1DataType::OperandType> 51811308Santhony.gutierrez@amd.com { 51911308Santhony.gutierrez@amd.com public: 52011308Santhony.gutierrez@amd.com typedef typename DestDataType::CType DestCType; 52111308Santhony.gutierrez@amd.com typedef typename Src0DataType::CType Src0CType; 52211308Santhony.gutierrez@amd.com typedef typename Src1DataType::CType Src1CType; 52311308Santhony.gutierrez@amd.com 52411308Santhony.gutierrez@amd.com TwoNonUniformSourceInst(const Brig::BrigInstBase *ib, 52511308Santhony.gutierrez@amd.com const BrigObject *obj, const char *opcode) 52611308Santhony.gutierrez@amd.com : TwoNonUniformSourceInstBase<typename DestDataType::OperandType, 52711308Santhony.gutierrez@amd.com typename Src0DataType::OperandType, 52811308Santhony.gutierrez@amd.com typename Src1DataType::OperandType>(ib, 52911308Santhony.gutierrez@amd.com obj, opcode) 53011308Santhony.gutierrez@amd.com { 53111308Santhony.gutierrez@amd.com } 53211308Santhony.gutierrez@amd.com }; 53311308Santhony.gutierrez@amd.com 53411308Santhony.gutierrez@amd.com // helper function for ClassInst 53511308Santhony.gutierrez@amd.com template<typename T> 53611308Santhony.gutierrez@amd.com bool 53711308Santhony.gutierrez@amd.com fpclassify(T src0, uint32_t src1) 53811308Santhony.gutierrez@amd.com { 53911308Santhony.gutierrez@amd.com int fpclass = std::fpclassify(src0); 54011308Santhony.gutierrez@amd.com 54111308Santhony.gutierrez@amd.com if ((src1 & 0x3) && (fpclass == FP_NAN)) { 54211308Santhony.gutierrez@amd.com return true; 54311308Santhony.gutierrez@amd.com } 54411308Santhony.gutierrez@amd.com 54511308Santhony.gutierrez@amd.com if (src0 <= -0.0) { 54611308Santhony.gutierrez@amd.com if ((src1 & 0x4) && fpclass == FP_INFINITE) 54711308Santhony.gutierrez@amd.com return true; 54811308Santhony.gutierrez@amd.com if ((src1 & 0x8) && fpclass == FP_NORMAL) 54911308Santhony.gutierrez@amd.com return true; 55011308Santhony.gutierrez@amd.com if ((src1 & 0x10) && fpclass == FP_SUBNORMAL) 55111308Santhony.gutierrez@amd.com return true; 55211308Santhony.gutierrez@amd.com if ((src1 & 0x20) && fpclass == FP_ZERO) 55311308Santhony.gutierrez@amd.com return true; 55411308Santhony.gutierrez@amd.com } else { 55511308Santhony.gutierrez@amd.com if ((src1 & 0x40) && fpclass == FP_ZERO) 55611308Santhony.gutierrez@amd.com return true; 55711308Santhony.gutierrez@amd.com if ((src1 & 0x80) && fpclass == FP_SUBNORMAL) 55811308Santhony.gutierrez@amd.com return true; 55911308Santhony.gutierrez@amd.com if ((src1 & 0x100) && fpclass == FP_NORMAL) 56011308Santhony.gutierrez@amd.com return true; 56111308Santhony.gutierrez@amd.com if ((src1 & 0x200) && fpclass == FP_INFINITE) 56211308Santhony.gutierrez@amd.com return true; 56311308Santhony.gutierrez@amd.com } 56411308Santhony.gutierrez@amd.com return false; 56511308Santhony.gutierrez@amd.com } 56611308Santhony.gutierrez@amd.com 56711308Santhony.gutierrez@amd.com template<typename DataType> 56811308Santhony.gutierrez@amd.com class ClassInst : public TwoNonUniformSourceInst<B1, DataType, U32> 56911308Santhony.gutierrez@amd.com { 57011308Santhony.gutierrez@amd.com public: 57111308Santhony.gutierrez@amd.com ClassInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 57211308Santhony.gutierrez@amd.com const char *opcode) 57311308Santhony.gutierrez@amd.com : TwoNonUniformSourceInst<B1, DataType, U32>(ib, obj, opcode) 57411308Santhony.gutierrez@amd.com { 57511308Santhony.gutierrez@amd.com } 57611308Santhony.gutierrez@amd.com }; 57711308Santhony.gutierrez@amd.com 57811308Santhony.gutierrez@amd.com template<typename DataType> 57911308Santhony.gutierrez@amd.com class ShiftInst : public TwoNonUniformSourceInst<DataType, DataType, U32> 58011308Santhony.gutierrez@amd.com { 58111308Santhony.gutierrez@amd.com public: 58211308Santhony.gutierrez@amd.com ShiftInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 58311308Santhony.gutierrez@amd.com const char *opcode) 58411308Santhony.gutierrez@amd.com : TwoNonUniformSourceInst<DataType, DataType, U32>(ib, obj, opcode) 58511308Santhony.gutierrez@amd.com { 58611308Santhony.gutierrez@amd.com } 58711308Santhony.gutierrez@amd.com }; 58811308Santhony.gutierrez@amd.com 58911308Santhony.gutierrez@amd.com // helper function for CmpInst 59011308Santhony.gutierrez@amd.com template<typename T> 59111308Santhony.gutierrez@amd.com bool 59211308Santhony.gutierrez@amd.com compare(T src0, T src1, Brig::BrigCompareOperation cmpOp) 59311308Santhony.gutierrez@amd.com { 59411308Santhony.gutierrez@amd.com using namespace Brig; 59511308Santhony.gutierrez@amd.com 59611308Santhony.gutierrez@amd.com switch (cmpOp) { 59711308Santhony.gutierrez@amd.com case BRIG_COMPARE_EQ: 59811308Santhony.gutierrez@amd.com case BRIG_COMPARE_EQU: 59911308Santhony.gutierrez@amd.com case BRIG_COMPARE_SEQ: 60011308Santhony.gutierrez@amd.com case BRIG_COMPARE_SEQU: 60111308Santhony.gutierrez@amd.com return (src0 == src1); 60211308Santhony.gutierrez@amd.com 60311308Santhony.gutierrez@amd.com case BRIG_COMPARE_NE: 60411308Santhony.gutierrez@amd.com case BRIG_COMPARE_NEU: 60511308Santhony.gutierrez@amd.com case BRIG_COMPARE_SNE: 60611308Santhony.gutierrez@amd.com case BRIG_COMPARE_SNEU: 60711308Santhony.gutierrez@amd.com return (src0 != src1); 60811308Santhony.gutierrez@amd.com 60911308Santhony.gutierrez@amd.com case BRIG_COMPARE_LT: 61011308Santhony.gutierrez@amd.com case BRIG_COMPARE_LTU: 61111308Santhony.gutierrez@amd.com case BRIG_COMPARE_SLT: 61211308Santhony.gutierrez@amd.com case BRIG_COMPARE_SLTU: 61311308Santhony.gutierrez@amd.com return (src0 < src1); 61411308Santhony.gutierrez@amd.com 61511308Santhony.gutierrez@amd.com case BRIG_COMPARE_LE: 61611308Santhony.gutierrez@amd.com case BRIG_COMPARE_LEU: 61711308Santhony.gutierrez@amd.com case BRIG_COMPARE_SLE: 61811308Santhony.gutierrez@amd.com case BRIG_COMPARE_SLEU: 61911308Santhony.gutierrez@amd.com return (src0 <= src1); 62011308Santhony.gutierrez@amd.com 62111308Santhony.gutierrez@amd.com case BRIG_COMPARE_GT: 62211308Santhony.gutierrez@amd.com case BRIG_COMPARE_GTU: 62311308Santhony.gutierrez@amd.com case BRIG_COMPARE_SGT: 62411308Santhony.gutierrez@amd.com case BRIG_COMPARE_SGTU: 62511308Santhony.gutierrez@amd.com return (src0 > src1); 62611308Santhony.gutierrez@amd.com 62711308Santhony.gutierrez@amd.com case BRIG_COMPARE_GE: 62811308Santhony.gutierrez@amd.com case BRIG_COMPARE_GEU: 62911308Santhony.gutierrez@amd.com case BRIG_COMPARE_SGE: 63011308Santhony.gutierrez@amd.com case BRIG_COMPARE_SGEU: 63111308Santhony.gutierrez@amd.com return (src0 >= src1); 63211308Santhony.gutierrez@amd.com 63311308Santhony.gutierrez@amd.com case BRIG_COMPARE_NUM: 63411308Santhony.gutierrez@amd.com case BRIG_COMPARE_SNUM: 63511308Santhony.gutierrez@amd.com return (src0 == src0) || (src1 == src1); 63611308Santhony.gutierrez@amd.com 63711308Santhony.gutierrez@amd.com case BRIG_COMPARE_NAN: 63811308Santhony.gutierrez@amd.com case BRIG_COMPARE_SNAN: 63911308Santhony.gutierrez@amd.com return (src0 != src0) || (src1 != src1); 64011308Santhony.gutierrez@amd.com 64111308Santhony.gutierrez@amd.com default: 64211308Santhony.gutierrez@amd.com fatal("Bad cmpOp value %d\n", (int)cmpOp); 64311308Santhony.gutierrez@amd.com } 64411308Santhony.gutierrez@amd.com } 64511308Santhony.gutierrez@amd.com 64611308Santhony.gutierrez@amd.com template<typename T> 64711308Santhony.gutierrez@amd.com int32_t 64811308Santhony.gutierrez@amd.com firstbit(T src0) 64911308Santhony.gutierrez@amd.com { 65011308Santhony.gutierrez@amd.com if (!src0) 65111308Santhony.gutierrez@amd.com return -1; 65211308Santhony.gutierrez@amd.com 65311308Santhony.gutierrez@amd.com //handle positive and negative numbers 65411699Santhony.gutierrez@amd.com T tmp = ((int64_t)src0 < 0) ? (~src0) : (src0); 65511308Santhony.gutierrez@amd.com 65611308Santhony.gutierrez@amd.com //the starting pos is MSB 65711308Santhony.gutierrez@amd.com int pos = 8 * sizeof(T) - 1; 65811308Santhony.gutierrez@amd.com int cnt = 0; 65911308Santhony.gutierrez@amd.com 66011308Santhony.gutierrez@amd.com //search the first bit set to 1 66111308Santhony.gutierrez@amd.com while (!(tmp & (1 << pos))) { 66211308Santhony.gutierrez@amd.com ++cnt; 66311308Santhony.gutierrez@amd.com --pos; 66411308Santhony.gutierrez@amd.com } 66511308Santhony.gutierrez@amd.com return cnt; 66611308Santhony.gutierrez@amd.com } 66711308Santhony.gutierrez@amd.com 66811308Santhony.gutierrez@amd.com const char* cmpOpToString(Brig::BrigCompareOperation cmpOp); 66911308Santhony.gutierrez@amd.com 67011308Santhony.gutierrez@amd.com template<typename DestOperandType, typename SrcOperandType> 67111308Santhony.gutierrez@amd.com class CmpInstBase : public CommonInstBase<DestOperandType, SrcOperandType, 67211308Santhony.gutierrez@amd.com 2> 67311308Santhony.gutierrez@amd.com { 67411308Santhony.gutierrez@amd.com protected: 67511308Santhony.gutierrez@amd.com Brig::BrigCompareOperation cmpOp; 67611308Santhony.gutierrez@amd.com 67711308Santhony.gutierrez@amd.com public: 67811308Santhony.gutierrez@amd.com CmpInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, 67911308Santhony.gutierrez@amd.com const char *_opcode) 68011308Santhony.gutierrez@amd.com : CommonInstBase<DestOperandType, SrcOperandType, 2>(ib, obj, 68111308Santhony.gutierrez@amd.com _opcode) 68211308Santhony.gutierrez@amd.com { 68311308Santhony.gutierrez@amd.com assert(ib->base.kind == Brig::BRIG_KIND_INST_CMP); 68411308Santhony.gutierrez@amd.com Brig::BrigInstCmp *i = (Brig::BrigInstCmp*)ib; 68511308Santhony.gutierrez@amd.com cmpOp = (Brig::BrigCompareOperation)i->compare; 68611308Santhony.gutierrez@amd.com } 68711308Santhony.gutierrez@amd.com }; 68811308Santhony.gutierrez@amd.com 68911308Santhony.gutierrez@amd.com template<typename DestDataType, typename SrcDataType> 69011308Santhony.gutierrez@amd.com class CmpInst : public CmpInstBase<typename DestDataType::OperandType, 69111308Santhony.gutierrez@amd.com typename SrcDataType::OperandType> 69211308Santhony.gutierrez@amd.com { 69311308Santhony.gutierrez@amd.com public: 69411308Santhony.gutierrez@amd.com std::string 69511308Santhony.gutierrez@amd.com opcode_suffix() 69611308Santhony.gutierrez@amd.com { 69711308Santhony.gutierrez@amd.com return csprintf("_%s_%s_%s", cmpOpToString(this->cmpOp), 69811308Santhony.gutierrez@amd.com DestDataType::label, SrcDataType::label); 69911308Santhony.gutierrez@amd.com } 70011308Santhony.gutierrez@amd.com 70111308Santhony.gutierrez@amd.com CmpInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 70211308Santhony.gutierrez@amd.com const char *_opcode) 70311308Santhony.gutierrez@amd.com : CmpInstBase<typename DestDataType::OperandType, 70411308Santhony.gutierrez@amd.com typename SrcDataType::OperandType>(ib, obj, _opcode) 70511308Santhony.gutierrez@amd.com { 70611308Santhony.gutierrez@amd.com } 70711308Santhony.gutierrez@amd.com }; 70811308Santhony.gutierrez@amd.com 70911308Santhony.gutierrez@amd.com template<typename DestDataType, typename SrcDataType> 71011308Santhony.gutierrez@amd.com class CvtInst : public CommonInstBase<typename DestDataType::OperandType, 71111308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 1> 71211308Santhony.gutierrez@amd.com { 71311308Santhony.gutierrez@amd.com public: 71411308Santhony.gutierrez@amd.com std::string opcode_suffix() 71511308Santhony.gutierrez@amd.com { 71611308Santhony.gutierrez@amd.com return csprintf("_%s_%s", DestDataType::label, SrcDataType::label); 71711308Santhony.gutierrez@amd.com } 71811308Santhony.gutierrez@amd.com 71911308Santhony.gutierrez@amd.com CvtInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 72011308Santhony.gutierrez@amd.com const char *_opcode) 72111308Santhony.gutierrez@amd.com : CommonInstBase<typename DestDataType::OperandType, 72211308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 72311308Santhony.gutierrez@amd.com 1>(ib, obj, _opcode) 72411308Santhony.gutierrez@amd.com { 72511308Santhony.gutierrez@amd.com } 72611308Santhony.gutierrez@amd.com }; 72711308Santhony.gutierrez@amd.com 72811308Santhony.gutierrez@amd.com class SpecialInstNoSrcNoDest : public HsailGPUStaticInst 72911308Santhony.gutierrez@amd.com { 73011308Santhony.gutierrez@amd.com public: 73111308Santhony.gutierrez@amd.com SpecialInstNoSrcNoDest(const Brig::BrigInstBase *ib, 73211308Santhony.gutierrez@amd.com const BrigObject *obj, const char *_opcode) 73311308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 73411308Santhony.gutierrez@amd.com { 73511308Santhony.gutierrez@amd.com } 73611308Santhony.gutierrez@amd.com 73711308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { return false; } 73811308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { return false; } 73911308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { return false; } 74011308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { return false; } 74111308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { return false; } 74211308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { return 0; } 74311699Santhony.gutierrez@amd.com 74411699Santhony.gutierrez@amd.com int 74511699Santhony.gutierrez@amd.com getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) 74611699Santhony.gutierrez@amd.com { 74711699Santhony.gutierrez@amd.com return -1; 74811699Santhony.gutierrez@amd.com } 74911308Santhony.gutierrez@amd.com 75011308Santhony.gutierrez@amd.com int numSrcRegOperands() { return 0; } 75111308Santhony.gutierrez@amd.com int numDstRegOperands() { return 0; } 75211308Santhony.gutierrez@amd.com int getNumOperands() { return 0; } 75311308Santhony.gutierrez@amd.com }; 75411308Santhony.gutierrez@amd.com 75511308Santhony.gutierrez@amd.com template<typename DestOperandType> 75611308Santhony.gutierrez@amd.com class SpecialInstNoSrcBase : public HsailGPUStaticInst 75711308Santhony.gutierrez@amd.com { 75811308Santhony.gutierrez@amd.com protected: 75911308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 76011308Santhony.gutierrez@amd.com 76111308Santhony.gutierrez@amd.com void generateDisassembly() 76211308Santhony.gutierrez@amd.com { 76311308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s", opcode, dest.disassemble()); 76411308Santhony.gutierrez@amd.com } 76511308Santhony.gutierrez@amd.com 76611308Santhony.gutierrez@amd.com public: 76711308Santhony.gutierrez@amd.com SpecialInstNoSrcBase(const Brig::BrigInstBase *ib, 76811308Santhony.gutierrez@amd.com const BrigObject *obj, const char *_opcode) 76911308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 77011308Santhony.gutierrez@amd.com { 77111308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 77211308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 77311308Santhony.gutierrez@amd.com } 77411308Santhony.gutierrez@amd.com 77511308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { 77611308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 77711308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 77811308Santhony.gutierrez@amd.com } 77911308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { 78011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 78111308Santhony.gutierrez@amd.com return dest.isCondRegister(); 78211308Santhony.gutierrez@amd.com } 78311308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { 78411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 78511308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 78611308Santhony.gutierrez@amd.com } 78711308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { return false; } 78811308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { return true; } 78911308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { 79011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 79111308Santhony.gutierrez@amd.com return dest.opSize(); 79211308Santhony.gutierrez@amd.com } 79311699Santhony.gutierrez@amd.com 79411699Santhony.gutierrez@amd.com int 79511699Santhony.gutierrez@amd.com getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) 79611699Santhony.gutierrez@amd.com { 79711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 79811308Santhony.gutierrez@amd.com return dest.regIndex(); 79911308Santhony.gutierrez@amd.com } 80011699Santhony.gutierrez@amd.com 80111308Santhony.gutierrez@amd.com int numSrcRegOperands() { return 0; } 80211308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 80311308Santhony.gutierrez@amd.com int getNumOperands() { return 1; } 80411308Santhony.gutierrez@amd.com }; 80511308Santhony.gutierrez@amd.com 80611308Santhony.gutierrez@amd.com template<typename DestDataType> 80711308Santhony.gutierrez@amd.com class SpecialInstNoSrc : 80811308Santhony.gutierrez@amd.com public SpecialInstNoSrcBase<typename DestDataType::OperandType> 80911308Santhony.gutierrez@amd.com { 81011308Santhony.gutierrez@amd.com public: 81111308Santhony.gutierrez@amd.com typedef typename DestDataType::CType DestCType; 81211308Santhony.gutierrez@amd.com 81311308Santhony.gutierrez@amd.com SpecialInstNoSrc(const Brig::BrigInstBase *ib, const BrigObject *obj, 81411308Santhony.gutierrez@amd.com const char *_opcode) 81511308Santhony.gutierrez@amd.com : SpecialInstNoSrcBase<typename DestDataType::OperandType>(ib, obj, 81611308Santhony.gutierrez@amd.com _opcode) 81711308Santhony.gutierrez@amd.com { 81811308Santhony.gutierrez@amd.com } 81911308Santhony.gutierrez@amd.com }; 82011308Santhony.gutierrez@amd.com 82111308Santhony.gutierrez@amd.com template<typename DestOperandType> 82211308Santhony.gutierrez@amd.com class SpecialInst1SrcBase : public HsailGPUStaticInst 82311308Santhony.gutierrez@amd.com { 82411308Santhony.gutierrez@amd.com protected: 82511308Santhony.gutierrez@amd.com typedef int SrcCType; // used in execute() template 82611308Santhony.gutierrez@amd.com 82711308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 82811308Santhony.gutierrez@amd.com ImmOperand<SrcCType> src0; 82911308Santhony.gutierrez@amd.com 83011308Santhony.gutierrez@amd.com void 83111308Santhony.gutierrez@amd.com generateDisassembly() 83211308Santhony.gutierrez@amd.com { 83311308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s,%s", opcode, dest.disassemble(), 83411308Santhony.gutierrez@amd.com src0.disassemble()); 83511308Santhony.gutierrez@amd.com } 83611308Santhony.gutierrez@amd.com 83711308Santhony.gutierrez@amd.com public: 83811308Santhony.gutierrez@amd.com SpecialInst1SrcBase(const Brig::BrigInstBase *ib, 83911308Santhony.gutierrez@amd.com const BrigObject *obj, const char *_opcode) 84011308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 84111308Santhony.gutierrez@amd.com { 84211692Santhony.gutierrez@amd.com setFlag(ALU); 84311692Santhony.gutierrez@amd.com 84411308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 84511308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 84611308Santhony.gutierrez@amd.com 84711308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 84811308Santhony.gutierrez@amd.com src0.init(op_offs, obj); 84911308Santhony.gutierrez@amd.com } 85011308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { 85111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 85211308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 85311308Santhony.gutierrez@amd.com } 85411308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { 85511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 85611308Santhony.gutierrez@amd.com return dest.isCondRegister(); 85711308Santhony.gutierrez@amd.com } 85811308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { 85911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 86011308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 86111308Santhony.gutierrez@amd.com } 86211308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { return false; } 86311308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { return true; } 86411308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { 86511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 86611308Santhony.gutierrez@amd.com return dest.opSize(); 86711308Santhony.gutierrez@amd.com } 86811699Santhony.gutierrez@amd.com 86911699Santhony.gutierrez@amd.com int 87011699Santhony.gutierrez@amd.com getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) 87111699Santhony.gutierrez@amd.com { 87211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 87311308Santhony.gutierrez@amd.com return dest.regIndex(); 87411308Santhony.gutierrez@amd.com } 87511699Santhony.gutierrez@amd.com 87611308Santhony.gutierrez@amd.com int numSrcRegOperands() { return 0; } 87711308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 87811308Santhony.gutierrez@amd.com int getNumOperands() { return 1; } 87911308Santhony.gutierrez@amd.com }; 88011308Santhony.gutierrez@amd.com 88111308Santhony.gutierrez@amd.com template<typename DestDataType> 88211308Santhony.gutierrez@amd.com class SpecialInst1Src : 88311308Santhony.gutierrez@amd.com public SpecialInst1SrcBase<typename DestDataType::OperandType> 88411308Santhony.gutierrez@amd.com { 88511308Santhony.gutierrez@amd.com public: 88611308Santhony.gutierrez@amd.com typedef typename DestDataType::CType DestCType; 88711308Santhony.gutierrez@amd.com 88811308Santhony.gutierrez@amd.com SpecialInst1Src(const Brig::BrigInstBase *ib, const BrigObject *obj, 88911308Santhony.gutierrez@amd.com const char *_opcode) 89011308Santhony.gutierrez@amd.com : SpecialInst1SrcBase<typename DestDataType::OperandType>(ib, obj, 89111308Santhony.gutierrez@amd.com _opcode) 89211308Santhony.gutierrez@amd.com { 89311308Santhony.gutierrez@amd.com } 89411308Santhony.gutierrez@amd.com }; 89511308Santhony.gutierrez@amd.com 89611308Santhony.gutierrez@amd.com class Ret : public SpecialInstNoSrcNoDest 89711308Santhony.gutierrez@amd.com { 89811308Santhony.gutierrez@amd.com public: 89911308Santhony.gutierrez@amd.com typedef SpecialInstNoSrcNoDest Base; 90011308Santhony.gutierrez@amd.com 90111308Santhony.gutierrez@amd.com Ret(const Brig::BrigInstBase *ib, const BrigObject *obj) 90211308Santhony.gutierrez@amd.com : Base(ib, obj, "ret") 90311308Santhony.gutierrez@amd.com { 90411692Santhony.gutierrez@amd.com setFlag(GPUStaticInst::Return); 90511308Santhony.gutierrez@amd.com } 90611308Santhony.gutierrez@amd.com 90711308Santhony.gutierrez@amd.com void execute(GPUDynInstPtr gpuDynInst); 90811308Santhony.gutierrez@amd.com }; 90911308Santhony.gutierrez@amd.com 91011308Santhony.gutierrez@amd.com class Barrier : public SpecialInstNoSrcNoDest 91111308Santhony.gutierrez@amd.com { 91211308Santhony.gutierrez@amd.com public: 91311308Santhony.gutierrez@amd.com typedef SpecialInstNoSrcNoDest Base; 91411308Santhony.gutierrez@amd.com uint8_t width; 91511308Santhony.gutierrez@amd.com 91611308Santhony.gutierrez@amd.com Barrier(const Brig::BrigInstBase *ib, const BrigObject *obj) 91711308Santhony.gutierrez@amd.com : Base(ib, obj, "barrier") 91811308Santhony.gutierrez@amd.com { 91911692Santhony.gutierrez@amd.com setFlag(GPUStaticInst::MemBarrier); 92011308Santhony.gutierrez@amd.com assert(ib->base.kind == Brig::BRIG_KIND_INST_BR); 92111308Santhony.gutierrez@amd.com width = (uint8_t)((Brig::BrigInstBr*)ib)->width; 92211308Santhony.gutierrez@amd.com } 92311308Santhony.gutierrez@amd.com 92411308Santhony.gutierrez@amd.com void execute(GPUDynInstPtr gpuDynInst); 92511308Santhony.gutierrez@amd.com }; 92611308Santhony.gutierrez@amd.com 92711308Santhony.gutierrez@amd.com class MemFence : public SpecialInstNoSrcNoDest 92811308Santhony.gutierrez@amd.com { 92911308Santhony.gutierrez@amd.com public: 93011308Santhony.gutierrez@amd.com typedef SpecialInstNoSrcNoDest Base; 93111308Santhony.gutierrez@amd.com 93211308Santhony.gutierrez@amd.com Brig::BrigMemoryOrder memFenceMemOrder; 93311308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memFenceScopeSegGroup; 93411308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memFenceScopeSegGlobal; 93511308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memFenceScopeSegImage; 93611308Santhony.gutierrez@amd.com 93711308Santhony.gutierrez@amd.com MemFence(const Brig::BrigInstBase *ib, const BrigObject *obj) 93811308Santhony.gutierrez@amd.com : Base(ib, obj, "memfence") 93911308Santhony.gutierrez@amd.com { 94011308Santhony.gutierrez@amd.com assert(ib->base.kind == Brig::BRIG_KIND_INST_MEM_FENCE); 94111308Santhony.gutierrez@amd.com 94211308Santhony.gutierrez@amd.com memFenceScopeSegGlobal = (Brig::BrigMemoryScope) 94311308Santhony.gutierrez@amd.com ((Brig::BrigInstMemFence*)ib)->globalSegmentMemoryScope; 94411308Santhony.gutierrez@amd.com 94511308Santhony.gutierrez@amd.com memFenceScopeSegGroup = (Brig::BrigMemoryScope) 94611308Santhony.gutierrez@amd.com ((Brig::BrigInstMemFence*)ib)->groupSegmentMemoryScope; 94711308Santhony.gutierrez@amd.com 94811308Santhony.gutierrez@amd.com memFenceScopeSegImage = (Brig::BrigMemoryScope) 94911308Santhony.gutierrez@amd.com ((Brig::BrigInstMemFence*)ib)->imageSegmentMemoryScope; 95011308Santhony.gutierrez@amd.com 95111308Santhony.gutierrez@amd.com memFenceMemOrder = (Brig::BrigMemoryOrder) 95211308Santhony.gutierrez@amd.com ((Brig::BrigInstMemFence*)ib)->memoryOrder; 95311308Santhony.gutierrez@amd.com 95411692Santhony.gutierrez@amd.com setFlag(MemoryRef); 95511692Santhony.gutierrez@amd.com setFlag(GPUStaticInst::MemFence); 95611692Santhony.gutierrez@amd.com 95711692Santhony.gutierrez@amd.com switch (memFenceMemOrder) { 95811692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_ORDER_NONE: 95911692Santhony.gutierrez@amd.com setFlag(NoOrder); 96011692Santhony.gutierrez@amd.com break; 96111692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_ORDER_RELAXED: 96211692Santhony.gutierrez@amd.com setFlag(RelaxedOrder); 96311692Santhony.gutierrez@amd.com break; 96411692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_ORDER_SC_ACQUIRE: 96511692Santhony.gutierrez@amd.com setFlag(Acquire); 96611692Santhony.gutierrez@amd.com break; 96711692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_ORDER_SC_RELEASE: 96811692Santhony.gutierrez@amd.com setFlag(Release); 96911692Santhony.gutierrez@amd.com break; 97011692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE: 97111692Santhony.gutierrez@amd.com setFlag(AcquireRelease); 97211692Santhony.gutierrez@amd.com break; 97311692Santhony.gutierrez@amd.com default: 97411692Santhony.gutierrez@amd.com fatal("MemInst has bad BrigMemoryOrder\n"); 97511692Santhony.gutierrez@amd.com } 97611692Santhony.gutierrez@amd.com 97711692Santhony.gutierrez@amd.com // set inst flags based on scopes 97811308Santhony.gutierrez@amd.com if (memFenceScopeSegGlobal != Brig::BRIG_MEMORY_SCOPE_NONE && 97911308Santhony.gutierrez@amd.com memFenceScopeSegGroup != Brig::BRIG_MEMORY_SCOPE_NONE) { 98011692Santhony.gutierrez@amd.com setFlag(GPUStaticInst::GlobalSegment); 98111692Santhony.gutierrez@amd.com 98211692Santhony.gutierrez@amd.com /** 98311692Santhony.gutierrez@amd.com * A memory fence that has scope for 98411692Santhony.gutierrez@amd.com * both segments will use the global 98511692Santhony.gutierrez@amd.com * segment, and be executed in the 98611692Santhony.gutierrez@amd.com * global memory pipeline, therefore, 98711692Santhony.gutierrez@amd.com * we set the segment to match the 98811692Santhony.gutierrez@amd.com * global scope only 98911692Santhony.gutierrez@amd.com */ 99011692Santhony.gutierrez@amd.com switch (memFenceScopeSegGlobal) { 99111692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_NONE: 99211692Santhony.gutierrez@amd.com setFlag(NoScope); 99311692Santhony.gutierrez@amd.com break; 99411692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_WORKITEM: 99511692Santhony.gutierrez@amd.com setFlag(WorkitemScope); 99611692Santhony.gutierrez@amd.com break; 99711692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_WORKGROUP: 99811692Santhony.gutierrez@amd.com setFlag(WorkgroupScope); 99911692Santhony.gutierrez@amd.com break; 100011692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_AGENT: 100111692Santhony.gutierrez@amd.com setFlag(DeviceScope); 100211692Santhony.gutierrez@amd.com break; 100311692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_SYSTEM: 100411692Santhony.gutierrez@amd.com setFlag(SystemScope); 100511692Santhony.gutierrez@amd.com break; 100611692Santhony.gutierrez@amd.com default: 100711692Santhony.gutierrez@amd.com fatal("MemFence has bad global scope type\n"); 100811692Santhony.gutierrez@amd.com } 100911308Santhony.gutierrez@amd.com } else if (memFenceScopeSegGlobal != Brig::BRIG_MEMORY_SCOPE_NONE) { 101011692Santhony.gutierrez@amd.com setFlag(GPUStaticInst::GlobalSegment); 101111692Santhony.gutierrez@amd.com 101211692Santhony.gutierrez@amd.com switch (memFenceScopeSegGlobal) { 101311692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_NONE: 101411692Santhony.gutierrez@amd.com setFlag(NoScope); 101511692Santhony.gutierrez@amd.com break; 101611692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_WORKITEM: 101711692Santhony.gutierrez@amd.com setFlag(WorkitemScope); 101811692Santhony.gutierrez@amd.com break; 101911692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_WORKGROUP: 102011692Santhony.gutierrez@amd.com setFlag(WorkgroupScope); 102111692Santhony.gutierrez@amd.com break; 102211692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_AGENT: 102311692Santhony.gutierrez@amd.com setFlag(DeviceScope); 102411692Santhony.gutierrez@amd.com break; 102511692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_SYSTEM: 102611692Santhony.gutierrez@amd.com setFlag(SystemScope); 102711692Santhony.gutierrez@amd.com break; 102811692Santhony.gutierrez@amd.com default: 102911692Santhony.gutierrez@amd.com fatal("MemFence has bad global scope type\n"); 103011692Santhony.gutierrez@amd.com } 103111308Santhony.gutierrez@amd.com } else if (memFenceScopeSegGroup != Brig::BRIG_MEMORY_SCOPE_NONE) { 103211692Santhony.gutierrez@amd.com setFlag(GPUStaticInst::GroupSegment); 103311692Santhony.gutierrez@amd.com 103411692Santhony.gutierrez@amd.com switch (memFenceScopeSegGroup) { 103511692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_NONE: 103611692Santhony.gutierrez@amd.com setFlag(NoScope); 103711692Santhony.gutierrez@amd.com break; 103811692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_WORKITEM: 103911692Santhony.gutierrez@amd.com setFlag(WorkitemScope); 104011692Santhony.gutierrez@amd.com break; 104111692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_WORKGROUP: 104211692Santhony.gutierrez@amd.com setFlag(WorkgroupScope); 104311692Santhony.gutierrez@amd.com break; 104411692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_AGENT: 104511692Santhony.gutierrez@amd.com setFlag(DeviceScope); 104611692Santhony.gutierrez@amd.com break; 104711692Santhony.gutierrez@amd.com case Brig::BRIG_MEMORY_SCOPE_SYSTEM: 104811692Santhony.gutierrez@amd.com setFlag(SystemScope); 104911692Santhony.gutierrez@amd.com break; 105011692Santhony.gutierrez@amd.com default: 105111692Santhony.gutierrez@amd.com fatal("MemFence has bad group scope type\n"); 105211692Santhony.gutierrez@amd.com } 105311308Santhony.gutierrez@amd.com } else { 105411308Santhony.gutierrez@amd.com fatal("MemFence constructor: bad scope specifiers\n"); 105511308Santhony.gutierrez@amd.com } 105611308Santhony.gutierrez@amd.com } 105711308Santhony.gutierrez@amd.com 105811308Santhony.gutierrez@amd.com void 105911308Santhony.gutierrez@amd.com initiateAcc(GPUDynInstPtr gpuDynInst) 106011308Santhony.gutierrez@amd.com { 106111308Santhony.gutierrez@amd.com Wavefront *wave = gpuDynInst->wavefront(); 106211308Santhony.gutierrez@amd.com wave->computeUnit->injectGlobalMemFence(gpuDynInst); 106311308Santhony.gutierrez@amd.com } 106411308Santhony.gutierrez@amd.com 106511308Santhony.gutierrez@amd.com void 106611308Santhony.gutierrez@amd.com execute(GPUDynInstPtr gpuDynInst) 106711308Santhony.gutierrez@amd.com { 106811308Santhony.gutierrez@amd.com Wavefront *w = gpuDynInst->wavefront(); 106911308Santhony.gutierrez@amd.com // 2 cases: 107011308Santhony.gutierrez@amd.com // * memfence to a sequentially consistent memory (e.g., LDS). 107111308Santhony.gutierrez@amd.com // These can be handled as no-ops. 107211308Santhony.gutierrez@amd.com // * memfence to a relaxed consistency cache (e.g., Hermes, Viper, 107311308Santhony.gutierrez@amd.com // etc.). We send a packet, tagged with the memory order and 107411308Santhony.gutierrez@amd.com // scope, and let the GPU coalescer handle it. 107511308Santhony.gutierrez@amd.com 107611692Santhony.gutierrez@amd.com if (isGlobalSeg()) { 107711308Santhony.gutierrez@amd.com gpuDynInst->simdId = w->simdId; 107811308Santhony.gutierrez@amd.com gpuDynInst->wfSlotId = w->wfSlotId; 107911308Santhony.gutierrez@amd.com gpuDynInst->wfDynId = w->wfDynId; 108011639Salexandru.dutu@amd.com gpuDynInst->kern_id = w->kernId; 108111308Santhony.gutierrez@amd.com gpuDynInst->cu_id = w->computeUnit->cu_id; 108211308Santhony.gutierrez@amd.com 108311308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 108411308Santhony.gutierrez@amd.com GlobalMemPipeline* gmp = &(w->computeUnit->globalMemoryPipe); 108511308Santhony.gutierrez@amd.com gmp->getGMReqFIFO().push(gpuDynInst); 108611308Santhony.gutierrez@amd.com 108711639Salexandru.dutu@amd.com w->wrGmReqsInPipe--; 108811639Salexandru.dutu@amd.com w->rdGmReqsInPipe--; 108911639Salexandru.dutu@amd.com w->memReqsInPipe--; 109011639Salexandru.dutu@amd.com w->outstandingReqs++; 109111692Santhony.gutierrez@amd.com } else if (isGroupSeg()) { 109211308Santhony.gutierrez@amd.com // no-op 109311308Santhony.gutierrez@amd.com } else { 109411692Santhony.gutierrez@amd.com fatal("MemFence execute: bad op type\n"); 109511308Santhony.gutierrez@amd.com } 109611308Santhony.gutierrez@amd.com } 109711308Santhony.gutierrez@amd.com }; 109811308Santhony.gutierrez@amd.com 109911308Santhony.gutierrez@amd.com class Call : public HsailGPUStaticInst 110011308Santhony.gutierrez@amd.com { 110111308Santhony.gutierrez@amd.com public: 110211308Santhony.gutierrez@amd.com // private helper functions 110311308Santhony.gutierrez@amd.com void calcAddr(Wavefront* w, GPUDynInstPtr m); 110411308Santhony.gutierrez@amd.com 110511308Santhony.gutierrez@amd.com void 110611308Santhony.gutierrez@amd.com generateDisassembly() 110711308Santhony.gutierrez@amd.com { 110811308Santhony.gutierrez@amd.com if (dest.disassemble() == "") { 110911308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s (%s)", opcode, src0.disassemble(), 111011308Santhony.gutierrez@amd.com src1.disassemble()); 111111308Santhony.gutierrez@amd.com } else { 111211308Santhony.gutierrez@amd.com disassembly = csprintf("%s %s (%s) (%s)", opcode, 111311308Santhony.gutierrez@amd.com src0.disassemble(), dest.disassemble(), 111411308Santhony.gutierrez@amd.com src1.disassemble()); 111511308Santhony.gutierrez@amd.com } 111611308Santhony.gutierrez@amd.com } 111711308Santhony.gutierrez@amd.com 111811308Santhony.gutierrez@amd.com bool 111911308Santhony.gutierrez@amd.com isPseudoOp() 112011308Santhony.gutierrez@amd.com { 112111308Santhony.gutierrez@amd.com std::string func_name = src0.disassemble(); 112211308Santhony.gutierrez@amd.com if (func_name.find("__gem5_hsail_op") != std::string::npos) { 112311308Santhony.gutierrez@amd.com return true; 112411308Santhony.gutierrez@amd.com } 112511308Santhony.gutierrez@amd.com return false; 112611308Santhony.gutierrez@amd.com } 112711308Santhony.gutierrez@amd.com 112811308Santhony.gutierrez@amd.com // member variables 112911308Santhony.gutierrez@amd.com ListOperand dest; 113011308Santhony.gutierrez@amd.com FunctionRefOperand src0; 113111308Santhony.gutierrez@amd.com ListOperand src1; 113211308Santhony.gutierrez@amd.com HsailCode *func_ptr; 113311308Santhony.gutierrez@amd.com 113411308Santhony.gutierrez@amd.com // exec function for pseudo instructions mapped on top of call opcode 113511308Santhony.gutierrez@amd.com void execPseudoInst(Wavefront *w, GPUDynInstPtr gpuDynInst); 113611308Santhony.gutierrez@amd.com 113711308Santhony.gutierrez@amd.com // user-defined pseudo instructions 113811308Santhony.gutierrez@amd.com void MagicPrintLane(Wavefront *w); 113911308Santhony.gutierrez@amd.com void MagicPrintLane64(Wavefront *w); 114011308Santhony.gutierrez@amd.com void MagicPrintWF32(Wavefront *w); 114111308Santhony.gutierrez@amd.com void MagicPrintWF64(Wavefront *w); 114211308Santhony.gutierrez@amd.com void MagicPrintWFFloat(Wavefront *w); 114311308Santhony.gutierrez@amd.com void MagicSimBreak(Wavefront *w); 114411308Santhony.gutierrez@amd.com void MagicPrefixSum(Wavefront *w); 114511308Santhony.gutierrez@amd.com void MagicReduction(Wavefront *w); 114611308Santhony.gutierrez@amd.com void MagicMaskLower(Wavefront *w); 114711308Santhony.gutierrez@amd.com void MagicMaskUpper(Wavefront *w); 114811308Santhony.gutierrez@amd.com void MagicJoinWFBar(Wavefront *w); 114911308Santhony.gutierrez@amd.com void MagicWaitWFBar(Wavefront *w); 115011308Santhony.gutierrez@amd.com void MagicPanic(Wavefront *w); 115111308Santhony.gutierrez@amd.com 115211308Santhony.gutierrez@amd.com void MagicAtomicNRAddGlobalU32Reg(Wavefront *w, 115311308Santhony.gutierrez@amd.com GPUDynInstPtr gpuDynInst); 115411308Santhony.gutierrez@amd.com 115511308Santhony.gutierrez@amd.com void MagicAtomicNRAddGroupU32Reg(Wavefront *w, 115611308Santhony.gutierrez@amd.com GPUDynInstPtr gpuDynInst); 115711308Santhony.gutierrez@amd.com 115811308Santhony.gutierrez@amd.com void MagicLoadGlobalU32Reg(Wavefront *w, GPUDynInstPtr gpuDynInst); 115911308Santhony.gutierrez@amd.com 116011308Santhony.gutierrez@amd.com void MagicXactCasLd(Wavefront *w); 116111308Santhony.gutierrez@amd.com void MagicMostSigThread(Wavefront *w); 116211308Santhony.gutierrez@amd.com void MagicMostSigBroadcast(Wavefront *w); 116311308Santhony.gutierrez@amd.com 116411308Santhony.gutierrez@amd.com void MagicPrintWF32ID(Wavefront *w); 116511308Santhony.gutierrez@amd.com void MagicPrintWFID64(Wavefront *w); 116611308Santhony.gutierrez@amd.com 116711308Santhony.gutierrez@amd.com Call(const Brig::BrigInstBase *ib, const BrigObject *obj) 116811308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, "call") 116911308Santhony.gutierrez@amd.com { 117011692Santhony.gutierrez@amd.com setFlag(ALU); 117111308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 117211308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 117311308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 117411308Santhony.gutierrez@amd.com src0.init(op_offs, obj); 117511308Santhony.gutierrez@amd.com 117611308Santhony.gutierrez@amd.com func_ptr = nullptr; 117711308Santhony.gutierrez@amd.com std::string func_name = src0.disassemble(); 117811308Santhony.gutierrez@amd.com if (!isPseudoOp()) { 117911308Santhony.gutierrez@amd.com func_ptr = dynamic_cast<HsailCode*>(obj-> 118011308Santhony.gutierrez@amd.com getFunction(func_name)); 118111308Santhony.gutierrez@amd.com 118211308Santhony.gutierrez@amd.com if (!func_ptr) 118311308Santhony.gutierrez@amd.com fatal("call::exec cannot find function: %s\n", func_name); 118411308Santhony.gutierrez@amd.com } 118511308Santhony.gutierrez@amd.com 118611308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 2); 118711308Santhony.gutierrez@amd.com src1.init(op_offs, obj); 118811308Santhony.gutierrez@amd.com } 118911308Santhony.gutierrez@amd.com 119011308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) { return false; } 119111308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) { return false; } 119211308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) { return false; } 119311308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) { return false; } 119411308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) { return false; } 119511699Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) { return 0; } 119611699Santhony.gutierrez@amd.com 119711699Santhony.gutierrez@amd.com int 119811699Santhony.gutierrez@amd.com getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) 119911699Santhony.gutierrez@amd.com { 120011699Santhony.gutierrez@amd.com return -1; 120111699Santhony.gutierrez@amd.com } 120211308Santhony.gutierrez@amd.com 120311308Santhony.gutierrez@amd.com void 120411308Santhony.gutierrez@amd.com execute(GPUDynInstPtr gpuDynInst) 120511308Santhony.gutierrez@amd.com { 120611308Santhony.gutierrez@amd.com Wavefront *w = gpuDynInst->wavefront(); 120711308Santhony.gutierrez@amd.com 120811308Santhony.gutierrez@amd.com std::string func_name = src0.disassemble(); 120911308Santhony.gutierrez@amd.com if (isPseudoOp()) { 121011308Santhony.gutierrez@amd.com execPseudoInst(w, gpuDynInst); 121111308Santhony.gutierrez@amd.com } else { 121211308Santhony.gutierrez@amd.com fatal("Native HSAIL functions are not yet implemented: %s\n", 121311308Santhony.gutierrez@amd.com func_name); 121411308Santhony.gutierrez@amd.com } 121511308Santhony.gutierrez@amd.com } 121611308Santhony.gutierrez@amd.com int numSrcRegOperands() { return 0; } 121711308Santhony.gutierrez@amd.com int numDstRegOperands() { return 0; } 121811308Santhony.gutierrez@amd.com int getNumOperands() { return 2; } 121911308Santhony.gutierrez@amd.com }; 122011308Santhony.gutierrez@amd.com 122111308Santhony.gutierrez@amd.com template<typename T> T heynot(T arg) { return ~arg; } 122211308Santhony.gutierrez@amd.com template<> inline bool heynot<bool>(bool arg) { return !arg; } 122311308Santhony.gutierrez@amd.com} // namespace HsailISA 122411308Santhony.gutierrez@amd.com 122511308Santhony.gutierrez@amd.com#endif // __ARCH_HSAIL_INSTS_DECL_HH__ 1226