pwr: Adds logic to enter power gating for the cpu model
[gem5.git] / src / cpu / simple / exec_context.hh
index f474cc358b5fe9fe8d85224201500f8376f1d62a..6d51e5ed908d43cebbd68622b11348e5389de424 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 ARM Limited
+ * Copyright (c) 2014-2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
 #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;
 
@@ -62,6 +64,8 @@ class SimpleExecContext : public ExecContext {
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::CCReg CCReg;
+    using VecRegContainer = TheISA::VecRegContainer;
+    using VecElem = TheISA::VecElem;
 
   public:
     BaseSimpleCPU *cpu;
@@ -90,6 +94,9 @@ class SimpleExecContext : public ExecContext {
     // Number of float alu accesses
     Stats::Scalar numFpAluAccesses;
 
+    // Number of vector alu accesses
+    Stats::Scalar numVecAluAccesses;
+
     // Number of function calls/returns
     Stats::Scalar numCallsReturns;
 
@@ -102,6 +109,9 @@ class SimpleExecContext : public ExecContext {
     // 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;
@@ -110,6 +120,10 @@ class SimpleExecContext : public ExecContext {
     Stats::Scalar numFpRegReads;
     Stats::Scalar numFpRegWrites;
 
+    // Number of vector register file accesses
+    mutable Stats::Scalar numVecRegReads;
+    Stats::Scalar numVecRegWrites;
+
     // Number of condition code register file accesses
     Stats::Scalar numCCRegReads;
     Stats::Scalar numCCRegWrites;
@@ -160,93 +174,219 @@ class SimpleExecContext : public ExecContext {
     { }
 
     /** Reads an integer register. */
-    IntReg readIntRegOperand(const StaticInst *si, int idx) M5_ATTR_OVERRIDE
+    IntReg readIntRegOperand(const StaticInst *si, int idx) override
     {
         numIntRegReads++;
-        return thread->readIntReg(si->srcRegIdx(idx));
+        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, IntReg val)
-        M5_ATTR_OVERRIDE
+    void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
     {
         numIntRegWrites++;
-        thread->setIntReg(si->destRegIdx(idx), val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isIntReg());
+        thread->setIntReg(reg.index(), val);
     }
 
     /** Reads a floating point register of single register width. */
-    FloatReg readFloatRegOperand(const StaticInst *si, int idx)
-        M5_ATTR_OVERRIDE
+    FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
     {
         numFpRegReads++;
-        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
-        return thread->readFloatReg(reg_idx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isFloatReg());
+        return thread->readFloatReg(reg.index());
     }
 
     /** Reads a floating point register in its binary format, instead
      * of by value. */
-    FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
-        M5_ATTR_OVERRIDE
+    FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override
     {
         numFpRegReads++;
-        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
-        return thread->readFloatRegBits(reg_idx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isFloatReg());
+        return thread->readFloatRegBits(reg.index());
     }
 
     /** Sets a floating point register of single width to a value. */
-    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
-        M5_ATTR_OVERRIDE
+    void setFloatRegOperand(const StaticInst *si, int idx,
+                            FloatReg val) override
     {
         numFpRegWrites++;
-        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
-        thread->setFloatReg(reg_idx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isFloatReg());
+        thread->setFloatReg(reg.index(), val);
     }
 
     /** Sets the bits of a floating point register of single width
      * to a binary value. */
     void setFloatRegOperandBits(const StaticInst *si, int idx,
-                                FloatRegBits val) M5_ATTR_OVERRIDE
+                                FloatRegBits val) override
     {
         numFpRegWrites++;
-        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
-        thread->setFloatRegBits(reg_idx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isFloatReg());
+        thread->setFloatRegBits(reg.index(), val);
     }
 
-    CCReg readCCRegOperand(const StaticInst *si, int idx) M5_ATTR_OVERRIDE
+    /** Reads a vector register. */
+    const VecRegContainer&
+    readVecRegOperand(const StaticInst *si, int idx) const override
+    {
+        numVecRegReads++;
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->readVecReg(reg);
+    }
+
+    /** Reads a vector register for modification. */
+    VecRegContainer&
+    getWritableVecRegOperand(const StaticInst *si, int idx) override
+    {
+        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 VecRegContainer& val) override
+    {
+        numVecRegWrites++;
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecReg());
+        thread->setVecReg(reg, val);
+    }
+
+    /** Vector Register Lane Interfaces. */
+    /** @{ */
+    /** Reads source vector lane. */
+    template <typename VecElem>
+    VecLaneT<VecElem, true>
+    readVecLaneOperand(const StaticInst *si, int idx) const
+    {
+        numVecRegReads++;
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isVecReg());
+        return thread->readVecLane<VecElem>(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)
+    {
+        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. */
+    VecElem readVecElemOperand(const StaticInst *si, int idx) const override
+    {
+        numVecRegReads++;
+        const RegId& reg = si->destRegIdx(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 VecElem val) override
+    {
+        numVecRegWrites++;
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isVecElem());
+        thread->setVecElem(reg, val);
+    }
+
+    CCReg readCCRegOperand(const StaticInst *si, int idx) override
     {
         numCCRegReads++;
-        int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
-        return thread->readCCReg(reg_idx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isCCReg());
+        return thread->readCCReg(reg.index());
     }
 
-    void setCCRegOperand(const StaticInst *si, int idx, CCReg val)
-        M5_ATTR_OVERRIDE
+    void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
     {
         numCCRegWrites++;
-        int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
-        thread->setCCReg(reg_idx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isCCReg());
+        thread->setCCReg(reg.index(), val);
     }
 
-    MiscReg readMiscRegOperand(const StaticInst *si, int idx) M5_ATTR_OVERRIDE
+    MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
     {
         numIntRegReads++;
-        int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
-        return thread->readMiscReg(reg_idx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isMiscReg());
+        return thread->readMiscReg(reg.index());
     }
 
-    void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val)
-        M5_ATTR_OVERRIDE
+    void setMiscRegOperand(const StaticInst *si, int idx,
+                           const MiscReg &val) override
     {
         numIntRegWrites++;
-        int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
-        thread->setMiscReg(reg_idx, val);
+        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.
      */
-    MiscReg readMiscReg(int misc_reg) M5_ATTR_OVERRIDE
+    MiscReg readMiscReg(int misc_reg) override
     {
         numIntRegReads++;
         return thread->readMiscReg(misc_reg);
@@ -256,18 +396,18 @@ class SimpleExecContext : public ExecContext {
      * Sets a miscellaneous register, handling any architectural
      * side effects due to writing that register.
      */
-    void setMiscReg(int misc_reg, const MiscReg &val) M5_ATTR_OVERRIDE
+    void setMiscReg(int misc_reg, const MiscReg &val) override
     {
         numIntRegWrites++;
         thread->setMiscReg(misc_reg, val);
     }
 
-    PCState pcState() const M5_ATTR_OVERRIDE
+    PCState pcState() const override
     {
         return thread->pcState();
     }
 
-    void pcState(const PCState &val) M5_ATTR_OVERRIDE
+    void pcState(const PCState &val) override
     {
         thread->pcState(val);
     }
@@ -278,7 +418,7 @@ class SimpleExecContext : public ExecContext {
      *
      * @note Only valid for memory ops.
      */
-    void setEA(Addr EA) M5_ATTR_OVERRIDE
+    void setEA(Addr EA) override
     { panic("BaseSimpleCPU::setEA() not implemented\n"); }
 
     /**
@@ -286,17 +426,23 @@ class SimpleExecContext : public ExecContext {
      *
      * @note Only valid for memory ops.
      */
-    Addr getEA() const M5_ATTR_OVERRIDE
+    Addr getEA() const override
     { panic("BaseSimpleCPU::getEA() not implemented\n"); }
 
     Fault readMem(Addr addr, uint8_t *data, unsigned int size,
-                  unsigned int flags) M5_ATTR_OVERRIDE
+                  Request::Flags flags) override
     {
         return cpu->readMem(addr, data, size, flags);
     }
 
+    Fault initiateMemRead(Addr addr, unsigned int size,
+                          Request::Flags flags) override
+    {
+        return cpu->initiateMemRead(addr, size, flags);
+    }
+
     Fault writeMem(uint8_t *data, unsigned int size, Addr addr,
-                   unsigned int flags, uint64_t *res) M5_ATTR_OVERRIDE
+                   Request::Flags flags, uint64_t *res) override
     {
         return cpu->writeMem(data, size, addr, flags, res);
     }
@@ -304,7 +450,7 @@ class SimpleExecContext : public ExecContext {
     /**
      * Sets the number of consecutive store conditional failures.
      */
-    void setStCondFailures(unsigned int sc_failures) M5_ATTR_OVERRIDE
+    void setStCondFailures(unsigned int sc_failures) override
     {
         thread->setStCondFailures(sc_failures);
     }
@@ -312,7 +458,7 @@ class SimpleExecContext : public ExecContext {
     /**
      * Returns the number of consecutive store conditional failures.
      */
-    unsigned int readStCondFailures() const M5_ATTR_OVERRIDE
+    unsigned int readStCondFailures() const override
     {
         return thread->readStCondFailures();
     }
@@ -320,16 +466,16 @@ class SimpleExecContext : public ExecContext {
     /**
      * Executes a syscall specified by the callnum.
      */
-    void syscall(int64_t callnum) M5_ATTR_OVERRIDE
+    void syscall(int64_t callnum, Fault *fault) override
     {
         if (FullSystem)
             panic("Syscall emulation isn't available in FS mode.");
 
-        thread->syscall(callnum);
+        thread->syscall(callnum, fault);
     }
 
     /** Returns a pointer to the ThreadContext. */
-    ThreadContext *tcBase() M5_ATTR_OVERRIDE
+    ThreadContext *tcBase() override
     {
         return thread->getTC();
     }
@@ -338,7 +484,7 @@ class SimpleExecContext : public ExecContext {
      * Somewhat Alpha-specific function that handles returning from an
      * error or interrupt.
      */
-    Fault hwrei() M5_ATTR_OVERRIDE
+    Fault hwrei() override
     {
         return thread->hwrei();
     }
@@ -347,17 +493,17 @@ class SimpleExecContext : public ExecContext {
      * Check for special simulator handling of specific PAL calls.  If
      * return value is false, actual PAL call will be suppressed.
      */
-    bool simPalCheck(int palFunc) M5_ATTR_OVERRIDE
+    bool simPalCheck(int palFunc) override
     {
         return thread->simPalCheck(palFunc);
     }
 
-    bool readPredicate() M5_ATTR_OVERRIDE
+    bool readPredicate() override
     {
         return thread->readPredicate();
     }
 
-    void setPredicate(bool val) M5_ATTR_OVERRIDE
+    void setPredicate(bool val) override
     {
         thread->setPredicate(val);
 
@@ -369,41 +515,42 @@ class SimpleExecContext : public ExecContext {
     /**
      * Invalidate a page in the DTLB <i>and</i> ITLB.
      */
-    void demapPage(Addr vaddr, uint64_t asn) M5_ATTR_OVERRIDE
+    void demapPage(Addr vaddr, uint64_t asn) override
     {
         thread->demapPage(vaddr, asn);
     }
 
-    void armMonitor(Addr address) M5_ATTR_OVERRIDE
+    void armMonitor(Addr address) override
     {
-        cpu->armMonitor(address);
+        cpu->armMonitor(thread->threadId(), address);
     }
 
-    bool mwait(PacketPtr pkt) M5_ATTR_OVERRIDE
+    bool mwait(PacketPtr pkt) override
     {
-        return cpu->mwait(pkt);
+        return cpu->mwait(thread->threadId(), pkt);
     }
 
-    void mwaitAtomic(ThreadContext *tc) M5_ATTR_OVERRIDE
+    void mwaitAtomic(ThreadContext *tc) override
     {
-        cpu->mwaitAtomic(tc, thread->dtb);
+        cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb);
     }
 
-    AddressMonitor *getAddrMonitor() M5_ATTR_OVERRIDE
+    AddressMonitor *getAddrMonitor() override
     {
-        return cpu->getCpuAddrMonitor();
+        return cpu->getCpuAddrMonitor(thread->threadId());
     }
 
 #if THE_ISA == MIPS_ISA
-    MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
-        M5_ATTR_OVERRIDE
+    MiscReg readRegOtherThread(const RegId& reg,
+                               ThreadID tid = InvalidThreadID)
+        override
     {
         panic("Simple CPU models do not support multithreaded "
               "register access.");
     }
 
-    void setRegOtherThread(int regIdx, MiscReg val,
-                           ThreadID tid = InvalidThreadID) M5_ATTR_OVERRIDE
+    void setRegOtherThread(const RegId& reg, MiscReg val,
+                           ThreadID tid = InvalidThreadID) override
     {
         panic("Simple CPU models do not support multithreaded "
               "register access.");