/*
 * Copyright (c) 2012 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.
 *
 * Copyright (c) 2004-2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * 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.
 */

#ifndef __CPU_O3_DECODE_HH__
#define __CPU_O3_DECODE_HH__

#include <queue>

#include "base/statistics.hh"
#include "cpu/o3/comm.hh"
#include "cpu/o3/dyn_inst_ptr.hh"
#include "cpu/o3/limits.hh"
#include "cpu/timebuf.hh"

namespace gem5
{

struct O3CPUParams;

namespace o3
{

class CPU;

/**
 * Decode class handles both single threaded and SMT
 * decode. Its width is specified by the parameters; each cycles it
 * tries to decode that many instructions. Because instructions are
 * actually decoded when the StaticInst is created, this stage does
 * not do much other than check any PC-relative branches.
 */
class Decode
{
  public:
    /** Overall decode stage status. Used to determine if the CPU can
     * deschedule itself due to a lack of activity.
     */
    enum DecodeStatus
    {
        Active,
        Inactive
    };

    /** Individual thread status. */
    enum ThreadStatus
    {
        Running,
        Idle,
        StartSquash,
        Squashing,
        Blocked,
        Unblocking
    };

  private:
    /** Decode status. */
    DecodeStatus _status;

    /** Per-thread status. */
    ThreadStatus decodeStatus[MaxThreads];

  public:
    /** Decode constructor. */
    Decode(CPU *_cpu, const O3CPUParams &params);

    void startupStage();

    /** Clear all thread-specific states */
    void clearStates(ThreadID tid);

    void resetStage();

    /** Returns the name of decode. */
    std::string name() const;

    /** Sets the main backwards communication time buffer pointer. */
    void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);

    /** Sets pointer to time buffer used to communicate to the next stage. */
    void setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr);

