/*
 * Copyright (c) 2013-2014, 2016-2017 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * 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;
 * neither the name of the copyright holders 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
 * OWNER 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 "cpu/minor/scoreboard.hh"

#include "arch/registers.hh"
#include "cpu/reg_class.hh"
#include "debug/MinorScoreboard.hh"
#include "debug/MinorTiming.hh"

namespace Minor
{

bool
Scoreboard::findIndex(const RegId& reg, Index &scoreboard_index)
{
    bool ret = false;

    if (reg.isZeroReg()) {
        /* Don't bother with the zero register */
        ret = false;
    } else {
        switch (reg.classValue())
        {
          case IntRegClass:
            scoreboard_index = reg.index();
            ret = true;
            break;
          case FloatRegClass:
            scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
                reg.index();
            ret = true;
            break;
          case VecRegClass:
            scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
                TheISA::NumFloatRegs + reg.index();
            ret = true;
            break;
          case VecElemClass:
            scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
                TheISA::NumFloatRegs + reg.flatIndex();
            ret = true;
            break;
          case VecPredRegClass:
            scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
                TheISA::NumFloatRegs + TheISA::NumVecRegs + reg.index();
            ret = true;
            break;
          case CCRegClass:
            scoreboard_index = TheISA::NumIntRegs + reg.index();
            ret = true;
            break;
          case MiscRegClass:
              /* Don't bother with Misc registers */
            ret = false;
            break;
          default:
            panic("Unknown register class: %d",
                    static_cast<int>(reg.classValue()));
        }
    }

    return ret;
}

/** Flatten a RegId, irrespective of what reg type it's pointing to */
static RegId
flattenRegIndex(const RegId& reg, ThreadContext *thread_context)
{
    return thread_context->flattenRegId(reg);
}

void
Scoreboard::markupInstDests(MinorDynInstPtr inst, Cycles retire_time,
    ThreadContext *thread_context, bool mark_unpredictable)
{
    if (inst->isFault())
        return;

    StaticInstPtr staticInst = inst->staticInst;
    unsigned int num_dests = staticInst->numDestRegs();

    /** Mark each destination register */
    for (unsigned int dest_index = 0; dest_index < num_dests;
        dest_index++)
    {
        RegId reg = flattenRegIndex(
                staticInst->destRegIdx(dest_index), thread_context);
        Index index;

        if (findIndex(reg, index)) {
            if (mark_unpredictable)
                numUnpredictableResults[index]++;

            inst->flatDestRegIdx[dest_index] = reg;

            numResults[index]++;
            returnCycle[index] = retire_time;
            /* We should be able to rely on only being given accending
             *  execSeqNums, but sanity check */
            if (inst->id.execSeqNum > writingInst[index]) {
                writingInst[index] = inst->id.execSeqNum;
                fuIndices[index] = inst->fuIndex;
            }

            DPRINTF(MinorScoreboard, "Marking up inst: %s"
                " regIndex: %d final numResults: %d returnCycle: %d\n",
                *inst, index, numResults[index], returnCycle[index]);
        } else {
            /* Use ZeroReg to mark invalid/untracked dests */
            inst->flatDestRegIdx[dest_index] = RegId(IntRegClass,
                                                     TheISA::ZeroReg);
        }
    }
}

InstSeqNum
Scoreboard::execSeqNumToWaitFor(MinorDynInstPtr inst,
    ThreadContext *thread_context)
{
    InstSeqNum ret = 0;

    if (inst->isFault())
        return ret;

    StaticInstPtr staticInst = inst->staticInst;
    unsigned int num_srcs = staticInst->numSrcRegs();

    for (unsigned int src_index = 0; src_index < num_srcs; src_index++) {
        RegId reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
            thread_context);
        unsigned short int index;

        if (findIndex(reg, index)) {
            if (writingInst[index] > ret)
                ret = writingInst[index];
        }
    }

    DPRINTF(MinorScoreboard, "Inst: %s depends on execSeqNum: %d\n",
        *inst, ret);

    return ret;
}

