/*
 * Copyright (c) 2004-2005 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.
 */

// @todo: Fix the instantaneous communication among all the stages within
// iew.  There's a clear delay between issue and execute, yet backwards
// communication happens simultaneously.
// Update the statuses for each stage.

#include <queue>

#include "base/timebuf.hh"
#include "cpu/o3/iew.hh"

template<class Impl>
SimpleIEW<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst,
                                                SimpleIEW<Impl> *_iew)
    : Event(&mainEventQueue, CPU_Tick_Pri), inst(_inst), iewStage(_iew)
{
    this->setFlags(Event::AutoDelete);
}

template<class Impl>
void
SimpleIEW<Impl>::WritebackEvent::process()
{
    DPRINTF(IEW, "IEW: WRITEBACK EVENT!!!!\n");

    // Need to insert instruction into queue to commit
    iewStage->instToCommit(inst);
    // Need to execute second half of the instruction, do actual writing to
    // registers and such
    inst->execute();
}

template<class Impl>
const char *
SimpleIEW<Impl>::WritebackEvent::description()
{
    return "LSQ writeback event";
}

template<class Impl>
SimpleIEW<Impl>::SimpleIEW(Params &params)
    : // Just make this time buffer really big for now
      issueToExecQueue(5, 5),
      instQueue(params),
      ldstQueue(params),
      commitToIEWDelay(params.commitToIEWDelay),
      renameToIEWDelay(params.renameToIEWDelay),
      issueToExecuteDelay(params.issueToExecuteDelay),
      issueReadWidth(params.issueWidth),
      issueWidth(params.issueWidth),
      executeWidth(params.executeWidth)
{
    DPRINTF(IEW, "IEW: executeIntWidth: %i.\n", params.executeIntWidth);
    _status = Idle;
    _issueStatus = Idle;
    _exeStatus = Idle;
    _wbStatus = Idle;

    // Setup wire to read instructions coming from issue.
    fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay);

    // Instruction queue needs the queue between issue and execute.
    instQueue.setIssueToExecuteQueue(&issueToExecQueue);

    ldstQueue.setIEW(this);
}

template <class Impl>
void
SimpleIEW<Impl>::regStats()
{
    instQueue.regStats();

    iewIdleCycles
        .name(name() + ".iewIdleCycles")
        .desc("Number of cycles IEW is idle");

    iewSquashCycles
        .name(name() + ".iewSquashCycles")
        .desc("Number of cycles IEW is squashing");

    iewBlockCycles
        .name(name() + ".iewBlockCycles")
        .desc("Number of cycles IEW is blocking");

    iewUnblockCycles
        .name(name() + ".iewUnblockCycles")
        .desc("Number of cycles IEW is unblocking");

//    iewWBInsts;

    iewDispatchedInsts
        .name(name() + ".iewDispatchedInsts")
        .desc("Number of instructions dispatched to IQ");

    iewDispSquashedInsts
        .name(name() + ".iewDispSquashedInsts")
        .desc("Number of squashed instructions skipped by dispatch");

    iewDispLoadInsts
        .name(name() + ".iewDispLoadInsts")
        .desc("Number of dispatched load instructions");

    iewDispStoreInsts
        .name(name() + ".iewDispStoreInsts")
        .desc("Number of dispatched store instructions");

    iewDispNonSpecInsts
        .name(name() + ".iewDispNonSpecInsts")
        .desc("Number of dispatched non-speculative instructions");

    iewIQFullEvents
        .name(name() + ".iewIQFullEvents")
        .desc("Number of times the IQ has become full, causing a stall");

    iewExecutedInsts
        .name(name() + ".iewExecutedInsts")
        .desc("Number of executed instructions");

    iewExecLoadInsts
        .name(name() + ".iewExecLoadInsts")
        .desc("Number of load instructions executed");

    iewExecStoreInsts
        .name(name() + ".iewExecStoreInsts")
        .desc("Number of store instructions executed");

    iewExecSquashedInsts
        .name(name() + ".iewExecSquashedInsts")
        .desc("Number of squashed instructions skipped in execute");

    memOrderViolationEvents
        .name(name() + ".memOrderViolationEvents")
        .desc("Number of memory order violations");

    predictedTakenIncorrect
        .name(name() + ".predictedTakenIncorrect")
        .desc("Number of branches that were predicted taken incorrectly");
}

