/*
 * Copyright (c) 2014-2018, 2020 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) 2002-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.
 */

#ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__
#define __CPU_SIMPLE_EXEC_CONTEXT_HH__

#include "arch/registers.hh"
#include "base/types.hh"
#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/exec_context.hh"
#include "cpu/reg_class.hh"
#include "cpu/simple/base.hh"
#include "cpu/static_inst_fwd.hh"
#include "cpu/translation.hh"
#include "mem/request.hh"

class BaseSimpleCPU;

class SimpleExecContext : public ExecContext
{
  public:
    BaseSimpleCPU *cpu;
    SimpleThread* thread;

    // This is the offset from the current pc that fetch should be performed
    Addr fetchOffset;
    // This flag says to stay at the current pc. This is useful for
    // instructions which go beyond MachInst boundaries.
    bool stayAtPC;

    // Branch prediction
    TheISA::PCState predPC;

    /** PER-THREAD STATS */
    Counter numInst;
    Counter numOp;
    // Number of simulated loads
    Counter numLoad;
    // Number of cycles stalled for I-cache responses
    Counter lastIcacheStall;
    // Number of cycles stalled for D-cache responses
    Counter lastDcacheStall;

    struct ExecContextStats : public Stats::Group
    {
        ExecContextStats(BaseSimpleCPU *cpu, SimpleThread *thread)
            : Stats::Group(cpu,
                           csprintf("exec_context.thread_%i",
                                    thread->threadId()).c_str()),
              ADD_STAT(numInsts, UNIT_COUNT,
                       "Number of instructions committed"),
              ADD_STAT(numOps, UNIT_COUNT,
                       "Number of ops (including micro ops) committed"),
              ADD_STAT(numIntAluAccesses, UNIT_COUNT,
                       "Number of integer alu accesses"),
              ADD_STAT(numFpAluAccesses, UNIT_COUNT,
                       "Number of float alu accesses"),
              ADD_STAT(numVecAluAccesses, UNIT_COUNT,
                       "Number of vector alu accesses"),
              ADD_STAT(numCallsReturns, UNIT_COUNT,
                       "Number of times a function call or return occured"),
              ADD_STAT(numCondCtrlInsts, UNIT_COUNT,
                       "Number of instructions that are conditional controls"),
              ADD_STAT(numIntInsts, UNIT_COUNT,
                       "Number of integer instructions"),
              ADD_STAT(numFpInsts, UNIT_COUNT, "Number of float instructions"),
              ADD_STAT(numVecInsts, UNIT_COUNT,
                       "Number of vector instructions"),
              ADD_STAT(numIntRegReads, UNIT_COUNT,
                       "Number of times the integer registers were read"),
              ADD_STAT(numIntRegWrites, UNIT_COUNT,
                       "Number of times the integer registers were written"),
              ADD_STAT(numFpRegReads, UNIT_COUNT,
                       "Number of times the floating registers were read"),
              ADD_STAT(numFpRegWrites, UNIT_COUNT,
                       "Number of times the floating registers were written"),
              ADD_STAT(numVecRegReads, UNIT_COUNT,
                       "Number of times the vector registers were read"),
              ADD_STAT(numVecRegWrites, UNIT_COUNT,
                       "Number of times the vector registers were written"),
              ADD_STAT(numVecPredRegReads, UNIT_COUNT,
                       "Number of times the predicate registers were read"),
              ADD_STAT(numVecPredRegWrites, UNIT_COUNT,
                       "Number of times the predicate registers were written"),
              ADD_STAT(numCCRegReads, UNIT_COUNT,
                       "Number of times the CC registers were read"),
              ADD_STAT(numCCRegWrites, UNIT_COUNT,
                       "Number of times the CC registers were written"),
              ADD_STAT(numMemRefs, UNIT_COUNT, "Number of memory refs"),
              ADD_STAT(numLoadInsts, UNIT_COUNT,
                       "Number of load instructions"),
              ADD_STAT(numStoreInsts, UNIT_COUNT,
                       "Number of store instructions"),
              ADD_STAT(numIdleCycles, UNIT_CYCLE, "Number of idle cycles"),
              ADD_STAT(numBusyCycles, UNIT_CYCLE, "Number of busy cycles"),
              ADD_STAT(notIdleFraction, UNIT_RATIO,
                       "Percentage of non-idle cycles"),
              ADD_STAT(idleFraction, UNIT_RATIO, "Percentage of idle cycles"),
              ADD_STAT(icacheStallCycles, UNIT_CYCLE,
                       "ICache total stall cycles"),
              ADD_STAT(dcacheStallCycles, UNIT_CYCLE,
                       "DCache total stall cycles"),
              ADD_STAT(numBranches, UNIT_COUNT, "Number of branches fetched"),
              ADD_STAT(numPredictedBranches, UNIT_COUNT,
                       "Number of branches predicted as taken"),
              ADD_STAT(numBranchMispred, UNIT_COUNT,
                       "Number of branch mispredictions"),
              ADD_STAT(statExecutedInstType, UNIT_COUNT,
                       "Class of executed instruction.")
        {
            numCCRegReads
                .flags(Stats::nozero);

            numCCRegWrites
                .flags(Stats::nozero);

            icacheStallCycles
                .prereq(icacheStallCycles);

            dcacheStallCycles
                .prereq(dcacheStallCycles);

            statExecutedInstType
                .init(Enums::Num_OpClass)
                .flags(Stats::total | Stats::pdf | Stats::dist);

            for (unsigned i = 0; i < Num_OpClasses; ++i) {
                statExecutedInstType.subname(i, Enums::OpClassStrings[i]);
            }

            idleFraction = Stats::constant(1.0) - notIdleFraction;
            numIdleCycles = idleFraction * cpu->baseStats.numCycles;
            numBusyCycles = notIdleFraction * cpu->baseStats.numCycles;

            numBranches
                .prereq(numBranches);

            numPredictedBranches
                .prereq(numPredictedBranches);

            numBranchMispred
                .prereq(numBranchMispred);
        }

