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 * 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_STATIC_INST_HH__ 3711308Santhony.gutierrez@amd.com#define __GPU_STATIC_INST_HH__ 3811308Santhony.gutierrez@amd.com 3911308Santhony.gutierrez@amd.com/* 4011308Santhony.gutierrez@amd.com * @file gpu_static_inst.hh 4111308Santhony.gutierrez@amd.com * 4211308Santhony.gutierrez@amd.com * Defines the base class representing static instructions for the GPU. The 4311308Santhony.gutierrez@amd.com * instructions are "static" because they contain no dynamic instruction 4411308Santhony.gutierrez@amd.com * information. GPUStaticInst corresponds to the StaticInst class for the CPU 4511308Santhony.gutierrez@amd.com * models. 4611308Santhony.gutierrez@amd.com */ 4711308Santhony.gutierrez@amd.com 4811308Santhony.gutierrez@amd.com#include <cstdint> 4911308Santhony.gutierrez@amd.com#include <string> 5011308Santhony.gutierrez@amd.com 5111692Santhony.gutierrez@amd.com#include "enums/GPUStaticInstFlags.hh" 5211308Santhony.gutierrez@amd.com#include "enums/StorageClassType.hh" 5311308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_dyn_inst.hh" 5411308Santhony.gutierrez@amd.com#include "gpu-compute/misc.hh" 5511308Santhony.gutierrez@amd.com 5611308Santhony.gutierrez@amd.comclass BaseOperand; 5711308Santhony.gutierrez@amd.comclass BaseRegOperand; 5811308Santhony.gutierrez@amd.comclass Wavefront; 5911308Santhony.gutierrez@amd.com 6011692Santhony.gutierrez@amd.comclass GPUStaticInst : public GPUStaticInstFlags 6111308Santhony.gutierrez@amd.com{ 6211308Santhony.gutierrez@amd.com public: 6311308Santhony.gutierrez@amd.com GPUStaticInst(const std::string &opcode); 6411697Santhony.gutierrez@amd.com void instAddr(int inst_addr) { _instAddr = inst_addr; } 6511697Santhony.gutierrez@amd.com int instAddr() const { return _instAddr; } 6611697Santhony.gutierrez@amd.com int nextInstAddr() const { return _instAddr + instSize(); } 6711308Santhony.gutierrez@amd.com 6811308Santhony.gutierrez@amd.com void instNum(int num) { _instNum = num; } 6911308Santhony.gutierrez@amd.com 7011308Santhony.gutierrez@amd.com int instNum() { return _instNum; } 7111308Santhony.gutierrez@amd.com 7211308Santhony.gutierrez@amd.com void ipdInstNum(int num) { _ipdInstNum = num; } 7311308Santhony.gutierrez@amd.com 7411308Santhony.gutierrez@amd.com int ipdInstNum() const { return _ipdInstNum; } 7511308Santhony.gutierrez@amd.com 7611308Santhony.gutierrez@amd.com virtual void execute(GPUDynInstPtr gpuDynInst) = 0; 7711308Santhony.gutierrez@amd.com virtual void generateDisassembly() = 0; 7811691Santhony.gutierrez@amd.com const std::string& disassemble(); 7911308Santhony.gutierrez@amd.com virtual int getNumOperands() = 0; 8011308Santhony.gutierrez@amd.com virtual bool isCondRegister(int operandIndex) = 0; 8111308Santhony.gutierrez@amd.com virtual bool isScalarRegister(int operandIndex) = 0; 8211308Santhony.gutierrez@amd.com virtual bool isVectorRegister(int operandIndex) = 0; 8311308Santhony.gutierrez@amd.com virtual bool isSrcOperand(int operandIndex) = 0; 8411308Santhony.gutierrez@amd.com virtual bool isDstOperand(int operandIndex) = 0; 8511308Santhony.gutierrez@amd.com virtual int getOperandSize(int operandIndex) = 0; 8611699Santhony.gutierrez@amd.com 8711699Santhony.gutierrez@amd.com virtual int getRegisterIndex(int operandIndex, 8811699Santhony.gutierrez@amd.com GPUDynInstPtr gpuDynInst) = 0; 8911699Santhony.gutierrez@amd.com 9011308Santhony.gutierrez@amd.com virtual int numDstRegOperands() = 0; 9111308Santhony.gutierrez@amd.com virtual int numSrcRegOperands() = 0; 9211308Santhony.gutierrez@amd.com 9311690Santhony.gutierrez@amd.com virtual bool isValid() const = 0; 9411690Santhony.gutierrez@amd.com 9511692Santhony.gutierrez@amd.com bool isALU() const { return _flags[ALU]; } 9611692Santhony.gutierrez@amd.com bool isBranch() const { return _flags[Branch]; } 9711692Santhony.gutierrez@amd.com bool isNop() const { return _flags[Nop]; } 9811692Santhony.gutierrez@amd.com bool isReturn() const { return _flags[Return]; } 9911308Santhony.gutierrez@amd.com 10011692Santhony.gutierrez@amd.com bool 10111692Santhony.gutierrez@amd.com isUnconditionalJump() const 10211308Santhony.gutierrez@amd.com { 10311692Santhony.gutierrez@amd.com return _flags[UnconditionalJump]; 10411308Santhony.gutierrez@amd.com } 10511308Santhony.gutierrez@amd.com 10611692Santhony.gutierrez@amd.com bool isSpecialOp() const { return _flags[SpecialOp]; } 10711692Santhony.gutierrez@amd.com bool isWaitcnt() const { return _flags[Waitcnt]; } 10811692Santhony.gutierrez@amd.com 10911692Santhony.gutierrez@amd.com bool isBarrier() const { return _flags[MemBarrier]; } 11011692Santhony.gutierrez@amd.com bool isMemFence() const { return _flags[MemFence]; } 11111692Santhony.gutierrez@amd.com bool isMemRef() const { return _flags[MemoryRef]; } 11211692Santhony.gutierrez@amd.com bool isFlat() const { return _flags[Flat]; } 11311692Santhony.gutierrez@amd.com bool isLoad() const { return _flags[Load]; } 11411692Santhony.gutierrez@amd.com bool isStore() const { return _flags[Store]; } 11511692Santhony.gutierrez@amd.com 11611692Santhony.gutierrez@amd.com bool 11711692Santhony.gutierrez@amd.com isAtomic() const 11811692Santhony.gutierrez@amd.com { 11911692Santhony.gutierrez@amd.com return _flags[AtomicReturn] || _flags[AtomicNoReturn]; 12011692Santhony.gutierrez@amd.com } 12111692Santhony.gutierrez@amd.com 12211692Santhony.gutierrez@amd.com bool isAtomicNoRet() const { return _flags[AtomicNoReturn]; } 12311692Santhony.gutierrez@amd.com bool isAtomicRet() const { return _flags[AtomicReturn]; } 12411692Santhony.gutierrez@amd.com 12511692Santhony.gutierrez@amd.com bool isScalar() const { return _flags[Scalar]; } 12611692Santhony.gutierrez@amd.com bool readsSCC() const { return _flags[ReadsSCC]; } 12711692Santhony.gutierrez@amd.com bool writesSCC() const { return _flags[WritesSCC]; } 12811692Santhony.gutierrez@amd.com bool readsVCC() const { return _flags[ReadsVCC]; } 12911692Santhony.gutierrez@amd.com bool writesVCC() const { return _flags[WritesVCC]; } 13011692Santhony.gutierrez@amd.com 13111692Santhony.gutierrez@amd.com bool isAtomicAnd() const { return _flags[AtomicAnd]; } 13211692Santhony.gutierrez@amd.com bool isAtomicOr() const { return _flags[AtomicOr]; } 13311692Santhony.gutierrez@amd.com bool isAtomicXor() const { return _flags[AtomicXor]; } 13411692Santhony.gutierrez@amd.com bool isAtomicCAS() const { return _flags[AtomicCAS]; } 13511692Santhony.gutierrez@amd.com bool isAtomicExch() const { return _flags[AtomicExch]; } 13611692Santhony.gutierrez@amd.com bool isAtomicAdd() const { return _flags[AtomicAdd]; } 13711692Santhony.gutierrez@amd.com bool isAtomicSub() const { return _flags[AtomicSub]; } 13811692Santhony.gutierrez@amd.com bool isAtomicInc() const { return _flags[AtomicInc]; } 13911692Santhony.gutierrez@amd.com bool isAtomicDec() const { return _flags[AtomicDec]; } 14011692Santhony.gutierrez@amd.com bool isAtomicMax() const { return _flags[AtomicMax]; } 14111692Santhony.gutierrez@amd.com bool isAtomicMin() const { return _flags[AtomicMin]; } 14211692Santhony.gutierrez@amd.com 14311692Santhony.gutierrez@amd.com bool 14411692Santhony.gutierrez@amd.com isArgLoad() const 14511692Santhony.gutierrez@amd.com { 14611692Santhony.gutierrez@amd.com return (_flags[KernArgSegment] || _flags[ArgSegment]) && _flags[Load]; 14711692Santhony.gutierrez@amd.com } 14811692Santhony.gutierrez@amd.com 14911692Santhony.gutierrez@amd.com bool 15011692Santhony.gutierrez@amd.com isGlobalMem() const 15111692Santhony.gutierrez@amd.com { 15211692Santhony.gutierrez@amd.com return _flags[MemoryRef] && (_flags[GlobalSegment] || 15311692Santhony.gutierrez@amd.com _flags[PrivateSegment] || _flags[ReadOnlySegment] || 15411692Santhony.gutierrez@amd.com _flags[SpillSegment]); 15511692Santhony.gutierrez@amd.com } 15611692Santhony.gutierrez@amd.com 15711692Santhony.gutierrez@amd.com bool 15811692Santhony.gutierrez@amd.com isLocalMem() const 15911692Santhony.gutierrez@amd.com { 16011692Santhony.gutierrez@amd.com return _flags[MemoryRef] && _flags[GroupSegment]; 16111692Santhony.gutierrez@amd.com } 16211692Santhony.gutierrez@amd.com 16311692Santhony.gutierrez@amd.com bool isArgSeg() const { return _flags[ArgSegment]; } 16411692Santhony.gutierrez@amd.com bool isGlobalSeg() const { return _flags[GlobalSegment]; } 16511692Santhony.gutierrez@amd.com bool isGroupSeg() const { return _flags[GroupSegment]; } 16611692Santhony.gutierrez@amd.com bool isKernArgSeg() const { return _flags[KernArgSegment]; } 16711692Santhony.gutierrez@amd.com bool isPrivateSeg() const { return _flags[PrivateSegment]; } 16811692Santhony.gutierrez@amd.com bool isReadOnlySeg() const { return _flags[ReadOnlySegment]; } 16911692Santhony.gutierrez@amd.com bool isSpillSeg() const { return _flags[SpillSegment]; } 17011692Santhony.gutierrez@amd.com 17111692Santhony.gutierrez@amd.com bool isWorkitemScope() const { return _flags[WorkitemScope]; } 17211692Santhony.gutierrez@amd.com bool isWavefrontScope() const { return _flags[WavefrontScope]; } 17311692Santhony.gutierrez@amd.com bool isWorkgroupScope() const { return _flags[WorkgroupScope]; } 17411692Santhony.gutierrez@amd.com bool isDeviceScope() const { return _flags[DeviceScope]; } 17511692Santhony.gutierrez@amd.com bool isSystemScope() const { return _flags[SystemScope]; } 17611692Santhony.gutierrez@amd.com bool isNoScope() const { return _flags[NoScope]; } 17711692Santhony.gutierrez@amd.com 17811692Santhony.gutierrez@amd.com bool isRelaxedOrder() const { return _flags[RelaxedOrder]; } 17911692Santhony.gutierrez@amd.com bool isAcquire() const { return _flags[Acquire]; } 18011692Santhony.gutierrez@amd.com bool isRelease() const { return _flags[Release]; } 18111692Santhony.gutierrez@amd.com bool isAcquireRelease() const { return _flags[AcquireRelease]; } 18211692Santhony.gutierrez@amd.com bool isNoOrder() const { return _flags[NoOrder]; } 18311692Santhony.gutierrez@amd.com 18411692Santhony.gutierrez@amd.com /** 18511692Santhony.gutierrez@amd.com * Coherence domain of a memory instruction. Only valid for 18611692Santhony.gutierrez@amd.com * machine ISA. The coherence domain specifies where it is 18711692Santhony.gutierrez@amd.com * possible to perform memory synchronization, e.g., acquire 18811692Santhony.gutierrez@amd.com * or release, from the shader kernel. 18911692Santhony.gutierrez@amd.com * 19011692Santhony.gutierrez@amd.com * isGloballyCoherent(): returns true if kernel is sharing memory 19111692Santhony.gutierrez@amd.com * with other work-items on the same device (GPU) 19211692Santhony.gutierrez@amd.com * 19311692Santhony.gutierrez@amd.com * isSystemCoherent(): returns true if kernel is sharing memory 19411692Santhony.gutierrez@amd.com * with other work-items on a different device (GPU) or the host (CPU) 19511692Santhony.gutierrez@amd.com */ 19611692Santhony.gutierrez@amd.com bool isGloballyCoherent() const { return _flags[GloballyCoherent]; } 19711692Santhony.gutierrez@amd.com bool isSystemCoherent() const { return _flags[SystemCoherent]; } 19811692Santhony.gutierrez@amd.com 19911697Santhony.gutierrez@amd.com virtual int instSize() const = 0; 20011308Santhony.gutierrez@amd.com 20111308Santhony.gutierrez@amd.com // only used for memory instructions 20211308Santhony.gutierrez@amd.com virtual void 20311308Santhony.gutierrez@amd.com initiateAcc(GPUDynInstPtr gpuDynInst) 20411308Santhony.gutierrez@amd.com { 20511308Santhony.gutierrez@amd.com fatal("calling initiateAcc() on a non-memory instruction.\n"); 20611308Santhony.gutierrez@amd.com } 20711308Santhony.gutierrez@amd.com 20811690Santhony.gutierrez@amd.com // only used for memory instructions 20911690Santhony.gutierrez@amd.com virtual void 21011690Santhony.gutierrez@amd.com completeAcc(GPUDynInstPtr gpuDynInst) 21111690Santhony.gutierrez@amd.com { 21211690Santhony.gutierrez@amd.com fatal("calling completeAcc() on a non-memory instruction.\n"); 21311690Santhony.gutierrez@amd.com } 21411690Santhony.gutierrez@amd.com 21511308Santhony.gutierrez@amd.com virtual uint32_t getTargetPc() { return 0; } 21611308Santhony.gutierrez@amd.com 21711308Santhony.gutierrez@amd.com static uint64_t dynamic_id_count; 21811308Santhony.gutierrez@amd.com 21911308Santhony.gutierrez@amd.com // For flat memory accesses 22011308Santhony.gutierrez@amd.com Enums::StorageClassType executed_as; 22111308Santhony.gutierrez@amd.com 22211692Santhony.gutierrez@amd.com void setFlag(Flags flag) { _flags[flag] = true; } 22311692Santhony.gutierrez@amd.com 22411308Santhony.gutierrez@amd.com virtual void 22511308Santhony.gutierrez@amd.com execLdAcq(GPUDynInstPtr gpuDynInst) 22611308Santhony.gutierrez@amd.com { 22711308Santhony.gutierrez@amd.com fatal("calling execLdAcq() on a non-load instruction.\n"); 22811308Santhony.gutierrez@amd.com } 22911308Santhony.gutierrez@amd.com 23011308Santhony.gutierrez@amd.com virtual void 23111308Santhony.gutierrez@amd.com execSt(GPUDynInstPtr gpuDynInst) 23211308Santhony.gutierrez@amd.com { 23311308Santhony.gutierrez@amd.com fatal("calling execLdAcq() on a non-load instruction.\n"); 23411308Santhony.gutierrez@amd.com } 23511308Santhony.gutierrez@amd.com 23611308Santhony.gutierrez@amd.com virtual void 23711308Santhony.gutierrez@amd.com execAtomic(GPUDynInstPtr gpuDynInst) 23811308Santhony.gutierrez@amd.com { 23911308Santhony.gutierrez@amd.com fatal("calling execAtomic() on a non-atomic instruction.\n"); 24011308Santhony.gutierrez@amd.com } 24111308Santhony.gutierrez@amd.com 24211308Santhony.gutierrez@amd.com virtual void 24311308Santhony.gutierrez@amd.com execAtomicAcq(GPUDynInstPtr gpuDynInst) 24411308Santhony.gutierrez@amd.com { 24511308Santhony.gutierrez@amd.com fatal("calling execAtomicAcq() on a non-atomic instruction.\n"); 24611308Santhony.gutierrez@amd.com } 24711308Santhony.gutierrez@amd.com 24811704Santhony.gutierrez@amd.com protected: 24911308Santhony.gutierrez@amd.com const std::string opcode; 25011308Santhony.gutierrez@amd.com std::string disassembly; 25111308Santhony.gutierrez@amd.com int _instNum; 25211697Santhony.gutierrez@amd.com int _instAddr; 25311308Santhony.gutierrez@amd.com /** 25411308Santhony.gutierrez@amd.com * Identifier of the immediate post-dominator instruction. 25511308Santhony.gutierrez@amd.com */ 25611308Santhony.gutierrez@amd.com int _ipdInstNum; 25711308Santhony.gutierrez@amd.com 25811692Santhony.gutierrez@amd.com std::bitset<Num_Flags> _flags; 25911692Santhony.gutierrez@amd.com}; 26011692Santhony.gutierrez@amd.com 26111692Santhony.gutierrez@amd.comclass KernelLaunchStaticInst : public GPUStaticInst 26211692Santhony.gutierrez@amd.com{ 26311692Santhony.gutierrez@amd.com public: 26411692Santhony.gutierrez@amd.com KernelLaunchStaticInst() : GPUStaticInst("kernel_launch") 26511692Santhony.gutierrez@amd.com { 26611692Santhony.gutierrez@amd.com setFlag(Nop); 26711692Santhony.gutierrez@amd.com setFlag(Scalar); 26811692Santhony.gutierrez@amd.com setFlag(Acquire); 26911692Santhony.gutierrez@amd.com setFlag(SystemScope); 27011692Santhony.gutierrez@amd.com setFlag(GlobalSegment); 27111692Santhony.gutierrez@amd.com } 27211692Santhony.gutierrez@amd.com 27311692Santhony.gutierrez@amd.com void 27411882Sbrandon.potter@amd.com execute(GPUDynInstPtr gpuDynInst) override 27511692Santhony.gutierrez@amd.com { 27611692Santhony.gutierrez@amd.com fatal("kernel launch instruction should not be executed\n"); 27711692Santhony.gutierrez@amd.com } 27811692Santhony.gutierrez@amd.com 27911692Santhony.gutierrez@amd.com void 28011882Sbrandon.potter@amd.com generateDisassembly() override 28111692Santhony.gutierrez@amd.com { 28211692Santhony.gutierrez@amd.com disassembly = opcode; 28311692Santhony.gutierrez@amd.com } 28411692Santhony.gutierrez@amd.com 28511882Sbrandon.potter@amd.com int getNumOperands() override { return 0; } 28611882Sbrandon.potter@amd.com bool isCondRegister(int operandIndex) override { return false; } 28711882Sbrandon.potter@amd.com bool isScalarRegister(int operandIndex) override { return false; } 28811882Sbrandon.potter@amd.com bool isVectorRegister(int operandIndex) override { return false; } 28911882Sbrandon.potter@amd.com bool isSrcOperand(int operandIndex) override { return false; } 29011882Sbrandon.potter@amd.com bool isDstOperand(int operandIndex) override { return false; } 29111882Sbrandon.potter@amd.com int getOperandSize(int operandIndex) override { return 0; } 29211699Santhony.gutierrez@amd.com 29311699Santhony.gutierrez@amd.com int 29411699Santhony.gutierrez@amd.com getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) override 29511699Santhony.gutierrez@amd.com { 29611699Santhony.gutierrez@amd.com return 0; 29711699Santhony.gutierrez@amd.com } 29811699Santhony.gutierrez@amd.com 29911882Sbrandon.potter@amd.com int numDstRegOperands() override { return 0; } 30011882Sbrandon.potter@amd.com int numSrcRegOperands() override { return 0; } 30111882Sbrandon.potter@amd.com bool isValid() const override { return true; } 30211697Santhony.gutierrez@amd.com int instSize() const override { return 0; } 30311308Santhony.gutierrez@amd.com}; 30411308Santhony.gutierrez@amd.com 30511308Santhony.gutierrez@amd.com#endif // __GPU_STATIC_INST_HH__ 306