From: Tuan Ta Date: Mon, 2 Apr 2018 20:22:16 +0000 (-0400) Subject: cpu: fix how branching is handled when a thread is suspended in MinorCPU X-Git-Tag: v19.0.0.0~1172 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e437086341712f1435db655b3527ea29b3311f4e;p=gem5.git cpu: fix how branching is handled when a thread is suspended in MinorCPU When a thread is suspended, all instructions after the suspension need to be discarded since the thread will take a different execution stream when it wakes up. To do that, in MinorCPU, whenever a thread gets suspended, we change the current execution stream by updating the current branch with BranchData::SuspendThread reason. Change-Id: I7cdcda22c1cf6e8ac8db8800b7d9ec052433fdf3 Reviewed-on: https://gem5-review.googlesource.com/c/9626 Reviewed-by: Jason Lowe-Power Reviewed-by: Giacomo Gabrielli Maintainer: Jason Lowe-Power --- diff --git a/src/cpu/minor/execute.cc b/src/cpu/minor/execute.cc index d7cb475c6..234a233c2 100644 --- a/src/cpu/minor/execute.cc +++ b/src/cpu/minor/execute.cc @@ -248,7 +248,14 @@ Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch) pc_before, target); } - if (inst->predictedTaken && !force_branch) { + if (thread->status() == ThreadContext::Suspended) { + /* Thread got suspended */ + DPRINTF(Branch, "Thread got suspended: branch from 0x%x to 0x%x " + "inst: %s\n", + inst->pc.instAddr(), target.instAddr(), *inst); + + reason = BranchData::SuspendThread; + } else if (inst->predictedTaken && !force_branch) { /* Predicted to branch */ if (!must_branch) { /* No branch was taken, change stream to get us back to the @@ -1054,8 +1061,7 @@ Execute::commit(ThreadID thread_id, bool only_commit_microops, bool discard, !branch.isStreamChange() && /* No real branch */ fault == NoFault && /* No faults */ completed_inst && /* Still finding instructions to execute */ - num_insts_committed != commitLimit && /* Not reached commit limit */ - cpu.getContext(thread_id)->status() != ThreadContext::Suspended + num_insts_committed != commitLimit /* Not reached commit limit */ ) { if (only_commit_microops) {