summaryrefslogtreecommitdiff
path: root/src/cpu/base_dyn_inst.hh
diff options
context:
space:
mode:
authorGeoffrey Blake <geoffrey.blake@arm.com>2012-01-31 07:46:03 -0800
committerGeoffrey Blake <geoffrey.blake@arm.com>2012-01-31 07:46:03 -0800
commitaf6aaf258171027af8d3cf0ef86dddff501a3ccb (patch)
tree3473845b7217b48dcf43460f0a90ca655a7018ed /src/cpu/base_dyn_inst.hh
parentade53def9252a36a39b2c4bd61196355906f0505 (diff)
downloadgem5-af6aaf258171027af8d3cf0ef86dddff501a3ccb.tar.xz
CheckerCPU: Re-factor CheckerCPU to be compatible with current gem5
Brings the CheckerCPU back to life to allow FS and SE checking of the O3CPU. These changes have only been tested with the ARM ISA. Other ISAs potentially require modification.
Diffstat (limited to 'src/cpu/base_dyn_inst.hh')
-rw-r--r--src/cpu/base_dyn_inst.hh84
1 files changed, 59 insertions, 25 deletions
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index 5719fc84d..14889a206 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -48,6 +48,7 @@
#include <bitset>
#include <list>
#include <string>
+#include <queue>
#include "arch/faults.hh"
#include "arch/utility.hh"
@@ -55,6 +56,7 @@
#include "base/trace.hh"
#include "config/full_system.hh"
#include "config/the_isa.hh"
+#include "config/use_checker.hh"
#include "cpu/o3/comm.hh"
#include "cpu/exetrace.hh"
#include "cpu/inst_seq.hh"
@@ -176,6 +178,11 @@ class BaseDynInst : public FastAlloc, public RefCounted
RequestPtr savedSreqLow;
RequestPtr savedSreqHigh;
+#if USE_CHECKER
+ // Need a copy of main request pointer to verify on writes.
+ RequestPtr reqToVerify;
+#endif //USE_CHECKER
+
/** @todo: Consider making this private. */
public:
/** The sequence number of the instruction. */
@@ -248,14 +255,17 @@ class BaseDynInst : public FastAlloc, public RefCounted
union Result {
uint64_t integer;
-// float fp;
double dbl;
+ void set(uint64_t i) { integer = i; }
+ void set(double d) { dbl = d; }
+ void get(uint64_t& i) { i = integer; }
+ void get(double& d) { d = dbl; }
};
- /** The result of the instruction; assumes for now that there's only one
- * destination register.
+ /** The result of the instruction; assumes an instruction can have many
+ * destination registers.
*/
- Result instResult;
+ std::queue<Result> instResult;
/** Records changes to result? */
bool recordResult;
@@ -558,56 +568,68 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** Returns the logical register index of the i'th source register. */
RegIndex srcRegIdx(int i) const { return staticInst->srcRegIdx(i); }
- /** Returns the result of an integer instruction. */
- uint64_t readIntResult() { return instResult.integer; }
+ /** Pops a result off the instResult queue */
+ template <class T>
+ void popResult(T& t)
+ {
+ if (!instResult.empty()) {
+ instResult.front().get(t);
+ instResult.pop();
+ }
+ }
- /** Returns the result of a floating point instruction. */
- float readFloatResult() { return (float)instResult.dbl; }
+ /** Read the most recent result stored by this instruction */
+ template <class T>
+ void readResult(T& t)
+ {
+ instResult.back().get(t);
+ }
- /** Returns the result of a floating point (double) instruction. */
- double readDoubleResult() { return instResult.dbl; }
+ /** Pushes a result onto the instResult queue */
+ template <class T>
+ void setResult(T t)
+ {
+ if (recordResult) {
+ Result instRes;
+ instRes.set(t);
+ instResult.push(instRes);
+ }
+ }
/** Records an integer register being set to a value. */
void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
{
- if (recordResult)
- instResult.integer = val;
+ setResult<uint64_t>(val);
}
/** Records an fp register being set to a value. */
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
int width)
{
- if (recordResult) {
- if (width == 32)
- instResult.dbl = (double)val;
- else if (width == 64)
- instResult.dbl = val;
- else
- panic("Unsupported width!");
+ if (width == 32 || width == 64) {
+ setResult<double>(val);
+ } else {
+ panic("Unsupported width!");
}
}
/** Records an fp register being set to a value. */
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
{
- if (recordResult)
- instResult.dbl = (double)val;
+ setResult<double>(val);
}
/** Records an fp register being set to an integer value. */
void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val,
int width)
{
- if (recordResult)
- instResult.integer = val;
+ setResult<uint64_t>(val);
}
/** Records an fp register being set to an integer value. */
void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val)
{
- if (recordResult)
- instResult.integer = val;
+ setResult<uint64_t>(val);
}
/** Records that one of the source registers is ready. */
@@ -872,6 +894,12 @@ BaseDynInst<Impl>::readMem(Addr addr, uint8_t *data,
effAddr = req->getVaddr();
effSize = size;
effAddrValid = true;
+#if USE_CHECKER
+ if (reqToVerify != NULL) {
+ delete reqToVerify;
+ }
+ reqToVerify = new Request(*req);
+#endif //USE_CHECKER
fault = cpu->read(req, sreqLow, sreqHigh, data, lqIdx);
} else {
// Commit will have to clean up whatever happened. Set this
@@ -927,6 +955,12 @@ BaseDynInst<Impl>::writeMem(uint8_t *data, unsigned size,
effAddr = req->getVaddr();
effSize = size;
effAddrValid = true;
+#if USE_CHECKER
+ if (reqToVerify != NULL) {
+ delete reqToVerify;
+ }
+ reqToVerify = new Request(*req);
+#endif // USE_CHECKER
fault = cpu->write(req, sreqLow, sreqHigh, data, sqIdx);
}