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