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