/*
 * Copyright (c) 2011-2012, 2016-2018 ARM Limited
 * Copyright (c) 2013 Advanced Micro Devices, Inc.
 * 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) 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_CHECKER_THREAD_CONTEXT_HH__
#define __CPU_CHECKER_THREAD_CONTEXT_HH__

#include "arch/types.hh"
#include "config/the_isa.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "debug/Checker.hh"

namespace TheISA
{
    class Decoder;
} // namespace TheISA

/**
 * Derived ThreadContext class for use with the Checker.  The template
 * parameter is the ThreadContext class used by the specific CPU being
 * verified.  This CheckerThreadContext is then used by the main CPU
 * in place of its usual ThreadContext class.  It handles updating the
 * checker's state any time state is updated externally through the
 * ThreadContext.
 */
template <class TC>
class CheckerThreadContext : public ThreadContext
{
  public:
    CheckerThreadContext(TC *actual_tc,
                         CheckerCPU *checker_cpu)
        : actualTC(actual_tc), checkerTC(checker_cpu->thread),
          checkerCPU(checker_cpu)
    { }

  private:
    /** The main CPU's ThreadContext, or class that implements the
     * ThreadContext interface. */
    TC *actualTC;
    /** The checker's own SimpleThread. Will be updated any time
     * anything uses this ThreadContext to externally update a
     * thread's state. */
    SimpleThread *checkerTC;
    /** Pointer to the checker CPU. */
    CheckerCPU *checkerCPU;

  public:
    bool schedule(PCEvent *e) override { return actualTC->schedule(e); }
    bool remove(PCEvent *e) override { return actualTC->remove(e); }

    void
    scheduleInstCountEvent(Event *event, Tick count) override
    {
        actualTC->scheduleInstCountEvent(event, count);
    }
    void
    descheduleInstCountEvent(Event *event) override
    {
        actualTC->descheduleInstCountEvent(event);
    }
    Tick
    getCurrentInstCount() override
    {
        return actualTC->getCurrentInstCount();
    }

    BaseCPU *getCpuPtr() override { return actualTC->getCpuPtr(); }

    uint32_t socketId() const override { return actualTC->socketId(); }

    int cpuId() const override { return actualTC->cpuId(); }

    ContextID contextId() const override { return actualTC->contextId(); }

    void
    setContextId(ContextID id) override
    {
       actualTC->setContextId(id);
       checkerTC->setContextId(id);
    }

    /** Returns this thread's ID number. */
    int threadId() const override { return actualTC->threadId(); }
    void
    setThreadId(int id) override
    {
        checkerTC->setThreadId(id);
        actualTC->setThreadId(id);
    }

    BaseTLB *getITBPtr() override { return actualTC->getITBPtr(); }

    BaseTLB *getDTBPtr() override { return actualTC->getDTBPtr(); }

    CheckerCPU *
    getCheckerCpuPtr() override
    {
        return checkerCPU;
    }

    BaseISA *getIsaPtr() override { return actualTC->getIsaPtr(); }

    TheISA::Decoder *
    getDecoderPtr() override
    {
        return actualTC->getDecoderPtr();
    }

    System *getSystemPtr() override { return actualTC->getSystemPtr(); }

    Process *getProcessPtr() override { return actualTC->getProcessPtr(); }

    void setProcessPtr(Process *p) override { actualTC->setProcessPtr(p); }

    PortProxy &getPhysProxy() override { return actualTC->getPhysProxy(); }

    PortProxy &
    getVirtProxy() override
    {
        return actualTC->getVirtProxy();
    }

    void
    initMemProxies(ThreadContext *tc) override
    {
        actualTC->initMemProxies(tc);
    }

    void
    connectMemPorts(ThreadContext *tc)
    {
        actualTC->connectMemPorts(tc);
    }

    /** Executes a syscall in SE mode. */
    void
    syscall(Fault *fault) override
    {
        return actualTC->syscall(fault);
    }

    Status status() const override { return actualTC->status(); }

    void
    setStatus(Status new_status) override
    {
        actualTC->setStatus(new_status);
        checkerTC->setStatus(new_status);
    }

    /// Set the status to Active.
    void activate() override { actualTC->activate(); }

    /// Set the status to Suspended.
    void suspend() override { actualTC->suspend(); }

    /// Set the status to Halted.
    void halt() override { actualTC->halt(); }

    void
    takeOverFrom(ThreadContext *oldContext) override
    {
        actualTC->takeOverFrom(oldContext);
        checkerTC->copyState(oldContext);
    }

    void
    regStats(const std::string &name) override
    {
        actualTC->regStats(name);
        checkerTC->regStats(name);
    }

