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;