/*
 * 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
    std::unique_ptr<PCStateBase> 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."),
              numRegReads{
                  &numIntRegReads,
                  &numFpRegReads,
                  &numVecRegReads,
                  &numVecRegReads,
                  &numVecPredRegReads,
                  &numCCRegReads
              },
              numRegWrites{
                  &numIntRegWrites,
                  &numFpRegWrites,
                  &numVecRegWrites,
                  &numVecRegWrites,
                  &numVecPredRegWrites,
                  &numCCRegWrites
              }
        {
            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;

        std::array<statistics::Scalar *, CCRegClass + 1> numRegReads;
        std::array<statistics::Scalar *, CCRegClass + 1> numRegWrites;

    } 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)
    { }

    RegVal
    getRegOperand(const StaticInst *si, int idx) override
    {
        const RegId &reg = si->srcRegIdx(idx);
        if (reg.is(InvalidRegClass))
            return 0;
        (*execContextStats.numRegReads[reg.classValue()])++;
        return thread->getReg(reg);
    }

    void
    getRegOperand(const StaticInst *si, int idx, void *val) override
    {
        const RegId &reg = si->srcRegIdx(idx);
        (*execContextStats.numRegReads[reg.classValue()])++;
        thread->getReg(reg, val);
    }

    void *
    getWritableRegOperand(const StaticInst *si, int idx) override
    {
        const RegId &reg = si->destRegIdx(idx);
        (*execContextStats.numRegWrites[reg.classValue()])++;
        return thread->getWritableReg(reg);
    }

    void
    setRegOperand(const StaticInst *si, int idx, RegVal val) override
    {
        const RegId &reg = si->destRegIdx(idx);
        if (reg.is(InvalidRegClass))
            return;
        (*execContextStats.numRegWrites[reg.classValue()])++;
        thread->setReg(reg, val);
    }

    void
    setRegOperand(const StaticInst *si, int idx, const void *val) override
    {
        const RegId &reg = si->destRegIdx(idx);
        (*execContextStats.numRegWrites[reg.classValue()])++;
        thread->setReg(reg, 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);
    }

    const PCStateBase &
    pcState() const override
    {
        return thread->pcState();
    }

    void
    pcState(const PCStateBase &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
    initiateMemMgmtCmd(Request::Flags flags) override
    {
        return cpu->initiateMemMgmtCmd(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__