    Tick readLastActivate() override { return actualTC->readLastActivate(); }
    Tick readLastSuspend() override { return actualTC->readLastSuspend(); }

    // @todo: Do I need this?
    void
    copyArchRegs(ThreadContext *tc) override
    {
        actualTC->copyArchRegs(tc);
        checkerTC->copyArchRegs(tc);
    }

    void
    clearArchRegs() override
    {
        actualTC->clearArchRegs();
        checkerTC->clearArchRegs();
    }

    //
    // New accessors for new decoder.
    //
    RegVal
    readIntReg(RegIndex reg_idx) const override
    {
        return actualTC->readIntReg(reg_idx);
    }

    RegVal
    readFloatReg(RegIndex reg_idx) const override
    {
        return actualTC->readFloatReg(reg_idx);
    }

    const VecRegContainer &
    readVecReg (const RegId &reg) const override
    {
        return actualTC->readVecReg(reg);
    }

    /**
     * Read vector register for modification, hierarchical indexing.
     */
    VecRegContainer &
    getWritableVecReg (const RegId &reg) override
    {
        return actualTC->getWritableVecReg(reg);
    }

    /** Vector Register Lane Interfaces. */
    /** @{ */
    /** Reads source vector 8bit operand. */
    ConstVecLane8
    readVec8BitLaneReg(const RegId &reg) const override
    {
        return actualTC->readVec8BitLaneReg(reg);
    }

    /** Reads source vector 16bit operand. */
    ConstVecLane16
    readVec16BitLaneReg(const RegId &reg) const override
    {
        return actualTC->readVec16BitLaneReg(reg);
    }

    /** Reads source vector 32bit operand. */
    ConstVecLane32
    readVec32BitLaneReg(const RegId &reg) const override
    {
        return actualTC->readVec32BitLaneReg(reg);
    }

    /** Reads source vector 64bit operand. */
    ConstVecLane64
    readVec64BitLaneReg(const RegId &reg) const override
    {
        return actualTC->readVec64BitLaneReg(reg);
    }

    /** Write a lane of the destination vector register. */
    virtual void
    setVecLane(const RegId &reg,
               const LaneData<LaneSize::Byte> &val) override
    {
        return actualTC->setVecLane(reg, val);
    }
    virtual void
    setVecLane(const RegId &reg,
               const LaneData<LaneSize::TwoByte> &val) override
    {
        return actualTC->setVecLane(reg, val);
    }
    virtual void
    setVecLane(const RegId &reg,
               const LaneData<LaneSize::FourByte> &val) override
    {
        return actualTC->setVecLane(reg, val);
    }
    virtual void
    setVecLane(const RegId &reg,
               const LaneData<LaneSize::EightByte> &val) override
    {
        return actualTC->setVecLane(reg, val);
    }
    /** @} */

    const VecElem &
    readVecElem(const RegId& reg) const override
    {
        return actualTC->readVecElem(reg);
    }

    const VecPredRegContainer &
    readVecPredReg(const RegId& reg) const override
    {
        return actualTC->readVecPredReg(reg);
    }

    VecPredRegContainer &
    getWritableVecPredReg(const RegId& reg) override
    {
        return actualTC->getWritableVecPredReg(reg);
    }

    RegVal
    readCCReg(RegIndex reg_idx) const override
    {
        return actualTC->readCCReg(reg_idx);
    }

    void
    setIntReg(RegIndex reg_idx, RegVal val) override
    {
        actualTC->setIntReg(reg_idx, val);
        checkerTC->setIntReg(reg_idx, val);
    }

    void
    setFloatReg(RegIndex reg_idx, RegVal val) override
    {
        actualTC->setFloatReg(reg_idx, val);
        checkerTC->setFloatReg(reg_idx, val);
    }

    void
    setVecReg(const RegId& reg, const VecRegContainer& val) override
    {
        actualTC->setVecReg(reg, val);
        checkerTC->setVecReg(reg, val);
    }

    void
    setVecElem(const RegId& reg, const VecElem& val) override
    {
        actualTC->setVecElem(reg, val);
        checkerTC->setVecElem(reg, val);
    }

    void
    setVecPredReg(const RegId& reg, const VecPredRegContainer& val) override
    {
        actualTC->setVecPredReg(reg, val);
        checkerTC->setVecPredReg(reg, val);
    }

    void
    setCCReg(RegIndex reg_idx, RegVal val) override
    {
        actualTC->setCCReg(reg_idx, val);
        checkerTC->setCCReg(reg_idx, val);
    }

    /** Reads this thread's PC state. */
    TheISA::PCState pcState() const override { return actualTC->pcState(); }

