From: Geoffrey Blake Date: Fri, 15 Feb 2013 22:40:10 +0000 (-0500) Subject: cpu: Fix rename mis-handling serializing instructions when resource constrained X-Git-Tag: stable_2013_06_16~112 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8e79c68936f819e9efa05e5085232bd501af2bc7;p=gem5.git 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. --- diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index e27c66dcd..341ba8804 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -600,6 +600,18 @@ DefaultRename::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::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);