template<class Impl>
void
SimpleIEW<Impl>::setCPU(FullCPU *cpu_ptr)
{
    DPRINTF(IEW, "IEW: Setting CPU pointer.\n");
    cpu = cpu_ptr;

    instQueue.setCPU(cpu_ptr);
    ldstQueue.setCPU(cpu_ptr);
}

template<class Impl>
void
SimpleIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
{
    DPRINTF(IEW, "IEW: Setting time buffer pointer.\n");
    timeBuffer = tb_ptr;

    // Setup wire to read information from time buffer, from commit.
    fromCommit = timeBuffer->getWire(-commitToIEWDelay);

    // Setup wire to write information back to previous stages.
    toRename = timeBuffer->getWire(0);

    // Instruction queue also needs main time buffer.
    instQueue.setTimeBuffer(tb_ptr);
}

template<class Impl>
void
SimpleIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
{
    DPRINTF(IEW, "IEW: Setting rename queue pointer.\n");
    renameQueue = rq_ptr;

    // Setup wire to read information from rename queue.
    fromRename = renameQueue->getWire(-renameToIEWDelay);
}

template<class Impl>
void
SimpleIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr)
{
    DPRINTF(IEW, "IEW: Setting IEW queue pointer.\n");
    iewQueue = iq_ptr;

    // Setup wire to write instructions to commit.
    toCommit = iewQueue->getWire(0);
}

template<class Impl>
void
SimpleIEW<Impl>::setRenameMap(RenameMap *rm_ptr)
{
    DPRINTF(IEW, "IEW: Setting rename map pointer.\n");
    renameMap = rm_ptr;
}

template<class Impl>
void
SimpleIEW<Impl>::squash()
{
    DPRINTF(IEW, "IEW: Squashing all instructions.\n");
    _status = Squashing;

    // Tell the IQ to start squashing.
    instQueue.squash();

    // Tell the LDSTQ to start squashing.
    ldstQueue.squash(fromCommit->commitInfo.doneSeqNum);
}

template<class Impl>
void
SimpleIEW<Impl>::squashDueToBranch(DynInstPtr &inst)
{
    DPRINTF(IEW, "IEW: Squashing from a specific instruction, PC: %#x.\n",
            inst->PC);
    // Perhaps leave the squashing up to the ROB stage to tell it when to
    // squash?
    _status = Squashing;

    // Tell rename to squash through the time buffer.
    toCommit->squash = true;
    // Also send PC update information back to prior stages.
    toCommit->squashedSeqNum = inst->seqNum;
    toCommit->mispredPC = inst->readPC();
    toCommit->nextPC = inst->readNextPC();
    toCommit->branchMispredict = true;
    // Prediction was incorrect, so send back inverse.
    toCommit->branchTaken = inst->readNextPC() !=
        (inst->readPC() + sizeof(MachInst));
}

template<class Impl>
void
SimpleIEW<Impl>::squashDueToMem(DynInstPtr &inst)
{
    DPRINTF(IEW, "IEW: Squashing from a specific instruction, PC: %#x.\n",
            inst->PC);
    // Perhaps leave the squashing up to the ROB stage to tell it when to
    // squash?
    _status = Squashing;

    // Tell rename to squash through the time buffer.
    toCommit->squash = true;
    // Also send PC update information back to prior stages.
    toCommit->squashedSeqNum = inst->seqNum;
    toCommit->nextPC = inst->readNextPC();
}

template<class Impl>
void
SimpleIEW<Impl>::block()
{
    DPRINTF(IEW, "IEW: Blocking.\n");
    // Set the status to Blocked.
    _status = Blocked;

    // Add the current inputs to the skid buffer so they can be
    // reprocessed when this stage unblocks.
    skidBuffer.push(*fromRename);

    // Note that this stage only signals previous stages to stall when
    // it is the cause of the stall originates at this stage.  Otherwise
    // the previous stages are expected to check all possible stall signals.
}

template<class Impl>
inline void
SimpleIEW<Impl>::unblock()
{
    // Check if there's information in the skid buffer.  If there is, then
    // set status to unblocking, otherwise set it directly to running.
    DPRINTF(IEW, "IEW: Reading instructions out of the skid "
            "buffer.\n");
    // Remove the now processed instructions from the skid buffer.
    skidBuffer.pop();

    // If there's still information in the skid buffer, then
    // continue to tell previous stages to stall.  They will be
    // able to restart once the skid buffer is empty.
    if (!skidBuffer.empty()) {
        toRename->iewInfo.stall = true;
    } else {
        DPRINTF(IEW, "IEW: Stage is done unblocking.\n");
        _status = Running;
    }
}

