summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/base_cpu.cc7
-rw-r--r--cpu/base_cpu.hh20
-rw-r--r--cpu/exec_context.cc2
-rw-r--r--cpu/memtest/memtest.cc2
-rw-r--r--cpu/memtest/memtest.hh6
-rw-r--r--cpu/simple_cpu/simple_cpu.cc16
-rw-r--r--cpu/simple_cpu/simple_cpu.hh99
-rw-r--r--cpu/static_inst.hh23
8 files changed, 123 insertions, 52 deletions
diff --git a/cpu/base_cpu.cc b/cpu/base_cpu.cc
index e00de8389..702a9afe8 100644
--- a/cpu/base_cpu.cc
+++ b/cpu/base_cpu.cc
@@ -130,6 +130,13 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads,
void
BaseCPU::regStats()
{
+ using namespace Stats;
+
+ numCycles
+ .name(name() + ".numCycles")
+ .desc("number of cpu cycles simulated")
+ ;
+
int size = execContexts.size();
if (size > 1) {
for (int i = 0; i < size; ++i) {
diff --git a/cpu/base_cpu.hh b/cpu/base_cpu.hh
index 648035732..9c4026784 100644
--- a/cpu/base_cpu.hh
+++ b/cpu/base_cpu.hh
@@ -31,10 +31,10 @@
#include <vector>
+#include "base/statistics.hh"
#include "sim/eventq.hh"
#include "sim/sim_object.hh"
-
-#include "targetarch/isa_traits.hh" // for Addr
+#include "targetarch/isa_traits.hh"
#ifdef FULL_SYSTEM
class System;
@@ -147,11 +147,27 @@ class BaseCPU : public SimObject
*/
virtual BranchPred *getBranchPred() { return NULL; };
+ virtual Counter totalInstructions() const { return 0; }
+
private:
static std::vector<BaseCPU *> cpuList; //!< Static global cpu list
public:
static int numSimulatedCPUs() { return cpuList.size(); }
+ static Counter numSimulatedInstructions()
+ {
+ Counter total = 0;
+
+ int size = cpuList.size();
+ for (int i = 0; i < size; ++i)
+ total += cpuList[i]->totalInstructions();
+
+ return total;
+ }
+
+ public:
+ // Number of CPU cycles simulated
+ Stats::Scalar<> numCycles;
};
#endif // __BASE_CPU_HH__
diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc
index 832a621f8..0d3a80fe7 100644
--- a/cpu/exec_context.cc
+++ b/cpu/exec_context.cc
@@ -129,7 +129,7 @@ ExecContext::serialize(ostream &os)
SERIALIZE_SCALAR(ctx);
}
if (system->bin) {
- Statistics::MainBin *cur = Statistics::MainBin::curBin();
+ Stats::MainBin *cur = Stats::MainBin::curBin();
string bin_name = cur->name();
SERIALIZE_SCALAR(bin_name);
}
diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc
index 5d608976d..1d745724f 100644
--- a/cpu/memtest/memtest.cc
+++ b/cpu/memtest/memtest.cc
@@ -186,7 +186,7 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
void
MemTest::regStats()
{
- using namespace Statistics;
+ using namespace Stats;
numReadsStat
diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh
index f2409d54c..4bde5c066 100644
--- a/cpu/memtest/memtest.hh
+++ b/cpu/memtest/memtest.hh
@@ -111,9 +111,9 @@ class MemTest : public BaseCPU
Tick noResponseCycles;
uint64_t numReads;
- Statistics::Scalar<> numReadsStat;
- Statistics::Scalar<> numWritesStat;
- Statistics::Scalar<> numCopiesStat;
+ Stats::Scalar<> numReadsStat;
+ Stats::Scalar<> numWritesStat;
+ Stats::Scalar<> numCopiesStat;
// called by MemCompleteEvent::process()
void completeRequest(MemReqPtr &req, uint8_t *data);
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index 05b88b04b..e1a861ad8 100644
--- a/cpu/simple_cpu/simple_cpu.cc
+++ b/cpu/simple_cpu/simple_cpu.cc
@@ -42,6 +42,7 @@
#include "base/pollevent.hh"
#include "base/range.hh"
#include "base/trace.hh"
+#include "base/stats/events.hh"
#include "cpu/base_cpu.hh"
#include "cpu/exec_context.hh"
#include "cpu/exetrace.hh"
@@ -50,7 +51,6 @@
#include "cpu/static_inst.hh"
#include "mem/base_mem.hh"
#include "mem/mem_interface.hh"
-#include "sim/annotation.hh"
#include "sim/builder.hh"
#include "sim/debug.hh"
#include "sim/host.hh"
@@ -255,7 +255,7 @@ SimpleCPU::haltContext(int thread_num)
void
SimpleCPU::regStats()
{
- using namespace Statistics;
+ using namespace Stats;
BaseCPU::regStats();
@@ -287,8 +287,6 @@ SimpleCPU::regStats()
;
idleFraction = constant(1.0) - notIdleFraction;
- numInsts = Statistics::scalar(numInst) - Statistics::scalar(startNumInst);
- simInsts += numInsts;
}
void
@@ -405,6 +403,9 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
}
}
+ if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
+ Stats::recordEvent("Uncached Read");
+
return fault;
}
@@ -490,6 +491,9 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
if (res && (fault == No_Fault))
*res = memReq->result;
+ if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
+ Stats::recordEvent("Uncached Write");
+
return fault;
}
@@ -581,7 +585,6 @@ SimpleCPU::post_interrupt(int int_num, int index)
if (xc->status() == ExecContext::Suspended) {
DPRINTF(IPI,"Suspended Processor awoke\n");
xc->activate();
- Annotate::Resume(xc);
}
}
#endif // FULL_SYSTEM
@@ -590,6 +593,8 @@ SimpleCPU::post_interrupt(int int_num, int index)
void
SimpleCPU::tick()
{
+ numCycles++;
+
traceData = NULL;
Fault fault = No_Fault;
@@ -697,6 +702,7 @@ SimpleCPU::tick()
// keep an instruction count
numInst++;
+ numInsts++;
// check for instruction-count-based events
comInstEventQueue[0]->serviceEvents(numInst);
diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh
index 4977e6992..1c6b18d03 100644
--- a/cpu/simple_cpu/simple_cpu.hh
+++ b/cpu/simple_cpu/simple_cpu.hh
@@ -34,7 +34,8 @@
#include "base/loader/symtab.hh"
#include "cpu/pc_event.hh"
#include "base/statistics.hh"
-
+#include "cpu/exec_context.hh"
+#include "cpu/static_inst.hh"
// forward declarations
#ifdef FULL_SYSTEM
@@ -46,6 +47,11 @@ class PhysicalMemory;
class RemoteGDB;
class GDBListener;
+
+#else
+
+class Process;
+
#endif // FULL_SYSTEM
class MemInterface;
@@ -204,25 +210,30 @@ class SimpleCPU : public BaseCPU
// number of simulated instructions
Counter numInst;
Counter startNumInst;
- Statistics::Formula numInsts;
+ Stats::Scalar<> numInsts;
+
+ virtual Counter totalInstructions() const
+ {
+ return numInst - startNumInst;
+ }
// number of simulated memory references
- Statistics::Scalar<> numMemRefs;
+ Stats::Scalar<> numMemRefs;
// number of simulated loads
Counter numLoad;
Counter startNumLoad;
// number of idle cycles
- Statistics::Average<> notIdleFraction;
- Statistics::Formula idleFraction;
+ Stats::Average<> notIdleFraction;
+ Stats::Formula idleFraction;
// number of cycles stalled for I-cache misses
- Statistics::Scalar<> icacheStallCycles;
+ Stats::Scalar<> icacheStallCycles;
Counter lastIcacheStall;
// number of cycles stalled for D-cache misses
- Statistics::Scalar<> dcacheStallCycles;
+ Stats::Scalar<> dcacheStallCycles;
Counter lastDcacheStall;
void processCacheCompletion();
@@ -251,37 +262,71 @@ class SimpleCPU : public BaseCPU
Fault copy(Addr dest);
- uint64_t readIntReg(int reg_idx) { return xc->readIntReg(reg_idx); }
+ // The register accessor methods provide the index of the
+ // instruction's operand (e.g., 0 or 1), not the architectural
+ // register index, to simplify the implementation of register
+ // renaming. We find the architectural register index by indexing
+ // into the instruction's own operand index table. Note that a
+ // raw pointer to the StaticInst is provided instead of a
+ // ref-counted StaticInstPtr to redice overhead. This is fine as
+ // long as these methods don't copy the pointer into any long-term
+ // storage (which is pretty hard to imagine they would have reason
+ // to do).
+
+ uint64_t readIntReg(StaticInst<TheISA> *si, int idx)
+ {
+ return xc->readIntReg(si->srcRegIdx(idx));
+ }
- float readFloatRegSingle(int reg_idx)
- { return xc->readFloatRegSingle(reg_idx); }
+ float readFloatRegSingle(StaticInst<TheISA> *si, int idx)
+ {
+ int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
+ return xc->readFloatRegSingle(reg_idx);
+ }
- double readFloatRegDouble(int reg_idx)
- { return xc->readFloatRegDouble(reg_idx); }
+ double readFloatRegDouble(StaticInst<TheISA> *si, int idx)
+ {
+ int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
+ return xc->readFloatRegDouble(reg_idx);
+ }
- uint64_t readFloatRegInt(int reg_idx)
- { return xc->readFloatRegInt(reg_idx); }
+ uint64_t readFloatRegInt(StaticInst<TheISA> *si, int idx)
+ {
+ int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
+ return xc->readFloatRegInt(reg_idx);
+ }
- void setIntReg(int reg_idx, uint64_t val)
- { return xc->setIntReg(reg_idx, val); }
+ void setIntReg(StaticInst<TheISA> *si, int idx, uint64_t val)
+ {
+ xc->setIntReg(si->destRegIdx(idx), val);
+ }
- void setFloatRegSingle(int reg_idx, float val)
- { return xc->setFloatRegSingle(reg_idx, val); }
+ void setFloatRegSingle(StaticInst<TheISA> *si, int idx, float val)
+ {
+ int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
+ xc->setFloatRegSingle(reg_idx, val);
+ }
- void setFloatRegDouble(int reg_idx, double val)
- { return xc->setFloatRegDouble(reg_idx, val); }
+ void setFloatRegDouble(StaticInst<TheISA> *si, int idx, double val)
+ {
+ int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
+ xc->setFloatRegDouble(reg_idx, val);
+ }
- void setFloatRegInt(int reg_idx, uint64_t val)
- { return xc->setFloatRegInt(reg_idx, val); }
+ void setFloatRegInt(StaticInst<TheISA> *si, int idx, uint64_t val)
+ {
+ int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
+ xc->setFloatRegInt(reg_idx, val);
+ }
uint64_t readPC() { return xc->readPC(); }
- void setNextPC(uint64_t val) { return xc->setNextPC(val); }
+ void setNextPC(uint64_t val) { xc->setNextPC(val); }
uint64_t readUniq() { return xc->readUniq(); }
- void setUniq(uint64_t val) { return xc->setUniq(val); }
+ void setUniq(uint64_t val) { xc->setUniq(val); }
uint64_t readFpcr() { return xc->readFpcr(); }
- void setFpcr(uint64_t val) { return xc->setFpcr(val); }
+ void setFpcr(uint64_t val) { xc->setFpcr(val); }
#ifdef FULL_SYSTEM
uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); }
@@ -290,7 +335,7 @@ class SimpleCPU : public BaseCPU
int readIntrFlag() { return xc->readIntrFlag(); }
void setIntrFlag(int val) { xc->setIntrFlag(val); }
bool inPalMode() { return xc->inPalMode(); }
- void ev5_trap(Fault fault) { return xc->ev5_trap(fault); }
+ void ev5_trap(Fault fault) { xc->ev5_trap(fault); }
bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); }
#else
void syscall() { xc->syscall(); }
@@ -300,6 +345,4 @@ class SimpleCPU : public BaseCPU
ExecContext *xcBase() { return xc; }
};
-typedef SimpleCPU SimpleCPUExecContext;
-
#endif // __SIMPLE_CPU_HH__
diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh
index 131c5f756..3eeefb675 100644
--- a/cpu/static_inst.hh
+++ b/cpu/static_inst.hh
@@ -42,11 +42,8 @@
// forward declarations
class ExecContext;
class DynInst;
-typedef DynInst FullCPUExecContext;
class FastCPU;
-typedef FastCPU FastCPUExecContext;
class SimpleCPU;
-typedef SimpleCPU SimpleCPUExecContext;
class SymbolTable;
namespace Trace {
@@ -110,11 +107,13 @@ class StaticInstBase : public RefCounted
IsThreadSync, ///< Thread synchronization operation.
- IsSerializing, ///< Serializes pipeline: won't until all
+ IsSerializing, ///< Serializes pipeline: won't execute until all
/// older instructions have committed.
IsMemBarrier, ///< Is a memory barrier
IsWriteBarrier, ///< Is a write barrier
+ IsNonSpeculative, ///< Should not be executed speculatively
+
NumFlags
};
@@ -196,6 +195,7 @@ class StaticInstBase : public RefCounted
bool isSerializing() const { return flags[IsSerializing]; }
bool isMemBarrier() const { return flags[IsMemBarrier]; }
bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
+ bool isNonSpeculative() const { return flags[IsNonSpeculative]; }
//@}
/// Operation class. Used to select appropriate function unit in issue.
@@ -251,7 +251,8 @@ class StaticInst : public StaticInstBase
* obtain the dependence info (numSrcRegs and srcRegIdx[]) for
* just the EA computation.
*/
- virtual StaticInstPtr<ISA> eaCompInst() { return nullStaticInstPtr; }
+ virtual const
+ StaticInstPtr<ISA> &eaCompInst() const { return nullStaticInstPtr; }
/**
* Memory references only: returns "fake" instruction representing
@@ -259,7 +260,8 @@ class StaticInst : public StaticInstBase
* obtain the dependence info (numSrcRegs and srcRegIdx[]) for
* just the memory access (not the EA computation).
*/
- virtual StaticInstPtr<ISA> memAccInst() { return nullStaticInstPtr; }
+ virtual const
+ StaticInstPtr<ISA> &memAccInst() const { return nullStaticInstPtr; }
/// The binary machine instruction.
const MachInst machInst;
@@ -309,20 +311,17 @@ class StaticInst : public StaticInstBase
/**
* Execute this instruction under SimpleCPU model.
*/
- virtual Fault execute(SimpleCPUExecContext *xc,
- Trace::InstRecord *traceData) = 0;
+ virtual Fault execute(SimpleCPU *xc, Trace::InstRecord *traceData) = 0;
/**
* Execute this instruction under FastCPU model.
*/
- virtual Fault execute(FastCPUExecContext *xc,
- Trace::InstRecord *traceData) = 0;
+ virtual Fault execute(FastCPU *xc, Trace::InstRecord *traceData) = 0;
/**
* Execute this instruction under detailed FullCPU model.
*/
- virtual Fault execute(FullCPUExecContext *xc,
- Trace::InstRecord *traceData) = 0;
+ virtual Fault execute(DynInst *xc, Trace::InstRecord *traceData) = 0;
/**
* Return the target address for a PC-relative branch.