111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2013-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: Marc Orr
3411308Santhony.gutierrez@amd.com */
3511308Santhony.gutierrez@amd.com
3611308Santhony.gutierrez@amd.com#include <csignal>
3711308Santhony.gutierrez@amd.com
3811308Santhony.gutierrez@amd.com#include "arch/hsail/insts/decl.hh"
3911308Santhony.gutierrez@amd.com#include "arch/hsail/insts/mem.hh"
4011308Santhony.gutierrez@amd.com
4111308Santhony.gutierrez@amd.comnamespace HsailISA
4211308Santhony.gutierrez@amd.com{
4311308Santhony.gutierrez@amd.com    // Pseudo (or magic) instructions are overloaded on the hsail call
4411308Santhony.gutierrez@amd.com    // instruction, because of its flexible parameter signature.
4511308Santhony.gutierrez@amd.com
4611308Santhony.gutierrez@amd.com    // To add a new magic instruction:
4711308Santhony.gutierrez@amd.com    // 1. Add an entry to the enum.
4811308Santhony.gutierrez@amd.com    // 2. Implement it in the switch statement below (Call::exec).
4911308Santhony.gutierrez@amd.com    // 3. Add a utility function to hsa/hsail-gpu-compute/util/magicinst.h,
5011308Santhony.gutierrez@amd.com    //    so its easy to call from an OpenCL kernel.
5111308Santhony.gutierrez@amd.com
5211308Santhony.gutierrez@amd.com    // This enum should be identical to the enum in
5311308Santhony.gutierrez@amd.com    // hsa/hsail-gpu-compute/util/magicinst.h
5411308Santhony.gutierrez@amd.com    enum
5511308Santhony.gutierrez@amd.com    {
5611308Santhony.gutierrez@amd.com        MAGIC_PRINT_WF_32 = 0,
5711308Santhony.gutierrez@amd.com        MAGIC_PRINT_WF_64,
5811308Santhony.gutierrez@amd.com        MAGIC_PRINT_LANE,
5911308Santhony.gutierrez@amd.com        MAGIC_PRINT_LANE_64,
6011308Santhony.gutierrez@amd.com        MAGIC_PRINT_WF_FLOAT,
6111308Santhony.gutierrez@amd.com        MAGIC_SIM_BREAK,
6211308Santhony.gutierrez@amd.com        MAGIC_PREF_SUM,
6311308Santhony.gutierrez@amd.com        MAGIC_REDUCTION,
6411308Santhony.gutierrez@amd.com        MAGIC_MASKLANE_LOWER,
6511308Santhony.gutierrez@amd.com        MAGIC_MASKLANE_UPPER,
6611308Santhony.gutierrez@amd.com        MAGIC_JOIN_WF_BAR,
6711308Santhony.gutierrez@amd.com        MAGIC_WAIT_WF_BAR,
6811308Santhony.gutierrez@amd.com        MAGIC_PANIC,
6911308Santhony.gutierrez@amd.com        MAGIC_ATOMIC_NR_ADD_GLOBAL_U32_REG,
7011308Santhony.gutierrez@amd.com        MAGIC_ATOMIC_NR_ADD_GROUP_U32_REG,
7111308Santhony.gutierrez@amd.com        MAGIC_LOAD_GLOBAL_U32_REG,
7211308Santhony.gutierrez@amd.com        MAGIC_XACT_CAS_LD,
7311308Santhony.gutierrez@amd.com        MAGIC_MOST_SIG_THD,
7411308Santhony.gutierrez@amd.com        MAGIC_MOST_SIG_BROADCAST,
7511308Santhony.gutierrez@amd.com        MAGIC_PRINT_WFID_32,
7611308Santhony.gutierrez@amd.com        MAGIC_PRINT_WFID_64
7711308Santhony.gutierrez@amd.com    };
7811308Santhony.gutierrez@amd.com
7911308Santhony.gutierrez@amd.com    void
8011308Santhony.gutierrez@amd.com    Call::execPseudoInst(Wavefront *w, GPUDynInstPtr gpuDynInst)
8111308Santhony.gutierrez@amd.com    {
8211639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
8311308Santhony.gutierrez@amd.com
8411308Santhony.gutierrez@amd.com        int op = 0;
8511308Santhony.gutierrez@amd.com        bool got_op = false;
8611308Santhony.gutierrez@amd.com
8711534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
8811308Santhony.gutierrez@amd.com            if (mask[lane]) {
8911308Santhony.gutierrez@amd.com                int src_val0 = src1.get<int>(w, lane, 0);
9011308Santhony.gutierrez@amd.com                if (got_op) {
9111308Santhony.gutierrez@amd.com                    if (src_val0 != op) {
9211308Santhony.gutierrez@amd.com                        fatal("Multiple magic instructions per PC not "
9311308Santhony.gutierrez@amd.com                              "supported\n");
9411308Santhony.gutierrez@amd.com                    }
9511308Santhony.gutierrez@amd.com                } else {
9611308Santhony.gutierrez@amd.com                    op = src_val0;
9711308Santhony.gutierrez@amd.com                    got_op = true;
9811308Santhony.gutierrez@amd.com                }
9911308Santhony.gutierrez@amd.com            }
10011308Santhony.gutierrez@amd.com        }
10111308Santhony.gutierrez@amd.com
10211308Santhony.gutierrez@amd.com        switch(op) {
10311308Santhony.gutierrez@amd.com          case MAGIC_PRINT_WF_32:
10411308Santhony.gutierrez@amd.com            MagicPrintWF32(w);
10511308Santhony.gutierrez@amd.com            break;
10611308Santhony.gutierrez@amd.com          case MAGIC_PRINT_WF_64:
10711308Santhony.gutierrez@amd.com            MagicPrintWF64(w);
10811308Santhony.gutierrez@amd.com            break;
10911308Santhony.gutierrez@amd.com          case MAGIC_PRINT_LANE:
11011308Santhony.gutierrez@amd.com            MagicPrintLane(w);
11111308Santhony.gutierrez@amd.com            break;
11211308Santhony.gutierrez@amd.com          case MAGIC_PRINT_LANE_64:
11311308Santhony.gutierrez@amd.com            MagicPrintLane64(w);
11411308Santhony.gutierrez@amd.com            break;
11511308Santhony.gutierrez@amd.com          case MAGIC_PRINT_WF_FLOAT:
11611308Santhony.gutierrez@amd.com            MagicPrintWFFloat(w);
11711308Santhony.gutierrez@amd.com            break;
11811308Santhony.gutierrez@amd.com          case MAGIC_SIM_BREAK:
11911308Santhony.gutierrez@amd.com            MagicSimBreak(w);
12011308Santhony.gutierrez@amd.com            break;
12111308Santhony.gutierrez@amd.com          case MAGIC_PREF_SUM:
12211308Santhony.gutierrez@amd.com            MagicPrefixSum(w);
12311308Santhony.gutierrez@amd.com            break;
12411308Santhony.gutierrez@amd.com          case MAGIC_REDUCTION:
12511308Santhony.gutierrez@amd.com            MagicReduction(w);
12611308Santhony.gutierrez@amd.com            break;
12711308Santhony.gutierrez@amd.com          case MAGIC_MASKLANE_LOWER:
12811308Santhony.gutierrez@amd.com            MagicMaskLower(w);
12911308Santhony.gutierrez@amd.com            break;
13011308Santhony.gutierrez@amd.com          case MAGIC_MASKLANE_UPPER:
13111308Santhony.gutierrez@amd.com            MagicMaskUpper(w);
13211308Santhony.gutierrez@amd.com            break;
13311308Santhony.gutierrez@amd.com          case MAGIC_JOIN_WF_BAR:
13411308Santhony.gutierrez@amd.com            MagicJoinWFBar(w);
13511308Santhony.gutierrez@amd.com            break;
13611308Santhony.gutierrez@amd.com          case MAGIC_WAIT_WF_BAR:
13711308Santhony.gutierrez@amd.com            MagicWaitWFBar(w);
13811308Santhony.gutierrez@amd.com            break;
13911308Santhony.gutierrez@amd.com          case MAGIC_PANIC:
14011308Santhony.gutierrez@amd.com            MagicPanic(w);
14111308Santhony.gutierrez@amd.com            break;
14211308Santhony.gutierrez@amd.com
14311308Santhony.gutierrez@amd.com          // atomic instructions
14411308Santhony.gutierrez@amd.com          case MAGIC_ATOMIC_NR_ADD_GLOBAL_U32_REG:
14511308Santhony.gutierrez@amd.com            MagicAtomicNRAddGlobalU32Reg(w, gpuDynInst);
14611308Santhony.gutierrez@amd.com            break;
14711308Santhony.gutierrez@amd.com
14811308Santhony.gutierrez@amd.com          case MAGIC_ATOMIC_NR_ADD_GROUP_U32_REG:
14911308Santhony.gutierrez@amd.com            MagicAtomicNRAddGroupU32Reg(w, gpuDynInst);
15011308Santhony.gutierrez@amd.com            break;
15111308Santhony.gutierrez@amd.com
15211308Santhony.gutierrez@amd.com          case MAGIC_LOAD_GLOBAL_U32_REG:
15311308Santhony.gutierrez@amd.com            MagicLoadGlobalU32Reg(w, gpuDynInst);
15411308Santhony.gutierrez@amd.com            break;
15511308Santhony.gutierrez@amd.com
15611308Santhony.gutierrez@amd.com          case MAGIC_XACT_CAS_LD:
15711308Santhony.gutierrez@amd.com            MagicXactCasLd(w);
15811308Santhony.gutierrez@amd.com            break;
15911308Santhony.gutierrez@amd.com
16011308Santhony.gutierrez@amd.com          case MAGIC_MOST_SIG_THD:
16111308Santhony.gutierrez@amd.com            MagicMostSigThread(w);
16211308Santhony.gutierrez@amd.com            break;
16311308Santhony.gutierrez@amd.com
16411308Santhony.gutierrez@amd.com          case MAGIC_MOST_SIG_BROADCAST:
16511308Santhony.gutierrez@amd.com            MagicMostSigBroadcast(w);
16611308Santhony.gutierrez@amd.com            break;
16711308Santhony.gutierrez@amd.com
16811308Santhony.gutierrez@amd.com          case MAGIC_PRINT_WFID_32:
16911308Santhony.gutierrez@amd.com            MagicPrintWF32ID(w);
17011308Santhony.gutierrez@amd.com            break;
17111308Santhony.gutierrez@amd.com
17211308Santhony.gutierrez@amd.com          case MAGIC_PRINT_WFID_64:
17311308Santhony.gutierrez@amd.com            MagicPrintWFID64(w);
17411308Santhony.gutierrez@amd.com            break;
17511308Santhony.gutierrez@amd.com
17611308Santhony.gutierrez@amd.com          default: fatal("unrecognized magic instruction: %d\n", op);
17711308Santhony.gutierrez@amd.com        }
17811308Santhony.gutierrez@amd.com    }
17911308Santhony.gutierrez@amd.com
18011308Santhony.gutierrez@amd.com    void
18111308Santhony.gutierrez@amd.com    Call::MagicPrintLane(Wavefront *w)
18211308Santhony.gutierrez@amd.com    {
18311308Santhony.gutierrez@amd.com    #if TRACING_ON
18411639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
18511534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
18611308Santhony.gutierrez@amd.com            if (mask[lane]) {
18711308Santhony.gutierrez@amd.com                int src_val1 = src1.get<int>(w, lane, 1);
18811308Santhony.gutierrez@amd.com                int src_val2 = src1.get<int>(w, lane, 2);
18911308Santhony.gutierrez@amd.com                if (src_val2) {
19011308Santhony.gutierrez@amd.com                    DPRINTFN("krl_prt (%s): CU%d, WF[%d][%d], lane %d: 0x%x\n",
19111308Santhony.gutierrez@amd.com                             disassemble(), w->computeUnit->cu_id, w->simdId,
19211308Santhony.gutierrez@amd.com                             w->wfSlotId, lane, src_val1);
19311308Santhony.gutierrez@amd.com                } else {
19411308Santhony.gutierrez@amd.com                    DPRINTFN("krl_prt (%s): CU%d, WF[%d][%d], lane %d: %d\n",
19511308Santhony.gutierrez@amd.com                             disassemble(), w->computeUnit->cu_id, w->simdId,
19611308Santhony.gutierrez@amd.com                             w->wfSlotId, lane, src_val1);
19711308Santhony.gutierrez@amd.com                }
19811308Santhony.gutierrez@amd.com            }
19911308Santhony.gutierrez@amd.com        }
20011308Santhony.gutierrez@amd.com    #endif
20111308Santhony.gutierrez@amd.com    }
20211308Santhony.gutierrez@amd.com
20311308Santhony.gutierrez@amd.com    void
20411308Santhony.gutierrez@amd.com    Call::MagicPrintLane64(Wavefront *w)
20511308Santhony.gutierrez@amd.com    {
20611308Santhony.gutierrez@amd.com    #if TRACING_ON
20711639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
20811534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
20911308Santhony.gutierrez@amd.com            if (mask[lane]) {
21011308Santhony.gutierrez@amd.com                int64_t src_val1 = src1.get<int64_t>(w, lane, 1);
21111308Santhony.gutierrez@amd.com                int src_val2 = src1.get<int>(w, lane, 2);
21211308Santhony.gutierrez@amd.com                if (src_val2) {
21311308Santhony.gutierrez@amd.com                    DPRINTFN("krl_prt (%s): CU%d, WF[%d][%d], lane %d: 0x%x\n",
21411308Santhony.gutierrez@amd.com                             disassemble(), w->computeUnit->cu_id, w->simdId,
21511308Santhony.gutierrez@amd.com                             w->wfSlotId, lane, src_val1);
21611308Santhony.gutierrez@amd.com                } else {
21711308Santhony.gutierrez@amd.com                    DPRINTFN("krl_prt (%s): CU%d, WF[%d][%d], lane %d: %d\n",
21811308Santhony.gutierrez@amd.com                             disassemble(), w->computeUnit->cu_id, w->simdId,
21911308Santhony.gutierrez@amd.com                             w->wfSlotId, lane, src_val1);
22011308Santhony.gutierrez@amd.com                }
22111308Santhony.gutierrez@amd.com            }
22211308Santhony.gutierrez@amd.com        }
22311308Santhony.gutierrez@amd.com    #endif
22411308Santhony.gutierrez@amd.com    }
22511308Santhony.gutierrez@amd.com
22611308Santhony.gutierrez@amd.com    void
22711308Santhony.gutierrez@amd.com    Call::MagicPrintWF32(Wavefront *w)
22811308Santhony.gutierrez@amd.com    {
22911308Santhony.gutierrez@amd.com    #if TRACING_ON
23011639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
23111308Santhony.gutierrez@amd.com        std::string res_str;
23211308Santhony.gutierrez@amd.com        res_str = csprintf("krl_prt (%s)\n", disassemble());
23311308Santhony.gutierrez@amd.com
23411534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
23511308Santhony.gutierrez@amd.com            if (!(lane & 7)) {
23611308Santhony.gutierrez@amd.com                res_str += csprintf("DB%03d: ", (int)w->wfDynId);
23711308Santhony.gutierrez@amd.com            }
23811308Santhony.gutierrez@amd.com
23911308Santhony.gutierrez@amd.com            if (mask[lane]) {
24011308Santhony.gutierrez@amd.com                int src_val1 = src1.get<int>(w, lane, 1);
24111308Santhony.gutierrez@amd.com                int src_val2 = src1.get<int>(w, lane, 2);
24211308Santhony.gutierrez@amd.com
24311308Santhony.gutierrez@amd.com                if (src_val2) {
24411308Santhony.gutierrez@amd.com                    res_str += csprintf("%08x", src_val1);
24511308Santhony.gutierrez@amd.com                } else {
24611308Santhony.gutierrez@amd.com                    res_str += csprintf("%08d", src_val1);
24711308Santhony.gutierrez@amd.com                }
24811308Santhony.gutierrez@amd.com            } else {
24911308Santhony.gutierrez@amd.com                res_str += csprintf("xxxxxxxx");
25011308Santhony.gutierrez@amd.com            }
25111308Santhony.gutierrez@amd.com
25211308Santhony.gutierrez@amd.com            if ((lane & 7) == 7) {
25311308Santhony.gutierrez@amd.com                res_str += csprintf("\n");
25411308Santhony.gutierrez@amd.com            } else {
25511308Santhony.gutierrez@amd.com                res_str += csprintf(" ");
25611308Santhony.gutierrez@amd.com            }
25711308Santhony.gutierrez@amd.com        }
25811308Santhony.gutierrez@amd.com
25911308Santhony.gutierrez@amd.com        res_str += "\n\n";
26011308Santhony.gutierrez@amd.com        DPRINTFN(res_str.c_str());
26111308Santhony.gutierrez@amd.com    #endif
26211308Santhony.gutierrez@amd.com    }
26311308Santhony.gutierrez@amd.com
26411308Santhony.gutierrez@amd.com    void
26511308Santhony.gutierrez@amd.com    Call::MagicPrintWF32ID(Wavefront *w)
26611308Santhony.gutierrez@amd.com    {
26711308Santhony.gutierrez@amd.com    #if TRACING_ON
26811639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
26911308Santhony.gutierrez@amd.com        std::string res_str;
27011308Santhony.gutierrez@amd.com        int src_val3 = -1;
27111308Santhony.gutierrez@amd.com        res_str = csprintf("krl_prt (%s)\n", disassemble());
27211308Santhony.gutierrez@amd.com
27311534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
27411308Santhony.gutierrez@amd.com            if (!(lane & 7)) {
27511308Santhony.gutierrez@amd.com                res_str += csprintf("DB%03d: ", (int)w->wfDynId);
27611308Santhony.gutierrez@amd.com            }
27711308Santhony.gutierrez@amd.com
27811308Santhony.gutierrez@amd.com            if (mask[lane]) {
27911308Santhony.gutierrez@amd.com                int src_val1 = src1.get<int>(w, lane, 1);
28011308Santhony.gutierrez@amd.com                int src_val2 = src1.get<int>(w, lane, 2);
28111308Santhony.gutierrez@amd.com                src_val3 = src1.get<int>(w, lane, 3);
28211308Santhony.gutierrez@amd.com
28311308Santhony.gutierrez@amd.com                if (src_val2) {
28411308Santhony.gutierrez@amd.com                    res_str += csprintf("%08x", src_val1);
28511308Santhony.gutierrez@amd.com                } else {
28611308Santhony.gutierrez@amd.com                    res_str += csprintf("%08d", src_val1);
28711308Santhony.gutierrez@amd.com                }
28811308Santhony.gutierrez@amd.com            } else {
28911308Santhony.gutierrez@amd.com                res_str += csprintf("xxxxxxxx");
29011308Santhony.gutierrez@amd.com            }
29111308Santhony.gutierrez@amd.com
29211308Santhony.gutierrez@amd.com            if ((lane & 7) == 7) {
29311308Santhony.gutierrez@amd.com                res_str += csprintf("\n");
29411308Santhony.gutierrez@amd.com            } else {
29511308Santhony.gutierrez@amd.com                res_str += csprintf(" ");
29611308Santhony.gutierrez@amd.com            }
29711308Santhony.gutierrez@amd.com        }
29811308Santhony.gutierrez@amd.com
29911308Santhony.gutierrez@amd.com        res_str += "\n\n";
30011308Santhony.gutierrez@amd.com        if (w->wfDynId == src_val3) {
30111308Santhony.gutierrez@amd.com            DPRINTFN(res_str.c_str());
30211308Santhony.gutierrez@amd.com        }
30311308Santhony.gutierrez@amd.com    #endif
30411308Santhony.gutierrez@amd.com    }
30511308Santhony.gutierrez@amd.com
30611308Santhony.gutierrez@amd.com    void
30711308Santhony.gutierrez@amd.com    Call::MagicPrintWF64(Wavefront *w)
30811308Santhony.gutierrez@amd.com    {
30911308Santhony.gutierrez@amd.com    #if TRACING_ON
31011639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
31111308Santhony.gutierrez@amd.com        std::string res_str;
31211308Santhony.gutierrez@amd.com        res_str = csprintf("krl_prt (%s)\n", disassemble());
31311308Santhony.gutierrez@amd.com
31411534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
31511308Santhony.gutierrez@amd.com            if (!(lane & 3)) {
31611308Santhony.gutierrez@amd.com                res_str += csprintf("DB%03d: ", (int)w->wfDynId);
31711308Santhony.gutierrez@amd.com            }
31811308Santhony.gutierrez@amd.com
31911308Santhony.gutierrez@amd.com            if (mask[lane]) {
32011308Santhony.gutierrez@amd.com                int64_t src_val1 = src1.get<int64_t>(w, lane, 1);
32111308Santhony.gutierrez@amd.com                int src_val2 = src1.get<int>(w, lane, 2);
32211308Santhony.gutierrez@amd.com
32311308Santhony.gutierrez@amd.com                if (src_val2) {
32411308Santhony.gutierrez@amd.com                    res_str += csprintf("%016x", src_val1);
32511308Santhony.gutierrez@amd.com                } else {
32611308Santhony.gutierrez@amd.com                    res_str += csprintf("%016d", src_val1);
32711308Santhony.gutierrez@amd.com                }
32811308Santhony.gutierrez@amd.com            } else {
32911308Santhony.gutierrez@amd.com                res_str += csprintf("xxxxxxxxxxxxxxxx");
33011308Santhony.gutierrez@amd.com            }
33111308Santhony.gutierrez@amd.com
33211308Santhony.gutierrez@amd.com            if ((lane & 3) == 3) {
33311308Santhony.gutierrez@amd.com                res_str += csprintf("\n");
33411308Santhony.gutierrez@amd.com            } else {
33511308Santhony.gutierrez@amd.com                res_str += csprintf(" ");
33611308Santhony.gutierrez@amd.com            }
33711308Santhony.gutierrez@amd.com        }
33811308Santhony.gutierrez@amd.com
33911308Santhony.gutierrez@amd.com        res_str += "\n\n";
34011308Santhony.gutierrez@amd.com        DPRINTFN(res_str.c_str());
34111308Santhony.gutierrez@amd.com    #endif
34211308Santhony.gutierrez@amd.com    }
34311308Santhony.gutierrez@amd.com
34411308Santhony.gutierrez@amd.com    void
34511308Santhony.gutierrez@amd.com    Call::MagicPrintWFID64(Wavefront *w)
34611308Santhony.gutierrez@amd.com    {
34711308Santhony.gutierrez@amd.com    #if TRACING_ON
34811639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
34911308Santhony.gutierrez@amd.com        std::string res_str;
35011308Santhony.gutierrez@amd.com        int src_val3 = -1;
35111308Santhony.gutierrez@amd.com        res_str = csprintf("krl_prt (%s)\n", disassemble());
35211308Santhony.gutierrez@amd.com
35311534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
35411308Santhony.gutierrez@amd.com            if (!(lane & 3)) {
35511308Santhony.gutierrez@amd.com                res_str += csprintf("DB%03d: ", (int)w->wfDynId);
35611308Santhony.gutierrez@amd.com            }
35711308Santhony.gutierrez@amd.com
35811308Santhony.gutierrez@amd.com            if (mask[lane]) {
35911308Santhony.gutierrez@amd.com                int64_t src_val1 = src1.get<int64_t>(w, lane, 1);
36011308Santhony.gutierrez@amd.com                int src_val2 = src1.get<int>(w, lane, 2);
36111308Santhony.gutierrez@amd.com                src_val3 = src1.get<int>(w, lane, 3);
36211308Santhony.gutierrez@amd.com
36311308Santhony.gutierrez@amd.com                if (src_val2) {
36411308Santhony.gutierrez@amd.com                    res_str += csprintf("%016x", src_val1);
36511308Santhony.gutierrez@amd.com                } else {
36611308Santhony.gutierrez@amd.com                    res_str += csprintf("%016d", src_val1);
36711308Santhony.gutierrez@amd.com                }
36811308Santhony.gutierrez@amd.com            } else {
36911308Santhony.gutierrez@amd.com                res_str += csprintf("xxxxxxxxxxxxxxxx");
37011308Santhony.gutierrez@amd.com            }
37111308Santhony.gutierrez@amd.com
37211308Santhony.gutierrez@amd.com            if ((lane & 3) == 3) {
37311308Santhony.gutierrez@amd.com                res_str += csprintf("\n");
37411308Santhony.gutierrez@amd.com            } else {
37511308Santhony.gutierrez@amd.com                res_str += csprintf(" ");
37611308Santhony.gutierrez@amd.com            }
37711308Santhony.gutierrez@amd.com        }
37811308Santhony.gutierrez@amd.com
37911308Santhony.gutierrez@amd.com        res_str += "\n\n";
38011308Santhony.gutierrez@amd.com        if (w->wfDynId == src_val3) {
38111308Santhony.gutierrez@amd.com            DPRINTFN(res_str.c_str());
38211308Santhony.gutierrez@amd.com        }
38311308Santhony.gutierrez@amd.com    #endif
38411308Santhony.gutierrez@amd.com    }
38511308Santhony.gutierrez@amd.com
38611308Santhony.gutierrez@amd.com    void
38711308Santhony.gutierrez@amd.com    Call::MagicPrintWFFloat(Wavefront *w)
38811308Santhony.gutierrez@amd.com    {
38911308Santhony.gutierrez@amd.com    #if TRACING_ON
39011639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
39111308Santhony.gutierrez@amd.com        std::string res_str;
39211308Santhony.gutierrez@amd.com        res_str = csprintf("krl_prt (%s)\n", disassemble());
39311308Santhony.gutierrez@amd.com
39411534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
39511308Santhony.gutierrez@amd.com            if (!(lane & 7)) {
39611308Santhony.gutierrez@amd.com                res_str += csprintf("DB%03d: ", (int)w->wfDynId);
39711308Santhony.gutierrez@amd.com            }
39811308Santhony.gutierrez@amd.com
39911308Santhony.gutierrez@amd.com            if (mask[lane]) {
40011308Santhony.gutierrez@amd.com                float src_val1 = src1.get<float>(w, lane, 1);
40111308Santhony.gutierrez@amd.com                res_str += csprintf("%08f", src_val1);
40211308Santhony.gutierrez@amd.com            } else {
40311308Santhony.gutierrez@amd.com                res_str += csprintf("xxxxxxxx");
40411308Santhony.gutierrez@amd.com            }
40511308Santhony.gutierrez@amd.com
40611308Santhony.gutierrez@amd.com            if ((lane & 7) == 7) {
40711308Santhony.gutierrez@amd.com                res_str += csprintf("\n");
40811308Santhony.gutierrez@amd.com            } else {
40911308Santhony.gutierrez@amd.com                res_str += csprintf(" ");
41011308Santhony.gutierrez@amd.com            }
41111308Santhony.gutierrez@amd.com        }
41211308Santhony.gutierrez@amd.com
41311308Santhony.gutierrez@amd.com        res_str += "\n\n";
41411308Santhony.gutierrez@amd.com        DPRINTFN(res_str.c_str());
41511308Santhony.gutierrez@amd.com    #endif
41611308Santhony.gutierrez@amd.com    }
41711308Santhony.gutierrez@amd.com
41811308Santhony.gutierrez@amd.com    // raises a signal that GDB will catch
41911308Santhony.gutierrez@amd.com    // when done with the break, type "signal 0" in gdb to continue
42011308Santhony.gutierrez@amd.com    void
42111308Santhony.gutierrez@amd.com    Call::MagicSimBreak(Wavefront *w)
42211308Santhony.gutierrez@amd.com    {
42311308Santhony.gutierrez@amd.com        std::string res_str;
42411308Santhony.gutierrez@amd.com        // print out state for this wavefront and then break
42511308Santhony.gutierrez@amd.com        res_str = csprintf("Breakpoint encountered for wavefront %i\n",
42611308Santhony.gutierrez@amd.com                           w->wfSlotId);
42711308Santhony.gutierrez@amd.com
42811639Salexandru.dutu@amd.com        res_str += csprintf("  Kern ID: %i\n", w->kernId);
42911308Santhony.gutierrez@amd.com        res_str += csprintf("  Phase ID: %i\n", w->simdId);
43011308Santhony.gutierrez@amd.com        res_str += csprintf("  Executing on CU #%i\n", w->computeUnit->cu_id);
43111308Santhony.gutierrez@amd.com        res_str += csprintf("  Exec mask: ");
43211308Santhony.gutierrez@amd.com
43311534Sjohn.kalamatianos@amd.com        for (int i = w->computeUnit->wfSize() - 1; i >= 0; --i) {
43411308Santhony.gutierrez@amd.com            if (w->execMask(i))
43511308Santhony.gutierrez@amd.com                res_str += "1";
43611308Santhony.gutierrez@amd.com            else
43711308Santhony.gutierrez@amd.com                res_str += "0";
43811308Santhony.gutierrez@amd.com
43911308Santhony.gutierrez@amd.com            if ((i & 7) == 7)
44011308Santhony.gutierrez@amd.com                res_str += " ";
44111308Santhony.gutierrez@amd.com        }
44211308Santhony.gutierrez@amd.com
44311308Santhony.gutierrez@amd.com        res_str += csprintf("(0x%016llx)\n", w->execMask().to_ullong());
44411308Santhony.gutierrez@amd.com
44511308Santhony.gutierrez@amd.com        res_str += "\nHelpful debugging hints:\n";
44611308Santhony.gutierrez@amd.com        res_str += "   Check out w->s_reg / w->d_reg for register state\n";
44711308Santhony.gutierrez@amd.com
44811308Santhony.gutierrez@amd.com        res_str += "\n\n";
44911308Santhony.gutierrez@amd.com        DPRINTFN(res_str.c_str());
45011308Santhony.gutierrez@amd.com        fflush(stdout);
45111308Santhony.gutierrez@amd.com
45211308Santhony.gutierrez@amd.com        raise(SIGTRAP);
45311308Santhony.gutierrez@amd.com    }
45411308Santhony.gutierrez@amd.com
45511308Santhony.gutierrez@amd.com    void
45611308Santhony.gutierrez@amd.com    Call::MagicPrefixSum(Wavefront *w)
45711308Santhony.gutierrez@amd.com    {
45811639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
45911308Santhony.gutierrez@amd.com        int res = 0;
46011308Santhony.gutierrez@amd.com
46111534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
46211308Santhony.gutierrez@amd.com            if (mask[lane]) {
46311308Santhony.gutierrez@amd.com                int src_val1 = src1.get<int>(w, lane, 1);
46411308Santhony.gutierrez@amd.com                dest.set<int>(w, lane, res);
46511308Santhony.gutierrez@amd.com                res += src_val1;
46611308Santhony.gutierrez@amd.com            }
46711308Santhony.gutierrez@amd.com        }
46811308Santhony.gutierrez@amd.com    }
46911308Santhony.gutierrez@amd.com
47011308Santhony.gutierrez@amd.com    void
47111308Santhony.gutierrez@amd.com    Call::MagicReduction(Wavefront *w)
47211308Santhony.gutierrez@amd.com    {
47311308Santhony.gutierrez@amd.com        // reduction magic instruction
47411308Santhony.gutierrez@amd.com        //   The reduction instruction takes up to 64 inputs (one from
47511308Santhony.gutierrez@amd.com        //   each thread in a WF) and sums them. It returns the sum to
47611308Santhony.gutierrez@amd.com        //   each thread in the WF.
47711639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
47811308Santhony.gutierrez@amd.com        int res = 0;
47911308Santhony.gutierrez@amd.com
48011534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
48111308Santhony.gutierrez@amd.com            if (mask[lane]) {
48211308Santhony.gutierrez@amd.com                int src_val1 = src1.get<int>(w, lane, 1);
48311308Santhony.gutierrez@amd.com                res += src_val1;
48411308Santhony.gutierrez@amd.com            }
48511308Santhony.gutierrez@amd.com        }
48611308Santhony.gutierrez@amd.com
48711534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
48811308Santhony.gutierrez@amd.com            if (mask[lane]) {
48911308Santhony.gutierrez@amd.com                dest.set<int>(w, lane, res);
49011308Santhony.gutierrez@amd.com            }
49111308Santhony.gutierrez@amd.com        }
49211308Santhony.gutierrez@amd.com    }
49311308Santhony.gutierrez@amd.com
49411308Santhony.gutierrez@amd.com    void
49511308Santhony.gutierrez@amd.com    Call::MagicMaskLower(Wavefront *w)
49611308Santhony.gutierrez@amd.com    {
49711639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
49811308Santhony.gutierrez@amd.com        int res = 0;
49911308Santhony.gutierrez@amd.com
50011534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
50111308Santhony.gutierrez@amd.com            if (mask[lane]) {
50211308Santhony.gutierrez@amd.com                int src_val1 = src1.get<int>(w, lane, 1);
50311308Santhony.gutierrez@amd.com
50411308Santhony.gutierrez@amd.com                if (src_val1) {
50511534Sjohn.kalamatianos@amd.com                    if (lane < (w->computeUnit->wfSize()/2)) {
50611308Santhony.gutierrez@amd.com                        res = res | ((uint32_t)(1) << lane);
50711308Santhony.gutierrez@amd.com                    }
50811308Santhony.gutierrez@amd.com                }
50911308Santhony.gutierrez@amd.com            }
51011308Santhony.gutierrez@amd.com        }
51111308Santhony.gutierrez@amd.com
51211534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
51311308Santhony.gutierrez@amd.com            if (mask[lane]) {
51411308Santhony.gutierrez@amd.com                dest.set<int>(w, lane, res);
51511308Santhony.gutierrez@amd.com            }
51611308Santhony.gutierrez@amd.com        }
51711308Santhony.gutierrez@amd.com    }
51811308Santhony.gutierrez@amd.com
51911308Santhony.gutierrez@amd.com    void
52011308Santhony.gutierrez@amd.com    Call::MagicMaskUpper(Wavefront *w)
52111308Santhony.gutierrez@amd.com    {
52211639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
52311308Santhony.gutierrez@amd.com        int res = 0;
52411534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
52511308Santhony.gutierrez@amd.com            if (mask[lane]) {
52611308Santhony.gutierrez@amd.com                int src_val1 = src1.get<int>(w, lane, 1);
52711308Santhony.gutierrez@amd.com
52811308Santhony.gutierrez@amd.com                if (src_val1) {
52911534Sjohn.kalamatianos@amd.com                    if (lane >= (w->computeUnit->wfSize()/2)) {
53011534Sjohn.kalamatianos@amd.com                        res = res | ((uint32_t)(1) <<
53111534Sjohn.kalamatianos@amd.com                                     (lane - (w->computeUnit->wfSize()/2)));
53211308Santhony.gutierrez@amd.com                    }
53311308Santhony.gutierrez@amd.com                }
53411308Santhony.gutierrez@amd.com            }
53511308Santhony.gutierrez@amd.com        }
53611308Santhony.gutierrez@amd.com
53711534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
53811308Santhony.gutierrez@amd.com            if (mask[lane]) {
53911308Santhony.gutierrez@amd.com                dest.set<int>(w, lane, res);
54011308Santhony.gutierrez@amd.com            }
54111308Santhony.gutierrez@amd.com        }
54211308Santhony.gutierrez@amd.com    }
54311308Santhony.gutierrez@amd.com
54411308Santhony.gutierrez@amd.com    void
54511308Santhony.gutierrez@amd.com    Call::MagicJoinWFBar(Wavefront *w)
54611308Santhony.gutierrez@amd.com    {
54711639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
54811308Santhony.gutierrez@amd.com        int max_cnt = 0;
54911308Santhony.gutierrez@amd.com
55011534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
55111308Santhony.gutierrez@amd.com            if (mask[lane]) {
55211639Salexandru.dutu@amd.com                w->barCnt[lane]++;
55311308Santhony.gutierrez@amd.com
55411639Salexandru.dutu@amd.com                if (w->barCnt[lane] > max_cnt) {
55511639Salexandru.dutu@amd.com                    max_cnt = w->barCnt[lane];
55611308Santhony.gutierrez@amd.com                }
55711308Santhony.gutierrez@amd.com            }
55811308Santhony.gutierrez@amd.com        }
55911308Santhony.gutierrez@amd.com
56011639Salexandru.dutu@amd.com        if (max_cnt > w->maxBarCnt) {
56111639Salexandru.dutu@amd.com            w->maxBarCnt = max_cnt;
56211308Santhony.gutierrez@amd.com        }
56311308Santhony.gutierrez@amd.com    }
56411308Santhony.gutierrez@amd.com
56511308Santhony.gutierrez@amd.com    void
56611308Santhony.gutierrez@amd.com    Call::MagicWaitWFBar(Wavefront *w)
56711308Santhony.gutierrez@amd.com    {
56811639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
56911308Santhony.gutierrez@amd.com        int max_cnt = 0;
57011308Santhony.gutierrez@amd.com
57111534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
57211308Santhony.gutierrez@amd.com            if (mask[lane]) {
57311639Salexandru.dutu@amd.com                w->barCnt[lane]--;
57411308Santhony.gutierrez@amd.com            }
57511308Santhony.gutierrez@amd.com
57611639Salexandru.dutu@amd.com            if (w->barCnt[lane] > max_cnt) {
57711639Salexandru.dutu@amd.com                max_cnt = w->barCnt[lane];
57811308Santhony.gutierrez@amd.com            }
57911308Santhony.gutierrez@amd.com        }
58011308Santhony.gutierrez@amd.com
58111639Salexandru.dutu@amd.com        if (max_cnt < w->maxBarCnt) {
58211639Salexandru.dutu@amd.com            w->maxBarCnt = max_cnt;
58311308Santhony.gutierrez@amd.com        }
58411308Santhony.gutierrez@amd.com
58511308Santhony.gutierrez@amd.com        w->instructionBuffer.erase(w->instructionBuffer.begin() + 1,
58611308Santhony.gutierrez@amd.com                                   w->instructionBuffer.end());
58711308Santhony.gutierrez@amd.com        if (w->pendingFetch)
58811308Santhony.gutierrez@amd.com            w->dropFetch = true;
58911308Santhony.gutierrez@amd.com    }
59011308Santhony.gutierrez@amd.com
59111308Santhony.gutierrez@amd.com    void
59211308Santhony.gutierrez@amd.com    Call::MagicPanic(Wavefront *w)
59311308Santhony.gutierrez@amd.com    {
59411639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
59511308Santhony.gutierrez@amd.com
59611534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
59711308Santhony.gutierrez@amd.com            if (mask[lane]) {
59811308Santhony.gutierrez@amd.com                int src_val1 = src1.get<int>(w, lane, 1);
59911308Santhony.gutierrez@amd.com                panic("OpenCL Code failed assertion #%d. Triggered by lane %s",
60011308Santhony.gutierrez@amd.com                      src_val1, lane);
60111308Santhony.gutierrez@amd.com            }
60211308Santhony.gutierrez@amd.com        }
60311308Santhony.gutierrez@amd.com    }
60411308Santhony.gutierrez@amd.com
60511308Santhony.gutierrez@amd.com    void
60611308Santhony.gutierrez@amd.com    Call::calcAddr(Wavefront *w, GPUDynInstPtr m)
60711308Santhony.gutierrez@amd.com    {
60811308Santhony.gutierrez@amd.com        // the address is in src1 | src2
60911534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
61011308Santhony.gutierrez@amd.com            int src_val1 = src1.get<int>(w, lane, 1);
61111308Santhony.gutierrez@amd.com            int src_val2 = src1.get<int>(w, lane, 2);
61211308Santhony.gutierrez@amd.com            Addr addr = (((Addr) src_val1) << 32) | ((Addr) src_val2);
61311308Santhony.gutierrez@amd.com
61411308Santhony.gutierrez@amd.com            m->addr[lane] = addr;
61511308Santhony.gutierrez@amd.com        }
61611308Santhony.gutierrez@amd.com
61711308Santhony.gutierrez@amd.com    }
61811308Santhony.gutierrez@amd.com
61911308Santhony.gutierrez@amd.com    void
62011308Santhony.gutierrez@amd.com    Call::MagicAtomicNRAddGlobalU32Reg(Wavefront *w, GPUDynInstPtr gpuDynInst)
62111308Santhony.gutierrez@amd.com    {
62211308Santhony.gutierrez@amd.com        GPUDynInstPtr m = gpuDynInst;
62311308Santhony.gutierrez@amd.com
62411308Santhony.gutierrez@amd.com        calcAddr(w, m);
62511308Santhony.gutierrez@amd.com
62611534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
62711308Santhony.gutierrez@amd.com            ((int*)m->a_data)[lane] = src1.get<int>(w, lane, 3);
62811308Santhony.gutierrez@amd.com        }
62911308Santhony.gutierrez@amd.com
63011692Santhony.gutierrez@amd.com        setFlag(AtomicNoReturn);
63111692Santhony.gutierrez@amd.com        setFlag(AtomicAdd);
63211692Santhony.gutierrez@amd.com        setFlag(NoScope);
63311692Santhony.gutierrez@amd.com        setFlag(NoOrder);
63411692Santhony.gutierrez@amd.com        setFlag(GlobalSegment);
63511692Santhony.gutierrez@amd.com
63611308Santhony.gutierrez@amd.com        m->m_type = U32::memType;
63711308Santhony.gutierrez@amd.com        m->v_type = U32::vgprType;
63811308Santhony.gutierrez@amd.com
63911308Santhony.gutierrez@amd.com        m->exec_mask = w->execMask();
64011308Santhony.gutierrez@amd.com        m->statusBitVector = 0;
64111308Santhony.gutierrez@amd.com        m->equiv = 0;  // atomics don't have an equivalence class operand
64211308Santhony.gutierrez@amd.com        m->n_reg = 1;
64311308Santhony.gutierrez@amd.com
64411308Santhony.gutierrez@amd.com        m->simdId = w->simdId;
64511308Santhony.gutierrez@amd.com        m->wfSlotId = w->wfSlotId;
64611308Santhony.gutierrez@amd.com        m->wfDynId = w->wfDynId;
64711308Santhony.gutierrez@amd.com        m->latency.init(&w->computeUnit->shader->tick_cnt);
64811308Santhony.gutierrez@amd.com
64911308Santhony.gutierrez@amd.com        m->pipeId = GLBMEM_PIPE;
65011308Santhony.gutierrez@amd.com        m->latency.set(w->computeUnit->shader->ticks(64));
65111700Santhony.gutierrez@amd.com        w->computeUnit->globalMemoryPipe.issueRequest(m);
65211639Salexandru.dutu@amd.com        w->outstandingReqsWrGm++;
65311639Salexandru.dutu@amd.com        w->wrGmReqsInPipe--;
65411639Salexandru.dutu@amd.com        w->outstandingReqsRdGm++;
65511639Salexandru.dutu@amd.com        w->rdGmReqsInPipe--;
65611639Salexandru.dutu@amd.com        w->outstandingReqs++;
65711639Salexandru.dutu@amd.com        w->memReqsInPipe--;
65811308Santhony.gutierrez@amd.com    }
65911308Santhony.gutierrez@amd.com
66011308Santhony.gutierrez@amd.com    void
66111308Santhony.gutierrez@amd.com    Call::MagicAtomicNRAddGroupU32Reg(Wavefront *w, GPUDynInstPtr gpuDynInst)
66211308Santhony.gutierrez@amd.com    {
66311308Santhony.gutierrez@amd.com        GPUDynInstPtr m = gpuDynInst;
66411308Santhony.gutierrez@amd.com        calcAddr(w, m);
66511308Santhony.gutierrez@amd.com
66611534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
66711308Santhony.gutierrez@amd.com            ((int*)m->a_data)[lane] = src1.get<int>(w, lane, 1);
66811308Santhony.gutierrez@amd.com        }
66911308Santhony.gutierrez@amd.com
67011692Santhony.gutierrez@amd.com        setFlag(AtomicNoReturn);
67111692Santhony.gutierrez@amd.com        setFlag(AtomicAdd);
67211692Santhony.gutierrez@amd.com        setFlag(NoScope);
67311692Santhony.gutierrez@amd.com        setFlag(NoOrder);
67411692Santhony.gutierrez@amd.com        setFlag(GlobalSegment);
67511692Santhony.gutierrez@amd.com
67611308Santhony.gutierrez@amd.com        m->m_type = U32::memType;
67711308Santhony.gutierrez@amd.com        m->v_type = U32::vgprType;
67811308Santhony.gutierrez@amd.com
67911308Santhony.gutierrez@amd.com        m->exec_mask = w->execMask();
68011308Santhony.gutierrez@amd.com        m->statusBitVector = 0;
68111308Santhony.gutierrez@amd.com        m->equiv = 0;  // atomics don't have an equivalence class operand
68211308Santhony.gutierrez@amd.com        m->n_reg = 1;
68311308Santhony.gutierrez@amd.com
68411308Santhony.gutierrez@amd.com        m->simdId = w->simdId;
68511308Santhony.gutierrez@amd.com        m->wfSlotId = w->wfSlotId;
68611308Santhony.gutierrez@amd.com        m->wfDynId = w->wfDynId;
68711308Santhony.gutierrez@amd.com        m->latency.init(&w->computeUnit->shader->tick_cnt);
68811308Santhony.gutierrez@amd.com
68911308Santhony.gutierrez@amd.com        m->pipeId = GLBMEM_PIPE;
69011308Santhony.gutierrez@amd.com        m->latency.set(w->computeUnit->shader->ticks(64));
69111700Santhony.gutierrez@amd.com        w->computeUnit->globalMemoryPipe.issueRequest(m);
69211639Salexandru.dutu@amd.com        w->outstandingReqsWrGm++;
69311639Salexandru.dutu@amd.com        w->wrGmReqsInPipe--;
69411639Salexandru.dutu@amd.com        w->outstandingReqsRdGm++;
69511639Salexandru.dutu@amd.com        w->rdGmReqsInPipe--;
69611639Salexandru.dutu@amd.com        w->outstandingReqs++;
69711639Salexandru.dutu@amd.com        w->memReqsInPipe--;
69811308Santhony.gutierrez@amd.com    }
69911308Santhony.gutierrez@amd.com
70011308Santhony.gutierrez@amd.com    void
70111308Santhony.gutierrez@amd.com    Call::MagicLoadGlobalU32Reg(Wavefront *w, GPUDynInstPtr gpuDynInst)
70211308Santhony.gutierrez@amd.com    {
70311308Santhony.gutierrez@amd.com        GPUDynInstPtr m = gpuDynInst;
70411308Santhony.gutierrez@amd.com        // calculate the address
70511308Santhony.gutierrez@amd.com        calcAddr(w, m);
70611308Santhony.gutierrez@amd.com
70711692Santhony.gutierrez@amd.com        setFlag(Load);
70811692Santhony.gutierrez@amd.com        setFlag(NoScope);
70911692Santhony.gutierrez@amd.com        setFlag(NoOrder);
71011692Santhony.gutierrez@amd.com        setFlag(GlobalSegment);
71111692Santhony.gutierrez@amd.com
71211308Santhony.gutierrez@amd.com        m->m_type = U32::memType;  //MemDataType::memType;
71311308Santhony.gutierrez@amd.com        m->v_type = U32::vgprType; //DestDataType::vgprType;
71411308Santhony.gutierrez@amd.com
71511308Santhony.gutierrez@amd.com        m->exec_mask = w->execMask();
71611308Santhony.gutierrez@amd.com        m->statusBitVector = 0;
71711308Santhony.gutierrez@amd.com        m->equiv = 0;
71811308Santhony.gutierrez@amd.com        m->n_reg = 1;
71911308Santhony.gutierrez@amd.com
72011308Santhony.gutierrez@amd.com        // FIXME
72111308Santhony.gutierrez@amd.com        //m->dst_reg = this->dest.regIndex();
72211308Santhony.gutierrez@amd.com
72311308Santhony.gutierrez@amd.com        m->simdId = w->simdId;
72411308Santhony.gutierrez@amd.com        m->wfSlotId = w->wfSlotId;
72511308Santhony.gutierrez@amd.com        m->wfDynId = w->wfDynId;
72611308Santhony.gutierrez@amd.com        m->latency.init(&w->computeUnit->shader->tick_cnt);
72711308Santhony.gutierrez@amd.com
72811308Santhony.gutierrez@amd.com        m->pipeId = GLBMEM_PIPE;
72911308Santhony.gutierrez@amd.com        m->latency.set(w->computeUnit->shader->ticks(1));
73011700Santhony.gutierrez@amd.com        w->computeUnit->globalMemoryPipe.issueRequest(m);
73111639Salexandru.dutu@amd.com        w->outstandingReqsRdGm++;
73211639Salexandru.dutu@amd.com        w->rdGmReqsInPipe--;
73311639Salexandru.dutu@amd.com        w->outstandingReqs++;
73411639Salexandru.dutu@amd.com        w->memReqsInPipe--;
73511308Santhony.gutierrez@amd.com    }
73611308Santhony.gutierrez@amd.com
73711308Santhony.gutierrez@amd.com    void
73811308Santhony.gutierrez@amd.com    Call::MagicXactCasLd(Wavefront *w)
73911308Santhony.gutierrez@amd.com    {
74011639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
74111308Santhony.gutierrez@amd.com        int src_val1 = 0;
74211308Santhony.gutierrez@amd.com
74311534Sjohn.kalamatianos@amd.com        for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
74411308Santhony.gutierrez@amd.com            if (mask[lane]) {
74511308Santhony.gutierrez@amd.com                src_val1 = src1.get<int>(w, lane, 1);
74611308Santhony.gutierrez@amd.com                break;
74711308Santhony.gutierrez@amd.com            }
74811308Santhony.gutierrez@amd.com        }
74911308Santhony.gutierrez@amd.com
75011308Santhony.gutierrez@amd.com        if (!w->computeUnit->xactCasLoadMap.count(src_val1)) {
75111308Santhony.gutierrez@amd.com            w->computeUnit->xactCasLoadMap[src_val1] = ComputeUnit::waveQueue();
75211308Santhony.gutierrez@amd.com            w->computeUnit->xactCasLoadMap[src_val1].waveIDQueue.clear();
75311308Santhony.gutierrez@amd.com        }
75411308Santhony.gutierrez@amd.com
75511308Santhony.gutierrez@amd.com        w->computeUnit->xactCasLoadMap[src_val1].waveIDQueue
75611308Santhony.gutierrez@amd.com            .push_back(ComputeUnit::waveIdentifier(w->simdId, w->wfSlotId));
75711308Santhony.gutierrez@amd.com    }
75811308Santhony.gutierrez@amd.com
75911308Santhony.gutierrez@amd.com    void
76011308Santhony.gutierrez@amd.com    Call::MagicMostSigThread(Wavefront *w)
76111308Santhony.gutierrez@amd.com    {
76211639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
76311308Santhony.gutierrez@amd.com        unsigned mst = true;
76411308Santhony.gutierrez@amd.com
76511534Sjohn.kalamatianos@amd.com        for (int lane = w->computeUnit->wfSize() - 1; lane >= 0; --lane) {
76611308Santhony.gutierrez@amd.com            if (mask[lane]) {
76711308Santhony.gutierrez@amd.com                dest.set<int>(w, lane, mst);
76811308Santhony.gutierrez@amd.com                mst = false;
76911308Santhony.gutierrez@amd.com            }
77011308Santhony.gutierrez@amd.com        }
77111308Santhony.gutierrez@amd.com    }
77211308Santhony.gutierrez@amd.com
77311308Santhony.gutierrez@amd.com    void
77411308Santhony.gutierrez@amd.com    Call::MagicMostSigBroadcast(Wavefront *w)
77511308Santhony.gutierrez@amd.com    {
77611639Salexandru.dutu@amd.com        const VectorMask &mask = w->getPred();
77711308Santhony.gutierrez@amd.com        int res = 0;
77811308Santhony.gutierrez@amd.com        bool got_res = false;
77911308Santhony.gutierrez@amd.com
78011534Sjohn.kalamatianos@amd.com        for (int lane = w->computeUnit->wfSize() - 1; lane >= 0; --lane) {
78111308Santhony.gutierrez@amd.com            if (mask[lane]) {
78211308Santhony.gutierrez@amd.com                if (!got_res) {
78311308Santhony.gutierrez@amd.com                    res = src1.get<int>(w, lane, 1);
78411308Santhony.gutierrez@amd.com                    got_res = true;
78511308Santhony.gutierrez@amd.com                }
78611308Santhony.gutierrez@amd.com                dest.set<int>(w, lane, res);
78711308Santhony.gutierrez@amd.com            }
78811308Santhony.gutierrez@amd.com        }
78911308Santhony.gutierrez@amd.com    }
79011308Santhony.gutierrez@amd.com
79111308Santhony.gutierrez@amd.com} // namespace HsailISA
792