gpu_static_inst.hh revision 11692
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_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);
6411308Santhony.gutierrez@amd.com
6511308Santhony.gutierrez@amd.com    void instNum(int num) { _instNum = num; }
6611308Santhony.gutierrez@amd.com
6711308Santhony.gutierrez@amd.com    int instNum() { return _instNum;  }
6811308Santhony.gutierrez@amd.com
6911308Santhony.gutierrez@amd.com    void ipdInstNum(int num) { _ipdInstNum = num; }
7011308Santhony.gutierrez@amd.com
7111308Santhony.gutierrez@amd.com    int ipdInstNum() const { return _ipdInstNum; }
7211308Santhony.gutierrez@amd.com
7311308Santhony.gutierrez@amd.com    virtual void execute(GPUDynInstPtr gpuDynInst) = 0;
7411308Santhony.gutierrez@amd.com    virtual void generateDisassembly() = 0;
7511691Santhony.gutierrez@amd.com    const std::string& disassemble();
7611308Santhony.gutierrez@amd.com    virtual int getNumOperands() = 0;
7711308Santhony.gutierrez@amd.com    virtual bool isCondRegister(int operandIndex) = 0;
7811308Santhony.gutierrez@amd.com    virtual bool isScalarRegister(int operandIndex) = 0;
7911308Santhony.gutierrez@amd.com    virtual bool isVectorRegister(int operandIndex) = 0;
8011308Santhony.gutierrez@amd.com    virtual bool isSrcOperand(int operandIndex) = 0;
8111308Santhony.gutierrez@amd.com    virtual bool isDstOperand(int operandIndex) = 0;
8211308Santhony.gutierrez@amd.com    virtual int getOperandSize(int operandIndex) = 0;
8311308Santhony.gutierrez@amd.com    virtual int getRegisterIndex(int operandIndex) = 0;
8411308Santhony.gutierrez@amd.com    virtual int numDstRegOperands() = 0;
8511308Santhony.gutierrez@amd.com    virtual int numSrcRegOperands() = 0;
8611308Santhony.gutierrez@amd.com
8711690Santhony.gutierrez@amd.com    virtual bool isValid() const = 0;
8811690Santhony.gutierrez@amd.com
8911692Santhony.gutierrez@amd.com    bool isALU() const { return _flags[ALU]; }
9011692Santhony.gutierrez@amd.com    bool isBranch() const { return _flags[Branch]; }
9111692Santhony.gutierrez@amd.com    bool isNop() const { return _flags[Nop]; }
9211692Santhony.gutierrez@amd.com    bool isReturn() const { return _flags[Return]; }
9311308Santhony.gutierrez@amd.com
9411692Santhony.gutierrez@amd.com    bool
9511692Santhony.gutierrez@amd.com    isUnconditionalJump() const
9611308Santhony.gutierrez@amd.com    {
9711692Santhony.gutierrez@amd.com        return _flags[UnconditionalJump];
9811308Santhony.gutierrez@amd.com    }
9911308Santhony.gutierrez@amd.com
10011692Santhony.gutierrez@amd.com    bool isSpecialOp() const { return _flags[SpecialOp]; }
10111692Santhony.gutierrez@amd.com    bool isWaitcnt() const { return _flags[Waitcnt]; }
10211692Santhony.gutierrez@amd.com
10311692Santhony.gutierrez@amd.com    bool isBarrier() const { return _flags[MemBarrier]; }
10411692Santhony.gutierrez@amd.com    bool isMemFence() const { return _flags[MemFence]; }
10511692Santhony.gutierrez@amd.com    bool isMemRef() const { return _flags[MemoryRef]; }
10611692Santhony.gutierrez@amd.com    bool isFlat() const { return _flags[Flat]; }
10711692Santhony.gutierrez@amd.com    bool isLoad() const { return _flags[Load]; }
10811692Santhony.gutierrez@amd.com    bool isStore() const { return _flags[Store]; }
10911692Santhony.gutierrez@amd.com
11011692Santhony.gutierrez@amd.com    bool
11111692Santhony.gutierrez@amd.com    isAtomic() const
11211692Santhony.gutierrez@amd.com    {
11311692Santhony.gutierrez@amd.com        return _flags[AtomicReturn] || _flags[AtomicNoReturn];
11411692Santhony.gutierrez@amd.com    }
11511692Santhony.gutierrez@amd.com
11611692Santhony.gutierrez@amd.com    bool isAtomicNoRet() const { return _flags[AtomicNoReturn]; }
11711692Santhony.gutierrez@amd.com    bool isAtomicRet() const { return _flags[AtomicReturn]; }
11811692Santhony.gutierrez@amd.com
11911692Santhony.gutierrez@amd.com    bool isScalar() const { return _flags[Scalar]; }
12011692Santhony.gutierrez@amd.com    bool readsSCC() const { return _flags[ReadsSCC]; }
12111692Santhony.gutierrez@amd.com    bool writesSCC() const { return _flags[WritesSCC]; }
12211692Santhony.gutierrez@amd.com    bool readsVCC() const { return _flags[ReadsVCC]; }
12311692Santhony.gutierrez@amd.com    bool writesVCC() const { return _flags[WritesVCC]; }
12411692Santhony.gutierrez@amd.com
12511692Santhony.gutierrez@amd.com    bool isAtomicAnd() const { return _flags[AtomicAnd]; }
12611692Santhony.gutierrez@amd.com    bool isAtomicOr() const { return _flags[AtomicOr]; }
12711692Santhony.gutierrez@amd.com    bool isAtomicXor() const { return _flags[AtomicXor]; }
12811692Santhony.gutierrez@amd.com    bool isAtomicCAS() const { return _flags[AtomicCAS]; }
12911692Santhony.gutierrez@amd.com    bool isAtomicExch() const { return _flags[AtomicExch]; }
13011692Santhony.gutierrez@amd.com    bool isAtomicAdd() const { return _flags[AtomicAdd]; }
13111692Santhony.gutierrez@amd.com    bool isAtomicSub() const { return _flags[AtomicSub]; }
13211692Santhony.gutierrez@amd.com    bool isAtomicInc() const { return _flags[AtomicInc]; }
13311692Santhony.gutierrez@amd.com    bool isAtomicDec() const { return _flags[AtomicDec]; }
13411692Santhony.gutierrez@amd.com    bool isAtomicMax() const { return _flags[AtomicMax]; }
13511692Santhony.gutierrez@amd.com    bool isAtomicMin() const { return _flags[AtomicMin]; }
13611692Santhony.gutierrez@amd.com
13711692Santhony.gutierrez@amd.com    bool
13811692Santhony.gutierrez@amd.com    isArgLoad() const
13911692Santhony.gutierrez@amd.com    {
14011692Santhony.gutierrez@amd.com        return (_flags[KernArgSegment] || _flags[ArgSegment]) && _flags[Load];
14111692Santhony.gutierrez@amd.com    }
14211692Santhony.gutierrez@amd.com
14311692Santhony.gutierrez@amd.com    bool
14411692Santhony.gutierrez@amd.com    isGlobalMem() const
14511692Santhony.gutierrez@amd.com    {
14611692Santhony.gutierrez@amd.com        return _flags[MemoryRef] && (_flags[GlobalSegment] ||
14711692Santhony.gutierrez@amd.com               _flags[PrivateSegment] || _flags[ReadOnlySegment] ||
14811692Santhony.gutierrez@amd.com               _flags[SpillSegment]);
14911692Santhony.gutierrez@amd.com    }
15011692Santhony.gutierrez@amd.com
15111692Santhony.gutierrez@amd.com    bool
15211692Santhony.gutierrez@amd.com    isLocalMem() const
15311692Santhony.gutierrez@amd.com    {
15411692Santhony.gutierrez@amd.com        return _flags[MemoryRef] && _flags[GroupSegment];
15511692Santhony.gutierrez@amd.com    }
15611692Santhony.gutierrez@amd.com
15711692Santhony.gutierrez@amd.com    bool isArgSeg() const { return _flags[ArgSegment]; }
15811692Santhony.gutierrez@amd.com    bool isGlobalSeg() const { return _flags[GlobalSegment]; }
15911692Santhony.gutierrez@amd.com    bool isGroupSeg() const { return _flags[GroupSegment]; }
16011692Santhony.gutierrez@amd.com    bool isKernArgSeg() const { return _flags[KernArgSegment]; }
16111692Santhony.gutierrez@amd.com    bool isPrivateSeg() const { return _flags[PrivateSegment]; }
16211692Santhony.gutierrez@amd.com    bool isReadOnlySeg() const { return _flags[ReadOnlySegment]; }
16311692Santhony.gutierrez@amd.com    bool isSpillSeg() const { return _flags[SpillSegment]; }
16411692Santhony.gutierrez@amd.com
16511692Santhony.gutierrez@amd.com    bool isWorkitemScope() const { return _flags[WorkitemScope]; }
16611692Santhony.gutierrez@amd.com    bool isWavefrontScope() const { return _flags[WavefrontScope]; }
16711692Santhony.gutierrez@amd.com    bool isWorkgroupScope() const { return _flags[WorkgroupScope]; }
16811692Santhony.gutierrez@amd.com    bool isDeviceScope() const { return _flags[DeviceScope]; }
16911692Santhony.gutierrez@amd.com    bool isSystemScope() const { return _flags[SystemScope]; }
17011692Santhony.gutierrez@amd.com    bool isNoScope() const { return _flags[NoScope]; }
17111692Santhony.gutierrez@amd.com
17211692Santhony.gutierrez@amd.com    bool isRelaxedOrder() const { return _flags[RelaxedOrder]; }
17311692Santhony.gutierrez@amd.com    bool isAcquire() const { return _flags[Acquire]; }
17411692Santhony.gutierrez@amd.com    bool isRelease() const { return _flags[Release]; }
17511692Santhony.gutierrez@amd.com    bool isAcquireRelease() const { return _flags[AcquireRelease]; }
17611692Santhony.gutierrez@amd.com    bool isNoOrder() const { return _flags[NoOrder]; }
17711692Santhony.gutierrez@amd.com
17811692Santhony.gutierrez@amd.com    /**
17911692Santhony.gutierrez@amd.com     * Coherence domain of a memory instruction. Only valid for
18011692Santhony.gutierrez@amd.com     * machine ISA. The coherence domain specifies where it is
18111692Santhony.gutierrez@amd.com     * possible to perform memory synchronization, e.g., acquire
18211692Santhony.gutierrez@amd.com     * or release, from the shader kernel.
18311692Santhony.gutierrez@amd.com     *
18411692Santhony.gutierrez@amd.com     * isGloballyCoherent(): returns true if kernel is sharing memory
18511692Santhony.gutierrez@amd.com     * with other work-items on the same device (GPU)
18611692Santhony.gutierrez@amd.com     *
18711692Santhony.gutierrez@amd.com     * isSystemCoherent(): returns true if kernel is sharing memory
18811692Santhony.gutierrez@amd.com     * with other work-items on a different device (GPU) or the host (CPU)
18911692Santhony.gutierrez@amd.com     */
19011692Santhony.gutierrez@amd.com    bool isGloballyCoherent() const { return _flags[GloballyCoherent]; }
19111692Santhony.gutierrez@amd.com    bool isSystemCoherent() const { return _flags[SystemCoherent]; }
19211692Santhony.gutierrez@amd.com
19311308Santhony.gutierrez@amd.com    virtual uint32_t instSize() = 0;
19411308Santhony.gutierrez@amd.com
19511308Santhony.gutierrez@amd.com    // only used for memory instructions
19611308Santhony.gutierrez@amd.com    virtual void
19711308Santhony.gutierrez@amd.com    initiateAcc(GPUDynInstPtr gpuDynInst)
19811308Santhony.gutierrez@amd.com    {
19911308Santhony.gutierrez@amd.com        fatal("calling initiateAcc() on a non-memory instruction.\n");
20011308Santhony.gutierrez@amd.com    }
20111308Santhony.gutierrez@amd.com
20211690Santhony.gutierrez@amd.com    // only used for memory instructions
20311690Santhony.gutierrez@amd.com    virtual void
20411690Santhony.gutierrez@amd.com    completeAcc(GPUDynInstPtr gpuDynInst)
20511690Santhony.gutierrez@amd.com    {
20611690Santhony.gutierrez@amd.com        fatal("calling completeAcc() on a non-memory instruction.\n");
20711690Santhony.gutierrez@amd.com    }
20811690Santhony.gutierrez@amd.com
20911308Santhony.gutierrez@amd.com    virtual uint32_t getTargetPc() { return 0; }
21011308Santhony.gutierrez@amd.com
21111308Santhony.gutierrez@amd.com    static uint64_t dynamic_id_count;
21211308Santhony.gutierrez@amd.com
21311308Santhony.gutierrez@amd.com    // For flat memory accesses
21411308Santhony.gutierrez@amd.com    Enums::StorageClassType executed_as;
21511308Santhony.gutierrez@amd.com
21611692Santhony.gutierrez@amd.com    void setFlag(Flags flag) { _flags[flag] = true; }
21711692Santhony.gutierrez@amd.com
21811308Santhony.gutierrez@amd.com  protected:
21911308Santhony.gutierrez@amd.com    virtual void
22011308Santhony.gutierrez@amd.com    execLdAcq(GPUDynInstPtr gpuDynInst)
22111308Santhony.gutierrez@amd.com    {
22211308Santhony.gutierrez@amd.com        fatal("calling execLdAcq() on a non-load instruction.\n");
22311308Santhony.gutierrez@amd.com    }
22411308Santhony.gutierrez@amd.com
22511308Santhony.gutierrez@amd.com    virtual void
22611308Santhony.gutierrez@amd.com    execSt(GPUDynInstPtr gpuDynInst)
22711308Santhony.gutierrez@amd.com    {
22811308Santhony.gutierrez@amd.com        fatal("calling execLdAcq() on a non-load instruction.\n");
22911308Santhony.gutierrez@amd.com    }
23011308Santhony.gutierrez@amd.com
23111308Santhony.gutierrez@amd.com    virtual void
23211308Santhony.gutierrez@amd.com    execAtomic(GPUDynInstPtr gpuDynInst)
23311308Santhony.gutierrez@amd.com    {
23411308Santhony.gutierrez@amd.com        fatal("calling execAtomic() on a non-atomic instruction.\n");
23511308Santhony.gutierrez@amd.com    }
23611308Santhony.gutierrez@amd.com
23711308Santhony.gutierrez@amd.com    virtual void
23811308Santhony.gutierrez@amd.com    execAtomicAcq(GPUDynInstPtr gpuDynInst)
23911308Santhony.gutierrez@amd.com    {
24011308Santhony.gutierrez@amd.com        fatal("calling execAtomicAcq() on a non-atomic instruction.\n");
24111308Santhony.gutierrez@amd.com    }
24211308Santhony.gutierrez@amd.com
24311308Santhony.gutierrez@amd.com    const std::string opcode;
24411308Santhony.gutierrez@amd.com    std::string disassembly;
24511308Santhony.gutierrez@amd.com    int _instNum;
24611308Santhony.gutierrez@amd.com    /**
24711308Santhony.gutierrez@amd.com     * Identifier of the immediate post-dominator instruction.
24811308Santhony.gutierrez@amd.com     */
24911308Santhony.gutierrez@amd.com    int _ipdInstNum;
25011308Santhony.gutierrez@amd.com
25111692Santhony.gutierrez@amd.com    std::bitset<Num_Flags> _flags;
25211692Santhony.gutierrez@amd.com};
25311692Santhony.gutierrez@amd.com
25411692Santhony.gutierrez@amd.comclass KernelLaunchStaticInst : public GPUStaticInst
25511692Santhony.gutierrez@amd.com{
25611692Santhony.gutierrez@amd.com  public:
25711692Santhony.gutierrez@amd.com    KernelLaunchStaticInst() : GPUStaticInst("kernel_launch")
25811692Santhony.gutierrez@amd.com    {
25911692Santhony.gutierrez@amd.com        setFlag(Nop);
26011692Santhony.gutierrez@amd.com        setFlag(Scalar);
26111692Santhony.gutierrez@amd.com        setFlag(Acquire);
26211692Santhony.gutierrez@amd.com        setFlag(SystemScope);
26311692Santhony.gutierrez@amd.com        setFlag(GlobalSegment);
26411692Santhony.gutierrez@amd.com    }
26511692Santhony.gutierrez@amd.com
26611692Santhony.gutierrez@amd.com    void
26711692Santhony.gutierrez@amd.com    execute(GPUDynInstPtr gpuDynInst)
26811692Santhony.gutierrez@amd.com    {
26911692Santhony.gutierrez@amd.com        fatal("kernel launch instruction should not be executed\n");
27011692Santhony.gutierrez@amd.com    }
27111692Santhony.gutierrez@amd.com
27211692Santhony.gutierrez@amd.com    void
27311692Santhony.gutierrez@amd.com    generateDisassembly()
27411692Santhony.gutierrez@amd.com    {
27511692Santhony.gutierrez@amd.com        disassembly = opcode;
27611692Santhony.gutierrez@amd.com    }
27711692Santhony.gutierrez@amd.com
27811692Santhony.gutierrez@amd.com    int getNumOperands() { return 0; }
27911692Santhony.gutierrez@amd.com    bool isCondRegister(int operandIndex) { return false; }
28011692Santhony.gutierrez@amd.com    bool isScalarRegister(int operandIndex) { return false; }
28111692Santhony.gutierrez@amd.com    bool isVectorRegister(int operandIndex) { return false; }
28211692Santhony.gutierrez@amd.com    bool isSrcOperand(int operandIndex) { return false; }
28311692Santhony.gutierrez@amd.com    bool isDstOperand(int operandIndex) { return false; }
28411692Santhony.gutierrez@amd.com    int getOperandSize(int operandIndex) { return 0; }
28511692Santhony.gutierrez@amd.com    int getRegisterIndex(int operandIndex) { return 0; }
28611692Santhony.gutierrez@amd.com    int numDstRegOperands() { return 0; }
28711692Santhony.gutierrez@amd.com    int numSrcRegOperands() { return 0; }
28811692Santhony.gutierrez@amd.com    bool isValid() const { return true; }
28911692Santhony.gutierrez@amd.com    uint32_t instSize() { return 0; }
29011308Santhony.gutierrez@amd.com};
29111308Santhony.gutierrez@amd.com
29211308Santhony.gutierrez@amd.com#endif // __GPU_STATIC_INST_HH__
293