        // Number of simulated instructions
        Stats::Scalar numInsts;
        Stats::Scalar numOps;

        // Number of integer alu accesses
        Stats::Scalar numIntAluAccesses;

        // Number of float alu accesses
        Stats::Scalar numFpAluAccesses;

        // Number of vector alu accesses
        Stats::Scalar numVecAluAccesses;

        // Number of function calls/returns
        Stats::Scalar numCallsReturns;

        // Conditional control instructions;
        Stats::Scalar numCondCtrlInsts;

        // Number of int instructions
        Stats::Scalar numIntInsts;

        // Number of float instructions
        Stats::Scalar numFpInsts;

        // Number of vector instructions
        Stats::Scalar numVecInsts;

        // Number of integer register file accesses
        Stats::Scalar numIntRegReads;
        Stats::Scalar numIntRegWrites;

        // Number of float register file accesses
        Stats::Scalar numFpRegReads;
        Stats::Scalar numFpRegWrites;

        // Number of vector register file accesses
        mutable Stats::Scalar numVecRegReads;
        Stats::Scalar numVecRegWrites;

        // Number of predicate register file accesses
        mutable Stats::Scalar numVecPredRegReads;
        Stats::Scalar numVecPredRegWrites;

        // Number of condition code register file accesses
        Stats::Scalar numCCRegReads;
        Stats::Scalar numCCRegWrites;

        // Number of simulated memory references
        Stats::Scalar numMemRefs;
        Stats::Scalar numLoadInsts;
        Stats::Scalar numStoreInsts;

        // Number of idle cycles
        Stats::Formula numIdleCycles;

        // Number of busy cycles
        Stats::Formula numBusyCycles;

        // Number of idle cycles
        Stats::Average notIdleFraction;
        Stats::Formula idleFraction;

        // Number of cycles stalled for I-cache responses
        Stats::Scalar icacheStallCycles;

