/*
 * Copyright (c) 2007 MIPS Technologies, Inc.
 * Copyright (c) 2013 Advanced Micro Devices, Inc.
 * 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.
 *
 * Authors: Korey Sewell
 *
 */

#include <list>
#include <vector>

#include "arch/isa_traits.hh"
#include "config/the_isa.hh"
#include "cpu/inorder/resources/use_def.hh"
#include "cpu/inorder/cpu.hh"
#include "cpu/inorder/pipeline_traits.hh"
#include "debug/InOrderStall.hh"
#include "debug/InOrderUseDef.hh"

using namespace std;
using namespace TheISA;
using namespace ThePipeline;

UseDefUnit::UseDefUnit(string res_name, int res_id, int res_width,
                       Cycles res_latency, InOrderCPU *_cpu,
                       ThePipeline::Params *params)
    : Resource(res_name, res_id, res_width, res_latency, _cpu)
{
    for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
        nonSpecInstActive[tid] = &cpu->nonSpecInstActive[tid];
        nonSpecSeqNum[tid] = &cpu->nonSpecSeqNum[tid];
        serializeOnNextInst[tid] =  false;
        serializeAfterSeqNum[tid] = 0;
        regDepMap[tid] = &cpu->archRegDepMap[tid];
    }

}

void
UseDefUnit::regStats()
{
    uniqueRegsPerSwitch
        .name(name() + ".uniqueRegsPerSwitch")
        .desc("Number of Unique Registers Needed Per Context Switch")
        .prereq(uniqueRegsPerSwitch);

    intRegFileReads
        .name(name() + ".intRegFileReads")
        .desc("Number of Reads from Int. Register File");

    intRegFileWrites
        .name(name() + ".intRegFileWrites")
        .desc("Number of Writes to Int. Register File");

    intRegFileAccs
        .name(name() + ".intRegFileAccesses")
        .desc("Total Accesses (Read+Write) to the Int. Register File");
    intRegFileAccs = intRegFileReads + intRegFileWrites;

    floatRegFileReads
        .name(name() + ".floatRegFileReads")
        .desc("Number of Reads from FP Register File");

    floatRegFileWrites
        .name(name() + ".floatRegFileWrites")
        .desc("Number of Writes to FP Register File");

    floatRegFileAccs
        .name(name() + ".floatRegFileAccesses")
        .desc("Total Accesses (Read+Write) to the FP Register File");
    floatRegFileAccs = floatRegFileReads + floatRegFileWrites;

    //@todo: add miscreg reads/writes
    //       add forwarding by type???

    regForwards
        .name(name() + ".regForwards")
        .desc("Number of Registers Read Through Forwarding Logic");
    
    Resource::regStats();
}

void
UseDefUnit::init()
{
    // Set Up Resource Events to Appropriate Resource BandWidth
    if (latency > Cycles(0)) {
        resourceEvent = new ResourceEvent[width];
    } else {
        resourceEvent = NULL;
    }

    for (int i = 0; i < width; i++) {
        reqs[i] = new UseDefRequest(this);
    }

    initSlots();
}

ResReqPtr
UseDefUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
                     int slot_num, unsigned cmd)
{
    UseDefRequest *ud_req = dynamic_cast<UseDefRequest*>(reqs[slot_num]);
    ud_req->setRequest(inst, stage_num, id, slot_num, cmd,
                       inst->curSkedEntry->idx);
    return ud_req;
}


ResReqPtr
UseDefUnit::findRequest(DynInstPtr inst)
{
    for (int i = 0; i < width; i++) {
        UseDefRequest* ud_req =
            dynamic_cast<UseDefRequest*>(reqs[i]);
        assert(ud_req);

        if (ud_req->valid &&
            ud_req->getInst() == inst &&
            ud_req->cmd == inst->curSkedEntry->cmd &&
            ud_req->useDefIdx == inst->curSkedEntry->idx) {
            return ud_req;
        }
    }

    return NULL;
}

