gpu_dyn_inst.hh revision 13449
111308Santhony.gutierrez@amd.com/* 212697Santhony.gutierrez@amd.com * Copyright (c) 2015-2017 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 * 1712697Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its 1812697Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from this 1912697Santhony.gutierrez@amd.com * software 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 * 3312697Santhony.gutierrez@amd.com * Authors: 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 4213449Sgabeblack@google.com#include "base/logging.hh" 4311308Santhony.gutierrez@amd.com#include "enums/MemType.hh" 4411308Santhony.gutierrez@amd.com#include "enums/StorageClassType.hh" 4511308Santhony.gutierrez@amd.com#include "gpu-compute/compute_unit.hh" 4611308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_exec_context.hh" 4711308Santhony.gutierrez@amd.com 4811308Santhony.gutierrez@amd.comclass GPUStaticInst; 4911308Santhony.gutierrez@amd.com 5011308Santhony.gutierrez@amd.comtemplate<typename T> 5111308Santhony.gutierrez@amd.comclass AtomicOpAnd : public TypedAtomicOpFunctor<T> 5211308Santhony.gutierrez@amd.com{ 5311308Santhony.gutierrez@amd.com public: 5411308Santhony.gutierrez@amd.com T a; 5511308Santhony.gutierrez@amd.com 5611308Santhony.gutierrez@amd.com AtomicOpAnd(T _a) : a(_a) { } 5711308Santhony.gutierrez@amd.com void execute(T *b) { *b &= a; } 5812889Sbrandon.potter@amd.com AtomicOpFunctor* clone () { return new AtomicOpAnd(a); } 5911308Santhony.gutierrez@amd.com}; 6011308Santhony.gutierrez@amd.com 6111308Santhony.gutierrez@amd.comtemplate<typename T> 6211308Santhony.gutierrez@amd.comclass AtomicOpOr : public TypedAtomicOpFunctor<T> 6311308Santhony.gutierrez@amd.com{ 6411308Santhony.gutierrez@amd.com public: 6511308Santhony.gutierrez@amd.com T a; 6611308Santhony.gutierrez@amd.com AtomicOpOr(T _a) : a(_a) { } 6711308Santhony.gutierrez@amd.com void execute(T *b) { *b |= a; } 6812889Sbrandon.potter@amd.com AtomicOpFunctor* clone () { return new AtomicOpOr(a); } 6911308Santhony.gutierrez@amd.com}; 7011308Santhony.gutierrez@amd.com 7111308Santhony.gutierrez@amd.comtemplate<typename T> 7211308Santhony.gutierrez@amd.comclass AtomicOpXor : public TypedAtomicOpFunctor<T> 7311308Santhony.gutierrez@amd.com{ 7411308Santhony.gutierrez@amd.com public: 7511308Santhony.gutierrez@amd.com T a; 7611308Santhony.gutierrez@amd.com AtomicOpXor(T _a) : a(_a) {} 7711308Santhony.gutierrez@amd.com void execute(T *b) { *b ^= a; } 7812889Sbrandon.potter@amd.com AtomicOpFunctor* clone () { return new AtomicOpXor(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 } 10812889Sbrandon.potter@amd.com AtomicOpFunctor* clone () { return new AtomicOpCAS(c, s, computeUnit); } 10911308Santhony.gutierrez@amd.com}; 11011308Santhony.gutierrez@amd.com 11111308Santhony.gutierrez@amd.comtemplate<typename T> 11211308Santhony.gutierrez@amd.comclass AtomicOpExch : public TypedAtomicOpFunctor<T> 11311308Santhony.gutierrez@amd.com{ 11411308Santhony.gutierrez@amd.com public: 11511308Santhony.gutierrez@amd.com T a; 11611308Santhony.gutierrez@amd.com AtomicOpExch(T _a) : a(_a) { } 11711308Santhony.gutierrez@amd.com void execute(T *b) { *b = a; } 11812889Sbrandon.potter@amd.com AtomicOpFunctor* clone () { return new AtomicOpExch(a); } 11911308Santhony.gutierrez@amd.com}; 12011308Santhony.gutierrez@amd.com 12111308Santhony.gutierrez@amd.comtemplate<typename T> 12211308Santhony.gutierrez@amd.comclass AtomicOpAdd : public TypedAtomicOpFunctor<T> 12311308Santhony.gutierrez@amd.com{ 12411308Santhony.gutierrez@amd.com public: 12511308Santhony.gutierrez@amd.com T a; 12611308Santhony.gutierrez@amd.com AtomicOpAdd(T _a) : a(_a) { } 12711308Santhony.gutierrez@amd.com void execute(T *b) { *b += a; } 12812889Sbrandon.potter@amd.com AtomicOpFunctor* clone () { return new AtomicOpAdd(a); } 12911308Santhony.gutierrez@amd.com}; 13011308Santhony.gutierrez@amd.com 13111308Santhony.gutierrez@amd.comtemplate<typename T> 13211308Santhony.gutierrez@amd.comclass AtomicOpSub : public TypedAtomicOpFunctor<T> 13311308Santhony.gutierrez@amd.com{ 13411308Santhony.gutierrez@amd.com public: 13511308Santhony.gutierrez@amd.com T a; 13611308Santhony.gutierrez@amd.com AtomicOpSub(T _a) : a(_a) { } 13711308Santhony.gutierrez@amd.com void execute(T *b) { *b -= a; } 13812889Sbrandon.potter@amd.com AtomicOpFunctor* clone () { return new AtomicOpSub(a); } 13911308Santhony.gutierrez@amd.com}; 14011308Santhony.gutierrez@amd.com 14111308Santhony.gutierrez@amd.comtemplate<typename T> 14211308Santhony.gutierrez@amd.comclass AtomicOpInc : public TypedAtomicOpFunctor<T> 14311308Santhony.gutierrez@amd.com{ 14411308Santhony.gutierrez@amd.com public: 14511308Santhony.gutierrez@amd.com AtomicOpInc() { } 14611308Santhony.gutierrez@amd.com void execute(T *b) { *b += 1; } 14712889Sbrandon.potter@amd.com AtomicOpFunctor* clone () { return new AtomicOpInc(); } 14811308Santhony.gutierrez@amd.com}; 14911308Santhony.gutierrez@amd.com 15011308Santhony.gutierrez@amd.comtemplate<typename T> 15111308Santhony.gutierrez@amd.comclass AtomicOpDec : public TypedAtomicOpFunctor<T> 15211308Santhony.gutierrez@amd.com{ 15311308Santhony.gutierrez@amd.com public: 15411308Santhony.gutierrez@amd.com AtomicOpDec() {} 15511308Santhony.gutierrez@amd.com void execute(T *b) { *b -= 1; } 15612889Sbrandon.potter@amd.com AtomicOpFunctor* clone () { return new AtomicOpDec(); } 15711308Santhony.gutierrez@amd.com}; 15811308Santhony.gutierrez@amd.com 15911308Santhony.gutierrez@amd.comtemplate<typename T> 16011308Santhony.gutierrez@amd.comclass AtomicOpMax : public TypedAtomicOpFunctor<T> 16111308Santhony.gutierrez@amd.com{ 16211308Santhony.gutierrez@amd.com public: 16311308Santhony.gutierrez@amd.com T a; 16411308Santhony.gutierrez@amd.com AtomicOpMax(T _a) : a(_a) { } 16511308Santhony.gutierrez@amd.com 16611308Santhony.gutierrez@amd.com void 16711308Santhony.gutierrez@amd.com execute(T *b) 16811308Santhony.gutierrez@amd.com { 16911308Santhony.gutierrez@amd.com if (a > *b) 17011308Santhony.gutierrez@amd.com *b = a; 17111308Santhony.gutierrez@amd.com } 17212889Sbrandon.potter@amd.com AtomicOpFunctor* clone () { return new AtomicOpMax(a); } 17311308Santhony.gutierrez@amd.com}; 17411308Santhony.gutierrez@amd.com 17511308Santhony.gutierrez@amd.comtemplate<typename T> 17611308Santhony.gutierrez@amd.comclass AtomicOpMin : public TypedAtomicOpFunctor<T> 17711308Santhony.gutierrez@amd.com{ 17811308Santhony.gutierrez@amd.com public: 17911308Santhony.gutierrez@amd.com T a; 18011308Santhony.gutierrez@amd.com AtomicOpMin(T _a) : a(_a) {} 18111308Santhony.gutierrez@amd.com 18211308Santhony.gutierrez@amd.com void 18311308Santhony.gutierrez@amd.com execute(T *b) 18411308Santhony.gutierrez@amd.com { 18511308Santhony.gutierrez@amd.com if (a < *b) 18611308Santhony.gutierrez@amd.com *b = a; 18711308Santhony.gutierrez@amd.com } 18812889Sbrandon.potter@amd.com AtomicOpFunctor* clone () { return new AtomicOpMin(a); } 18911308Santhony.gutierrez@amd.com}; 19011308Santhony.gutierrez@amd.com 19111308Santhony.gutierrez@amd.comtypedef enum 19211308Santhony.gutierrez@amd.com{ 19311308Santhony.gutierrez@amd.com VT_32, 19411308Santhony.gutierrez@amd.com VT_64, 19511308Santhony.gutierrez@amd.com} vgpr_type; 19611308Santhony.gutierrez@amd.com 19711308Santhony.gutierrez@amd.comclass GPUDynInst : public GPUExecContext 19811308Santhony.gutierrez@amd.com{ 19911308Santhony.gutierrez@amd.com public: 20011692Santhony.gutierrez@amd.com GPUDynInst(ComputeUnit *_cu, Wavefront *_wf, GPUStaticInst *static_inst, 20111308Santhony.gutierrez@amd.com uint64_t instSeqNum); 20211534Sjohn.kalamatianos@amd.com ~GPUDynInst(); 20311692Santhony.gutierrez@amd.com void execute(GPUDynInstPtr gpuDynInst); 20411308Santhony.gutierrez@amd.com int numSrcRegOperands(); 20511308Santhony.gutierrez@amd.com int numDstRegOperands(); 20611308Santhony.gutierrez@amd.com int getNumOperands(); 20711308Santhony.gutierrez@amd.com bool isVectorRegister(int operandIdx); 20811308Santhony.gutierrez@amd.com bool isScalarRegister(int operandIdx); 20911699Santhony.gutierrez@amd.com bool isCondRegister(int operandIdx); 21011699Santhony.gutierrez@amd.com int getRegisterIndex(int operandIdx, GPUDynInstPtr gpuDynInst); 21111308Santhony.gutierrez@amd.com int getOperandSize(int operandIdx); 21211308Santhony.gutierrez@amd.com bool isDstOperand(int operandIdx); 21311308Santhony.gutierrez@amd.com bool isSrcOperand(int operandIdx); 21411308Santhony.gutierrez@amd.com 21511308Santhony.gutierrez@amd.com const std::string &disassemble() const; 21611308Santhony.gutierrez@amd.com 21711308Santhony.gutierrez@amd.com uint64_t seqNum() const; 21811308Santhony.gutierrez@amd.com 21911308Santhony.gutierrez@amd.com Enums::StorageClassType executedAs(); 22011308Santhony.gutierrez@amd.com 22111308Santhony.gutierrez@amd.com // The address of the memory operation 22211534Sjohn.kalamatianos@amd.com std::vector<Addr> addr; 22311308Santhony.gutierrez@amd.com Addr pAddr; 22411308Santhony.gutierrez@amd.com 22511308Santhony.gutierrez@amd.com // The data to get written 22611534Sjohn.kalamatianos@amd.com uint8_t *d_data; 22711308Santhony.gutierrez@amd.com // Additional data (for atomics) 22811534Sjohn.kalamatianos@amd.com uint8_t *a_data; 22911308Santhony.gutierrez@amd.com // Additional data (for atomics) 23011534Sjohn.kalamatianos@amd.com uint8_t *x_data; 23111308Santhony.gutierrez@amd.com // The execution mask 23211308Santhony.gutierrez@amd.com VectorMask exec_mask; 23311308Santhony.gutierrez@amd.com 23411308Santhony.gutierrez@amd.com // The memory type (M_U32, M_S32, ...) 23511308Santhony.gutierrez@amd.com Enums::MemType m_type; 23611308Santhony.gutierrez@amd.com 23711308Santhony.gutierrez@amd.com // The equivalency class 23811308Santhony.gutierrez@amd.com int equiv; 23911308Santhony.gutierrez@amd.com // The return VGPR type (VT_32 or VT_64) 24011308Santhony.gutierrez@amd.com vgpr_type v_type; 24111308Santhony.gutierrez@amd.com // Number of VGPR's accessed (1, 2, or 4) 24211308Santhony.gutierrez@amd.com int n_reg; 24311308Santhony.gutierrez@amd.com // The return VGPR index 24411308Santhony.gutierrez@amd.com int dst_reg; 24511308Santhony.gutierrez@amd.com // There can be max 4 dest regs> 24611308Santhony.gutierrez@amd.com int dst_reg_vec[4]; 24711308Santhony.gutierrez@amd.com // SIMD where the WF of the memory instruction has been mapped to 24811308Santhony.gutierrez@amd.com int simdId; 24911308Santhony.gutierrez@amd.com // unique id of the WF where the memory instruction belongs to 25011308Santhony.gutierrez@amd.com int wfDynId; 25111308Santhony.gutierrez@amd.com // The kernel id of the requesting wf 25211308Santhony.gutierrez@amd.com int kern_id; 25311308Santhony.gutierrez@amd.com // The CU id of the requesting wf 25411308Santhony.gutierrez@amd.com int cu_id; 25511308Santhony.gutierrez@amd.com // HW slot id where the WF is mapped to inside a SIMD unit 25611308Santhony.gutierrez@amd.com int wfSlotId; 25711308Santhony.gutierrez@amd.com // execution pipeline id where the memory instruction has been scheduled 25811308Santhony.gutierrez@amd.com int pipeId; 25911308Santhony.gutierrez@amd.com // The execution time of this operation 26011308Santhony.gutierrez@amd.com Tick time; 26111308Santhony.gutierrez@amd.com // The latency of this operation 26211308Santhony.gutierrez@amd.com WaitClass latency; 26311308Santhony.gutierrez@amd.com // A list of bank conflicts for the 4 cycles. 26411308Santhony.gutierrez@amd.com uint32_t bc[4]; 26511308Santhony.gutierrez@amd.com 26611308Santhony.gutierrez@amd.com // A pointer to ROM 26711308Santhony.gutierrez@amd.com uint8_t *rom; 26811308Santhony.gutierrez@amd.com // The size of the READONLY segment 26911308Santhony.gutierrez@amd.com int sz_rom; 27011308Santhony.gutierrez@amd.com 27111308Santhony.gutierrez@amd.com // Initiate the specified memory operation, by creating a 27211308Santhony.gutierrez@amd.com // memory request and sending it off to the memory system. 27311308Santhony.gutierrez@amd.com void initiateAcc(GPUDynInstPtr gpuDynInst); 27411693Santhony.gutierrez@amd.com // Complete the specified memory operation, by writing 27511693Santhony.gutierrez@amd.com // value back to the RF in the case of a load or atomic 27611693Santhony.gutierrez@amd.com // return or, in the case of a store, we do nothing 27711693Santhony.gutierrez@amd.com void completeAcc(GPUDynInstPtr gpuDynInst); 27811308Santhony.gutierrez@amd.com 27911308Santhony.gutierrez@amd.com void updateStats(); 28011308Santhony.gutierrez@amd.com 28111692Santhony.gutierrez@amd.com GPUStaticInst* staticInstruction() { return _staticInst; } 28211308Santhony.gutierrez@amd.com 28311692Santhony.gutierrez@amd.com bool isALU() const; 28411692Santhony.gutierrez@amd.com bool isBranch() const; 28511692Santhony.gutierrez@amd.com bool isNop() const; 28611692Santhony.gutierrez@amd.com bool isReturn() const; 28711692Santhony.gutierrez@amd.com bool isUnconditionalJump() const; 28811692Santhony.gutierrez@amd.com bool isSpecialOp() const; 28911692Santhony.gutierrez@amd.com bool isWaitcnt() const; 29011692Santhony.gutierrez@amd.com 29111692Santhony.gutierrez@amd.com bool isBarrier() const; 29211692Santhony.gutierrez@amd.com bool isMemFence() const; 29311692Santhony.gutierrez@amd.com bool isMemRef() const; 29411692Santhony.gutierrez@amd.com bool isFlat() const; 29511692Santhony.gutierrez@amd.com bool isLoad() const; 29611692Santhony.gutierrez@amd.com bool isStore() const; 29711692Santhony.gutierrez@amd.com 29811692Santhony.gutierrez@amd.com bool isAtomic() const; 29911692Santhony.gutierrez@amd.com bool isAtomicNoRet() const; 30011692Santhony.gutierrez@amd.com bool isAtomicRet() const; 30111692Santhony.gutierrez@amd.com 30211692Santhony.gutierrez@amd.com bool isScalar() const; 30311692Santhony.gutierrez@amd.com bool readsSCC() const; 30411692Santhony.gutierrez@amd.com bool writesSCC() const; 30511692Santhony.gutierrez@amd.com bool readsVCC() const; 30611692Santhony.gutierrez@amd.com bool writesVCC() const; 30711692Santhony.gutierrez@amd.com 30811692Santhony.gutierrez@amd.com bool isAtomicAnd() const; 30911692Santhony.gutierrez@amd.com bool isAtomicOr() const; 31011692Santhony.gutierrez@amd.com bool isAtomicXor() const; 31111692Santhony.gutierrez@amd.com bool isAtomicCAS() const; 31211692Santhony.gutierrez@amd.com bool isAtomicExch() const; 31311692Santhony.gutierrez@amd.com bool isAtomicAdd() const; 31411692Santhony.gutierrez@amd.com bool isAtomicSub() const; 31511692Santhony.gutierrez@amd.com bool isAtomicInc() const; 31611692Santhony.gutierrez@amd.com bool isAtomicDec() const; 31711692Santhony.gutierrez@amd.com bool isAtomicMax() const; 31811692Santhony.gutierrez@amd.com bool isAtomicMin() const; 31911692Santhony.gutierrez@amd.com 32011692Santhony.gutierrez@amd.com bool isArgLoad() const; 32111692Santhony.gutierrez@amd.com bool isGlobalMem() const; 32211692Santhony.gutierrez@amd.com bool isLocalMem() const; 32311692Santhony.gutierrez@amd.com 32411692Santhony.gutierrez@amd.com bool isArgSeg() const; 32511692Santhony.gutierrez@amd.com bool isGlobalSeg() const; 32611692Santhony.gutierrez@amd.com bool isGroupSeg() const; 32711692Santhony.gutierrez@amd.com bool isKernArgSeg() const; 32811692Santhony.gutierrez@amd.com bool isPrivateSeg() const; 32911692Santhony.gutierrez@amd.com bool isReadOnlySeg() const; 33011692Santhony.gutierrez@amd.com bool isSpillSeg() const; 33111692Santhony.gutierrez@amd.com 33211692Santhony.gutierrez@amd.com bool isWorkitemScope() const; 33311692Santhony.gutierrez@amd.com bool isWavefrontScope() const; 33411692Santhony.gutierrez@amd.com bool isWorkgroupScope() const; 33511692Santhony.gutierrez@amd.com bool isDeviceScope() const; 33611692Santhony.gutierrez@amd.com bool isSystemScope() const; 33711692Santhony.gutierrez@amd.com bool isNoScope() const; 33811692Santhony.gutierrez@amd.com 33911692Santhony.gutierrez@amd.com bool isRelaxedOrder() const; 34011692Santhony.gutierrez@amd.com bool isAcquire() const; 34111692Santhony.gutierrez@amd.com bool isRelease() const; 34211692Santhony.gutierrez@amd.com bool isAcquireRelease() const; 34311692Santhony.gutierrez@amd.com bool isNoOrder() const; 34411692Santhony.gutierrez@amd.com 34511692Santhony.gutierrez@amd.com bool isGloballyCoherent() const; 34611692Santhony.gutierrez@amd.com bool isSystemCoherent() const; 34711308Santhony.gutierrez@amd.com 34811308Santhony.gutierrez@amd.com /* 34911308Santhony.gutierrez@amd.com * Loads/stores/atomics may have acquire/release semantics associated 35011308Santhony.gutierrez@amd.com * withthem. Some protocols want to see the acquire/release as separate 35111308Santhony.gutierrez@amd.com * requests from the load/store/atomic. We implement that separation 35211308Santhony.gutierrez@amd.com * using continuations (i.e., a function pointer with an object associated 35311308Santhony.gutierrez@amd.com * with it). When, for example, the front-end generates a store with 35411308Santhony.gutierrez@amd.com * release semantics, we will first issue a normal store and set the 35511308Santhony.gutierrez@amd.com * continuation in the GPUDynInst to a function that generate a 35611308Santhony.gutierrez@amd.com * release request. That continuation will be called when the normal 35711308Santhony.gutierrez@amd.com * store completes (in ComputeUnit::DataPort::recvTimingResponse). The 35811308Santhony.gutierrez@amd.com * continuation will be called in the context of the same GPUDynInst 35911308Santhony.gutierrez@amd.com * that generated the initial store. 36011308Santhony.gutierrez@amd.com */ 36111308Santhony.gutierrez@amd.com std::function<void(GPUStaticInst*, GPUDynInstPtr)> execContinuation; 36211308Santhony.gutierrez@amd.com 36311308Santhony.gutierrez@amd.com // when true, call execContinuation when response arrives 36411308Santhony.gutierrez@amd.com bool useContinuation; 36511308Santhony.gutierrez@amd.com 36611308Santhony.gutierrez@amd.com template<typename c0> AtomicOpFunctor* 36711692Santhony.gutierrez@amd.com makeAtomicOpFunctor(c0 *reg0, c0 *reg1) 36811308Santhony.gutierrez@amd.com { 36911692Santhony.gutierrez@amd.com if (isAtomicAnd()) { 37011308Santhony.gutierrez@amd.com return new AtomicOpAnd<c0>(*reg0); 37111692Santhony.gutierrez@amd.com } else if (isAtomicOr()) { 37211308Santhony.gutierrez@amd.com return new AtomicOpOr<c0>(*reg0); 37311692Santhony.gutierrez@amd.com } else if (isAtomicXor()) { 37411308Santhony.gutierrez@amd.com return new AtomicOpXor<c0>(*reg0); 37511692Santhony.gutierrez@amd.com } else if (isAtomicCAS()) { 37611308Santhony.gutierrez@amd.com return new AtomicOpCAS<c0>(*reg0, *reg1, cu); 37711692Santhony.gutierrez@amd.com } else if (isAtomicExch()) { 37811308Santhony.gutierrez@amd.com return new AtomicOpExch<c0>(*reg0); 37911692Santhony.gutierrez@amd.com } else if (isAtomicAdd()) { 38011308Santhony.gutierrez@amd.com return new AtomicOpAdd<c0>(*reg0); 38111692Santhony.gutierrez@amd.com } else if (isAtomicSub()) { 38211308Santhony.gutierrez@amd.com return new AtomicOpSub<c0>(*reg0); 38311692Santhony.gutierrez@amd.com } else if (isAtomicInc()) { 38411308Santhony.gutierrez@amd.com return new AtomicOpInc<c0>(); 38511692Santhony.gutierrez@amd.com } else if (isAtomicDec()) { 38611308Santhony.gutierrez@amd.com return new AtomicOpDec<c0>(); 38711692Santhony.gutierrez@amd.com } else if (isAtomicMax()) { 38811308Santhony.gutierrez@amd.com return new AtomicOpMax<c0>(*reg0); 38911692Santhony.gutierrez@amd.com } else if (isAtomicMin()) { 39011308Santhony.gutierrez@amd.com return new AtomicOpMin<c0>(*reg0); 39111692Santhony.gutierrez@amd.com } else { 39211692Santhony.gutierrez@amd.com fatal("Unrecognized atomic operation"); 39311308Santhony.gutierrez@amd.com } 39411308Santhony.gutierrez@amd.com } 39511308Santhony.gutierrez@amd.com 39611308Santhony.gutierrez@amd.com void 39712748Sgiacomo.travaglini@arm.com setRequestFlags(RequestPtr req, bool setMemOrder=true) 39811308Santhony.gutierrez@amd.com { 39911308Santhony.gutierrez@amd.com // currently these are the easy scopes to deduce 40011692Santhony.gutierrez@amd.com if (isPrivateSeg()) { 40111308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::PRIVATE_SEGMENT); 40211692Santhony.gutierrez@amd.com } else if (isSpillSeg()) { 40311308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SPILL_SEGMENT); 40411692Santhony.gutierrez@amd.com } else if (isGlobalSeg()) { 40511308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::GLOBAL_SEGMENT); 40611692Santhony.gutierrez@amd.com } else if (isReadOnlySeg()) { 40711308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::READONLY_SEGMENT); 40811692Santhony.gutierrez@amd.com } else if (isGroupSeg()) { 40911308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::GROUP_SEGMENT); 41011692Santhony.gutierrez@amd.com } else if (isFlat()) { 41113449Sgabeblack@google.com panic("TODO: translate to correct scope"); 41211692Santhony.gutierrez@amd.com } else { 41311692Santhony.gutierrez@amd.com fatal("%s has bad segment type\n", disassemble()); 41411308Santhony.gutierrez@amd.com } 41511308Santhony.gutierrez@amd.com 41611692Santhony.gutierrez@amd.com if (isWavefrontScope()) { 41711308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SCOPE_VALID | 41811308Santhony.gutierrez@amd.com Request::WAVEFRONT_SCOPE); 41911692Santhony.gutierrez@amd.com } else if (isWorkgroupScope()) { 42011308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SCOPE_VALID | 42111308Santhony.gutierrez@amd.com Request::WORKGROUP_SCOPE); 42211692Santhony.gutierrez@amd.com } else if (isDeviceScope()) { 42311308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SCOPE_VALID | 42411308Santhony.gutierrez@amd.com Request::DEVICE_SCOPE); 42511692Santhony.gutierrez@amd.com } else if (isSystemScope()) { 42611308Santhony.gutierrez@amd.com req->setMemSpaceConfigFlags(Request::SCOPE_VALID | 42711308Santhony.gutierrez@amd.com Request::SYSTEM_SCOPE); 42811692Santhony.gutierrez@amd.com } else if (!isNoScope() && !isWorkitemScope()) { 42911692Santhony.gutierrez@amd.com fatal("%s has bad scope type\n", disassemble()); 43011308Santhony.gutierrez@amd.com } 43111308Santhony.gutierrez@amd.com 43211308Santhony.gutierrez@amd.com if (setMemOrder) { 43311308Santhony.gutierrez@amd.com // set acquire and release flags 43411692Santhony.gutierrez@amd.com if (isAcquire()) { 43511308Santhony.gutierrez@amd.com req->setFlags(Request::ACQUIRE); 43611692Santhony.gutierrez@amd.com } else if (isRelease()) { 43711308Santhony.gutierrez@amd.com req->setFlags(Request::RELEASE); 43811692Santhony.gutierrez@amd.com } else if (isAcquireRelease()) { 43911308Santhony.gutierrez@amd.com req->setFlags(Request::ACQUIRE | Request::RELEASE); 44011692Santhony.gutierrez@amd.com } else if (!isNoOrder()) { 44111692Santhony.gutierrez@amd.com fatal("%s has bad memory order\n", disassemble()); 44211308Santhony.gutierrez@amd.com } 44311308Santhony.gutierrez@amd.com } 44411308Santhony.gutierrez@amd.com 44511308Santhony.gutierrez@amd.com // set atomic type 44611308Santhony.gutierrez@amd.com // currently, the instruction genenerator only produces atomic return 44711308Santhony.gutierrez@amd.com // but a magic instruction can produce atomic no return 44811692Santhony.gutierrez@amd.com if (isAtomicRet()) { 44911308Santhony.gutierrez@amd.com req->setFlags(Request::ATOMIC_RETURN_OP); 45011692Santhony.gutierrez@amd.com } else if (isAtomicNoRet()) { 45111308Santhony.gutierrez@amd.com req->setFlags(Request::ATOMIC_NO_RETURN_OP); 45211308Santhony.gutierrez@amd.com } 45311308Santhony.gutierrez@amd.com } 45411308Santhony.gutierrez@amd.com 45511308Santhony.gutierrez@amd.com // Map returned packets and the addresses they satisfy with which lane they 45611308Santhony.gutierrez@amd.com // were requested from 45711308Santhony.gutierrez@amd.com typedef std::unordered_map<Addr, std::vector<int>> StatusVector; 45811308Santhony.gutierrez@amd.com StatusVector memStatusVector; 45911308Santhony.gutierrez@amd.com 46011308Santhony.gutierrez@amd.com // Track the status of memory requests per lane, a bit per lane 46111308Santhony.gutierrez@amd.com VectorMask statusBitVector; 46211308Santhony.gutierrez@amd.com // for ld_v# or st_v# 46311308Santhony.gutierrez@amd.com std::vector<int> statusVector; 46411308Santhony.gutierrez@amd.com std::vector<int> tlbHitLevel; 46511308Santhony.gutierrez@amd.com 46611308Santhony.gutierrez@amd.com private: 46711692Santhony.gutierrez@amd.com GPUStaticInst *_staticInst; 46811308Santhony.gutierrez@amd.com uint64_t _seqNum; 46911308Santhony.gutierrez@amd.com}; 47011308Santhony.gutierrez@amd.com 47111308Santhony.gutierrez@amd.com#endif // __GPU_DYN_INST_HH__ 472