mem.hh revision 11534
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_MEM_HH__ 3711308Santhony.gutierrez@amd.com#define __ARCH_HSAIL_INSTS_MEM_HH__ 3811308Santhony.gutierrez@amd.com 3911308Santhony.gutierrez@amd.com#include "arch/hsail/insts/decl.hh" 4011308Santhony.gutierrez@amd.com#include "arch/hsail/insts/gpu_static_inst.hh" 4111308Santhony.gutierrez@amd.com#include "arch/hsail/operand.hh" 4211308Santhony.gutierrez@amd.com 4311308Santhony.gutierrez@amd.comnamespace HsailISA 4411308Santhony.gutierrez@amd.com{ 4511308Santhony.gutierrez@amd.com class MemInst 4611308Santhony.gutierrez@amd.com { 4711308Santhony.gutierrez@amd.com public: 4811308Santhony.gutierrez@amd.com MemInst() : size(0), addr_operand(nullptr) { } 4911308Santhony.gutierrez@amd.com 5011308Santhony.gutierrez@amd.com MemInst(Enums::MemType m_type) 5111308Santhony.gutierrez@amd.com { 5211308Santhony.gutierrez@amd.com if (m_type == Enums::M_U64 || 5311308Santhony.gutierrez@amd.com m_type == Enums::M_S64 || 5411308Santhony.gutierrez@amd.com m_type == Enums::M_F64) { 5511308Santhony.gutierrez@amd.com size = 8; 5611308Santhony.gutierrez@amd.com } else if (m_type == Enums::M_U32 || 5711308Santhony.gutierrez@amd.com m_type == Enums::M_S32 || 5811308Santhony.gutierrez@amd.com m_type == Enums::M_F32) { 5911308Santhony.gutierrez@amd.com size = 4; 6011308Santhony.gutierrez@amd.com } else if (m_type == Enums::M_U16 || 6111308Santhony.gutierrez@amd.com m_type == Enums::M_S16 || 6211308Santhony.gutierrez@amd.com m_type == Enums::M_F16) { 6311308Santhony.gutierrez@amd.com size = 2; 6411308Santhony.gutierrez@amd.com } else { 6511308Santhony.gutierrez@amd.com size = 1; 6611308Santhony.gutierrez@amd.com } 6711308Santhony.gutierrez@amd.com 6811308Santhony.gutierrez@amd.com addr_operand = nullptr; 6911308Santhony.gutierrez@amd.com } 7011308Santhony.gutierrez@amd.com 7111308Santhony.gutierrez@amd.com void 7211308Santhony.gutierrez@amd.com init_addr(AddrOperandBase *_addr_operand) 7311308Santhony.gutierrez@amd.com { 7411308Santhony.gutierrez@amd.com addr_operand = _addr_operand; 7511308Santhony.gutierrez@amd.com } 7611308Santhony.gutierrez@amd.com 7711308Santhony.gutierrez@amd.com private: 7811308Santhony.gutierrez@amd.com int size; 7911308Santhony.gutierrez@amd.com AddrOperandBase *addr_operand; 8011308Santhony.gutierrez@amd.com 8111308Santhony.gutierrez@amd.com public: 8211308Santhony.gutierrez@amd.com int getMemOperandSize() { return size; } 8311308Santhony.gutierrez@amd.com AddrOperandBase *getAddressOperand() { return addr_operand; } 8411308Santhony.gutierrez@amd.com }; 8511308Santhony.gutierrez@amd.com 8611308Santhony.gutierrez@amd.com template<typename DestOperandType, typename AddrOperandType> 8711308Santhony.gutierrez@amd.com class LdaInstBase : public HsailGPUStaticInst 8811308Santhony.gutierrez@amd.com { 8911308Santhony.gutierrez@amd.com public: 9011308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 9111308Santhony.gutierrez@amd.com AddrOperandType addr; 9211308Santhony.gutierrez@amd.com 9311308Santhony.gutierrez@amd.com LdaInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, 9411308Santhony.gutierrez@amd.com const char *_opcode) 9511308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 9611308Santhony.gutierrez@amd.com { 9711308Santhony.gutierrez@amd.com using namespace Brig; 9811308Santhony.gutierrez@amd.com 9911308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 10011308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 10111308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 10211308Santhony.gutierrez@amd.com addr.init(op_offs, obj); 10311308Santhony.gutierrez@amd.com } 10411308Santhony.gutierrez@amd.com 10511347Sandreas.hansson@arm.com int numSrcRegOperands() override 10611347Sandreas.hansson@arm.com { return(this->addr.isVectorRegister()); } 10711347Sandreas.hansson@arm.com int numDstRegOperands() override 10811347Sandreas.hansson@arm.com { return dest.isVectorRegister(); } 10911347Sandreas.hansson@arm.com bool isVectorRegister(int operandIndex) override 11011308Santhony.gutierrez@amd.com { 11111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 11211308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.isVectorRegister() : 11311308Santhony.gutierrez@amd.com this->addr.isVectorRegister()); 11411308Santhony.gutierrez@amd.com } 11511347Sandreas.hansson@arm.com bool isCondRegister(int operandIndex) override 11611308Santhony.gutierrez@amd.com { 11711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 11811308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.isCondRegister() : 11911308Santhony.gutierrez@amd.com this->addr.isCondRegister()); 12011308Santhony.gutierrez@amd.com } 12111347Sandreas.hansson@arm.com bool isScalarRegister(int operandIndex) override 12211308Santhony.gutierrez@amd.com { 12311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 12411308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.isScalarRegister() : 12511308Santhony.gutierrez@amd.com this->addr.isScalarRegister()); 12611308Santhony.gutierrez@amd.com } 12711347Sandreas.hansson@arm.com bool isSrcOperand(int operandIndex) override 12811308Santhony.gutierrez@amd.com { 12911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 13011308Santhony.gutierrez@amd.com if (operandIndex > 0) 13111308Santhony.gutierrez@amd.com return(this->addr.isVectorRegister()); 13211308Santhony.gutierrez@amd.com return false; 13311308Santhony.gutierrez@amd.com } 13411347Sandreas.hansson@arm.com bool isDstOperand(int operandIndex) override { 13511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 13611308Santhony.gutierrez@amd.com return(operandIndex == 0); 13711308Santhony.gutierrez@amd.com } 13811347Sandreas.hansson@arm.com int getOperandSize(int operandIndex) override 13911308Santhony.gutierrez@amd.com { 14011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 14111308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.opSize() : 14211308Santhony.gutierrez@amd.com this->addr.opSize()); 14311308Santhony.gutierrez@amd.com } 14411347Sandreas.hansson@arm.com int getRegisterIndex(int operandIndex) override 14511308Santhony.gutierrez@amd.com { 14611308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 14711308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.regIndex() : 14811308Santhony.gutierrez@amd.com this->addr.regIndex()); 14911308Santhony.gutierrez@amd.com } 15011347Sandreas.hansson@arm.com int getNumOperands() override 15111308Santhony.gutierrez@amd.com { 15211308Santhony.gutierrez@amd.com if (this->addr.isVectorRegister()) 15311308Santhony.gutierrez@amd.com return 2; 15411308Santhony.gutierrez@amd.com return 1; 15511308Santhony.gutierrez@amd.com } 15611308Santhony.gutierrez@amd.com }; 15711308Santhony.gutierrez@amd.com 15811308Santhony.gutierrez@amd.com template<typename DestDataType, typename AddrOperandType> 15911308Santhony.gutierrez@amd.com class LdaInst : 16011308Santhony.gutierrez@amd.com public LdaInstBase<typename DestDataType::OperandType, AddrOperandType>, 16111308Santhony.gutierrez@amd.com public MemInst 16211308Santhony.gutierrez@amd.com { 16311308Santhony.gutierrez@amd.com public: 16411308Santhony.gutierrez@amd.com void generateDisassembly(); 16511308Santhony.gutierrez@amd.com 16611308Santhony.gutierrez@amd.com LdaInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 16711308Santhony.gutierrez@amd.com const char *_opcode) 16811308Santhony.gutierrez@amd.com : LdaInstBase<typename DestDataType::OperandType, 16911308Santhony.gutierrez@amd.com AddrOperandType>(ib, obj, _opcode) 17011308Santhony.gutierrez@amd.com { 17111308Santhony.gutierrez@amd.com init_addr(&this->addr); 17211308Santhony.gutierrez@amd.com } 17311308Santhony.gutierrez@amd.com 17411308Santhony.gutierrez@amd.com void execute(GPUDynInstPtr gpuDynInst); 17511308Santhony.gutierrez@amd.com }; 17611308Santhony.gutierrez@amd.com 17711308Santhony.gutierrez@amd.com template<typename DataType> 17811308Santhony.gutierrez@amd.com GPUStaticInst* 17911308Santhony.gutierrez@amd.com decodeLda(const Brig::BrigInstBase *ib, const BrigObject *obj) 18011308Santhony.gutierrez@amd.com { 18111308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 1); 18211308Santhony.gutierrez@amd.com BrigRegOperandInfo regDataType = findRegDataType(op_offs, obj); 18311308Santhony.gutierrez@amd.com 18411308Santhony.gutierrez@amd.com if (regDataType.kind == Brig::BRIG_KIND_OPERAND_ADDRESS) { 18511308Santhony.gutierrez@amd.com return new LdaInst<DataType, NoRegAddrOperand>(ib, obj, "ldas"); 18611308Santhony.gutierrez@amd.com } else if (regDataType.kind == Brig::BRIG_KIND_OPERAND_REGISTER) { 18711308Santhony.gutierrez@amd.com // V2/V4 not allowed 18811308Santhony.gutierrez@amd.com switch (regDataType.regKind) { 18911308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_SINGLE: 19011308Santhony.gutierrez@amd.com return new LdaInst<DataType, SRegAddrOperand>(ib, obj, "ldas"); 19111308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_DOUBLE: 19211308Santhony.gutierrez@amd.com return new LdaInst<DataType, DRegAddrOperand>(ib, obj, "ldas"); 19311308Santhony.gutierrez@amd.com default: 19411308Santhony.gutierrez@amd.com fatal("Bad ldas register operand type %d\n", regDataType.type); 19511308Santhony.gutierrez@amd.com } 19611308Santhony.gutierrez@amd.com } else { 19711308Santhony.gutierrez@amd.com fatal("Bad ldas register operand kind %d\n", regDataType.kind); 19811308Santhony.gutierrez@amd.com } 19911308Santhony.gutierrez@amd.com } 20011308Santhony.gutierrez@amd.com 20111308Santhony.gutierrez@amd.com template<typename MemOperandType, typename DestOperandType, 20211308Santhony.gutierrez@amd.com typename AddrOperandType> 20311308Santhony.gutierrez@amd.com class LdInstBase : public HsailGPUStaticInst 20411308Santhony.gutierrez@amd.com { 20511308Santhony.gutierrez@amd.com public: 20611308Santhony.gutierrez@amd.com Brig::BrigWidth8_t width; 20711308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 20811308Santhony.gutierrez@amd.com AddrOperandType addr; 20911308Santhony.gutierrez@amd.com 21011308Santhony.gutierrez@amd.com Brig::BrigSegment segment; 21111308Santhony.gutierrez@amd.com Brig::BrigMemoryOrder memoryOrder; 21211308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memoryScope; 21311308Santhony.gutierrez@amd.com unsigned int equivClass; 21411308Santhony.gutierrez@amd.com bool isArgLoad() 21511308Santhony.gutierrez@amd.com { 21611308Santhony.gutierrez@amd.com return segment == Brig::BRIG_SEGMENT_KERNARG || 21711308Santhony.gutierrez@amd.com segment == Brig::BRIG_SEGMENT_ARG; 21811308Santhony.gutierrez@amd.com } 21911308Santhony.gutierrez@amd.com void 22011308Santhony.gutierrez@amd.com initLd(const Brig::BrigInstBase *ib, const BrigObject *obj, 22111308Santhony.gutierrez@amd.com const char *_opcode) 22211308Santhony.gutierrez@amd.com { 22311308Santhony.gutierrez@amd.com using namespace Brig; 22411308Santhony.gutierrez@amd.com 22511308Santhony.gutierrez@amd.com const BrigInstMem *ldst = (const BrigInstMem*)ib; 22611308Santhony.gutierrez@amd.com 22711308Santhony.gutierrez@amd.com segment = (BrigSegment)ldst->segment; 22811308Santhony.gutierrez@amd.com memoryOrder = BRIG_MEMORY_ORDER_NONE; 22911308Santhony.gutierrez@amd.com memoryScope = BRIG_MEMORY_SCOPE_NONE; 23011308Santhony.gutierrez@amd.com equivClass = ldst->equivClass; 23111308Santhony.gutierrez@amd.com 23211308Santhony.gutierrez@amd.com switch (segment) { 23311308Santhony.gutierrez@amd.com case BRIG_SEGMENT_GLOBAL: 23411308Santhony.gutierrez@amd.com o_type = Enums::OT_GLOBAL_READ; 23511308Santhony.gutierrez@amd.com break; 23611308Santhony.gutierrez@amd.com 23711308Santhony.gutierrez@amd.com case BRIG_SEGMENT_GROUP: 23811308Santhony.gutierrez@amd.com o_type = Enums::OT_SHARED_READ; 23911308Santhony.gutierrez@amd.com break; 24011308Santhony.gutierrez@amd.com 24111308Santhony.gutierrez@amd.com case BRIG_SEGMENT_PRIVATE: 24211308Santhony.gutierrez@amd.com o_type = Enums::OT_PRIVATE_READ; 24311308Santhony.gutierrez@amd.com break; 24411308Santhony.gutierrez@amd.com 24511308Santhony.gutierrez@amd.com case BRIG_SEGMENT_READONLY: 24611308Santhony.gutierrez@amd.com o_type = Enums::OT_READONLY_READ; 24711308Santhony.gutierrez@amd.com break; 24811308Santhony.gutierrez@amd.com 24911308Santhony.gutierrez@amd.com case BRIG_SEGMENT_SPILL: 25011308Santhony.gutierrez@amd.com o_type = Enums::OT_SPILL_READ; 25111308Santhony.gutierrez@amd.com break; 25211308Santhony.gutierrez@amd.com 25311308Santhony.gutierrez@amd.com case BRIG_SEGMENT_FLAT: 25411308Santhony.gutierrez@amd.com o_type = Enums::OT_FLAT_READ; 25511308Santhony.gutierrez@amd.com break; 25611308Santhony.gutierrez@amd.com 25711308Santhony.gutierrez@amd.com case BRIG_SEGMENT_KERNARG: 25811308Santhony.gutierrez@amd.com o_type = Enums::OT_KERN_READ; 25911308Santhony.gutierrez@amd.com break; 26011308Santhony.gutierrez@amd.com 26111308Santhony.gutierrez@amd.com case BRIG_SEGMENT_ARG: 26211308Santhony.gutierrez@amd.com o_type = Enums::OT_ARG; 26311308Santhony.gutierrez@amd.com break; 26411308Santhony.gutierrez@amd.com 26511308Santhony.gutierrez@amd.com default: 26611308Santhony.gutierrez@amd.com panic("Ld: segment %d not supported\n", segment); 26711308Santhony.gutierrez@amd.com } 26811308Santhony.gutierrez@amd.com 26911308Santhony.gutierrez@amd.com width = ldst->width; 27011308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 27111308Santhony.gutierrez@amd.com const Brig::BrigOperand *brigOp = obj->getOperand(op_offs); 27211308Santhony.gutierrez@amd.com if (brigOp->kind == BRIG_KIND_OPERAND_REGISTER) 27311308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 27411308Santhony.gutierrez@amd.com 27511308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 27611308Santhony.gutierrez@amd.com addr.init(op_offs, obj); 27711308Santhony.gutierrez@amd.com } 27811308Santhony.gutierrez@amd.com 27911308Santhony.gutierrez@amd.com void 28011308Santhony.gutierrez@amd.com initAtomicLd(const Brig::BrigInstBase *ib, const BrigObject *obj, 28111308Santhony.gutierrez@amd.com const char *_opcode) 28211308Santhony.gutierrez@amd.com { 28311308Santhony.gutierrez@amd.com using namespace Brig; 28411308Santhony.gutierrez@amd.com 28511308Santhony.gutierrez@amd.com const BrigInstAtomic *at = (const BrigInstAtomic*)ib; 28611308Santhony.gutierrez@amd.com 28711308Santhony.gutierrez@amd.com segment = (BrigSegment)at->segment; 28811308Santhony.gutierrez@amd.com memoryOrder = (BrigMemoryOrder)at->memoryOrder; 28911308Santhony.gutierrez@amd.com memoryScope = (BrigMemoryScope)at->memoryScope; 29011308Santhony.gutierrez@amd.com equivClass = 0; 29111308Santhony.gutierrez@amd.com 29211308Santhony.gutierrez@amd.com switch (segment) { 29311308Santhony.gutierrez@amd.com case BRIG_SEGMENT_GLOBAL: 29411308Santhony.gutierrez@amd.com o_type = Enums::OT_GLOBAL_READ; 29511308Santhony.gutierrez@amd.com break; 29611308Santhony.gutierrez@amd.com 29711308Santhony.gutierrez@amd.com case BRIG_SEGMENT_GROUP: 29811308Santhony.gutierrez@amd.com o_type = Enums::OT_SHARED_READ; 29911308Santhony.gutierrez@amd.com break; 30011308Santhony.gutierrez@amd.com 30111308Santhony.gutierrez@amd.com case BRIG_SEGMENT_PRIVATE: 30211308Santhony.gutierrez@amd.com o_type = Enums::OT_PRIVATE_READ; 30311308Santhony.gutierrez@amd.com break; 30411308Santhony.gutierrez@amd.com 30511308Santhony.gutierrez@amd.com case BRIG_SEGMENT_READONLY: 30611308Santhony.gutierrez@amd.com o_type = Enums::OT_READONLY_READ; 30711308Santhony.gutierrez@amd.com break; 30811308Santhony.gutierrez@amd.com 30911308Santhony.gutierrez@amd.com case BRIG_SEGMENT_SPILL: 31011308Santhony.gutierrez@amd.com o_type = Enums::OT_SPILL_READ; 31111308Santhony.gutierrez@amd.com break; 31211308Santhony.gutierrez@amd.com 31311308Santhony.gutierrez@amd.com case BRIG_SEGMENT_FLAT: 31411308Santhony.gutierrez@amd.com o_type = Enums::OT_FLAT_READ; 31511308Santhony.gutierrez@amd.com break; 31611308Santhony.gutierrez@amd.com 31711308Santhony.gutierrez@amd.com case BRIG_SEGMENT_KERNARG: 31811308Santhony.gutierrez@amd.com o_type = Enums::OT_KERN_READ; 31911308Santhony.gutierrez@amd.com break; 32011308Santhony.gutierrez@amd.com 32111308Santhony.gutierrez@amd.com case BRIG_SEGMENT_ARG: 32211308Santhony.gutierrez@amd.com o_type = Enums::OT_ARG; 32311308Santhony.gutierrez@amd.com break; 32411308Santhony.gutierrez@amd.com 32511308Santhony.gutierrez@amd.com default: 32611308Santhony.gutierrez@amd.com panic("Ld: segment %d not supported\n", segment); 32711308Santhony.gutierrez@amd.com } 32811308Santhony.gutierrez@amd.com 32911308Santhony.gutierrez@amd.com width = BRIG_WIDTH_1; 33011308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 33111308Santhony.gutierrez@amd.com const Brig::BrigOperand *brigOp = obj->getOperand(op_offs); 33211308Santhony.gutierrez@amd.com 33311308Santhony.gutierrez@amd.com if (brigOp->kind == BRIG_KIND_OPERAND_REGISTER) 33411308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 33511308Santhony.gutierrez@amd.com 33611308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands,1); 33711308Santhony.gutierrez@amd.com addr.init(op_offs, obj); 33811308Santhony.gutierrez@amd.com } 33911308Santhony.gutierrez@amd.com 34011308Santhony.gutierrez@amd.com LdInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, 34111308Santhony.gutierrez@amd.com const char *_opcode) 34211308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 34311308Santhony.gutierrez@amd.com { 34411308Santhony.gutierrez@amd.com using namespace Brig; 34511308Santhony.gutierrez@amd.com 34611308Santhony.gutierrez@amd.com if (ib->opcode == BRIG_OPCODE_LD) { 34711308Santhony.gutierrez@amd.com initLd(ib, obj, _opcode); 34811308Santhony.gutierrez@amd.com } else { 34911308Santhony.gutierrez@amd.com initAtomicLd(ib, obj, _opcode); 35011308Santhony.gutierrez@amd.com } 35111308Santhony.gutierrez@amd.com } 35211308Santhony.gutierrez@amd.com 35311347Sandreas.hansson@arm.com int numSrcRegOperands() override 35411347Sandreas.hansson@arm.com { return(this->addr.isVectorRegister()); } 35511347Sandreas.hansson@arm.com int numDstRegOperands() override { return dest.isVectorRegister(); } 35611347Sandreas.hansson@arm.com int getNumOperands() override 35711308Santhony.gutierrez@amd.com { 35811308Santhony.gutierrez@amd.com if (this->addr.isVectorRegister()) 35911308Santhony.gutierrez@amd.com return 2; 36011308Santhony.gutierrez@amd.com else 36111308Santhony.gutierrez@amd.com return 1; 36211308Santhony.gutierrez@amd.com } 36311347Sandreas.hansson@arm.com bool isVectorRegister(int operandIndex) override 36411308Santhony.gutierrez@amd.com { 36511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 36611308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.isVectorRegister() : 36711308Santhony.gutierrez@amd.com this->addr.isVectorRegister()); 36811308Santhony.gutierrez@amd.com } 36911347Sandreas.hansson@arm.com bool isCondRegister(int operandIndex) override 37011308Santhony.gutierrez@amd.com { 37111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 37211308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.isCondRegister() : 37311308Santhony.gutierrez@amd.com this->addr.isCondRegister()); 37411308Santhony.gutierrez@amd.com } 37511347Sandreas.hansson@arm.com bool isScalarRegister(int operandIndex) override 37611308Santhony.gutierrez@amd.com { 37711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 37811308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.isScalarRegister() : 37911308Santhony.gutierrez@amd.com this->addr.isScalarRegister()); 38011308Santhony.gutierrez@amd.com } 38111347Sandreas.hansson@arm.com bool isSrcOperand(int operandIndex) override 38211308Santhony.gutierrez@amd.com { 38311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 38411308Santhony.gutierrez@amd.com if (operandIndex > 0) 38511308Santhony.gutierrez@amd.com return(this->addr.isVectorRegister()); 38611308Santhony.gutierrez@amd.com return false; 38711308Santhony.gutierrez@amd.com } 38811347Sandreas.hansson@arm.com bool isDstOperand(int operandIndex) override 38911308Santhony.gutierrez@amd.com { 39011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 39111308Santhony.gutierrez@amd.com return(operandIndex == 0); 39211308Santhony.gutierrez@amd.com } 39311347Sandreas.hansson@arm.com int getOperandSize(int operandIndex) override 39411308Santhony.gutierrez@amd.com { 39511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 39611308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.opSize() : 39711308Santhony.gutierrez@amd.com this->addr.opSize()); 39811308Santhony.gutierrez@amd.com } 39911347Sandreas.hansson@arm.com int getRegisterIndex(int operandIndex) override 40011308Santhony.gutierrez@amd.com { 40111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 40211308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.regIndex() : 40311308Santhony.gutierrez@amd.com this->addr.regIndex()); 40411308Santhony.gutierrez@amd.com } 40511308Santhony.gutierrez@amd.com }; 40611308Santhony.gutierrez@amd.com 40711308Santhony.gutierrez@amd.com template<typename MemDataType, typename DestDataType, 40811308Santhony.gutierrez@amd.com typename AddrOperandType> 40911308Santhony.gutierrez@amd.com class LdInst : 41011308Santhony.gutierrez@amd.com public LdInstBase<typename MemDataType::CType, 41111308Santhony.gutierrez@amd.com typename DestDataType::OperandType, AddrOperandType>, 41211308Santhony.gutierrez@amd.com public MemInst 41311308Santhony.gutierrez@amd.com { 41411308Santhony.gutierrez@amd.com typename DestDataType::OperandType::DestOperand dest_vect[4]; 41511308Santhony.gutierrez@amd.com uint16_t num_dest_operands; 41611347Sandreas.hansson@arm.com void generateDisassembly() override; 41711308Santhony.gutierrez@amd.com 41811308Santhony.gutierrez@amd.com public: 41911308Santhony.gutierrez@amd.com LdInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 42011308Santhony.gutierrez@amd.com const char *_opcode) 42111308Santhony.gutierrez@amd.com : LdInstBase<typename MemDataType::CType, 42211308Santhony.gutierrez@amd.com typename DestDataType::OperandType, 42311308Santhony.gutierrez@amd.com AddrOperandType>(ib, obj, _opcode), 42411308Santhony.gutierrez@amd.com MemInst(MemDataType::memType) 42511308Santhony.gutierrez@amd.com { 42611308Santhony.gutierrez@amd.com init_addr(&this->addr); 42711308Santhony.gutierrez@amd.com 42811308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands,0); 42911308Santhony.gutierrez@amd.com const Brig::BrigOperand *brigOp = obj->getOperand(op_offs); 43011308Santhony.gutierrez@amd.com 43111308Santhony.gutierrez@amd.com if (brigOp->kind == Brig::BRIG_KIND_OPERAND_OPERAND_LIST) { 43211308Santhony.gutierrez@amd.com const Brig::BrigOperandOperandList *brigRegVecOp = 43311308Santhony.gutierrez@amd.com (const Brig::BrigOperandOperandList*)brigOp; 43411308Santhony.gutierrez@amd.com 43511308Santhony.gutierrez@amd.com num_dest_operands = 43611308Santhony.gutierrez@amd.com *((unsigned*)obj->getData(brigRegVecOp->elements)) / 4; 43711308Santhony.gutierrez@amd.com 43811308Santhony.gutierrez@amd.com assert(num_dest_operands <= 4); 43911308Santhony.gutierrez@amd.com } else { 44011308Santhony.gutierrez@amd.com num_dest_operands = 1; 44111308Santhony.gutierrez@amd.com } 44211308Santhony.gutierrez@amd.com 44311308Santhony.gutierrez@amd.com if (num_dest_operands > 1) { 44411308Santhony.gutierrez@amd.com assert(brigOp->kind == Brig::BRIG_KIND_OPERAND_OPERAND_LIST); 44511308Santhony.gutierrez@amd.com 44611308Santhony.gutierrez@amd.com for (int i = 0; i < num_dest_operands; ++i) { 44711308Santhony.gutierrez@amd.com dest_vect[i].init_from_vect(op_offs, obj, i); 44811308Santhony.gutierrez@amd.com } 44911308Santhony.gutierrez@amd.com } 45011308Santhony.gutierrez@amd.com } 45111308Santhony.gutierrez@amd.com 45211308Santhony.gutierrez@amd.com void 45311308Santhony.gutierrez@amd.com initiateAcc(GPUDynInstPtr gpuDynInst) override 45411308Santhony.gutierrez@amd.com { 45511308Santhony.gutierrez@amd.com typedef typename MemDataType::CType c0; 45611308Santhony.gutierrez@amd.com 45711308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = gpuDynInst->exec_mask; 45811308Santhony.gutierrez@amd.com 45911308Santhony.gutierrez@amd.com if (num_dest_operands > 1) { 46011534Sjohn.kalamatianos@amd.com for (int i = 0; i < gpuDynInst->computeUnit()->wfSize(); ++i) 46111308Santhony.gutierrez@amd.com if (gpuDynInst->exec_mask[i]) 46211308Santhony.gutierrez@amd.com gpuDynInst->statusVector.push_back(num_dest_operands); 46311308Santhony.gutierrez@amd.com else 46411308Santhony.gutierrez@amd.com gpuDynInst->statusVector.push_back(0); 46511308Santhony.gutierrez@amd.com } 46611308Santhony.gutierrez@amd.com 46711308Santhony.gutierrez@amd.com for (int k = 0; k < num_dest_operands; ++k) { 46811308Santhony.gutierrez@amd.com 46911534Sjohn.kalamatianos@amd.com c0 *d = &((c0*)gpuDynInst->d_data) 47011534Sjohn.kalamatianos@amd.com [k * gpuDynInst->computeUnit()->wfSize()]; 47111308Santhony.gutierrez@amd.com 47211534Sjohn.kalamatianos@amd.com for (int i = 0; i < gpuDynInst->computeUnit()->wfSize(); ++i) { 47311308Santhony.gutierrez@amd.com if (gpuDynInst->exec_mask[i]) { 47411308Santhony.gutierrez@amd.com Addr vaddr = gpuDynInst->addr[i] + k * sizeof(c0); 47511308Santhony.gutierrez@amd.com 47611308Santhony.gutierrez@amd.com if (isLocalMem()) { 47711308Santhony.gutierrez@amd.com // load from shared memory 47811308Santhony.gutierrez@amd.com *d = gpuDynInst->wavefront()->ldsChunk-> 47911308Santhony.gutierrez@amd.com read<c0>(vaddr); 48011308Santhony.gutierrez@amd.com } else { 48111308Santhony.gutierrez@amd.com Request *req = new Request(0, vaddr, sizeof(c0), 0, 48211308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 48311435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId); 48411308Santhony.gutierrez@amd.com 48511308Santhony.gutierrez@amd.com gpuDynInst->setRequestFlags(req); 48611308Santhony.gutierrez@amd.com PacketPtr pkt = new Packet(req, MemCmd::ReadReq); 48711308Santhony.gutierrez@amd.com pkt->dataStatic(d); 48811308Santhony.gutierrez@amd.com 48911308Santhony.gutierrez@amd.com if (gpuDynInst->computeUnit()->shader-> 49011308Santhony.gutierrez@amd.com separate_acquire_release && 49111308Santhony.gutierrez@amd.com gpuDynInst->memoryOrder == 49211308Santhony.gutierrez@amd.com Enums::MEMORY_ORDER_SC_ACQUIRE) { 49311308Santhony.gutierrez@amd.com // if this load has acquire semantics, 49411308Santhony.gutierrez@amd.com // set the response continuation function 49511308Santhony.gutierrez@amd.com // to perform an Acquire request 49611308Santhony.gutierrez@amd.com gpuDynInst->execContinuation = 49711308Santhony.gutierrez@amd.com &GPUStaticInst::execLdAcq; 49811308Santhony.gutierrez@amd.com 49911308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = true; 50011308Santhony.gutierrez@amd.com } else { 50111308Santhony.gutierrez@amd.com // the request will be finished when 50211308Santhony.gutierrez@amd.com // the load completes 50311308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 50411308Santhony.gutierrez@amd.com } 50511308Santhony.gutierrez@amd.com // translation is performed in sendRequest() 50611308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->sendRequest(gpuDynInst, 50711308Santhony.gutierrez@amd.com i, pkt); 50811308Santhony.gutierrez@amd.com } 50911308Santhony.gutierrez@amd.com } 51011308Santhony.gutierrez@amd.com ++d; 51111308Santhony.gutierrez@amd.com } 51211308Santhony.gutierrez@amd.com } 51311308Santhony.gutierrez@amd.com 51411308Santhony.gutierrez@amd.com gpuDynInst->updateStats(); 51511308Santhony.gutierrez@amd.com } 51611308Santhony.gutierrez@amd.com 51711308Santhony.gutierrez@amd.com private: 51811308Santhony.gutierrez@amd.com void 51911308Santhony.gutierrez@amd.com execLdAcq(GPUDynInstPtr gpuDynInst) override 52011308Santhony.gutierrez@amd.com { 52111308Santhony.gutierrez@amd.com // after the load has complete and if the load has acquire 52211308Santhony.gutierrez@amd.com // semantics, issue an acquire request. 52311308Santhony.gutierrez@amd.com if (!isLocalMem()) { 52411308Santhony.gutierrez@amd.com if (gpuDynInst->computeUnit()->shader->separate_acquire_release 52511308Santhony.gutierrez@amd.com && gpuDynInst->memoryOrder == 52611308Santhony.gutierrez@amd.com Enums::MEMORY_ORDER_SC_ACQUIRE) { 52711308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = VectorMask(1); 52811308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 52911308Santhony.gutierrez@amd.com // create request 53011308Santhony.gutierrez@amd.com Request *req = new Request(0, 0, 0, 0, 53111308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 53211435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId); 53311308Santhony.gutierrez@amd.com req->setFlags(Request::ACQUIRE); 53411308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->injectGlobalMemFence(gpuDynInst, false, req); 53511308Santhony.gutierrez@amd.com } 53611308Santhony.gutierrez@amd.com } 53711308Santhony.gutierrez@amd.com } 53811308Santhony.gutierrez@amd.com 53911308Santhony.gutierrez@amd.com public: 54011308Santhony.gutierrez@amd.com bool 54111308Santhony.gutierrez@amd.com isLocalMem() const override 54211308Santhony.gutierrez@amd.com { 54311308Santhony.gutierrez@amd.com return this->segment == Brig::BRIG_SEGMENT_GROUP; 54411308Santhony.gutierrez@amd.com } 54511308Santhony.gutierrez@amd.com 54611347Sandreas.hansson@arm.com bool isVectorRegister(int operandIndex) override 54711308Santhony.gutierrez@amd.com { 54811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 54911308Santhony.gutierrez@amd.com if ((num_dest_operands != getNumOperands()) && 55011308Santhony.gutierrez@amd.com (operandIndex == (getNumOperands()-1))) 55111308Santhony.gutierrez@amd.com return(this->addr.isVectorRegister()); 55211308Santhony.gutierrez@amd.com if (num_dest_operands > 1) { 55311308Santhony.gutierrez@amd.com return dest_vect[operandIndex].isVectorRegister(); 55411308Santhony.gutierrez@amd.com } 55511308Santhony.gutierrez@amd.com else if (num_dest_operands == 1) { 55611308Santhony.gutierrez@amd.com return LdInstBase<typename MemDataType::CType, 55711308Santhony.gutierrez@amd.com typename DestDataType::OperandType, 55811308Santhony.gutierrez@amd.com AddrOperandType>::dest.isVectorRegister(); 55911308Santhony.gutierrez@amd.com } 56011308Santhony.gutierrez@amd.com return false; 56111308Santhony.gutierrez@amd.com } 56211347Sandreas.hansson@arm.com bool isCondRegister(int operandIndex) override 56311308Santhony.gutierrez@amd.com { 56411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 56511308Santhony.gutierrez@amd.com if ((num_dest_operands != getNumOperands()) && 56611308Santhony.gutierrez@amd.com (operandIndex == (getNumOperands()-1))) 56711308Santhony.gutierrez@amd.com return(this->addr.isCondRegister()); 56811308Santhony.gutierrez@amd.com if (num_dest_operands > 1) 56911308Santhony.gutierrez@amd.com return dest_vect[operandIndex].isCondRegister(); 57011308Santhony.gutierrez@amd.com else if (num_dest_operands == 1) 57111308Santhony.gutierrez@amd.com return LdInstBase<typename MemDataType::CType, 57211308Santhony.gutierrez@amd.com typename DestDataType::OperandType, 57311308Santhony.gutierrez@amd.com AddrOperandType>::dest.isCondRegister(); 57411308Santhony.gutierrez@amd.com return false; 57511308Santhony.gutierrez@amd.com } 57611347Sandreas.hansson@arm.com bool isScalarRegister(int operandIndex) override 57711308Santhony.gutierrez@amd.com { 57811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 57911308Santhony.gutierrez@amd.com if ((num_dest_operands != getNumOperands()) && 58011308Santhony.gutierrez@amd.com (operandIndex == (getNumOperands()-1))) 58111308Santhony.gutierrez@amd.com return(this->addr.isScalarRegister()); 58211308Santhony.gutierrez@amd.com if (num_dest_operands > 1) 58311308Santhony.gutierrez@amd.com return dest_vect[operandIndex].isScalarRegister(); 58411308Santhony.gutierrez@amd.com else if (num_dest_operands == 1) 58511308Santhony.gutierrez@amd.com return LdInstBase<typename MemDataType::CType, 58611308Santhony.gutierrez@amd.com typename DestDataType::OperandType, 58711308Santhony.gutierrez@amd.com AddrOperandType>::dest.isScalarRegister(); 58811308Santhony.gutierrez@amd.com return false; 58911308Santhony.gutierrez@amd.com } 59011347Sandreas.hansson@arm.com bool isSrcOperand(int operandIndex) override 59111308Santhony.gutierrez@amd.com { 59211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 59311308Santhony.gutierrez@amd.com if ((num_dest_operands != getNumOperands()) && 59411308Santhony.gutierrez@amd.com (operandIndex == (getNumOperands()-1))) 59511308Santhony.gutierrez@amd.com return(this->addr.isVectorRegister()); 59611308Santhony.gutierrez@amd.com return false; 59711308Santhony.gutierrez@amd.com } 59811347Sandreas.hansson@arm.com bool isDstOperand(int operandIndex) override 59911308Santhony.gutierrez@amd.com { 60011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 60111308Santhony.gutierrez@amd.com if ((num_dest_operands != getNumOperands()) && 60211308Santhony.gutierrez@amd.com (operandIndex == (getNumOperands()-1))) 60311308Santhony.gutierrez@amd.com return false; 60411308Santhony.gutierrez@amd.com return true; 60511308Santhony.gutierrez@amd.com } 60611347Sandreas.hansson@arm.com int getOperandSize(int operandIndex) override 60711308Santhony.gutierrez@amd.com { 60811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 60911308Santhony.gutierrez@amd.com if ((num_dest_operands != getNumOperands()) && 61011308Santhony.gutierrez@amd.com (operandIndex == (getNumOperands()-1))) 61111308Santhony.gutierrez@amd.com return(this->addr.opSize()); 61211308Santhony.gutierrez@amd.com if (num_dest_operands > 1) 61311308Santhony.gutierrez@amd.com return(dest_vect[operandIndex].opSize()); 61411308Santhony.gutierrez@amd.com else if (num_dest_operands == 1) 61511308Santhony.gutierrez@amd.com return(LdInstBase<typename MemDataType::CType, 61611308Santhony.gutierrez@amd.com typename DestDataType::OperandType, 61711308Santhony.gutierrez@amd.com AddrOperandType>::dest.opSize()); 61811308Santhony.gutierrez@amd.com return 0; 61911308Santhony.gutierrez@amd.com } 62011347Sandreas.hansson@arm.com int getRegisterIndex(int operandIndex) override 62111308Santhony.gutierrez@amd.com { 62211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 62311308Santhony.gutierrez@amd.com if ((num_dest_operands != getNumOperands()) && 62411308Santhony.gutierrez@amd.com (operandIndex == (getNumOperands()-1))) 62511308Santhony.gutierrez@amd.com return(this->addr.regIndex()); 62611308Santhony.gutierrez@amd.com if (num_dest_operands > 1) 62711308Santhony.gutierrez@amd.com return(dest_vect[operandIndex].regIndex()); 62811308Santhony.gutierrez@amd.com else if (num_dest_operands == 1) 62911308Santhony.gutierrez@amd.com return(LdInstBase<typename MemDataType::CType, 63011308Santhony.gutierrez@amd.com typename DestDataType::OperandType, 63111308Santhony.gutierrez@amd.com AddrOperandType>::dest.regIndex()); 63211308Santhony.gutierrez@amd.com return -1; 63311308Santhony.gutierrez@amd.com } 63411347Sandreas.hansson@arm.com int getNumOperands() override 63511308Santhony.gutierrez@amd.com { 63611308Santhony.gutierrez@amd.com if (this->addr.isVectorRegister() || this->addr.isScalarRegister()) 63711308Santhony.gutierrez@amd.com return(num_dest_operands+1); 63811308Santhony.gutierrez@amd.com else 63911308Santhony.gutierrez@amd.com return(num_dest_operands); 64011308Santhony.gutierrez@amd.com } 64111347Sandreas.hansson@arm.com void execute(GPUDynInstPtr gpuDynInst) override; 64211308Santhony.gutierrez@amd.com }; 64311308Santhony.gutierrez@amd.com 64411308Santhony.gutierrez@amd.com template<typename MemDT, typename DestDT> 64511308Santhony.gutierrez@amd.com GPUStaticInst* 64611308Santhony.gutierrez@amd.com decodeLd2(const Brig::BrigInstBase *ib, const BrigObject *obj) 64711308Santhony.gutierrez@amd.com { 64811308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands,1); 64911308Santhony.gutierrez@amd.com BrigRegOperandInfo tmp = findRegDataType(op_offs, obj); 65011308Santhony.gutierrez@amd.com 65111308Santhony.gutierrez@amd.com if (tmp.kind == Brig::BRIG_KIND_OPERAND_ADDRESS) { 65211308Santhony.gutierrez@amd.com return new LdInst<MemDT, DestDT, NoRegAddrOperand>(ib, obj, "ld"); 65311308Santhony.gutierrez@amd.com } else if (tmp.kind == Brig::BRIG_KIND_OPERAND_REGISTER || 65411308Santhony.gutierrez@amd.com tmp.kind == Brig::BRIG_KIND_OPERAND_OPERAND_LIST) { 65511308Santhony.gutierrez@amd.com switch (tmp.regKind) { 65611308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_SINGLE: 65711308Santhony.gutierrez@amd.com return new LdInst<MemDT, DestDT, 65811308Santhony.gutierrez@amd.com SRegAddrOperand>(ib, obj, "ld"); 65911308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_DOUBLE: 66011308Santhony.gutierrez@amd.com return new LdInst<MemDT, DestDT, 66111308Santhony.gutierrez@amd.com DRegAddrOperand>(ib, obj, "ld"); 66211308Santhony.gutierrez@amd.com default: 66311308Santhony.gutierrez@amd.com fatal("Bad ld register operand type %d\n", tmp.regKind); 66411308Santhony.gutierrez@amd.com } 66511308Santhony.gutierrez@amd.com } else { 66611308Santhony.gutierrez@amd.com fatal("Bad ld register operand kind %d\n", tmp.kind); 66711308Santhony.gutierrez@amd.com } 66811308Santhony.gutierrez@amd.com } 66911308Santhony.gutierrez@amd.com 67011308Santhony.gutierrez@amd.com template<typename MemDT> 67111308Santhony.gutierrez@amd.com GPUStaticInst* 67211308Santhony.gutierrez@amd.com decodeLd(const Brig::BrigInstBase *ib, const BrigObject *obj) 67311308Santhony.gutierrez@amd.com { 67411308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands,0); 67511308Santhony.gutierrez@amd.com BrigRegOperandInfo dest = findRegDataType(op_offs, obj); 67611308Santhony.gutierrez@amd.com 67711308Santhony.gutierrez@amd.com assert(dest.kind == Brig::BRIG_KIND_OPERAND_REGISTER || 67811308Santhony.gutierrez@amd.com dest.kind == Brig::BRIG_KIND_OPERAND_OPERAND_LIST); 67911308Santhony.gutierrez@amd.com switch(dest.regKind) { 68011308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_SINGLE: 68111308Santhony.gutierrez@amd.com switch (ib->type) { 68211308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B8: 68311308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B16: 68411308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B32: 68511308Santhony.gutierrez@amd.com return decodeLd2<MemDT, B32>(ib, obj); 68611308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_U8: 68711308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_U16: 68811308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_U32: 68911308Santhony.gutierrez@amd.com return decodeLd2<MemDT, U32>(ib, obj); 69011308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_S8: 69111308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_S16: 69211308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_S32: 69311308Santhony.gutierrez@amd.com return decodeLd2<MemDT, S32>(ib, obj); 69411308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_F16: 69511308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_F32: 69611308Santhony.gutierrez@amd.com return decodeLd2<MemDT, U32>(ib, obj); 69711308Santhony.gutierrez@amd.com default: 69811308Santhony.gutierrez@amd.com fatal("Bad ld register operand type %d, %d\n", 69911308Santhony.gutierrez@amd.com dest.regKind, ib->type); 70011308Santhony.gutierrez@amd.com }; 70111308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_DOUBLE: 70211308Santhony.gutierrez@amd.com switch (ib->type) { 70311308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B64: 70411308Santhony.gutierrez@amd.com return decodeLd2<MemDT, B64>(ib, obj); 70511308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_U64: 70611308Santhony.gutierrez@amd.com return decodeLd2<MemDT, U64>(ib, obj); 70711308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_S64: 70811308Santhony.gutierrez@amd.com return decodeLd2<MemDT, S64>(ib, obj); 70911308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_F64: 71011308Santhony.gutierrez@amd.com return decodeLd2<MemDT, U64>(ib, obj); 71111308Santhony.gutierrez@amd.com default: 71211308Santhony.gutierrez@amd.com fatal("Bad ld register operand type %d, %d\n", 71311308Santhony.gutierrez@amd.com dest.regKind, ib->type); 71411308Santhony.gutierrez@amd.com }; 71511308Santhony.gutierrez@amd.com default: 71611308Santhony.gutierrez@amd.com fatal("Bad ld register operand type %d, %d\n", dest.regKind, 71711308Santhony.gutierrez@amd.com ib->type); 71811308Santhony.gutierrez@amd.com } 71911308Santhony.gutierrez@amd.com } 72011308Santhony.gutierrez@amd.com 72111308Santhony.gutierrez@amd.com template<typename MemDataType, typename SrcOperandType, 72211308Santhony.gutierrez@amd.com typename AddrOperandType> 72311308Santhony.gutierrez@amd.com class StInstBase : public HsailGPUStaticInst 72411308Santhony.gutierrez@amd.com { 72511308Santhony.gutierrez@amd.com public: 72611308Santhony.gutierrez@amd.com typename SrcOperandType::SrcOperand src; 72711308Santhony.gutierrez@amd.com AddrOperandType addr; 72811308Santhony.gutierrez@amd.com 72911308Santhony.gutierrez@amd.com Brig::BrigSegment segment; 73011308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memoryScope; 73111308Santhony.gutierrez@amd.com Brig::BrigMemoryOrder memoryOrder; 73211308Santhony.gutierrez@amd.com unsigned int equivClass; 73311308Santhony.gutierrez@amd.com 73411308Santhony.gutierrez@amd.com void 73511308Santhony.gutierrez@amd.com initSt(const Brig::BrigInstBase *ib, const BrigObject *obj, 73611308Santhony.gutierrez@amd.com const char *_opcode) 73711308Santhony.gutierrez@amd.com { 73811308Santhony.gutierrez@amd.com using namespace Brig; 73911308Santhony.gutierrez@amd.com 74011308Santhony.gutierrez@amd.com const BrigInstMem *ldst = (const BrigInstMem*)ib; 74111308Santhony.gutierrez@amd.com 74211308Santhony.gutierrez@amd.com segment = (BrigSegment)ldst->segment; 74311308Santhony.gutierrez@amd.com memoryOrder = BRIG_MEMORY_ORDER_NONE; 74411308Santhony.gutierrez@amd.com memoryScope = BRIG_MEMORY_SCOPE_NONE; 74511308Santhony.gutierrez@amd.com equivClass = ldst->equivClass; 74611308Santhony.gutierrez@amd.com 74711308Santhony.gutierrez@amd.com switch (segment) { 74811308Santhony.gutierrez@amd.com case BRIG_SEGMENT_GLOBAL: 74911308Santhony.gutierrez@amd.com o_type = Enums::OT_GLOBAL_WRITE; 75011308Santhony.gutierrez@amd.com break; 75111308Santhony.gutierrez@amd.com 75211308Santhony.gutierrez@amd.com case BRIG_SEGMENT_GROUP: 75311308Santhony.gutierrez@amd.com o_type = Enums::OT_SHARED_WRITE; 75411308Santhony.gutierrez@amd.com break; 75511308Santhony.gutierrez@amd.com 75611308Santhony.gutierrez@amd.com case BRIG_SEGMENT_PRIVATE: 75711308Santhony.gutierrez@amd.com o_type = Enums::OT_PRIVATE_WRITE; 75811308Santhony.gutierrez@amd.com break; 75911308Santhony.gutierrez@amd.com 76011308Santhony.gutierrez@amd.com case BRIG_SEGMENT_READONLY: 76111308Santhony.gutierrez@amd.com o_type = Enums::OT_READONLY_WRITE; 76211308Santhony.gutierrez@amd.com break; 76311308Santhony.gutierrez@amd.com 76411308Santhony.gutierrez@amd.com case BRIG_SEGMENT_SPILL: 76511308Santhony.gutierrez@amd.com o_type = Enums::OT_SPILL_WRITE; 76611308Santhony.gutierrez@amd.com break; 76711308Santhony.gutierrez@amd.com 76811308Santhony.gutierrez@amd.com case BRIG_SEGMENT_FLAT: 76911308Santhony.gutierrez@amd.com o_type = Enums::OT_FLAT_WRITE; 77011308Santhony.gutierrez@amd.com break; 77111308Santhony.gutierrez@amd.com 77211308Santhony.gutierrez@amd.com case BRIG_SEGMENT_ARG: 77311308Santhony.gutierrez@amd.com o_type = Enums::OT_ARG; 77411308Santhony.gutierrez@amd.com break; 77511308Santhony.gutierrez@amd.com 77611308Santhony.gutierrez@amd.com default: 77711308Santhony.gutierrez@amd.com panic("St: segment %d not supported\n", segment); 77811308Santhony.gutierrez@amd.com } 77911308Santhony.gutierrez@amd.com 78011308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 78111308Santhony.gutierrez@amd.com const BrigOperand *baseOp = obj->getOperand(op_offs); 78211308Santhony.gutierrez@amd.com 78311308Santhony.gutierrez@amd.com if ((baseOp->kind == BRIG_KIND_OPERAND_CONSTANT_BYTES) || 78411308Santhony.gutierrez@amd.com (baseOp->kind == BRIG_KIND_OPERAND_REGISTER)) { 78511308Santhony.gutierrez@amd.com src.init(op_offs, obj); 78611308Santhony.gutierrez@amd.com } 78711308Santhony.gutierrez@amd.com 78811308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 78911308Santhony.gutierrez@amd.com addr.init(op_offs, obj); 79011308Santhony.gutierrez@amd.com } 79111308Santhony.gutierrez@amd.com 79211308Santhony.gutierrez@amd.com void 79311308Santhony.gutierrez@amd.com initAtomicSt(const Brig::BrigInstBase *ib, const BrigObject *obj, 79411308Santhony.gutierrez@amd.com const char *_opcode) 79511308Santhony.gutierrez@amd.com { 79611308Santhony.gutierrez@amd.com using namespace Brig; 79711308Santhony.gutierrez@amd.com 79811308Santhony.gutierrez@amd.com const BrigInstAtomic *at = (const BrigInstAtomic*)ib; 79911308Santhony.gutierrez@amd.com 80011308Santhony.gutierrez@amd.com segment = (BrigSegment)at->segment; 80111308Santhony.gutierrez@amd.com memoryScope = (BrigMemoryScope)at->memoryScope; 80211308Santhony.gutierrez@amd.com memoryOrder = (BrigMemoryOrder)at->memoryOrder; 80311308Santhony.gutierrez@amd.com equivClass = 0; 80411308Santhony.gutierrez@amd.com 80511308Santhony.gutierrez@amd.com switch (segment) { 80611308Santhony.gutierrez@amd.com case BRIG_SEGMENT_GLOBAL: 80711308Santhony.gutierrez@amd.com o_type = Enums::OT_GLOBAL_WRITE; 80811308Santhony.gutierrez@amd.com break; 80911308Santhony.gutierrez@amd.com 81011308Santhony.gutierrez@amd.com case BRIG_SEGMENT_GROUP: 81111308Santhony.gutierrez@amd.com o_type = Enums::OT_SHARED_WRITE; 81211308Santhony.gutierrez@amd.com break; 81311308Santhony.gutierrez@amd.com 81411308Santhony.gutierrez@amd.com case BRIG_SEGMENT_PRIVATE: 81511308Santhony.gutierrez@amd.com o_type = Enums::OT_PRIVATE_WRITE; 81611308Santhony.gutierrez@amd.com break; 81711308Santhony.gutierrez@amd.com 81811308Santhony.gutierrez@amd.com case BRIG_SEGMENT_READONLY: 81911308Santhony.gutierrez@amd.com o_type = Enums::OT_READONLY_WRITE; 82011308Santhony.gutierrez@amd.com break; 82111308Santhony.gutierrez@amd.com 82211308Santhony.gutierrez@amd.com case BRIG_SEGMENT_SPILL: 82311308Santhony.gutierrez@amd.com o_type = Enums::OT_SPILL_WRITE; 82411308Santhony.gutierrez@amd.com break; 82511308Santhony.gutierrez@amd.com 82611308Santhony.gutierrez@amd.com case BRIG_SEGMENT_FLAT: 82711308Santhony.gutierrez@amd.com o_type = Enums::OT_FLAT_WRITE; 82811308Santhony.gutierrez@amd.com break; 82911308Santhony.gutierrez@amd.com 83011308Santhony.gutierrez@amd.com case BRIG_SEGMENT_ARG: 83111308Santhony.gutierrez@amd.com o_type = Enums::OT_ARG; 83211308Santhony.gutierrez@amd.com break; 83311308Santhony.gutierrez@amd.com 83411308Santhony.gutierrez@amd.com default: 83511308Santhony.gutierrez@amd.com panic("St: segment %d not supported\n", segment); 83611308Santhony.gutierrez@amd.com } 83711308Santhony.gutierrez@amd.com 83811308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 83911308Santhony.gutierrez@amd.com addr.init(op_offs, obj); 84011308Santhony.gutierrez@amd.com 84111308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 84211308Santhony.gutierrez@amd.com src.init(op_offs, obj); 84311308Santhony.gutierrez@amd.com } 84411308Santhony.gutierrez@amd.com 84511308Santhony.gutierrez@amd.com StInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, 84611308Santhony.gutierrez@amd.com const char *_opcode) 84711308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 84811308Santhony.gutierrez@amd.com { 84911308Santhony.gutierrez@amd.com using namespace Brig; 85011308Santhony.gutierrez@amd.com 85111308Santhony.gutierrez@amd.com if (ib->opcode == BRIG_OPCODE_ST) { 85211308Santhony.gutierrez@amd.com initSt(ib, obj, _opcode); 85311308Santhony.gutierrez@amd.com } else { 85411308Santhony.gutierrez@amd.com initAtomicSt(ib, obj, _opcode); 85511308Santhony.gutierrez@amd.com } 85611308Santhony.gutierrez@amd.com } 85711308Santhony.gutierrez@amd.com 85811347Sandreas.hansson@arm.com int numDstRegOperands() override { return 0; } 85911347Sandreas.hansson@arm.com int numSrcRegOperands() override 86011308Santhony.gutierrez@amd.com { 86111308Santhony.gutierrez@amd.com return src.isVectorRegister() + this->addr.isVectorRegister(); 86211308Santhony.gutierrez@amd.com } 86311347Sandreas.hansson@arm.com int getNumOperands() override 86411308Santhony.gutierrez@amd.com { 86511308Santhony.gutierrez@amd.com if (this->addr.isVectorRegister() || this->addr.isScalarRegister()) 86611308Santhony.gutierrez@amd.com return 2; 86711308Santhony.gutierrez@amd.com else 86811308Santhony.gutierrez@amd.com return 1; 86911308Santhony.gutierrez@amd.com } 87011347Sandreas.hansson@arm.com bool isVectorRegister(int operandIndex) override 87111308Santhony.gutierrez@amd.com { 87211308Santhony.gutierrez@amd.com assert(operandIndex >= 0 && operandIndex < getNumOperands()); 87311308Santhony.gutierrez@amd.com return !operandIndex ? src.isVectorRegister() : 87411308Santhony.gutierrez@amd.com this->addr.isVectorRegister(); 87511308Santhony.gutierrez@amd.com } 87611347Sandreas.hansson@arm.com bool isCondRegister(int operandIndex) override 87711308Santhony.gutierrez@amd.com { 87811308Santhony.gutierrez@amd.com assert(operandIndex >= 0 && operandIndex < getNumOperands()); 87911308Santhony.gutierrez@amd.com return !operandIndex ? src.isCondRegister() : 88011308Santhony.gutierrez@amd.com this->addr.isCondRegister(); 88111308Santhony.gutierrez@amd.com } 88211347Sandreas.hansson@arm.com bool isScalarRegister(int operandIndex) override 88311308Santhony.gutierrez@amd.com { 88411308Santhony.gutierrez@amd.com assert(operandIndex >= 0 && operandIndex < getNumOperands()); 88511308Santhony.gutierrez@amd.com return !operandIndex ? src.isScalarRegister() : 88611308Santhony.gutierrez@amd.com this->addr.isScalarRegister(); 88711308Santhony.gutierrez@amd.com } 88811347Sandreas.hansson@arm.com bool isSrcOperand(int operandIndex) override 88911308Santhony.gutierrez@amd.com { 89011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 89111308Santhony.gutierrez@amd.com return true; 89211308Santhony.gutierrez@amd.com } 89311347Sandreas.hansson@arm.com bool isDstOperand(int operandIndex) override { return false; } 89411347Sandreas.hansson@arm.com int getOperandSize(int operandIndex) override 89511308Santhony.gutierrez@amd.com { 89611308Santhony.gutierrez@amd.com assert(operandIndex >= 0 && operandIndex < getNumOperands()); 89711308Santhony.gutierrez@amd.com return !operandIndex ? src.opSize() : this->addr.opSize(); 89811308Santhony.gutierrez@amd.com } 89911347Sandreas.hansson@arm.com int getRegisterIndex(int operandIndex) override 90011308Santhony.gutierrez@amd.com { 90111308Santhony.gutierrez@amd.com assert(operandIndex >= 0 && operandIndex < getNumOperands()); 90211308Santhony.gutierrez@amd.com return !operandIndex ? src.regIndex() : this->addr.regIndex(); 90311308Santhony.gutierrez@amd.com } 90411308Santhony.gutierrez@amd.com }; 90511308Santhony.gutierrez@amd.com 90611308Santhony.gutierrez@amd.com 90711308Santhony.gutierrez@amd.com template<typename MemDataType, typename SrcDataType, 90811308Santhony.gutierrez@amd.com typename AddrOperandType> 90911308Santhony.gutierrez@amd.com class StInst : 91011308Santhony.gutierrez@amd.com public StInstBase<MemDataType, typename SrcDataType::OperandType, 91111308Santhony.gutierrez@amd.com AddrOperandType>, 91211308Santhony.gutierrez@amd.com public MemInst 91311308Santhony.gutierrez@amd.com { 91411308Santhony.gutierrez@amd.com public: 91511308Santhony.gutierrez@amd.com typename SrcDataType::OperandType::SrcOperand src_vect[4]; 91611308Santhony.gutierrez@amd.com uint16_t num_src_operands; 91711347Sandreas.hansson@arm.com void generateDisassembly() override; 91811308Santhony.gutierrez@amd.com 91911308Santhony.gutierrez@amd.com StInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 92011308Santhony.gutierrez@amd.com const char *_opcode, int srcIdx) 92111308Santhony.gutierrez@amd.com : StInstBase<MemDataType, typename SrcDataType::OperandType, 92211308Santhony.gutierrez@amd.com AddrOperandType>(ib, obj, _opcode), 92311308Santhony.gutierrez@amd.com MemInst(SrcDataType::memType) 92411308Santhony.gutierrez@amd.com { 92511308Santhony.gutierrez@amd.com init_addr(&this->addr); 92611308Santhony.gutierrez@amd.com 92711308Santhony.gutierrez@amd.com BrigRegOperandInfo rinfo; 92811308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands,srcIdx); 92911308Santhony.gutierrez@amd.com const Brig::BrigOperand *baseOp = obj->getOperand(op_offs); 93011308Santhony.gutierrez@amd.com 93111308Santhony.gutierrez@amd.com if (baseOp->kind == Brig::BRIG_KIND_OPERAND_CONSTANT_BYTES) { 93211308Santhony.gutierrez@amd.com const Brig::BrigOperandConstantBytes *op = 93311308Santhony.gutierrez@amd.com (Brig::BrigOperandConstantBytes*)baseOp; 93411308Santhony.gutierrez@amd.com 93511308Santhony.gutierrez@amd.com rinfo = BrigRegOperandInfo((Brig::BrigKind16_t)op->base.kind, 93611308Santhony.gutierrez@amd.com Brig::BRIG_TYPE_NONE); 93711308Santhony.gutierrez@amd.com } else { 93811308Santhony.gutierrez@amd.com rinfo = findRegDataType(op_offs, obj); 93911308Santhony.gutierrez@amd.com } 94011308Santhony.gutierrez@amd.com 94111308Santhony.gutierrez@amd.com if (baseOp->kind == Brig::BRIG_KIND_OPERAND_OPERAND_LIST) { 94211308Santhony.gutierrez@amd.com const Brig::BrigOperandOperandList *brigRegVecOp = 94311308Santhony.gutierrez@amd.com (const Brig::BrigOperandOperandList*)baseOp; 94411308Santhony.gutierrez@amd.com 94511308Santhony.gutierrez@amd.com num_src_operands = 94611308Santhony.gutierrez@amd.com *((unsigned*)obj->getData(brigRegVecOp->elements)) / 4; 94711308Santhony.gutierrez@amd.com 94811308Santhony.gutierrez@amd.com assert(num_src_operands <= 4); 94911308Santhony.gutierrez@amd.com } else { 95011308Santhony.gutierrez@amd.com num_src_operands = 1; 95111308Santhony.gutierrez@amd.com } 95211308Santhony.gutierrez@amd.com 95311308Santhony.gutierrez@amd.com if (num_src_operands > 1) { 95411308Santhony.gutierrez@amd.com assert(baseOp->kind == Brig::BRIG_KIND_OPERAND_OPERAND_LIST); 95511308Santhony.gutierrez@amd.com 95611308Santhony.gutierrez@amd.com for (int i = 0; i < num_src_operands; ++i) { 95711308Santhony.gutierrez@amd.com src_vect[i].init_from_vect(op_offs, obj, i); 95811308Santhony.gutierrez@amd.com } 95911308Santhony.gutierrez@amd.com } 96011308Santhony.gutierrez@amd.com } 96111308Santhony.gutierrez@amd.com 96211308Santhony.gutierrez@amd.com void 96311308Santhony.gutierrez@amd.com initiateAcc(GPUDynInstPtr gpuDynInst) override 96411308Santhony.gutierrez@amd.com { 96511308Santhony.gutierrez@amd.com // before performing a store, check if this store has 96611308Santhony.gutierrez@amd.com // release semantics, and if so issue a release first 96711308Santhony.gutierrez@amd.com if (!isLocalMem()) { 96811308Santhony.gutierrez@amd.com if (gpuDynInst->computeUnit()->shader->separate_acquire_release 96911308Santhony.gutierrez@amd.com && gpuDynInst->memoryOrder == 97011308Santhony.gutierrez@amd.com Enums::MEMORY_ORDER_SC_RELEASE) { 97111308Santhony.gutierrez@amd.com 97211308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = VectorMask(1); 97311308Santhony.gutierrez@amd.com gpuDynInst->execContinuation = &GPUStaticInst::execSt; 97411308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = true; 97511308Santhony.gutierrez@amd.com // create request 97611308Santhony.gutierrez@amd.com Request *req = new Request(0, 0, 0, 0, 97711308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 97811435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId); 97911308Santhony.gutierrez@amd.com req->setFlags(Request::RELEASE); 98011308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->injectGlobalMemFence(gpuDynInst, false, req); 98111308Santhony.gutierrez@amd.com 98211308Santhony.gutierrez@amd.com return; 98311308Santhony.gutierrez@amd.com } 98411308Santhony.gutierrez@amd.com } 98511308Santhony.gutierrez@amd.com 98611308Santhony.gutierrez@amd.com // if there is no release semantic, perform stores immediately 98711308Santhony.gutierrez@amd.com execSt(gpuDynInst); 98811308Santhony.gutierrez@amd.com } 98911308Santhony.gutierrez@amd.com 99011308Santhony.gutierrez@amd.com bool 99111308Santhony.gutierrez@amd.com isLocalMem() const override 99211308Santhony.gutierrez@amd.com { 99311308Santhony.gutierrez@amd.com return this->segment == Brig::BRIG_SEGMENT_GROUP; 99411308Santhony.gutierrez@amd.com } 99511308Santhony.gutierrez@amd.com 99611308Santhony.gutierrez@amd.com private: 99711308Santhony.gutierrez@amd.com // execSt may be called through a continuation 99811308Santhony.gutierrez@amd.com // if the store had release semantics. see comment for 99911308Santhony.gutierrez@amd.com // execSt in gpu_static_inst.hh 100011308Santhony.gutierrez@amd.com void 100111308Santhony.gutierrez@amd.com execSt(GPUDynInstPtr gpuDynInst) override 100211308Santhony.gutierrez@amd.com { 100311308Santhony.gutierrez@amd.com typedef typename MemDataType::CType c0; 100411308Santhony.gutierrez@amd.com 100511308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = gpuDynInst->exec_mask; 100611308Santhony.gutierrez@amd.com 100711308Santhony.gutierrez@amd.com if (num_src_operands > 1) { 100811534Sjohn.kalamatianos@amd.com for (int i = 0; i < gpuDynInst->computeUnit()->wfSize(); ++i) 100911308Santhony.gutierrez@amd.com if (gpuDynInst->exec_mask[i]) 101011308Santhony.gutierrez@amd.com gpuDynInst->statusVector.push_back(num_src_operands); 101111308Santhony.gutierrez@amd.com else 101211308Santhony.gutierrez@amd.com gpuDynInst->statusVector.push_back(0); 101311308Santhony.gutierrez@amd.com } 101411308Santhony.gutierrez@amd.com 101511308Santhony.gutierrez@amd.com for (int k = 0; k < num_src_operands; ++k) { 101611534Sjohn.kalamatianos@amd.com c0 *d = &((c0*)gpuDynInst->d_data) 101711534Sjohn.kalamatianos@amd.com [k * gpuDynInst->computeUnit()->wfSize()]; 101811308Santhony.gutierrez@amd.com 101911534Sjohn.kalamatianos@amd.com for (int i = 0; i < gpuDynInst->computeUnit()->wfSize(); ++i) { 102011308Santhony.gutierrez@amd.com if (gpuDynInst->exec_mask[i]) { 102111308Santhony.gutierrez@amd.com Addr vaddr = gpuDynInst->addr[i] + k * sizeof(c0); 102211308Santhony.gutierrez@amd.com 102311308Santhony.gutierrez@amd.com if (isLocalMem()) { 102411308Santhony.gutierrez@amd.com //store to shared memory 102511308Santhony.gutierrez@amd.com gpuDynInst->wavefront()->ldsChunk->write<c0>(vaddr, 102611308Santhony.gutierrez@amd.com *d); 102711308Santhony.gutierrez@amd.com } else { 102811308Santhony.gutierrez@amd.com Request *req = 102911308Santhony.gutierrez@amd.com new Request(0, vaddr, sizeof(c0), 0, 103011308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 103111435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId); 103211308Santhony.gutierrez@amd.com 103311308Santhony.gutierrez@amd.com gpuDynInst->setRequestFlags(req); 103411308Santhony.gutierrez@amd.com PacketPtr pkt = new Packet(req, MemCmd::WriteReq); 103511308Santhony.gutierrez@amd.com pkt->dataStatic<c0>(d); 103611308Santhony.gutierrez@amd.com 103711308Santhony.gutierrez@amd.com // translation is performed in sendRequest() 103811308Santhony.gutierrez@amd.com // the request will be finished when the store completes 103911308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 104011308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->sendRequest(gpuDynInst, 104111308Santhony.gutierrez@amd.com i, pkt); 104211308Santhony.gutierrez@amd.com 104311308Santhony.gutierrez@amd.com } 104411308Santhony.gutierrez@amd.com } 104511308Santhony.gutierrez@amd.com ++d; 104611308Santhony.gutierrez@amd.com } 104711308Santhony.gutierrez@amd.com } 104811308Santhony.gutierrez@amd.com 104911308Santhony.gutierrez@amd.com gpuDynInst->updateStats(); 105011308Santhony.gutierrez@amd.com } 105111308Santhony.gutierrez@amd.com 105211308Santhony.gutierrez@amd.com public: 105311347Sandreas.hansson@arm.com bool isVectorRegister(int operandIndex) override 105411308Santhony.gutierrez@amd.com { 105511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 105611308Santhony.gutierrez@amd.com if (operandIndex == num_src_operands) 105711308Santhony.gutierrez@amd.com return this->addr.isVectorRegister(); 105811308Santhony.gutierrez@amd.com if (num_src_operands > 1) 105911308Santhony.gutierrez@amd.com return src_vect[operandIndex].isVectorRegister(); 106011308Santhony.gutierrez@amd.com else if (num_src_operands == 1) 106111308Santhony.gutierrez@amd.com return StInstBase<MemDataType, 106211308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 106311308Santhony.gutierrez@amd.com AddrOperandType>::src.isVectorRegister(); 106411308Santhony.gutierrez@amd.com return false; 106511308Santhony.gutierrez@amd.com } 106611347Sandreas.hansson@arm.com bool isCondRegister(int operandIndex) override 106711308Santhony.gutierrez@amd.com { 106811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 106911308Santhony.gutierrez@amd.com if (operandIndex == num_src_operands) 107011308Santhony.gutierrez@amd.com return this->addr.isCondRegister(); 107111308Santhony.gutierrez@amd.com if (num_src_operands > 1) 107211308Santhony.gutierrez@amd.com return src_vect[operandIndex].isCondRegister(); 107311308Santhony.gutierrez@amd.com else if (num_src_operands == 1) 107411308Santhony.gutierrez@amd.com return StInstBase<MemDataType, 107511308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 107611308Santhony.gutierrez@amd.com AddrOperandType>::src.isCondRegister(); 107711308Santhony.gutierrez@amd.com return false; 107811308Santhony.gutierrez@amd.com } 107911347Sandreas.hansson@arm.com bool isScalarRegister(int operandIndex) override 108011308Santhony.gutierrez@amd.com { 108111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 108211308Santhony.gutierrez@amd.com if (operandIndex == num_src_operands) 108311308Santhony.gutierrez@amd.com return this->addr.isScalarRegister(); 108411308Santhony.gutierrez@amd.com if (num_src_operands > 1) 108511308Santhony.gutierrez@amd.com return src_vect[operandIndex].isScalarRegister(); 108611308Santhony.gutierrez@amd.com else if (num_src_operands == 1) 108711308Santhony.gutierrez@amd.com return StInstBase<MemDataType, 108811308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 108911308Santhony.gutierrez@amd.com AddrOperandType>::src.isScalarRegister(); 109011308Santhony.gutierrez@amd.com return false; 109111308Santhony.gutierrez@amd.com } 109211347Sandreas.hansson@arm.com bool isSrcOperand(int operandIndex) override 109311308Santhony.gutierrez@amd.com { 109411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 109511308Santhony.gutierrez@amd.com return true; 109611308Santhony.gutierrez@amd.com } 109711347Sandreas.hansson@arm.com bool isDstOperand(int operandIndex) override { return false; } 109811347Sandreas.hansson@arm.com int getOperandSize(int operandIndex) override 109911308Santhony.gutierrez@amd.com { 110011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 110111308Santhony.gutierrez@amd.com if (operandIndex == num_src_operands) 110211308Santhony.gutierrez@amd.com return this->addr.opSize(); 110311308Santhony.gutierrez@amd.com if (num_src_operands > 1) 110411308Santhony.gutierrez@amd.com return src_vect[operandIndex].opSize(); 110511308Santhony.gutierrez@amd.com else if (num_src_operands == 1) 110611308Santhony.gutierrez@amd.com return StInstBase<MemDataType, 110711308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 110811308Santhony.gutierrez@amd.com AddrOperandType>::src.opSize(); 110911308Santhony.gutierrez@amd.com return 0; 111011308Santhony.gutierrez@amd.com } 111111347Sandreas.hansson@arm.com int getRegisterIndex(int operandIndex) override 111211308Santhony.gutierrez@amd.com { 111311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 111411308Santhony.gutierrez@amd.com if (operandIndex == num_src_operands) 111511308Santhony.gutierrez@amd.com return this->addr.regIndex(); 111611308Santhony.gutierrez@amd.com if (num_src_operands > 1) 111711308Santhony.gutierrez@amd.com return src_vect[operandIndex].regIndex(); 111811308Santhony.gutierrez@amd.com else if (num_src_operands == 1) 111911308Santhony.gutierrez@amd.com return StInstBase<MemDataType, 112011308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 112111308Santhony.gutierrez@amd.com AddrOperandType>::src.regIndex(); 112211308Santhony.gutierrez@amd.com return -1; 112311308Santhony.gutierrez@amd.com } 112411347Sandreas.hansson@arm.com int getNumOperands() override 112511308Santhony.gutierrez@amd.com { 112611308Santhony.gutierrez@amd.com if (this->addr.isVectorRegister() || this->addr.isScalarRegister()) 112711308Santhony.gutierrez@amd.com return num_src_operands + 1; 112811308Santhony.gutierrez@amd.com else 112911308Santhony.gutierrez@amd.com return num_src_operands; 113011308Santhony.gutierrez@amd.com } 113111347Sandreas.hansson@arm.com void execute(GPUDynInstPtr gpuDynInst) override; 113211308Santhony.gutierrez@amd.com }; 113311308Santhony.gutierrez@amd.com 113411308Santhony.gutierrez@amd.com template<typename DataType, typename SrcDataType> 113511308Santhony.gutierrez@amd.com GPUStaticInst* 113611308Santhony.gutierrez@amd.com decodeSt(const Brig::BrigInstBase *ib, const BrigObject *obj) 113711308Santhony.gutierrez@amd.com { 113811308Santhony.gutierrez@amd.com int srcIdx = 0; 113911308Santhony.gutierrez@amd.com int destIdx = 1; 114011308Santhony.gutierrez@amd.com if (ib->opcode == Brig::BRIG_OPCODE_ATOMIC || 114111308Santhony.gutierrez@amd.com ib->opcode == Brig::BRIG_OPCODE_ATOMICNORET) { 114211308Santhony.gutierrez@amd.com srcIdx = 1; 114311308Santhony.gutierrez@amd.com destIdx = 0; 114411308Santhony.gutierrez@amd.com } 114511308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands,destIdx); 114611308Santhony.gutierrez@amd.com 114711308Santhony.gutierrez@amd.com BrigRegOperandInfo tmp = findRegDataType(op_offs, obj); 114811308Santhony.gutierrez@amd.com 114911308Santhony.gutierrez@amd.com if (tmp.kind == Brig::BRIG_KIND_OPERAND_ADDRESS) { 115011308Santhony.gutierrez@amd.com return new StInst<DataType, SrcDataType, 115111308Santhony.gutierrez@amd.com NoRegAddrOperand>(ib, obj, "st", srcIdx); 115211308Santhony.gutierrez@amd.com } else if (tmp.kind == Brig::BRIG_KIND_OPERAND_REGISTER) { 115311308Santhony.gutierrez@amd.com // V2/V4 not allowed 115411308Santhony.gutierrez@amd.com switch (tmp.regKind) { 115511308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_SINGLE: 115611308Santhony.gutierrez@amd.com return new StInst<DataType, SrcDataType, 115711308Santhony.gutierrez@amd.com SRegAddrOperand>(ib, obj, "st", srcIdx); 115811308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_DOUBLE: 115911308Santhony.gutierrez@amd.com return new StInst<DataType, SrcDataType, 116011308Santhony.gutierrez@amd.com DRegAddrOperand>(ib, obj, "st", srcIdx); 116111308Santhony.gutierrez@amd.com default: 116211308Santhony.gutierrez@amd.com fatal("Bad st register operand type %d\n", tmp.type); 116311308Santhony.gutierrez@amd.com } 116411308Santhony.gutierrez@amd.com } else { 116511308Santhony.gutierrez@amd.com fatal("Bad st register operand kind %d\n", tmp.kind); 116611308Santhony.gutierrez@amd.com } 116711308Santhony.gutierrez@amd.com } 116811308Santhony.gutierrez@amd.com 116911308Santhony.gutierrez@amd.com Enums::MemOpType brigAtomicToMemOpType(Brig::BrigOpcode brigOpCode, 117011308Santhony.gutierrez@amd.com Brig::BrigAtomicOperation brigOp); 117111308Santhony.gutierrez@amd.com 117211308Santhony.gutierrez@amd.com template<typename OperandType, typename AddrOperandType, int NumSrcOperands, 117311308Santhony.gutierrez@amd.com bool HasDst> 117411308Santhony.gutierrez@amd.com class AtomicInstBase : public HsailGPUStaticInst 117511308Santhony.gutierrez@amd.com { 117611308Santhony.gutierrez@amd.com public: 117711308Santhony.gutierrez@amd.com typename OperandType::DestOperand dest; 117811308Santhony.gutierrez@amd.com typename OperandType::SrcOperand src[NumSrcOperands]; 117911308Santhony.gutierrez@amd.com AddrOperandType addr; 118011308Santhony.gutierrez@amd.com 118111308Santhony.gutierrez@amd.com Brig::BrigSegment segment; 118211308Santhony.gutierrez@amd.com Brig::BrigMemoryOrder memoryOrder; 118311308Santhony.gutierrez@amd.com Brig::BrigAtomicOperation atomicOperation; 118411308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memoryScope; 118511308Santhony.gutierrez@amd.com Brig::BrigOpcode opcode; 118611308Santhony.gutierrez@amd.com Enums::MemOpType opType; 118711308Santhony.gutierrez@amd.com 118811308Santhony.gutierrez@amd.com AtomicInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, 118911308Santhony.gutierrez@amd.com const char *_opcode) 119011308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 119111308Santhony.gutierrez@amd.com { 119211308Santhony.gutierrez@amd.com using namespace Brig; 119311308Santhony.gutierrez@amd.com 119411308Santhony.gutierrez@amd.com const BrigInstAtomic *at = (const BrigInstAtomic*)ib; 119511308Santhony.gutierrez@amd.com 119611308Santhony.gutierrez@amd.com segment = (BrigSegment)at->segment; 119711308Santhony.gutierrez@amd.com memoryScope = (BrigMemoryScope)at->memoryScope; 119811308Santhony.gutierrez@amd.com memoryOrder = (BrigMemoryOrder)at->memoryOrder; 119911308Santhony.gutierrez@amd.com atomicOperation = (BrigAtomicOperation)at->atomicOperation; 120011308Santhony.gutierrez@amd.com opcode = (BrigOpcode)ib->opcode; 120111308Santhony.gutierrez@amd.com opType = brigAtomicToMemOpType(opcode, atomicOperation); 120211308Santhony.gutierrez@amd.com 120311308Santhony.gutierrez@amd.com switch (segment) { 120411308Santhony.gutierrez@amd.com case BRIG_SEGMENT_GLOBAL: 120511308Santhony.gutierrez@amd.com o_type = Enums::OT_GLOBAL_ATOMIC; 120611308Santhony.gutierrez@amd.com break; 120711308Santhony.gutierrez@amd.com 120811308Santhony.gutierrez@amd.com case BRIG_SEGMENT_GROUP: 120911308Santhony.gutierrez@amd.com o_type = Enums::OT_SHARED_ATOMIC; 121011308Santhony.gutierrez@amd.com break; 121111308Santhony.gutierrez@amd.com 121211308Santhony.gutierrez@amd.com case BRIG_SEGMENT_FLAT: 121311308Santhony.gutierrez@amd.com o_type = Enums::OT_FLAT_ATOMIC; 121411308Santhony.gutierrez@amd.com break; 121511308Santhony.gutierrez@amd.com 121611308Santhony.gutierrez@amd.com default: 121711308Santhony.gutierrez@amd.com panic("Atomic: segment %d not supported\n", segment); 121811308Santhony.gutierrez@amd.com } 121911308Santhony.gutierrez@amd.com 122011308Santhony.gutierrez@amd.com if (HasDst) { 122111308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 122211308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 122311308Santhony.gutierrez@amd.com 122411308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 122511308Santhony.gutierrez@amd.com addr.init(op_offs, obj); 122611308Santhony.gutierrez@amd.com 122711308Santhony.gutierrez@amd.com for (int i = 0; i < NumSrcOperands; ++i) { 122811308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, i + 2); 122911308Santhony.gutierrez@amd.com src[i].init(op_offs, obj); 123011308Santhony.gutierrez@amd.com } 123111308Santhony.gutierrez@amd.com } else { 123211308Santhony.gutierrez@amd.com 123311308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 123411308Santhony.gutierrez@amd.com addr.init(op_offs, obj); 123511308Santhony.gutierrez@amd.com 123611308Santhony.gutierrez@amd.com for (int i = 0; i < NumSrcOperands; ++i) { 123711308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, i + 1); 123811308Santhony.gutierrez@amd.com src[i].init(op_offs, obj); 123911308Santhony.gutierrez@amd.com } 124011308Santhony.gutierrez@amd.com } 124111308Santhony.gutierrez@amd.com } 124211308Santhony.gutierrez@amd.com 124311308Santhony.gutierrez@amd.com int numSrcRegOperands() 124411308Santhony.gutierrez@amd.com { 124511308Santhony.gutierrez@amd.com int operands = 0; 124611308Santhony.gutierrez@amd.com for (int i = 0; i < NumSrcOperands; i++) { 124711325Ssteve.reinhardt@amd.com if (src[i].isVectorRegister()) { 124811308Santhony.gutierrez@amd.com operands++; 124911308Santhony.gutierrez@amd.com } 125011308Santhony.gutierrez@amd.com } 125111308Santhony.gutierrez@amd.com if (addr.isVectorRegister()) 125211308Santhony.gutierrez@amd.com operands++; 125311308Santhony.gutierrez@amd.com return operands; 125411308Santhony.gutierrez@amd.com } 125511308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 125611308Santhony.gutierrez@amd.com int getNumOperands() 125711308Santhony.gutierrez@amd.com { 125811308Santhony.gutierrez@amd.com if (addr.isVectorRegister()) 125911308Santhony.gutierrez@amd.com return(NumSrcOperands + 2); 126011308Santhony.gutierrez@amd.com return(NumSrcOperands + 1); 126111308Santhony.gutierrez@amd.com } 126211308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) 126311308Santhony.gutierrez@amd.com { 126411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 126511308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 126611308Santhony.gutierrez@amd.com return src[operandIndex].isVectorRegister(); 126711308Santhony.gutierrez@amd.com else if (operandIndex == NumSrcOperands) 126811308Santhony.gutierrez@amd.com return(addr.isVectorRegister()); 126911308Santhony.gutierrez@amd.com else 127011308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 127111308Santhony.gutierrez@amd.com } 127211308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) 127311308Santhony.gutierrez@amd.com { 127411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 127511308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 127611308Santhony.gutierrez@amd.com return src[operandIndex].isCondRegister(); 127711308Santhony.gutierrez@amd.com else if (operandIndex == NumSrcOperands) 127811308Santhony.gutierrez@amd.com return(addr.isCondRegister()); 127911308Santhony.gutierrez@amd.com else 128011308Santhony.gutierrez@amd.com return dest.isCondRegister(); 128111308Santhony.gutierrez@amd.com } 128211308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) 128311308Santhony.gutierrez@amd.com { 128411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 128511308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 128611308Santhony.gutierrez@amd.com return src[operandIndex].isScalarRegister(); 128711308Santhony.gutierrez@amd.com else if (operandIndex == NumSrcOperands) 128811308Santhony.gutierrez@amd.com return(addr.isScalarRegister()); 128911308Santhony.gutierrez@amd.com else 129011308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 129111308Santhony.gutierrez@amd.com } 129211308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) 129311308Santhony.gutierrez@amd.com { 129411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 129511308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 129611308Santhony.gutierrez@amd.com return true; 129711308Santhony.gutierrez@amd.com else if (operandIndex == NumSrcOperands) 129811308Santhony.gutierrez@amd.com return(addr.isVectorRegister()); 129911308Santhony.gutierrez@amd.com else 130011308Santhony.gutierrez@amd.com return false; 130111308Santhony.gutierrez@amd.com } 130211308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) 130311308Santhony.gutierrez@amd.com { 130411308Santhony.gutierrez@amd.com if (operandIndex <= NumSrcOperands) 130511308Santhony.gutierrez@amd.com return false; 130611308Santhony.gutierrez@amd.com else 130711308Santhony.gutierrez@amd.com return true; 130811308Santhony.gutierrez@amd.com } 130911308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) 131011308Santhony.gutierrez@amd.com { 131111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 131211308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 131311308Santhony.gutierrez@amd.com return(src[operandIndex].opSize()); 131411308Santhony.gutierrez@amd.com else if (operandIndex == NumSrcOperands) 131511308Santhony.gutierrez@amd.com return(addr.opSize()); 131611308Santhony.gutierrez@amd.com else 131711308Santhony.gutierrez@amd.com return(dest.opSize()); 131811308Santhony.gutierrez@amd.com } 131911308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) 132011308Santhony.gutierrez@amd.com { 132111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 132211308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 132311308Santhony.gutierrez@amd.com return(src[operandIndex].regIndex()); 132411308Santhony.gutierrez@amd.com else if (operandIndex == NumSrcOperands) 132511308Santhony.gutierrez@amd.com return(addr.regIndex()); 132611308Santhony.gutierrez@amd.com else 132711308Santhony.gutierrez@amd.com return(dest.regIndex()); 132811308Santhony.gutierrez@amd.com return -1; 132911308Santhony.gutierrez@amd.com } 133011308Santhony.gutierrez@amd.com }; 133111308Santhony.gutierrez@amd.com 133211308Santhony.gutierrez@amd.com template<typename MemDataType, typename AddrOperandType, int NumSrcOperands, 133311308Santhony.gutierrez@amd.com bool HasDst> 133411308Santhony.gutierrez@amd.com class AtomicInst : 133511308Santhony.gutierrez@amd.com public AtomicInstBase<typename MemDataType::OperandType, 133611308Santhony.gutierrez@amd.com AddrOperandType, NumSrcOperands, HasDst>, 133711308Santhony.gutierrez@amd.com public MemInst 133811308Santhony.gutierrez@amd.com { 133911308Santhony.gutierrez@amd.com public: 134011347Sandreas.hansson@arm.com void generateDisassembly() override; 134111308Santhony.gutierrez@amd.com 134211308Santhony.gutierrez@amd.com AtomicInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 134311308Santhony.gutierrez@amd.com const char *_opcode) 134411308Santhony.gutierrez@amd.com : AtomicInstBase<typename MemDataType::OperandType, AddrOperandType, 134511308Santhony.gutierrez@amd.com NumSrcOperands, HasDst> 134611308Santhony.gutierrez@amd.com (ib, obj, _opcode), 134711308Santhony.gutierrez@amd.com MemInst(MemDataType::memType) 134811308Santhony.gutierrez@amd.com { 134911308Santhony.gutierrez@amd.com init_addr(&this->addr); 135011308Santhony.gutierrez@amd.com } 135111308Santhony.gutierrez@amd.com 135211308Santhony.gutierrez@amd.com void 135311308Santhony.gutierrez@amd.com initiateAcc(GPUDynInstPtr gpuDynInst) override 135411308Santhony.gutierrez@amd.com { 135511308Santhony.gutierrez@amd.com // before doing the RMW, check if this atomic has 135611308Santhony.gutierrez@amd.com // release semantics, and if so issue a release first 135711308Santhony.gutierrez@amd.com if (!isLocalMem()) { 135811308Santhony.gutierrez@amd.com if (gpuDynInst->computeUnit()->shader->separate_acquire_release 135911308Santhony.gutierrez@amd.com && (gpuDynInst->memoryOrder == 136011308Santhony.gutierrez@amd.com Enums::MEMORY_ORDER_SC_RELEASE || gpuDynInst->memoryOrder == 136111308Santhony.gutierrez@amd.com Enums::MEMORY_ORDER_SC_ACQUIRE_RELEASE)) { 136211308Santhony.gutierrez@amd.com 136311308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = VectorMask(1); 136411308Santhony.gutierrez@amd.com 136511308Santhony.gutierrez@amd.com gpuDynInst->execContinuation = &GPUStaticInst::execAtomic; 136611308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = true; 136711308Santhony.gutierrez@amd.com 136811308Santhony.gutierrez@amd.com // create request 136911308Santhony.gutierrez@amd.com Request *req = new Request(0, 0, 0, 0, 137011308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 137111435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId); 137211308Santhony.gutierrez@amd.com req->setFlags(Request::RELEASE); 137311308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->injectGlobalMemFence(gpuDynInst, false, req); 137411308Santhony.gutierrez@amd.com 137511308Santhony.gutierrez@amd.com return; 137611308Santhony.gutierrez@amd.com } 137711308Santhony.gutierrez@amd.com } 137811308Santhony.gutierrez@amd.com 137911308Santhony.gutierrez@amd.com // if there is no release semantic, execute the RMW immediately 138011308Santhony.gutierrez@amd.com execAtomic(gpuDynInst); 138111308Santhony.gutierrez@amd.com 138211308Santhony.gutierrez@amd.com } 138311308Santhony.gutierrez@amd.com 138411347Sandreas.hansson@arm.com void execute(GPUDynInstPtr gpuDynInst) override; 138511308Santhony.gutierrez@amd.com 138611308Santhony.gutierrez@amd.com bool 138711308Santhony.gutierrez@amd.com isLocalMem() const override 138811308Santhony.gutierrez@amd.com { 138911308Santhony.gutierrez@amd.com return this->segment == Brig::BRIG_SEGMENT_GROUP; 139011308Santhony.gutierrez@amd.com } 139111308Santhony.gutierrez@amd.com 139211308Santhony.gutierrez@amd.com private: 139311308Santhony.gutierrez@amd.com // execAtomic may be called through a continuation 139411308Santhony.gutierrez@amd.com // if the RMW had release semantics. see comment for 139511308Santhony.gutierrez@amd.com // execContinuation in gpu_dyn_inst.hh 139611308Santhony.gutierrez@amd.com void 139711308Santhony.gutierrez@amd.com execAtomic(GPUDynInstPtr gpuDynInst) override 139811308Santhony.gutierrez@amd.com { 139911308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = gpuDynInst->exec_mask; 140011308Santhony.gutierrez@amd.com 140111308Santhony.gutierrez@amd.com typedef typename MemDataType::CType c0; 140211308Santhony.gutierrez@amd.com 140311308Santhony.gutierrez@amd.com c0 *d = &((c0*) gpuDynInst->d_data)[0]; 140411308Santhony.gutierrez@amd.com c0 *e = &((c0*) gpuDynInst->a_data)[0]; 140511308Santhony.gutierrez@amd.com c0 *f = &((c0*) gpuDynInst->x_data)[0]; 140611308Santhony.gutierrez@amd.com 140711534Sjohn.kalamatianos@amd.com for (int i = 0; i < gpuDynInst->computeUnit()->wfSize(); ++i) { 140811308Santhony.gutierrez@amd.com if (gpuDynInst->exec_mask[i]) { 140911308Santhony.gutierrez@amd.com Addr vaddr = gpuDynInst->addr[i]; 141011308Santhony.gutierrez@amd.com 141111308Santhony.gutierrez@amd.com if (isLocalMem()) { 141211308Santhony.gutierrez@amd.com Wavefront *wavefront = gpuDynInst->wavefront(); 141311308Santhony.gutierrez@amd.com *d = wavefront->ldsChunk->read<c0>(vaddr); 141411308Santhony.gutierrez@amd.com 141511308Santhony.gutierrez@amd.com switch (this->opType) { 141611308Santhony.gutierrez@amd.com case Enums::MO_AADD: 141711308Santhony.gutierrez@amd.com case Enums::MO_ANRADD: 141811308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 141911308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) + (*e)); 142011308Santhony.gutierrez@amd.com break; 142111308Santhony.gutierrez@amd.com case Enums::MO_ASUB: 142211308Santhony.gutierrez@amd.com case Enums::MO_ANRSUB: 142311308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 142411308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) - (*e)); 142511308Santhony.gutierrez@amd.com break; 142611308Santhony.gutierrez@amd.com case Enums::MO_AMAX: 142711308Santhony.gutierrez@amd.com case Enums::MO_ANRMAX: 142811308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 142911308Santhony.gutierrez@amd.com std::max(wavefront->ldsChunk->read<c0>(vaddr), 143011308Santhony.gutierrez@amd.com (*e))); 143111308Santhony.gutierrez@amd.com break; 143211308Santhony.gutierrez@amd.com case Enums::MO_AMIN: 143311308Santhony.gutierrez@amd.com case Enums::MO_ANRMIN: 143411308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 143511308Santhony.gutierrez@amd.com std::min(wavefront->ldsChunk->read<c0>(vaddr), 143611308Santhony.gutierrez@amd.com (*e))); 143711308Santhony.gutierrez@amd.com break; 143811308Santhony.gutierrez@amd.com case Enums::MO_AAND: 143911308Santhony.gutierrez@amd.com case Enums::MO_ANRAND: 144011308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 144111308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) & (*e)); 144211308Santhony.gutierrez@amd.com break; 144311308Santhony.gutierrez@amd.com case Enums::MO_AOR: 144411308Santhony.gutierrez@amd.com case Enums::MO_ANROR: 144511308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 144611308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) | (*e)); 144711308Santhony.gutierrez@amd.com break; 144811308Santhony.gutierrez@amd.com case Enums::MO_AXOR: 144911308Santhony.gutierrez@amd.com case Enums::MO_ANRXOR: 145011308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 145111308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) ^ (*e)); 145211308Santhony.gutierrez@amd.com break; 145311308Santhony.gutierrez@amd.com case Enums::MO_AINC: 145411308Santhony.gutierrez@amd.com case Enums::MO_ANRINC: 145511308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 145611308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) + 1); 145711308Santhony.gutierrez@amd.com break; 145811308Santhony.gutierrez@amd.com case Enums::MO_ADEC: 145911308Santhony.gutierrez@amd.com case Enums::MO_ANRDEC: 146011308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 146111308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) - 1); 146211308Santhony.gutierrez@amd.com break; 146311308Santhony.gutierrez@amd.com case Enums::MO_AEXCH: 146411308Santhony.gutierrez@amd.com case Enums::MO_ANREXCH: 146511308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, (*e)); 146611308Santhony.gutierrez@amd.com break; 146711308Santhony.gutierrez@amd.com case Enums::MO_ACAS: 146811308Santhony.gutierrez@amd.com case Enums::MO_ANRCAS: 146911308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 147011308Santhony.gutierrez@amd.com (wavefront->ldsChunk->read<c0>(vaddr) == (*e)) ? 147111308Santhony.gutierrez@amd.com (*f) : wavefront->ldsChunk->read<c0>(vaddr)); 147211308Santhony.gutierrez@amd.com break; 147311308Santhony.gutierrez@amd.com default: 147411308Santhony.gutierrez@amd.com fatal("Unrecognized or invalid HSAIL atomic op " 147511308Santhony.gutierrez@amd.com "type.\n"); 147611308Santhony.gutierrez@amd.com break; 147711308Santhony.gutierrez@amd.com } 147811308Santhony.gutierrez@amd.com } else { 147911308Santhony.gutierrez@amd.com Request *req = 148011308Santhony.gutierrez@amd.com new Request(0, vaddr, sizeof(c0), 0, 148111308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 148211435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId, 148311308Santhony.gutierrez@amd.com gpuDynInst->makeAtomicOpFunctor<c0>(e, 148411308Santhony.gutierrez@amd.com f, this->opType)); 148511308Santhony.gutierrez@amd.com 148611308Santhony.gutierrez@amd.com gpuDynInst->setRequestFlags(req); 148711308Santhony.gutierrez@amd.com PacketPtr pkt = new Packet(req, MemCmd::SwapReq); 148811308Santhony.gutierrez@amd.com pkt->dataStatic(d); 148911308Santhony.gutierrez@amd.com 149011308Santhony.gutierrez@amd.com if (gpuDynInst->computeUnit()->shader-> 149111308Santhony.gutierrez@amd.com separate_acquire_release && 149211308Santhony.gutierrez@amd.com (gpuDynInst->memoryOrder == 149311308Santhony.gutierrez@amd.com Enums::MEMORY_ORDER_SC_ACQUIRE)) { 149411308Santhony.gutierrez@amd.com // if this atomic has acquire semantics, 149511308Santhony.gutierrez@amd.com // schedule the continuation to perform an 149611308Santhony.gutierrez@amd.com // acquire after the RMW completes 149711308Santhony.gutierrez@amd.com gpuDynInst->execContinuation = 149811308Santhony.gutierrez@amd.com &GPUStaticInst::execAtomicAcq; 149911308Santhony.gutierrez@amd.com 150011308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = true; 150111308Santhony.gutierrez@amd.com } else { 150211308Santhony.gutierrez@amd.com // the request will be finished when the RMW completes 150311308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 150411308Santhony.gutierrez@amd.com } 150511308Santhony.gutierrez@amd.com // translation is performed in sendRequest() 150611308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->sendRequest(gpuDynInst, i, 150711308Santhony.gutierrez@amd.com pkt); 150811308Santhony.gutierrez@amd.com } 150911308Santhony.gutierrez@amd.com } 151011308Santhony.gutierrez@amd.com 151111308Santhony.gutierrez@amd.com ++d; 151211308Santhony.gutierrez@amd.com ++e; 151311308Santhony.gutierrez@amd.com ++f; 151411308Santhony.gutierrez@amd.com } 151511308Santhony.gutierrez@amd.com 151611308Santhony.gutierrez@amd.com gpuDynInst->updateStats(); 151711308Santhony.gutierrez@amd.com } 151811308Santhony.gutierrez@amd.com 151911308Santhony.gutierrez@amd.com // execAtomicACq will always be called through a continuation. 152011308Santhony.gutierrez@amd.com // see comment for execContinuation in gpu_dyn_inst.hh 152111308Santhony.gutierrez@amd.com void 152211308Santhony.gutierrez@amd.com execAtomicAcq(GPUDynInstPtr gpuDynInst) override 152311308Santhony.gutierrez@amd.com { 152411308Santhony.gutierrez@amd.com // after performing the RMW, check to see if this instruction 152511308Santhony.gutierrez@amd.com // has acquire semantics, and if so, issue an acquire 152611308Santhony.gutierrez@amd.com if (!isLocalMem()) { 152711308Santhony.gutierrez@amd.com if (gpuDynInst->computeUnit()->shader->separate_acquire_release 152811308Santhony.gutierrez@amd.com && gpuDynInst->memoryOrder == 152911308Santhony.gutierrez@amd.com Enums::MEMORY_ORDER_SC_ACQUIRE) { 153011308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = VectorMask(1); 153111308Santhony.gutierrez@amd.com 153211308Santhony.gutierrez@amd.com // the request will be finished when 153311308Santhony.gutierrez@amd.com // the acquire completes 153411308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 153511308Santhony.gutierrez@amd.com // create request 153611308Santhony.gutierrez@amd.com Request *req = new Request(0, 0, 0, 0, 153711308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 153811435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId); 153911308Santhony.gutierrez@amd.com req->setFlags(Request::ACQUIRE); 154011308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->injectGlobalMemFence(gpuDynInst, false, req); 154111308Santhony.gutierrez@amd.com } 154211308Santhony.gutierrez@amd.com } 154311308Santhony.gutierrez@amd.com } 154411308Santhony.gutierrez@amd.com }; 154511308Santhony.gutierrez@amd.com 154611308Santhony.gutierrez@amd.com template<typename DataType, typename AddrOperandType, int NumSrcOperands> 154711308Santhony.gutierrez@amd.com GPUStaticInst* 154811308Santhony.gutierrez@amd.com constructAtomic(const Brig::BrigInstBase *ib, const BrigObject *obj) 154911308Santhony.gutierrez@amd.com { 155011308Santhony.gutierrez@amd.com const Brig::BrigInstAtomic *at = (const Brig::BrigInstAtomic*)ib; 155111308Santhony.gutierrez@amd.com 155211308Santhony.gutierrez@amd.com if (at->atomicOperation == Brig::BRIG_ATOMIC_LD) { 155311308Santhony.gutierrez@amd.com return decodeLd<DataType>(ib, obj); 155411308Santhony.gutierrez@amd.com } else if (at->atomicOperation == Brig::BRIG_ATOMIC_ST) { 155511308Santhony.gutierrez@amd.com switch (ib->type) { 155611308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B8: 155711308Santhony.gutierrez@amd.com return decodeSt<S8,S8>(ib, obj); 155811308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B16: 155911308Santhony.gutierrez@amd.com return decodeSt<S8,S16>(ib, obj); 156011308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B32: 156111308Santhony.gutierrez@amd.com return decodeSt<S8,S32>(ib, obj); 156211308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B64: 156311308Santhony.gutierrez@amd.com return decodeSt<S8,S64>(ib, obj); 156411308Santhony.gutierrez@amd.com default: fatal("AtomicSt: Operand type mismatch %d\n", ib->type); 156511308Santhony.gutierrez@amd.com } 156611308Santhony.gutierrez@amd.com } else { 156711308Santhony.gutierrez@amd.com if ((Brig::BrigOpcode)ib->opcode == Brig::BRIG_OPCODE_ATOMICNORET) 156811308Santhony.gutierrez@amd.com return new AtomicInst<DataType, AddrOperandType, 156911308Santhony.gutierrez@amd.com NumSrcOperands, false>(ib, obj, "atomicnoret"); 157011308Santhony.gutierrez@amd.com else 157111308Santhony.gutierrez@amd.com return new AtomicInst<DataType, AddrOperandType, 157211308Santhony.gutierrez@amd.com NumSrcOperands, true>(ib, obj, "atomic"); 157311308Santhony.gutierrez@amd.com } 157411308Santhony.gutierrez@amd.com } 157511308Santhony.gutierrez@amd.com 157611308Santhony.gutierrez@amd.com template<typename DataType, int NumSrcOperands> 157711308Santhony.gutierrez@amd.com GPUStaticInst* 157811308Santhony.gutierrez@amd.com decodeAtomicHelper(const Brig::BrigInstBase *ib, const BrigObject *obj) 157911308Santhony.gutierrez@amd.com { 158011308Santhony.gutierrez@amd.com unsigned addrIndex = (Brig::BrigOpcode)ib->opcode == 158111308Santhony.gutierrez@amd.com Brig::BRIG_OPCODE_ATOMICNORET ? 0 : 1; 158211308Santhony.gutierrez@amd.com 158311308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands,addrIndex); 158411308Santhony.gutierrez@amd.com 158511308Santhony.gutierrez@amd.com BrigRegOperandInfo tmp = findRegDataType(op_offs, obj); 158611308Santhony.gutierrez@amd.com 158711308Santhony.gutierrez@amd.com if (tmp.kind == Brig::BRIG_KIND_OPERAND_ADDRESS) { 158811308Santhony.gutierrez@amd.com return constructAtomic<DataType, NoRegAddrOperand, 158911308Santhony.gutierrez@amd.com NumSrcOperands>(ib, obj); 159011308Santhony.gutierrez@amd.com } else if (tmp.kind == Brig::BRIG_KIND_OPERAND_REGISTER) { 159111308Santhony.gutierrez@amd.com // V2/V4 not allowed 159211308Santhony.gutierrez@amd.com switch (tmp.regKind) { 159311308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_SINGLE: 159411308Santhony.gutierrez@amd.com return constructAtomic<DataType, SRegAddrOperand, 159511308Santhony.gutierrez@amd.com NumSrcOperands>(ib, obj); 159611308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_DOUBLE: 159711308Santhony.gutierrez@amd.com return constructAtomic<DataType, DRegAddrOperand, 159811308Santhony.gutierrez@amd.com NumSrcOperands>(ib, obj); 159911308Santhony.gutierrez@amd.com default: 160011308Santhony.gutierrez@amd.com fatal("Bad atomic register operand type %d\n", tmp.type); 160111308Santhony.gutierrez@amd.com } 160211308Santhony.gutierrez@amd.com } else { 160311308Santhony.gutierrez@amd.com fatal("Bad atomic register operand kind %d\n", tmp.kind); 160411308Santhony.gutierrez@amd.com } 160511308Santhony.gutierrez@amd.com } 160611308Santhony.gutierrez@amd.com 160711308Santhony.gutierrez@amd.com 160811308Santhony.gutierrez@amd.com template<typename DataType> 160911308Santhony.gutierrez@amd.com GPUStaticInst* 161011308Santhony.gutierrez@amd.com decodeAtomic(const Brig::BrigInstBase *ib, const BrigObject *obj) 161111308Santhony.gutierrez@amd.com { 161211308Santhony.gutierrez@amd.com const Brig::BrigInstAtomic *at = (const Brig::BrigInstAtomic*)ib; 161311308Santhony.gutierrez@amd.com 161411308Santhony.gutierrez@amd.com if (at->atomicOperation == Brig::BRIG_ATOMIC_CAS) { 161511308Santhony.gutierrez@amd.com return decodeAtomicHelper<DataType, 2>(ib, obj); 161611308Santhony.gutierrez@amd.com } else { 161711308Santhony.gutierrez@amd.com return decodeAtomicHelper<DataType, 1>(ib, obj); 161811308Santhony.gutierrez@amd.com } 161911308Santhony.gutierrez@amd.com } 162011308Santhony.gutierrez@amd.com 162111308Santhony.gutierrez@amd.com template<typename DataType> 162211308Santhony.gutierrez@amd.com GPUStaticInst* 162311308Santhony.gutierrez@amd.com decodeAtomicNoRet(const Brig::BrigInstBase *ib, const BrigObject *obj) 162411308Santhony.gutierrez@amd.com { 162511308Santhony.gutierrez@amd.com const Brig::BrigInstAtomic *at = (const Brig::BrigInstAtomic*)ib; 162611308Santhony.gutierrez@amd.com if (at->atomicOperation == Brig::BRIG_ATOMIC_CAS) { 162711308Santhony.gutierrez@amd.com return decodeAtomicHelper<DataType, 2>(ib, obj); 162811308Santhony.gutierrez@amd.com } else { 162911308Santhony.gutierrez@amd.com return decodeAtomicHelper<DataType, 1>(ib, obj); 163011308Santhony.gutierrez@amd.com } 163111308Santhony.gutierrez@amd.com } 163211308Santhony.gutierrez@amd.com} // namespace HsailISA 163311308Santhony.gutierrez@amd.com 163411308Santhony.gutierrez@amd.com#endif // __ARCH_HSAIL_INSTS_MEM_HH__ 1635