gpu_dyn_inst.hh revision 12889
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
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; }
5712889Sbrandon.potter@amd.com    AtomicOpFunctor* clone () { return new AtomicOpAnd(a); }
5811308Santhony.gutierrez@amd.com};
5911308Santhony.gutierrez@amd.com
6011308Santhony.gutierrez@amd.comtemplate<typename T>
6111308Santhony.gutierrez@amd.comclass AtomicOpOr : public TypedAtomicOpFunctor<T>
6211308Santhony.gutierrez@amd.com{
6311308Santhony.gutierrez@amd.com  public:
6411308Santhony.gutierrez@amd.com    T a;
6511308Santhony.gutierrez@amd.com    AtomicOpOr(T _a) : a(_a) { }
6611308Santhony.gutierrez@amd.com    void execute(T *b) { *b |= a; }
6712889Sbrandon.potter@amd.com    AtomicOpFunctor* clone () { return new AtomicOpOr(a); }
6811308Santhony.gutierrez@amd.com};
6911308Santhony.gutierrez@amd.com
7011308Santhony.gutierrez@amd.comtemplate<typename T>
7111308Santhony.gutierrez@amd.comclass AtomicOpXor : public TypedAtomicOpFunctor<T>
7211308Santhony.gutierrez@amd.com{
7311308Santhony.gutierrez@amd.com  public:
7411308Santhony.gutierrez@amd.com    T a;
7511308Santhony.gutierrez@amd.com    AtomicOpXor(T _a) : a(_a) {}
7611308Santhony.gutierrez@amd.com    void execute(T *b) { *b ^= a; }
7712889Sbrandon.potter@amd.com    AtomicOpFunctor* clone () { return new AtomicOpXor(a); }
7811308Santhony.gutierrez@amd.com};
7911308Santhony.gutierrez@amd.com
8011308Santhony.gutierrez@amd.comtemplate<typename T>
8111308Santhony.gutierrez@amd.comclass AtomicOpCAS : public TypedAtomicOpFunctor<T>
8211308Santhony.gutierrez@amd.com{
8311308Santhony.gutierrez@amd.com  public:
8411308Santhony.gutierrez@amd.com    T c;
8511308Santhony.gutierrez@amd.com    T s;
8611308Santhony.gutierrez@amd.com
8711308Santhony.gutierrez@amd.com    ComputeUnit *computeUnit;
8811308Santhony.gutierrez@amd.com
8911308Santhony.gutierrez@amd.com    AtomicOpCAS(T _c, T _s, ComputeUnit *compute_unit)
9011308Santhony.gutierrez@amd.com      : c(_c), s(_s), computeUnit(compute_unit) { }
9111308Santhony.gutierrez@amd.com
9211308Santhony.gutierrez@amd.com    void
9311308Santhony.gutierrez@amd.com    execute(T *b)
9411308Santhony.gutierrez@amd.com    {
9511308Santhony.gutierrez@amd.com        computeUnit->numCASOps++;
9611308Santhony.gutierrez@amd.com
9711308Santhony.gutierrez@amd.com        if (*b == c) {
9811308Santhony.gutierrez@amd.com            *b = s;
9911308Santhony.gutierrez@amd.com        } else {
10011308Santhony.gutierrez@amd.com            computeUnit->numFailedCASOps++;
10111308Santhony.gutierrez@amd.com        }
10211308Santhony.gutierrez@amd.com
10311308Santhony.gutierrez@amd.com        if (computeUnit->xact_cas_mode) {
10411308Santhony.gutierrez@amd.com            computeUnit->xactCasLoadMap.clear();
10511308Santhony.gutierrez@amd.com        }
10611308Santhony.gutierrez@amd.com    }
10712889Sbrandon.potter@amd.com    AtomicOpFunctor* clone () { return new AtomicOpCAS(c, s, computeUnit); }
10811308Santhony.gutierrez@amd.com};
10911308Santhony.gutierrez@amd.com
11011308Santhony.gutierrez@amd.comtemplate<typename T>
11111308Santhony.gutierrez@amd.comclass AtomicOpExch : public TypedAtomicOpFunctor<T>
11211308Santhony.gutierrez@amd.com{
11311308Santhony.gutierrez@amd.com  public:
11411308Santhony.gutierrez@amd.com    T a;
11511308Santhony.gutierrez@amd.com    AtomicOpExch(T _a) : a(_a) { }
11611308Santhony.gutierrez@amd.com    void execute(T *b) { *b = a; }
11712889Sbrandon.potter@amd.com    AtomicOpFunctor* clone () { return new AtomicOpExch(a); }
11811308Santhony.gutierrez@amd.com};
11911308Santhony.gutierrez@amd.com
12011308Santhony.gutierrez@amd.comtemplate<typename T>
12111308Santhony.gutierrez@amd.comclass AtomicOpAdd : public TypedAtomicOpFunctor<T>
12211308Santhony.gutierrez@amd.com{
12311308Santhony.gutierrez@amd.com  public:
12411308Santhony.gutierrez@amd.com    T a;
12511308Santhony.gutierrez@amd.com    AtomicOpAdd(T _a) : a(_a) { }
12611308Santhony.gutierrez@amd.com    void execute(T *b) { *b += a; }
12712889Sbrandon.potter@amd.com    AtomicOpFunctor* clone () { return new AtomicOpAdd(a); }
12811308Santhony.gutierrez@amd.com};
12911308Santhony.gutierrez@amd.com
13011308Santhony.gutierrez@amd.comtemplate<typename T>
13111308Santhony.gutierrez@amd.comclass AtomicOpSub : public TypedAtomicOpFunctor<T>
13211308Santhony.gutierrez@amd.com{
13311308Santhony.gutierrez@amd.com  public:
13411308Santhony.gutierrez@amd.com    T a;
13511308Santhony.gutierrez@amd.com    AtomicOpSub(T _a) : a(_a) { }
13611308Santhony.gutierrez@amd.com    void execute(T *b) { *b -= a; }
13712889Sbrandon.potter@amd.com    AtomicOpFunctor* clone () { return new AtomicOpSub(a); }
13811308Santhony.gutierrez@amd.com};
13911308Santhony.gutierrez@amd.com
14011308Santhony.gutierrez@amd.comtemplate<typename T>
14111308Santhony.gutierrez@amd.comclass AtomicOpInc : public TypedAtomicOpFunctor<T>
14211308Santhony.gutierrez@amd.com{
14311308Santhony.gutierrez@amd.com  public:
14411308Santhony.gutierrez@amd.com    AtomicOpInc() { }
14511308Santhony.gutierrez@amd.com    void execute(T *b) { *b += 1; }
14612889Sbrandon.potter@amd.com    AtomicOpFunctor* clone () { return new AtomicOpInc(); }
14711308Santhony.gutierrez@amd.com};
14811308Santhony.gutierrez@amd.com
14911308Santhony.gutierrez@amd.comtemplate<typename T>
15011308Santhony.gutierrez@amd.comclass AtomicOpDec : public TypedAtomicOpFunctor<T>
15111308Santhony.gutierrez@amd.com{
15211308Santhony.gutierrez@amd.com  public:
15311308Santhony.gutierrez@amd.com    AtomicOpDec() {}
15411308Santhony.gutierrez@amd.com    void execute(T *b) { *b -= 1; }
15512889Sbrandon.potter@amd.com    AtomicOpFunctor* clone () { return new AtomicOpDec(); }
15611308Santhony.gutierrez@amd.com};
15711308Santhony.gutierrez@amd.com
15811308Santhony.gutierrez@amd.comtemplate<typename T>
15911308Santhony.gutierrez@amd.comclass AtomicOpMax : public TypedAtomicOpFunctor<T>
16011308Santhony.gutierrez@amd.com{
16111308Santhony.gutierrez@amd.com  public:
16211308Santhony.gutierrez@amd.com    T a;
16311308Santhony.gutierrez@amd.com    AtomicOpMax(T _a) : a(_a) { }
16411308Santhony.gutierrez@amd.com
16511308Santhony.gutierrez@amd.com    void
16611308Santhony.gutierrez@amd.com    execute(T *b)
16711308Santhony.gutierrez@amd.com    {
16811308Santhony.gutierrez@amd.com        if (a > *b)
16911308Santhony.gutierrez@amd.com            *b = a;
17011308Santhony.gutierrez@amd.com    }
17112889Sbrandon.potter@amd.com    AtomicOpFunctor* clone () { return new AtomicOpMax(a); }
17211308Santhony.gutierrez@amd.com};
17311308Santhony.gutierrez@amd.com
17411308Santhony.gutierrez@amd.comtemplate<typename T>
17511308Santhony.gutierrez@amd.comclass AtomicOpMin : public TypedAtomicOpFunctor<T>
17611308Santhony.gutierrez@amd.com{
17711308Santhony.gutierrez@amd.com  public:
17811308Santhony.gutierrez@amd.com    T a;
17911308Santhony.gutierrez@amd.com    AtomicOpMin(T _a) : a(_a) {}
18011308Santhony.gutierrez@amd.com
18111308Santhony.gutierrez@amd.com    void
18211308Santhony.gutierrez@amd.com    execute(T *b)
18311308Santhony.gutierrez@amd.com    {
18411308Santhony.gutierrez@amd.com        if (a < *b)
18511308Santhony.gutierrez@amd.com            *b = a;
18611308Santhony.gutierrez@amd.com    }
18712889Sbrandon.potter@amd.com    AtomicOpFunctor* clone () { return new AtomicOpMin(a); }
18811308Santhony.gutierrez@amd.com};
18911308Santhony.gutierrez@amd.com
19011308Santhony.gutierrez@amd.comtypedef enum
19111308Santhony.gutierrez@amd.com{
19211308Santhony.gutierrez@amd.com    VT_32,
19311308Santhony.gutierrez@amd.com    VT_64,
19411308Santhony.gutierrez@amd.com} vgpr_type;
19511308Santhony.gutierrez@amd.com
19611308Santhony.gutierrez@amd.comclass GPUDynInst : public GPUExecContext
19711308Santhony.gutierrez@amd.com{
19811308Santhony.gutierrez@amd.com  public:
19911692Santhony.gutierrez@amd.com    GPUDynInst(ComputeUnit *_cu, Wavefront *_wf, GPUStaticInst *static_inst,
20011308Santhony.gutierrez@amd.com               uint64_t instSeqNum);
20111534Sjohn.kalamatianos@amd.com    ~GPUDynInst();
20211692Santhony.gutierrez@amd.com    void execute(GPUDynInstPtr gpuDynInst);
20311308Santhony.gutierrez@amd.com    int numSrcRegOperands();
20411308Santhony.gutierrez@amd.com    int numDstRegOperands();
20511308Santhony.gutierrez@amd.com    int getNumOperands();
20611308Santhony.gutierrez@amd.com    bool isVectorRegister(int operandIdx);
20711308Santhony.gutierrez@amd.com    bool isScalarRegister(int operandIdx);
20811699Santhony.gutierrez@amd.com    bool isCondRegister(int operandIdx);
20911699Santhony.gutierrez@amd.com    int getRegisterIndex(int operandIdx, GPUDynInstPtr gpuDynInst);
21011308Santhony.gutierrez@amd.com    int getOperandSize(int operandIdx);
21111308Santhony.gutierrez@amd.com    bool isDstOperand(int operandIdx);
21211308Santhony.gutierrez@amd.com    bool isSrcOperand(int operandIdx);
21311308Santhony.gutierrez@amd.com
21411308Santhony.gutierrez@amd.com    const std::string &disassemble() const;
21511308Santhony.gutierrez@amd.com
21611308Santhony.gutierrez@amd.com    uint64_t seqNum() const;
21711308Santhony.gutierrez@amd.com
21811308Santhony.gutierrez@amd.com    Enums::StorageClassType executedAs();
21911308Santhony.gutierrez@amd.com
22011308Santhony.gutierrez@amd.com    // The address of the memory operation
22111534Sjohn.kalamatianos@amd.com    std::vector<Addr> addr;
22211308Santhony.gutierrez@amd.com    Addr pAddr;
22311308Santhony.gutierrez@amd.com
22411308Santhony.gutierrez@amd.com    // The data to get written
22511534Sjohn.kalamatianos@amd.com    uint8_t *d_data;
22611308Santhony.gutierrez@amd.com    // Additional data (for atomics)
22711534Sjohn.kalamatianos@amd.com    uint8_t *a_data;
22811308Santhony.gutierrez@amd.com    // Additional data (for atomics)
22911534Sjohn.kalamatianos@amd.com    uint8_t *x_data;
23011308Santhony.gutierrez@amd.com    // The execution mask
23111308Santhony.gutierrez@amd.com    VectorMask exec_mask;
23211308Santhony.gutierrez@amd.com
23311308Santhony.gutierrez@amd.com    // The memory type (M_U32, M_S32, ...)
23411308Santhony.gutierrez@amd.com    Enums::MemType m_type;
23511308Santhony.gutierrez@amd.com
23611308Santhony.gutierrez@amd.com    // The equivalency class
23711308Santhony.gutierrez@amd.com    int equiv;
23811308Santhony.gutierrez@amd.com    // The return VGPR type (VT_32 or VT_64)
23911308Santhony.gutierrez@amd.com    vgpr_type v_type;
24011308Santhony.gutierrez@amd.com    // Number of VGPR's accessed (1, 2, or 4)
24111308Santhony.gutierrez@amd.com    int n_reg;
24211308Santhony.gutierrez@amd.com    // The return VGPR index
24311308Santhony.gutierrez@amd.com    int dst_reg;
24411308Santhony.gutierrez@amd.com    // There can be max 4 dest regs>
24511308Santhony.gutierrez@amd.com    int dst_reg_vec[4];
24611308Santhony.gutierrez@amd.com    // SIMD where the WF of the memory instruction has been mapped to
24711308Santhony.gutierrez@amd.com    int simdId;
24811308Santhony.gutierrez@amd.com    // unique id of the WF where the memory instruction belongs to
24911308Santhony.gutierrez@amd.com    int wfDynId;
25011308Santhony.gutierrez@amd.com    // The kernel id of the requesting wf
25111308Santhony.gutierrez@amd.com    int kern_id;
25211308Santhony.gutierrez@amd.com    // The CU id of the requesting wf
25311308Santhony.gutierrez@amd.com    int cu_id;
25411308Santhony.gutierrez@amd.com    // HW slot id where the WF is mapped to inside a SIMD unit
25511308Santhony.gutierrez@amd.com    int wfSlotId;
25611308Santhony.gutierrez@amd.com    // execution pipeline id where the memory instruction has been scheduled
25711308Santhony.gutierrez@amd.com    int pipeId;
25811308Santhony.gutierrez@amd.com    // The execution time of this operation
25911308Santhony.gutierrez@amd.com    Tick time;
26011308Santhony.gutierrez@amd.com    // The latency of this operation
26111308Santhony.gutierrez@amd.com    WaitClass latency;
26211308Santhony.gutierrez@amd.com    // A list of bank conflicts for the 4 cycles.
26311308Santhony.gutierrez@amd.com    uint32_t bc[4];
26411308Santhony.gutierrez@amd.com
26511308Santhony.gutierrez@amd.com    // A pointer to ROM
26611308Santhony.gutierrez@amd.com    uint8_t *rom;
26711308Santhony.gutierrez@amd.com    // The size of the READONLY segment
26811308Santhony.gutierrez@amd.com    int sz_rom;
26911308Santhony.gutierrez@amd.com
27011308Santhony.gutierrez@amd.com    // Initiate the specified memory operation, by creating a
27111308Santhony.gutierrez@amd.com    // memory request and sending it off to the memory system.
27211308Santhony.gutierrez@amd.com    void initiateAcc(GPUDynInstPtr gpuDynInst);
27311693Santhony.gutierrez@amd.com    // Complete the specified memory operation, by writing
27411693Santhony.gutierrez@amd.com    // value back to the RF in the case of a load or atomic
27511693Santhony.gutierrez@amd.com    // return or, in the case of a store, we do nothing
27611693Santhony.gutierrez@amd.com    void completeAcc(GPUDynInstPtr gpuDynInst);
27711308Santhony.gutierrez@amd.com
27811308Santhony.gutierrez@amd.com    void updateStats();
27911308Santhony.gutierrez@amd.com
28011692Santhony.gutierrez@amd.com    GPUStaticInst* staticInstruction() { return _staticInst; }
28111308Santhony.gutierrez@amd.com
28211692Santhony.gutierrez@amd.com    bool isALU() const;
28311692Santhony.gutierrez@amd.com    bool isBranch() const;
28411692Santhony.gutierrez@amd.com    bool isNop() const;
28511692Santhony.gutierrez@amd.com    bool isReturn() const;
28611692Santhony.gutierrez@amd.com    bool isUnconditionalJump() const;
28711692Santhony.gutierrez@amd.com    bool isSpecialOp() const;
28811692Santhony.gutierrez@amd.com    bool isWaitcnt() const;
28911692Santhony.gutierrez@amd.com
29011692Santhony.gutierrez@amd.com    bool isBarrier() const;
29111692Santhony.gutierrez@amd.com    bool isMemFence() const;
29211692Santhony.gutierrez@amd.com    bool isMemRef() const;
29311692Santhony.gutierrez@amd.com    bool isFlat() const;
29411692Santhony.gutierrez@amd.com    bool isLoad() const;
29511692Santhony.gutierrez@amd.com    bool isStore() const;
29611692Santhony.gutierrez@amd.com
29711692Santhony.gutierrez@amd.com    bool isAtomic() const;
29811692Santhony.gutierrez@amd.com    bool isAtomicNoRet() const;
29911692Santhony.gutierrez@amd.com    bool isAtomicRet() const;
30011692Santhony.gutierrez@amd.com
30111692Santhony.gutierrez@amd.com    bool isScalar() const;
30211692Santhony.gutierrez@amd.com    bool readsSCC() const;
30311692Santhony.gutierrez@amd.com    bool writesSCC() const;
30411692Santhony.gutierrez@amd.com    bool readsVCC() const;
30511692Santhony.gutierrez@amd.com    bool writesVCC() const;
30611692Santhony.gutierrez@amd.com
30711692Santhony.gutierrez@amd.com    bool isAtomicAnd() const;
30811692Santhony.gutierrez@amd.com    bool isAtomicOr() const;
30911692Santhony.gutierrez@amd.com    bool isAtomicXor() const;
31011692Santhony.gutierrez@amd.com    bool isAtomicCAS() const;
31111692Santhony.gutierrez@amd.com    bool isAtomicExch() const;
31211692Santhony.gutierrez@amd.com    bool isAtomicAdd() const;
31311692Santhony.gutierrez@amd.com    bool isAtomicSub() const;
31411692Santhony.gutierrez@amd.com    bool isAtomicInc() const;
31511692Santhony.gutierrez@amd.com    bool isAtomicDec() const;
31611692Santhony.gutierrez@amd.com    bool isAtomicMax() const;
31711692Santhony.gutierrez@amd.com    bool isAtomicMin() const;
31811692Santhony.gutierrez@amd.com
31911692Santhony.gutierrez@amd.com    bool isArgLoad() const;
32011692Santhony.gutierrez@amd.com    bool isGlobalMem() const;
32111692Santhony.gutierrez@amd.com    bool isLocalMem() const;
32211692Santhony.gutierrez@amd.com
32311692Santhony.gutierrez@amd.com    bool isArgSeg() const;
32411692Santhony.gutierrez@amd.com    bool isGlobalSeg() const;
32511692Santhony.gutierrez@amd.com    bool isGroupSeg() const;
32611692Santhony.gutierrez@amd.com    bool isKernArgSeg() const;
32711692Santhony.gutierrez@amd.com    bool isPrivateSeg() const;
32811692Santhony.gutierrez@amd.com    bool isReadOnlySeg() const;
32911692Santhony.gutierrez@amd.com    bool isSpillSeg() const;
33011692Santhony.gutierrez@amd.com
33111692Santhony.gutierrez@amd.com    bool isWorkitemScope() const;
33211692Santhony.gutierrez@amd.com    bool isWavefrontScope() const;
33311692Santhony.gutierrez@amd.com    bool isWorkgroupScope() const;
33411692Santhony.gutierrez@amd.com    bool isDeviceScope() const;
33511692Santhony.gutierrez@amd.com    bool isSystemScope() const;
33611692Santhony.gutierrez@amd.com    bool isNoScope() const;
33711692Santhony.gutierrez@amd.com
33811692Santhony.gutierrez@amd.com    bool isRelaxedOrder() const;
33911692Santhony.gutierrez@amd.com    bool isAcquire() const;
34011692Santhony.gutierrez@amd.com    bool isRelease() const;
34111692Santhony.gutierrez@amd.com    bool isAcquireRelease() const;
34211692Santhony.gutierrez@amd.com    bool isNoOrder() const;
34311692Santhony.gutierrez@amd.com
34411692Santhony.gutierrez@amd.com    bool isGloballyCoherent() const;
34511692Santhony.gutierrez@amd.com    bool isSystemCoherent() const;
34611308Santhony.gutierrez@amd.com
34711308Santhony.gutierrez@amd.com    /*
34811308Santhony.gutierrez@amd.com     * Loads/stores/atomics may have acquire/release semantics associated
34911308Santhony.gutierrez@amd.com     * withthem. Some protocols want to see the acquire/release as separate
35011308Santhony.gutierrez@amd.com     * requests from the load/store/atomic. We implement that separation
35111308Santhony.gutierrez@amd.com     * using continuations (i.e., a function pointer with an object associated
35211308Santhony.gutierrez@amd.com     * with it). When, for example, the front-end generates a store with
35311308Santhony.gutierrez@amd.com     * release semantics, we will first issue a normal store and set the
35411308Santhony.gutierrez@amd.com     * continuation in the GPUDynInst to a function that generate a
35511308Santhony.gutierrez@amd.com     * release request. That continuation will be called when the normal
35611308Santhony.gutierrez@amd.com     * store completes (in ComputeUnit::DataPort::recvTimingResponse). The
35711308Santhony.gutierrez@amd.com     * continuation will be called in the context of the same GPUDynInst
35811308Santhony.gutierrez@amd.com     * that generated the initial store.
35911308Santhony.gutierrez@amd.com     */
36011308Santhony.gutierrez@amd.com    std::function<void(GPUStaticInst*, GPUDynInstPtr)> execContinuation;
36111308Santhony.gutierrez@amd.com
36211308Santhony.gutierrez@amd.com    // when true, call execContinuation when response arrives
36311308Santhony.gutierrez@amd.com    bool useContinuation;
36411308Santhony.gutierrez@amd.com
36511308Santhony.gutierrez@amd.com    template<typename c0> AtomicOpFunctor*
36611692Santhony.gutierrez@amd.com    makeAtomicOpFunctor(c0 *reg0, c0 *reg1)
36711308Santhony.gutierrez@amd.com    {
36811692Santhony.gutierrez@amd.com        if (isAtomicAnd()) {
36911308Santhony.gutierrez@amd.com            return new AtomicOpAnd<c0>(*reg0);
37011692Santhony.gutierrez@amd.com        } else if (isAtomicOr()) {
37111308Santhony.gutierrez@amd.com            return new AtomicOpOr<c0>(*reg0);
37211692Santhony.gutierrez@amd.com        } else if (isAtomicXor()) {
37311308Santhony.gutierrez@amd.com            return new AtomicOpXor<c0>(*reg0);
37411692Santhony.gutierrez@amd.com        } else if (isAtomicCAS()) {
37511308Santhony.gutierrez@amd.com            return new AtomicOpCAS<c0>(*reg0, *reg1, cu);
37611692Santhony.gutierrez@amd.com        } else if (isAtomicExch()) {
37711308Santhony.gutierrez@amd.com            return new AtomicOpExch<c0>(*reg0);
37811692Santhony.gutierrez@amd.com        } else if (isAtomicAdd()) {
37911308Santhony.gutierrez@amd.com            return new AtomicOpAdd<c0>(*reg0);
38011692Santhony.gutierrez@amd.com        } else if (isAtomicSub()) {
38111308Santhony.gutierrez@amd.com            return new AtomicOpSub<c0>(*reg0);
38211692Santhony.gutierrez@amd.com        } else if (isAtomicInc()) {
38311308Santhony.gutierrez@amd.com            return new AtomicOpInc<c0>();
38411692Santhony.gutierrez@amd.com        } else if (isAtomicDec()) {
38511308Santhony.gutierrez@amd.com            return new AtomicOpDec<c0>();
38611692Santhony.gutierrez@amd.com        } else if (isAtomicMax()) {
38711308Santhony.gutierrez@amd.com            return new AtomicOpMax<c0>(*reg0);
38811692Santhony.gutierrez@amd.com        } else if (isAtomicMin()) {
38911308Santhony.gutierrez@amd.com            return new AtomicOpMin<c0>(*reg0);
39011692Santhony.gutierrez@amd.com        } else {
39111692Santhony.gutierrez@amd.com            fatal("Unrecognized atomic operation");
39211308Santhony.gutierrez@amd.com        }
39311308Santhony.gutierrez@amd.com    }
39411308Santhony.gutierrez@amd.com
39511308Santhony.gutierrez@amd.com    void
39612748Sgiacomo.travaglini@arm.com    setRequestFlags(RequestPtr req, bool setMemOrder=true)
39711308Santhony.gutierrez@amd.com    {
39811308Santhony.gutierrez@amd.com        // currently these are the easy scopes to deduce
39911692Santhony.gutierrez@amd.com        if (isPrivateSeg()) {
40011308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::PRIVATE_SEGMENT);
40111692Santhony.gutierrez@amd.com        } else if (isSpillSeg()) {
40211308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::SPILL_SEGMENT);
40311692Santhony.gutierrez@amd.com        } else if (isGlobalSeg()) {
40411308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::GLOBAL_SEGMENT);
40511692Santhony.gutierrez@amd.com        } else if (isReadOnlySeg()) {
40611308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::READONLY_SEGMENT);
40711692Santhony.gutierrez@amd.com        } else if (isGroupSeg()) {
40811308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::GROUP_SEGMENT);
40911692Santhony.gutierrez@amd.com        } else if (isFlat()) {
41011308Santhony.gutierrez@amd.com            // TODO: translate to correct scope
41111308Santhony.gutierrez@amd.com            assert(false);
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