changeset 1edf525495b1 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=1edf525495b1
description:
inorder: handle serializing instructions
including IPR accesses and store-conditionals. These class of
instructions will not
execute correctly in a superscalar machine
diffstat:
src/cpu/inorder/pipeline_stage.cc | 1 +
src/cpu/inorder/resource.cc | 1 +
src/cpu/inorder/resources/cache_unit.cc | 6 +++-
src/cpu/inorder/resources/execution_unit.cc | 20 +++--------------
src/cpu/inorder/resources/execution_unit.hh | 1 -
src/cpu/inorder/resources/use_def.cc | 33 ++++++++++++++++++++++------
src/cpu/inorder/resources/use_def.hh | 4 ++-
7 files changed, 39 insertions(+), 27 deletions(-)
diffs (182 lines):
diff -r 87c3641f5bed -r 1edf525495b1 src/cpu/inorder/pipeline_stage.cc
--- a/src/cpu/inorder/pipeline_stage.cc Sun Jun 19 21:43:40 2011 -0400
+++ b/src/cpu/inorder/pipeline_stage.cc Sun Jun 19 21:43:41 2011 -0400
@@ -1093,6 +1093,7 @@
// Take note of trace data for this inst & stage
if (inst->traceData) {
+ //@todo: exec traces are broke. fix them
inst->traceData->setStageCycle(stageNum, curTick());
}
diff -r 87c3641f5bed -r 1edf525495b1 src/cpu/inorder/resource.cc
--- a/src/cpu/inorder/resource.cc Sun Jun 19 21:43:40 2011 -0400
+++ b/src/cpu/inorder/resource.cc Sun Jun 19 21:43:41 2011 -0400
@@ -272,6 +272,7 @@
void
Resource::execute(int slot_idx)
{
+ //@todo: have each resource print out command their executing
DPRINTF(Resource, "[tid:%i]: Executing %s resource.\n",
reqs[slot_idx]->getTid(), name());
reqs[slot_idx]->setCompleted(true);
diff -r 87c3641f5bed -r 1edf525495b1 src/cpu/inorder/resources/cache_unit.cc
--- a/src/cpu/inorder/resources/cache_unit.cc Sun Jun 19 21:43:40 2011 -0400
+++ b/src/cpu/inorder/resources/cache_unit.cc Sun Jun 19 21:43:41 2011 -0400
@@ -105,8 +105,10 @@
pkt->getAddr());
else if (pkt->isResponse())
cachePortUnit->processCacheCompletion(pkt);
- else
- DPRINTF(Cache, "Received snoop pkt %x,Ignoring\n", pkt->getAddr());
+ else {
+ //@note: depending on consistency model, update here
+ DPRINTF(InOrderCachePort, "Received snoop pkt %x,Ignoring\n",
pkt->getAddr());
+ }
return true;
}
diff -r 87c3641f5bed -r 1edf525495b1 src/cpu/inorder/resources/execution_unit.cc
--- a/src/cpu/inorder/resources/execution_unit.cc Sun Jun 19 21:43:40
2011 -0400
+++ b/src/cpu/inorder/resources/execution_unit.cc Sun Jun 19 21:43:41
2011 -0400
@@ -45,7 +45,7 @@
int res_latency, InOrderCPU *_cpu,
ThePipeline::Params *params)
: Resource(res_name, res_id, res_width, res_latency, _cpu),
- lastExecuteTick(0), lastControlTick(0), serializeTick(0)
+ lastExecuteTick(0), lastControlTick(0)
{ }
void
@@ -103,13 +103,6 @@
#if TRACING_ON
InstSeqNum seq_num = inst->seqNum;
#endif
- if (cur_tick == serializeTick) {
- DPRINTF(InOrderExecute, "Can not execute [tid:%i][sn:%i][PC:%s] %s. "
- "All instructions are being serialized this cycle\n",
- inst->readTid(), seq_num, inst->pcState(), inst->instName());
- exec_req->done(false);
- return;
- }
switch (exec_req->cmd)
{
@@ -131,15 +124,9 @@
lastExecuteTick = cur_tick;
}
+ //@todo: handle address generation here
assert(!inst->isMemRef());
- if (inst->isSerializeAfter()) {
- serializeTick = cur_tick;
- DPRINTF(InOrderExecute, "Serializing execution after [tid:%i] "
- "[sn:%i] [PC:%s] %s.\n", inst->readTid(), seq_num,
- inst->pcState(), inst->instName());
- }
-
if (inst->isControl()) {
if (lastControlTick == cur_tick) {
DPRINTF(InOrderExecute, "Can not Execute More than One
Control "
@@ -219,11 +206,12 @@
#if TRACING_ON
for (int didx = 0; didx < inst->numDestRegs(); didx++)
if (inst->resultType(didx) == InOrderDynInst::Float ||
+ inst->resultType(didx) ==
InOrderDynInst::FloatBits ||
inst->resultType(didx) == InOrderDynInst::Double)
DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: Dest
result %i "
"of FP execution is %08f (%x).\n",
inst->readTid(),
seq_num, didx, inst->readFloatResult(didx),
- inst->readIntResult(didx));
+ inst->readFloatBitsResult(didx));
else
DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: Dest
result %i "
"of Int execution is 0x%x.\n",
inst->readTid(),
diff -r 87c3641f5bed -r 1edf525495b1 src/cpu/inorder/resources/execution_unit.hh
--- a/src/cpu/inorder/resources/execution_unit.hh Sun Jun 19 21:43:40
2011 -0400
+++ b/src/cpu/inorder/resources/execution_unit.hh Sun Jun 19 21:43:41
2011 -0400
@@ -76,7 +76,6 @@
Stats::Scalar executions;
Tick lastExecuteTick;
Tick lastControlTick;
- Tick serializeTick;
};
diff -r 87c3641f5bed -r 1edf525495b1 src/cpu/inorder/resources/use_def.cc
--- a/src/cpu/inorder/resources/use_def.cc Sun Jun 19 21:43:40 2011 -0400
+++ b/src/cpu/inorder/resources/use_def.cc Sun Jun 19 21:43:41 2011 -0400
@@ -52,7 +52,8 @@
for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
nonSpecInstActive[tid] = &cpu->nonSpecInstActive[tid];
nonSpecSeqNum[tid] = &cpu->nonSpecSeqNum[tid];
-
+ serializeOnNextInst[tid] = false;
+ serializeAfterSeqNum[tid] = 0;
regDepMap[tid] = &cpu->archRegDepMap[tid];
}
@@ -152,11 +153,12 @@
void
UseDefUnit::execute(int slot_idx)
{
- // After this is working, change this to a reinterpret cast
- // for performance considerations
UseDefRequest* ud_req = dynamic_cast<UseDefRequest*>(reqs[slot_idx]);
- assert(ud_req);
DynInstPtr inst = ud_req->inst;
+ ThreadID tid = inst->readTid();
+ InstSeqNum seq_num = inst->seqNum;
+ int ud_idx = ud_req->useDefIdx;
+
if (inst->fault != NoFault) {
DPRINTF(InOrderUseDef,
"[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
@@ -166,11 +168,28 @@
return;
}
- ThreadID tid = inst->readTid();
- InstSeqNum seq_num = inst->seqNum;
- int ud_idx = ud_req->useDefIdx;
+ if (serializeOnNextInst[tid] &&
+ seq_num > serializeAfterSeqNum[tid]) {
+ inst->setSerializeBefore();
+ serializeOnNextInst[tid] = false;
+ }
+
+ if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
+ cpu->instList[tid].front() != inst) {
+ DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] Serialize before instruction
encountered."
+ " Blocking until pipeline is clear.\n", tid, seq_num);
+ ud_req->done(false);
+ return;
+ } else if (inst->isStoreConditional() || inst->isSerializeAfter()) {
+ DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] Serialize after instruction
encountered."
+ " Blocking until pipeline is clear.\n", tid, seq_num);
+ serializeOnNextInst[tid] = true;
+ serializeAfterSeqNum[tid] = seq_num;
+ }
+
// If there is a non-speculative instruction
// in the pipeline then stall instructions here
+ // ---
if (*nonSpecInstActive[tid] == true && seq_num > *nonSpecSeqNum[tid]) {
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] cannot execute because"
"there is non-speculative instruction [sn:%i] has not "
diff -r 87c3641f5bed -r 1edf525495b1 src/cpu/inorder/resources/use_def.hh
--- a/src/cpu/inorder/resources/use_def.hh Sun Jun 19 21:43:40 2011 -0400
+++ b/src/cpu/inorder/resources/use_def.hh Sun Jun 19 21:43:41 2011 -0400
@@ -76,8 +76,10 @@
RegDepMap *regDepMap[ThePipeline::MaxThreads];
bool *nonSpecInstActive[ThePipeline::MaxThreads];
+ InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
- InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
+ bool serializeOnNextInst[ThePipeline::MaxThreads];
+ InstSeqNum serializeAfterSeqNum[ThePipeline::MaxThreads];
Stats::Average uniqueRegsPerSwitch;
std::map<RegIndex, bool> uniqueIntRegMap;
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev