/*
 * 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.
 */

/**
 * @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 gem5
{

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 = NoBranch;

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

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

    /** Starting PC of that stream */
    std::unique_ptr<PCStateBase> target;

    /** Instruction which caused this branch */
    MinorDynInstPtr inst = MinorDynInst::bubble();

  public:
    BranchData() {}

    BranchData(Reason reason_, ThreadID thread_id,
            InstSeqNum new_stream_seq_num, InstSeqNum new_prediction_seq_num,
            const PCStateBase &_target, MinorDynInstPtr inst_) :
        reason(reason_), threadId(thread_id),
        newStreamSeqNum(new_stream_seq_num),
        newPredictionSeqNum(new_prediction_seq_num),
        inst(inst_)
    {
        set(target, _target);
    }

    BranchData(const BranchData &other) :
        reason(other.reason), threadId(other.threadId),
        newStreamSeqNum(other.newStreamSeqNum),
        newPredictionSeqNum(other.newPredictionSeqNum),
        inst(other.inst)
    {
        set(target, other.target);
    }
    BranchData &
    operator=(const BranchData &other)
    {
        reason = other.reason;
        threadId = other.threadId;
        newStreamSeqNum = other.newStreamSeqNum;
        newPredictionSeqNum = other.newPredictionSeqNum;
        set(target, other.target);
        inst = other.inst;
        return *this;
    }

    /** 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
     *  Make lines bubbles by default */
    bool bubbleFlag = true;

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

    /** PC of the first inst within this sequence */
    std::unique_ptr<PCStateBase> pc;

    /** Address of this line of data */
    Addr fetchAddr;

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

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

    /** 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 = nullptr;

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

  public:
    ForwardLineData() {}
    ForwardLineData(const ForwardLineData &other) :
        bubbleFlag(other.bubbleFlag), lineBaseAddr(other.lineBaseAddr),
        pc(other.pc->clone()), fetchAddr(other.fetchAddr),
        lineWidth(other.lineWidth), fault(other.fault), id(other.id),
        line(other.line), packet(other.packet)
    {}
    ForwardLineData &
    operator=(const ForwardLineData &other)
    {
        bubbleFlag = other.bubbleFlag;
        lineBaseAddr = other.lineBaseAddr;
        set(pc, other.pc);
        fetchAddr = other.fetchAddr;
        lineWidth = other.lineWidth;
        fault = other.fault;
        id = other.id;
        line = other.line;
        packet = other.packet;
        return *this;
    }

    ~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;
};

} // namespace minor
} // namespace gem5

#endif /* __CPU_MINOR_PIPE_DATA_HH__ */
