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