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:
parent
27630e9cad
commit
8e79c68936
|
@ -600,6 +600,18 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
|
||||||
DPRINTF(Rename, "[tid:%u]: Processing instruction [sn:%lli] with "
|
DPRINTF(Rename, "[tid:%u]: Processing instruction [sn:%lli] with "
|
||||||
"PC %s.\n", tid, inst->seqNum, inst->pcState());
|
"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.
|
// Handle serializeAfter/serializeBefore instructions.
|
||||||
// serializeAfter marks the next instruction as serializeBefore.
|
// serializeAfter marks the next instruction as serializeBefore.
|
||||||
// serializeBefore makes the instruction wait in rename until the ROB
|
// serializeBefore makes the instruction wait in rename until the ROB
|
||||||
|
@ -641,18 +653,6 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
|
||||||
serializeAfter(insts_to_rename, 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);
|
renameSrcRegs(inst, inst->threadNumber);
|
||||||
|
|
||||||
renameDestRegs(inst, inst->threadNumber);
|
renameDestRegs(inst, inst->threadNumber);
|
||||||
|
|
Loading…
Reference in a new issue