summaryrefslogtreecommitdiff
path: root/src/cpu/o3/fetch_impl.hh
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-04-15 21:52:38 +0000
committerGabe Black <gblack@eecs.umich.edu>2007-04-15 21:52:38 +0000
commit8248af53b19a633ae6d9aa8cd6b5a12cfa3b1644 (patch)
tree56ca4cc3fc9ae682b60fb6b50e5f3328640ed660 /src/cpu/o3/fetch_impl.hh
parent308b2f0ce3215eaaed69da937555008f9ed36835 (diff)
downloadgem5-8248af53b19a633ae6d9aa8cd6b5a12cfa3b1644.tar.xz
Make an inner loop which pulls microops out of macroops. These aren't checked for control flow because we can pull out microops until we run out of buffer. This prevents microops from being interpretted as branches because the pc doesn't become npc.
--HG-- extra : convert_revision : 9fff7c6c32900692bbc567ecb75701c9c73da259
Diffstat (limited to 'src/cpu/o3/fetch_impl.hh')
-rw-r--r--src/cpu/o3/fetch_impl.hh127
1 files changed, 64 insertions, 63 deletions
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index d1f38e38b..3ae7bc402 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -1094,11 +1094,9 @@ DefaultFetch<Impl>::fetch(bool &status_change)
// ended this fetch block.
bool predicted_branch = false;
- for (;
- offset < cacheBlkSize &&
- numInst < fetchWidth &&
- !predicted_branch;
- ++numInst) {
+ while (offset < cacheBlkSize &&
+ numInst < fetchWidth &&
+ !predicted_branch) {
// If we're branching after this instruction, quite fetching
// from the same block then.
@@ -1109,10 +1107,6 @@ DefaultFetch<Impl>::fetch(bool &status_change)
fetch_PC, fetch_NPC);
}
-
- // Get a sequence number.
- inst_seq = cpu->getAndIncrementInstSeq();
-
// Make sure this is a valid index.
assert(offset <= cacheBlkSize - instSize);
@@ -1129,80 +1123,87 @@ DefaultFetch<Impl>::fetch(bool &status_change)
if (staticInst->isMacroOp())
macroop = staticInst;
}
- if (macroop) {
- staticInst = macroop->fetchMicroOp(fetch_MicroPC);
- if (staticInst->isLastMicroOp())
- macroop = NULL;
- }
+ do {
+ if (macroop) {
+ staticInst = macroop->fetchMicroOp(fetch_MicroPC);
+ if (staticInst->isLastMicroOp())
+ macroop = NULL;
+ }
- // Create a new DynInst from the instruction fetched.
- DynInstPtr instruction = new DynInst(staticInst,
- fetch_PC, fetch_NPC, fetch_MicroPC,
- next_PC, next_NPC, next_MicroPC,
- inst_seq, cpu);
- instruction->setTid(tid);
+ // Get a sequence number.
+ inst_seq = cpu->getAndIncrementInstSeq();
- instruction->setASID(tid);
+ // Create a new DynInst from the instruction fetched.
+ DynInstPtr instruction = new DynInst(staticInst,
+ fetch_PC, fetch_NPC, fetch_MicroPC,
+ next_PC, next_NPC, next_MicroPC,
+ inst_seq, cpu);
+ instruction->setTid(tid);
- instruction->setThreadState(cpu->thread[tid]);
+ instruction->setASID(tid);
- DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x created "
- "[sn:%lli]\n",
- tid, instruction->readPC(), inst_seq);
+ instruction->setThreadState(cpu->thread[tid]);
- //DPRINTF(Fetch, "[tid:%i]: MachInst is %#x\n", tid, ext_inst);
+ DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x created "
+ "[sn:%lli]\n",
+ tid, instruction->readPC(), inst_seq);
- DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n",
- tid, instruction->staticInst->disassemble(fetch_PC));
+ //DPRINTF(Fetch, "[tid:%i]: MachInst is %#x\n", tid, ext_inst);
- instruction->traceData =
- Trace::getInstRecord(curTick, cpu->tcBase(tid),
- instruction->staticInst,
- instruction->readPC());
+ DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n",
+ tid, instruction->staticInst->disassemble(fetch_PC));
- ///FIXME This needs to be more robust in dealing with delay slots
- lookupAndUpdateNextPC(instruction, next_PC, next_NPC, next_MicroPC);
- predicted_branch |= (next_PC != fetch_NPC);
+ instruction->traceData =
+ Trace::getInstRecord(curTick, cpu->tcBase(tid),
+ instruction->staticInst,
+ instruction->readPC());
- // Add instruction to the CPU's list of instructions.
- instruction->setInstListIt(cpu->addInst(instruction));
+ ///FIXME This needs to be more robust in dealing with delay slots
+ predicted_branch |=
+ lookupAndUpdateNextPC(instruction, next_PC, next_NPC, next_MicroPC);
- // Write the instruction to the first slot in the queue
- // that heads to decode.
- toDecode->insts[numInst] = instruction;
+ // Add instruction to the CPU's list of instructions.
+ instruction->setInstListIt(cpu->addInst(instruction));
- toDecode->size++;
+ // Write the instruction to the first slot in the queue
+ // that heads to decode.
+ toDecode->insts[numInst] = instruction;
- // Increment stat of fetched instructions.
- ++fetchedInsts;
+ toDecode->size++;
- // Move to the next instruction, unless we have a branch.
- fetch_PC = next_PC;
- fetch_NPC = next_NPC;
- fetch_MicroPC = next_MicroPC;
+ // Increment stat of fetched instructions.
+ ++fetchedInsts;
- if (instruction->isQuiesce()) {
- DPRINTF(Fetch, "Quiesce instruction encountered, halting fetch!",
- curTick);
- fetchStatus[tid] = QuiescePending;
- ++numInst;
- status_change = true;
- break;
- }
+ // Move to the next instruction, unless we have a branch.
+ fetch_PC = next_PC;
+ fetch_NPC = next_NPC;
+ fetch_MicroPC = next_MicroPC;
+
+ if (instruction->isQuiesce()) {
+ DPRINTF(Fetch, "Quiesce instruction encountered, halting fetch!",
+ curTick);
+ fetchStatus[tid] = QuiescePending;
+ ++numInst;
+ status_change = true;
+ break;
+ }
- if (!macroop)
- offset += instSize;
+ ++numInst;
+ } while (staticInst->isMicroOp() &&
+ !staticInst->isLastMicroOp() &&
+ numInst < fetchWidth);
+ offset += instSize;
}
- if (offset >= cacheBlkSize) {
- DPRINTF(Fetch, "[tid:%i]: Done fetching, reached the end of cache "
- "block.\n", tid);
+ if (predicted_branch) {
+ DPRINTF(Fetch, "[tid:%i]: Done fetching, predicted branch "
+ "instruction encountered.\n", tid);
} else if (numInst >= fetchWidth) {
DPRINTF(Fetch, "[tid:%i]: Done fetching, reached fetch bandwidth "
"for this cycle.\n", tid);
- } else if (predicted_branch) {
- DPRINTF(Fetch, "[tid:%i]: Done fetching, predicted branch "
- "instruction encountered.\n", tid);
+ } else if (offset >= cacheBlkSize) {
+ DPRINTF(Fetch, "[tid:%i]: Done fetching, reached the end of cache "
+ "block.\n", tid);
}
}