        // Number of cycles stalled for D-cache responses
        Stats::Scalar dcacheStallCycles;

        /// @{
        /// Total number of branches fetched
        Stats::Scalar numBranches;
        /// Number of branches predicted as taken
        Stats::Scalar numPredictedBranches;
        /// Number of misprediced branches
        Stats::Scalar numBranchMispred;
        /// @}

        // Instruction mix histogram by OpClass
        Stats::Vector statExecutedInstType;

    } execContextStats;

  public:
    /** Constructor */
    SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread)
        : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false),
        numInst(0), numOp(0), numLoad(0), lastIcacheStall(0),
        lastDcacheStall(0), execContextStats(cpu, thread)
    { }

    /** Reads an integer register. */
    RegVal
    readIntRegOperand(const StaticInst *si, int idx) override
    {
        execContextStats.numIntRegReads++;
        const RegId& reg = si->srcRegIdx(idx);
        assert(reg.isIntReg());
        return thread->readIntReg(reg.index());
    }

    /** Sets an integer register to a value. */
    void
    setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
    {
        execContextStats.numIntRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.isIntReg());
        thread->setIntReg(reg.index(), val);
    }

    /** Reads a floating point register in its binary format, instead
     * of by value. */
    RegVal
    readFloatRegOperandBits(const StaticInst *si, int idx) override
    {
        execContextStats.numFpRegReads++;
        const RegId& reg = si->srcRegIdx(idx);
        assert(reg.isFloatReg());
        return thread->readFloatReg(reg.index());
    }

    /** Sets the bits of a floating point register of single width
     * to a binary value. */
    void
    setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
    {
        execContextStats.numFpRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.isFloatReg());
        thread->setFloatReg(reg.index(), val);
    }

    /** Reads a vector register. */
    const TheISA::VecRegContainer &
    readVecRegOperand(const StaticInst *si, int idx) const override
    {
        execContextStats.numVecRegReads++;
        const RegId& reg = si->srcRegIdx(idx);
        assert(reg.isVecReg());
        return thread->readVecReg(reg);
    }

    /** Reads a vector register for modification. */
    TheISA::VecRegContainer &
    getWritableVecRegOperand(const StaticInst *si, int idx) override
    {
        execContextStats.numVecRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.isVecReg());
        return thread->getWritableVecReg(reg);
    }

    /** Sets a vector register to a value. */
    void
    setVecRegOperand(const StaticInst *si, int idx,
                     const TheISA::VecRegContainer& val) override
    {
        execContextStats.numVecRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.isVecReg());
        thread->setVecReg(reg, val);
    }

    /** Vector Register Lane Interfaces. */
    /** @{ */
    /** Reads source vector lane. */
    template <typename VE>
    VecLaneT<VE, true>
    readVecLaneOperand(const StaticInst *si, int idx) const
    {
        execContextStats.numVecRegReads++;
        const RegId& reg = si->srcRegIdx(idx);
        assert(reg.isVecReg());
        return thread->readVecLane<VE>(reg);
    }
    /** Reads source vector 8bit operand. */
    virtual ConstVecLane8
    readVec8BitLaneOperand(const StaticInst *si, int idx) const
                            override
    { return readVecLaneOperand<uint8_t>(si, idx); }

    /** Reads source vector 16bit operand. */
    virtual ConstVecLane16
    readVec16BitLaneOperand(const StaticInst *si, int idx) const
                            override
    { return readVecLaneOperand<uint16_t>(si, idx); }

    /** Reads source vector 32bit operand. */
    virtual ConstVecLane32
    readVec32BitLaneOperand(const StaticInst *si, int idx) const
                            override
    { return readVecLaneOperand<uint32_t>(si, idx); }

    /** Reads source vector 64bit operand. */
    virtual ConstVecLane64
    readVec64BitLaneOperand(const StaticInst *si, int idx) const
                            override
    { return readVecLaneOperand<uint64_t>(si, idx); }

    /** Write a lane of the destination vector operand. */
    template <typename LD>
    void
    setVecLaneOperandT(const StaticInst *si, int idx,
            const LD& val)
    {
        execContextStats.numVecRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.isVecReg());
        return thread->setVecLane(reg, val);
    }
    /** Write a lane of the destination vector operand. */
    virtual void
    setVecLaneOperand(const StaticInst *si, int idx,
            const LaneData<LaneSize::Byte>& val) override
    { return setVecLaneOperandT(si, idx, val); }
    /** Write a lane of the destination vector operand. */
    virtual void
    setVecLaneOperand(const StaticInst *si, int idx,
            const LaneData<LaneSize::TwoByte>& val) override
    { return setVecLaneOperandT(si, idx, val); }
    /** Write a lane of the destination vector operand. */
    virtual void
    setVecLaneOperand(const StaticInst *si, int idx,
            const LaneData<LaneSize::FourByte>& val) override
    { return setVecLaneOperandT(si, idx, val); }
    /** Write a lane of the destination vector operand. */
    virtual void
    setVecLaneOperand(const StaticInst *si, int idx,
            const LaneData<LaneSize::EightByte>& val) override
    { return setVecLaneOperandT(si, idx, val); }
    /** @} */

    /** Reads an element of a vector register. */
    TheISA::VecElem
    readVecElemOperand(const StaticInst *si, int idx) const override
    {
        execContextStats.numVecRegReads++;
        const RegId& reg = si->srcRegIdx(idx);
        assert(reg.isVecElem());
        return thread->readVecElem(reg);
    }

    /** Sets an element of a vector register to a value. */
    void
    setVecElemOperand(const StaticInst *si, int idx,
                      const TheISA::VecElem val) override
    {
        execContextStats.numVecRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.isVecElem());
        thread->setVecElem(reg, val);
    }

    const TheISA::VecPredRegContainer&
    readVecPredRegOperand(const StaticInst *si, int idx) const override
    {
        execContextStats.numVecPredRegReads++;
        const RegId& reg = si->srcRegIdx(idx);
        assert(reg.isVecPredReg());
        return thread->readVecPredReg(reg);
    }

    TheISA::VecPredRegContainer&
    getWritableVecPredRegOperand(const StaticInst *si, int idx) override
    {
        execContextStats.numVecPredRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.isVecPredReg());
        return thread->getWritableVecPredReg(reg);
    }

    void
    setVecPredRegOperand(const StaticInst *si, int idx,
                         const TheISA::VecPredRegContainer& val) override
    {
        execContextStats.numVecPredRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.isVecPredReg());
        thread->setVecPredReg(reg, val);
    }

    RegVal
    readCCRegOperand(const StaticInst *si, int idx) override
    {
        execContextStats.numCCRegReads++;
        const RegId& reg = si->srcRegIdx(idx);
        assert(reg.isCCReg());
        return thread->readCCReg(reg.index());
    }

    void
    setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
    {
        execContextStats.numCCRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.isCCReg());
        thread->setCCReg(reg.index(), val);
    }

    RegVal
    readMiscRegOperand(const StaticInst *si, int idx) override
    {
        execContextStats.numIntRegReads++;
        const RegId& reg = si->srcRegIdx(idx);
        assert(reg.isMiscReg());
        return thread->readMiscReg(reg.index());
    }

    void
    setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
    {
        execContextStats.numIntRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.isMiscReg());
        thread->setMiscReg(reg.index(), val);
    }

    /**
     * Reads a miscellaneous register, handling any architectural
     * side effects due to reading that register.
     */
    RegVal
    readMiscReg(int misc_reg) override
    {
        execContextStats.numIntRegReads++;
        return thread->readMiscReg(misc_reg);
    }

    /**
     * Sets a miscellaneous register, handling any architectural
     * side effects due to writing that register.
     */
    void
    setMiscReg(int misc_reg, RegVal val) override
    {
        execContextStats.numIntRegWrites++;
        thread->setMiscReg(misc_reg, val);
    }

    TheISA::PCState
    pcState() const override
    {
        return thread->pcState();
    }

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

    Fault
    readMem(Addr addr, uint8_t *data, unsigned int size,
            Request::Flags flags,
            const std::vector<bool>& byte_enable)
        override
    {
        assert(byte_enable.size() == size);
        return cpu->readMem(addr, data, size, flags, byte_enable);
    }

    Fault
    initiateMemRead(Addr addr, unsigned int size,
                    Request::Flags flags,
                    const std::vector<bool>& byte_enable)
        override
    {
        assert(byte_enable.size() == size);
        return cpu->initiateMemRead(addr, size, flags, byte_enable);
    }

    Fault
    writeMem(uint8_t *data, unsigned int size, Addr addr,
             Request::Flags flags, uint64_t *res,
             const std::vector<bool>& byte_enable)
        override
    {
        assert(byte_enable.size() == size);
        return cpu->writeMem(data, size, addr, flags, res,
            byte_enable);
    }

    Fault amoMem(Addr addr, uint8_t *data, unsigned int size,
                 Request::Flags flags, AtomicOpFunctorPtr amo_op) override
    {
        return cpu->amoMem(addr, data, size, flags, std::move(amo_op));
    }

    Fault initiateMemAMO(Addr addr, unsigned int size,
                         Request::Flags flags,
                         AtomicOpFunctorPtr amo_op) override
    {
        return cpu->initiateMemAMO(addr, size, flags, std::move(amo_op));
    }

    Fault initiateHtmCmd(Request::Flags flags) override
    {
        return cpu->initiateHtmCmd(flags);
    }

    /**
     * Sets the number of consecutive store conditional failures.
     */
    void
    setStCondFailures(unsigned int sc_failures) override
    {
        thread->setStCondFailures(sc_failures);
    }

    /**
     * Returns the number of consecutive store conditional failures.
     */
    unsigned int
    readStCondFailures() const override
    {
        return thread->readStCondFailures();
    }

    /** Returns a pointer to the ThreadContext. */
    ThreadContext *tcBase() const override { return thread->getTC(); }

    bool
    readPredicate() const override
    {
        return thread->readPredicate();
    }

    void
    setPredicate(bool val) override
    {
        thread->setPredicate(val);

        if (cpu->traceData) {
            cpu->traceData->setPredicate(val);
        }
    }

    bool
    readMemAccPredicate() const override
    {
        return thread->readMemAccPredicate();
    }

    void
    setMemAccPredicate(bool val) override
    {
        thread->setMemAccPredicate(val);
    }

    uint64_t
    getHtmTransactionUid() const override
    {
        return tcBase()->getHtmCheckpointPtr()->getHtmUid();
    }

    uint64_t
    newHtmTransactionUid() const override
    {
        return tcBase()->getHtmCheckpointPtr()->newHtmUid();
    }

    bool
    inHtmTransactionalState() const override
    {
        return (getHtmTransactionalDepth() > 0);
    }

    uint64_t
    getHtmTransactionalDepth() const override
    {
        assert(thread->htmTransactionStarts >= thread->htmTransactionStops);
        return (thread->htmTransactionStarts - thread->htmTransactionStops);
    }

    /**
     * Invalidate a page in the DTLB <i>and</i> ITLB.
     */
    void
    demapPage(Addr vaddr, uint64_t asn) override
    {
        thread->demapPage(vaddr, asn);
    }

    void
    armMonitor(Addr address) override
    {
        cpu->armMonitor(thread->threadId(), address);
    }

    bool
    mwait(PacketPtr pkt) override
    {
        return cpu->mwait(thread->threadId(), pkt);
    }

    void
    mwaitAtomic(ThreadContext *tc) override
    {
        cpu->mwaitAtomic(thread->threadId(), tc, thread->mmu);
    }

    AddressMonitor *
    getAddrMonitor() override
    {
        return cpu->getCpuAddrMonitor(thread->threadId());
    }
};

#endif // __CPU_EXEC_CONTEXT_HH__