void
Scoreboard::clearInstDests(MinorDynInstPtr inst, bool clear_unpredictable)
{
    if (inst->isFault())
        return;

    StaticInstPtr staticInst = inst->staticInst;
    unsigned int num_dests = staticInst->numDestRegs();

    /** Mark each destination register */
    for (unsigned int dest_index = 0; dest_index < num_dests;
        dest_index++)
    {
        const RegId& reg = inst->flatDestRegIdx[dest_index];
        Index index;

        if (findIndex(reg, index)) {
            if (clear_unpredictable && numUnpredictableResults[index] != 0)
                numUnpredictableResults[index] --;

            numResults[index] --;

            if (numResults[index] == 0) {
                returnCycle[index] = Cycles(0);
                writingInst[index] = 0;
                fuIndices[index] = -1;
            }

            DPRINTF(MinorScoreboard, "Clearing inst: %s"
                " regIndex: %d final numResults: %d\n",
                *inst, index, numResults[index]);
        }
    }
}

bool
Scoreboard::canInstIssue(MinorDynInstPtr inst,
    const std::vector<Cycles> *src_reg_relative_latencies,
    const std::vector<bool> *cant_forward_from_fu_indices,
    Cycles now, ThreadContext *thread_context)
{
    /* Always allow fault to be issued */
    if (inst->isFault())
        return true;

    StaticInstPtr staticInst = inst->staticInst;
    unsigned int num_srcs = staticInst->numSrcRegs();

    /* Default to saying you can issue */
    bool ret = true;

    unsigned int num_relative_latencies = 0;
    Cycles default_relative_latency = Cycles(0);

    /* Where relative latencies are given, the default is the last
     *  one as that allows the rel. lat. list to be shorted than the
     *  number of src. regs */
    if (src_reg_relative_latencies &&
        src_reg_relative_latencies->size() != 0)
    {
        num_relative_latencies = src_reg_relative_latencies->size();
        default_relative_latency = (*src_reg_relative_latencies)
            [num_relative_latencies-1];
    }

    /* For each source register, find the latest result */
    unsigned int src_index = 0;
    while (src_index < num_srcs && /* More registers */
        ret /* Still possible */)
    {
        RegId reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
            thread_context);
        unsigned short int index;

        if (findIndex(reg, index)) {
            bool cant_forward = fuIndices[index] != 1 &&
                cant_forward_from_fu_indices &&
                index < cant_forward_from_fu_indices->size() &&
                (*cant_forward_from_fu_indices)[index];

            Cycles relative_latency = (cant_forward ? Cycles(0) :
                (src_index >= num_relative_latencies ?
                    default_relative_latency :
                    (*src_reg_relative_latencies)[src_index]));

            if (returnCycle[index] > (now + relative_latency) ||
                numUnpredictableResults[index] != 0)
            {
                ret = false;
            }
        }
        src_index++;
    }

    if (DTRACE(MinorTiming)) {
        if (ret && num_srcs > num_relative_latencies &&
            num_relative_latencies != 0)
        {
            DPRINTF(MinorTiming, "Warning, inst: %s timing extra decode has"
                " more src. regs: %d than relative latencies: %d\n",
                staticInst->disassemble(0), num_srcs, num_relative_latencies);
        }
    }

    return ret;
}

void
Scoreboard::minorTrace() const
{
    std::ostringstream result_stream;

    bool printed_element = false;

    unsigned int i = 0;
    while (i < numRegs) {
        unsigned short int num_results = numResults[i];
        unsigned short int num_unpredictable_results =
            numUnpredictableResults[i];

        if (!(num_results == 0 && num_unpredictable_results == Cycles(0))) {
            if (printed_element)
                result_stream << ',';

            result_stream << '(' << i << ','
                 << num_results << '/'
                 << num_unpredictable_results << '/'
                 << returnCycle[i] << '/'
                 << writingInst[i] << ')';

            printed_element = true;
        }

        i++;
    }

    MINORTRACE("busy=%s\n", result_stream.str());
}

}
