/*
 * 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
 *
 *  Contains class definitions for data flowing between pipeline stages in
 *  the top-level structure portion of this model.  Latch types are also
 *  defined which pair forward/backward flowing data specific to each stage
 *  pair.
 *
 *  No post-configuration inter-stage communication should *ever* take place
 *  outside these classes (except for reservation!)
 */

#ifndef __CPU_MINOR_PIPE_DATA_HH__
#define __CPU_MINOR_PIPE_DATA_HH__

#include "cpu/minor/buffers.hh"
#include "cpu/minor/dyn_inst.hh"
#include "cpu/base.hh"

namespace Minor
{

/** Forward data betwen Execute and Fetch1 carrying change-of-address/stream
 *  information. */
class BranchData /* : public ReportIF, public BubbleIF */
{
  public:
    enum Reason
    {
        /* *** No change of stream (information to branch prediction) */

        /* Don't branch at all (bubble) */
        NoBranch,
        /* Don't branch, but here's the details of a correct prediction
         * that was executed */
        CorrectlyPredictedBranch,

        /* *** Change of stream */

        /* Take an unpredicted branch */
        UnpredictedBranch,
        /* Take a branch on branch prediction data (from Fetch2) */
        BranchPrediction,
        /* Prediction of wrong target PC */
        BadlyPredictedBranchTarget,
        /* Bad branch prediction (didn't actually branch).  Need to branch
         *  back to correct stream.  If the target is wrong, use
         *  BadlyPredictedBranchTarget */
        BadlyPredictedBranch,
        /* Suspend fetching for this thread (inst->id.threadId).
         * This will be woken up by another stream changing branch so
         * count it as stream changing itself and expect pc to be the PC
         * of the next instruction */
        SuspendThread,
        /* Branch from an interrupt (no instruction) */
        Interrupt,
        /* Stop fetching in anticipation of of draining */
        HaltFetch
    };

    /** Is a request with this reason actually a request to change the
     *  PC rather than a bubble or branch prediction information */
    static bool isStreamChange(const BranchData::Reason reason);

    /** Is a request with this reason actually a 'real' branch, that is,
     *  a stream change that's not just an instruction to Fetch1 to halt
     *  or wake up */
    static bool isBranch(const BranchData::Reason reason);

  public:
    /** Explanation for this branch */
    Reason reason;

    /** ThreadID associated with branch */
    ThreadID threadId;

    /** Sequence number of new stream/prediction to be adopted */
    InstSeqNum newStreamSeqNum;
    InstSeqNum newPredictionSeqNum;

    /** Starting PC of that stream */
    TheISA::PCState target;

    /** Instruction which caused this branch */
    MinorDynInstPtr inst;

  public:
    BranchData() :
        reason(NoBranch), threadId(InvalidThreadID), newStreamSeqNum(0),
        newPredictionSeqNum(0), target(TheISA::PCState(0)),
        inst(MinorDynInst::bubble())
    { }

    BranchData(
        Reason reason_,
        ThreadID thread_id,
        InstSeqNum new_stream_seq_num,
        InstSeqNum new_prediction_seq_num,
        TheISA::PCState target,
        MinorDynInstPtr inst_) :
        reason(reason_),
        threadId(thread_id),
        newStreamSeqNum(new_stream_seq_num),
        newPredictionSeqNum(new_prediction_seq_num),
        target(target),
        inst(inst_)
    { }

    /** BubbleIF interface */
    static BranchData bubble() { return BranchData(); }
    bool isBubble() const { return reason == NoBranch; }

    /** As static isStreamChange but on this branch data */
    bool isStreamChange() const { return isStreamChange(reason); }

    /** As static isBranch but on this branch data */
    bool isBranch() const { return isBranch(reason); }

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

/** Print a branch reason enum */
std::ostream &operator <<(std::ostream &os, BranchData::Reason reason);

/** Print BranchData contents in a format suitable for DPRINTF comments, not
 *  for MinorTrace */
std::ostream &operator <<(std::ostream &os, const BranchData &branch);

/** Line fetch data in the forward direction.  Contains a single cache line
 *  (or fragment of a line), its address, a sequence number assigned when
 *  that line was fetched and a bubbleFlag that can allow ForwardLineData to
 *  be used to represent the absence of line data in a pipeline. */
class ForwardLineData /* : public ReportIF, public BubbleIF */
{
  private:
    /** This line is a bubble.  No other data member is required to be valid
     *  if this is true */
    bool bubbleFlag;

  public:
    /** First byte address in the line.  This is allowed to be
     *  <= pc.instAddr() */
    Addr lineBaseAddr;

    /** PC of the first requested inst within this line */
    TheISA::PCState pc;

    /** Explicit line width, don't rely on data.size */
    unsigned int lineWidth;

  public:
    /** This line has a fault.  The bubble flag will be false and seqNums
     *  will be valid but no data will */
    Fault fault;

    /** Thread, stream, prediction ... id of this line */
    InstId id;

    /** Line data.  line[0] is the byte at address pc.instAddr().  Data is
     *  only valid upto lineWidth - 1. */
    uint8_t *line;

    /** Packet from which the line is taken */
    Packet *packet;

  public:
    ForwardLineData() :
        bubbleFlag(true),
        lineBaseAddr(0),
        lineWidth(0),
        fault(NoFault),
        line(NULL),
        packet(NULL)
    {
        /* Make lines bubbles by default */
    }

    ~ForwardLineData() { line = NULL; }

  public:
    /** This is a fault, not a line */
    bool isFault() const { return fault != NoFault; }

    /** Set fault and possible clear the bubble flag */
    void setFault(Fault fault_);

    /** In-place initialise a ForwardLineData, freeing and overridding the
     *  line */
    void allocateLine(unsigned int width_);

    /** Use the data from a packet as line instead of allocating new
     *  space.  On destruction of this object, the packet will be destroyed */
    void adoptPacketData(Packet *packet);

    /** Free this ForwardLineData line.  Note that these are shared between
     *  line objects and so you must be careful when deallocating them.
     *  Copying of ForwardLineData can, therefore, be done by default copy
     *  constructors/assignment */
    void freeLine();

    /** BubbleIF interface */
    static ForwardLineData bubble() { return ForwardLineData(); }
    bool isBubble() const { return bubbleFlag; }

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

/** Maximum number of instructions that can be carried by the pipeline. */
const unsigned int MAX_FORWARD_INSTS = 16;

/** Forward flowing data between Fetch2,Decode,Execute carrying a packet of
 *  instructions of a width appropriate to the configured stage widths.
 *  Also carries exception information where instructions are not valid */
class ForwardInstData /* : public ReportIF, public BubbleIF */
{
  public:
    /** Array of carried insts, ref counted */
    MinorDynInstPtr insts[MAX_FORWARD_INSTS];

    /** The number of insts slots that can be expected to be valid insts */
    unsigned int numInsts;

    /** Thread associated with these instructions */
    ThreadID threadId;

  public:
    explicit ForwardInstData(unsigned int width = 0,
                             ThreadID tid = InvalidThreadID);

    ForwardInstData(const ForwardInstData &src);

  public:
    /** Number of instructions carried by this object */
    unsigned int width() const { return numInsts; }

    /** Copy the inst array only as far as numInsts */
    ForwardInstData &operator =(const ForwardInstData &src);

    /** Resize a bubble/empty ForwardInstData and fill with bubbles */
    void resize(unsigned int width);

    /** Fill with bubbles from 0 to width() - 1 */
    void bubbleFill();

    /** BubbleIF interface */
    bool isBubble() const;

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

}

#endif /* __CPU_MINOR_PIPE_DATA_HH__ */
