// Make sure this is a valid index.
assert(offset <= cacheBlkSize - instSize);
- // Get the instruction from the array of the cache line.
- inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *>
- (&cacheData[tid][offset]));
+ if (!macroop) {
+ // Get the instruction from the array of the cache line.
+ inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *>
+ (&cacheData[tid][offset]));
- predecoder.setTC(cpu->thread[tid]->getTC());
- predecoder.moreBytes(fetch_PC, fetch_PC, 0, inst);
+ predecoder.setTC(cpu->thread[tid]->getTC());
- predecoder.moreBytes(fetch_PC, 0, inst);
++ predecoder.moreBytes(fetch_PC, fetch_PC, 0, inst);
- ext_inst = predecoder.getExtMachInst();
+ ext_inst = predecoder.getExtMachInst();
+ staticInst = StaticInstPtr(ext_inst);
+ if (staticInst->isMacroOp())
+ macroop = staticInst;
+ }
+ 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(ext_inst,
- fetch_PC, fetch_NPC,
- next_PC, next_NPC,
- 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);
+
+ DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n",
+ tid, instruction->staticInst->disassemble(fetch_PC));
- instruction->traceData =
- Trace::getInstRecord(curTick, cpu->tcBase(tid),
- instruction->staticInst,
- instruction->readPC());
+#if TRACING_ON
- instruction->traceData = NULL;
+ instruction->traceData =
+ Trace::getInstRecord(curTick, cpu->tcBase(tid),
+ instruction->staticInst,
+ instruction->readPC());
+#else
++ instruction->traceData = NULL;
+#endif
- ///FIXME This needs to be more robust in dealing with delay slots
- #if !ISA_HAS_DELAY_SLOT
- // predicted_branch |=
- #endif
- lookupAndUpdateNextPC(instruction, next_PC, next_NPC);
- predicted_branch |= (next_PC != fetch_NPC);
+ ///FIXME This needs to be more robust in dealing with delay slots
+ predicted_branch |=
+ lookupAndUpdateNextPC(instruction, next_PC, next_NPC, next_MicroPC);
- // Add instruction to the CPU's list of instructions.
- instruction->setInstListIt(cpu->addInst(instruction));
+ // Add instruction to the CPU's list of instructions.
+ instruction->setInstListIt(cpu->addInst(instruction));
- // Write the instruction to the first slot in the queue
- // that heads to decode.
- toDecode->insts[numInst] = instruction;
+ // Write the instruction to the first slot in the queue
+ // that heads to decode.
+ toDecode->insts[numInst] = instruction;
- toDecode->size++;
+ toDecode->size++;
- // Increment stat of fetched instructions.
- ++fetchedInsts;
+ // Increment stat of fetched instructions.
+ ++fetchedInsts;
- // Move to the next instruction, unless we have a branch.
- fetch_PC = next_PC;
- fetch_NPC = next_NPC;
+ // 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 (instruction->isQuiesce()) {
+ DPRINTF(Fetch, "Quiesce instruction encountered, halting fetch!",
+ curTick);
+ fetchStatus[tid] = QuiescePending;
+ ++numInst;
+ status_change = true;
+ break;
+ }
+ ++numInst;
+ } while (staticInst->isMicroOp() &&
+ !staticInst->isLastMicroOp() &&
+ numInst < fetchWidth);
offset += instSize;
}