void
UseDefUnit::execute(int slot_idx)
{
    UseDefRequest* ud_req = dynamic_cast<UseDefRequest*>(reqs[slot_idx]);
    DynInstPtr inst = ud_req->inst;
    ThreadID tid = inst->readTid();
    InstSeqNum seq_num = inst->seqNum;
    int ud_idx = ud_req->useDefIdx;

    if (serializeOnNextInst[tid] &&
        seq_num > serializeAfterSeqNum[tid]) {
        inst->setSerializeBefore();
        serializeOnNextInst[tid] = false;
    }

    if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
        cpu->instList[tid].front() != inst) {
        DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] Serialize before instruction encountered."
                " Blocking until pipeline is clear.\n", tid, seq_num);
        ud_req->done(false);
        return;
    } else if (inst->isStoreConditional() || inst->isSerializeAfter()) {
        DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] Serialize after instruction encountered."
                " Blocking until pipeline is clear.\n", tid, seq_num);
        serializeOnNextInst[tid] = true;
        serializeAfterSeqNum[tid] = seq_num;
    }

    if (inst->fault != NoFault) {
        DPRINTF(InOrderUseDef,
                "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
                "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(),
                inst->pcState());
        ud_req->done();
        return;
    }

    // If there is a non-speculative instruction
    // in the pipeline then stall instructions here
    // ---
    if (*nonSpecInstActive[tid] == true && seq_num > *nonSpecSeqNum[tid]) {
        DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] cannot execute because"
                "there is non-speculative instruction [sn:%i] has not "
                "graduated.\n", tid, seq_num, *nonSpecSeqNum[tid]);
        ud_req->done(false);
        return;
    } else if (inst->isNonSpeculative()) {
        *nonSpecInstActive[tid] = true;
        *nonSpecSeqNum[tid] = seq_num;
    }

    switch (ud_req->cmd)
    {
      case ReadSrcReg:
        {
            RegClass reg_type;
            RegIndex reg_idx = inst->_srcRegIdx[ud_idx];
            RegIndex flat_idx = cpu->flattenRegIdx(reg_idx, reg_type, tid);
            inst->flattenSrcReg(ud_idx, flat_idx);
            
            if (flat_idx == TheISA::ZeroReg && reg_type == IntRegClass) {
                DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Ignoring Reading of ISA-ZeroReg "
                        "(Int. Reg %i).\n", tid, inst->seqNum, flat_idx);
                ud_req->done();
                return;
            } else {
                DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Attempting to read source "
                        "register idx %i (reg #%i, flat#%i).\n",
                        tid, seq_num, ud_idx, reg_idx, flat_idx);
            }

            if (regDepMap[tid]->canRead(reg_type, flat_idx, inst)) {
                switch (reg_type)
                {
                  case IntRegClass:
                    {
                        uniqueIntRegMap[flat_idx] = true;

                        DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Reading Int Reg %i"
                                " (%i) from Register File:0x%x.\n",
                                tid, seq_num,
                                reg_idx, flat_idx,
                                cpu->readIntReg(flat_idx,inst->readTid()));
                        inst->setIntSrc(ud_idx,
                                        cpu->readIntReg(flat_idx,
                                                        inst->readTid()));
                        intRegFileReads++;
                    }
                    break;

                  case FloatRegClass:
                    {
                        uniqueFloatRegMap[flat_idx] = true;
                        DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Reading Float Reg %i"
                                " (%i) from Register File:%x (%08f).\n",
                                tid, seq_num,
                                reg_idx - FP_Reg_Base, flat_idx,
                                cpu->readFloatRegBits(flat_idx,
                                                      inst->readTid()),
                                cpu->readFloatReg(flat_idx,
                                                  inst->readTid()));

                        inst->setFloatSrc(ud_idx,
                                          cpu->readFloatReg(flat_idx,
                                                            inst->readTid()));
                        inst->setFloatRegBitsSrc(ud_idx,
                                                 cpu->readFloatRegBits(flat_idx,
                                                                       inst->readTid()));
                        floatRegFileReads++;
                    }
                    break;

                  case MiscRegClass:
                    {
                        uniqueMiscRegMap[flat_idx] = true;
                        DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Reading Misc Reg %i "
                                " (%i) from Register File:0x%x.\n",
                                tid, seq_num,
                                reg_idx - Misc_Reg_Base, flat_idx,
                                cpu->readMiscReg(flat_idx,
                                inst->readTid()));
                        inst->setIntSrc(ud_idx,
                                        cpu->readMiscReg(flat_idx,
                                                         inst->readTid()));
                    }
                    break;

                  default:
                    panic("Invalid Register Type: %i", reg_type);
                }

                ud_req->done();
            } else {
                // Look for forwarding opportunities
                DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_type,
                                                                     flat_idx,
                                                                     inst);

                if (forward_inst) {
                    int dest_reg_idx =
                        forward_inst->getDestIdxNum(flat_idx);

                    switch (reg_type)
                    {
                      case IntRegClass:
                        {
                            DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
                                    " reg %i (%i), value 0x%x from "
                                    "[sn:%i] to [sn:%i] source #%x.\n",
                                    tid, reg_idx, flat_idx,
                                    forward_inst->readIntResult(dest_reg_idx),
                                    forward_inst->seqNum, 
                                    inst->seqNum, ud_idx);
                            inst->setIntSrc(ud_idx, 
                                            forward_inst->
                                            readIntResult(dest_reg_idx));
                        }
                        break;

                      case FloatRegClass:
                        {
                            DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
                                    " reg %i (%i) value 0x%x from "
                                    "[sn:%i] to [sn:%i] source #%i.\n",
                                    tid, reg_idx - FP_Reg_Base, flat_idx,
                                    forward_inst->readFloatResult(dest_reg_idx),
                                    forward_inst->seqNum, inst->seqNum, ud_idx);
                            inst->setFloatSrc(ud_idx,
                                              forward_inst->
                                              readFloatResult(dest_reg_idx));
                        }
                        break;

                      case MiscRegClass:
                        {
                            DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
                                    " reg %i (%i) value 0x%x from "
                                    "[sn:%i] to [sn:%i] source #%i.\n",
                                    tid, reg_idx - Misc_Reg_Base, flat_idx,
                                    forward_inst->readIntResult(dest_reg_idx),
                                    forward_inst->seqNum, 
                                    inst->seqNum, ud_idx);
                            inst->setIntSrc(ud_idx, 
                                            forward_inst->
                                            readIntResult(dest_reg_idx));
                        }
                        break;

                      default:
                        panic("Invalid Register Type: %i", reg_type);
                    }

                    regForwards++;
                    ud_req->done();
                } else {
                    DPRINTF(InOrderUseDef, "[tid:%i]: Source register idx: %i "
                            "is not ready to read.\n",
                            tid, reg_idx);
                    DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to read "
                            "register (idx=%i)\n",
                            tid, reg_idx);
                    ud_req->done(false);
                }
            }
        }
        break;

      case WriteDestReg:
        {
            RegClass reg_type;
            RegIndex reg_idx = inst->_destRegIdx[ud_idx];
            RegIndex flat_idx = cpu->flattenRegIdx(reg_idx, reg_type, tid);

            if (flat_idx == TheISA::ZeroReg && reg_type == IntRegClass) {
                DPRINTF(IntRegs, "[tid:%i]: Ignoring Writing of ISA-ZeroReg "
                        "(Int. Reg %i)\n", tid, flat_idx);
                ud_req->done();
                return;
            }

            if (regDepMap[tid]->canWrite(reg_type, flat_idx, inst)) {
                DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Flattening register idx %i "
                        "(%i) and Attempting to write to Register File.\n",
                        tid, seq_num, reg_idx, flat_idx);

                switch (reg_type)
                {
                  case IntRegClass:
                    {
                        uniqueIntRegMap[flat_idx] = true;

                        DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing Int. Result "
                                "0x%x to register idx %i (%i).\n",
                                tid, seq_num, inst->readIntResult(ud_idx),
                                reg_idx, flat_idx);

                        // Remove Dependencies
                        regDepMap[tid]->removeFront(reg_type, flat_idx, inst);

                        cpu->setIntReg(flat_idx,
                                       inst->readIntResult(ud_idx),
                                       inst->readTid());
                        intRegFileWrites++;
                    }
                    break;

                  case FloatRegClass:
                    {
                        uniqueFloatRegMap[flat_idx] = true;

                        // Remove Reg. Dependecny Block on this Register
                        regDepMap[tid]->removeFront(reg_type, flat_idx, inst);

                        if (inst->resultType(ud_idx) == 
                            InOrderDynInst::FloatBits) {
                            DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing FP-Bits "
                                    "Result %08f (bits:0x%x) to register "
                                    "idx %i (%i).\n",
                                    tid, seq_num,
                                    inst->readFloatResult(ud_idx), 
                                    inst->readFloatBitsResult(ud_idx),
                                    reg_idx - FP_Reg_Base, flat_idx);

                            // Check for FloatRegBits Here
                            cpu->setFloatRegBits(flat_idx,
                                                 inst->readFloatBitsResult(ud_idx),
                                                 inst->readTid());
                        } else if (inst->resultType(ud_idx) == 
                                   InOrderDynInst::Float) {
                            DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing Float "
                                    "Result %08f (bits:0x%x) to register "
                                    "idx %i (%i).\n",
                                    tid, seq_num, inst->readFloatResult(ud_idx),
                                    inst->readIntResult(ud_idx), 
                                    reg_idx - FP_Reg_Base, flat_idx);

                            cpu->setFloatReg(flat_idx,
                                             inst->readFloatResult(ud_idx),
                                             inst->readTid());
                        } else if (inst->resultType(ud_idx) == 
                                   InOrderDynInst::Double) {
                            DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing Double "
                                    "Result %08f (bits:0x%x) to register "
                                    "idx %i (%i).\n",
                                    tid, seq_num,
                                    inst->readFloatResult(ud_idx), 
                                    inst->readIntResult(ud_idx), 
                                    reg_idx - FP_Reg_Base, flat_idx);

                            cpu->setFloatReg(flat_idx,
                                             inst->readFloatResult(ud_idx),
                                             inst->readTid());
                        } else {
                            panic("Result Type Not Set For [sn:%i] %s.\n", 
                                  inst->seqNum, inst->instName());
                        }

                        floatRegFileWrites++;
                    }
                    break;

                  case MiscRegClass:
                    {
                        uniqueMiscRegMap[flat_idx] = true;

                        DPRINTF(InOrderUseDef, "[tid:%i]: Writing Misc. 0x%x "
                                "to register idx %i.\n",
                                tid, inst->readIntResult(ud_idx), reg_idx - Misc_Reg_Base);

                        // Remove Dependencies
                        regDepMap[tid]->removeFront(reg_type, flat_idx, inst);

                        cpu->setMiscReg(flat_idx,
                                    inst->readIntResult(ud_idx),
                                        inst->readTid());
                    }
                    break;

                  default:
                    panic("Invalid Register Type: %i", reg_type);
                }

                ud_req->done();
            } else {
                DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Dest. register idx: %i is "
                        "not ready to write.\n",
                        tid, seq_num, reg_idx);
                DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to write "
                        "register (idx=%i)\n",
                        tid, reg_idx);
                ud_req->done(false);
            }
        }
        break;

      case MarkDestRegs:
        {
            regDepMap[tid]->insert(inst);
            ud_req->done();
        }
        break;

      default:
        fatal("Unrecognized command to %s", resName);
    }

}

void
UseDefUnit::updateAfterContextSwitch(DynInstPtr inst, ThreadID tid)
{
    uniqueRegsPerSwitch = uniqueIntRegMap.size() + uniqueFloatRegMap.size()
        + uniqueMiscRegMap.size();
    uniqueIntRegMap.clear();
    uniqueFloatRegMap.clear();
    uniqueMiscRegMap.clear();
}
