/*
 * 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 "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;

    switch (reg.classValue()) {
      case IntRegClass:
        if (reg.index() == zeroReg) {
            /* Don't bother with the zero register */
            ret = false;
        } else {
            scoreboard_index = reg.index();
            ret = true;
        }
        break;
      case FloatRegClass:
        scoreboard_index = floatRegOffset + reg.index();
        ret = true;
        break;
      case VecRegClass:
      case VecElemClass:
        scoreboard_index = vecRegOffset + reg.index();
        ret = true;
        break;
      case VecPredRegClass:
        scoreboard_index = vecPredRegOffset + reg.index();
        ret = true;
        break;
      case CCRegClass:
        scoreboard_index = ccRegOffset + reg.index();
        ret = true;
        break;
      case MiscRegClass:
          /* Don't bother with Misc registers */
        ret = false;
        break;
      default:
        panic("Unknown register class: %d", 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, 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 (Debug::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++;
    }

    Minor::minorTrace("busy=%s\n", result_stream.str());
}

}
