/*
 * Copyright (c) 2013-2014 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.
 *
 * Authors: Andrew Bardsley
 */

/**
 * @file
 *
 *  The dynamic instruction and instruction/line id (sequence numbers)
 *  definition for Minor.  A spirited attempt is made here to not carry too
 *  much on this structure.
 */

#ifndef __CPU_MINOR_DYN_INST_HH__
#define __CPU_MINOR_DYN_INST_HH__

#include <iostream>

#include "base/refcnt.hh"
#include "cpu/minor/buffers.hh"
#include "cpu/inst_seq.hh"
#include "cpu/static_inst.hh"
#include "cpu/timing_expr.hh"
#include "sim/faults.hh"

namespace Minor
{

class MinorDynInst;

/** MinorDynInsts are currently reference counted. */
typedef RefCountingPtr<MinorDynInst> MinorDynInstPtr;

/** Id for lines and instructions.  This includes all the relevant sequence
 *  numbers and thread ids for all stages of execution. */
class InstId
{
  public:
    /** First sequence numbers to use in initialisation of the pipeline and
     *  to be expected on the first line/instruction issued */
    static const InstSeqNum firstStreamSeqNum = 1;
    static const InstSeqNum firstPredictionSeqNum = 1;
    static const InstSeqNum firstLineSeqNum = 1;
    static const InstSeqNum firstFetchSeqNum = 1;
    static const InstSeqNum firstExecSeqNum = 1;

  public:
    /** The thread to which this line/instruction belongs */
    ThreadID threadId;

    /** The 'stream' this instruction belongs to.  Streams are interrupted
     *  (and sequence numbers increased) when Execute finds it wants to
     *  change the stream of instructions due to a branch. */
    InstSeqNum streamSeqNum;

    /** The predicted qualifier to stream, attached by Fetch2 as a
     *  consequence of branch prediction */
    InstSeqNum predictionSeqNum;

    /** Line sequence number.  This is the sequence number of the fetched
     *  line from which this instruction was fetched */
    InstSeqNum lineSeqNum;

    /** Fetch sequence number.  This is 0 for bubbles and an ascending
     *  sequence for the stream of all fetched instructions */
    InstSeqNum fetchSeqNum;

    /** 'Execute' sequence number.  These are assigned after micro-op
     *  decomposition and form an ascending sequence (starting with 1) for
     *  post-micro-op decomposed instructions. */
    InstSeqNum execSeqNum;

  public:
    /** Very boring default constructor */
    InstId(
        ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0,
        InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0,
        InstSeqNum fetch_seq_num = 0, InstSeqNum exec_seq_num = 0) :
        threadId(thread_id), streamSeqNum(stream_seq_num),
        predictionSeqNum(prediction_seq_num), lineSeqNum(line_seq_num),
        fetchSeqNum(fetch_seq_num), execSeqNum(exec_seq_num)
    { }

  public:
    /* Equal if the thread and last set sequence number matches */
    bool
    operator== (const InstId &rhs)
    {
        /* If any of fetch and exec sequence number are not set
         *  they need to be 0, so a straight comparison is still
         *  fine */
        bool ret = (threadId == rhs.threadId &&
            lineSeqNum == rhs.lineSeqNum &&
            fetchSeqNum == rhs.fetchSeqNum &&
            execSeqNum == rhs.execSeqNum);

        /* Stream and prediction *must* match if these are the same id */
        if (ret) {
            assert(streamSeqNum == rhs.streamSeqNum &&
                predictionSeqNum == rhs.predictionSeqNum);
        }

        return ret;
    }
};

/** Print this id in the usual slash-separated format expected by
 *  MinorTrace */
std::ostream &operator <<(std::ostream &os, const InstId &id);

class MinorDynInst;

/** Print a short reference to this instruction.  '-' for a bubble and a
 *  series of '/' separated sequence numbers for other instructions.  The
 *  sequence numbers will be in the order: stream, prediction, line, fetch,
 *  exec with exec absent if it is 0.  This is used by MinorTrace. */
std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);

