cpu: Fix rename mis-handling serializing instructions when resource constrained

The rename can mis-handle serializing instructions (i.e. strex) if it gets
into a resource constrained situation and the serializing instruction has
to be placed on the skid buffer to handle blocking.  In this situation the
instruction informs the pipeline it is serializing and logs that the next
instruction must be serialized, but since we are blocking the pipeline
defers this action to place the serializing instruction and
incoming instructions into the skid buffer. When resuming from blocking,
rename will pull the serializing instruction from the skid buffer and
the current logic will see this as the "next" instruction that has to
be serialized and because of flags set on the serializing instruction,
it passes through the pipeline stage as normal and resets rename to
non-serializing.  This causes instructions to follow the serializing inst
incorrectly and eventually leads to an error in the pipeline. To fix this
rename should check first if it has to block before checking for serializing
instructions.
This commit is contained in:
Geoffrey Blake 2013-02-15 17:40:10 -05:00
parent 27630e9cad
commit 8e79c68936

View file

@ -600,6 +600,18 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
DPRINTF(Rename, "[tid:%u]: Processing instruction [sn:%lli] with "
"PC %s.\n", tid, inst->seqNum, inst->pcState());
// Check here to make sure there are enough destination registers
// to rename to. Otherwise block.
if (renameMap[tid]->numFreeEntries() < inst->numDestRegs()) {
DPRINTF(Rename, "Blocking due to lack of free "
"physical registers to rename to.\n");
blockThisCycle = true;
insts_to_rename.push_front(inst);
++renameFullRegistersEvents;
break;
}
// Handle serializeAfter/serializeBefore instructions.
// serializeAfter marks the next instruction as serializeBefore.
// serializeBefore makes the instruction wait in rename until the ROB
@ -641,18 +653,6 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
serializeAfter(insts_to_rename, tid);
}
// Check here to make sure there are enough destination registers
// to rename to. Otherwise block.
if (renameMap[tid]->numFreeEntries() < inst->numDestRegs()) {
DPRINTF(Rename, "Blocking due to lack of free "
"physical registers to rename to.\n");
blockThisCycle = true;
insts_to_rename.push_front(inst);
++renameFullRegistersEvents;
break;
}
renameSrcRegs(inst, inst->threadNumber);
renameDestRegs(inst, inst->threadNumber);