template<class Impl>
void
SimpleIEW<Impl>::wakeDependents(DynInstPtr &inst)
{
    instQueue.wakeDependents(inst);
}


template<class Impl>
void
SimpleIEW<Impl>::instToCommit(DynInstPtr &inst)
{

}

template <class Impl>
void
SimpleIEW<Impl>::dispatchInsts()
{
    ////////////////////////////////////////
    // DISPATCH/ISSUE stage
    ////////////////////////////////////////

    //Put into its own function?
    //Add instructions to IQ if there are any instructions there

    // Check if there are any instructions coming from rename, and we're.
    // not squashing.
    if (fromRename->size > 0) {
        int insts_to_add = fromRename->size;

        // Loop through the instructions, putting them in the instruction
        // queue.
        for (int inst_num = 0; inst_num < insts_to_add; ++inst_num)
        {
            DynInstPtr inst = fromRename->insts[inst_num];

            // Make sure there's a valid instruction there.
            assert(inst);

            DPRINTF(IEW, "IEW: Issue: Adding PC %#x to IQ.\n",
                    inst->readPC());

            // Be sure to mark these instructions as ready so that the
            // commit stage can go ahead and execute them, and mark
            // them as issued so the IQ doesn't reprocess them.
            if (inst->isSquashed()) {
                ++iewDispSquashedInsts;
                continue;
            } else if (instQueue.isFull()) {
                DPRINTF(IEW, "IEW: Issue: IQ has become full.\n");
                // Call function to start blocking.
                block();
                // Tell previous stage to stall.
                toRename->iewInfo.stall = true;

                ++iewIQFullEvents;
                break;
            } else if (inst->isLoad()) {
                DPRINTF(IEW, "IEW: Issue: Memory instruction "
                        "encountered, adding to LDSTQ.\n");

                // Reserve a spot in the load store queue for this
                // memory access.
                ldstQueue.insertLoad(inst);

                ++iewDispLoadInsts;
            } else if (inst->isStore()) {
                ldstQueue.insertStore(inst);

                ++iewDispStoreInsts;
            } else if (inst->isNonSpeculative()) {
                DPRINTF(IEW, "IEW: Issue: Nonspeculative instruction "
                        "encountered, skipping.\n");

                // Same hack as with stores.
                inst->setCanCommit();

                // Specificall insert it as nonspeculative.
                instQueue.insertNonSpec(inst);

                ++iewDispNonSpecInsts;

                continue;
            } else if (inst->isNop()) {
                DPRINTF(IEW, "IEW: Issue: Nop instruction encountered "
                        ", skipping.\n");

                inst->setIssued();
                inst->setExecuted();
                inst->setCanCommit();

                instQueue.advanceTail(inst);

                continue;
            } else if (inst->isExecuted()) {
                assert(0 && "Instruction shouldn't be executed.\n");
                DPRINTF(IEW, "IEW: Issue: Executed branch encountered, "
                        "skipping.\n");

                inst->setIssued();
                inst->setCanCommit();

                instQueue.advanceTail(inst);

                continue;
            }

            // If the instruction queue is not full, then add the
            // instruction.
            instQueue.insert(fromRename->insts[inst_num]);

            ++iewDispatchedInsts;
        }
    }
}

