/*
 * Copyright (c) 2015-2017 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * For use for simulation and test purposes only
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "gpu-compute/vector_register_file.hh"

#include <string>

#include "base/logging.hh"
#include "base/trace.hh"
#include "debug/GPUVRF.hh"
#include "gpu-compute/compute_unit.hh"
#include "gpu-compute/gpu_dyn_inst.hh"
#include "gpu-compute/simple_pool_manager.hh"
#include "gpu-compute/wavefront.hh"
#include "params/VectorRegisterFile.hh"

namespace gem5
{

VectorRegisterFile::VectorRegisterFile(const VectorRegisterFileParams &p)
    : RegisterFile(p)
{
    regFile.resize(numRegs(), VecRegContainer());

    for (auto &reg : regFile) {
        reg.zero();
    }
}

bool
VectorRegisterFile::operandsReady(Wavefront *w, GPUDynInstPtr ii) const
{
    for (const auto& srcVecOp : ii->srcVecRegOperands()) {
        for (const auto& physIdx : srcVecOp.physIndices()) {
            if (regBusy(physIdx)) {
                DPRINTF(GPUVRF, "RAW stall: WV[%d]: %s: physReg[%d]\n",
                        w->wfDynId, ii->disassemble(), physIdx);
                w->stats.numTimesBlockedDueRAWDependencies++;
                return false;
            }
        }
    }

    return true;
}

void
VectorRegisterFile::scheduleWriteOperands(Wavefront *w, GPUDynInstPtr ii)
{
    for (const auto& dstVecOp : ii->dstVecRegOperands()) {
        for (const auto& physIdx : dstVecOp.physIndices()) {
            // If the instruction is atomic instruciton and the atomics do
            // not return value, then do not mark this reg as busy.
            if (!(ii->isAtomic() && !ii->isAtomicRet())) {
                /**
                 * if the instruction is a load with EXEC = 0, then we do not
                 * mark the reg. We do this to avoid a deadlock that can
                 * occur because a load reserves its destination regs before
                 * checking its exec mask, and in the cas it is 0, it will not
                 * send/recv any packets, and therefore it will never free its
                 * dst reg(s)
                 */
                if (!ii->isLoad() || (ii->isLoad() && ii->exec_mask.any())) {
                    markReg(physIdx, true);
                }
            }
        }
    }
}

void
VectorRegisterFile::waveExecuteInst(Wavefront *w, GPUDynInstPtr ii)
{
    // increment count of number of DWords read from VRF
    int DWords = ii->numSrcVecDWords();
    stats.registerReads += (DWords * w->execMask().count());

    uint64_t mask = w->execMask().to_ullong();
    int srams = w->execMask().size() / 4;
    for (int i = 0; i < srams; i++) {
        if (mask & 0xF) {
            stats.sramReads += DWords;
        }
        mask = mask >> 4;
    }

    if (!ii->isLoad()
        && !(ii->isAtomic() || ii->isMemSync())) {
        // TODO: compute proper delay
        // For now, it is based on largest operand size
        int opSize = ii->maxOperandSize();
        Cycles delay(opSize <= 4 ? computeUnit->spBypassLength()
            : computeUnit->dpBypassLength());
        Tick tickDelay = computeUnit->cyclesToTicks(delay);

        for (const auto& dstVecOp : ii->dstVecRegOperands()) {
            for (const auto& physIdx : dstVecOp.physIndices()) {
                enqRegFreeEvent(physIdx, tickDelay);
            }
        }
        // increment count of number of DWords written to VRF
        DWords = ii->numDstVecDWords();
        stats.registerWrites += (DWords * w->execMask().count());

        mask = w->execMask().to_ullong();
        srams = w->execMask().size() / 4;
        for (int i = 0; i < srams; i++) {
            if (mask & 0xF) {
                stats.sramWrites += DWords;
            }
            mask = mask >> 4;
        }
    }
}

void
VectorRegisterFile::scheduleWriteOperandsFromLoad(
    Wavefront *w, GPUDynInstPtr ii)
{
    assert(ii->isLoad() || ii->isAtomicRet());
    for (const auto& dstVecOp : ii->dstVecRegOperands()) {
        for (const auto& physIdx : dstVecOp.physIndices()) {
            enqRegFreeEvent(physIdx, computeUnit->clockPeriod());
        }
    }
    // increment count of number of DWords written to VRF
    int DWords = ii->numDstVecDWords();
    stats.registerWrites += (DWords * ii->exec_mask.count());

    uint64_t mask = ii->exec_mask.to_ullong();
    int srams = ii->exec_mask.size() / 4;
    for (int i = 0; i < srams; i++) {
        if (mask & 0xF) {
            stats.sramWrites += DWords;
        }
        mask = mask >> 4;
    }
}

} // namespace gem5
