fetch_impl.hh (3070:0ca43be10749) fetch_impl.hh (3093:b09c33e66bce)
1/*
2 * Copyright (c) 2004-2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 325 unchanged lines hidden (view full) ---

334template<class Impl>
335void
336DefaultFetch<Impl>::initStage()
337{
338 // Setup PC and nextPC with initial state.
339 for (int tid = 0; tid < numThreads; tid++) {
340 PC[tid] = cpu->readPC(tid);
341 nextPC[tid] = cpu->readNextPC(tid);
1/*
2 * Copyright (c) 2004-2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 325 unchanged lines hidden (view full) ---

334template<class Impl>
335void
336DefaultFetch<Impl>::initStage()
337{
338 // Setup PC and nextPC with initial state.
339 for (int tid = 0; tid < numThreads; tid++) {
340 PC[tid] = cpu->readPC(tid);
341 nextPC[tid] = cpu->readNextPC(tid);
342#if THE_ISA != ALPHA_ISA
342#if ISA_HAS_DELAY_SLOT
343 nextNPC[tid] = cpu->readNextNPC(tid);
344#endif
345 }
346}
347
348template<class Impl>
349void
350DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)

--- 73 unchanged lines hidden (view full) ---

424 // Reset all state
425 for (int i = 0; i < Impl::MaxThreads; ++i) {
426 stalls[i].decode = 0;
427 stalls[i].rename = 0;
428 stalls[i].iew = 0;
429 stalls[i].commit = 0;
430 PC[i] = cpu->readPC(i);
431 nextPC[i] = cpu->readNextPC(i);
343 nextNPC[tid] = cpu->readNextNPC(tid);
344#endif
345 }
346}
347
348template<class Impl>
349void
350DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)

--- 73 unchanged lines hidden (view full) ---

424 // Reset all state
425 for (int i = 0; i < Impl::MaxThreads; ++i) {
426 stalls[i].decode = 0;
427 stalls[i].rename = 0;
428 stalls[i].iew = 0;
429 stalls[i].commit = 0;
430 PC[i] = cpu->readPC(i);
431 nextPC[i] = cpu->readNextPC(i);
432#if THE_ISA != ALPHA_ISA
432#if ISA_HAS_DELAY_SLOT
433 nextNPC[i] = cpu->readNextNPC(i);
434 delaySlotInfo[i].branchSeqNum = -1;
435 delaySlotInfo[i].numInsts = 0;
436 delaySlotInfo[i].targetAddr = 0;
437 delaySlotInfo[i].targetReady = false;
438#endif
439 fetchStatus[i] = Running;
440 }

--- 46 unchanged lines hidden (view full) ---

487 Addr &next_NPC)
488{
489 // Do branch prediction check here.
490 // A bit of a misnomer...next_PC is actually the current PC until
491 // this function updates it.
492 bool predict_taken;
493
494 if (!inst->isControl()) {
433 nextNPC[i] = cpu->readNextNPC(i);
434 delaySlotInfo[i].branchSeqNum = -1;
435 delaySlotInfo[i].numInsts = 0;
436 delaySlotInfo[i].targetAddr = 0;
437 delaySlotInfo[i].targetReady = false;
438#endif
439 fetchStatus[i] = Running;
440 }

--- 46 unchanged lines hidden (view full) ---

487 Addr &next_NPC)
488{
489 // Do branch prediction check here.
490 // A bit of a misnomer...next_PC is actually the current PC until
491 // this function updates it.
492 bool predict_taken;
493
494 if (!inst->isControl()) {
495#if THE_ISA == ALPHA_ISA
496 next_PC = next_PC + instSize;
497 inst->setPredTarg(next_PC);
498#else
495#if ISA_HAS_DELAY_SLOT
499 Addr cur_PC = next_PC;
500 next_PC = cur_PC + instSize; //next_NPC;
501 next_NPC = cur_PC + (2 * instSize);//next_NPC + instSize;
502 inst->setPredTarg(next_NPC);
496 Addr cur_PC = next_PC;
497 next_PC = cur_PC + instSize; //next_NPC;
498 next_NPC = cur_PC + (2 * instSize);//next_NPC + instSize;
499 inst->setPredTarg(next_NPC);
500#else
501 next_PC = next_PC + instSize;
502 inst->setPredTarg(next_PC);
503#endif
504 return false;
505 }
506
507 int tid = inst->threadNumber;
503#endif
504 return false;
505 }
506
507 int tid = inst->threadNumber;
508#if THE_ISA == ALPHA_ISA
509 predict_taken = branchPred.predict(inst, next_PC, tid);
510#else
508#if ISA_HAS_DELAY_SLOT
511 Addr pred_PC = next_PC;
512 predict_taken = branchPred.predict(inst, pred_PC, tid);
513
514 if (predict_taken) {
515 DPRINTF(Fetch, "[tid:%i]: Branch predicted to be true.\n", tid);
516 } else {
517 DPRINTF(Fetch, "[tid:%i]: Branch predicted to be false.\n", tid);
518 }

--- 15 unchanged lines hidden (view full) ---

534 } else {
535 next_PC = next_NPC;
536 // No need to declare a delay slot here since
537 // there is no for the pred. target to jump
538 }
539
540 next_NPC = next_NPC + instSize;
541 }
509 Addr pred_PC = next_PC;
510 predict_taken = branchPred.predict(inst, pred_PC, tid);
511
512 if (predict_taken) {
513 DPRINTF(Fetch, "[tid:%i]: Branch predicted to be true.\n", tid);
514 } else {
515 DPRINTF(Fetch, "[tid:%i]: Branch predicted to be false.\n", tid);
516 }

--- 15 unchanged lines hidden (view full) ---

532 } else {
533 next_PC = next_NPC;
534 // No need to declare a delay slot here since
535 // there is no for the pred. target to jump
536 }
537
538 next_NPC = next_NPC + instSize;
539 }
540#else
541 predict_taken = branchPred.predict(inst, next_PC, tid);
542#endif
543
544 ++fetchedBranches;
545
546 if (predict_taken) {
547 ++predictedBranches;
548 }
549

--- 137 unchanged lines hidden (view full) ---

687DefaultFetch<Impl>::squashFromDecode(const Addr &new_PC,
688 const InstSeqNum &seq_num,
689 unsigned tid)
690{
691 DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n",tid);
692
693 doSquash(new_PC, tid);
694
542#endif
543
544 ++fetchedBranches;
545
546 if (predict_taken) {
547 ++predictedBranches;
548 }
549

--- 137 unchanged lines hidden (view full) ---

687DefaultFetch<Impl>::squashFromDecode(const Addr &new_PC,
688 const InstSeqNum &seq_num,
689 unsigned tid)
690{
691 DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n",tid);
692
693 doSquash(new_PC, tid);
694
695#if THE_ISA != ALPHA_ISA
695#if ISA_HAS_DELAY_SLOT
696 if (seq_num <= delaySlotInfo[tid].branchSeqNum) {
697 delaySlotInfo[tid].numInsts = 0;
698 delaySlotInfo[tid].targetAddr = 0;
699 delaySlotInfo[tid].targetReady = false;
700 }
701#endif
702
703 // Tell the CPU to remove any instructions that are in flight between

--- 71 unchanged lines hidden (view full) ---

775void
776DefaultFetch<Impl>::squash(const Addr &new_PC, const InstSeqNum &seq_num,
777 bool squash_delay_slot, unsigned tid)
778{
779 DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n",tid);
780
781 doSquash(new_PC, tid);
782
696 if (seq_num <= delaySlotInfo[tid].branchSeqNum) {
697 delaySlotInfo[tid].numInsts = 0;
698 delaySlotInfo[tid].targetAddr = 0;
699 delaySlotInfo[tid].targetReady = false;
700 }
701#endif
702
703 // Tell the CPU to remove any instructions that are in flight between

--- 71 unchanged lines hidden (view full) ---

775void
776DefaultFetch<Impl>::squash(const Addr &new_PC, const InstSeqNum &seq_num,
777 bool squash_delay_slot, unsigned tid)
778{
779 DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n",tid);
780
781 doSquash(new_PC, tid);
782
783#if THE_ISA == ALPHA_ISA
784 // Tell the CPU to remove any instructions that are not in the ROB.
785 cpu->removeInstsNotInROB(tid, true, 0);
786#else
783#if ISA_HAS_DELAY_SLOT
787 if (seq_num <= delaySlotInfo[tid].branchSeqNum) {
788 delaySlotInfo[tid].numInsts = 0;
789 delaySlotInfo[tid].targetAddr = 0;
790 delaySlotInfo[tid].targetReady = false;
791 }
792
793 // Tell the CPU to remove any instructions that are not in the ROB.
794 cpu->removeInstsNotInROB(tid, squash_delay_slot, seq_num);
784 if (seq_num <= delaySlotInfo[tid].branchSeqNum) {
785 delaySlotInfo[tid].numInsts = 0;
786 delaySlotInfo[tid].targetAddr = 0;
787 delaySlotInfo[tid].targetReady = false;
788 }
789
790 // Tell the CPU to remove any instructions that are not in the ROB.
791 cpu->removeInstsNotInROB(tid, squash_delay_slot, seq_num);
792#else
793 // Tell the CPU to remove any instructions that are not in the ROB.
794 cpu->removeInstsNotInROB(tid, true, 0);
795#endif
796}
797
798template <class Impl>
799void
800DefaultFetch<Impl>::tick()
801{
802 std::list<unsigned>::iterator threads = (*activeThreads).begin();

--- 93 unchanged lines hidden (view full) ---

896 }
897
898 // Check squash signals from commit.
899 if (fromCommit->commitInfo[tid].squash) {
900
901 DPRINTF(Fetch, "[tid:%u]: Squashing instructions due to squash "
902 "from commit.\n",tid);
903
795#endif
796}
797
798template <class Impl>
799void
800DefaultFetch<Impl>::tick()
801{
802 std::list<unsigned>::iterator threads = (*activeThreads).begin();

--- 93 unchanged lines hidden (view full) ---

896 }
897
898 // Check squash signals from commit.
899 if (fromCommit->commitInfo[tid].squash) {
900
901 DPRINTF(Fetch, "[tid:%u]: Squashing instructions due to squash "
902 "from commit.\n",tid);
903
904#if THE_ISA == ALPHA_ISA
905 InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].doneSeqNum;
904#if ISA_HAS_DELAY_SLOT
905 InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].bdelayDoneSeqNum;
906#else
906#else
907 InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].bdelayDoneSeqNum;
907 InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].doneSeqNum;
908#endif
909 // In any case, squash.
910 squash(fromCommit->commitInfo[tid].nextPC,
911 doneSeqNum,
912 fromCommit->commitInfo[tid].squashDelaySlot,
913 tid);
914
915 // Also check if there's a mispredict that happened.

--- 37 unchanged lines hidden (view full) ---

953 tid);
954 } else {
955 branchPred.squash(fromDecode->decodeInfo[tid].doneSeqNum,
956 tid);
957 }
958
959 if (fetchStatus[tid] != Squashing) {
960
908#endif
909 // In any case, squash.
910 squash(fromCommit->commitInfo[tid].nextPC,
911 doneSeqNum,
912 fromCommit->commitInfo[tid].squashDelaySlot,
913 tid);
914
915 // Also check if there's a mispredict that happened.

--- 37 unchanged lines hidden (view full) ---

953 tid);
954 } else {
955 branchPred.squash(fromDecode->decodeInfo[tid].doneSeqNum,
956 tid);
957 }
958
959 if (fetchStatus[tid] != Squashing) {
960
961#if THE_ISA == ALPHA_ISA
962 InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].doneSeqNum;
963#else
961#if ISA_HAS_DELAY_SLOT
964 InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].bdelayDoneSeqNum;
962 InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].bdelayDoneSeqNum;
963#else
964 InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].doneSeqNum;
965#endif
966 // Squash unless we're already squashing
967 squashFromDecode(fromDecode->decodeInfo[tid].nextPC,
968 doneSeqNum,
969 tid);
970
971 return true;
972 }

--- 151 unchanged lines hidden (view full) ---

1124 DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x created "
1125 "[sn:%lli]\n",
1126 tid, instruction->readPC(), inst_seq);
1127
1128 DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n",
1129 tid, instruction->staticInst->disassemble(fetch_PC));
1130
1131 instruction->traceData =
965#endif
966 // Squash unless we're already squashing
967 squashFromDecode(fromDecode->decodeInfo[tid].nextPC,
968 doneSeqNum,
969 tid);
970
971 return true;
972 }

--- 151 unchanged lines hidden (view full) ---

1124 DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x created "
1125 "[sn:%lli]\n",
1126 tid, instruction->readPC(), inst_seq);
1127
1128 DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n",
1129 tid, instruction->staticInst->disassemble(fetch_PC));
1130
1131 instruction->traceData =
1132 Trace::getInstRecord(curTick, cpu->tcBase(tid),
1132 Trace::getInstRecord(curTick, cpu->tcBase(tid), cpu,
1133 instruction->staticInst,
1133 instruction->staticInst,
1134 instruction->readPC());
1134 instruction->readPC(),tid);
1135
1136 predicted_branch = lookupAndUpdateNextPC(instruction, next_PC,
1137 next_NPC);
1138
1139 // Add instruction to the CPU's list of instructions.
1140 instruction->setInstListIt(cpu->addInst(instruction));
1141
1142 // Write the instruction to the first slot in the queue

--- 14 unchanged lines hidden (view full) ---

1157 fetchStatus[tid] = QuiescePending;
1158 ++numInst;
1159 status_change = true;
1160 break;
1161 }
1162
1163 offset += instSize;
1164
1135
1136 predicted_branch = lookupAndUpdateNextPC(instruction, next_PC,
1137 next_NPC);
1138
1139 // Add instruction to the CPU's list of instructions.
1140 instruction->setInstListIt(cpu->addInst(instruction));
1141
1142 // Write the instruction to the first slot in the queue

--- 14 unchanged lines hidden (view full) ---

1157 fetchStatus[tid] = QuiescePending;
1158 ++numInst;
1159 status_change = true;
1160 break;
1161 }
1162
1163 offset += instSize;
1164
1165#if THE_ISA != ALPHA_ISA
1165#if ISA_HAS_DELAY_SLOT
1166 if (predicted_branch) {
1167 delaySlotInfo[tid].branchSeqNum = inst_seq;
1168
1169 DPRINTF(Fetch, "[tid:%i]: Delay slot branch set to [sn:%i]\n",
1170 tid, inst_seq);
1171 continue;
1172 } else if (delaySlotInfo[tid].numInsts > 0) {
1173 --delaySlotInfo[tid].numInsts;

--- 26 unchanged lines hidden (view full) ---

1200
1201 if (numInst > 0) {
1202 wroteToTimeBuffer = true;
1203 }
1204
1205 // Now that fetching is completed, update the PC to signify what the next
1206 // cycle will be.
1207 if (fault == NoFault) {
1166 if (predicted_branch) {
1167 delaySlotInfo[tid].branchSeqNum = inst_seq;
1168
1169 DPRINTF(Fetch, "[tid:%i]: Delay slot branch set to [sn:%i]\n",
1170 tid, inst_seq);
1171 continue;
1172 } else if (delaySlotInfo[tid].numInsts > 0) {
1173 --delaySlotInfo[tid].numInsts;

--- 26 unchanged lines hidden (view full) ---

1200
1201 if (numInst > 0) {
1202 wroteToTimeBuffer = true;
1203 }
1204
1205 // Now that fetching is completed, update the PC to signify what the next
1206 // cycle will be.
1207 if (fault == NoFault) {
1208#if THE_ISA == ALPHA_ISA
1209 DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n",tid, next_PC);
1210 PC[tid] = next_PC;
1211 nextPC[tid] = next_PC + instSize;
1212#else
1208#if ISA_HAS_DELAY_SLOT
1213 if (delaySlotInfo[tid].targetReady &&
1214 delaySlotInfo[tid].numInsts == 0) {
1215 // Set PC to target
1216 PC[tid] = delaySlotInfo[tid].targetAddr; //next_PC
1217 nextPC[tid] = next_PC + instSize; //next_NPC
1218 nextNPC[tid] = next_PC + (2 * instSize);
1219
1220 delaySlotInfo[tid].targetReady = false;
1221 } else {
1222 PC[tid] = next_PC;
1223 nextPC[tid] = next_NPC;
1224 nextNPC[tid] = next_NPC + instSize;
1225 }
1226
1227 DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, PC[tid]);
1209 if (delaySlotInfo[tid].targetReady &&
1210 delaySlotInfo[tid].numInsts == 0) {
1211 // Set PC to target
1212 PC[tid] = delaySlotInfo[tid].targetAddr; //next_PC
1213 nextPC[tid] = next_PC + instSize; //next_NPC
1214 nextNPC[tid] = next_PC + (2 * instSize);
1215
1216 delaySlotInfo[tid].targetReady = false;
1217 } else {
1218 PC[tid] = next_PC;
1219 nextPC[tid] = next_NPC;
1220 nextNPC[tid] = next_NPC + instSize;
1221 }
1222
1223 DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, PC[tid]);
1224#else
1225 DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n",tid, next_PC);
1226 PC[tid] = next_PC;
1227 nextPC[tid] = next_PC + instSize;
1228#endif
1229 } else {
1230 // We shouldn't be in an icache miss and also have a fault (an ITB
1231 // miss)
1232 if (fetchStatus[tid] == IcacheWaitResponse) {
1233 panic("Fetch should have exited prior to this!");
1234 }
1235

--- 209 unchanged lines hidden ---
1228#endif
1229 } else {
1230 // We shouldn't be in an icache miss and also have a fault (an ITB
1231 // miss)
1232 if (fetchStatus[tid] == IcacheWaitResponse) {
1233 panic("Fetch should have exited prior to this!");
1234 }
1235

--- 209 unchanged lines hidden ---