mem.hh revision 11692
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2012-2015 Advanced Micro Devices, Inc. 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only 611308Santhony.gutierrez@amd.com * 711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met: 911308Santhony.gutierrez@amd.com * 1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice, 1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer. 1211308Santhony.gutierrez@amd.com * 1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice, 1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation 1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution. 1611308Santhony.gutierrez@amd.com * 1711308Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its contributors 1811308Santhony.gutierrez@amd.com * may be used to endorse or promote products derived from this software 1911308Santhony.gutierrez@amd.com * without specific prior written permission. 2011308Santhony.gutierrez@amd.com * 2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE. 3211308Santhony.gutierrez@amd.com * 3311308Santhony.gutierrez@amd.com * Author: Steve Reinhardt 3411308Santhony.gutierrez@amd.com */ 3511308Santhony.gutierrez@amd.com 3611308Santhony.gutierrez@amd.com#ifndef __ARCH_HSAIL_INSTS_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 9911692Santhony.gutierrez@amd.com setFlag(ALU); 10011692Santhony.gutierrez@amd.com 10111308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 10211308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 10311308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 10411308Santhony.gutierrez@amd.com addr.init(op_offs, obj); 10511308Santhony.gutierrez@amd.com } 10611308Santhony.gutierrez@amd.com 10711347Sandreas.hansson@arm.com int numSrcRegOperands() override 10811347Sandreas.hansson@arm.com { return(this->addr.isVectorRegister()); } 10911347Sandreas.hansson@arm.com int numDstRegOperands() override 11011347Sandreas.hansson@arm.com { return dest.isVectorRegister(); } 11111347Sandreas.hansson@arm.com bool isVectorRegister(int operandIndex) override 11211308Santhony.gutierrez@amd.com { 11311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 11411308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.isVectorRegister() : 11511308Santhony.gutierrez@amd.com this->addr.isVectorRegister()); 11611308Santhony.gutierrez@amd.com } 11711347Sandreas.hansson@arm.com bool isCondRegister(int operandIndex) override 11811308Santhony.gutierrez@amd.com { 11911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 12011308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.isCondRegister() : 12111308Santhony.gutierrez@amd.com this->addr.isCondRegister()); 12211308Santhony.gutierrez@amd.com } 12311347Sandreas.hansson@arm.com bool isScalarRegister(int operandIndex) override 12411308Santhony.gutierrez@amd.com { 12511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 12611308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.isScalarRegister() : 12711308Santhony.gutierrez@amd.com this->addr.isScalarRegister()); 12811308Santhony.gutierrez@amd.com } 12911347Sandreas.hansson@arm.com bool isSrcOperand(int operandIndex) override 13011308Santhony.gutierrez@amd.com { 13111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 13211308Santhony.gutierrez@amd.com if (operandIndex > 0) 13311308Santhony.gutierrez@amd.com return(this->addr.isVectorRegister()); 13411308Santhony.gutierrez@amd.com return false; 13511308Santhony.gutierrez@amd.com } 13611347Sandreas.hansson@arm.com bool isDstOperand(int operandIndex) override { 13711308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 13811308Santhony.gutierrez@amd.com return(operandIndex == 0); 13911308Santhony.gutierrez@amd.com } 14011347Sandreas.hansson@arm.com int getOperandSize(int operandIndex) override 14111308Santhony.gutierrez@amd.com { 14211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 14311308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.opSize() : 14411308Santhony.gutierrez@amd.com this->addr.opSize()); 14511308Santhony.gutierrez@amd.com } 14611347Sandreas.hansson@arm.com int getRegisterIndex(int operandIndex) override 14711308Santhony.gutierrez@amd.com { 14811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 14911308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.regIndex() : 15011308Santhony.gutierrez@amd.com this->addr.regIndex()); 15111308Santhony.gutierrez@amd.com } 15211347Sandreas.hansson@arm.com int getNumOperands() override 15311308Santhony.gutierrez@amd.com { 15411308Santhony.gutierrez@amd.com if (this->addr.isVectorRegister()) 15511308Santhony.gutierrez@amd.com return 2; 15611308Santhony.gutierrez@amd.com return 1; 15711308Santhony.gutierrez@amd.com } 15811308Santhony.gutierrez@amd.com }; 15911308Santhony.gutierrez@amd.com 16011308Santhony.gutierrez@amd.com template<typename DestDataType, typename AddrOperandType> 16111308Santhony.gutierrez@amd.com class LdaInst : 16211308Santhony.gutierrez@amd.com public LdaInstBase<typename DestDataType::OperandType, AddrOperandType>, 16311308Santhony.gutierrez@amd.com public MemInst 16411308Santhony.gutierrez@amd.com { 16511308Santhony.gutierrez@amd.com public: 16611308Santhony.gutierrez@amd.com void generateDisassembly(); 16711308Santhony.gutierrez@amd.com 16811308Santhony.gutierrez@amd.com LdaInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 16911308Santhony.gutierrez@amd.com const char *_opcode) 17011308Santhony.gutierrez@amd.com : LdaInstBase<typename DestDataType::OperandType, 17111308Santhony.gutierrez@amd.com AddrOperandType>(ib, obj, _opcode) 17211308Santhony.gutierrez@amd.com { 17311308Santhony.gutierrez@amd.com init_addr(&this->addr); 17411308Santhony.gutierrez@amd.com } 17511308Santhony.gutierrez@amd.com 17611308Santhony.gutierrez@amd.com void execute(GPUDynInstPtr gpuDynInst); 17711308Santhony.gutierrez@amd.com }; 17811308Santhony.gutierrez@amd.com 17911308Santhony.gutierrez@amd.com template<typename DataType> 18011308Santhony.gutierrez@amd.com GPUStaticInst* 18111308Santhony.gutierrez@amd.com decodeLda(const Brig::BrigInstBase *ib, const BrigObject *obj) 18211308Santhony.gutierrez@amd.com { 18311308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 1); 18411308Santhony.gutierrez@amd.com BrigRegOperandInfo regDataType = findRegDataType(op_offs, obj); 18511308Santhony.gutierrez@amd.com 18611308Santhony.gutierrez@amd.com if (regDataType.kind == Brig::BRIG_KIND_OPERAND_ADDRESS) { 18711308Santhony.gutierrez@amd.com return new LdaInst<DataType, NoRegAddrOperand>(ib, obj, "ldas"); 18811308Santhony.gutierrez@amd.com } else if (regDataType.kind == Brig::BRIG_KIND_OPERAND_REGISTER) { 18911308Santhony.gutierrez@amd.com // V2/V4 not allowed 19011308Santhony.gutierrez@amd.com switch (regDataType.regKind) { 19111308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_SINGLE: 19211308Santhony.gutierrez@amd.com return new LdaInst<DataType, SRegAddrOperand>(ib, obj, "ldas"); 19311308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_DOUBLE: 19411308Santhony.gutierrez@amd.com return new LdaInst<DataType, DRegAddrOperand>(ib, obj, "ldas"); 19511308Santhony.gutierrez@amd.com default: 19611308Santhony.gutierrez@amd.com fatal("Bad ldas register operand type %d\n", regDataType.type); 19711308Santhony.gutierrez@amd.com } 19811308Santhony.gutierrez@amd.com } else { 19911308Santhony.gutierrez@amd.com fatal("Bad ldas register operand kind %d\n", regDataType.kind); 20011308Santhony.gutierrez@amd.com } 20111308Santhony.gutierrez@amd.com } 20211308Santhony.gutierrez@amd.com 20311308Santhony.gutierrez@amd.com template<typename MemOperandType, typename DestOperandType, 20411308Santhony.gutierrez@amd.com typename AddrOperandType> 20511308Santhony.gutierrez@amd.com class LdInstBase : public HsailGPUStaticInst 20611308Santhony.gutierrez@amd.com { 20711308Santhony.gutierrez@amd.com public: 20811308Santhony.gutierrez@amd.com Brig::BrigWidth8_t width; 20911308Santhony.gutierrez@amd.com typename DestOperandType::DestOperand dest; 21011308Santhony.gutierrez@amd.com AddrOperandType addr; 21111308Santhony.gutierrez@amd.com 21211308Santhony.gutierrez@amd.com Brig::BrigSegment segment; 21311308Santhony.gutierrez@amd.com Brig::BrigMemoryOrder memoryOrder; 21411308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memoryScope; 21511308Santhony.gutierrez@amd.com unsigned int equivClass; 21611308Santhony.gutierrez@amd.com 21711308Santhony.gutierrez@amd.com LdInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, 21811308Santhony.gutierrez@amd.com const char *_opcode) 21911308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 22011308Santhony.gutierrez@amd.com { 22111308Santhony.gutierrez@amd.com using namespace Brig; 22211308Santhony.gutierrez@amd.com 22311692Santhony.gutierrez@amd.com setFlag(MemoryRef); 22411692Santhony.gutierrez@amd.com setFlag(Load); 22511692Santhony.gutierrez@amd.com 22611308Santhony.gutierrez@amd.com if (ib->opcode == BRIG_OPCODE_LD) { 22711692Santhony.gutierrez@amd.com const BrigInstMem *ldst = (const BrigInstMem*)ib; 22811692Santhony.gutierrez@amd.com 22911692Santhony.gutierrez@amd.com segment = (BrigSegment)ldst->segment; 23011692Santhony.gutierrez@amd.com memoryOrder = BRIG_MEMORY_ORDER_NONE; 23111692Santhony.gutierrez@amd.com memoryScope = BRIG_MEMORY_SCOPE_NONE; 23211692Santhony.gutierrez@amd.com equivClass = ldst->equivClass; 23311692Santhony.gutierrez@amd.com 23411692Santhony.gutierrez@amd.com width = ldst->width; 23511692Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 23611692Santhony.gutierrez@amd.com const Brig::BrigOperand *brigOp = obj->getOperand(op_offs); 23711692Santhony.gutierrez@amd.com if (brigOp->kind == BRIG_KIND_OPERAND_REGISTER) 23811692Santhony.gutierrez@amd.com dest.init(op_offs, obj); 23911692Santhony.gutierrez@amd.com 24011692Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 24111692Santhony.gutierrez@amd.com addr.init(op_offs, obj); 24211308Santhony.gutierrez@amd.com } else { 24311692Santhony.gutierrez@amd.com const BrigInstAtomic *at = (const BrigInstAtomic*)ib; 24411692Santhony.gutierrez@amd.com 24511692Santhony.gutierrez@amd.com segment = (BrigSegment)at->segment; 24611692Santhony.gutierrez@amd.com memoryOrder = (BrigMemoryOrder)at->memoryOrder; 24711692Santhony.gutierrez@amd.com memoryScope = (BrigMemoryScope)at->memoryScope; 24811692Santhony.gutierrez@amd.com equivClass = 0; 24911692Santhony.gutierrez@amd.com 25011692Santhony.gutierrez@amd.com width = BRIG_WIDTH_1; 25111692Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 25211692Santhony.gutierrez@amd.com const Brig::BrigOperand *brigOp = obj->getOperand(op_offs); 25311692Santhony.gutierrez@amd.com 25411692Santhony.gutierrez@amd.com if (brigOp->kind == BRIG_KIND_OPERAND_REGISTER) 25511692Santhony.gutierrez@amd.com dest.init(op_offs, obj); 25611692Santhony.gutierrez@amd.com 25711692Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands,1); 25811692Santhony.gutierrez@amd.com addr.init(op_offs, obj); 25911692Santhony.gutierrez@amd.com } 26011692Santhony.gutierrez@amd.com 26111692Santhony.gutierrez@amd.com switch (memoryOrder) { 26211692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_NONE: 26311692Santhony.gutierrez@amd.com setFlag(NoOrder); 26411692Santhony.gutierrez@amd.com break; 26511692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_RELAXED: 26611692Santhony.gutierrez@amd.com setFlag(RelaxedOrder); 26711692Santhony.gutierrez@amd.com break; 26811692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_SC_ACQUIRE: 26911692Santhony.gutierrez@amd.com setFlag(Acquire); 27011692Santhony.gutierrez@amd.com break; 27111692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_SC_RELEASE: 27211692Santhony.gutierrez@amd.com setFlag(Release); 27311692Santhony.gutierrez@amd.com break; 27411692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE: 27511692Santhony.gutierrez@amd.com setFlag(AcquireRelease); 27611692Santhony.gutierrez@amd.com break; 27711692Santhony.gutierrez@amd.com default: 27811692Santhony.gutierrez@amd.com fatal("LdInst has bad memory order type\n"); 27911692Santhony.gutierrez@amd.com } 28011692Santhony.gutierrez@amd.com 28111692Santhony.gutierrez@amd.com switch (memoryScope) { 28211692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_NONE: 28311692Santhony.gutierrez@amd.com setFlag(NoScope); 28411692Santhony.gutierrez@amd.com break; 28511692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_WORKITEM: 28611692Santhony.gutierrez@amd.com setFlag(WorkitemScope); 28711692Santhony.gutierrez@amd.com break; 28811692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_WORKGROUP: 28911692Santhony.gutierrez@amd.com setFlag(WorkgroupScope); 29011692Santhony.gutierrez@amd.com break; 29111692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_AGENT: 29211692Santhony.gutierrez@amd.com setFlag(DeviceScope); 29311692Santhony.gutierrez@amd.com break; 29411692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_SYSTEM: 29511692Santhony.gutierrez@amd.com setFlag(SystemScope); 29611692Santhony.gutierrez@amd.com break; 29711692Santhony.gutierrez@amd.com default: 29811692Santhony.gutierrez@amd.com fatal("LdInst has bad memory scope type\n"); 29911692Santhony.gutierrez@amd.com } 30011692Santhony.gutierrez@amd.com 30111692Santhony.gutierrez@amd.com switch (segment) { 30211692Santhony.gutierrez@amd.com case BRIG_SEGMENT_GLOBAL: 30311692Santhony.gutierrez@amd.com setFlag(GlobalSegment); 30411692Santhony.gutierrez@amd.com break; 30511692Santhony.gutierrez@amd.com case BRIG_SEGMENT_GROUP: 30611692Santhony.gutierrez@amd.com setFlag(GroupSegment); 30711692Santhony.gutierrez@amd.com break; 30811692Santhony.gutierrez@amd.com case BRIG_SEGMENT_PRIVATE: 30911692Santhony.gutierrez@amd.com setFlag(PrivateSegment); 31011692Santhony.gutierrez@amd.com break; 31111692Santhony.gutierrez@amd.com case BRIG_SEGMENT_READONLY: 31211692Santhony.gutierrez@amd.com setFlag(ReadOnlySegment); 31311692Santhony.gutierrez@amd.com break; 31411692Santhony.gutierrez@amd.com case BRIG_SEGMENT_SPILL: 31511692Santhony.gutierrez@amd.com setFlag(SpillSegment); 31611692Santhony.gutierrez@amd.com break; 31711692Santhony.gutierrez@amd.com case BRIG_SEGMENT_FLAT: 31811692Santhony.gutierrez@amd.com setFlag(Flat); 31911692Santhony.gutierrez@amd.com break; 32011692Santhony.gutierrez@amd.com case BRIG_SEGMENT_KERNARG: 32111692Santhony.gutierrez@amd.com setFlag(KernArgSegment); 32211692Santhony.gutierrez@amd.com break; 32311692Santhony.gutierrez@amd.com case BRIG_SEGMENT_ARG: 32411692Santhony.gutierrez@amd.com setFlag(ArgSegment); 32511692Santhony.gutierrez@amd.com break; 32611692Santhony.gutierrez@amd.com default: 32711692Santhony.gutierrez@amd.com panic("Ld: segment %d not supported\n", segment); 32811308Santhony.gutierrez@amd.com } 32911308Santhony.gutierrez@amd.com } 33011308Santhony.gutierrez@amd.com 33111347Sandreas.hansson@arm.com int numSrcRegOperands() override 33211347Sandreas.hansson@arm.com { return(this->addr.isVectorRegister()); } 33311347Sandreas.hansson@arm.com int numDstRegOperands() override { return dest.isVectorRegister(); } 33411347Sandreas.hansson@arm.com int getNumOperands() override 33511308Santhony.gutierrez@amd.com { 33611308Santhony.gutierrez@amd.com if (this->addr.isVectorRegister()) 33711308Santhony.gutierrez@amd.com return 2; 33811308Santhony.gutierrez@amd.com else 33911308Santhony.gutierrez@amd.com return 1; 34011308Santhony.gutierrez@amd.com } 34111347Sandreas.hansson@arm.com bool isVectorRegister(int operandIndex) override 34211308Santhony.gutierrez@amd.com { 34311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 34411308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.isVectorRegister() : 34511308Santhony.gutierrez@amd.com this->addr.isVectorRegister()); 34611308Santhony.gutierrez@amd.com } 34711347Sandreas.hansson@arm.com bool isCondRegister(int operandIndex) override 34811308Santhony.gutierrez@amd.com { 34911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 35011308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.isCondRegister() : 35111308Santhony.gutierrez@amd.com this->addr.isCondRegister()); 35211308Santhony.gutierrez@amd.com } 35311347Sandreas.hansson@arm.com bool isScalarRegister(int operandIndex) override 35411308Santhony.gutierrez@amd.com { 35511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 35611308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.isScalarRegister() : 35711308Santhony.gutierrez@amd.com this->addr.isScalarRegister()); 35811308Santhony.gutierrez@amd.com } 35911347Sandreas.hansson@arm.com bool isSrcOperand(int operandIndex) override 36011308Santhony.gutierrez@amd.com { 36111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 36211308Santhony.gutierrez@amd.com if (operandIndex > 0) 36311308Santhony.gutierrez@amd.com return(this->addr.isVectorRegister()); 36411308Santhony.gutierrez@amd.com return false; 36511308Santhony.gutierrez@amd.com } 36611347Sandreas.hansson@arm.com bool isDstOperand(int operandIndex) override 36711308Santhony.gutierrez@amd.com { 36811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 36911308Santhony.gutierrez@amd.com return(operandIndex == 0); 37011308Santhony.gutierrez@amd.com } 37111347Sandreas.hansson@arm.com int getOperandSize(int operandIndex) override 37211308Santhony.gutierrez@amd.com { 37311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 37411308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.opSize() : 37511308Santhony.gutierrez@amd.com this->addr.opSize()); 37611308Santhony.gutierrez@amd.com } 37711347Sandreas.hansson@arm.com int getRegisterIndex(int operandIndex) override 37811308Santhony.gutierrez@amd.com { 37911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 38011308Santhony.gutierrez@amd.com return((operandIndex == 0) ? dest.regIndex() : 38111308Santhony.gutierrez@amd.com this->addr.regIndex()); 38211308Santhony.gutierrez@amd.com } 38311308Santhony.gutierrez@amd.com }; 38411308Santhony.gutierrez@amd.com 38511308Santhony.gutierrez@amd.com template<typename MemDataType, typename DestDataType, 38611308Santhony.gutierrez@amd.com typename AddrOperandType> 38711308Santhony.gutierrez@amd.com class LdInst : 38811308Santhony.gutierrez@amd.com public LdInstBase<typename MemDataType::CType, 38911308Santhony.gutierrez@amd.com typename DestDataType::OperandType, AddrOperandType>, 39011308Santhony.gutierrez@amd.com public MemInst 39111308Santhony.gutierrez@amd.com { 39211308Santhony.gutierrez@amd.com typename DestDataType::OperandType::DestOperand dest_vect[4]; 39311308Santhony.gutierrez@amd.com uint16_t num_dest_operands; 39411347Sandreas.hansson@arm.com void generateDisassembly() override; 39511308Santhony.gutierrez@amd.com 39611308Santhony.gutierrez@amd.com public: 39711308Santhony.gutierrez@amd.com LdInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 39811308Santhony.gutierrez@amd.com const char *_opcode) 39911308Santhony.gutierrez@amd.com : LdInstBase<typename MemDataType::CType, 40011308Santhony.gutierrez@amd.com typename DestDataType::OperandType, 40111308Santhony.gutierrez@amd.com AddrOperandType>(ib, obj, _opcode), 40211308Santhony.gutierrez@amd.com MemInst(MemDataType::memType) 40311308Santhony.gutierrez@amd.com { 40411308Santhony.gutierrez@amd.com init_addr(&this->addr); 40511308Santhony.gutierrez@amd.com 40611308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands,0); 40711308Santhony.gutierrez@amd.com const Brig::BrigOperand *brigOp = obj->getOperand(op_offs); 40811308Santhony.gutierrez@amd.com 40911308Santhony.gutierrez@amd.com if (brigOp->kind == Brig::BRIG_KIND_OPERAND_OPERAND_LIST) { 41011308Santhony.gutierrez@amd.com const Brig::BrigOperandOperandList *brigRegVecOp = 41111308Santhony.gutierrez@amd.com (const Brig::BrigOperandOperandList*)brigOp; 41211308Santhony.gutierrez@amd.com 41311308Santhony.gutierrez@amd.com num_dest_operands = 41411308Santhony.gutierrez@amd.com *((unsigned*)obj->getData(brigRegVecOp->elements)) / 4; 41511308Santhony.gutierrez@amd.com 41611308Santhony.gutierrez@amd.com assert(num_dest_operands <= 4); 41711308Santhony.gutierrez@amd.com } else { 41811308Santhony.gutierrez@amd.com num_dest_operands = 1; 41911308Santhony.gutierrez@amd.com } 42011308Santhony.gutierrez@amd.com 42111308Santhony.gutierrez@amd.com if (num_dest_operands > 1) { 42211308Santhony.gutierrez@amd.com assert(brigOp->kind == Brig::BRIG_KIND_OPERAND_OPERAND_LIST); 42311308Santhony.gutierrez@amd.com 42411308Santhony.gutierrez@amd.com for (int i = 0; i < num_dest_operands; ++i) { 42511308Santhony.gutierrez@amd.com dest_vect[i].init_from_vect(op_offs, obj, i); 42611308Santhony.gutierrez@amd.com } 42711308Santhony.gutierrez@amd.com } 42811308Santhony.gutierrez@amd.com } 42911308Santhony.gutierrez@amd.com 43011308Santhony.gutierrez@amd.com void 43111308Santhony.gutierrez@amd.com initiateAcc(GPUDynInstPtr gpuDynInst) override 43211308Santhony.gutierrez@amd.com { 43311308Santhony.gutierrez@amd.com typedef typename MemDataType::CType c0; 43411308Santhony.gutierrez@amd.com 43511308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = gpuDynInst->exec_mask; 43611308Santhony.gutierrez@amd.com 43711308Santhony.gutierrez@amd.com if (num_dest_operands > 1) { 43811534Sjohn.kalamatianos@amd.com for (int i = 0; i < gpuDynInst->computeUnit()->wfSize(); ++i) 43911308Santhony.gutierrez@amd.com if (gpuDynInst->exec_mask[i]) 44011308Santhony.gutierrez@amd.com gpuDynInst->statusVector.push_back(num_dest_operands); 44111308Santhony.gutierrez@amd.com else 44211308Santhony.gutierrez@amd.com gpuDynInst->statusVector.push_back(0); 44311308Santhony.gutierrez@amd.com } 44411308Santhony.gutierrez@amd.com 44511308Santhony.gutierrez@amd.com for (int k = 0; k < num_dest_operands; ++k) { 44611308Santhony.gutierrez@amd.com 44711534Sjohn.kalamatianos@amd.com c0 *d = &((c0*)gpuDynInst->d_data) 44811534Sjohn.kalamatianos@amd.com [k * gpuDynInst->computeUnit()->wfSize()]; 44911308Santhony.gutierrez@amd.com 45011534Sjohn.kalamatianos@amd.com for (int i = 0; i < gpuDynInst->computeUnit()->wfSize(); ++i) { 45111308Santhony.gutierrez@amd.com if (gpuDynInst->exec_mask[i]) { 45211308Santhony.gutierrez@amd.com Addr vaddr = gpuDynInst->addr[i] + k * sizeof(c0); 45311308Santhony.gutierrez@amd.com 45411692Santhony.gutierrez@amd.com if (this->isLocalMem()) { 45511308Santhony.gutierrez@amd.com // load from shared memory 45611308Santhony.gutierrez@amd.com *d = gpuDynInst->wavefront()->ldsChunk-> 45711308Santhony.gutierrez@amd.com read<c0>(vaddr); 45811308Santhony.gutierrez@amd.com } else { 45911308Santhony.gutierrez@amd.com Request *req = new Request(0, vaddr, sizeof(c0), 0, 46011308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 46111435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId); 46211308Santhony.gutierrez@amd.com 46311308Santhony.gutierrez@amd.com gpuDynInst->setRequestFlags(req); 46411308Santhony.gutierrez@amd.com PacketPtr pkt = new Packet(req, MemCmd::ReadReq); 46511308Santhony.gutierrez@amd.com pkt->dataStatic(d); 46611308Santhony.gutierrez@amd.com 46711308Santhony.gutierrez@amd.com if (gpuDynInst->computeUnit()->shader-> 46811308Santhony.gutierrez@amd.com separate_acquire_release && 46911692Santhony.gutierrez@amd.com gpuDynInst->isAcquire()) { 47011308Santhony.gutierrez@amd.com // if this load has acquire semantics, 47111308Santhony.gutierrez@amd.com // set the response continuation function 47211308Santhony.gutierrez@amd.com // to perform an Acquire request 47311308Santhony.gutierrez@amd.com gpuDynInst->execContinuation = 47411308Santhony.gutierrez@amd.com &GPUStaticInst::execLdAcq; 47511308Santhony.gutierrez@amd.com 47611308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = true; 47711308Santhony.gutierrez@amd.com } else { 47811308Santhony.gutierrez@amd.com // the request will be finished when 47911308Santhony.gutierrez@amd.com // the load completes 48011308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 48111308Santhony.gutierrez@amd.com } 48211308Santhony.gutierrez@amd.com // translation is performed in sendRequest() 48311308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->sendRequest(gpuDynInst, 48411308Santhony.gutierrez@amd.com i, pkt); 48511308Santhony.gutierrez@amd.com } 48611308Santhony.gutierrez@amd.com } 48711308Santhony.gutierrez@amd.com ++d; 48811308Santhony.gutierrez@amd.com } 48911308Santhony.gutierrez@amd.com } 49011308Santhony.gutierrez@amd.com 49111308Santhony.gutierrez@amd.com gpuDynInst->updateStats(); 49211308Santhony.gutierrez@amd.com } 49311308Santhony.gutierrez@amd.com 49411308Santhony.gutierrez@amd.com private: 49511308Santhony.gutierrez@amd.com void 49611308Santhony.gutierrez@amd.com execLdAcq(GPUDynInstPtr gpuDynInst) override 49711308Santhony.gutierrez@amd.com { 49811308Santhony.gutierrez@amd.com // after the load has complete and if the load has acquire 49911308Santhony.gutierrez@amd.com // semantics, issue an acquire request. 50011692Santhony.gutierrez@amd.com if (!this->isLocalMem()) { 50111308Santhony.gutierrez@amd.com if (gpuDynInst->computeUnit()->shader->separate_acquire_release 50211692Santhony.gutierrez@amd.com && gpuDynInst->isAcquire()) { 50311308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = VectorMask(1); 50411308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 50511308Santhony.gutierrez@amd.com // create request 50611308Santhony.gutierrez@amd.com Request *req = new Request(0, 0, 0, 0, 50711308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 50811435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId); 50911308Santhony.gutierrez@amd.com req->setFlags(Request::ACQUIRE); 51011308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->injectGlobalMemFence(gpuDynInst, false, req); 51111308Santhony.gutierrez@amd.com } 51211308Santhony.gutierrez@amd.com } 51311308Santhony.gutierrez@amd.com } 51411308Santhony.gutierrez@amd.com 51511308Santhony.gutierrez@amd.com public: 51611347Sandreas.hansson@arm.com bool isVectorRegister(int operandIndex) override 51711308Santhony.gutierrez@amd.com { 51811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 51911308Santhony.gutierrez@amd.com if ((num_dest_operands != getNumOperands()) && 52011308Santhony.gutierrez@amd.com (operandIndex == (getNumOperands()-1))) 52111308Santhony.gutierrez@amd.com return(this->addr.isVectorRegister()); 52211308Santhony.gutierrez@amd.com if (num_dest_operands > 1) { 52311308Santhony.gutierrez@amd.com return dest_vect[operandIndex].isVectorRegister(); 52411308Santhony.gutierrez@amd.com } 52511308Santhony.gutierrez@amd.com else if (num_dest_operands == 1) { 52611308Santhony.gutierrez@amd.com return LdInstBase<typename MemDataType::CType, 52711308Santhony.gutierrez@amd.com typename DestDataType::OperandType, 52811308Santhony.gutierrez@amd.com AddrOperandType>::dest.isVectorRegister(); 52911308Santhony.gutierrez@amd.com } 53011308Santhony.gutierrez@amd.com return false; 53111308Santhony.gutierrez@amd.com } 53211347Sandreas.hansson@arm.com bool isCondRegister(int operandIndex) override 53311308Santhony.gutierrez@amd.com { 53411308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 53511308Santhony.gutierrez@amd.com if ((num_dest_operands != getNumOperands()) && 53611308Santhony.gutierrez@amd.com (operandIndex == (getNumOperands()-1))) 53711308Santhony.gutierrez@amd.com return(this->addr.isCondRegister()); 53811308Santhony.gutierrez@amd.com if (num_dest_operands > 1) 53911308Santhony.gutierrez@amd.com return dest_vect[operandIndex].isCondRegister(); 54011308Santhony.gutierrez@amd.com else if (num_dest_operands == 1) 54111308Santhony.gutierrez@amd.com return LdInstBase<typename MemDataType::CType, 54211308Santhony.gutierrez@amd.com typename DestDataType::OperandType, 54311308Santhony.gutierrez@amd.com AddrOperandType>::dest.isCondRegister(); 54411308Santhony.gutierrez@amd.com return false; 54511308Santhony.gutierrez@amd.com } 54611347Sandreas.hansson@arm.com bool isScalarRegister(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.isScalarRegister()); 55211308Santhony.gutierrez@amd.com if (num_dest_operands > 1) 55311308Santhony.gutierrez@amd.com return dest_vect[operandIndex].isScalarRegister(); 55411308Santhony.gutierrez@amd.com else if (num_dest_operands == 1) 55511308Santhony.gutierrez@amd.com return LdInstBase<typename MemDataType::CType, 55611308Santhony.gutierrez@amd.com typename DestDataType::OperandType, 55711308Santhony.gutierrez@amd.com AddrOperandType>::dest.isScalarRegister(); 55811308Santhony.gutierrez@amd.com return false; 55911308Santhony.gutierrez@amd.com } 56011347Sandreas.hansson@arm.com bool isSrcOperand(int operandIndex) override 56111308Santhony.gutierrez@amd.com { 56211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 56311308Santhony.gutierrez@amd.com if ((num_dest_operands != getNumOperands()) && 56411308Santhony.gutierrez@amd.com (operandIndex == (getNumOperands()-1))) 56511308Santhony.gutierrez@amd.com return(this->addr.isVectorRegister()); 56611308Santhony.gutierrez@amd.com return false; 56711308Santhony.gutierrez@amd.com } 56811347Sandreas.hansson@arm.com bool isDstOperand(int operandIndex) override 56911308Santhony.gutierrez@amd.com { 57011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 57111308Santhony.gutierrez@amd.com if ((num_dest_operands != getNumOperands()) && 57211308Santhony.gutierrez@amd.com (operandIndex == (getNumOperands()-1))) 57311308Santhony.gutierrez@amd.com return false; 57411308Santhony.gutierrez@amd.com return true; 57511308Santhony.gutierrez@amd.com } 57611347Sandreas.hansson@arm.com int getOperandSize(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.opSize()); 58211308Santhony.gutierrez@amd.com if (num_dest_operands > 1) 58311308Santhony.gutierrez@amd.com return(dest_vect[operandIndex].opSize()); 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.opSize()); 58811308Santhony.gutierrez@amd.com return 0; 58911308Santhony.gutierrez@amd.com } 59011347Sandreas.hansson@arm.com int getRegisterIndex(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.regIndex()); 59611308Santhony.gutierrez@amd.com if (num_dest_operands > 1) 59711308Santhony.gutierrez@amd.com return(dest_vect[operandIndex].regIndex()); 59811308Santhony.gutierrez@amd.com else if (num_dest_operands == 1) 59911308Santhony.gutierrez@amd.com return(LdInstBase<typename MemDataType::CType, 60011308Santhony.gutierrez@amd.com typename DestDataType::OperandType, 60111308Santhony.gutierrez@amd.com AddrOperandType>::dest.regIndex()); 60211308Santhony.gutierrez@amd.com return -1; 60311308Santhony.gutierrez@amd.com } 60411347Sandreas.hansson@arm.com int getNumOperands() override 60511308Santhony.gutierrez@amd.com { 60611308Santhony.gutierrez@amd.com if (this->addr.isVectorRegister() || this->addr.isScalarRegister()) 60711308Santhony.gutierrez@amd.com return(num_dest_operands+1); 60811308Santhony.gutierrez@amd.com else 60911308Santhony.gutierrez@amd.com return(num_dest_operands); 61011308Santhony.gutierrez@amd.com } 61111347Sandreas.hansson@arm.com void execute(GPUDynInstPtr gpuDynInst) override; 61211308Santhony.gutierrez@amd.com }; 61311308Santhony.gutierrez@amd.com 61411308Santhony.gutierrez@amd.com template<typename MemDT, typename DestDT> 61511308Santhony.gutierrez@amd.com GPUStaticInst* 61611308Santhony.gutierrez@amd.com decodeLd2(const Brig::BrigInstBase *ib, const BrigObject *obj) 61711308Santhony.gutierrez@amd.com { 61811308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands,1); 61911308Santhony.gutierrez@amd.com BrigRegOperandInfo tmp = findRegDataType(op_offs, obj); 62011308Santhony.gutierrez@amd.com 62111308Santhony.gutierrez@amd.com if (tmp.kind == Brig::BRIG_KIND_OPERAND_ADDRESS) { 62211308Santhony.gutierrez@amd.com return new LdInst<MemDT, DestDT, NoRegAddrOperand>(ib, obj, "ld"); 62311308Santhony.gutierrez@amd.com } else if (tmp.kind == Brig::BRIG_KIND_OPERAND_REGISTER || 62411308Santhony.gutierrez@amd.com tmp.kind == Brig::BRIG_KIND_OPERAND_OPERAND_LIST) { 62511308Santhony.gutierrez@amd.com switch (tmp.regKind) { 62611308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_SINGLE: 62711308Santhony.gutierrez@amd.com return new LdInst<MemDT, DestDT, 62811308Santhony.gutierrez@amd.com SRegAddrOperand>(ib, obj, "ld"); 62911308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_DOUBLE: 63011308Santhony.gutierrez@amd.com return new LdInst<MemDT, DestDT, 63111308Santhony.gutierrez@amd.com DRegAddrOperand>(ib, obj, "ld"); 63211308Santhony.gutierrez@amd.com default: 63311308Santhony.gutierrez@amd.com fatal("Bad ld register operand type %d\n", tmp.regKind); 63411308Santhony.gutierrez@amd.com } 63511308Santhony.gutierrez@amd.com } else { 63611308Santhony.gutierrez@amd.com fatal("Bad ld register operand kind %d\n", tmp.kind); 63711308Santhony.gutierrez@amd.com } 63811308Santhony.gutierrez@amd.com } 63911308Santhony.gutierrez@amd.com 64011308Santhony.gutierrez@amd.com template<typename MemDT> 64111308Santhony.gutierrez@amd.com GPUStaticInst* 64211308Santhony.gutierrez@amd.com decodeLd(const Brig::BrigInstBase *ib, const BrigObject *obj) 64311308Santhony.gutierrez@amd.com { 64411308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands,0); 64511308Santhony.gutierrez@amd.com BrigRegOperandInfo dest = findRegDataType(op_offs, obj); 64611308Santhony.gutierrez@amd.com 64711308Santhony.gutierrez@amd.com assert(dest.kind == Brig::BRIG_KIND_OPERAND_REGISTER || 64811308Santhony.gutierrez@amd.com dest.kind == Brig::BRIG_KIND_OPERAND_OPERAND_LIST); 64911308Santhony.gutierrez@amd.com switch(dest.regKind) { 65011308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_SINGLE: 65111308Santhony.gutierrez@amd.com switch (ib->type) { 65211308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B8: 65311308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B16: 65411308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B32: 65511308Santhony.gutierrez@amd.com return decodeLd2<MemDT, B32>(ib, obj); 65611308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_U8: 65711308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_U16: 65811308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_U32: 65911308Santhony.gutierrez@amd.com return decodeLd2<MemDT, U32>(ib, obj); 66011308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_S8: 66111308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_S16: 66211308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_S32: 66311308Santhony.gutierrez@amd.com return decodeLd2<MemDT, S32>(ib, obj); 66411308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_F16: 66511308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_F32: 66611308Santhony.gutierrez@amd.com return decodeLd2<MemDT, U32>(ib, obj); 66711308Santhony.gutierrez@amd.com default: 66811308Santhony.gutierrez@amd.com fatal("Bad ld register operand type %d, %d\n", 66911308Santhony.gutierrez@amd.com dest.regKind, ib->type); 67011308Santhony.gutierrez@amd.com }; 67111308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_DOUBLE: 67211308Santhony.gutierrez@amd.com switch (ib->type) { 67311308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B64: 67411308Santhony.gutierrez@amd.com return decodeLd2<MemDT, B64>(ib, obj); 67511308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_U64: 67611308Santhony.gutierrez@amd.com return decodeLd2<MemDT, U64>(ib, obj); 67711308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_S64: 67811308Santhony.gutierrez@amd.com return decodeLd2<MemDT, S64>(ib, obj); 67911308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_F64: 68011308Santhony.gutierrez@amd.com return decodeLd2<MemDT, U64>(ib, obj); 68111308Santhony.gutierrez@amd.com default: 68211308Santhony.gutierrez@amd.com fatal("Bad ld register operand type %d, %d\n", 68311308Santhony.gutierrez@amd.com dest.regKind, ib->type); 68411308Santhony.gutierrez@amd.com }; 68511308Santhony.gutierrez@amd.com default: 68611308Santhony.gutierrez@amd.com fatal("Bad ld register operand type %d, %d\n", dest.regKind, 68711308Santhony.gutierrez@amd.com ib->type); 68811308Santhony.gutierrez@amd.com } 68911308Santhony.gutierrez@amd.com } 69011308Santhony.gutierrez@amd.com 69111308Santhony.gutierrez@amd.com template<typename MemDataType, typename SrcOperandType, 69211308Santhony.gutierrez@amd.com typename AddrOperandType> 69311308Santhony.gutierrez@amd.com class StInstBase : public HsailGPUStaticInst 69411308Santhony.gutierrez@amd.com { 69511308Santhony.gutierrez@amd.com public: 69611308Santhony.gutierrez@amd.com typename SrcOperandType::SrcOperand src; 69711308Santhony.gutierrez@amd.com AddrOperandType addr; 69811308Santhony.gutierrez@amd.com 69911308Santhony.gutierrez@amd.com Brig::BrigSegment segment; 70011308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memoryScope; 70111308Santhony.gutierrez@amd.com Brig::BrigMemoryOrder memoryOrder; 70211308Santhony.gutierrez@amd.com unsigned int equivClass; 70311308Santhony.gutierrez@amd.com 70411308Santhony.gutierrez@amd.com StInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, 70511308Santhony.gutierrez@amd.com const char *_opcode) 70611308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 70711308Santhony.gutierrez@amd.com { 70811308Santhony.gutierrez@amd.com using namespace Brig; 70911308Santhony.gutierrez@amd.com 71011692Santhony.gutierrez@amd.com setFlag(MemoryRef); 71111692Santhony.gutierrez@amd.com setFlag(Store); 71211692Santhony.gutierrez@amd.com 71311308Santhony.gutierrez@amd.com if (ib->opcode == BRIG_OPCODE_ST) { 71411692Santhony.gutierrez@amd.com const BrigInstMem *ldst = (const BrigInstMem*)ib; 71511692Santhony.gutierrez@amd.com 71611692Santhony.gutierrez@amd.com segment = (BrigSegment)ldst->segment; 71711692Santhony.gutierrez@amd.com memoryOrder = BRIG_MEMORY_ORDER_NONE; 71811692Santhony.gutierrez@amd.com memoryScope = BRIG_MEMORY_SCOPE_NONE; 71911692Santhony.gutierrez@amd.com equivClass = ldst->equivClass; 72011692Santhony.gutierrez@amd.com 72111692Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 72211692Santhony.gutierrez@amd.com const BrigOperand *baseOp = obj->getOperand(op_offs); 72311692Santhony.gutierrez@amd.com 72411692Santhony.gutierrez@amd.com if ((baseOp->kind == BRIG_KIND_OPERAND_CONSTANT_BYTES) || 72511692Santhony.gutierrez@amd.com (baseOp->kind == BRIG_KIND_OPERAND_REGISTER)) { 72611692Santhony.gutierrez@amd.com src.init(op_offs, obj); 72711692Santhony.gutierrez@amd.com } 72811692Santhony.gutierrez@amd.com 72911692Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 73011692Santhony.gutierrez@amd.com addr.init(op_offs, obj); 73111308Santhony.gutierrez@amd.com } else { 73211692Santhony.gutierrez@amd.com const BrigInstAtomic *at = (const BrigInstAtomic*)ib; 73311692Santhony.gutierrez@amd.com 73411692Santhony.gutierrez@amd.com segment = (BrigSegment)at->segment; 73511692Santhony.gutierrez@amd.com memoryScope = (BrigMemoryScope)at->memoryScope; 73611692Santhony.gutierrez@amd.com memoryOrder = (BrigMemoryOrder)at->memoryOrder; 73711692Santhony.gutierrez@amd.com equivClass = 0; 73811692Santhony.gutierrez@amd.com 73911692Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 74011692Santhony.gutierrez@amd.com addr.init(op_offs, obj); 74111692Santhony.gutierrez@amd.com 74211692Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 74311692Santhony.gutierrez@amd.com src.init(op_offs, obj); 74411692Santhony.gutierrez@amd.com } 74511692Santhony.gutierrez@amd.com 74611692Santhony.gutierrez@amd.com switch (memoryOrder) { 74711692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_NONE: 74811692Santhony.gutierrez@amd.com setFlag(NoOrder); 74911692Santhony.gutierrez@amd.com break; 75011692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_RELAXED: 75111692Santhony.gutierrez@amd.com setFlag(RelaxedOrder); 75211692Santhony.gutierrez@amd.com break; 75311692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_SC_ACQUIRE: 75411692Santhony.gutierrez@amd.com setFlag(Acquire); 75511692Santhony.gutierrez@amd.com break; 75611692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_SC_RELEASE: 75711692Santhony.gutierrez@amd.com setFlag(Release); 75811692Santhony.gutierrez@amd.com break; 75911692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE: 76011692Santhony.gutierrez@amd.com setFlag(AcquireRelease); 76111692Santhony.gutierrez@amd.com break; 76211692Santhony.gutierrez@amd.com default: 76311692Santhony.gutierrez@amd.com fatal("StInst has bad memory order type\n"); 76411692Santhony.gutierrez@amd.com } 76511692Santhony.gutierrez@amd.com 76611692Santhony.gutierrez@amd.com switch (memoryScope) { 76711692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_NONE: 76811692Santhony.gutierrez@amd.com setFlag(NoScope); 76911692Santhony.gutierrez@amd.com break; 77011692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_WORKITEM: 77111692Santhony.gutierrez@amd.com setFlag(WorkitemScope); 77211692Santhony.gutierrez@amd.com break; 77311692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_WORKGROUP: 77411692Santhony.gutierrez@amd.com setFlag(WorkgroupScope); 77511692Santhony.gutierrez@amd.com break; 77611692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_AGENT: 77711692Santhony.gutierrez@amd.com setFlag(DeviceScope); 77811692Santhony.gutierrez@amd.com break; 77911692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_SYSTEM: 78011692Santhony.gutierrez@amd.com setFlag(SystemScope); 78111692Santhony.gutierrez@amd.com break; 78211692Santhony.gutierrez@amd.com default: 78311692Santhony.gutierrez@amd.com fatal("StInst has bad memory scope type\n"); 78411692Santhony.gutierrez@amd.com } 78511692Santhony.gutierrez@amd.com 78611692Santhony.gutierrez@amd.com switch (segment) { 78711692Santhony.gutierrez@amd.com case BRIG_SEGMENT_GLOBAL: 78811692Santhony.gutierrez@amd.com setFlag(GlobalSegment); 78911692Santhony.gutierrez@amd.com break; 79011692Santhony.gutierrez@amd.com case BRIG_SEGMENT_GROUP: 79111692Santhony.gutierrez@amd.com setFlag(GroupSegment); 79211692Santhony.gutierrez@amd.com break; 79311692Santhony.gutierrez@amd.com case BRIG_SEGMENT_PRIVATE: 79411692Santhony.gutierrez@amd.com setFlag(PrivateSegment); 79511692Santhony.gutierrez@amd.com break; 79611692Santhony.gutierrez@amd.com case BRIG_SEGMENT_READONLY: 79711692Santhony.gutierrez@amd.com setFlag(ReadOnlySegment); 79811692Santhony.gutierrez@amd.com break; 79911692Santhony.gutierrez@amd.com case BRIG_SEGMENT_SPILL: 80011692Santhony.gutierrez@amd.com setFlag(SpillSegment); 80111692Santhony.gutierrez@amd.com break; 80211692Santhony.gutierrez@amd.com case BRIG_SEGMENT_FLAT: 80311692Santhony.gutierrez@amd.com setFlag(Flat); 80411692Santhony.gutierrez@amd.com break; 80511692Santhony.gutierrez@amd.com case BRIG_SEGMENT_ARG: 80611692Santhony.gutierrez@amd.com setFlag(ArgSegment); 80711692Santhony.gutierrez@amd.com break; 80811692Santhony.gutierrez@amd.com default: 80911692Santhony.gutierrez@amd.com panic("St: segment %d not supported\n", segment); 81011308Santhony.gutierrez@amd.com } 81111308Santhony.gutierrez@amd.com } 81211308Santhony.gutierrez@amd.com 81311347Sandreas.hansson@arm.com int numDstRegOperands() override { return 0; } 81411347Sandreas.hansson@arm.com int numSrcRegOperands() override 81511308Santhony.gutierrez@amd.com { 81611308Santhony.gutierrez@amd.com return src.isVectorRegister() + this->addr.isVectorRegister(); 81711308Santhony.gutierrez@amd.com } 81811347Sandreas.hansson@arm.com int getNumOperands() override 81911308Santhony.gutierrez@amd.com { 82011308Santhony.gutierrez@amd.com if (this->addr.isVectorRegister() || this->addr.isScalarRegister()) 82111308Santhony.gutierrez@amd.com return 2; 82211308Santhony.gutierrez@amd.com else 82311308Santhony.gutierrez@amd.com return 1; 82411308Santhony.gutierrez@amd.com } 82511347Sandreas.hansson@arm.com bool isVectorRegister(int operandIndex) override 82611308Santhony.gutierrez@amd.com { 82711308Santhony.gutierrez@amd.com assert(operandIndex >= 0 && operandIndex < getNumOperands()); 82811308Santhony.gutierrez@amd.com return !operandIndex ? src.isVectorRegister() : 82911308Santhony.gutierrez@amd.com this->addr.isVectorRegister(); 83011308Santhony.gutierrez@amd.com } 83111347Sandreas.hansson@arm.com bool isCondRegister(int operandIndex) override 83211308Santhony.gutierrez@amd.com { 83311308Santhony.gutierrez@amd.com assert(operandIndex >= 0 && operandIndex < getNumOperands()); 83411308Santhony.gutierrez@amd.com return !operandIndex ? src.isCondRegister() : 83511308Santhony.gutierrez@amd.com this->addr.isCondRegister(); 83611308Santhony.gutierrez@amd.com } 83711347Sandreas.hansson@arm.com bool isScalarRegister(int operandIndex) override 83811308Santhony.gutierrez@amd.com { 83911308Santhony.gutierrez@amd.com assert(operandIndex >= 0 && operandIndex < getNumOperands()); 84011308Santhony.gutierrez@amd.com return !operandIndex ? src.isScalarRegister() : 84111308Santhony.gutierrez@amd.com this->addr.isScalarRegister(); 84211308Santhony.gutierrez@amd.com } 84311347Sandreas.hansson@arm.com bool isSrcOperand(int operandIndex) override 84411308Santhony.gutierrez@amd.com { 84511308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 84611308Santhony.gutierrez@amd.com return true; 84711308Santhony.gutierrez@amd.com } 84811347Sandreas.hansson@arm.com bool isDstOperand(int operandIndex) override { return false; } 84911347Sandreas.hansson@arm.com int getOperandSize(int operandIndex) override 85011308Santhony.gutierrez@amd.com { 85111308Santhony.gutierrez@amd.com assert(operandIndex >= 0 && operandIndex < getNumOperands()); 85211308Santhony.gutierrez@amd.com return !operandIndex ? src.opSize() : this->addr.opSize(); 85311308Santhony.gutierrez@amd.com } 85411347Sandreas.hansson@arm.com int getRegisterIndex(int operandIndex) override 85511308Santhony.gutierrez@amd.com { 85611308Santhony.gutierrez@amd.com assert(operandIndex >= 0 && operandIndex < getNumOperands()); 85711308Santhony.gutierrez@amd.com return !operandIndex ? src.regIndex() : this->addr.regIndex(); 85811308Santhony.gutierrez@amd.com } 85911308Santhony.gutierrez@amd.com }; 86011308Santhony.gutierrez@amd.com 86111308Santhony.gutierrez@amd.com 86211308Santhony.gutierrez@amd.com template<typename MemDataType, typename SrcDataType, 86311308Santhony.gutierrez@amd.com typename AddrOperandType> 86411308Santhony.gutierrez@amd.com class StInst : 86511308Santhony.gutierrez@amd.com public StInstBase<MemDataType, typename SrcDataType::OperandType, 86611308Santhony.gutierrez@amd.com AddrOperandType>, 86711308Santhony.gutierrez@amd.com public MemInst 86811308Santhony.gutierrez@amd.com { 86911308Santhony.gutierrez@amd.com public: 87011308Santhony.gutierrez@amd.com typename SrcDataType::OperandType::SrcOperand src_vect[4]; 87111308Santhony.gutierrez@amd.com uint16_t num_src_operands; 87211347Sandreas.hansson@arm.com void generateDisassembly() override; 87311308Santhony.gutierrez@amd.com 87411308Santhony.gutierrez@amd.com StInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 87511308Santhony.gutierrez@amd.com const char *_opcode, int srcIdx) 87611308Santhony.gutierrez@amd.com : StInstBase<MemDataType, typename SrcDataType::OperandType, 87711308Santhony.gutierrez@amd.com AddrOperandType>(ib, obj, _opcode), 87811308Santhony.gutierrez@amd.com MemInst(SrcDataType::memType) 87911308Santhony.gutierrez@amd.com { 88011308Santhony.gutierrez@amd.com init_addr(&this->addr); 88111308Santhony.gutierrez@amd.com 88211308Santhony.gutierrez@amd.com BrigRegOperandInfo rinfo; 88311308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands,srcIdx); 88411308Santhony.gutierrez@amd.com const Brig::BrigOperand *baseOp = obj->getOperand(op_offs); 88511308Santhony.gutierrez@amd.com 88611308Santhony.gutierrez@amd.com if (baseOp->kind == Brig::BRIG_KIND_OPERAND_CONSTANT_BYTES) { 88711308Santhony.gutierrez@amd.com const Brig::BrigOperandConstantBytes *op = 88811308Santhony.gutierrez@amd.com (Brig::BrigOperandConstantBytes*)baseOp; 88911308Santhony.gutierrez@amd.com 89011308Santhony.gutierrez@amd.com rinfo = BrigRegOperandInfo((Brig::BrigKind16_t)op->base.kind, 89111308Santhony.gutierrez@amd.com Brig::BRIG_TYPE_NONE); 89211308Santhony.gutierrez@amd.com } else { 89311308Santhony.gutierrez@amd.com rinfo = findRegDataType(op_offs, obj); 89411308Santhony.gutierrez@amd.com } 89511308Santhony.gutierrez@amd.com 89611308Santhony.gutierrez@amd.com if (baseOp->kind == Brig::BRIG_KIND_OPERAND_OPERAND_LIST) { 89711308Santhony.gutierrez@amd.com const Brig::BrigOperandOperandList *brigRegVecOp = 89811308Santhony.gutierrez@amd.com (const Brig::BrigOperandOperandList*)baseOp; 89911308Santhony.gutierrez@amd.com 90011308Santhony.gutierrez@amd.com num_src_operands = 90111308Santhony.gutierrez@amd.com *((unsigned*)obj->getData(brigRegVecOp->elements)) / 4; 90211308Santhony.gutierrez@amd.com 90311308Santhony.gutierrez@amd.com assert(num_src_operands <= 4); 90411308Santhony.gutierrez@amd.com } else { 90511308Santhony.gutierrez@amd.com num_src_operands = 1; 90611308Santhony.gutierrez@amd.com } 90711308Santhony.gutierrez@amd.com 90811308Santhony.gutierrez@amd.com if (num_src_operands > 1) { 90911308Santhony.gutierrez@amd.com assert(baseOp->kind == Brig::BRIG_KIND_OPERAND_OPERAND_LIST); 91011308Santhony.gutierrez@amd.com 91111308Santhony.gutierrez@amd.com for (int i = 0; i < num_src_operands; ++i) { 91211308Santhony.gutierrez@amd.com src_vect[i].init_from_vect(op_offs, obj, i); 91311308Santhony.gutierrez@amd.com } 91411308Santhony.gutierrez@amd.com } 91511308Santhony.gutierrez@amd.com } 91611308Santhony.gutierrez@amd.com 91711308Santhony.gutierrez@amd.com void 91811308Santhony.gutierrez@amd.com initiateAcc(GPUDynInstPtr gpuDynInst) override 91911308Santhony.gutierrez@amd.com { 92011308Santhony.gutierrez@amd.com // before performing a store, check if this store has 92111308Santhony.gutierrez@amd.com // release semantics, and if so issue a release first 92211692Santhony.gutierrez@amd.com if (!this->isLocalMem()) { 92311308Santhony.gutierrez@amd.com if (gpuDynInst->computeUnit()->shader->separate_acquire_release 92411692Santhony.gutierrez@amd.com && gpuDynInst->isRelease()) { 92511308Santhony.gutierrez@amd.com 92611308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = VectorMask(1); 92711308Santhony.gutierrez@amd.com gpuDynInst->execContinuation = &GPUStaticInst::execSt; 92811308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = true; 92911308Santhony.gutierrez@amd.com // create request 93011308Santhony.gutierrez@amd.com Request *req = new Request(0, 0, 0, 0, 93111308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 93211435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId); 93311308Santhony.gutierrez@amd.com req->setFlags(Request::RELEASE); 93411308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->injectGlobalMemFence(gpuDynInst, false, req); 93511308Santhony.gutierrez@amd.com 93611308Santhony.gutierrez@amd.com return; 93711308Santhony.gutierrez@amd.com } 93811308Santhony.gutierrez@amd.com } 93911308Santhony.gutierrez@amd.com 94011308Santhony.gutierrez@amd.com // if there is no release semantic, perform stores immediately 94111308Santhony.gutierrez@amd.com execSt(gpuDynInst); 94211308Santhony.gutierrez@amd.com } 94311308Santhony.gutierrez@amd.com 94411308Santhony.gutierrez@amd.com private: 94511308Santhony.gutierrez@amd.com // execSt may be called through a continuation 94611308Santhony.gutierrez@amd.com // if the store had release semantics. see comment for 94711308Santhony.gutierrez@amd.com // execSt in gpu_static_inst.hh 94811308Santhony.gutierrez@amd.com void 94911308Santhony.gutierrez@amd.com execSt(GPUDynInstPtr gpuDynInst) override 95011308Santhony.gutierrez@amd.com { 95111308Santhony.gutierrez@amd.com typedef typename MemDataType::CType c0; 95211308Santhony.gutierrez@amd.com 95311308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = gpuDynInst->exec_mask; 95411308Santhony.gutierrez@amd.com 95511308Santhony.gutierrez@amd.com if (num_src_operands > 1) { 95611534Sjohn.kalamatianos@amd.com for (int i = 0; i < gpuDynInst->computeUnit()->wfSize(); ++i) 95711308Santhony.gutierrez@amd.com if (gpuDynInst->exec_mask[i]) 95811308Santhony.gutierrez@amd.com gpuDynInst->statusVector.push_back(num_src_operands); 95911308Santhony.gutierrez@amd.com else 96011308Santhony.gutierrez@amd.com gpuDynInst->statusVector.push_back(0); 96111308Santhony.gutierrez@amd.com } 96211308Santhony.gutierrez@amd.com 96311308Santhony.gutierrez@amd.com for (int k = 0; k < num_src_operands; ++k) { 96411534Sjohn.kalamatianos@amd.com c0 *d = &((c0*)gpuDynInst->d_data) 96511534Sjohn.kalamatianos@amd.com [k * gpuDynInst->computeUnit()->wfSize()]; 96611308Santhony.gutierrez@amd.com 96711534Sjohn.kalamatianos@amd.com for (int i = 0; i < gpuDynInst->computeUnit()->wfSize(); ++i) { 96811308Santhony.gutierrez@amd.com if (gpuDynInst->exec_mask[i]) { 96911308Santhony.gutierrez@amd.com Addr vaddr = gpuDynInst->addr[i] + k * sizeof(c0); 97011308Santhony.gutierrez@amd.com 97111692Santhony.gutierrez@amd.com if (this->isLocalMem()) { 97211308Santhony.gutierrez@amd.com //store to shared memory 97311308Santhony.gutierrez@amd.com gpuDynInst->wavefront()->ldsChunk->write<c0>(vaddr, 97411308Santhony.gutierrez@amd.com *d); 97511308Santhony.gutierrez@amd.com } else { 97611308Santhony.gutierrez@amd.com Request *req = 97711308Santhony.gutierrez@amd.com new Request(0, vaddr, sizeof(c0), 0, 97811308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 97911435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId); 98011308Santhony.gutierrez@amd.com 98111308Santhony.gutierrez@amd.com gpuDynInst->setRequestFlags(req); 98211308Santhony.gutierrez@amd.com PacketPtr pkt = new Packet(req, MemCmd::WriteReq); 98311308Santhony.gutierrez@amd.com pkt->dataStatic<c0>(d); 98411308Santhony.gutierrez@amd.com 98511308Santhony.gutierrez@amd.com // translation is performed in sendRequest() 98611308Santhony.gutierrez@amd.com // the request will be finished when the store completes 98711308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 98811308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->sendRequest(gpuDynInst, 98911308Santhony.gutierrez@amd.com i, pkt); 99011308Santhony.gutierrez@amd.com 99111308Santhony.gutierrez@amd.com } 99211308Santhony.gutierrez@amd.com } 99311308Santhony.gutierrez@amd.com ++d; 99411308Santhony.gutierrez@amd.com } 99511308Santhony.gutierrez@amd.com } 99611308Santhony.gutierrez@amd.com 99711308Santhony.gutierrez@amd.com gpuDynInst->updateStats(); 99811308Santhony.gutierrez@amd.com } 99911308Santhony.gutierrez@amd.com 100011308Santhony.gutierrez@amd.com public: 100111347Sandreas.hansson@arm.com bool isVectorRegister(int operandIndex) override 100211308Santhony.gutierrez@amd.com { 100311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 100411308Santhony.gutierrez@amd.com if (operandIndex == num_src_operands) 100511308Santhony.gutierrez@amd.com return this->addr.isVectorRegister(); 100611308Santhony.gutierrez@amd.com if (num_src_operands > 1) 100711308Santhony.gutierrez@amd.com return src_vect[operandIndex].isVectorRegister(); 100811308Santhony.gutierrez@amd.com else if (num_src_operands == 1) 100911308Santhony.gutierrez@amd.com return StInstBase<MemDataType, 101011308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 101111308Santhony.gutierrez@amd.com AddrOperandType>::src.isVectorRegister(); 101211308Santhony.gutierrez@amd.com return false; 101311308Santhony.gutierrez@amd.com } 101411347Sandreas.hansson@arm.com bool isCondRegister(int operandIndex) override 101511308Santhony.gutierrez@amd.com { 101611308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 101711308Santhony.gutierrez@amd.com if (operandIndex == num_src_operands) 101811308Santhony.gutierrez@amd.com return this->addr.isCondRegister(); 101911308Santhony.gutierrez@amd.com if (num_src_operands > 1) 102011308Santhony.gutierrez@amd.com return src_vect[operandIndex].isCondRegister(); 102111308Santhony.gutierrez@amd.com else if (num_src_operands == 1) 102211308Santhony.gutierrez@amd.com return StInstBase<MemDataType, 102311308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 102411308Santhony.gutierrez@amd.com AddrOperandType>::src.isCondRegister(); 102511308Santhony.gutierrez@amd.com return false; 102611308Santhony.gutierrez@amd.com } 102711347Sandreas.hansson@arm.com bool isScalarRegister(int operandIndex) override 102811308Santhony.gutierrez@amd.com { 102911308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 103011308Santhony.gutierrez@amd.com if (operandIndex == num_src_operands) 103111308Santhony.gutierrez@amd.com return this->addr.isScalarRegister(); 103211308Santhony.gutierrez@amd.com if (num_src_operands > 1) 103311308Santhony.gutierrez@amd.com return src_vect[operandIndex].isScalarRegister(); 103411308Santhony.gutierrez@amd.com else if (num_src_operands == 1) 103511308Santhony.gutierrez@amd.com return StInstBase<MemDataType, 103611308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 103711308Santhony.gutierrez@amd.com AddrOperandType>::src.isScalarRegister(); 103811308Santhony.gutierrez@amd.com return false; 103911308Santhony.gutierrez@amd.com } 104011347Sandreas.hansson@arm.com bool isSrcOperand(int operandIndex) override 104111308Santhony.gutierrez@amd.com { 104211308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 104311308Santhony.gutierrez@amd.com return true; 104411308Santhony.gutierrez@amd.com } 104511347Sandreas.hansson@arm.com bool isDstOperand(int operandIndex) override { return false; } 104611347Sandreas.hansson@arm.com int getOperandSize(int operandIndex) override 104711308Santhony.gutierrez@amd.com { 104811308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 104911308Santhony.gutierrez@amd.com if (operandIndex == num_src_operands) 105011308Santhony.gutierrez@amd.com return this->addr.opSize(); 105111308Santhony.gutierrez@amd.com if (num_src_operands > 1) 105211308Santhony.gutierrez@amd.com return src_vect[operandIndex].opSize(); 105311308Santhony.gutierrez@amd.com else if (num_src_operands == 1) 105411308Santhony.gutierrez@amd.com return StInstBase<MemDataType, 105511308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 105611308Santhony.gutierrez@amd.com AddrOperandType>::src.opSize(); 105711308Santhony.gutierrez@amd.com return 0; 105811308Santhony.gutierrez@amd.com } 105911347Sandreas.hansson@arm.com int getRegisterIndex(int operandIndex) override 106011308Santhony.gutierrez@amd.com { 106111308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 106211308Santhony.gutierrez@amd.com if (operandIndex == num_src_operands) 106311308Santhony.gutierrez@amd.com return this->addr.regIndex(); 106411308Santhony.gutierrez@amd.com if (num_src_operands > 1) 106511308Santhony.gutierrez@amd.com return src_vect[operandIndex].regIndex(); 106611308Santhony.gutierrez@amd.com else if (num_src_operands == 1) 106711308Santhony.gutierrez@amd.com return StInstBase<MemDataType, 106811308Santhony.gutierrez@amd.com typename SrcDataType::OperandType, 106911308Santhony.gutierrez@amd.com AddrOperandType>::src.regIndex(); 107011308Santhony.gutierrez@amd.com return -1; 107111308Santhony.gutierrez@amd.com } 107211347Sandreas.hansson@arm.com int getNumOperands() override 107311308Santhony.gutierrez@amd.com { 107411308Santhony.gutierrez@amd.com if (this->addr.isVectorRegister() || this->addr.isScalarRegister()) 107511308Santhony.gutierrez@amd.com return num_src_operands + 1; 107611308Santhony.gutierrez@amd.com else 107711308Santhony.gutierrez@amd.com return num_src_operands; 107811308Santhony.gutierrez@amd.com } 107911347Sandreas.hansson@arm.com void execute(GPUDynInstPtr gpuDynInst) override; 108011308Santhony.gutierrez@amd.com }; 108111308Santhony.gutierrez@amd.com 108211308Santhony.gutierrez@amd.com template<typename DataType, typename SrcDataType> 108311308Santhony.gutierrez@amd.com GPUStaticInst* 108411308Santhony.gutierrez@amd.com decodeSt(const Brig::BrigInstBase *ib, const BrigObject *obj) 108511308Santhony.gutierrez@amd.com { 108611308Santhony.gutierrez@amd.com int srcIdx = 0; 108711308Santhony.gutierrez@amd.com int destIdx = 1; 108811308Santhony.gutierrez@amd.com if (ib->opcode == Brig::BRIG_OPCODE_ATOMIC || 108911308Santhony.gutierrez@amd.com ib->opcode == Brig::BRIG_OPCODE_ATOMICNORET) { 109011308Santhony.gutierrez@amd.com srcIdx = 1; 109111308Santhony.gutierrez@amd.com destIdx = 0; 109211308Santhony.gutierrez@amd.com } 109311308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands,destIdx); 109411308Santhony.gutierrez@amd.com 109511308Santhony.gutierrez@amd.com BrigRegOperandInfo tmp = findRegDataType(op_offs, obj); 109611308Santhony.gutierrez@amd.com 109711308Santhony.gutierrez@amd.com if (tmp.kind == Brig::BRIG_KIND_OPERAND_ADDRESS) { 109811308Santhony.gutierrez@amd.com return new StInst<DataType, SrcDataType, 109911308Santhony.gutierrez@amd.com NoRegAddrOperand>(ib, obj, "st", srcIdx); 110011308Santhony.gutierrez@amd.com } else if (tmp.kind == Brig::BRIG_KIND_OPERAND_REGISTER) { 110111308Santhony.gutierrez@amd.com // V2/V4 not allowed 110211308Santhony.gutierrez@amd.com switch (tmp.regKind) { 110311308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_SINGLE: 110411308Santhony.gutierrez@amd.com return new StInst<DataType, SrcDataType, 110511308Santhony.gutierrez@amd.com SRegAddrOperand>(ib, obj, "st", srcIdx); 110611308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_DOUBLE: 110711308Santhony.gutierrez@amd.com return new StInst<DataType, SrcDataType, 110811308Santhony.gutierrez@amd.com DRegAddrOperand>(ib, obj, "st", srcIdx); 110911308Santhony.gutierrez@amd.com default: 111011308Santhony.gutierrez@amd.com fatal("Bad st register operand type %d\n", tmp.type); 111111308Santhony.gutierrez@amd.com } 111211308Santhony.gutierrez@amd.com } else { 111311308Santhony.gutierrez@amd.com fatal("Bad st register operand kind %d\n", tmp.kind); 111411308Santhony.gutierrez@amd.com } 111511308Santhony.gutierrez@amd.com } 111611308Santhony.gutierrez@amd.com 111711308Santhony.gutierrez@amd.com template<typename OperandType, typename AddrOperandType, int NumSrcOperands, 111811308Santhony.gutierrez@amd.com bool HasDst> 111911308Santhony.gutierrez@amd.com class AtomicInstBase : public HsailGPUStaticInst 112011308Santhony.gutierrez@amd.com { 112111308Santhony.gutierrez@amd.com public: 112211308Santhony.gutierrez@amd.com typename OperandType::DestOperand dest; 112311308Santhony.gutierrez@amd.com typename OperandType::SrcOperand src[NumSrcOperands]; 112411308Santhony.gutierrez@amd.com AddrOperandType addr; 112511308Santhony.gutierrez@amd.com 112611308Santhony.gutierrez@amd.com Brig::BrigSegment segment; 112711308Santhony.gutierrez@amd.com Brig::BrigMemoryOrder memoryOrder; 112811308Santhony.gutierrez@amd.com Brig::BrigAtomicOperation atomicOperation; 112911308Santhony.gutierrez@amd.com Brig::BrigMemoryScope memoryScope; 113011308Santhony.gutierrez@amd.com Brig::BrigOpcode opcode; 113111308Santhony.gutierrez@amd.com 113211308Santhony.gutierrez@amd.com AtomicInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, 113311308Santhony.gutierrez@amd.com const char *_opcode) 113411308Santhony.gutierrez@amd.com : HsailGPUStaticInst(obj, _opcode) 113511308Santhony.gutierrez@amd.com { 113611308Santhony.gutierrez@amd.com using namespace Brig; 113711308Santhony.gutierrez@amd.com 113811308Santhony.gutierrez@amd.com const BrigInstAtomic *at = (const BrigInstAtomic*)ib; 113911308Santhony.gutierrez@amd.com 114011308Santhony.gutierrez@amd.com segment = (BrigSegment)at->segment; 114111308Santhony.gutierrez@amd.com memoryScope = (BrigMemoryScope)at->memoryScope; 114211308Santhony.gutierrez@amd.com memoryOrder = (BrigMemoryOrder)at->memoryOrder; 114311308Santhony.gutierrez@amd.com atomicOperation = (BrigAtomicOperation)at->atomicOperation; 114411308Santhony.gutierrez@amd.com opcode = (BrigOpcode)ib->opcode; 114511692Santhony.gutierrez@amd.com 114611692Santhony.gutierrez@amd.com assert(opcode == Brig::BRIG_OPCODE_ATOMICNORET || 114711692Santhony.gutierrez@amd.com opcode == Brig::BRIG_OPCODE_ATOMIC); 114811692Santhony.gutierrez@amd.com 114911692Santhony.gutierrez@amd.com setFlag(MemoryRef); 115011692Santhony.gutierrez@amd.com 115111692Santhony.gutierrez@amd.com if (opcode == Brig::BRIG_OPCODE_ATOMIC) { 115211692Santhony.gutierrez@amd.com setFlag(AtomicReturn); 115311692Santhony.gutierrez@amd.com } else { 115411692Santhony.gutierrez@amd.com setFlag(AtomicNoReturn); 115511692Santhony.gutierrez@amd.com } 115611692Santhony.gutierrez@amd.com 115711692Santhony.gutierrez@amd.com switch (memoryOrder) { 115811692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_NONE: 115911692Santhony.gutierrez@amd.com setFlag(NoOrder); 116011692Santhony.gutierrez@amd.com break; 116111692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_RELAXED: 116211692Santhony.gutierrez@amd.com setFlag(RelaxedOrder); 116311692Santhony.gutierrez@amd.com break; 116411692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_SC_ACQUIRE: 116511692Santhony.gutierrez@amd.com setFlag(Acquire); 116611692Santhony.gutierrez@amd.com break; 116711692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_SC_RELEASE: 116811692Santhony.gutierrez@amd.com setFlag(Release); 116911692Santhony.gutierrez@amd.com break; 117011692Santhony.gutierrez@amd.com case BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE: 117111692Santhony.gutierrez@amd.com setFlag(AcquireRelease); 117211692Santhony.gutierrez@amd.com break; 117311692Santhony.gutierrez@amd.com default: 117411692Santhony.gutierrez@amd.com fatal("AtomicInst has bad memory order type\n"); 117511692Santhony.gutierrez@amd.com } 117611692Santhony.gutierrez@amd.com 117711692Santhony.gutierrez@amd.com switch (memoryScope) { 117811692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_NONE: 117911692Santhony.gutierrez@amd.com setFlag(NoScope); 118011692Santhony.gutierrez@amd.com break; 118111692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_WORKITEM: 118211692Santhony.gutierrez@amd.com setFlag(WorkitemScope); 118311692Santhony.gutierrez@amd.com break; 118411692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_WORKGROUP: 118511692Santhony.gutierrez@amd.com setFlag(WorkgroupScope); 118611692Santhony.gutierrez@amd.com break; 118711692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_AGENT: 118811692Santhony.gutierrez@amd.com setFlag(DeviceScope); 118911692Santhony.gutierrez@amd.com break; 119011692Santhony.gutierrez@amd.com case BRIG_MEMORY_SCOPE_SYSTEM: 119111692Santhony.gutierrez@amd.com setFlag(SystemScope); 119211692Santhony.gutierrez@amd.com break; 119311692Santhony.gutierrez@amd.com default: 119411692Santhony.gutierrez@amd.com fatal("AtomicInst has bad memory scope type\n"); 119511692Santhony.gutierrez@amd.com } 119611692Santhony.gutierrez@amd.com 119711692Santhony.gutierrez@amd.com switch (atomicOperation) { 119811692Santhony.gutierrez@amd.com case Brig::BRIG_ATOMIC_AND: 119911692Santhony.gutierrez@amd.com setFlag(AtomicAnd); 120011692Santhony.gutierrez@amd.com break; 120111692Santhony.gutierrez@amd.com case Brig::BRIG_ATOMIC_OR: 120211692Santhony.gutierrez@amd.com setFlag(AtomicOr); 120311692Santhony.gutierrez@amd.com break; 120411692Santhony.gutierrez@amd.com case Brig::BRIG_ATOMIC_XOR: 120511692Santhony.gutierrez@amd.com setFlag(AtomicXor); 120611692Santhony.gutierrez@amd.com break; 120711692Santhony.gutierrez@amd.com case Brig::BRIG_ATOMIC_CAS: 120811692Santhony.gutierrez@amd.com setFlag(AtomicCAS); 120911692Santhony.gutierrez@amd.com break; 121011692Santhony.gutierrez@amd.com case Brig::BRIG_ATOMIC_EXCH: 121111692Santhony.gutierrez@amd.com setFlag(AtomicExch); 121211692Santhony.gutierrez@amd.com break; 121311692Santhony.gutierrez@amd.com case Brig::BRIG_ATOMIC_ADD: 121411692Santhony.gutierrez@amd.com setFlag(AtomicAdd); 121511692Santhony.gutierrez@amd.com break; 121611692Santhony.gutierrez@amd.com case Brig::BRIG_ATOMIC_WRAPINC: 121711692Santhony.gutierrez@amd.com setFlag(AtomicInc); 121811692Santhony.gutierrez@amd.com break; 121911692Santhony.gutierrez@amd.com case Brig::BRIG_ATOMIC_WRAPDEC: 122011692Santhony.gutierrez@amd.com setFlag(AtomicDec); 122111692Santhony.gutierrez@amd.com break; 122211692Santhony.gutierrez@amd.com case Brig::BRIG_ATOMIC_MIN: 122311692Santhony.gutierrez@amd.com setFlag(AtomicMin); 122411692Santhony.gutierrez@amd.com break; 122511692Santhony.gutierrez@amd.com case Brig::BRIG_ATOMIC_MAX: 122611692Santhony.gutierrez@amd.com setFlag(AtomicMax); 122711692Santhony.gutierrez@amd.com break; 122811692Santhony.gutierrez@amd.com case Brig::BRIG_ATOMIC_SUB: 122911692Santhony.gutierrez@amd.com setFlag(AtomicSub); 123011692Santhony.gutierrez@amd.com break; 123111692Santhony.gutierrez@amd.com default: 123211692Santhony.gutierrez@amd.com fatal("Bad BrigAtomicOperation code %d\n", atomicOperation); 123311692Santhony.gutierrez@amd.com } 123411308Santhony.gutierrez@amd.com 123511308Santhony.gutierrez@amd.com switch (segment) { 123611308Santhony.gutierrez@amd.com case BRIG_SEGMENT_GLOBAL: 123711692Santhony.gutierrez@amd.com setFlag(GlobalSegment); 123811308Santhony.gutierrez@amd.com break; 123911308Santhony.gutierrez@amd.com case BRIG_SEGMENT_GROUP: 124011692Santhony.gutierrez@amd.com setFlag(GroupSegment); 124111308Santhony.gutierrez@amd.com break; 124211308Santhony.gutierrez@amd.com case BRIG_SEGMENT_FLAT: 124311692Santhony.gutierrez@amd.com setFlag(Flat); 124411308Santhony.gutierrez@amd.com break; 124511308Santhony.gutierrez@amd.com default: 124611308Santhony.gutierrez@amd.com panic("Atomic: segment %d not supported\n", segment); 124711308Santhony.gutierrez@amd.com } 124811308Santhony.gutierrez@amd.com 124911308Santhony.gutierrez@amd.com if (HasDst) { 125011308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 125111308Santhony.gutierrez@amd.com dest.init(op_offs, obj); 125211308Santhony.gutierrez@amd.com 125311308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, 1); 125411308Santhony.gutierrez@amd.com addr.init(op_offs, obj); 125511308Santhony.gutierrez@amd.com 125611308Santhony.gutierrez@amd.com for (int i = 0; i < NumSrcOperands; ++i) { 125711308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, i + 2); 125811308Santhony.gutierrez@amd.com src[i].init(op_offs, obj); 125911308Santhony.gutierrez@amd.com } 126011308Santhony.gutierrez@amd.com } else { 126111308Santhony.gutierrez@amd.com 126211308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands, 0); 126311308Santhony.gutierrez@amd.com addr.init(op_offs, obj); 126411308Santhony.gutierrez@amd.com 126511308Santhony.gutierrez@amd.com for (int i = 0; i < NumSrcOperands; ++i) { 126611308Santhony.gutierrez@amd.com op_offs = obj->getOperandPtr(ib->operands, i + 1); 126711308Santhony.gutierrez@amd.com src[i].init(op_offs, obj); 126811308Santhony.gutierrez@amd.com } 126911308Santhony.gutierrez@amd.com } 127011308Santhony.gutierrez@amd.com } 127111308Santhony.gutierrez@amd.com 127211308Santhony.gutierrez@amd.com int numSrcRegOperands() 127311308Santhony.gutierrez@amd.com { 127411308Santhony.gutierrez@amd.com int operands = 0; 127511308Santhony.gutierrez@amd.com for (int i = 0; i < NumSrcOperands; i++) { 127611325Ssteve.reinhardt@amd.com if (src[i].isVectorRegister()) { 127711308Santhony.gutierrez@amd.com operands++; 127811308Santhony.gutierrez@amd.com } 127911308Santhony.gutierrez@amd.com } 128011308Santhony.gutierrez@amd.com if (addr.isVectorRegister()) 128111308Santhony.gutierrez@amd.com operands++; 128211308Santhony.gutierrez@amd.com return operands; 128311308Santhony.gutierrez@amd.com } 128411308Santhony.gutierrez@amd.com int numDstRegOperands() { return dest.isVectorRegister(); } 128511308Santhony.gutierrez@amd.com int getNumOperands() 128611308Santhony.gutierrez@amd.com { 128711308Santhony.gutierrez@amd.com if (addr.isVectorRegister()) 128811308Santhony.gutierrez@amd.com return(NumSrcOperands + 2); 128911308Santhony.gutierrez@amd.com return(NumSrcOperands + 1); 129011308Santhony.gutierrez@amd.com } 129111308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIndex) 129211308Santhony.gutierrez@amd.com { 129311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 129411308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 129511308Santhony.gutierrez@amd.com return src[operandIndex].isVectorRegister(); 129611308Santhony.gutierrez@amd.com else if (operandIndex == NumSrcOperands) 129711308Santhony.gutierrez@amd.com return(addr.isVectorRegister()); 129811308Santhony.gutierrez@amd.com else 129911308Santhony.gutierrez@amd.com return dest.isVectorRegister(); 130011308Santhony.gutierrez@amd.com } 130111308Santhony.gutierrez@amd.com bool isCondRegister(int operandIndex) 130211308Santhony.gutierrez@amd.com { 130311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 130411308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 130511308Santhony.gutierrez@amd.com return src[operandIndex].isCondRegister(); 130611308Santhony.gutierrez@amd.com else if (operandIndex == NumSrcOperands) 130711308Santhony.gutierrez@amd.com return(addr.isCondRegister()); 130811308Santhony.gutierrez@amd.com else 130911308Santhony.gutierrez@amd.com return dest.isCondRegister(); 131011308Santhony.gutierrez@amd.com } 131111308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIndex) 131211308Santhony.gutierrez@amd.com { 131311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 131411308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 131511308Santhony.gutierrez@amd.com return src[operandIndex].isScalarRegister(); 131611308Santhony.gutierrez@amd.com else if (operandIndex == NumSrcOperands) 131711308Santhony.gutierrez@amd.com return(addr.isScalarRegister()); 131811308Santhony.gutierrez@amd.com else 131911308Santhony.gutierrez@amd.com return dest.isScalarRegister(); 132011308Santhony.gutierrez@amd.com } 132111308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIndex) 132211308Santhony.gutierrez@amd.com { 132311308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 132411308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 132511308Santhony.gutierrez@amd.com return true; 132611308Santhony.gutierrez@amd.com else if (operandIndex == NumSrcOperands) 132711308Santhony.gutierrez@amd.com return(addr.isVectorRegister()); 132811308Santhony.gutierrez@amd.com else 132911308Santhony.gutierrez@amd.com return false; 133011308Santhony.gutierrez@amd.com } 133111308Santhony.gutierrez@amd.com bool isDstOperand(int operandIndex) 133211308Santhony.gutierrez@amd.com { 133311308Santhony.gutierrez@amd.com if (operandIndex <= NumSrcOperands) 133411308Santhony.gutierrez@amd.com return false; 133511308Santhony.gutierrez@amd.com else 133611308Santhony.gutierrez@amd.com return true; 133711308Santhony.gutierrez@amd.com } 133811308Santhony.gutierrez@amd.com int getOperandSize(int operandIndex) 133911308Santhony.gutierrez@amd.com { 134011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 134111308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 134211308Santhony.gutierrez@amd.com return(src[operandIndex].opSize()); 134311308Santhony.gutierrez@amd.com else if (operandIndex == NumSrcOperands) 134411308Santhony.gutierrez@amd.com return(addr.opSize()); 134511308Santhony.gutierrez@amd.com else 134611308Santhony.gutierrez@amd.com return(dest.opSize()); 134711308Santhony.gutierrez@amd.com } 134811308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIndex) 134911308Santhony.gutierrez@amd.com { 135011308Santhony.gutierrez@amd.com assert((operandIndex >= 0) && (operandIndex < getNumOperands())); 135111308Santhony.gutierrez@amd.com if (operandIndex < NumSrcOperands) 135211308Santhony.gutierrez@amd.com return(src[operandIndex].regIndex()); 135311308Santhony.gutierrez@amd.com else if (operandIndex == NumSrcOperands) 135411308Santhony.gutierrez@amd.com return(addr.regIndex()); 135511308Santhony.gutierrez@amd.com else 135611308Santhony.gutierrez@amd.com return(dest.regIndex()); 135711308Santhony.gutierrez@amd.com return -1; 135811308Santhony.gutierrez@amd.com } 135911308Santhony.gutierrez@amd.com }; 136011308Santhony.gutierrez@amd.com 136111308Santhony.gutierrez@amd.com template<typename MemDataType, typename AddrOperandType, int NumSrcOperands, 136211308Santhony.gutierrez@amd.com bool HasDst> 136311308Santhony.gutierrez@amd.com class AtomicInst : 136411308Santhony.gutierrez@amd.com public AtomicInstBase<typename MemDataType::OperandType, 136511308Santhony.gutierrez@amd.com AddrOperandType, NumSrcOperands, HasDst>, 136611308Santhony.gutierrez@amd.com public MemInst 136711308Santhony.gutierrez@amd.com { 136811308Santhony.gutierrez@amd.com public: 136911347Sandreas.hansson@arm.com void generateDisassembly() override; 137011308Santhony.gutierrez@amd.com 137111308Santhony.gutierrez@amd.com AtomicInst(const Brig::BrigInstBase *ib, const BrigObject *obj, 137211308Santhony.gutierrez@amd.com const char *_opcode) 137311308Santhony.gutierrez@amd.com : AtomicInstBase<typename MemDataType::OperandType, AddrOperandType, 137411308Santhony.gutierrez@amd.com NumSrcOperands, HasDst> 137511308Santhony.gutierrez@amd.com (ib, obj, _opcode), 137611308Santhony.gutierrez@amd.com MemInst(MemDataType::memType) 137711308Santhony.gutierrez@amd.com { 137811308Santhony.gutierrez@amd.com init_addr(&this->addr); 137911308Santhony.gutierrez@amd.com } 138011308Santhony.gutierrez@amd.com 138111308Santhony.gutierrez@amd.com void 138211308Santhony.gutierrez@amd.com initiateAcc(GPUDynInstPtr gpuDynInst) override 138311308Santhony.gutierrez@amd.com { 138411308Santhony.gutierrez@amd.com // before doing the RMW, check if this atomic has 138511308Santhony.gutierrez@amd.com // release semantics, and if so issue a release first 138611692Santhony.gutierrez@amd.com if (!this->isLocalMem()) { 138711308Santhony.gutierrez@amd.com if (gpuDynInst->computeUnit()->shader->separate_acquire_release 138811692Santhony.gutierrez@amd.com && (gpuDynInst->isRelease() 138911692Santhony.gutierrez@amd.com || gpuDynInst->isAcquireRelease())) { 139011308Santhony.gutierrez@amd.com 139111308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = VectorMask(1); 139211308Santhony.gutierrez@amd.com 139311308Santhony.gutierrez@amd.com gpuDynInst->execContinuation = &GPUStaticInst::execAtomic; 139411308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = true; 139511308Santhony.gutierrez@amd.com 139611308Santhony.gutierrez@amd.com // create request 139711308Santhony.gutierrez@amd.com Request *req = new Request(0, 0, 0, 0, 139811308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 139911435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId); 140011308Santhony.gutierrez@amd.com req->setFlags(Request::RELEASE); 140111308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->injectGlobalMemFence(gpuDynInst, false, req); 140211308Santhony.gutierrez@amd.com 140311308Santhony.gutierrez@amd.com return; 140411308Santhony.gutierrez@amd.com } 140511308Santhony.gutierrez@amd.com } 140611308Santhony.gutierrez@amd.com 140711308Santhony.gutierrez@amd.com // if there is no release semantic, execute the RMW immediately 140811308Santhony.gutierrez@amd.com execAtomic(gpuDynInst); 140911308Santhony.gutierrez@amd.com 141011308Santhony.gutierrez@amd.com } 141111308Santhony.gutierrez@amd.com 141211347Sandreas.hansson@arm.com void execute(GPUDynInstPtr gpuDynInst) override; 141311308Santhony.gutierrez@amd.com 141411308Santhony.gutierrez@amd.com private: 141511308Santhony.gutierrez@amd.com // execAtomic may be called through a continuation 141611308Santhony.gutierrez@amd.com // if the RMW had release semantics. see comment for 141711308Santhony.gutierrez@amd.com // execContinuation in gpu_dyn_inst.hh 141811308Santhony.gutierrez@amd.com void 141911308Santhony.gutierrez@amd.com execAtomic(GPUDynInstPtr gpuDynInst) override 142011308Santhony.gutierrez@amd.com { 142111308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = gpuDynInst->exec_mask; 142211308Santhony.gutierrez@amd.com 142311308Santhony.gutierrez@amd.com typedef typename MemDataType::CType c0; 142411308Santhony.gutierrez@amd.com 142511308Santhony.gutierrez@amd.com c0 *d = &((c0*) gpuDynInst->d_data)[0]; 142611308Santhony.gutierrez@amd.com c0 *e = &((c0*) gpuDynInst->a_data)[0]; 142711308Santhony.gutierrez@amd.com c0 *f = &((c0*) gpuDynInst->x_data)[0]; 142811308Santhony.gutierrez@amd.com 142911534Sjohn.kalamatianos@amd.com for (int i = 0; i < gpuDynInst->computeUnit()->wfSize(); ++i) { 143011308Santhony.gutierrez@amd.com if (gpuDynInst->exec_mask[i]) { 143111308Santhony.gutierrez@amd.com Addr vaddr = gpuDynInst->addr[i]; 143211308Santhony.gutierrez@amd.com 143311692Santhony.gutierrez@amd.com if (this->isLocalMem()) { 143411308Santhony.gutierrez@amd.com Wavefront *wavefront = gpuDynInst->wavefront(); 143511308Santhony.gutierrez@amd.com *d = wavefront->ldsChunk->read<c0>(vaddr); 143611308Santhony.gutierrez@amd.com 143711692Santhony.gutierrez@amd.com if (this->isAtomicAdd()) { 143811308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 143911308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) + (*e)); 144011692Santhony.gutierrez@amd.com } else if (this->isAtomicSub()) { 144111308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 144211308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) - (*e)); 144311692Santhony.gutierrez@amd.com } else if (this->isAtomicMax()) { 144411308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 144511308Santhony.gutierrez@amd.com std::max(wavefront->ldsChunk->read<c0>(vaddr), 144611308Santhony.gutierrez@amd.com (*e))); 144711692Santhony.gutierrez@amd.com } else if (this->isAtomicMin()) { 144811308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 144911308Santhony.gutierrez@amd.com std::min(wavefront->ldsChunk->read<c0>(vaddr), 145011308Santhony.gutierrez@amd.com (*e))); 145111692Santhony.gutierrez@amd.com } else if (this->isAtomicAnd()) { 145211308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 145311308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) & (*e)); 145411692Santhony.gutierrez@amd.com } else if (this->isAtomicOr()) { 145511308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 145611308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) | (*e)); 145711692Santhony.gutierrez@amd.com } else if (this->isAtomicXor()) { 145811308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 145911308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) ^ (*e)); 146011692Santhony.gutierrez@amd.com } else if (this->isAtomicInc()) { 146111308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 146211308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) + 1); 146311692Santhony.gutierrez@amd.com } else if (this->isAtomicDec()) { 146411308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, 146511308Santhony.gutierrez@amd.com wavefront->ldsChunk->read<c0>(vaddr) - 1); 146611692Santhony.gutierrez@amd.com } else if (this->isAtomicExch()) { 146711308Santhony.gutierrez@amd.com wavefront->ldsChunk->write<c0>(vaddr, (*e)); 146811692Santhony.gutierrez@amd.com } else if (this->isAtomicCAS()) { 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)); 147211692Santhony.gutierrez@amd.com } else { 147311308Santhony.gutierrez@amd.com fatal("Unrecognized or invalid HSAIL atomic op " 147411308Santhony.gutierrez@amd.com "type.\n"); 147511308Santhony.gutierrez@amd.com } 147611308Santhony.gutierrez@amd.com } else { 147711308Santhony.gutierrez@amd.com Request *req = 147811308Santhony.gutierrez@amd.com new Request(0, vaddr, sizeof(c0), 0, 147911308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 148011435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId, 148111308Santhony.gutierrez@amd.com gpuDynInst->makeAtomicOpFunctor<c0>(e, 148211692Santhony.gutierrez@amd.com f)); 148311308Santhony.gutierrez@amd.com 148411308Santhony.gutierrez@amd.com gpuDynInst->setRequestFlags(req); 148511308Santhony.gutierrez@amd.com PacketPtr pkt = new Packet(req, MemCmd::SwapReq); 148611308Santhony.gutierrez@amd.com pkt->dataStatic(d); 148711308Santhony.gutierrez@amd.com 148811308Santhony.gutierrez@amd.com if (gpuDynInst->computeUnit()->shader-> 148911308Santhony.gutierrez@amd.com separate_acquire_release && 149011692Santhony.gutierrez@amd.com (gpuDynInst->isAcquire())) { 149111308Santhony.gutierrez@amd.com // if this atomic has acquire semantics, 149211308Santhony.gutierrez@amd.com // schedule the continuation to perform an 149311308Santhony.gutierrez@amd.com // acquire after the RMW completes 149411308Santhony.gutierrez@amd.com gpuDynInst->execContinuation = 149511308Santhony.gutierrez@amd.com &GPUStaticInst::execAtomicAcq; 149611308Santhony.gutierrez@amd.com 149711308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = true; 149811308Santhony.gutierrez@amd.com } else { 149911308Santhony.gutierrez@amd.com // the request will be finished when the RMW completes 150011308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 150111308Santhony.gutierrez@amd.com } 150211308Santhony.gutierrez@amd.com // translation is performed in sendRequest() 150311308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->sendRequest(gpuDynInst, i, 150411308Santhony.gutierrez@amd.com pkt); 150511308Santhony.gutierrez@amd.com } 150611308Santhony.gutierrez@amd.com } 150711308Santhony.gutierrez@amd.com 150811308Santhony.gutierrez@amd.com ++d; 150911308Santhony.gutierrez@amd.com ++e; 151011308Santhony.gutierrez@amd.com ++f; 151111308Santhony.gutierrez@amd.com } 151211308Santhony.gutierrez@amd.com 151311308Santhony.gutierrez@amd.com gpuDynInst->updateStats(); 151411308Santhony.gutierrez@amd.com } 151511308Santhony.gutierrez@amd.com 151611308Santhony.gutierrez@amd.com // execAtomicACq will always be called through a continuation. 151711308Santhony.gutierrez@amd.com // see comment for execContinuation in gpu_dyn_inst.hh 151811308Santhony.gutierrez@amd.com void 151911308Santhony.gutierrez@amd.com execAtomicAcq(GPUDynInstPtr gpuDynInst) override 152011308Santhony.gutierrez@amd.com { 152111308Santhony.gutierrez@amd.com // after performing the RMW, check to see if this instruction 152211308Santhony.gutierrez@amd.com // has acquire semantics, and if so, issue an acquire 152311692Santhony.gutierrez@amd.com if (!this->isLocalMem()) { 152411308Santhony.gutierrez@amd.com if (gpuDynInst->computeUnit()->shader->separate_acquire_release 152511692Santhony.gutierrez@amd.com && gpuDynInst->isAcquire()) { 152611308Santhony.gutierrez@amd.com gpuDynInst->statusBitVector = VectorMask(1); 152711308Santhony.gutierrez@amd.com 152811308Santhony.gutierrez@amd.com // the request will be finished when 152911308Santhony.gutierrez@amd.com // the acquire completes 153011308Santhony.gutierrez@amd.com gpuDynInst->useContinuation = false; 153111308Santhony.gutierrez@amd.com // create request 153211308Santhony.gutierrez@amd.com Request *req = new Request(0, 0, 0, 0, 153311308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->masterId(), 153411435Smitch.hayenga@arm.com 0, gpuDynInst->wfDynId); 153511308Santhony.gutierrez@amd.com req->setFlags(Request::ACQUIRE); 153611308Santhony.gutierrez@amd.com gpuDynInst->computeUnit()->injectGlobalMemFence(gpuDynInst, false, req); 153711308Santhony.gutierrez@amd.com } 153811308Santhony.gutierrez@amd.com } 153911308Santhony.gutierrez@amd.com } 154011308Santhony.gutierrez@amd.com }; 154111308Santhony.gutierrez@amd.com 154211308Santhony.gutierrez@amd.com template<typename DataType, typename AddrOperandType, int NumSrcOperands> 154311308Santhony.gutierrez@amd.com GPUStaticInst* 154411308Santhony.gutierrez@amd.com constructAtomic(const Brig::BrigInstBase *ib, const BrigObject *obj) 154511308Santhony.gutierrez@amd.com { 154611308Santhony.gutierrez@amd.com const Brig::BrigInstAtomic *at = (const Brig::BrigInstAtomic*)ib; 154711308Santhony.gutierrez@amd.com 154811308Santhony.gutierrez@amd.com if (at->atomicOperation == Brig::BRIG_ATOMIC_LD) { 154911308Santhony.gutierrez@amd.com return decodeLd<DataType>(ib, obj); 155011308Santhony.gutierrez@amd.com } else if (at->atomicOperation == Brig::BRIG_ATOMIC_ST) { 155111308Santhony.gutierrez@amd.com switch (ib->type) { 155211308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B8: 155311308Santhony.gutierrez@amd.com return decodeSt<S8,S8>(ib, obj); 155411308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B16: 155511536Staquangtuan1992@gmail.com return decodeSt<S16,S16>(ib, obj); 155611308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B32: 155711536Staquangtuan1992@gmail.com return decodeSt<S32,S32>(ib, obj); 155811308Santhony.gutierrez@amd.com case Brig::BRIG_TYPE_B64: 155911536Staquangtuan1992@gmail.com return decodeSt<S64,S64>(ib, obj); 156011308Santhony.gutierrez@amd.com default: fatal("AtomicSt: Operand type mismatch %d\n", ib->type); 156111308Santhony.gutierrez@amd.com } 156211308Santhony.gutierrez@amd.com } else { 156311308Santhony.gutierrez@amd.com if ((Brig::BrigOpcode)ib->opcode == Brig::BRIG_OPCODE_ATOMICNORET) 156411308Santhony.gutierrez@amd.com return new AtomicInst<DataType, AddrOperandType, 156511308Santhony.gutierrez@amd.com NumSrcOperands, false>(ib, obj, "atomicnoret"); 156611308Santhony.gutierrez@amd.com else 156711308Santhony.gutierrez@amd.com return new AtomicInst<DataType, AddrOperandType, 156811308Santhony.gutierrez@amd.com NumSrcOperands, true>(ib, obj, "atomic"); 156911308Santhony.gutierrez@amd.com } 157011308Santhony.gutierrez@amd.com } 157111308Santhony.gutierrez@amd.com 157211308Santhony.gutierrez@amd.com template<typename DataType, int NumSrcOperands> 157311308Santhony.gutierrez@amd.com GPUStaticInst* 157411308Santhony.gutierrez@amd.com decodeAtomicHelper(const Brig::BrigInstBase *ib, const BrigObject *obj) 157511308Santhony.gutierrez@amd.com { 157611308Santhony.gutierrez@amd.com unsigned addrIndex = (Brig::BrigOpcode)ib->opcode == 157711308Santhony.gutierrez@amd.com Brig::BRIG_OPCODE_ATOMICNORET ? 0 : 1; 157811308Santhony.gutierrez@amd.com 157911308Santhony.gutierrez@amd.com unsigned op_offs = obj->getOperandPtr(ib->operands,addrIndex); 158011308Santhony.gutierrez@amd.com 158111308Santhony.gutierrez@amd.com BrigRegOperandInfo tmp = findRegDataType(op_offs, obj); 158211308Santhony.gutierrez@amd.com 158311308Santhony.gutierrez@amd.com if (tmp.kind == Brig::BRIG_KIND_OPERAND_ADDRESS) { 158411308Santhony.gutierrez@amd.com return constructAtomic<DataType, NoRegAddrOperand, 158511308Santhony.gutierrez@amd.com NumSrcOperands>(ib, obj); 158611308Santhony.gutierrez@amd.com } else if (tmp.kind == Brig::BRIG_KIND_OPERAND_REGISTER) { 158711308Santhony.gutierrez@amd.com // V2/V4 not allowed 158811308Santhony.gutierrez@amd.com switch (tmp.regKind) { 158911308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_SINGLE: 159011308Santhony.gutierrez@amd.com return constructAtomic<DataType, SRegAddrOperand, 159111308Santhony.gutierrez@amd.com NumSrcOperands>(ib, obj); 159211308Santhony.gutierrez@amd.com case Brig::BRIG_REGISTER_KIND_DOUBLE: 159311308Santhony.gutierrez@amd.com return constructAtomic<DataType, DRegAddrOperand, 159411308Santhony.gutierrez@amd.com NumSrcOperands>(ib, obj); 159511308Santhony.gutierrez@amd.com default: 159611308Santhony.gutierrez@amd.com fatal("Bad atomic register operand type %d\n", tmp.type); 159711308Santhony.gutierrez@amd.com } 159811308Santhony.gutierrez@amd.com } else { 159911308Santhony.gutierrez@amd.com fatal("Bad atomic register operand kind %d\n", tmp.kind); 160011308Santhony.gutierrez@amd.com } 160111308Santhony.gutierrez@amd.com } 160211308Santhony.gutierrez@amd.com 160311308Santhony.gutierrez@amd.com 160411308Santhony.gutierrez@amd.com template<typename DataType> 160511308Santhony.gutierrez@amd.com GPUStaticInst* 160611308Santhony.gutierrez@amd.com decodeAtomic(const Brig::BrigInstBase *ib, const BrigObject *obj) 160711308Santhony.gutierrez@amd.com { 160811308Santhony.gutierrez@amd.com const Brig::BrigInstAtomic *at = (const Brig::BrigInstAtomic*)ib; 160911308Santhony.gutierrez@amd.com 161011308Santhony.gutierrez@amd.com if (at->atomicOperation == Brig::BRIG_ATOMIC_CAS) { 161111308Santhony.gutierrez@amd.com return decodeAtomicHelper<DataType, 2>(ib, obj); 161211308Santhony.gutierrez@amd.com } else { 161311308Santhony.gutierrez@amd.com return decodeAtomicHelper<DataType, 1>(ib, obj); 161411308Santhony.gutierrez@amd.com } 161511308Santhony.gutierrez@amd.com } 161611308Santhony.gutierrez@amd.com 161711308Santhony.gutierrez@amd.com template<typename DataType> 161811308Santhony.gutierrez@amd.com GPUStaticInst* 161911308Santhony.gutierrez@amd.com decodeAtomicNoRet(const Brig::BrigInstBase *ib, const BrigObject *obj) 162011308Santhony.gutierrez@amd.com { 162111308Santhony.gutierrez@amd.com const Brig::BrigInstAtomic *at = (const Brig::BrigInstAtomic*)ib; 162211308Santhony.gutierrez@amd.com if (at->atomicOperation == Brig::BRIG_ATOMIC_CAS) { 162311308Santhony.gutierrez@amd.com return decodeAtomicHelper<DataType, 2>(ib, obj); 162411308Santhony.gutierrez@amd.com } else { 162511308Santhony.gutierrez@amd.com return decodeAtomicHelper<DataType, 1>(ib, obj); 162611308Santhony.gutierrez@amd.com } 162711308Santhony.gutierrez@amd.com } 162811308Santhony.gutierrez@amd.com} // namespace HsailISA 162911308Santhony.gutierrez@amd.com 163011308Santhony.gutierrez@amd.com#endif // __ARCH_HSAIL_INSTS_MEM_HH__ 1631