    /** Sets this thread's PC state. */
    void
    pcState(const TheISA::PCState &val) override
    {
        DPRINTF(Checker, "Changing PC to %s, old PC %s\n",
                         val, checkerTC->pcState());
        checkerTC->pcState(val);
        checkerCPU->recordPCChange(val);
        return actualTC->pcState(val);
    }

    void
    setNPC(Addr val)
    {
        checkerTC->setNPC(val);
        actualTC->setNPC(val);
    }

    void
    pcStateNoRecord(const TheISA::PCState &val) override
    {
        return actualTC->pcState(val);
    }

    /** Reads this thread's PC. */
    Addr instAddr() const override { return actualTC->instAddr(); }

    /** Reads this thread's next PC. */
    Addr nextInstAddr() const override { return actualTC->nextInstAddr(); }

    /** Reads this thread's next PC. */
    MicroPC microPC() const override { return actualTC->microPC(); }

    RegVal
    readMiscRegNoEffect(RegIndex misc_reg) const override
    {
        return actualTC->readMiscRegNoEffect(misc_reg);
    }

    RegVal
    readMiscReg(RegIndex misc_reg) override
    {
        return actualTC->readMiscReg(misc_reg);
    }

    void
    setMiscRegNoEffect(RegIndex misc_reg, RegVal val) override
    {
        DPRINTF(Checker, "Setting misc reg with no effect: %d to both Checker"
                         " and O3..\n", misc_reg);
        checkerTC->setMiscRegNoEffect(misc_reg, val);
        actualTC->setMiscRegNoEffect(misc_reg, val);
    }

    void
    setMiscReg(RegIndex misc_reg, RegVal val) override
    {
        DPRINTF(Checker, "Setting misc reg with effect: %d to both Checker"
                         " and O3..\n", misc_reg);
        checkerTC->setMiscReg(misc_reg, val);
        actualTC->setMiscReg(misc_reg, val);
    }

    RegId
    flattenRegId(const RegId& regId) const override
    {
        return actualTC->flattenRegId(regId);
    }

    unsigned
    readStCondFailures() const override
    {
        return actualTC->readStCondFailures();
    }

    void
    setStCondFailures(unsigned sc_failures) override
    {
        actualTC->setStCondFailures(sc_failures);
    }

    Counter
    readFuncExeInst() const override
    {
        return actualTC->readFuncExeInst();
    }

    RegVal
    readIntRegFlat(RegIndex idx) const override
    {
        return actualTC->readIntRegFlat(idx);
    }

    void
    setIntRegFlat(RegIndex idx, RegVal val) override
    {
        actualTC->setIntRegFlat(idx, val);
    }

    RegVal
    readFloatRegFlat(RegIndex idx) const override
    {
        return actualTC->readFloatRegFlat(idx);
    }

    void
    setFloatRegFlat(RegIndex idx, RegVal val) override
    {
        actualTC->setFloatRegFlat(idx, val);
    }

    const VecRegContainer &
    readVecRegFlat(RegIndex idx) const override
    {
        return actualTC->readVecRegFlat(idx);
    }

    /**
     * Read vector register for modification, flat indexing.
     */
    VecRegContainer &
    getWritableVecRegFlat(RegIndex idx) override
    {
        return actualTC->getWritableVecRegFlat(idx);
    }

    void
    setVecRegFlat(RegIndex idx, const VecRegContainer& val) override
    {
        actualTC->setVecRegFlat(idx, val);
    }

    const VecElem &
    readVecElemFlat(RegIndex idx, const ElemIndex& elem_idx) const override
    {
        return actualTC->readVecElemFlat(idx, elem_idx);
    }

    void
    setVecElemFlat(RegIndex idx,
                   const ElemIndex& elem_idx, const VecElem& val) override
    {
        actualTC->setVecElemFlat(idx, elem_idx, val);
    }

    const VecPredRegContainer &
    readVecPredRegFlat(RegIndex idx) const override
    {
        return actualTC->readVecPredRegFlat(idx);
    }

    VecPredRegContainer &
    getWritableVecPredRegFlat(RegIndex idx) override
    {
        return actualTC->getWritableVecPredRegFlat(idx);
    }

    void
    setVecPredRegFlat(RegIndex idx, const VecPredRegContainer& val) override
    {
        actualTC->setVecPredRegFlat(idx, val);
    }

    RegVal
    readCCRegFlat(RegIndex idx) const override
    {
        return actualTC->readCCRegFlat(idx);
    }

    void
    setCCRegFlat(RegIndex idx, RegVal val) override
    {
        actualTC->setCCRegFlat(idx, val);
    }
};

#endif // __CPU_CHECKER_EXEC_CONTEXT_HH__