    /** Sets pointer to time buffer coming from fetch. */
    void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);

    /** Sets pointer to list of active threads. */
    void setActiveThreads(std::list<ThreadID> *at_ptr);

    /** Perform sanity checks after a drain. */
    void drainSanityCheck() const;

    /** Has the stage drained? */
    bool isDrained() const;

    /** Takes over from another CPU's thread. */
    void takeOverFrom() { resetStage(); }

    /** Ticks decode, processing all input signals and decoding as many
     * instructions as possible.
     */
    void tick();

    /** Determines what to do based on decode's current status.
     * @param status_change decode() sets this variable if there was a status
     * change (ie switching from from blocking to unblocking).
     * @param tid Thread id to decode instructions from.
     */
    void decode(bool &status_change, ThreadID tid);

    /** Processes instructions from fetch and passes them on to rename.
     * Decoding of instructions actually happens when they are created in
     * fetch, so this function mostly checks if PC-relative branches are
     * correct.
     */
    void decodeInsts(ThreadID tid);

  private:
    /** Inserts a thread's instructions into the skid buffer, to be decoded
     * once decode unblocks.
     */
    void skidInsert(ThreadID tid);

    /** Returns if all of the skid buffers are empty. */
    bool skidsEmpty();

    /** Updates overall decode status based on all of the threads' statuses. */
    void updateStatus();

    /** Separates instructions from fetch into individual lists of instructions
     * sorted by thread.
     */
    void sortInsts();

    /** Reads all stall signals from the backwards communication timebuffer. */
    void readStallSignals(ThreadID tid);

    /** Checks all input signals and updates decode's status appropriately. */
    bool checkSignalsAndUpdate(ThreadID tid);

    /** Checks all stall signals, and returns if any are true. */
    bool checkStall(ThreadID tid) const;

    /** Returns if there any instructions from fetch on this cycle. */
    bool fetchInstsValid();

    /** Switches decode to blocking, and signals back that decode has
     * become blocked.
     * @return Returns true if there is a status change.
     */
    bool block(ThreadID tid);

    /** Switches decode to unblocking if the skid buffer is empty, and
     * signals back that decode has unblocked.
     * @return Returns true if there is a status change.
     */
    bool unblock(ThreadID tid);

    /** Squashes if there is a PC-relative branch that was predicted
     * incorrectly. Sends squash information back to fetch.
     */
    void squash(const DynInstPtr &inst, ThreadID tid);

  public:
    /** Squashes due to commit signalling a squash. Changes status to
     * squashing and clears block/unblock signals as needed.
     */
    unsigned squash(ThreadID tid);

  private:
    // Interfaces to objects outside of decode.
    /** CPU interface. */
    CPU *cpu;

    /** Time buffer interface. */
    TimeBuffer<TimeStruct> *timeBuffer;

    /** Wire to get rename's output from backwards time buffer. */
    TimeBuffer<TimeStruct>::wire fromRename;

    /** Wire to get iew's information from backwards time buffer. */
    TimeBuffer<TimeStruct>::wire fromIEW;

    /** Wire to get commit's information from backwards time buffer. */
    TimeBuffer<TimeStruct>::wire fromCommit;

    /** Wire to write information heading to previous stages. */
    // Might not be the best name as not only fetch will read it.
    TimeBuffer<TimeStruct>::wire toFetch;

    /** Decode instruction queue. */
    TimeBuffer<DecodeStruct> *decodeQueue;

    /** Wire used to write any information heading to rename. */
    TimeBuffer<DecodeStruct>::wire toRename;

    /** Fetch instruction queue interface. */
    TimeBuffer<FetchStruct> *fetchQueue;

    /** Wire to get fetch's output from fetch queue. */
    TimeBuffer<FetchStruct>::wire fromFetch;

    /** Queue of all instructions coming from fetch this cycle. */
    std::queue<DynInstPtr> insts[MaxThreads];

    /** Skid buffer between fetch and decode. */
    std::queue<DynInstPtr> skidBuffer[MaxThreads];

    /** Variable that tracks if decode has written to the time buffer this
     * cycle. Used to tell CPU if there is activity this cycle.
     */
    bool wroteToTimeBuffer;

    /** Source of possible stalls. */
    struct Stalls
    {
        bool rename;
    };

    /** Tracks which stages are telling decode to stall. */
    Stalls stalls[MaxThreads];

    /** Rename to decode delay. */
    Cycles renameToDecodeDelay;

    /** IEW to decode delay. */
    Cycles iewToDecodeDelay;

    /** Commit to decode delay. */
    Cycles commitToDecodeDelay;

    /** Fetch to decode delay. */
    Cycles fetchToDecodeDelay;

    /** The width of decode, in instructions. */
    unsigned decodeWidth;

    /** Index of instructions being sent to rename. */
    unsigned toRenameIndex;

    /** number of Active Threads*/
    ThreadID numThreads;

    /** List of active thread ids */
    std::list<ThreadID> *activeThreads;

    /** Maximum size of the skid buffer. */
    unsigned skidBufferMax;

    /** SeqNum of Squashing Branch Delay Instruction (used for MIPS)*/
    Addr bdelayDoneSeqNum[MaxThreads];

    /** Instruction used for squashing branch (used for MIPS)*/
    DynInstPtr squashInst[MaxThreads];

    /** Tells when their is a pending delay slot inst. to send
     *  to rename. If there is, then wait squash after the next
     *  instruction (used for MIPS).
     */
    bool squashAfterDelaySlot[MaxThreads];

    struct DecodeStats : public statistics::Group
    {
        DecodeStats(CPU *cpu);

        /** Stat for total number of idle cycles. */
        statistics::Scalar idleCycles;
        /** Stat for total number of blocked cycles. */
        statistics::Scalar blockedCycles;
        /** Stat for total number of normal running cycles. */
        statistics::Scalar runCycles;
        /** Stat for total number of unblocking cycles. */
        statistics::Scalar unblockCycles;
        /** Stat for total number of squashing cycles. */
        statistics::Scalar squashCycles;
        /** Stat for number of times a branch is resolved at decode. */
        statistics::Scalar branchResolved;
        /** Stat for number of times a branch mispredict is detected. */
        statistics::Scalar branchMispred;
        /** Stat for number of times decode detected a non-control instruction
         * incorrectly predicted as a branch.
         */
        statistics::Scalar controlMispred;
        /** Stat for total number of decoded instructions. */
        statistics::Scalar decodedInsts;
        /** Stat for total number of squashed instructions. */
        statistics::Scalar squashedInsts;
    } stats;
};

} // namespace o3
} // namespace gem5

#endif // __CPU_O3_DECODE_HH__
