gpu_dyn_inst.hh revision 11308
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_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/GenericMemoryOrder.hh"
4311308Santhony.gutierrez@amd.com#include "enums/GenericMemoryScope.hh"
4411308Santhony.gutierrez@amd.com#include "enums/MemOpType.hh"
4511308Santhony.gutierrez@amd.com#include "enums/MemType.hh"
4611308Santhony.gutierrez@amd.com#include "enums/OpType.hh"
4711308Santhony.gutierrez@amd.com#include "enums/StorageClassType.hh"
4811308Santhony.gutierrez@amd.com#include "gpu-compute/compute_unit.hh"
4911308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_exec_context.hh"
5011308Santhony.gutierrez@amd.com
5111308Santhony.gutierrez@amd.comclass GPUStaticInst;
5211308Santhony.gutierrez@amd.com
5311308Santhony.gutierrez@amd.comtemplate<typename T>
5411308Santhony.gutierrez@amd.comclass AtomicOpAnd : public TypedAtomicOpFunctor<T>
5511308Santhony.gutierrez@amd.com{
5611308Santhony.gutierrez@amd.com  public:
5711308Santhony.gutierrez@amd.com    T a;
5811308Santhony.gutierrez@amd.com
5911308Santhony.gutierrez@amd.com    AtomicOpAnd(T _a) : a(_a) { }
6011308Santhony.gutierrez@amd.com    void execute(T *b) { *b &= a; }
6111308Santhony.gutierrez@amd.com};
6211308Santhony.gutierrez@amd.com
6311308Santhony.gutierrez@amd.comtemplate<typename T>
6411308Santhony.gutierrez@amd.comclass AtomicOpOr : public TypedAtomicOpFunctor<T>
6511308Santhony.gutierrez@amd.com{
6611308Santhony.gutierrez@amd.com  public:
6711308Santhony.gutierrez@amd.com    T a;
6811308Santhony.gutierrez@amd.com    AtomicOpOr(T _a) : a(_a) { }
6911308Santhony.gutierrez@amd.com    void execute(T *b) { *b |= a; }
7011308Santhony.gutierrez@amd.com};
7111308Santhony.gutierrez@amd.com
7211308Santhony.gutierrez@amd.comtemplate<typename T>
7311308Santhony.gutierrez@amd.comclass AtomicOpXor : public TypedAtomicOpFunctor<T>
7411308Santhony.gutierrez@amd.com{
7511308Santhony.gutierrez@amd.com  public:
7611308Santhony.gutierrez@amd.com    T a;
7711308Santhony.gutierrez@amd.com    AtomicOpXor(T _a) : a(_a) {}
7811308Santhony.gutierrez@amd.com    void execute(T *b) { *b ^= 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    }
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; }
11711308Santhony.gutierrez@amd.com};
11811308Santhony.gutierrez@amd.com
11911308Santhony.gutierrez@amd.comtemplate<typename T>
12011308Santhony.gutierrez@amd.comclass AtomicOpAdd : public TypedAtomicOpFunctor<T>
12111308Santhony.gutierrez@amd.com{
12211308Santhony.gutierrez@amd.com  public:
12311308Santhony.gutierrez@amd.com    T a;
12411308Santhony.gutierrez@amd.com    AtomicOpAdd(T _a) : a(_a) { }
12511308Santhony.gutierrez@amd.com    void execute(T *b) { *b += a; }
12611308Santhony.gutierrez@amd.com};
12711308Santhony.gutierrez@amd.com
12811308Santhony.gutierrez@amd.comtemplate<typename T>
12911308Santhony.gutierrez@amd.comclass AtomicOpSub : public TypedAtomicOpFunctor<T>
13011308Santhony.gutierrez@amd.com{
13111308Santhony.gutierrez@amd.com  public:
13211308Santhony.gutierrez@amd.com    T a;
13311308Santhony.gutierrez@amd.com    AtomicOpSub(T _a) : a(_a) { }
13411308Santhony.gutierrez@amd.com    void execute(T *b) { *b -= a; }
13511308Santhony.gutierrez@amd.com};
13611308Santhony.gutierrez@amd.com
13711308Santhony.gutierrez@amd.comtemplate<typename T>
13811308Santhony.gutierrez@amd.comclass AtomicOpInc : public TypedAtomicOpFunctor<T>
13911308Santhony.gutierrez@amd.com{
14011308Santhony.gutierrez@amd.com  public:
14111308Santhony.gutierrez@amd.com    AtomicOpInc() { }
14211308Santhony.gutierrez@amd.com    void execute(T *b) { *b += 1; }
14311308Santhony.gutierrez@amd.com};
14411308Santhony.gutierrez@amd.com
14511308Santhony.gutierrez@amd.comtemplate<typename T>
14611308Santhony.gutierrez@amd.comclass AtomicOpDec : public TypedAtomicOpFunctor<T>
14711308Santhony.gutierrez@amd.com{
14811308Santhony.gutierrez@amd.com  public:
14911308Santhony.gutierrez@amd.com    AtomicOpDec() {}
15011308Santhony.gutierrez@amd.com    void execute(T *b) { *b -= 1; }
15111308Santhony.gutierrez@amd.com};
15211308Santhony.gutierrez@amd.com
15311308Santhony.gutierrez@amd.comtemplate<typename T>
15411308Santhony.gutierrez@amd.comclass AtomicOpMax : public TypedAtomicOpFunctor<T>
15511308Santhony.gutierrez@amd.com{
15611308Santhony.gutierrez@amd.com  public:
15711308Santhony.gutierrez@amd.com    T a;
15811308Santhony.gutierrez@amd.com    AtomicOpMax(T _a) : a(_a) { }
15911308Santhony.gutierrez@amd.com
16011308Santhony.gutierrez@amd.com    void
16111308Santhony.gutierrez@amd.com    execute(T *b)
16211308Santhony.gutierrez@amd.com    {
16311308Santhony.gutierrez@amd.com        if (a > *b)
16411308Santhony.gutierrez@amd.com            *b = a;
16511308Santhony.gutierrez@amd.com    }
16611308Santhony.gutierrez@amd.com};
16711308Santhony.gutierrez@amd.com
16811308Santhony.gutierrez@amd.comtemplate<typename T>
16911308Santhony.gutierrez@amd.comclass AtomicOpMin : public TypedAtomicOpFunctor<T>
17011308Santhony.gutierrez@amd.com{
17111308Santhony.gutierrez@amd.com  public:
17211308Santhony.gutierrez@amd.com    T a;
17311308Santhony.gutierrez@amd.com    AtomicOpMin(T _a) : a(_a) {}
17411308Santhony.gutierrez@amd.com
17511308Santhony.gutierrez@amd.com    void
17611308Santhony.gutierrez@amd.com    execute(T *b)
17711308Santhony.gutierrez@amd.com    {
17811308Santhony.gutierrez@amd.com        if (a < *b)
17911308Santhony.gutierrez@amd.com            *b = a;
18011308Santhony.gutierrez@amd.com    }
18111308Santhony.gutierrez@amd.com};
18211308Santhony.gutierrez@amd.com
18311308Santhony.gutierrez@amd.com#define MO_A(a) ((a)>=Enums::MO_AAND && (a)<=Enums::MO_AMIN)
18411308Santhony.gutierrez@amd.com#define MO_ANR(a) ((a)>=Enums::MO_ANRAND && (a)<=Enums::MO_ANRMIN)
18511308Santhony.gutierrez@amd.com#define MO_H(a) ((a)>=Enums::MO_HAND && (a)<=Enums::MO_HMIN)
18611308Santhony.gutierrez@amd.com
18711308Santhony.gutierrez@amd.comtypedef enum
18811308Santhony.gutierrez@amd.com{
18911308Santhony.gutierrez@amd.com    VT_32,
19011308Santhony.gutierrez@amd.com    VT_64,
19111308Santhony.gutierrez@amd.com} vgpr_type;
19211308Santhony.gutierrez@amd.com
19311308Santhony.gutierrez@amd.comtypedef enum
19411308Santhony.gutierrez@amd.com{
19511308Santhony.gutierrez@amd.com    SEG_PRIVATE,
19611308Santhony.gutierrez@amd.com    SEG_SPILL,
19711308Santhony.gutierrez@amd.com    SEG_GLOBAL,
19811308Santhony.gutierrez@amd.com    SEG_SHARED,
19911308Santhony.gutierrez@amd.com    SEG_READONLY,
20011308Santhony.gutierrez@amd.com    SEG_FLAT
20111308Santhony.gutierrez@amd.com} seg_type;
20211308Santhony.gutierrez@amd.com
20311308Santhony.gutierrez@amd.comclass GPUDynInst : public GPUExecContext
20411308Santhony.gutierrez@amd.com{
20511308Santhony.gutierrez@amd.com  public:
20611308Santhony.gutierrez@amd.com    GPUDynInst(ComputeUnit *_cu, Wavefront *_wf, GPUStaticInst *_staticInst,
20711308Santhony.gutierrez@amd.com               uint64_t instSeqNum);
20811308Santhony.gutierrez@amd.com
20911308Santhony.gutierrez@amd.com    void execute();
21011308Santhony.gutierrez@amd.com    int numSrcRegOperands();
21111308Santhony.gutierrez@amd.com    int numDstRegOperands();
21211308Santhony.gutierrez@amd.com    int getNumOperands();
21311308Santhony.gutierrez@amd.com    bool isVectorRegister(int operandIdx);
21411308Santhony.gutierrez@amd.com    bool isScalarRegister(int operandIdx);
21511308Santhony.gutierrez@amd.com    int getRegisterIndex(int operandIdx);
21611308Santhony.gutierrez@amd.com    int getOperandSize(int operandIdx);
21711308Santhony.gutierrez@amd.com    bool isDstOperand(int operandIdx);
21811308Santhony.gutierrez@amd.com    bool isSrcOperand(int operandIdx);
21911308Santhony.gutierrez@amd.com    bool isArgLoad();
22011308Santhony.gutierrez@amd.com
22111308Santhony.gutierrez@amd.com    const std::string &disassemble() const;
22211308Santhony.gutierrez@amd.com
22311308Santhony.gutierrez@amd.com    uint64_t seqNum() const;
22411308Santhony.gutierrez@amd.com
22511308Santhony.gutierrez@amd.com    Enums::OpType opType();
22611308Santhony.gutierrez@amd.com    Enums::StorageClassType executedAs();
22711308Santhony.gutierrez@amd.com
22811308Santhony.gutierrez@amd.com    // The address of the memory operation
22911308Santhony.gutierrez@amd.com    Addr addr[VSZ];
23011308Santhony.gutierrez@amd.com    Addr pAddr;
23111308Santhony.gutierrez@amd.com
23211308Santhony.gutierrez@amd.com    // The data to get written
23311308Santhony.gutierrez@amd.com    uint8_t d_data[VSZ * 16];
23411308Santhony.gutierrez@amd.com    // Additional data (for atomics)
23511308Santhony.gutierrez@amd.com    uint8_t a_data[VSZ * 8];
23611308Santhony.gutierrez@amd.com    // Additional data (for atomics)
23711308Santhony.gutierrez@amd.com    uint8_t x_data[VSZ * 8];
23811308Santhony.gutierrez@amd.com    // The execution mask
23911308Santhony.gutierrez@amd.com    VectorMask exec_mask;
24011308Santhony.gutierrez@amd.com
24111308Santhony.gutierrez@amd.com    // The memory type (M_U32, M_S32, ...)
24211308Santhony.gutierrez@amd.com    Enums::MemType m_type;
24311308Santhony.gutierrez@amd.com    // The memory operation (MO_LD, MO_ST, ...)
24411308Santhony.gutierrez@amd.com    Enums::MemOpType m_op;
24511308Santhony.gutierrez@amd.com    Enums::GenericMemoryOrder memoryOrder;
24611308Santhony.gutierrez@amd.com
24711308Santhony.gutierrez@amd.com    // Scope of the request
24811308Santhony.gutierrez@amd.com    Enums::GenericMemoryScope scope;
24911308Santhony.gutierrez@amd.com    // The memory segment (SEG_SHARED, SEG_GLOBAL, ...)
25011308Santhony.gutierrez@amd.com    seg_type s_type;
25111308Santhony.gutierrez@amd.com    // The equivalency class
25211308Santhony.gutierrez@amd.com    int equiv;
25311308Santhony.gutierrez@amd.com    // The return VGPR type (VT_32 or VT_64)
25411308Santhony.gutierrez@amd.com    vgpr_type v_type;
25511308Santhony.gutierrez@amd.com    // Number of VGPR's accessed (1, 2, or 4)
25611308Santhony.gutierrez@amd.com    int n_reg;
25711308Santhony.gutierrez@amd.com    // The return VGPR index
25811308Santhony.gutierrez@amd.com    int dst_reg;
25911308Santhony.gutierrez@amd.com    // There can be max 4 dest regs>
26011308Santhony.gutierrez@amd.com    int dst_reg_vec[4];
26111308Santhony.gutierrez@amd.com    // SIMD where the WF of the memory instruction has been mapped to
26211308Santhony.gutierrez@amd.com    int simdId;
26311308Santhony.gutierrez@amd.com    // unique id of the WF where the memory instruction belongs to
26411308Santhony.gutierrez@amd.com    int wfDynId;
26511308Santhony.gutierrez@amd.com    // The kernel id of the requesting wf
26611308Santhony.gutierrez@amd.com    int kern_id;
26711308Santhony.gutierrez@amd.com    // The CU id of the requesting wf
26811308Santhony.gutierrez@amd.com    int cu_id;
26911308Santhony.gutierrez@amd.com    // HW slot id where the WF is mapped to inside a SIMD unit
27011308Santhony.gutierrez@amd.com    int wfSlotId;
27111308Santhony.gutierrez@amd.com    // execution pipeline id where the memory instruction has been scheduled
27211308Santhony.gutierrez@amd.com    int pipeId;
27311308Santhony.gutierrez@amd.com    // The execution time of this operation
27411308Santhony.gutierrez@amd.com    Tick time;
27511308Santhony.gutierrez@amd.com    // The latency of this operation
27611308Santhony.gutierrez@amd.com    WaitClass latency;
27711308Santhony.gutierrez@amd.com    // A list of bank conflicts for the 4 cycles.
27811308Santhony.gutierrez@amd.com    uint32_t bc[4];
27911308Santhony.gutierrez@amd.com
28011308Santhony.gutierrez@amd.com    // A pointer to ROM
28111308Santhony.gutierrez@amd.com    uint8_t *rom;
28211308Santhony.gutierrez@amd.com    // The size of the READONLY segment
28311308Santhony.gutierrez@amd.com    int sz_rom;
28411308Santhony.gutierrez@amd.com
28511308Santhony.gutierrez@amd.com    // Initiate the specified memory operation, by creating a
28611308Santhony.gutierrez@amd.com    // memory request and sending it off to the memory system.
28711308Santhony.gutierrez@amd.com    void initiateAcc(GPUDynInstPtr gpuDynInst);
28811308Santhony.gutierrez@amd.com
28911308Santhony.gutierrez@amd.com    void updateStats();
29011308Santhony.gutierrez@amd.com
29111308Santhony.gutierrez@amd.com    GPUStaticInst* staticInstruction() { return staticInst; }
29211308Santhony.gutierrez@amd.com
29311308Santhony.gutierrez@amd.com    // Is the instruction a scalar or vector op?
29411308Santhony.gutierrez@amd.com    bool scalarOp() const;
29511308Santhony.gutierrez@amd.com
29611308Santhony.gutierrez@amd.com    /*
29711308Santhony.gutierrez@amd.com     * Loads/stores/atomics may have acquire/release semantics associated
29811308Santhony.gutierrez@amd.com     * withthem. Some protocols want to see the acquire/release as separate
29911308Santhony.gutierrez@amd.com     * requests from the load/store/atomic. We implement that separation
30011308Santhony.gutierrez@amd.com     * using continuations (i.e., a function pointer with an object associated
30111308Santhony.gutierrez@amd.com     * with it). When, for example, the front-end generates a store with
30211308Santhony.gutierrez@amd.com     * release semantics, we will first issue a normal store and set the
30311308Santhony.gutierrez@amd.com     * continuation in the GPUDynInst to a function that generate a
30411308Santhony.gutierrez@amd.com     * release request. That continuation will be called when the normal
30511308Santhony.gutierrez@amd.com     * store completes (in ComputeUnit::DataPort::recvTimingResponse). The
30611308Santhony.gutierrez@amd.com     * continuation will be called in the context of the same GPUDynInst
30711308Santhony.gutierrez@amd.com     * that generated the initial store.
30811308Santhony.gutierrez@amd.com     */
30911308Santhony.gutierrez@amd.com    std::function<void(GPUStaticInst*, GPUDynInstPtr)> execContinuation;
31011308Santhony.gutierrez@amd.com
31111308Santhony.gutierrez@amd.com    // when true, call execContinuation when response arrives
31211308Santhony.gutierrez@amd.com    bool useContinuation;
31311308Santhony.gutierrez@amd.com
31411308Santhony.gutierrez@amd.com    template<typename c0> AtomicOpFunctor*
31511308Santhony.gutierrez@amd.com    makeAtomicOpFunctor(c0 *reg0, c0 *reg1, Enums::MemOpType op)
31611308Santhony.gutierrez@amd.com    {
31711308Santhony.gutierrez@amd.com        using namespace Enums;
31811308Santhony.gutierrez@amd.com
31911308Santhony.gutierrez@amd.com        switch(op) {
32011308Santhony.gutierrez@amd.com          case MO_AAND:
32111308Santhony.gutierrez@amd.com          case MO_ANRAND:
32211308Santhony.gutierrez@amd.com            return new AtomicOpAnd<c0>(*reg0);
32311308Santhony.gutierrez@amd.com          case MO_AOR:
32411308Santhony.gutierrez@amd.com          case MO_ANROR:
32511308Santhony.gutierrez@amd.com            return new AtomicOpOr<c0>(*reg0);
32611308Santhony.gutierrez@amd.com          case MO_AXOR:
32711308Santhony.gutierrez@amd.com          case MO_ANRXOR:
32811308Santhony.gutierrez@amd.com            return new AtomicOpXor<c0>(*reg0);
32911308Santhony.gutierrez@amd.com          case MO_ACAS:
33011308Santhony.gutierrez@amd.com          case MO_ANRCAS:
33111308Santhony.gutierrez@amd.com            return new AtomicOpCAS<c0>(*reg0, *reg1, cu);
33211308Santhony.gutierrez@amd.com          case MO_AEXCH:
33311308Santhony.gutierrez@amd.com          case MO_ANREXCH:
33411308Santhony.gutierrez@amd.com            return new AtomicOpExch<c0>(*reg0);
33511308Santhony.gutierrez@amd.com          case MO_AADD:
33611308Santhony.gutierrez@amd.com          case MO_ANRADD:
33711308Santhony.gutierrez@amd.com            return new AtomicOpAdd<c0>(*reg0);
33811308Santhony.gutierrez@amd.com          case MO_ASUB:
33911308Santhony.gutierrez@amd.com          case MO_ANRSUB:
34011308Santhony.gutierrez@amd.com            return new AtomicOpSub<c0>(*reg0);
34111308Santhony.gutierrez@amd.com          case MO_AINC:
34211308Santhony.gutierrez@amd.com          case MO_ANRINC:
34311308Santhony.gutierrez@amd.com            return new AtomicOpInc<c0>();
34411308Santhony.gutierrez@amd.com          case MO_ADEC:
34511308Santhony.gutierrez@amd.com          case MO_ANRDEC:
34611308Santhony.gutierrez@amd.com            return new AtomicOpDec<c0>();
34711308Santhony.gutierrez@amd.com          case MO_AMAX:
34811308Santhony.gutierrez@amd.com          case MO_ANRMAX:
34911308Santhony.gutierrez@amd.com            return new AtomicOpMax<c0>(*reg0);
35011308Santhony.gutierrez@amd.com          case MO_AMIN:
35111308Santhony.gutierrez@amd.com          case MO_ANRMIN:
35211308Santhony.gutierrez@amd.com            return new AtomicOpMin<c0>(*reg0);
35311308Santhony.gutierrez@amd.com          default:
35411308Santhony.gutierrez@amd.com            panic("Unrecognized atomic operation");
35511308Santhony.gutierrez@amd.com        }
35611308Santhony.gutierrez@amd.com    }
35711308Santhony.gutierrez@amd.com
35811308Santhony.gutierrez@amd.com    void
35911308Santhony.gutierrez@amd.com    setRequestFlags(Request *req, bool setMemOrder=true)
36011308Santhony.gutierrez@amd.com    {
36111308Santhony.gutierrez@amd.com        // currently these are the easy scopes to deduce
36211308Santhony.gutierrez@amd.com        switch (s_type) {
36311308Santhony.gutierrez@amd.com          case SEG_PRIVATE:
36411308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::PRIVATE_SEGMENT);
36511308Santhony.gutierrez@amd.com            break;
36611308Santhony.gutierrez@amd.com          case SEG_SPILL:
36711308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::SPILL_SEGMENT);
36811308Santhony.gutierrez@amd.com            break;
36911308Santhony.gutierrez@amd.com          case SEG_GLOBAL:
37011308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::GLOBAL_SEGMENT);
37111308Santhony.gutierrez@amd.com            break;
37211308Santhony.gutierrez@amd.com          case SEG_READONLY:
37311308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::READONLY_SEGMENT);
37411308Santhony.gutierrez@amd.com            break;
37511308Santhony.gutierrez@amd.com          case SEG_SHARED:
37611308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::GROUP_SEGMENT);
37711308Santhony.gutierrez@amd.com            break;
37811308Santhony.gutierrez@amd.com          case SEG_FLAT:
37911308Santhony.gutierrez@amd.com            // TODO: translate to correct scope
38011308Santhony.gutierrez@amd.com            assert(false);
38111308Santhony.gutierrez@amd.com          default:
38211308Santhony.gutierrez@amd.com            panic("Bad segment type");
38311308Santhony.gutierrez@amd.com            break;
38411308Santhony.gutierrez@amd.com        }
38511308Santhony.gutierrez@amd.com
38611308Santhony.gutierrez@amd.com        switch (scope) {
38711308Santhony.gutierrez@amd.com          case Enums::MEMORY_SCOPE_NONE:
38811308Santhony.gutierrez@amd.com          case Enums::MEMORY_SCOPE_WORKITEM:
38911308Santhony.gutierrez@amd.com            break;
39011308Santhony.gutierrez@amd.com          case Enums::MEMORY_SCOPE_WAVEFRONT:
39111308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::SCOPE_VALID |
39211308Santhony.gutierrez@amd.com                                        Request::WAVEFRONT_SCOPE);
39311308Santhony.gutierrez@amd.com            break;
39411308Santhony.gutierrez@amd.com          case Enums::MEMORY_SCOPE_WORKGROUP:
39511308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::SCOPE_VALID |
39611308Santhony.gutierrez@amd.com                                        Request::WORKGROUP_SCOPE);
39711308Santhony.gutierrez@amd.com            break;
39811308Santhony.gutierrez@amd.com          case Enums::MEMORY_SCOPE_DEVICE:
39911308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::SCOPE_VALID |
40011308Santhony.gutierrez@amd.com                                        Request::DEVICE_SCOPE);
40111308Santhony.gutierrez@amd.com            break;
40211308Santhony.gutierrez@amd.com          case Enums::MEMORY_SCOPE_SYSTEM:
40311308Santhony.gutierrez@amd.com            req->setMemSpaceConfigFlags(Request::SCOPE_VALID |
40411308Santhony.gutierrez@amd.com                                        Request::SYSTEM_SCOPE);
40511308Santhony.gutierrez@amd.com            break;
40611308Santhony.gutierrez@amd.com          default:
40711308Santhony.gutierrez@amd.com            panic("Bad scope type");
40811308Santhony.gutierrez@amd.com            break;
40911308Santhony.gutierrez@amd.com        }
41011308Santhony.gutierrez@amd.com
41111308Santhony.gutierrez@amd.com        if (setMemOrder) {
41211308Santhony.gutierrez@amd.com            // set acquire and release flags
41311308Santhony.gutierrez@amd.com            switch (memoryOrder){
41411308Santhony.gutierrez@amd.com              case Enums::MEMORY_ORDER_SC_ACQUIRE:
41511308Santhony.gutierrez@amd.com                req->setFlags(Request::ACQUIRE);
41611308Santhony.gutierrez@amd.com                break;
41711308Santhony.gutierrez@amd.com              case Enums::MEMORY_ORDER_SC_RELEASE:
41811308Santhony.gutierrez@amd.com                req->setFlags(Request::RELEASE);
41911308Santhony.gutierrez@amd.com                break;
42011308Santhony.gutierrez@amd.com              case Enums::MEMORY_ORDER_SC_ACQUIRE_RELEASE:
42111308Santhony.gutierrez@amd.com                req->setFlags(Request::ACQUIRE | Request::RELEASE);
42211308Santhony.gutierrez@amd.com                break;
42311308Santhony.gutierrez@amd.com              default:
42411308Santhony.gutierrez@amd.com                break;
42511308Santhony.gutierrez@amd.com            }
42611308Santhony.gutierrez@amd.com        }
42711308Santhony.gutierrez@amd.com
42811308Santhony.gutierrez@amd.com        // set atomic type
42911308Santhony.gutierrez@amd.com        // currently, the instruction genenerator only produces atomic return
43011308Santhony.gutierrez@amd.com        // but a magic instruction can produce atomic no return
43111308Santhony.gutierrez@amd.com        if (m_op == Enums::MO_AADD || m_op == Enums::MO_ASUB ||
43211308Santhony.gutierrez@amd.com            m_op == Enums::MO_AAND || m_op == Enums::MO_AOR ||
43311308Santhony.gutierrez@amd.com            m_op == Enums::MO_AXOR || m_op == Enums::MO_AMAX ||
43411308Santhony.gutierrez@amd.com            m_op == Enums::MO_AMIN || m_op == Enums::MO_AINC ||
43511308Santhony.gutierrez@amd.com            m_op == Enums::MO_ADEC || m_op == Enums::MO_AEXCH ||
43611308Santhony.gutierrez@amd.com            m_op == Enums::MO_ACAS) {
43711308Santhony.gutierrez@amd.com            req->setFlags(Request::ATOMIC_RETURN_OP);
43811308Santhony.gutierrez@amd.com        } else if (m_op == Enums::MO_ANRADD || m_op == Enums::MO_ANRSUB ||
43911308Santhony.gutierrez@amd.com                   m_op == Enums::MO_ANRAND || m_op == Enums::MO_ANROR ||
44011308Santhony.gutierrez@amd.com                   m_op == Enums::MO_ANRXOR || m_op == Enums::MO_ANRMAX ||
44111308Santhony.gutierrez@amd.com                   m_op == Enums::MO_ANRMIN || m_op == Enums::MO_ANRINC ||
44211308Santhony.gutierrez@amd.com                   m_op == Enums::MO_ANRDEC || m_op == Enums::MO_ANREXCH ||
44311308Santhony.gutierrez@amd.com                   m_op == Enums::MO_ANRCAS) {
44411308Santhony.gutierrez@amd.com            req->setFlags(Request::ATOMIC_NO_RETURN_OP);
44511308Santhony.gutierrez@amd.com        }
44611308Santhony.gutierrez@amd.com    }
44711308Santhony.gutierrez@amd.com
44811308Santhony.gutierrez@amd.com    // Map returned packets and the addresses they satisfy with which lane they
44911308Santhony.gutierrez@amd.com    // were requested from
45011308Santhony.gutierrez@amd.com    typedef std::unordered_map<Addr, std::vector<int>> StatusVector;
45111308Santhony.gutierrez@amd.com    StatusVector memStatusVector;
45211308Santhony.gutierrez@amd.com
45311308Santhony.gutierrez@amd.com    // Track the status of memory requests per lane, a bit per lane
45411308Santhony.gutierrez@amd.com    VectorMask statusBitVector;
45511308Santhony.gutierrez@amd.com    // for ld_v# or st_v#
45611308Santhony.gutierrez@amd.com    std::vector<int> statusVector;
45711308Santhony.gutierrez@amd.com    std::vector<int> tlbHitLevel;
45811308Santhony.gutierrez@amd.com
45911308Santhony.gutierrez@amd.com  private:
46011308Santhony.gutierrez@amd.com    GPUStaticInst *staticInst;
46111308Santhony.gutierrez@amd.com    uint64_t _seqNum;
46211308Santhony.gutierrez@amd.com};
46311308Santhony.gutierrez@amd.com
46411308Santhony.gutierrez@amd.com#endif // __GPU_DYN_INST_HH__
465