template <class Impl>
void
SimpleIEW<Impl>::executeInsts()
{
    ////////////////////////////////////////
    //EXECUTE/WRITEBACK stage
    ////////////////////////////////////////

    //Put into its own function?
    //Similarly should probably have separate execution for int vs FP.
    // Above comment is handled by the issue queue only issuing a valid
    // mix of int/fp instructions.
    //Actually okay to just have one execution, buuuuuut will need
    //somewhere that defines the execution latency of all instructions.
    // @todo: Move to the FU pool used in the current full cpu.

    int fu_usage = 0;
    bool fetch_redirect = false;
    int inst_slot = 0;
    int time_slot = 0;

    // Execute/writeback any instructions that are available.
    for (int inst_num = 0;
         fu_usage < executeWidth && /* Haven't exceeded available FU's. */
             inst_num < issueWidth &&
             fromIssue->insts[inst_num];
         ++inst_num) {

        DPRINTF(IEW, "IEW: Execute: Executing instructions from IQ.\n");

        // Get instruction from issue's queue.
        DynInstPtr inst = fromIssue->insts[inst_num];

        DPRINTF(IEW, "IEW: Execute: Processing PC %#x.\n", inst->readPC());

        // Check if the instruction is squashed; if so then skip it
        // and don't count it towards the FU usage.
        if (inst->isSquashed()) {
            DPRINTF(IEW, "IEW: Execute: Instruction was squashed.\n");

            // Consider this instruction executed so that commit can go
            // ahead and retire the instruction.
            inst->setExecuted();

            toCommit->insts[inst_num] = inst;

            ++iewExecSquashedInsts;

            continue;
        }

        inst->setExecuted();

        // If an instruction is executed, then count it towards FU usage.
        ++fu_usage;

        // Execute instruction.
        // Note that if the instruction faults, it will be handled
        // at the commit stage.
        if (inst->isMemRef()) {
            DPRINTF(IEW, "IEW: Execute: Calculating address for memory "
                    "reference.\n");

            // Tell the LDSTQ to execute this instruction (if it is a load).
            if (inst->isLoad()) {
                ldstQueue.executeLoad(inst);

                ++iewExecLoadInsts;
            } else if (inst->isStore()) {
                ldstQueue.executeStore(inst);

                ++iewExecStoreInsts;
            } else {
                panic("IEW: Unexpected memory type!\n");
            }

        } else {
            inst->execute();

            ++iewExecutedInsts;
        }

        // First check the time slot that this instruction will write
        // to.  If there are free write ports at the time, then go ahead
        // and write the instruction to that time.  If there are not,
        // keep looking back to see where's the first time there's a
        // free slot.  What happens if you run out of free spaces?
        // For now naively assume that all instructions take one cycle.
        // Otherwise would have to look into the time buffer based on the
        // latency of the instruction.
        (*iewQueue)[time_slot].insts[inst_slot];
        while ((*iewQueue)[time_slot].insts[inst_slot]) {
            if (inst_slot < issueWidth) {
                ++inst_slot;
            } else {
                ++time_slot;
                inst_slot = 0;
            }

            assert(time_slot < 5);
        }

        // May actually have to work this out, especially with loads and stores

        // Add finished instruction to queue to commit.
        (*iewQueue)[time_slot].insts[inst_slot] = inst;
        (*iewQueue)[time_slot].size++;

        // Check if branch was correct.  This check happens after the
        // instruction is added to the queue because even if the branch
        // is mispredicted, the branch instruction itself is still valid.
        // Only handle this if there hasn't already been something that
        // redirects fetch in this group of instructions.
        if (!fetch_redirect) {
            if (inst->mispredicted()) {
                fetch_redirect = true;

                DPRINTF(IEW, "IEW: Execute: Branch mispredict detected.\n");
                DPRINTF(IEW, "IEW: Execute: Redirecting fetch to PC: %#x.\n",
                        inst->nextPC);

                // If incorrect, then signal the ROB that it must be squashed.
                squashDueToBranch(inst);

                if (inst->predTaken()) {
                    predictedTakenIncorrect++;
                }
            } else if (ldstQueue.violation()) {
                fetch_redirect = true;

                // Get the DynInst that caused the violation.
                DynInstPtr violator = ldstQueue.getMemDepViolator();

                DPRINTF(IEW, "IEW: LDSTQ detected a violation.  Violator PC: "
                        "%#x, inst PC: %#x.  Addr is: %#x.\n",
                        violator->readPC(), inst->readPC(), inst->physEffAddr);

                // Tell the instruction queue that a violation has occured.
                instQueue.violation(inst, violator);

                // Squash.
                squashDueToMem(inst);

                ++memOrderViolationEvents;
            }
        }
    }
}

