mem_impl.hh revision 11308
111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2012-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: Steve Reinhardt
3411308Santhony.gutierrez@amd.com */
3511308Santhony.gutierrez@amd.com
3611308Santhony.gutierrez@amd.com#include "arch/hsail/generic_types.hh"
3711308Santhony.gutierrez@amd.com#include "gpu-compute/hsail_code.hh"
3811308Santhony.gutierrez@amd.com
3911308Santhony.gutierrez@amd.com// defined in code.cc, but not worth sucking in all of code.h for this
4011308Santhony.gutierrez@amd.com// at this point
4111308Santhony.gutierrez@amd.comextern const char *segmentNames[];
4211308Santhony.gutierrez@amd.com
4311308Santhony.gutierrez@amd.comnamespace HsailISA
4411308Santhony.gutierrez@amd.com{
4511308Santhony.gutierrez@amd.com    template<typename DestDataType, typename AddrRegOperandType>
4611308Santhony.gutierrez@amd.com    void
4711308Santhony.gutierrez@amd.com    LdaInst<DestDataType, AddrRegOperandType>::generateDisassembly()
4811308Santhony.gutierrez@amd.com    {
4911308Santhony.gutierrez@amd.com        this->disassembly = csprintf("%s_%s %s,%s", this->opcode,
5011308Santhony.gutierrez@amd.com                                     DestDataType::label,
5111308Santhony.gutierrez@amd.com                                     this->dest.disassemble(),
5211308Santhony.gutierrez@amd.com                                     this->addr.disassemble());
5311308Santhony.gutierrez@amd.com    }
5411308Santhony.gutierrez@amd.com
5511308Santhony.gutierrez@amd.com    template<typename DestDataType, typename AddrRegOperandType>
5611308Santhony.gutierrez@amd.com    void
5711308Santhony.gutierrez@amd.com    LdaInst<DestDataType, AddrRegOperandType>::execute(GPUDynInstPtr gpuDynInst)
5811308Santhony.gutierrez@amd.com    {
5911308Santhony.gutierrez@amd.com        Wavefront *w = gpuDynInst->wavefront();
6011308Santhony.gutierrez@amd.com
6111308Santhony.gutierrez@amd.com        typedef typename DestDataType::CType CType M5_VAR_USED;
6211308Santhony.gutierrez@amd.com        const VectorMask &mask = w->get_pred();
6311308Santhony.gutierrez@amd.com        uint64_t addr_vec[VSZ];
6411308Santhony.gutierrez@amd.com        this->addr.calcVector(w, addr_vec);
6511308Santhony.gutierrez@amd.com
6611308Santhony.gutierrez@amd.com        for (int lane = 0; lane < VSZ; ++lane) {
6711308Santhony.gutierrez@amd.com            if (mask[lane]) {
6811308Santhony.gutierrez@amd.com                this->dest.set(w, lane, addr_vec[lane]);
6911308Santhony.gutierrez@amd.com            }
7011308Santhony.gutierrez@amd.com        }
7111308Santhony.gutierrez@amd.com    }
7211308Santhony.gutierrez@amd.com
7311308Santhony.gutierrez@amd.com    template<typename MemDataType, typename DestDataType,
7411308Santhony.gutierrez@amd.com             typename AddrRegOperandType>
7511308Santhony.gutierrez@amd.com    void
7611308Santhony.gutierrez@amd.com    LdInst<MemDataType, DestDataType, AddrRegOperandType>::generateDisassembly()
7711308Santhony.gutierrez@amd.com    {
7811308Santhony.gutierrez@amd.com        switch (num_dest_operands) {
7911308Santhony.gutierrez@amd.com          case 1:
8011308Santhony.gutierrez@amd.com            this->disassembly = csprintf("%s_%s_%s %s,%s", this->opcode,
8111308Santhony.gutierrez@amd.com                                         segmentNames[this->segment],
8211308Santhony.gutierrez@amd.com                                         MemDataType::label,
8311308Santhony.gutierrez@amd.com                                         this->dest.disassemble(),
8411308Santhony.gutierrez@amd.com                                         this->addr.disassemble());
8511308Santhony.gutierrez@amd.com            break;
8611308Santhony.gutierrez@amd.com          case 2:
8711308Santhony.gutierrez@amd.com            this->disassembly = csprintf("%s_%s_%s (%s,%s), %s", this->opcode,
8811308Santhony.gutierrez@amd.com                                         segmentNames[this->segment],
8911308Santhony.gutierrez@amd.com                                         MemDataType::label,
9011308Santhony.gutierrez@amd.com                                         this->dest_vect[0].disassemble(),
9111308Santhony.gutierrez@amd.com                                         this->dest_vect[1].disassemble(),
9211308Santhony.gutierrez@amd.com                                         this->addr.disassemble());
9311308Santhony.gutierrez@amd.com            break;
9411308Santhony.gutierrez@amd.com          case 4:
9511308Santhony.gutierrez@amd.com            this->disassembly = csprintf("%s_%s_%s (%s,%s,%s,%s), %s",
9611308Santhony.gutierrez@amd.com                                         this->opcode,
9711308Santhony.gutierrez@amd.com                                         segmentNames[this->segment],
9811308Santhony.gutierrez@amd.com                                         MemDataType::label,
9911308Santhony.gutierrez@amd.com                                         this->dest_vect[0].disassemble(),
10011308Santhony.gutierrez@amd.com                                         this->dest_vect[1].disassemble(),
10111308Santhony.gutierrez@amd.com                                         this->dest_vect[2].disassemble(),
10211308Santhony.gutierrez@amd.com                                         this->dest_vect[3].disassemble(),
10311308Santhony.gutierrez@amd.com                                         this->addr.disassemble());
10411308Santhony.gutierrez@amd.com            break;
10511308Santhony.gutierrez@amd.com          default:
10611308Santhony.gutierrez@amd.com            fatal("Bad ld register dest operand, num vector operands: %d \n",
10711308Santhony.gutierrez@amd.com                  num_dest_operands);
10811308Santhony.gutierrez@amd.com            break;
10911308Santhony.gutierrez@amd.com        }
11011308Santhony.gutierrez@amd.com    }
11111308Santhony.gutierrez@amd.com
11211308Santhony.gutierrez@amd.com    static Addr
11311308Santhony.gutierrez@amd.com    calcPrivAddr(Addr addr, Wavefront *w, int lane, GPUStaticInst *i)
11411308Santhony.gutierrez@amd.com    {
11511308Santhony.gutierrez@amd.com        // what is the size of the object we are accessing??
11611308Santhony.gutierrez@amd.com        // NOTE: the compiler doesn't generate enough information
11711308Santhony.gutierrez@amd.com        // to do this yet..have to just line up all the private
11811308Santhony.gutierrez@amd.com        // work-item spaces back to back for now
11911308Santhony.gutierrez@amd.com        /*
12011308Santhony.gutierrez@amd.com        StorageElement* se =
12111308Santhony.gutierrez@amd.com            i->parent->findSymbol(Brig::BrigPrivateSpace, addr);
12211308Santhony.gutierrez@amd.com        assert(se);
12311308Santhony.gutierrez@amd.com
12411308Santhony.gutierrez@amd.com        return w->wfSlotId * w->privSizePerItem * VSZ +
12511308Santhony.gutierrez@amd.com            se->offset * VSZ +
12611308Santhony.gutierrez@amd.com            lane * se->size;
12711308Santhony.gutierrez@amd.com        */
12811308Santhony.gutierrez@amd.com
12911308Santhony.gutierrez@amd.com        // addressing strategy: interleave the private spaces of
13011308Santhony.gutierrez@amd.com        // work-items in a wave-front on 8 byte granularity.
13111308Santhony.gutierrez@amd.com        // this won't be perfect coalescing like the spill space
13211308Santhony.gutierrez@amd.com        // strategy, but it's better than nothing. The spill space
13311308Santhony.gutierrez@amd.com        // strategy won't work with private because the same address
13411308Santhony.gutierrez@amd.com        // may be accessed by different sized loads/stores.
13511308Santhony.gutierrez@amd.com
13611308Santhony.gutierrez@amd.com        // Note: I'm assuming that the largest load/store to private
13711308Santhony.gutierrez@amd.com        // is 8 bytes. If it is larger, the stride will have to increase
13811308Santhony.gutierrez@amd.com
13911308Santhony.gutierrez@amd.com        Addr addr_div8 = addr / 8;
14011308Santhony.gutierrez@amd.com        Addr addr_mod8 = addr % 8;
14111308Santhony.gutierrez@amd.com
14211308Santhony.gutierrez@amd.com        Addr ret = addr_div8 * 8 * VSZ + lane * 8 + addr_mod8 + w->privBase;
14311308Santhony.gutierrez@amd.com
14411308Santhony.gutierrez@amd.com        assert(ret < w->privBase + (w->privSizePerItem * VSZ));
14511308Santhony.gutierrez@amd.com
14611308Santhony.gutierrez@amd.com        return ret;
14711308Santhony.gutierrez@amd.com    }
14811308Santhony.gutierrez@amd.com
14911308Santhony.gutierrez@amd.com    template<typename MemDataType, typename DestDataType,
15011308Santhony.gutierrez@amd.com             typename AddrRegOperandType>
15111308Santhony.gutierrez@amd.com    void
15211308Santhony.gutierrez@amd.com    LdInst<MemDataType, DestDataType,
15311308Santhony.gutierrez@amd.com           AddrRegOperandType>::execute(GPUDynInstPtr gpuDynInst)
15411308Santhony.gutierrez@amd.com    {
15511308Santhony.gutierrez@amd.com        Wavefront *w = gpuDynInst->wavefront();
15611308Santhony.gutierrez@amd.com
15711308Santhony.gutierrez@amd.com        typedef typename MemDataType::CType MemCType;
15811308Santhony.gutierrez@amd.com        const VectorMask &mask = w->get_pred();
15911308Santhony.gutierrez@amd.com
16011308Santhony.gutierrez@amd.com        // Kernarg references are handled uniquely for now (no Memory Request
16111308Santhony.gutierrez@amd.com        // is used), so special-case them up front.  Someday we should
16211308Santhony.gutierrez@amd.com        // make this more realistic, at which we should get rid of this
16311308Santhony.gutierrez@amd.com        // block and fold this case into the switch below.
16411308Santhony.gutierrez@amd.com        if (this->segment == Brig::BRIG_SEGMENT_KERNARG) {
16511308Santhony.gutierrez@amd.com            MemCType val;
16611308Santhony.gutierrez@amd.com
16711308Santhony.gutierrez@amd.com            // I assume no vector ld for kernargs
16811308Santhony.gutierrez@amd.com            assert(num_dest_operands == 1);
16911308Santhony.gutierrez@amd.com
17011308Santhony.gutierrez@amd.com            // assuming for the moment that we'll never do register
17111308Santhony.gutierrez@amd.com            // offsets into kernarg space... just to make life simpler
17211308Santhony.gutierrez@amd.com            uint64_t address = this->addr.calcUniform();
17311308Santhony.gutierrez@amd.com
17411308Santhony.gutierrez@amd.com            val = *(MemCType*)&w->kernelArgs[address];
17511308Santhony.gutierrez@amd.com
17611308Santhony.gutierrez@amd.com            DPRINTF(HSAIL, "ld_kernarg [%d] -> %d\n", address, val);
17711308Santhony.gutierrez@amd.com
17811308Santhony.gutierrez@amd.com            for (int lane = 0; lane < VSZ; ++lane) {
17911308Santhony.gutierrez@amd.com                if (mask[lane]) {
18011308Santhony.gutierrez@amd.com                    this->dest.set(w, lane, val);
18111308Santhony.gutierrez@amd.com                }
18211308Santhony.gutierrez@amd.com            }
18311308Santhony.gutierrez@amd.com
18411308Santhony.gutierrez@amd.com            return;
18511308Santhony.gutierrez@amd.com        } else if (this->segment == Brig::BRIG_SEGMENT_ARG) {
18611308Santhony.gutierrez@amd.com            uint64_t address = this->addr.calcUniform();
18711308Santhony.gutierrez@amd.com            for (int lane = 0; lane < VSZ; ++lane) {
18811308Santhony.gutierrez@amd.com                if (mask[lane]) {
18911308Santhony.gutierrez@amd.com                    MemCType val = w->readCallArgMem<MemCType>(lane, address);
19011308Santhony.gutierrez@amd.com
19111308Santhony.gutierrez@amd.com                    DPRINTF(HSAIL, "ld_arg [%d] -> %llu\n", address,
19211308Santhony.gutierrez@amd.com                            (unsigned long long)val);
19311308Santhony.gutierrez@amd.com
19411308Santhony.gutierrez@amd.com                    this->dest.set(w, lane, val);
19511308Santhony.gutierrez@amd.com                }
19611308Santhony.gutierrez@amd.com            }
19711308Santhony.gutierrez@amd.com
19811308Santhony.gutierrez@amd.com            return;
19911308Santhony.gutierrez@amd.com        }
20011308Santhony.gutierrez@amd.com
20111308Santhony.gutierrez@amd.com        GPUDynInstPtr m = gpuDynInst;
20211308Santhony.gutierrez@amd.com
20311308Santhony.gutierrez@amd.com        this->addr.calcVector(w, m->addr);
20411308Santhony.gutierrez@amd.com
20511308Santhony.gutierrez@amd.com        m->m_op = Enums::MO_LD;
20611308Santhony.gutierrez@amd.com        m->m_type = MemDataType::memType;
20711308Santhony.gutierrez@amd.com        m->v_type = DestDataType::vgprType;
20811308Santhony.gutierrez@amd.com
20911308Santhony.gutierrez@amd.com        m->exec_mask = w->execMask();
21011308Santhony.gutierrez@amd.com        m->statusBitVector = 0;
21111308Santhony.gutierrez@amd.com        m->equiv = this->equivClass;
21211308Santhony.gutierrez@amd.com        m->memoryOrder = getGenericMemoryOrder(this->memoryOrder);
21311308Santhony.gutierrez@amd.com
21411308Santhony.gutierrez@amd.com        m->scope = getGenericMemoryScope(this->memoryScope);
21511308Santhony.gutierrez@amd.com
21611308Santhony.gutierrez@amd.com        if (num_dest_operands == 1) {
21711308Santhony.gutierrez@amd.com            m->dst_reg = this->dest.regIndex();
21811308Santhony.gutierrez@amd.com            m->n_reg = 1;
21911308Santhony.gutierrez@amd.com        } else {
22011308Santhony.gutierrez@amd.com            m->n_reg = num_dest_operands;
22111308Santhony.gutierrez@amd.com            for (int i = 0; i < num_dest_operands; ++i) {
22211308Santhony.gutierrez@amd.com                m->dst_reg_vec[i] = this->dest_vect[i].regIndex();
22311308Santhony.gutierrez@amd.com            }
22411308Santhony.gutierrez@amd.com        }
22511308Santhony.gutierrez@amd.com
22611308Santhony.gutierrez@amd.com        m->simdId = w->simdId;
22711308Santhony.gutierrez@amd.com        m->wfSlotId = w->wfSlotId;
22811308Santhony.gutierrez@amd.com        m->wfDynId = w->wfDynId;
22911308Santhony.gutierrez@amd.com        m->kern_id = w->kern_id;
23011308Santhony.gutierrez@amd.com        m->cu_id = w->computeUnit->cu_id;
23111308Santhony.gutierrez@amd.com        m->latency.init(&w->computeUnit->shader->tick_cnt);
23211308Santhony.gutierrez@amd.com
23311308Santhony.gutierrez@amd.com        switch (this->segment) {
23411308Santhony.gutierrez@amd.com          case Brig::BRIG_SEGMENT_GLOBAL:
23511308Santhony.gutierrez@amd.com            m->s_type = SEG_GLOBAL;
23611308Santhony.gutierrez@amd.com            m->pipeId = GLBMEM_PIPE;
23711308Santhony.gutierrez@amd.com            m->latency.set(w->computeUnit->shader->ticks(1));
23811308Santhony.gutierrez@amd.com
23911308Santhony.gutierrez@amd.com            // this is a complete hack to get around a compiler bug
24011308Santhony.gutierrez@amd.com            // (the compiler currently generates global access for private
24111308Santhony.gutierrez@amd.com            //  addresses (starting from 0). We need to add the private offset)
24211308Santhony.gutierrez@amd.com            for (int lane = 0; lane < VSZ; ++lane) {
24311308Santhony.gutierrez@amd.com                if (m->addr[lane] < w->privSizePerItem) {
24411308Santhony.gutierrez@amd.com                    if (mask[lane]) {
24511308Santhony.gutierrez@amd.com                        // what is the size of the object we are accessing?
24611308Santhony.gutierrez@amd.com                        // find base for for this wavefront
24711308Santhony.gutierrez@amd.com
24811308Santhony.gutierrez@amd.com                        // calcPrivAddr will fail if accesses are unaligned
24911308Santhony.gutierrez@amd.com                        assert(!((sizeof(MemCType) - 1) & m->addr[lane]));
25011308Santhony.gutierrez@amd.com
25111308Santhony.gutierrez@amd.com                        Addr privAddr = calcPrivAddr(m->addr[lane], w, lane,
25211308Santhony.gutierrez@amd.com                                                     this);
25311308Santhony.gutierrez@amd.com
25411308Santhony.gutierrez@amd.com                        m->addr[lane] = privAddr;
25511308Santhony.gutierrez@amd.com                    }
25611308Santhony.gutierrez@amd.com                }
25711308Santhony.gutierrez@amd.com            }
25811308Santhony.gutierrez@amd.com
25911308Santhony.gutierrez@amd.com            w->computeUnit->globalMemoryPipe.getGMReqFIFO().push(m);
26011308Santhony.gutierrez@amd.com            w->outstanding_reqs_rd_gm++;
26111308Santhony.gutierrez@amd.com            w->rd_gm_reqs_in_pipe--;
26211308Santhony.gutierrez@amd.com            break;
26311308Santhony.gutierrez@amd.com
26411308Santhony.gutierrez@amd.com          case Brig::BRIG_SEGMENT_SPILL:
26511308Santhony.gutierrez@amd.com            assert(num_dest_operands == 1);
26611308Santhony.gutierrez@amd.com            m->s_type = SEG_SPILL;
26711308Santhony.gutierrez@amd.com            m->pipeId = GLBMEM_PIPE;
26811308Santhony.gutierrez@amd.com            m->latency.set(w->computeUnit->shader->ticks(1));
26911308Santhony.gutierrez@amd.com            {
27011308Santhony.gutierrez@amd.com                for (int lane = 0; lane < VSZ; ++lane) {
27111308Santhony.gutierrez@amd.com                    //  note: this calculation will NOT WORK if the compiler
27211308Santhony.gutierrez@amd.com                    //  ever generates loads/stores to the same address with
27311308Santhony.gutierrez@amd.com                    //  different widths (e.g., a ld_u32 addr and a ld_u16 addr)
27411308Santhony.gutierrez@amd.com                    if (mask[lane]) {
27511308Santhony.gutierrez@amd.com                        assert(m->addr[lane] < w->spillSizePerItem);
27611308Santhony.gutierrez@amd.com
27711308Santhony.gutierrez@amd.com                        m->addr[lane] = m->addr[lane] * w->spillWidth +
27811308Santhony.gutierrez@amd.com                                        lane * sizeof(MemCType) + w->spillBase;
27911308Santhony.gutierrez@amd.com
28011308Santhony.gutierrez@amd.com                        w->last_addr[lane] = m->addr[lane];
28111308Santhony.gutierrez@amd.com                    }
28211308Santhony.gutierrez@amd.com                }
28311308Santhony.gutierrez@amd.com            }
28411308Santhony.gutierrez@amd.com
28511308Santhony.gutierrez@amd.com            w->computeUnit->globalMemoryPipe.getGMReqFIFO().push(m);
28611308Santhony.gutierrez@amd.com            w->outstanding_reqs_rd_gm++;
28711308Santhony.gutierrez@amd.com            w->rd_gm_reqs_in_pipe--;
28811308Santhony.gutierrez@amd.com            break;
28911308Santhony.gutierrez@amd.com
29011308Santhony.gutierrez@amd.com          case Brig::BRIG_SEGMENT_GROUP:
29111308Santhony.gutierrez@amd.com            m->s_type = SEG_SHARED;
29211308Santhony.gutierrez@amd.com            m->pipeId = LDSMEM_PIPE;
29311308Santhony.gutierrez@amd.com            m->latency.set(w->computeUnit->shader->ticks(24));
29411308Santhony.gutierrez@amd.com            w->computeUnit->localMemoryPipe.getLMReqFIFO().push(m);
29511308Santhony.gutierrez@amd.com            w->outstanding_reqs_rd_lm++;
29611308Santhony.gutierrez@amd.com            w->rd_lm_reqs_in_pipe--;
29711308Santhony.gutierrez@amd.com            break;
29811308Santhony.gutierrez@amd.com
29911308Santhony.gutierrez@amd.com          case Brig::BRIG_SEGMENT_READONLY:
30011308Santhony.gutierrez@amd.com            m->s_type = SEG_READONLY;
30111308Santhony.gutierrez@amd.com            m->pipeId = GLBMEM_PIPE;
30211308Santhony.gutierrez@amd.com            m->latency.set(w->computeUnit->shader->ticks(1));
30311308Santhony.gutierrez@amd.com
30411308Santhony.gutierrez@amd.com            for (int lane = 0; lane < VSZ; ++lane) {
30511308Santhony.gutierrez@amd.com                if (mask[lane]) {
30611308Santhony.gutierrez@amd.com                    assert(m->addr[lane] + sizeof(MemCType) <= w->roSize);
30711308Santhony.gutierrez@amd.com                    m->addr[lane] += w->roBase;
30811308Santhony.gutierrez@amd.com                }
30911308Santhony.gutierrez@amd.com            }
31011308Santhony.gutierrez@amd.com
31111308Santhony.gutierrez@amd.com            w->computeUnit->globalMemoryPipe.getGMReqFIFO().push(m);
31211308Santhony.gutierrez@amd.com            w->outstanding_reqs_rd_gm++;
31311308Santhony.gutierrez@amd.com            w->rd_gm_reqs_in_pipe--;
31411308Santhony.gutierrez@amd.com            break;
31511308Santhony.gutierrez@amd.com
31611308Santhony.gutierrez@amd.com          case Brig::BRIG_SEGMENT_PRIVATE:
31711308Santhony.gutierrez@amd.com            m->s_type = SEG_PRIVATE;
31811308Santhony.gutierrez@amd.com            m->pipeId = GLBMEM_PIPE;
31911308Santhony.gutierrez@amd.com            m->latency.set(w->computeUnit->shader->ticks(1));
32011308Santhony.gutierrez@amd.com            {
32111308Santhony.gutierrez@amd.com                for (int lane = 0; lane < VSZ; ++lane) {
32211308Santhony.gutierrez@amd.com                    if (mask[lane]) {
32311308Santhony.gutierrez@amd.com                        assert(m->addr[lane] < w->privSizePerItem);
32411308Santhony.gutierrez@amd.com
32511308Santhony.gutierrez@amd.com                        m->addr[lane] = m->addr[lane] +
32611308Santhony.gutierrez@amd.com                            lane * sizeof(MemCType) + w->privBase;
32711308Santhony.gutierrez@amd.com                    }
32811308Santhony.gutierrez@amd.com                }
32911308Santhony.gutierrez@amd.com            }
33011308Santhony.gutierrez@amd.com            w->computeUnit->globalMemoryPipe.getGMReqFIFO().push(m);
33111308Santhony.gutierrez@amd.com            w->outstanding_reqs_rd_gm++;
33211308Santhony.gutierrez@amd.com            w->rd_gm_reqs_in_pipe--;
33311308Santhony.gutierrez@amd.com            break;
33411308Santhony.gutierrez@amd.com
33511308Santhony.gutierrez@amd.com          default:
33611308Santhony.gutierrez@amd.com            fatal("Load to unsupported segment %d %llxe\n", this->segment,
33711308Santhony.gutierrez@amd.com                  m->addr[0]);
33811308Santhony.gutierrez@amd.com        }
33911308Santhony.gutierrez@amd.com
34011308Santhony.gutierrez@amd.com        w->outstanding_reqs++;
34111308Santhony.gutierrez@amd.com        w->mem_reqs_in_pipe--;
34211308Santhony.gutierrez@amd.com    }
34311308Santhony.gutierrez@amd.com
34411308Santhony.gutierrez@amd.com    template<typename OperationType, typename SrcDataType,
34511308Santhony.gutierrez@amd.com             typename AddrRegOperandType>
34611308Santhony.gutierrez@amd.com    void
34711308Santhony.gutierrez@amd.com    StInst<OperationType, SrcDataType,
34811308Santhony.gutierrez@amd.com           AddrRegOperandType>::execute(GPUDynInstPtr gpuDynInst)
34911308Santhony.gutierrez@amd.com    {
35011308Santhony.gutierrez@amd.com        Wavefront *w = gpuDynInst->wavefront();
35111308Santhony.gutierrez@amd.com
35211308Santhony.gutierrez@amd.com        typedef typename OperationType::CType CType;
35311308Santhony.gutierrez@amd.com
35411308Santhony.gutierrez@amd.com        const VectorMask &mask = w->get_pred();
35511308Santhony.gutierrez@amd.com
35611308Santhony.gutierrez@amd.com        // arg references are handled uniquely for now (no Memory Request
35711308Santhony.gutierrez@amd.com        // is used), so special-case them up front.  Someday we should
35811308Santhony.gutierrez@amd.com        // make this more realistic, at which we should get rid of this
35911308Santhony.gutierrez@amd.com        // block and fold this case into the switch below.
36011308Santhony.gutierrez@amd.com        if (this->segment == Brig::BRIG_SEGMENT_ARG) {
36111308Santhony.gutierrez@amd.com            uint64_t address = this->addr.calcUniform();
36211308Santhony.gutierrez@amd.com
36311308Santhony.gutierrez@amd.com            for (int lane = 0; lane < VSZ; ++lane) {
36411308Santhony.gutierrez@amd.com                if (mask[lane]) {
36511308Santhony.gutierrez@amd.com                    CType data = this->src.template get<CType>(w, lane);
36611308Santhony.gutierrez@amd.com                    DPRINTF(HSAIL, "st_arg [%d] <- %d\n", address, data);
36711308Santhony.gutierrez@amd.com                    w->writeCallArgMem<CType>(lane, address, data);
36811308Santhony.gutierrez@amd.com                }
36911308Santhony.gutierrez@amd.com            }
37011308Santhony.gutierrez@amd.com
37111308Santhony.gutierrez@amd.com            return;
37211308Santhony.gutierrez@amd.com        }
37311308Santhony.gutierrez@amd.com
37411308Santhony.gutierrez@amd.com        GPUDynInstPtr m = gpuDynInst;
37511308Santhony.gutierrez@amd.com
37611308Santhony.gutierrez@amd.com        m->exec_mask = w->execMask();
37711308Santhony.gutierrez@amd.com
37811308Santhony.gutierrez@amd.com        this->addr.calcVector(w, m->addr);
37911308Santhony.gutierrez@amd.com
38011308Santhony.gutierrez@amd.com        if (num_src_operands == 1) {
38111308Santhony.gutierrez@amd.com            for (int lane = 0; lane < VSZ; ++lane) {
38211308Santhony.gutierrez@amd.com                if (mask[lane]) {
38311308Santhony.gutierrez@amd.com                    ((CType*)m->d_data)[lane] =
38411308Santhony.gutierrez@amd.com                        this->src.template get<CType>(w, lane);
38511308Santhony.gutierrez@amd.com                }
38611308Santhony.gutierrez@amd.com            }
38711308Santhony.gutierrez@amd.com        } else {
38811308Santhony.gutierrez@amd.com            for (int k= 0; k < num_src_operands; ++k) {
38911308Santhony.gutierrez@amd.com                for (int lane = 0; lane < VSZ; ++lane) {
39011308Santhony.gutierrez@amd.com                    if (mask[lane]) {
39111308Santhony.gutierrez@amd.com                        ((CType*)m->d_data)[k * VSZ + lane] =
39211308Santhony.gutierrez@amd.com                            this->src_vect[k].template get<CType>(w, lane);
39311308Santhony.gutierrez@amd.com                    }
39411308Santhony.gutierrez@amd.com                }
39511308Santhony.gutierrez@amd.com            }
39611308Santhony.gutierrez@amd.com        }
39711308Santhony.gutierrez@amd.com
39811308Santhony.gutierrez@amd.com        m->m_op = Enums::MO_ST;
39911308Santhony.gutierrez@amd.com        m->m_type = OperationType::memType;
40011308Santhony.gutierrez@amd.com        m->v_type = OperationType::vgprType;
40111308Santhony.gutierrez@amd.com
40211308Santhony.gutierrez@amd.com        m->statusBitVector = 0;
40311308Santhony.gutierrez@amd.com        m->equiv = this->equivClass;
40411308Santhony.gutierrez@amd.com
40511308Santhony.gutierrez@amd.com        if (num_src_operands == 1) {
40611308Santhony.gutierrez@amd.com            m->n_reg = 1;
40711308Santhony.gutierrez@amd.com        } else {
40811308Santhony.gutierrez@amd.com            m->n_reg = num_src_operands;
40911308Santhony.gutierrez@amd.com        }
41011308Santhony.gutierrez@amd.com
41111308Santhony.gutierrez@amd.com        m->memoryOrder = getGenericMemoryOrder(this->memoryOrder);
41211308Santhony.gutierrez@amd.com
41311308Santhony.gutierrez@amd.com        m->scope = getGenericMemoryScope(this->memoryScope);
41411308Santhony.gutierrez@amd.com
41511308Santhony.gutierrez@amd.com        m->simdId = w->simdId;
41611308Santhony.gutierrez@amd.com        m->wfSlotId = w->wfSlotId;
41711308Santhony.gutierrez@amd.com        m->wfDynId = w->wfDynId;
41811308Santhony.gutierrez@amd.com        m->kern_id = w->kern_id;
41911308Santhony.gutierrez@amd.com        m->cu_id = w->computeUnit->cu_id;
42011308Santhony.gutierrez@amd.com        m->latency.init(&w->computeUnit->shader->tick_cnt);
42111308Santhony.gutierrez@amd.com
42211308Santhony.gutierrez@amd.com        switch (this->segment) {
42311308Santhony.gutierrez@amd.com          case Brig::BRIG_SEGMENT_GLOBAL:
42411308Santhony.gutierrez@amd.com            m->s_type = SEG_GLOBAL;
42511308Santhony.gutierrez@amd.com            m->pipeId = GLBMEM_PIPE;
42611308Santhony.gutierrez@amd.com            m->latency.set(w->computeUnit->shader->ticks(1));
42711308Santhony.gutierrez@amd.com
42811308Santhony.gutierrez@amd.com            // this is a complete hack to get around a compiler bug
42911308Santhony.gutierrez@amd.com            // (the compiler currently generates global access for private
43011308Santhony.gutierrez@amd.com            //  addresses (starting from 0). We need to add the private offset)
43111308Santhony.gutierrez@amd.com            for (int lane = 0; lane < VSZ; ++lane) {
43211308Santhony.gutierrez@amd.com                if (mask[lane]) {
43311308Santhony.gutierrez@amd.com                    if (m->addr[lane] < w->privSizePerItem) {
43411308Santhony.gutierrez@amd.com
43511308Santhony.gutierrez@amd.com                        // calcPrivAddr will fail if accesses are unaligned
43611308Santhony.gutierrez@amd.com                        assert(!((sizeof(CType)-1) & m->addr[lane]));
43711308Santhony.gutierrez@amd.com
43811308Santhony.gutierrez@amd.com                        Addr privAddr = calcPrivAddr(m->addr[lane], w, lane,
43911308Santhony.gutierrez@amd.com                                                     this);
44011308Santhony.gutierrez@amd.com
44111308Santhony.gutierrez@amd.com                        m->addr[lane] = privAddr;
44211308Santhony.gutierrez@amd.com                    }
44311308Santhony.gutierrez@amd.com                }
44411308Santhony.gutierrez@amd.com            }
44511308Santhony.gutierrez@amd.com
44611308Santhony.gutierrez@amd.com            w->computeUnit->globalMemoryPipe.getGMReqFIFO().push(m);
44711308Santhony.gutierrez@amd.com            w->outstanding_reqs_wr_gm++;
44811308Santhony.gutierrez@amd.com            w->wr_gm_reqs_in_pipe--;
44911308Santhony.gutierrez@amd.com            break;
45011308Santhony.gutierrez@amd.com
45111308Santhony.gutierrez@amd.com          case Brig::BRIG_SEGMENT_SPILL:
45211308Santhony.gutierrez@amd.com            assert(num_src_operands == 1);
45311308Santhony.gutierrez@amd.com            m->s_type = SEG_SPILL;
45411308Santhony.gutierrez@amd.com            m->pipeId = GLBMEM_PIPE;
45511308Santhony.gutierrez@amd.com            m->latency.set(w->computeUnit->shader->ticks(1));
45611308Santhony.gutierrez@amd.com            {
45711308Santhony.gutierrez@amd.com                for (int lane = 0; lane < VSZ; ++lane) {
45811308Santhony.gutierrez@amd.com                    if (mask[lane]) {
45911308Santhony.gutierrez@amd.com                        assert(m->addr[lane] < w->spillSizePerItem);
46011308Santhony.gutierrez@amd.com
46111308Santhony.gutierrez@amd.com                        m->addr[lane] = m->addr[lane] * w->spillWidth +
46211308Santhony.gutierrez@amd.com                                        lane * sizeof(CType) + w->spillBase;
46311308Santhony.gutierrez@amd.com                    }
46411308Santhony.gutierrez@amd.com                }
46511308Santhony.gutierrez@amd.com            }
46611308Santhony.gutierrez@amd.com
46711308Santhony.gutierrez@amd.com            w->computeUnit->globalMemoryPipe.getGMReqFIFO().push(m);
46811308Santhony.gutierrez@amd.com            w->outstanding_reqs_wr_gm++;
46911308Santhony.gutierrez@amd.com            w->wr_gm_reqs_in_pipe--;
47011308Santhony.gutierrez@amd.com            break;
47111308Santhony.gutierrez@amd.com
47211308Santhony.gutierrez@amd.com          case Brig::BRIG_SEGMENT_GROUP:
47311308Santhony.gutierrez@amd.com            m->s_type = SEG_SHARED;
47411308Santhony.gutierrez@amd.com            m->pipeId = LDSMEM_PIPE;
47511308Santhony.gutierrez@amd.com            m->latency.set(w->computeUnit->shader->ticks(24));
47611308Santhony.gutierrez@amd.com            w->computeUnit->localMemoryPipe.getLMReqFIFO().push(m);
47711308Santhony.gutierrez@amd.com            w->outstanding_reqs_wr_lm++;
47811308Santhony.gutierrez@amd.com            w->wr_lm_reqs_in_pipe--;
47911308Santhony.gutierrez@amd.com            break;
48011308Santhony.gutierrez@amd.com
48111308Santhony.gutierrez@amd.com          case Brig::BRIG_SEGMENT_PRIVATE:
48211308Santhony.gutierrez@amd.com            m->s_type = SEG_PRIVATE;
48311308Santhony.gutierrez@amd.com            m->pipeId = GLBMEM_PIPE;
48411308Santhony.gutierrez@amd.com            m->latency.set(w->computeUnit->shader->ticks(1));
48511308Santhony.gutierrez@amd.com            {
48611308Santhony.gutierrez@amd.com                for (int lane = 0; lane < VSZ; ++lane) {
48711308Santhony.gutierrez@amd.com                    if (mask[lane]) {
48811308Santhony.gutierrez@amd.com                        assert(m->addr[lane] < w->privSizePerItem);
48911308Santhony.gutierrez@amd.com                        m->addr[lane] = m->addr[lane] + lane *
49011308Santhony.gutierrez@amd.com                            sizeof(CType)+w->privBase;
49111308Santhony.gutierrez@amd.com                    }
49211308Santhony.gutierrez@amd.com                }
49311308Santhony.gutierrez@amd.com            }
49411308Santhony.gutierrez@amd.com
49511308Santhony.gutierrez@amd.com            w->computeUnit->globalMemoryPipe.getGMReqFIFO().push(m);
49611308Santhony.gutierrez@amd.com            w->outstanding_reqs_wr_gm++;
49711308Santhony.gutierrez@amd.com            w->wr_gm_reqs_in_pipe--;
49811308Santhony.gutierrez@amd.com            break;
49911308Santhony.gutierrez@amd.com
50011308Santhony.gutierrez@amd.com          default:
50111308Santhony.gutierrez@amd.com            fatal("Store to unsupported segment %d\n", this->segment);
50211308Santhony.gutierrez@amd.com        }
50311308Santhony.gutierrez@amd.com
50411308Santhony.gutierrez@amd.com        w->outstanding_reqs++;
50511308Santhony.gutierrez@amd.com        w->mem_reqs_in_pipe--;
50611308Santhony.gutierrez@amd.com    }
50711308Santhony.gutierrez@amd.com
50811308Santhony.gutierrez@amd.com    template<typename OperationType, typename SrcDataType,
50911308Santhony.gutierrez@amd.com             typename AddrRegOperandType>
51011308Santhony.gutierrez@amd.com    void
51111308Santhony.gutierrez@amd.com    StInst<OperationType, SrcDataType,
51211308Santhony.gutierrez@amd.com           AddrRegOperandType>::generateDisassembly()
51311308Santhony.gutierrez@amd.com    {
51411308Santhony.gutierrez@amd.com        switch (num_src_operands) {
51511308Santhony.gutierrez@amd.com          case 1:
51611308Santhony.gutierrez@amd.com            this->disassembly = csprintf("%s_%s_%s %s,%s", this->opcode,
51711308Santhony.gutierrez@amd.com                                         segmentNames[this->segment],
51811308Santhony.gutierrez@amd.com                                         OperationType::label,
51911308Santhony.gutierrez@amd.com                                         this->src.disassemble(),
52011308Santhony.gutierrez@amd.com                                         this->addr.disassemble());
52111308Santhony.gutierrez@amd.com            break;
52211308Santhony.gutierrez@amd.com          case 2:
52311308Santhony.gutierrez@amd.com            this->disassembly = csprintf("%s_%s_%s (%s,%s), %s", this->opcode,
52411308Santhony.gutierrez@amd.com                                         segmentNames[this->segment],
52511308Santhony.gutierrez@amd.com                                         OperationType::label,
52611308Santhony.gutierrez@amd.com                                         this->src_vect[0].disassemble(),
52711308Santhony.gutierrez@amd.com                                         this->src_vect[1].disassemble(),
52811308Santhony.gutierrez@amd.com                                         this->addr.disassemble());
52911308Santhony.gutierrez@amd.com            break;
53011308Santhony.gutierrez@amd.com          case 4:
53111308Santhony.gutierrez@amd.com            this->disassembly = csprintf("%s_%s_%s (%s,%s,%s,%s), %s",
53211308Santhony.gutierrez@amd.com                                         this->opcode,
53311308Santhony.gutierrez@amd.com                                         segmentNames[this->segment],
53411308Santhony.gutierrez@amd.com                                         OperationType::label,
53511308Santhony.gutierrez@amd.com                                         this->src_vect[0].disassemble(),
53611308Santhony.gutierrez@amd.com                                         this->src_vect[1].disassemble(),
53711308Santhony.gutierrez@amd.com                                         this->src_vect[2].disassemble(),
53811308Santhony.gutierrez@amd.com                                         this->src_vect[3].disassemble(),
53911308Santhony.gutierrez@amd.com                                         this->addr.disassemble());
54011308Santhony.gutierrez@amd.com            break;
54111308Santhony.gutierrez@amd.com          default: fatal("Bad ld register src operand, num vector operands: "
54211308Santhony.gutierrez@amd.com                         "%d \n", num_src_operands);
54311308Santhony.gutierrez@amd.com            break;
54411308Santhony.gutierrez@amd.com        }
54511308Santhony.gutierrez@amd.com    }
54611308Santhony.gutierrez@amd.com
54711308Santhony.gutierrez@amd.com    template<typename DataType, typename AddrRegOperandType, int NumSrcOperands,
54811308Santhony.gutierrez@amd.com             bool HasDst>
54911308Santhony.gutierrez@amd.com    void
55011308Santhony.gutierrez@amd.com    AtomicInst<DataType, AddrRegOperandType, NumSrcOperands,
55111308Santhony.gutierrez@amd.com        HasDst>::execute(GPUDynInstPtr gpuDynInst)
55211308Santhony.gutierrez@amd.com    {
55311308Santhony.gutierrez@amd.com        typedef typename DataType::CType CType;
55411308Santhony.gutierrez@amd.com
55511308Santhony.gutierrez@amd.com        Wavefront *w = gpuDynInst->wavefront();
55611308Santhony.gutierrez@amd.com
55711308Santhony.gutierrez@amd.com        GPUDynInstPtr m = gpuDynInst;
55811308Santhony.gutierrez@amd.com
55911308Santhony.gutierrez@amd.com        this->addr.calcVector(w, m->addr);
56011308Santhony.gutierrez@amd.com
56111308Santhony.gutierrez@amd.com        for (int lane = 0; lane < VSZ; ++lane) {
56211308Santhony.gutierrez@amd.com            ((CType *)m->a_data)[lane] =
56311308Santhony.gutierrez@amd.com                this->src[0].template get<CType>(w, lane);
56411308Santhony.gutierrez@amd.com        }
56511308Santhony.gutierrez@amd.com
56611308Santhony.gutierrez@amd.com        // load second source operand for CAS
56711308Santhony.gutierrez@amd.com        if (NumSrcOperands > 1) {
56811308Santhony.gutierrez@amd.com            for (int lane = 0; lane < VSZ; ++lane) {
56911308Santhony.gutierrez@amd.com                ((CType*)m->x_data)[lane] =
57011308Santhony.gutierrez@amd.com                    this->src[1].template get<CType>(w, lane);
57111308Santhony.gutierrez@amd.com            }
57211308Santhony.gutierrez@amd.com        }
57311308Santhony.gutierrez@amd.com
57411308Santhony.gutierrez@amd.com        assert(NumSrcOperands <= 2);
57511308Santhony.gutierrez@amd.com
57611308Santhony.gutierrez@amd.com        m->m_op = this->opType;
57711308Santhony.gutierrez@amd.com        m->m_type = DataType::memType;
57811308Santhony.gutierrez@amd.com        m->v_type = DataType::vgprType;
57911308Santhony.gutierrez@amd.com
58011308Santhony.gutierrez@amd.com        m->exec_mask = w->execMask();
58111308Santhony.gutierrez@amd.com        m->statusBitVector = 0;
58211308Santhony.gutierrez@amd.com        m->equiv = 0;  // atomics don't have an equivalence class operand
58311308Santhony.gutierrez@amd.com        m->n_reg = 1;
58411308Santhony.gutierrez@amd.com        m->memoryOrder = getGenericMemoryOrder(this->memoryOrder);
58511308Santhony.gutierrez@amd.com
58611308Santhony.gutierrez@amd.com        m->scope = getGenericMemoryScope(this->memoryScope);
58711308Santhony.gutierrez@amd.com
58811308Santhony.gutierrez@amd.com        if (HasDst) {
58911308Santhony.gutierrez@amd.com            m->dst_reg = this->dest.regIndex();
59011308Santhony.gutierrez@amd.com        }
59111308Santhony.gutierrez@amd.com
59211308Santhony.gutierrez@amd.com        m->simdId = w->simdId;
59311308Santhony.gutierrez@amd.com        m->wfSlotId = w->wfSlotId;
59411308Santhony.gutierrez@amd.com        m->wfDynId = w->wfDynId;
59511308Santhony.gutierrez@amd.com        m->kern_id = w->kern_id;
59611308Santhony.gutierrez@amd.com        m->cu_id = w->computeUnit->cu_id;
59711308Santhony.gutierrez@amd.com        m->latency.init(&w->computeUnit->shader->tick_cnt);
59811308Santhony.gutierrez@amd.com
59911308Santhony.gutierrez@amd.com        switch (this->segment) {
60011308Santhony.gutierrez@amd.com          case Brig::BRIG_SEGMENT_GLOBAL:
60111308Santhony.gutierrez@amd.com            m->s_type = SEG_GLOBAL;
60211308Santhony.gutierrez@amd.com            m->latency.set(w->computeUnit->shader->ticks(64));
60311308Santhony.gutierrez@amd.com            m->pipeId = GLBMEM_PIPE;
60411308Santhony.gutierrez@amd.com
60511308Santhony.gutierrez@amd.com            w->computeUnit->globalMemoryPipe.getGMReqFIFO().push(m);
60611308Santhony.gutierrez@amd.com            w->outstanding_reqs_wr_gm++;
60711308Santhony.gutierrez@amd.com            w->wr_gm_reqs_in_pipe--;
60811308Santhony.gutierrez@amd.com            w->outstanding_reqs_rd_gm++;
60911308Santhony.gutierrez@amd.com            w->rd_gm_reqs_in_pipe--;
61011308Santhony.gutierrez@amd.com            break;
61111308Santhony.gutierrez@amd.com
61211308Santhony.gutierrez@amd.com          case Brig::BRIG_SEGMENT_GROUP:
61311308Santhony.gutierrez@amd.com            m->s_type = SEG_SHARED;
61411308Santhony.gutierrez@amd.com            m->pipeId = LDSMEM_PIPE;
61511308Santhony.gutierrez@amd.com            m->latency.set(w->computeUnit->shader->ticks(24));
61611308Santhony.gutierrez@amd.com            w->computeUnit->localMemoryPipe.getLMReqFIFO().push(m);
61711308Santhony.gutierrez@amd.com            w->outstanding_reqs_wr_lm++;
61811308Santhony.gutierrez@amd.com            w->wr_lm_reqs_in_pipe--;
61911308Santhony.gutierrez@amd.com            w->outstanding_reqs_rd_lm++;
62011308Santhony.gutierrez@amd.com            w->rd_lm_reqs_in_pipe--;
62111308Santhony.gutierrez@amd.com            break;
62211308Santhony.gutierrez@amd.com
62311308Santhony.gutierrez@amd.com          default:
62411308Santhony.gutierrez@amd.com            fatal("Atomic op to unsupported segment %d\n",
62511308Santhony.gutierrez@amd.com                  this->segment);
62611308Santhony.gutierrez@amd.com        }
62711308Santhony.gutierrez@amd.com
62811308Santhony.gutierrez@amd.com        w->outstanding_reqs++;
62911308Santhony.gutierrez@amd.com        w->mem_reqs_in_pipe--;
63011308Santhony.gutierrez@amd.com    }
63111308Santhony.gutierrez@amd.com
63211308Santhony.gutierrez@amd.com    const char* atomicOpToString(Brig::BrigAtomicOperation atomicOp);
63311308Santhony.gutierrez@amd.com
63411308Santhony.gutierrez@amd.com    template<typename DataType, typename AddrRegOperandType, int NumSrcOperands,
63511308Santhony.gutierrez@amd.com             bool HasDst>
63611308Santhony.gutierrez@amd.com    void
63711308Santhony.gutierrez@amd.com    AtomicInst<DataType, AddrRegOperandType, NumSrcOperands,
63811308Santhony.gutierrez@amd.com               HasDst>::generateDisassembly()
63911308Santhony.gutierrez@amd.com    {
64011308Santhony.gutierrez@amd.com        if (HasDst) {
64111308Santhony.gutierrez@amd.com            this->disassembly =
64211308Santhony.gutierrez@amd.com                csprintf("%s_%s_%s_%s %s,%s", this->opcode,
64311308Santhony.gutierrez@amd.com                         atomicOpToString(this->atomicOperation),
64411308Santhony.gutierrez@amd.com                         segmentNames[this->segment],
64511308Santhony.gutierrez@amd.com                         DataType::label, this->dest.disassemble(),
64611308Santhony.gutierrez@amd.com                         this->addr.disassemble());
64711308Santhony.gutierrez@amd.com        } else {
64811308Santhony.gutierrez@amd.com            this->disassembly =
64911308Santhony.gutierrez@amd.com                csprintf("%s_%s_%s_%s %s", this->opcode,
65011308Santhony.gutierrez@amd.com                         atomicOpToString(this->atomicOperation),
65111308Santhony.gutierrez@amd.com                         segmentNames[this->segment],
65211308Santhony.gutierrez@amd.com                         DataType::label, this->addr.disassemble());
65311308Santhony.gutierrez@amd.com        }
65411308Santhony.gutierrez@amd.com
65511308Santhony.gutierrez@amd.com        for (int i = 0; i < NumSrcOperands; ++i) {
65611308Santhony.gutierrez@amd.com            this->disassembly += ",";
65711308Santhony.gutierrez@amd.com            this->disassembly += this->src[i].disassemble();
65811308Santhony.gutierrez@amd.com        }
65911308Santhony.gutierrez@amd.com    }
66011308Santhony.gutierrez@amd.com} // namespace HsailISA
661