gpu_dyn_inst.hh revision 11308
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 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: Anthony Gutierrez 3411308Santhony.gutierrez@amd.com */ 3511308Santhony.gutierrez@amd.com 3611308Santhony.gutierrez@amd.com#ifndef __GPU_DYN_INST_HH__ 3711308Santhony.gutierrez@amd.com#define __GPU_DYN_INST_HH__ 3811308Santhony.gutierrez@amd.com 3911308Santhony.gutierrez@amd.com#include <cstdint> 4011308Santhony.gutierrez@amd.com#include <string> 4111308Santhony.gutierrez@amd.com 4211308Santhony.gutierrez@amd.com#include "enums/GenericMemoryOrder.hh" 4311308Santhony.gutierrez@amd.com#include "enums/GenericMemoryScope.hh" 4411308Santhony.gutierrez@amd.com#include "enums/MemOpType.hh" 4511308Santhony.gutierrez@amd.com#include "enums/MemType.hh" 4611308Santhony.gutierrez@amd.com#include "enums/OpType.hh" 4711308Santhony.gutierrez@amd.com#include "enums/StorageClassType.hh" 4811308Santhony.gutierrez@amd.com#include "gpu-compute/compute_unit.hh" 4911308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_exec_context.hh" 5011308Santhony.gutierrez@amd.com 5111308Santhony.gutierrez@amd.comclass GPUStaticInst; 5211308Santhony.gutierrez@amd.com 5311308Santhony.gutierrez@amd.comtemplate<typename T> 5411308Santhony.gutierrez@amd.comclass AtomicOpAnd : public TypedAtomicOpFunctor<T> 5511308Santhony.gutierrez@amd.com{ 5611308Santhony.gutierrez@amd.com public: 5711308Santhony.gutierrez@amd.com T a; 5811308Santhony.gutierrez@amd.com 5911308Santhony.gutierrez@amd.com AtomicOpAnd(T _a) : a(_a) { } 6011308Santhony.gutierrez@amd.com void execute(T *b) { *b &= a; } 6111308Santhony.gutierrez@amd.com}; 6211308Santhony.gutierrez@amd.com 6311308Santhony.gutierrez@amd.comtemplate<typename T> 6411308Santhony.gutierrez@amd.comclass AtomicOpOr : public TypedAtomicOpFunctor<T> 6511308Santhony.gutierrez@amd.com{ 6611308Santhony.gutierrez@amd.com public: 6711308Santhony.gutierrez@amd.com T a; 6811308Santhony.gutierrez@amd.com AtomicOpOr(T _a) : a(_a) { } 6911308Santhony.gutierrez@amd.com void execute(T *b) { *b |= a; } 7011308Santhony.gutierrez@amd.com}; 7111308Santhony.gutierrez@amd.com 7211308Santhony.gutierrez@amd.comtemplate<typename T> 7311308Santhony.gutierrez@amd.comclass AtomicOpXor : public TypedAtomicOpFunctor<T> 7411308Santhony.gutierrez@amd.com{ 7511308Santhony.gutierrez@amd.com public: 7611308Santhony.gutierrez@amd.com T a; 7711308Santhony.gutierrez@amd.com AtomicOpXor(T _a) : a(_a) {} 7811308Santhony.gutierrez@amd.com void execute(T *b) { *b ^= a; } 7911308Santhony.gutierrez@amd.com}; 8011308Santhony.gutierrez@amd.com 8111308Santhony.gutierrez@amd.comtemplate<typename T> 8211308Santhony.gutierrez@amd.comclass AtomicOpCAS : public TypedAtomicOpFunctor<T> 8311308Santhony.gutierrez@amd.com{ 8411308Santhony.gutierrez@amd.com public: 8511308Santhony.gutierrez@amd.com T c; 8611308Santhony.gutierrez@amd.com T s; 8711308Santhony.gutierrez@amd.com 8811308Santhony.gutierrez@amd.com ComputeUnit *computeUnit; 8911308Santhony.gutierrez@amd.com 9011308Santhony.gutierrez@amd.com AtomicOpCAS(T _c, T _s, ComputeUnit *compute_unit) 9111308Santhony.gutierrez@amd.com : c(_c), s(_s), computeUnit(compute_unit) { } 9211308Santhony.gutierrez@amd.com 9311308Santhony.gutierrez@amd.com void 9411308Santhony.gutierrez@amd.com execute(T *b) 9511308Santhony.gutierrez@amd.com { 9611308Santhony.gutierrez@amd.com computeUnit->numCASOps++; 9711308Santhony.gutierrez@amd.com 9811308Santhony.gutierrez@amd.com if (*b == c) { 9911308Santhony.gutierrez@amd.com *b = s; 10011308Santhony.gutierrez@amd.com } else { 10111308Santhony.gutierrez@amd.com computeUnit->numFailedCASOps++; 10211308Santhony.gutierrez@amd.com } 10311308Santhony.gutierrez@amd.com 10411308Santhony.gutierrez@amd.com if (computeUnit->xact_cas_mode) { 10511308Santhony.gutierrez@amd.com computeUnit->xactCasLoadMap.clear(); 10611308Santhony.gutierrez@amd.com } 10711308Santhony.gutierrez@amd.com } 10811308Santhony.gutierrez@amd.com}; 10911308Santhony.gutierrez@amd.com 11011308Santhony.gutierrez@amd.comtemplate<typename T> 11111308Santhony.gutierrez@amd.comclass AtomicOpExch : public TypedAtomicOpFunctor<T> 11211308Santhony.gutierrez@amd.com{ 11311308Santhony.gutierrez@amd.com public: 11411308Santhony.gutierrez@amd.com T a; 11511308Santhony.gutierrez@amd.com AtomicOpExch(T _a) : a(_a) { } 11611308Santhony.gutierrez@amd.com void execute(T *b) { *b = a; } 11711308Santhony.gutierrez@amd.com}; 11811308Santhony.gutierrez@amd.com 11911308Santhony.gutierrez@amd.comtemplate<typename T> 12011308Santhony.gutierrez@amd.comclass AtomicOpAdd : public TypedAtomicOpFunctor<T> 12111308Santhony.gutierrez@amd.com{ 12211308Santhony.gutierrez@amd.com public: 12311308Santhony.gutierrez@amd.com T a; 12411308Santhony.gutierrez@amd.com AtomicOpAdd(T _a) : a(_a) { } 12511308Santhony.gutierrez@amd.com void execute(T *b) { *b += a; } 12611308Santhony.gutierrez@amd.com}; 12711308Santhony.gutierrez@amd.com 12811308Santhony.gutierrez@amd.comtemplate<typename T> 12911308Santhony.gutierrez@amd.comclass AtomicOpSub : public TypedAtomicOpFunctor<T> 13011308Santhony.gutierrez@amd.com{ 13111308Santhony.gutierrez@amd.com public: 13211308Santhony.gutierrez@amd.com T a; 13311308Santhony.gutierrez@amd.com AtomicOpSub(T _a) : a(_a) { } 13411308Santhony.gutierrez@amd.com void execute(T *b) { *b -= a; } 13511308Santhony.gutierrez@amd.com}; 13611308Santhony.gutierrez@amd.com 13711308Santhony.gutierrez@amd.comtemplate<typename T> 13811308Santhony.gutierrez@amd.comclass AtomicOpInc : public TypedAtomicOpFunctor<T> 13911308Santhony.gutierrez@amd.com{ 14011308Santhony.gutierrez@amd.com public: 14111308Santhony.gutierrez@amd.com AtomicOpInc() { } 14211308Santhony.gutierrez@amd.com void execute(T *b) { *b += 1; } 14311308Santhony.gutierrez@amd.com}; 14411308Santhony.gutierrez@amd.com 14511308Santhony.gutierrez@amd.comtemplate<typename T> 14611308Santhony.gutierrez@amd.comclass AtomicOpDec : public TypedAtomicOpFunctor<T> 14711308Santhony.gutierrez@amd.com{ 14811308Santhony.gutierrez@amd.com public: 14911308Santhony.gutierrez@amd.com AtomicOpDec() {} 15011308Santhony.gutierrez@amd.com void execute(T *b) { *b -= 1; } 15111308Santhony.gutierrez@amd.com}; 15211308Santhony.gutierrez@amd.com 15311308Santhony.gutierrez@amd.comtemplate<typename T> 15411308Santhony.gutierrez@amd.comclass AtomicOpMax : public TypedAtomicOpFunctor<T> 15511308Santhony.gutierrez@amd.com{ 15611308Santhony.gutierrez@amd.com public: 15711308Santhony.gutierrez@amd.com T a; 15811308Santhony.gutierrez@amd.com AtomicOpMax(T _a) : a(_a) { } 15911308Santhony.gutierrez@amd.com 16011308Santhony.gutierrez@amd.com void 16111308Santhony.gutierrez@amd.com execute(T *b) 16211308Santhony.gutierrez@amd.com { 16311308Santhony.gutierrez@amd.com if (a > *b) 16411308Santhony.gutierrez@amd.com *b = a; 16511308Santhony.gutierrez@amd.com } 16611308Santhony.gutierrez@amd.com}; 16711308Santhony.gutierrez@amd.com 16811308Santhony.gutierrez@amd.comtemplate<typename T> 16911308Santhony.gutierrez@amd.comclass AtomicOpMin : public TypedAtomicOpFunctor<T> 17011308Santhony.gutierrez@amd.com{ 17111308Santhony.gutierrez@amd.com public: 17211308Santhony.gutierrez@amd.com T a; 17311308Santhony.gutierrez@amd.com AtomicOpMin(T _a) : a(_a) {} 17411308Santhony.gutierrez@amd.com 17511308Santhony.gutierrez@amd.com void 17611308Santhony.gutierrez@amd.com execute(T *b) 17711308Santhony.gutierrez@amd.com { 17811308Santhony.gutierrez@amd.com if (a < *b) 17911308Santhony.gutierrez@amd.com *b = a; 18011308Santhony.gutierrez@amd.com } 18111308Santhony.gutierrez@amd.com}; 18211308Santhony.gutierrez@amd.com 18311308Santhony.gutierrez@amd.com#define MO_A(a) ((a)>=Enums::MO_AAND && (a)<=Enums::MO_AMIN) 18411308Santhony.gutierrez@amd.com#define MO_ANR(a) ((a)>=Enums::MO_ANRAND && (a)<=Enums::MO_ANRMIN) 18511308Santhony.gutierrez@amd.com#define MO_H(a) ((a)>=Enums::MO_HAND && (a)<=Enums::MO_HMIN) 18611308Santhony.gutierrez@amd.com 18711308Santhony.gutierrez@amd.comtypedef enum 18811308Santhony.gutierrez@amd.com{ 18911308Santhony.gutierrez@amd.com VT_32, 19011308Santhony.gutierrez@amd.com VT_64, 19111308Santhony.gutierrez@amd.com} vgpr_type; 19211308Santhony.gutierrez@amd.com 19311308Santhony.gutierrez@amd.comtypedef enum 19411308Santhony.gutierrez@amd.com{ 19511308Santhony.gutierrez@amd.com SEG_PRIVATE, 19611308Santhony.gutierrez@amd.com SEG_SPILL, 19711308Santhony.gutierrez@amd.com SEG_GLOBAL, 19811308Santhony.gutierrez@amd.com SEG_SHARED, 19911308Santhony.gutierrez@amd.com SEG_READONLY, 20011308Santhony.gutierrez@amd.com SEG_FLAT 20111308Santhony.gutierrez@amd.com} seg_type; 20211308Santhony.gutierrez@amd.com 20311308Santhony.gutierrez@amd.comclass GPUDynInst : public GPUExecContext 20411308Santhony.gutierrez@amd.com{ 20511308Santhony.gutierrez@amd.com public: 20611308Santhony.gutierrez@amd.com GPUDynInst(ComputeUnit *_cu, Wavefront *_wf, GPUStaticInst *_staticInst, 20711308Santhony.gutierrez@amd.com uint64_t instSeqNum); 20811308Santhony.gutierrez@amd.com 20911308Santhony.gutierrez@amd.com void execute(); 21011308Santhony.gutierrez@amd.com int numSrcRegOperands(); 21111308Santhony.gutierrez@amd.com int numDstRegOperands(); 21211308Santhony.gutierrez@amd.com int getNumOperands(); 21311308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIdx); 21411308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIdx); 21511308Santhony.gutierrez@amd.com int getRegisterIndex(int operandIdx); 21611308Santhony.gutierrez@amd.com int getOperandSize(int operandIdx); 21711308Santhony.gutierrez@amd.com bool isDstOperand(int operandIdx); 21811308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIdx); 21911308Santhony.gutierrez@amd.com bool isArgLoad(); 22011308Santhony.gutierrez@amd.com 22111308Santhony.gutierrez@amd.com const std::string &disassemble() const; 22211308Santhony.gutierrez@amd.com 22311308Santhony.gutierrez@amd.com uint64_t seqNum() const; 22411308Santhony.gutierrez@amd.com 22511308Santhony.gutierrez@amd.com Enums::OpType opType(); 22611308Santhony.gutierrez@amd.com Enums::StorageClassType executedAs(); 22711308Santhony.gutierrez@amd.com 22811308Santhony.gutierrez@amd.com // The address of the memory operation 22911308Santhony.gutierrez@amd.com Addr addr[VSZ]; 23011308Santhony.gutierrez@amd.com Addr pAddr; 23111308Santhony.gutierrez@amd.com 23211308Santhony.gutierrez@amd.com // The data to get written 23311308Santhony.gutierrez@amd.com uint8_t d_data[VSZ * 16]; 23411308Santhony.gutierrez@amd.com // Additional data (for atomics) 23511308Santhony.gutierrez@amd.com uint8_t a_data[VSZ * 8]; 23611308Santhony.gutierrez@amd.com // Additional data (for atomics) 23711308Santhony.gutierrez@amd.com uint8_t x_data[VSZ * 8]; 23811308Santhony.gutierrez@amd.com // The execution mask 23911308Santhony.gutierrez@amd.com VectorMask exec_mask; 24011308Santhony.gutierrez@amd.com 24111308Santhony.gutierrez@amd.com // The memory type (M_U32, M_S32, ...) 24211308Santhony.gutierrez@amd.com Enums::MemType m_type; 24311308Santhony.gutierrez@amd.com // The memory operation (MO_LD, MO_ST, ...) 24411308Santhony.gutierrez@amd.com Enums::MemOpType m_op; 24511308Santhony.gutierrez@amd.com Enums::GenericMemoryOrder memoryOrder; 24611308Santhony.gutierrez@amd.com 24711308Santhony.gutierrez@amd.com // Scope of the request 24811308Santhony.gutierrez@amd.com Enums::GenericMemoryScope scope; 24911308Santhony.gutierrez@amd.com // The memory segment (SEG_SHARED, SEG_GLOBAL, ...) 25011308Santhony.gutierrez@amd.com seg_type s_type; 25111308Santhony.gutierrez@amd.com // The equivalency class 25211308Santhony.gutierrez@amd.com int equiv; 25311308Santhony.gutierrez@amd.com // The return VGPR type (VT_32 or VT_64) 25411308Santhony.gutierrez@amd.com vgpr_type v_type; 25511308Santhony.gutierrez@amd.com // Number of VGPR's accessed (1, 2, or 4) 25611308Santhony.gutierrez@amd.com int n_reg; 25711308Santhony.gutierrez@amd.com // The return VGPR index 25811308Santhony.gutierrez@amd.com int dst_reg; 25911308Santhony.gutierrez@amd.com // There can be max 4 dest regs> 26011308Santhony.gutierrez@amd.com int dst_reg_vec[4]; 26111308Santhony.gutierrez@amd.com // SIMD where the WF of the memory instruction has been mapped to 26211308Santhony.gutierrez@amd.com int simdId; 26311308Santhony.gutierrez@amd.com // unique id of the WF where the memory instruction belongs to 26411308Santhony.gutierrez@amd.com int wfDynId; 26511308Santhony.gutierrez@amd.com // The kernel id of the requesting wf 26611308Santhony.gutierrez@amd.com int kern_id; 26711308Santhony.gutierrez@amd.com // The CU id of the requesting wf 26811308Santhony.gutierrez@amd.com int cu_id; 26911308Santhony.gutierrez@amd.com // HW slot id where the WF is mapped to inside a SIMD unit 27011308Santhony.gutierrez@amd.com int wfSlotId; 27111308Santhony.gutierrez@amd.com // execution pipeline id where the memory instruction has been scheduled 27211308Santhony.gutierrez@amd.com int pipeId; 27311308Santhony.gutierrez@amd.com // The execution time of this operation 27411308Santhony.gutierrez@amd.com Tick time; 27511308Santhony.gutierrez@amd.com // The latency of this operation 27611308Santhony.gutierrez@amd.com WaitClass latency; 27711308Santhony.gutierrez@amd.com // A list of bank conflicts for the 4 cycles. 27811308Santhony.gutierrez@amd.com uint32_t bc[4]; 27911308Santhony.gutierrez@amd.com 28011308Santhony.gutierrez@amd.com // A pointer to ROM 28111308Santhony.gutierrez@amd.com uint8_t *rom; 28211308Santhony.gutierrez@amd.com // The size of the READONLY segment 28311308Santhony.gutierrez@amd.com int sz_rom; 28411308Santhony.gutierrez@amd.com 28511308Santhony.gutierrez@amd.com // Initiate the specified memory operation, by creating a 28611308Santhony.gutierrez@amd.com // memory request and sending it off to the memory system. 28711308Santhony.gutierrez@amd.com void initiateAcc(GPUDynInstPtr gpuDynInst); 28811308Santhony.gutierrez@amd.com 28911308Santhony.gutierrez@amd.com void updateStats(); 29011308Santhony.gutierrez@amd.com 29111308Santhony.gutierrez@amd.com GPUStaticInst* staticInstruction() { return staticInst; } 29211308Santhony.gutierrez@amd.com 29311308Santhony.gutierrez@amd.com // Is the instruction a scalar or vector op? 29411308Santhony.gutierrez@amd.com bool scalarOp() const; 29511308Santhony.gutierrez@amd.com 29611308Santhony.gutierrez@amd.com /* 29711308Santhony.gutierrez@amd.com * Loads/stores/atomics may have acquire/release semantics associated 29811308Santhony.gutierrez@amd.com * withthem. Some protocols want to see the acquire/release as separate 29911308Santhony.gutierrez@amd.com * requests from the load/store/atomic. We implement that separation 30011308Santhony.gutierrez@amd.com * using continuations (i.e., a function pointer with an object associated 30111308Santhony.gutierrez@amd.com * with it). When, for example, the front-end generates a store with 30211308Santhony.gutierrez@amd.com * release semantics, we will first issue a normal store and set the 30311308Santhony.gutierrez@amd.com * continuation in the GPUDynInst to a function that generate a 30411308Santhony.gutierrez@amd.com * release request. That continuation will be called when the normal 30511308Santhony.gutierrez@amd.com * store completes (in ComputeUnit::DataPort::recvTimingResponse). The 30611308Santhony.gutierrez@amd.com * continuation will be called in the context of the same GPUDynInst 30711308Santhony.gutierrez@amd.com * that generated the initial store. 30811308Santhony.gutierrez@amd.com */ 30911308Santhony.gutierrez@amd.com std::function<void(GPUStaticInst*, GPUDynInstPtr)> execContinuation; 31011308Santhony.gutierrez@amd.com 31111308Santhony.gutierrez@amd.com // when true, call execContinuation when response arrives 31211308Santhony.gutierrez@amd.com bool useContinuation; 31311308Santhony.gutierrez@amd.com 31411308Santhony.gutierrez@amd.com template<typename c0> AtomicOpFunctor* 31511308Santhony.gutierrez@amd.com makeAtomicOpFunctor(c0 *reg0, c0 *reg1, Enums::MemOpType op) 31611308Santhony.gutierrez@amd.com { 31711308Santhony.gutierrez@amd.com using namespace Enums; 31811308Santhony.gutierrez@amd.com 31911308Santhony.gutierrez@amd.com switch(op) { 32011308Santhony.gutierrez@amd.com case MO_AAND: 32111308Santhony.gutierrez@amd.com case MO_ANRAND: 32211308Santhony.gutierrez@amd.com return new AtomicOpAnd<c0>(*reg0); 32311308Santhony.gutierrez@amd.com case MO_AOR: 32411308Santhony.gutierrez@amd.com case MO_ANROR: 32511308Santhony.gutierrez@amd.com return new AtomicOpOr<c0>(*reg0); 32611308Santhony.gutierrez@amd.com case MO_AXOR: 32711308Santhony.gutierrez@amd.com case MO_ANRXOR: 32811308Santhony.gutierrez@amd.com return new AtomicOpXor<c0>(*reg0); 32911308Santhony.gutierrez@amd.com case MO_ACAS: 33011308Santhony.gutierrez@amd.com case MO_ANRCAS: 33111308Santhony.gutierrez@amd.com return new AtomicOpCAS<c0>(*reg0, *reg1, cu); 33211308Santhony.gutierrez@amd.com case MO_AEXCH: 33311308Santhony.gutierrez@amd.com case MO_ANREXCH: 33411308Santhony.gutierrez@amd.com return new AtomicOpExch<c0>(*reg0); 33511308Santhony.gutierrez@amd.com case MO_AADD: 33611308Santhony.gutierrez@amd.com case MO_ANRADD: 33711308Santhony.gutierrez@amd.com return new AtomicOpAdd<c0>(*reg0); 33811308Santhony.gutierrez@amd.com case MO_ASUB: 33911308Santhony.gutierrez@amd.com case MO_ANRSUB: 34011308Santhony.gutierrez@amd.com return new AtomicOpSub<c0>(*reg0); 34111308Santhony.gutierrez@amd.com case MO_AINC: 34211308Santhony.gutierrez@amd.com case MO_ANRINC: 34311308Santhony.gutierrez@amd.com return new AtomicOpInc<c0>(); 34411308Santhony.gutierrez@amd.com case MO_ADEC: 34511308Santhony.gutierrez@amd.com case MO_ANRDEC: 34611308Santhony.gutierrez@amd.com return new AtomicOpDec<c0>(); 34711308Santhony.gutierrez@amd.com case MO_AMAX: 34811308Santhony.gutierrez@amd.com case MO_ANRMAX: 34911308Santhony.gutierrez@amd.com return new AtomicOpMax<c0>(*reg0); 35011308Santhony.gutierrez@amd.com case MO_AMIN: 35111308Santhony.gutierrez@amd.com case MO_ANRMIN: 35211308Santhony.gutierrez@amd.com return new AtomicOpMin<c0>(*reg0); 35311308Santhony.gutierrez@amd.com default: 35411308Santhony.gutierrez@amd.com panic("Unrecognized atomic operation"); 35511308Santhony.gutierrez@amd.com } 35611308Santhony.gutierrez@amd.com } 35711308Santhony.gutierrez@amd.com 35811308Santhony.gutierrez@amd.com void 35911308Santhony.gutierrez@amd.com setRequestFlags(Request *req, bool setMemOrder=true) 36011308Santhony.gutierrez@amd.com { 36111308Santhony.gutierrez@amd.com // currently these are the easy scopes to deduce 36211308Santhony.gutierrez@amd.com switch (s_type) { 36311308Santhony.gutierrez@amd.com case SEG_PRIVATE: 36411308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::PRIVATE_SEGMENT); 36511308Santhony.gutierrez@amd.com break; 36611308Santhony.gutierrez@amd.com case SEG_SPILL: 36711308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SPILL_SEGMENT); 36811308Santhony.gutierrez@amd.com break; 36911308Santhony.gutierrez@amd.com case SEG_GLOBAL: 37011308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::GLOBAL_SEGMENT); 37111308Santhony.gutierrez@amd.com break; 37211308Santhony.gutierrez@amd.com case SEG_READONLY: 37311308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::READONLY_SEGMENT); 37411308Santhony.gutierrez@amd.com break; 37511308Santhony.gutierrez@amd.com case SEG_SHARED: 37611308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::GROUP_SEGMENT); 37711308Santhony.gutierrez@amd.com break; 37811308Santhony.gutierrez@amd.com case SEG_FLAT: 37911308Santhony.gutierrez@amd.com // TODO: translate to correct scope 38011308Santhony.gutierrez@amd.com assert(false); 38111308Santhony.gutierrez@amd.com default: 38211308Santhony.gutierrez@amd.com panic("Bad segment type"); 38311308Santhony.gutierrez@amd.com break; 38411308Santhony.gutierrez@amd.com } 38511308Santhony.gutierrez@amd.com 38611308Santhony.gutierrez@amd.com switch (scope) { 38711308Santhony.gutierrez@amd.com case Enums::MEMORY_SCOPE_NONE: 38811308Santhony.gutierrez@amd.com case Enums::MEMORY_SCOPE_WORKITEM: 38911308Santhony.gutierrez@amd.com break; 39011308Santhony.gutierrez@amd.com case Enums::MEMORY_SCOPE_WAVEFRONT: 39111308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SCOPE_VALID | 39211308Santhony.gutierrez@amd.com Request::WAVEFRONT_SCOPE); 39311308Santhony.gutierrez@amd.com break; 39411308Santhony.gutierrez@amd.com case Enums::MEMORY_SCOPE_WORKGROUP: 39511308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SCOPE_VALID | 39611308Santhony.gutierrez@amd.com Request::WORKGROUP_SCOPE); 39711308Santhony.gutierrez@amd.com break; 39811308Santhony.gutierrez@amd.com case Enums::MEMORY_SCOPE_DEVICE: 39911308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SCOPE_VALID | 40011308Santhony.gutierrez@amd.com Request::DEVICE_SCOPE); 40111308Santhony.gutierrez@amd.com break; 40211308Santhony.gutierrez@amd.com case Enums::MEMORY_SCOPE_SYSTEM: 40311308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SCOPE_VALID | 40411308Santhony.gutierrez@amd.com Request::SYSTEM_SCOPE); 40511308Santhony.gutierrez@amd.com break; 40611308Santhony.gutierrez@amd.com default: 40711308Santhony.gutierrez@amd.com panic("Bad scope type"); 40811308Santhony.gutierrez@amd.com break; 40911308Santhony.gutierrez@amd.com } 41011308Santhony.gutierrez@amd.com 41111308Santhony.gutierrez@amd.com if (setMemOrder) { 41211308Santhony.gutierrez@amd.com // set acquire and release flags 41311308Santhony.gutierrez@amd.com switch (memoryOrder){ 41411308Santhony.gutierrez@amd.com case Enums::MEMORY_ORDER_SC_ACQUIRE: 41511308Santhony.gutierrez@amd.com req->setFlags(Request::ACQUIRE); 41611308Santhony.gutierrez@amd.com break; 41711308Santhony.gutierrez@amd.com case Enums::MEMORY_ORDER_SC_RELEASE: 41811308Santhony.gutierrez@amd.com req->setFlags(Request::RELEASE); 41911308Santhony.gutierrez@amd.com break; 42011308Santhony.gutierrez@amd.com case Enums::MEMORY_ORDER_SC_ACQUIRE_RELEASE: 42111308Santhony.gutierrez@amd.com req->setFlags(Request::ACQUIRE | Request::RELEASE); 42211308Santhony.gutierrez@amd.com break; 42311308Santhony.gutierrez@amd.com default: 42411308Santhony.gutierrez@amd.com break; 42511308Santhony.gutierrez@amd.com } 42611308Santhony.gutierrez@amd.com } 42711308Santhony.gutierrez@amd.com 42811308Santhony.gutierrez@amd.com // set atomic type 42911308Santhony.gutierrez@amd.com // currently, the instruction genenerator only produces atomic return 43011308Santhony.gutierrez@amd.com // but a magic instruction can produce atomic no return 43111308Santhony.gutierrez@amd.com if (m_op == Enums::MO_AADD || m_op == Enums::MO_ASUB || 43211308Santhony.gutierrez@amd.com m_op == Enums::MO_AAND || m_op == Enums::MO_AOR || 43311308Santhony.gutierrez@amd.com m_op == Enums::MO_AXOR || m_op == Enums::MO_AMAX || 43411308Santhony.gutierrez@amd.com m_op == Enums::MO_AMIN || m_op == Enums::MO_AINC || 43511308Santhony.gutierrez@amd.com m_op == Enums::MO_ADEC || m_op == Enums::MO_AEXCH || 43611308Santhony.gutierrez@amd.com m_op == Enums::MO_ACAS) { 43711308Santhony.gutierrez@amd.com req->setFlags(Request::ATOMIC_RETURN_OP); 43811308Santhony.gutierrez@amd.com } else if (m_op == Enums::MO_ANRADD || m_op == Enums::MO_ANRSUB || 43911308Santhony.gutierrez@amd.com m_op == Enums::MO_ANRAND || m_op == Enums::MO_ANROR || 44011308Santhony.gutierrez@amd.com m_op == Enums::MO_ANRXOR || m_op == Enums::MO_ANRMAX || 44111308Santhony.gutierrez@amd.com m_op == Enums::MO_ANRMIN || m_op == Enums::MO_ANRINC || 44211308Santhony.gutierrez@amd.com m_op == Enums::MO_ANRDEC || m_op == Enums::MO_ANREXCH || 44311308Santhony.gutierrez@amd.com m_op == Enums::MO_ANRCAS) { 44411308Santhony.gutierrez@amd.com req->setFlags(Request::ATOMIC_NO_RETURN_OP); 44511308Santhony.gutierrez@amd.com } 44611308Santhony.gutierrez@amd.com } 44711308Santhony.gutierrez@amd.com 44811308Santhony.gutierrez@amd.com // Map returned packets and the addresses they satisfy with which lane they 44911308Santhony.gutierrez@amd.com // were requested from 45011308Santhony.gutierrez@amd.com typedef std::unordered_map<Addr, std::vector<int>> StatusVector; 45111308Santhony.gutierrez@amd.com StatusVector memStatusVector; 45211308Santhony.gutierrez@amd.com 45311308Santhony.gutierrez@amd.com // Track the status of memory requests per lane, a bit per lane 45411308Santhony.gutierrez@amd.com VectorMask statusBitVector; 45511308Santhony.gutierrez@amd.com // for ld_v# or st_v# 45611308Santhony.gutierrez@amd.com std::vector<int> statusVector; 45711308Santhony.gutierrez@amd.com std::vector<int> tlbHitLevel; 45811308Santhony.gutierrez@amd.com 45911308Santhony.gutierrez@amd.com private: 46011308Santhony.gutierrez@amd.com GPUStaticInst *staticInst; 46111308Santhony.gutierrez@amd.com uint64_t _seqNum; 46211308Santhony.gutierrez@amd.com}; 46311308Santhony.gutierrez@amd.com 46411308Santhony.gutierrez@amd.com#endif // __GPU_DYN_INST_HH__ 465