template<class Impl>
void
SimpleIEW<Impl>::tick()
{
    // Considering putting all the state-determining stuff in this section.

    // Try to fill up issue queue with as many instructions as bandwidth
    // allows.
    // Decode should try to execute as many instructions as its bandwidth
    // will allow, as long as it is not currently blocked.

    // Check if the stage is in a running status.
    if (_status != Blocked && _status != Squashing) {
        DPRINTF(IEW, "IEW: Status is not blocked, attempting to run "
                     "stage.\n");
        iew();

        // If it's currently unblocking, check to see if it should switch
        // to running.
        if (_status == Unblocking) {
            unblock();

            ++iewUnblockCycles;
        }
    } else if (_status == Squashing) {

        DPRINTF(IEW, "IEW: Still squashing.\n");

        // Check if stage should remain squashing.  Stop squashing if the
        // squash signal clears.
        if (!fromCommit->commitInfo.squash &&
            !fromCommit->commitInfo.robSquashing) {
            DPRINTF(IEW, "IEW: Done squashing, changing status to "
                    "running.\n");

            _status = Running;
            instQueue.stopSquash();
        } else {
            instQueue.doSquash();
        }

        ++iewSquashCycles;
    } else if (_status == Blocked) {
        // Continue to tell previous stage to stall.
        toRename->iewInfo.stall = true;

        // Check if possible stall conditions have cleared.
        if (!fromCommit->commitInfo.stall &&
            !instQueue.isFull()) {
            DPRINTF(IEW, "IEW: Stall signals cleared, going to unblock.\n");
            _status = Unblocking;
        }

        // If there's still instructions coming from rename, continue to
        // put them on the skid buffer.
        if (fromRename->size == 0) {
            block();
        }

        if (fromCommit->commitInfo.squash ||
            fromCommit->commitInfo.robSquashing) {
            squash();
        }

        ++iewBlockCycles;
    }

    // @todo: Maybe put these at the beginning, so if it's idle it can
    // return early.
    // Write back number of free IQ entries here.
    toRename->iewInfo.freeIQEntries = instQueue.numFreeEntries();

    ldstQueue.writebackStores();

    // Check the committed load/store signals to see if there's a load
    // or store to commit.  Also check if it's being told to execute a
    // nonspeculative instruction.
    // This is pretty inefficient...
    if (!fromCommit->commitInfo.squash &&
        !fromCommit->commitInfo.robSquashing) {
        ldstQueue.commitStores(fromCommit->commitInfo.doneSeqNum);
        ldstQueue.commitLoads(fromCommit->commitInfo.doneSeqNum);
    }

    if (fromCommit->commitInfo.nonSpecSeqNum != 0) {
        instQueue.scheduleNonSpec(fromCommit->commitInfo.nonSpecSeqNum);
    }

    DPRINTF(IEW, "IEW: IQ has %i free entries.\n",
            instQueue.numFreeEntries());
}

template<class Impl>
void
SimpleIEW<Impl>::iew()
{
    // Might want to put all state checks in the tick() function.
    // Check if being told to stall from commit.
    if (fromCommit->commitInfo.stall) {
        block();
        return;
    } else if (fromCommit->commitInfo.squash ||
               fromCommit->commitInfo.robSquashing) {
        // Also check if commit is telling this stage to squash.
        squash();
        return;
    }

    dispatchInsts();

    // Have the instruction queue try to schedule any ready instructions.
    instQueue.scheduleReadyInsts();

    executeInsts();

    // Loop through the head of the time buffer and wake any dependents.
    // These instructions are about to write back.  In the simple model
    // this loop can really happen within the previous loop, but when
    // instructions have actual latencies, this loop must be separate.
    // Also mark scoreboard that this instruction is finally complete.
    // Either have IEW have direct access to rename map, or have this as
    // part of backwards communication.
    for (int inst_num = 0; inst_num < issueWidth &&
             toCommit->insts[inst_num]; inst_num++)
    {
        DynInstPtr inst = toCommit->insts[inst_num];

        DPRINTF(IEW, "IEW: Sending instructions to commit, PC %#x.\n",
                inst->readPC());

        if(!inst->isSquashed()) {
            instQueue.wakeDependents(inst);

            for (int i = 0; i < inst->numDestRegs(); i++)
            {
                renameMap->markAsReady(inst->renamedDestRegIdx(i));
            }
        }
    }

    // Also should advance its own time buffers if the stage ran.
    // Not the best place for it, but this works (hopefully).
    issueToExecQueue.advance();
}

#ifndef FULL_SYSTEM
template<class Impl>
void
SimpleIEW<Impl>::lsqWriteback()
{
    ldstQueue.writebackAllInsts();
}
#endif