/** Dynamic instruction for Minor.
 *  MinorDynInst implements the BubbleIF interface
 *  Has two separate notions of sequence number for pre/post-micro-op
 *  decomposition: fetchSeqNum and execSeqNum */
class MinorDynInst : public RefCounted
{
  private:
    /** A prototypical bubble instruction.  You must call MinorDynInst::init
     *  to initialise this */
    static MinorDynInstPtr bubbleInst;

  public:
    StaticInstPtr staticInst;

    InstId id;

    /** Trace information for this instruction's execution */
    Trace::InstRecord *traceData;

    /** The fetch address of this instruction */
    TheISA::PCState pc;

    /** This is actually a fault masquerading as an instruction */
    Fault fault;

    /** Tried to predict the destination of this inst (if a control
     *  instruction or a sys call) */
    bool triedToPredict;

    /** This instruction was predicted to change control flow and
     *  the following instructions will have a newer predictionSeqNum */
    bool predictedTaken;

    /** Predicted branch target */
    TheISA::PCState predictedTarget;

    /** Fields only set during execution */

    /** FU this instruction is issued to */
    unsigned int fuIndex;

    /** This instruction is in the LSQ, not a functional unit */
    bool inLSQ;

    /** The instruction has been sent to the store buffer */
    bool inStoreBuffer;

    /** Can this instruction be executed out of order.  In this model,
     *  this only happens with mem refs that need to be issued early
     *  to allow other instructions to fill the fetch delay */
    bool canEarlyIssue;

    /** execSeqNum of the latest inst on which this inst depends.
     *  This can be used as a sanity check for dependency ordering
     *  where slightly out of order execution is required (notably
     *  initiateAcc for memory ops) */
    InstSeqNum instToWaitFor;

    /** Extra delay at the end of the pipeline */
    Cycles extraCommitDelay;
    TimingExpr *extraCommitDelayExpr;

    /** Once issued, extraCommitDelay becomes minimumCommitCycle
     *  to account for delay in absolute time */
    Cycles minimumCommitCycle;

    /** Flat register indices so that, when clearing the scoreboard, we
     *  have the same register indices as when the instruction was marked
     *  up */
    RegId flatDestRegIdx[TheISA::MaxInstDestRegs];

  public:
    MinorDynInst(InstId id_ = InstId(), Fault fault_ = NoFault) :
        staticInst(NULL), id(id_), traceData(NULL),
        pc(TheISA::PCState(0)), fault(fault_),
        triedToPredict(false), predictedTaken(false),
        fuIndex(0), inLSQ(false), inStoreBuffer(false),
        canEarlyIssue(false),
        instToWaitFor(0), extraCommitDelay(Cycles(0)),
        extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0))
    { }

  public:
    /** The BubbleIF interface. */
    bool isBubble() const { return id.fetchSeqNum == 0; }

    /** There is a single bubble inst */
    static MinorDynInstPtr bubble() { return bubbleInst; }

    /** Is this a fault rather than instruction */
    bool isFault() const { return fault != NoFault; }

    /** Is this a real instruction */
    bool isInst() const { return !isBubble() && !isFault(); }

    /** Is this a real mem ref instruction */
    bool isMemRef() const { return isInst() && staticInst->isMemRef(); }

    /** Is this an instruction that can be executed `for free' and
     *  needn't spend time in an FU */
    bool isNoCostInst() const;

    /** Assuming this is not a fault, is this instruction either
     *  a whole instruction or the last microop from a macroop */
    bool isLastOpInInst() const;

    /** Initialise the class */
    static void init();

    /** Print (possibly verbose) instruction information for
     *  MinorTrace using the given Named object's name */
    void minorTraceInst(const Named &named_object) const;

    /** ReportIF interface */
    void reportData(std::ostream &os) const;

    ~MinorDynInst();
};

/** Print a summary of the instruction */
std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);

}

#endif /* __CPU_MINOR_DYN_INST_HH__ */
