gpu_dyn_inst.hh revision 11699
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/MemType.hh" 4311308Santhony.gutierrez@amd.com#include "enums/StorageClassType.hh" 4411308Santhony.gutierrez@amd.com#include "gpu-compute/compute_unit.hh" 4511308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_exec_context.hh" 4611308Santhony.gutierrez@amd.com 4711308Santhony.gutierrez@amd.comclass GPUStaticInst; 4811308Santhony.gutierrez@amd.com 4911308Santhony.gutierrez@amd.comtemplate<typename T> 5011308Santhony.gutierrez@amd.comclass AtomicOpAnd : public TypedAtomicOpFunctor<T> 5111308Santhony.gutierrez@amd.com{ 5211308Santhony.gutierrez@amd.com public: 5311308Santhony.gutierrez@amd.com T a; 5411308Santhony.gutierrez@amd.com 5511308Santhony.gutierrez@amd.com AtomicOpAnd(T _a) : a(_a) { } 5611308Santhony.gutierrez@amd.com void execute(T *b) { *b &= a; } 5711308Santhony.gutierrez@amd.com}; 5811308Santhony.gutierrez@amd.com 5911308Santhony.gutierrez@amd.comtemplate<typename T> 6011308Santhony.gutierrez@amd.comclass AtomicOpOr : public TypedAtomicOpFunctor<T> 6111308Santhony.gutierrez@amd.com{ 6211308Santhony.gutierrez@amd.com public: 6311308Santhony.gutierrez@amd.com T a; 6411308Santhony.gutierrez@amd.com AtomicOpOr(T _a) : a(_a) { } 6511308Santhony.gutierrez@amd.com void execute(T *b) { *b |= a; } 6611308Santhony.gutierrez@amd.com}; 6711308Santhony.gutierrez@amd.com 6811308Santhony.gutierrez@amd.comtemplate<typename T> 6911308Santhony.gutierrez@amd.comclass AtomicOpXor : public TypedAtomicOpFunctor<T> 7011308Santhony.gutierrez@amd.com{ 7111308Santhony.gutierrez@amd.com public: 7211308Santhony.gutierrez@amd.com T a; 7311308Santhony.gutierrez@amd.com AtomicOpXor(T _a) : a(_a) {} 7411308Santhony.gutierrez@amd.com void execute(T *b) { *b ^= a; } 7511308Santhony.gutierrez@amd.com}; 7611308Santhony.gutierrez@amd.com 7711308Santhony.gutierrez@amd.comtemplate<typename T> 7811308Santhony.gutierrez@amd.comclass AtomicOpCAS : public TypedAtomicOpFunctor<T> 7911308Santhony.gutierrez@amd.com{ 8011308Santhony.gutierrez@amd.com public: 8111308Santhony.gutierrez@amd.com T c; 8211308Santhony.gutierrez@amd.com T s; 8311308Santhony.gutierrez@amd.com 8411308Santhony.gutierrez@amd.com ComputeUnit *computeUnit; 8511308Santhony.gutierrez@amd.com 8611308Santhony.gutierrez@amd.com AtomicOpCAS(T _c, T _s, ComputeUnit *compute_unit) 8711308Santhony.gutierrez@amd.com : c(_c), s(_s), computeUnit(compute_unit) { } 8811308Santhony.gutierrez@amd.com 8911308Santhony.gutierrez@amd.com void 9011308Santhony.gutierrez@amd.com execute(T *b) 9111308Santhony.gutierrez@amd.com { 9211308Santhony.gutierrez@amd.com computeUnit->numCASOps++; 9311308Santhony.gutierrez@amd.com 9411308Santhony.gutierrez@amd.com if (*b == c) { 9511308Santhony.gutierrez@amd.com *b = s; 9611308Santhony.gutierrez@amd.com } else { 9711308Santhony.gutierrez@amd.com computeUnit->numFailedCASOps++; 9811308Santhony.gutierrez@amd.com } 9911308Santhony.gutierrez@amd.com 10011308Santhony.gutierrez@amd.com if (computeUnit->xact_cas_mode) { 10111308Santhony.gutierrez@amd.com computeUnit->xactCasLoadMap.clear(); 10211308Santhony.gutierrez@amd.com } 10311308Santhony.gutierrez@amd.com } 10411308Santhony.gutierrez@amd.com}; 10511308Santhony.gutierrez@amd.com 10611308Santhony.gutierrez@amd.comtemplate<typename T> 10711308Santhony.gutierrez@amd.comclass AtomicOpExch : public TypedAtomicOpFunctor<T> 10811308Santhony.gutierrez@amd.com{ 10911308Santhony.gutierrez@amd.com public: 11011308Santhony.gutierrez@amd.com T a; 11111308Santhony.gutierrez@amd.com AtomicOpExch(T _a) : a(_a) { } 11211308Santhony.gutierrez@amd.com void execute(T *b) { *b = a; } 11311308Santhony.gutierrez@amd.com}; 11411308Santhony.gutierrez@amd.com 11511308Santhony.gutierrez@amd.comtemplate<typename T> 11611308Santhony.gutierrez@amd.comclass AtomicOpAdd : public TypedAtomicOpFunctor<T> 11711308Santhony.gutierrez@amd.com{ 11811308Santhony.gutierrez@amd.com public: 11911308Santhony.gutierrez@amd.com T a; 12011308Santhony.gutierrez@amd.com AtomicOpAdd(T _a) : a(_a) { } 12111308Santhony.gutierrez@amd.com void execute(T *b) { *b += a; } 12211308Santhony.gutierrez@amd.com}; 12311308Santhony.gutierrez@amd.com 12411308Santhony.gutierrez@amd.comtemplate<typename T> 12511308Santhony.gutierrez@amd.comclass AtomicOpSub : public TypedAtomicOpFunctor<T> 12611308Santhony.gutierrez@amd.com{ 12711308Santhony.gutierrez@amd.com public: 12811308Santhony.gutierrez@amd.com T a; 12911308Santhony.gutierrez@amd.com AtomicOpSub(T _a) : a(_a) { } 13011308Santhony.gutierrez@amd.com void execute(T *b) { *b -= a; } 13111308Santhony.gutierrez@amd.com}; 13211308Santhony.gutierrez@amd.com 13311308Santhony.gutierrez@amd.comtemplate<typename T> 13411308Santhony.gutierrez@amd.comclass AtomicOpInc : public TypedAtomicOpFunctor<T> 13511308Santhony.gutierrez@amd.com{ 13611308Santhony.gutierrez@amd.com public: 13711308Santhony.gutierrez@amd.com AtomicOpInc() { } 13811308Santhony.gutierrez@amd.com void execute(T *b) { *b += 1; } 13911308Santhony.gutierrez@amd.com}; 14011308Santhony.gutierrez@amd.com 14111308Santhony.gutierrez@amd.comtemplate<typename T> 14211308Santhony.gutierrez@amd.comclass AtomicOpDec : public TypedAtomicOpFunctor<T> 14311308Santhony.gutierrez@amd.com{ 14411308Santhony.gutierrez@amd.com public: 14511308Santhony.gutierrez@amd.com AtomicOpDec() {} 14611308Santhony.gutierrez@amd.com void execute(T *b) { *b -= 1; } 14711308Santhony.gutierrez@amd.com}; 14811308Santhony.gutierrez@amd.com 14911308Santhony.gutierrez@amd.comtemplate<typename T> 15011308Santhony.gutierrez@amd.comclass AtomicOpMax : public TypedAtomicOpFunctor<T> 15111308Santhony.gutierrez@amd.com{ 15211308Santhony.gutierrez@amd.com public: 15311308Santhony.gutierrez@amd.com T a; 15411308Santhony.gutierrez@amd.com AtomicOpMax(T _a) : a(_a) { } 15511308Santhony.gutierrez@amd.com 15611308Santhony.gutierrez@amd.com void 15711308Santhony.gutierrez@amd.com execute(T *b) 15811308Santhony.gutierrez@amd.com { 15911308Santhony.gutierrez@amd.com if (a > *b) 16011308Santhony.gutierrez@amd.com *b = a; 16111308Santhony.gutierrez@amd.com } 16211308Santhony.gutierrez@amd.com}; 16311308Santhony.gutierrez@amd.com 16411308Santhony.gutierrez@amd.comtemplate<typename T> 16511308Santhony.gutierrez@amd.comclass AtomicOpMin : public TypedAtomicOpFunctor<T> 16611308Santhony.gutierrez@amd.com{ 16711308Santhony.gutierrez@amd.com public: 16811308Santhony.gutierrez@amd.com T a; 16911308Santhony.gutierrez@amd.com AtomicOpMin(T _a) : a(_a) {} 17011308Santhony.gutierrez@amd.com 17111308Santhony.gutierrez@amd.com void 17211308Santhony.gutierrez@amd.com execute(T *b) 17311308Santhony.gutierrez@amd.com { 17411308Santhony.gutierrez@amd.com if (a < *b) 17511308Santhony.gutierrez@amd.com *b = a; 17611308Santhony.gutierrez@amd.com } 17711308Santhony.gutierrez@amd.com}; 17811308Santhony.gutierrez@amd.com 17911308Santhony.gutierrez@amd.comtypedef enum 18011308Santhony.gutierrez@amd.com{ 18111308Santhony.gutierrez@amd.com VT_32, 18211308Santhony.gutierrez@amd.com VT_64, 18311308Santhony.gutierrez@amd.com} vgpr_type; 18411308Santhony.gutierrez@amd.com 18511308Santhony.gutierrez@amd.comclass GPUDynInst : public GPUExecContext 18611308Santhony.gutierrez@amd.com{ 18711308Santhony.gutierrez@amd.com public: 18811692Santhony.gutierrez@amd.com GPUDynInst(ComputeUnit *_cu, Wavefront *_wf, GPUStaticInst *static_inst, 18911308Santhony.gutierrez@amd.com uint64_t instSeqNum); 19011534Sjohn.kalamatianos@amd.com ~GPUDynInst(); 19111692Santhony.gutierrez@amd.com void execute(GPUDynInstPtr gpuDynInst); 19211308Santhony.gutierrez@amd.com int numSrcRegOperands(); 19311308Santhony.gutierrez@amd.com int numDstRegOperands(); 19411308Santhony.gutierrez@amd.com int getNumOperands(); 19511308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIdx); 19611308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIdx); 19711699Santhony.gutierrez@amd.com bool isCondRegister(int operandIdx); 19811699Santhony.gutierrez@amd.com int getRegisterIndex(int operandIdx, GPUDynInstPtr gpuDynInst); 19911308Santhony.gutierrez@amd.com int getOperandSize(int operandIdx); 20011308Santhony.gutierrez@amd.com bool isDstOperand(int operandIdx); 20111308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIdx); 20211308Santhony.gutierrez@amd.com 20311308Santhony.gutierrez@amd.com const std::string &disassemble() const; 20411308Santhony.gutierrez@amd.com 20511308Santhony.gutierrez@amd.com uint64_t seqNum() const; 20611308Santhony.gutierrez@amd.com 20711308Santhony.gutierrez@amd.com Enums::StorageClassType executedAs(); 20811308Santhony.gutierrez@amd.com 20911308Santhony.gutierrez@amd.com // The address of the memory operation 21011534Sjohn.kalamatianos@amd.com std::vector<Addr> addr; 21111308Santhony.gutierrez@amd.com Addr pAddr; 21211308Santhony.gutierrez@amd.com 21311308Santhony.gutierrez@amd.com // The data to get written 21411534Sjohn.kalamatianos@amd.com uint8_t *d_data; 21511308Santhony.gutierrez@amd.com // Additional data (for atomics) 21611534Sjohn.kalamatianos@amd.com uint8_t *a_data; 21711308Santhony.gutierrez@amd.com // Additional data (for atomics) 21811534Sjohn.kalamatianos@amd.com uint8_t *x_data; 21911308Santhony.gutierrez@amd.com // The execution mask 22011308Santhony.gutierrez@amd.com VectorMask exec_mask; 22111308Santhony.gutierrez@amd.com 22211308Santhony.gutierrez@amd.com // The memory type (M_U32, M_S32, ...) 22311308Santhony.gutierrez@amd.com Enums::MemType m_type; 22411308Santhony.gutierrez@amd.com 22511308Santhony.gutierrez@amd.com // The equivalency class 22611308Santhony.gutierrez@amd.com int equiv; 22711308Santhony.gutierrez@amd.com // The return VGPR type (VT_32 or VT_64) 22811308Santhony.gutierrez@amd.com vgpr_type v_type; 22911308Santhony.gutierrez@amd.com // Number of VGPR's accessed (1, 2, or 4) 23011308Santhony.gutierrez@amd.com int n_reg; 23111308Santhony.gutierrez@amd.com // The return VGPR index 23211308Santhony.gutierrez@amd.com int dst_reg; 23311308Santhony.gutierrez@amd.com // There can be max 4 dest regs> 23411308Santhony.gutierrez@amd.com int dst_reg_vec[4]; 23511308Santhony.gutierrez@amd.com // SIMD where the WF of the memory instruction has been mapped to 23611308Santhony.gutierrez@amd.com int simdId; 23711308Santhony.gutierrez@amd.com // unique id of the WF where the memory instruction belongs to 23811308Santhony.gutierrez@amd.com int wfDynId; 23911308Santhony.gutierrez@amd.com // The kernel id of the requesting wf 24011308Santhony.gutierrez@amd.com int kern_id; 24111308Santhony.gutierrez@amd.com // The CU id of the requesting wf 24211308Santhony.gutierrez@amd.com int cu_id; 24311308Santhony.gutierrez@amd.com // HW slot id where the WF is mapped to inside a SIMD unit 24411308Santhony.gutierrez@amd.com int wfSlotId; 24511308Santhony.gutierrez@amd.com // execution pipeline id where the memory instruction has been scheduled 24611308Santhony.gutierrez@amd.com int pipeId; 24711308Santhony.gutierrez@amd.com // The execution time of this operation 24811308Santhony.gutierrez@amd.com Tick time; 24911308Santhony.gutierrez@amd.com // The latency of this operation 25011308Santhony.gutierrez@amd.com WaitClass latency; 25111308Santhony.gutierrez@amd.com // A list of bank conflicts for the 4 cycles. 25211308Santhony.gutierrez@amd.com uint32_t bc[4]; 25311308Santhony.gutierrez@amd.com 25411308Santhony.gutierrez@amd.com // A pointer to ROM 25511308Santhony.gutierrez@amd.com uint8_t *rom; 25611308Santhony.gutierrez@amd.com // The size of the READONLY segment 25711308Santhony.gutierrez@amd.com int sz_rom; 25811308Santhony.gutierrez@amd.com 25911308Santhony.gutierrez@amd.com // Initiate the specified memory operation, by creating a 26011308Santhony.gutierrez@amd.com // memory request and sending it off to the memory system. 26111308Santhony.gutierrez@amd.com void initiateAcc(GPUDynInstPtr gpuDynInst); 26211693Santhony.gutierrez@amd.com // Complete the specified memory operation, by writing 26311693Santhony.gutierrez@amd.com // value back to the RF in the case of a load or atomic 26411693Santhony.gutierrez@amd.com // return or, in the case of a store, we do nothing 26511693Santhony.gutierrez@amd.com void completeAcc(GPUDynInstPtr gpuDynInst); 26611308Santhony.gutierrez@amd.com 26711308Santhony.gutierrez@amd.com void updateStats(); 26811308Santhony.gutierrez@amd.com 26911692Santhony.gutierrez@amd.com GPUStaticInst* staticInstruction() { return _staticInst; } 27011308Santhony.gutierrez@amd.com 27111692Santhony.gutierrez@amd.com bool isALU() const; 27211692Santhony.gutierrez@amd.com bool isBranch() const; 27311692Santhony.gutierrez@amd.com bool isNop() const; 27411692Santhony.gutierrez@amd.com bool isReturn() const; 27511692Santhony.gutierrez@amd.com bool isUnconditionalJump() const; 27611692Santhony.gutierrez@amd.com bool isSpecialOp() const; 27711692Santhony.gutierrez@amd.com bool isWaitcnt() const; 27811692Santhony.gutierrez@amd.com 27911692Santhony.gutierrez@amd.com bool isBarrier() const; 28011692Santhony.gutierrez@amd.com bool isMemFence() const; 28111692Santhony.gutierrez@amd.com bool isMemRef() const; 28211692Santhony.gutierrez@amd.com bool isFlat() const; 28311692Santhony.gutierrez@amd.com bool isLoad() const; 28411692Santhony.gutierrez@amd.com bool isStore() const; 28511692Santhony.gutierrez@amd.com 28611692Santhony.gutierrez@amd.com bool isAtomic() const; 28711692Santhony.gutierrez@amd.com bool isAtomicNoRet() const; 28811692Santhony.gutierrez@amd.com bool isAtomicRet() const; 28911692Santhony.gutierrez@amd.com 29011692Santhony.gutierrez@amd.com bool isScalar() const; 29111692Santhony.gutierrez@amd.com bool readsSCC() const; 29211692Santhony.gutierrez@amd.com bool writesSCC() const; 29311692Santhony.gutierrez@amd.com bool readsVCC() const; 29411692Santhony.gutierrez@amd.com bool writesVCC() const; 29511692Santhony.gutierrez@amd.com 29611692Santhony.gutierrez@amd.com bool isAtomicAnd() const; 29711692Santhony.gutierrez@amd.com bool isAtomicOr() const; 29811692Santhony.gutierrez@amd.com bool isAtomicXor() const; 29911692Santhony.gutierrez@amd.com bool isAtomicCAS() const; 30011692Santhony.gutierrez@amd.com bool isAtomicExch() const; 30111692Santhony.gutierrez@amd.com bool isAtomicAdd() const; 30211692Santhony.gutierrez@amd.com bool isAtomicSub() const; 30311692Santhony.gutierrez@amd.com bool isAtomicInc() const; 30411692Santhony.gutierrez@amd.com bool isAtomicDec() const; 30511692Santhony.gutierrez@amd.com bool isAtomicMax() const; 30611692Santhony.gutierrez@amd.com bool isAtomicMin() const; 30711692Santhony.gutierrez@amd.com 30811692Santhony.gutierrez@amd.com bool isArgLoad() const; 30911692Santhony.gutierrez@amd.com bool isGlobalMem() const; 31011692Santhony.gutierrez@amd.com bool isLocalMem() const; 31111692Santhony.gutierrez@amd.com 31211692Santhony.gutierrez@amd.com bool isArgSeg() const; 31311692Santhony.gutierrez@amd.com bool isGlobalSeg() const; 31411692Santhony.gutierrez@amd.com bool isGroupSeg() const; 31511692Santhony.gutierrez@amd.com bool isKernArgSeg() const; 31611692Santhony.gutierrez@amd.com bool isPrivateSeg() const; 31711692Santhony.gutierrez@amd.com bool isReadOnlySeg() const; 31811692Santhony.gutierrez@amd.com bool isSpillSeg() const; 31911692Santhony.gutierrez@amd.com 32011692Santhony.gutierrez@amd.com bool isWorkitemScope() const; 32111692Santhony.gutierrez@amd.com bool isWavefrontScope() const; 32211692Santhony.gutierrez@amd.com bool isWorkgroupScope() const; 32311692Santhony.gutierrez@amd.com bool isDeviceScope() const; 32411692Santhony.gutierrez@amd.com bool isSystemScope() const; 32511692Santhony.gutierrez@amd.com bool isNoScope() const; 32611692Santhony.gutierrez@amd.com 32711692Santhony.gutierrez@amd.com bool isRelaxedOrder() const; 32811692Santhony.gutierrez@amd.com bool isAcquire() const; 32911692Santhony.gutierrez@amd.com bool isRelease() const; 33011692Santhony.gutierrez@amd.com bool isAcquireRelease() const; 33111692Santhony.gutierrez@amd.com bool isNoOrder() const; 33211692Santhony.gutierrez@amd.com 33311692Santhony.gutierrez@amd.com bool isGloballyCoherent() const; 33411692Santhony.gutierrez@amd.com bool isSystemCoherent() const; 33511308Santhony.gutierrez@amd.com 33611308Santhony.gutierrez@amd.com /* 33711308Santhony.gutierrez@amd.com * Loads/stores/atomics may have acquire/release semantics associated 33811308Santhony.gutierrez@amd.com * withthem. Some protocols want to see the acquire/release as separate 33911308Santhony.gutierrez@amd.com * requests from the load/store/atomic. We implement that separation 34011308Santhony.gutierrez@amd.com * using continuations (i.e., a function pointer with an object associated 34111308Santhony.gutierrez@amd.com * with it). When, for example, the front-end generates a store with 34211308Santhony.gutierrez@amd.com * release semantics, we will first issue a normal store and set the 34311308Santhony.gutierrez@amd.com * continuation in the GPUDynInst to a function that generate a 34411308Santhony.gutierrez@amd.com * release request. That continuation will be called when the normal 34511308Santhony.gutierrez@amd.com * store completes (in ComputeUnit::DataPort::recvTimingResponse). The 34611308Santhony.gutierrez@amd.com * continuation will be called in the context of the same GPUDynInst 34711308Santhony.gutierrez@amd.com * that generated the initial store. 34811308Santhony.gutierrez@amd.com */ 34911308Santhony.gutierrez@amd.com std::function<void(GPUStaticInst*, GPUDynInstPtr)> execContinuation; 35011308Santhony.gutierrez@amd.com 35111308Santhony.gutierrez@amd.com // when true, call execContinuation when response arrives 35211308Santhony.gutierrez@amd.com bool useContinuation; 35311308Santhony.gutierrez@amd.com 35411308Santhony.gutierrez@amd.com template<typename c0> AtomicOpFunctor* 35511692Santhony.gutierrez@amd.com makeAtomicOpFunctor(c0 *reg0, c0 *reg1) 35611308Santhony.gutierrez@amd.com { 35711692Santhony.gutierrez@amd.com if (isAtomicAnd()) { 35811308Santhony.gutierrez@amd.com return new AtomicOpAnd<c0>(*reg0); 35911692Santhony.gutierrez@amd.com } else if (isAtomicOr()) { 36011308Santhony.gutierrez@amd.com return new AtomicOpOr<c0>(*reg0); 36111692Santhony.gutierrez@amd.com } else if (isAtomicXor()) { 36211308Santhony.gutierrez@amd.com return new AtomicOpXor<c0>(*reg0); 36311692Santhony.gutierrez@amd.com } else if (isAtomicCAS()) { 36411308Santhony.gutierrez@amd.com return new AtomicOpCAS<c0>(*reg0, *reg1, cu); 36511692Santhony.gutierrez@amd.com } else if (isAtomicExch()) { 36611308Santhony.gutierrez@amd.com return new AtomicOpExch<c0>(*reg0); 36711692Santhony.gutierrez@amd.com } else if (isAtomicAdd()) { 36811308Santhony.gutierrez@amd.com return new AtomicOpAdd<c0>(*reg0); 36911692Santhony.gutierrez@amd.com } else if (isAtomicSub()) { 37011308Santhony.gutierrez@amd.com return new AtomicOpSub<c0>(*reg0); 37111692Santhony.gutierrez@amd.com } else if (isAtomicInc()) { 37211308Santhony.gutierrez@amd.com return new AtomicOpInc<c0>(); 37311692Santhony.gutierrez@amd.com } else if (isAtomicDec()) { 37411308Santhony.gutierrez@amd.com return new AtomicOpDec<c0>(); 37511692Santhony.gutierrez@amd.com } else if (isAtomicMax()) { 37611308Santhony.gutierrez@amd.com return new AtomicOpMax<c0>(*reg0); 37711692Santhony.gutierrez@amd.com } else if (isAtomicMin()) { 37811308Santhony.gutierrez@amd.com return new AtomicOpMin<c0>(*reg0); 37911692Santhony.gutierrez@amd.com } else { 38011692Santhony.gutierrez@amd.com fatal("Unrecognized atomic operation"); 38111308Santhony.gutierrez@amd.com } 38211308Santhony.gutierrez@amd.com } 38311308Santhony.gutierrez@amd.com 38411308Santhony.gutierrez@amd.com void 38511308Santhony.gutierrez@amd.com setRequestFlags(Request *req, bool setMemOrder=true) 38611308Santhony.gutierrez@amd.com { 38711308Santhony.gutierrez@amd.com // currently these are the easy scopes to deduce 38811692Santhony.gutierrez@amd.com if (isPrivateSeg()) { 38911308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::PRIVATE_SEGMENT); 39011692Santhony.gutierrez@amd.com } else if (isSpillSeg()) { 39111308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SPILL_SEGMENT); 39211692Santhony.gutierrez@amd.com } else if (isGlobalSeg()) { 39311308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::GLOBAL_SEGMENT); 39411692Santhony.gutierrez@amd.com } else if (isReadOnlySeg()) { 39511308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::READONLY_SEGMENT); 39611692Santhony.gutierrez@amd.com } else if (isGroupSeg()) { 39711308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::GROUP_SEGMENT); 39811692Santhony.gutierrez@amd.com } else if (isFlat()) { 39911308Santhony.gutierrez@amd.com // TODO: translate to correct scope 40011308Santhony.gutierrez@amd.com assert(false); 40111692Santhony.gutierrez@amd.com } else { 40211692Santhony.gutierrez@amd.com fatal("%s has bad segment type\n", disassemble()); 40311308Santhony.gutierrez@amd.com } 40411308Santhony.gutierrez@amd.com 40511692Santhony.gutierrez@amd.com if (isWavefrontScope()) { 40611308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SCOPE_VALID | 40711308Santhony.gutierrez@amd.com Request::WAVEFRONT_SCOPE); 40811692Santhony.gutierrez@amd.com } else if (isWorkgroupScope()) { 40911308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SCOPE_VALID | 41011308Santhony.gutierrez@amd.com Request::WORKGROUP_SCOPE); 41111692Santhony.gutierrez@amd.com } else if (isDeviceScope()) { 41211308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SCOPE_VALID | 41311308Santhony.gutierrez@amd.com Request::DEVICE_SCOPE); 41411692Santhony.gutierrez@amd.com } else if (isSystemScope()) { 41511308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SCOPE_VALID | 41611308Santhony.gutierrez@amd.com Request::SYSTEM_SCOPE); 41711692Santhony.gutierrez@amd.com } else if (!isNoScope() && !isWorkitemScope()) { 41811692Santhony.gutierrez@amd.com fatal("%s has bad scope type\n", disassemble()); 41911308Santhony.gutierrez@amd.com } 42011308Santhony.gutierrez@amd.com 42111308Santhony.gutierrez@amd.com if (setMemOrder) { 42211308Santhony.gutierrez@amd.com // set acquire and release flags 42311692Santhony.gutierrez@amd.com if (isAcquire()) { 42411308Santhony.gutierrez@amd.com req->setFlags(Request::ACQUIRE); 42511692Santhony.gutierrez@amd.com } else if (isRelease()) { 42611308Santhony.gutierrez@amd.com req->setFlags(Request::RELEASE); 42711692Santhony.gutierrez@amd.com } else if (isAcquireRelease()) { 42811308Santhony.gutierrez@amd.com req->setFlags(Request::ACQUIRE | Request::RELEASE); 42911692Santhony.gutierrez@amd.com } else if (!isNoOrder()) { 43011692Santhony.gutierrez@amd.com fatal("%s has bad memory order\n", disassemble()); 43111308Santhony.gutierrez@amd.com } 43211308Santhony.gutierrez@amd.com } 43311308Santhony.gutierrez@amd.com 43411308Santhony.gutierrez@amd.com // set atomic type 43511308Santhony.gutierrez@amd.com // currently, the instruction genenerator only produces atomic return 43611308Santhony.gutierrez@amd.com // but a magic instruction can produce atomic no return 43711692Santhony.gutierrez@amd.com if (isAtomicRet()) { 43811308Santhony.gutierrez@amd.com req->setFlags(Request::ATOMIC_RETURN_OP); 43911692Santhony.gutierrez@amd.com } else if (isAtomicNoRet()) { 44011308Santhony.gutierrez@amd.com req->setFlags(Request::ATOMIC_NO_RETURN_OP); 44111308Santhony.gutierrez@amd.com } 44211308Santhony.gutierrez@amd.com } 44311308Santhony.gutierrez@amd.com 44411308Santhony.gutierrez@amd.com // Map returned packets and the addresses they satisfy with which lane they 44511308Santhony.gutierrez@amd.com // were requested from 44611308Santhony.gutierrez@amd.com typedef std::unordered_map<Addr, std::vector<int>> StatusVector; 44711308Santhony.gutierrez@amd.com StatusVector memStatusVector; 44811308Santhony.gutierrez@amd.com 44911308Santhony.gutierrez@amd.com // Track the status of memory requests per lane, a bit per lane 45011308Santhony.gutierrez@amd.com VectorMask statusBitVector; 45111308Santhony.gutierrez@amd.com // for ld_v# or st_v# 45211308Santhony.gutierrez@amd.com std::vector<int> statusVector; 45311308Santhony.gutierrez@amd.com std::vector<int> tlbHitLevel; 45411308Santhony.gutierrez@amd.com 45511308Santhony.gutierrez@amd.com private: 45611692Santhony.gutierrez@amd.com GPUStaticInst *_staticInst; 45711308Santhony.gutierrez@amd.com uint64_t _seqNum; 45811308Santhony.gutierrez@amd.com}; 45911308Santhony.gutierrez@amd.com 46011308Santhony.gutierrez@amd.com#endif // __GPU_DYN_INST_HH__ 461