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

namespace gem5
{

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

            numCCRegWrites
                .flags(statistics::nozero);

            icacheStallCycles
                .prereq(icacheStallCycles);

            dcacheStallCycles
                .prereq(dcacheStallCycles);

            statExecutedInstType
                .init(enums::Num_OpClass)
                .flags(statistics::total | statistics::pdf | statistics::dist);

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

            idleFraction = statistics::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
        statistics::Scalar numInsts;
        statistics::Scalar numOps;

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

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

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

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

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

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

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

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

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

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

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

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

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

        // Number of misc register file accesses
        statistics::Scalar numMiscRegReads;
        statistics::Scalar numMiscRegWrites;

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

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

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

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

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

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

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

        // Instruction mix histogram by OpClass
        statistics::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.is(IntRegClass));
        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.is(IntRegClass));
        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.is(FloatRegClass));
        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.is(FloatRegClass));
        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.is(VecRegClass));
        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.is(VecRegClass));
        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.is(VecRegClass));
        thread->setVecReg(reg, val);
    }

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

    /** Sets an element of a vector register to a value. */
    void
    setVecElemOperand(const StaticInst *si, int idx, RegVal val) override
    {
        execContextStats.numVecRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.is(VecElemClass));
        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.is(VecPredRegClass));
        return thread->readVecPredReg(reg);
    }

    TheISA::VecPredRegContainer&
    getWritableVecPredRegOperand(const StaticInst *si, int idx) override
    {
        execContextStats.numVecPredRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.is(VecPredRegClass));
        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.is(VecPredRegClass));
        thread->setVecPredReg(reg, val);
    }

    RegVal
    readCCRegOperand(const StaticInst *si, int idx) override
    {
        execContextStats.numCCRegReads++;
        const RegId& reg = si->srcRegIdx(idx);
        assert(reg.is(CCRegClass));
        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.is(CCRegClass));
        thread->setCCReg(reg.index(), val);
    }

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

    void
    setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
    {
        execContextStats.numMiscRegWrites++;
        const RegId& reg = si->destRegIdx(idx);
        assert(reg.is(MiscRegClass));
        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.numMiscRegReads++;
        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.numMiscRegWrites++;
        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());
    }
};

} // namespace gem5

#endif // __CPU_EXEC_CONTEXT_HH__
