From f9cbef9bf79c6158c0c8f84300e6d169aa9576f5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 10 Oct 2021 14:53:43 -0700 Subject: [PATCH] cpu-minor: Disentangle the PC and fetch address. The minor CPU was using a PCState object both to track redirects when taking a branch, etc, and to track where to fetch a line of memory from. It would need to create a new PCState object, or at least update the existing one, whenever it needed to advance to the next line. This is problematic since it means the minor CPU needs to know how to create or set a PCState object, and since it by necessity only understands the most basic aspect of a PCState, what the address is, it can only set that, with all the other potential attributes staying at their old values or getting set to some default. Instead, this change separates the two. There is now a PC which is used for redirects which the later stages will only pick up if there is a change in "sequence", the same behavior as before. This PC will only ever be set when changing sequence, and will otherwise not be meaningful/useful. There is also now a separate fetch address which is what the fetch stage uses to get new lines. This was all the PC value that was artificially updated was used for anyway. Change-Id: Ia64bbe21e980566ae77786999689c9c8a94e9378 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52048 Tested-by: kokoro Reviewed-by: ZHENGRONG WANG Maintainer: ZHENGRONG WANG --- src/cpu/minor/fetch1.cc | 19 ++++++++++++------- src/cpu/minor/fetch1.hh | 12 ++++++++---- src/cpu/minor/pipe_data.hh | 5 ++++- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/cpu/minor/fetch1.cc b/src/cpu/minor/fetch1.cc index 198ed52588..193ebaa452 100644 --- a/src/cpu/minor/fetch1.cc +++ b/src/cpu/minor/fetch1.cc @@ -157,7 +157,7 @@ Fetch1::fetchLine(ThreadID tid) /* If line_offset != 0, a request is pushed for the remainder of the * line. */ /* Use a lower, sizeof(MachInst) aligned address for the fetch */ - Addr aligned_pc = thread.pc.instAddr() & ~((Addr) lineSnap - 1); + Addr aligned_pc = thread.fetchAddr & ~((Addr) lineSnap - 1); unsigned int line_offset = aligned_pc % lineSnap; unsigned int request_size = maxLineWidth - line_offset; @@ -166,17 +166,18 @@ Fetch1::fetchLine(ThreadID tid) thread.streamSeqNum, thread.predictionSeqNum, lineSeqNum); - FetchRequestPtr request = new FetchRequest(*this, request_id, thread.pc); + FetchRequestPtr request = new FetchRequest(*this, request_id, + thread.fetchAddr); DPRINTF(Fetch, "Inserting fetch into the fetch queue " "%s addr: 0x%x pc: %s line_offset: %d request_size: %d\n", - request_id, aligned_pc, thread.pc, line_offset, request_size); + request_id, aligned_pc, thread.fetchAddr, line_offset, request_size); request->request->setContext(cpu.threads[tid]->getTC()->contextId()); request->request->setVirt( aligned_pc, request_size, Request::INST_FETCH, cpu.instRequestorId(), /* I've no idea why we need the PC, but give it */ - thread.pc.instAddr()); + thread.fetchAddr); DPRINTF(Fetch, "Submitting ITLB request\n"); numFetchesInITLB++; @@ -200,7 +201,7 @@ Fetch1::fetchLine(ThreadID tid) /* Step the PC for the next line onto the line aligned next address. * Note that as instructions can span lines, this PC is only a * reliable 'new' PC if the next line has a new stream sequence number. */ - thread.pc.set(aligned_pc + request_size); + thread.fetchAddr = aligned_pc + request_size; } std::ostream & @@ -511,6 +512,7 @@ Fetch1::changeStream(const BranchData &branch) break; } thread.pc = branch.target; + thread.fetchAddr = thread.pc.instAddr(); } void @@ -543,8 +545,10 @@ Fetch1::processResponse(Fetch1::FetchRequestPtr response, line.setFault(response->fault); /* Make sequence numbers valid in return */ line.id = response->id; - /* Set PC to virtual address */ - line.pc = response->pc; + /* Set the PC in case there was a sequence change */ + line.pc = thread.pc; + /* Set fetch address to virtual address */ + line.fetchAddr = response->pc; /* Set the lineBase, which is a sizeof(MachInst) aligned address <= * pc.instAddr() */ line.lineBaseAddr = response->request->getVaddr(); @@ -712,6 +716,7 @@ Fetch1::wakeupFetch(ThreadID tid) ThreadContext *thread_ctx = cpu.getContext(tid); Fetch1ThreadInfo &thread = fetchInfo[tid]; thread.pc = thread_ctx->pcState(); + thread.fetchAddr = thread.pc.instAddr(); thread.state = FetchRunning; thread.wakeupGuard = true; DPRINTF(Fetch, "[tid:%d]: Changing stream wakeup %s\n", diff --git a/src/cpu/minor/fetch1.hh b/src/cpu/minor/fetch1.hh index dcdf35e77e..434fbba905 100644 --- a/src/cpu/minor/fetch1.hh +++ b/src/cpu/minor/fetch1.hh @@ -139,7 +139,7 @@ class Fetch1 : public Named RequestPtr request; /** PC to fixup with line address */ - TheISA::PCState pc; + Addr pc; /** Fill in a fault if one happens during fetch, check this by * picking apart the response packet */ @@ -173,7 +173,7 @@ class Fetch1 : public Named ThreadContext *tc, BaseMMU::Mode mode); public: - FetchRequest(Fetch1 &fetch_, InstId id_, TheISA::PCState pc_) : + FetchRequest(Fetch1 &fetch_, InstId id_, Addr pc_) : SenderState(), fetch(fetch_), state(NotIssued), @@ -248,6 +248,7 @@ class Fetch1 : public Named Fetch1ThreadInfo() : state(FetchWaitingForPC), pc(TheISA::PCState(0)), + fetchAddr(0), streamSeqNum(InstId::firstStreamSeqNum), predictionSeqNum(InstId::firstPredictionSeqNum), blocked(false), @@ -265,10 +266,13 @@ class Fetch1 : public Named FetchState state; /** Fetch PC value. This is updated by branches from Execute, branch - * prediction targets from Fetch2 and by incrementing it as we fetch - * lines subsequent to those two sources. */ + * prediction targets from Fetch2. This is only valid immediately + * following a redirect from one of those two sources. */ TheISA::PCState pc; + /** The address we're currently fetching lines from. */ + Addr fetchAddr; + /** Stream sequence number. This changes on request from Execute and is * used to tag instructions by the fetch stream to which they belong. * Execute originates new prediction sequence numbers. */ diff --git a/src/cpu/minor/pipe_data.hh b/src/cpu/minor/pipe_data.hh index f16af27b1d..e9bad03781 100644 --- a/src/cpu/minor/pipe_data.hh +++ b/src/cpu/minor/pipe_data.hh @@ -184,9 +184,12 @@ class ForwardLineData /* : public ReportIF, public BubbleIF */ * <= pc.instAddr() */ Addr lineBaseAddr; - /** PC of the first requested inst within this line */ + /** PC of the first inst within this sequence */ TheISA::PCState pc; + /** Address of this line of data */ + Addr fetchAddr; + /** Explicit line width, don't rely on data.size */ unsigned int lineWidth;