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

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 BaseO3CPUParams &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__
