fetch_impl.hh (13641:648f3106ebdf) fetch_impl.hh (13831:4fba790d88be)
1/*
2 * Copyright (c) 2010-2014 ARM Limited
3 * Copyright (c) 2012-2013 AMD
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating

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

382}
383
384template<class Impl>
385void
386DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
387{
388 ThreadID tid = cpu->contextToThread(pkt->req->contextId());
389
1/*
2 * Copyright (c) 2010-2014 ARM Limited
3 * Copyright (c) 2012-2013 AMD
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating

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

382}
383
384template<class Impl>
385void
386DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
387{
388 ThreadID tid = cpu->contextToThread(pkt->req->contextId());
389
390 DPRINTF(Fetch, "[tid:%u] Waking up from cache miss.\n", tid);
390 DPRINTF(Fetch, "[tid:%i] Waking up from cache miss.\n", tid);
391 assert(!cpu->switchedOut());
392
393 // Only change the status if it's still waiting on the icache access
394 // to return.
395 if (fetchStatus[tid] != IcacheWaitResponse ||
396 pkt->req != memReq[tid]) {
397 ++fetchIcacheSquashes;
398 delete pkt;
399 return;
400 }
401
402 memcpy(fetchBuffer[tid], pkt->getConstPtr<uint8_t>(), fetchBufferSize);
403 fetchBufferValid[tid] = true;
404
405 // Wake up the CPU (if it went to sleep and was waiting on
406 // this completion event).
407 cpu->wakeCPU();
408
391 assert(!cpu->switchedOut());
392
393 // Only change the status if it's still waiting on the icache access
394 // to return.
395 if (fetchStatus[tid] != IcacheWaitResponse ||
396 pkt->req != memReq[tid]) {
397 ++fetchIcacheSquashes;
398 delete pkt;
399 return;
400 }
401
402 memcpy(fetchBuffer[tid], pkt->getConstPtr<uint8_t>(), fetchBufferSize);
403 fetchBufferValid[tid] = true;
404
405 // Wake up the CPU (if it went to sleep and was waiting on
406 // this completion event).
407 cpu->wakeCPU();
408
409 DPRINTF(Activity, "[tid:%u] Activating fetch due to cache completion\n",
409 DPRINTF(Activity, "[tid:%i] Activating fetch due to cache completion\n",
410 tid);
411
412 switchToActive();
413
414 // Only switch to IcacheAccessComplete if we're not stalled as well.
415 if (checkStall(tid)) {
416 fetchStatus[tid] = Blocked;
417 } else {

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

567 return false;
568 }
569
570 ThreadID tid = inst->threadNumber;
571 predict_taken = branchPred->predict(inst->staticInst, inst->seqNum,
572 nextPC, tid);
573
574 if (predict_taken) {
410 tid);
411
412 switchToActive();
413
414 // Only switch to IcacheAccessComplete if we're not stalled as well.
415 if (checkStall(tid)) {
416 fetchStatus[tid] = Blocked;
417 } else {

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

567 return false;
568 }
569
570 ThreadID tid = inst->threadNumber;
571 predict_taken = branchPred->predict(inst->staticInst, inst->seqNum,
572 nextPC, tid);
573
574 if (predict_taken) {
575 DPRINTF(Fetch, "[tid:%i]: [sn:%i]: Branch predicted to be taken to %s.\n",
576 tid, inst->seqNum, nextPC);
575 DPRINTF(Fetch, "[tid:%i] [sn:%llu] Branch at PC %#x "
576 "predicted to be taken to %s\n",
577 tid, inst->seqNum, inst->pcState().instAddr(), nextPC);
577 } else {
578 } else {
578 DPRINTF(Fetch, "[tid:%i]: [sn:%i]:Branch predicted to be not taken.\n",
579 tid, inst->seqNum);
579 DPRINTF(Fetch, "[tid:%i] [sn:%llu] Branch at PC %#x "
580 "predicted to be not taken\n",
581 tid, inst->seqNum, inst->pcState().instAddr());
580 }
581
582 }
583
582 DPRINTF(Fetch, "[tid:%i]: [sn:%i] Branch predicted to go to %s.\n",
583 tid, inst->seqNum, nextPC);
584 DPRINTF(Fetch, "[tid:%i] [sn:%llu] Branch at PC %#x "
585 "predicted to go to %s\n",
586 tid, inst->seqNum, inst->pcState().instAddr(), nextPC);
584 inst->setPredTarg(nextPC);
585 inst->setPredTaken(predict_taken);
586
587 ++fetchedBranches;
588
589 if (predict_taken) {
590 ++predictedBranches;
591 }

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

694 assert(retryTid == InvalidThreadID);
695 DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid);
696
697 fetchStatus[tid] = IcacheWaitRetry;
698 retryPkt = data_pkt;
699 retryTid = tid;
700 cacheBlocked = true;
701 } else {
587 inst->setPredTarg(nextPC);
588 inst->setPredTaken(predict_taken);
589
590 ++fetchedBranches;
591
592 if (predict_taken) {
593 ++predictedBranches;
594 }

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

697 assert(retryTid == InvalidThreadID);
698 DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid);
699
700 fetchStatus[tid] = IcacheWaitRetry;
701 retryPkt = data_pkt;
702 retryTid = tid;
703 cacheBlocked = true;
704 } else {
702 DPRINTF(Fetch, "[tid:%i]: Doing Icache access.\n", tid);
703 DPRINTF(Activity, "[tid:%i]: Activity: Waiting on I-cache "
705 DPRINTF(Fetch, "[tid:%i] Doing Icache access.\n", tid);
706 DPRINTF(Activity, "[tid:%i] Activity: Waiting on I-cache "
704 "response.\n", tid);
705 lastIcacheStall[tid] = curTick();
706 fetchStatus[tid] = IcacheWaitResponse;
707 // Notify Fetch Request probe when a packet containing a fetch
708 // request is successfully sent
709 ppFetchRequestSent->notify(mem_req);
710 }
711 } else {

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

723 // Translation faulted, icache request won't be sent.
724 memReq[tid] = NULL;
725
726 // Send the fault to commit. This thread will not do anything
727 // until commit handles the fault. The only other way it can
728 // wake up is if a squash comes along and changes the PC.
729 TheISA::PCState fetchPC = pc[tid];
730
707 "response.\n", tid);
708 lastIcacheStall[tid] = curTick();
709 fetchStatus[tid] = IcacheWaitResponse;
710 // Notify Fetch Request probe when a packet containing a fetch
711 // request is successfully sent
712 ppFetchRequestSent->notify(mem_req);
713 }
714 } else {

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

726 // Translation faulted, icache request won't be sent.
727 memReq[tid] = NULL;
728
729 // Send the fault to commit. This thread will not do anything
730 // until commit handles the fault. The only other way it can
731 // wake up is if a squash comes along and changes the PC.
732 TheISA::PCState fetchPC = pc[tid];
733
731 DPRINTF(Fetch, "[tid:%i]: Translation faulted, building noop.\n", tid);
734 DPRINTF(Fetch, "[tid:%i] Translation faulted, building noop.\n", tid);
732 // We will use a nop in ordier to carry the fault.
733 DynInstPtr instruction = buildInst(tid, StaticInst::nopStaticInstPtr,
734 NULL, fetchPC, fetchPC, false);
735 instruction->setNotAnInst();
736
737 instruction->setPredTarg(fetchPC);
738 instruction->fault = fault;
739 wroteToTimeBuffer = true;
740
741 DPRINTF(Activity, "Activity this cycle.\n");
742 cpu->activityThisCycle();
743
744 fetchStatus[tid] = TrapPending;
745
735 // We will use a nop in ordier to carry the fault.
736 DynInstPtr instruction = buildInst(tid, StaticInst::nopStaticInstPtr,
737 NULL, fetchPC, fetchPC, false);
738 instruction->setNotAnInst();
739
740 instruction->setPredTarg(fetchPC);
741 instruction->fault = fault;
742 wroteToTimeBuffer = true;
743
744 DPRINTF(Activity, "Activity this cycle.\n");
745 cpu->activityThisCycle();
746
747 fetchStatus[tid] = TrapPending;
748
746 DPRINTF(Fetch, "[tid:%i]: Blocked, need to handle the trap.\n", tid);
747 DPRINTF(Fetch, "[tid:%i]: fault (%s) detected @ PC %s.\n",
749 DPRINTF(Fetch, "[tid:%i] Blocked, need to handle the trap.\n", tid);
750 DPRINTF(Fetch, "[tid:%i] fault (%s) detected @ PC %s.\n",
748 tid, fault->name(), pc[tid]);
749 }
750 _status = updateFetchStatus();
751}
752
753template <class Impl>
754inline void
755DefaultFetch<Impl>::doSquash(const TheISA::PCState &newPC,
756 const DynInstPtr squashInst, ThreadID tid)
757{
751 tid, fault->name(), pc[tid]);
752 }
753 _status = updateFetchStatus();
754}
755
756template <class Impl>
757inline void
758DefaultFetch<Impl>::doSquash(const TheISA::PCState &newPC,
759 const DynInstPtr squashInst, ThreadID tid)
760{
758 DPRINTF(Fetch, "[tid:%i]: Squashing, setting PC to: %s.\n",
761 DPRINTF(Fetch, "[tid:%i] Squashing, setting PC to: %s.\n",
759 tid, newPC);
760
761 pc[tid] = newPC;
762 fetchOffset[tid] = 0;
763 if (squashInst && squashInst->pcState().instAddr() == newPC.instAddr())
764 macroop[tid] = squashInst->macroop;
765 else
766 macroop[tid] = NULL;
767 decoder[tid]->reset();
768
769 // Clear the icache miss if it's outstanding.
770 if (fetchStatus[tid] == IcacheWaitResponse) {
762 tid, newPC);
763
764 pc[tid] = newPC;
765 fetchOffset[tid] = 0;
766 if (squashInst && squashInst->pcState().instAddr() == newPC.instAddr())
767 macroop[tid] = squashInst->macroop;
768 else
769 macroop[tid] = NULL;
770 decoder[tid]->reset();
771
772 // Clear the icache miss if it's outstanding.
773 if (fetchStatus[tid] == IcacheWaitResponse) {
771 DPRINTF(Fetch, "[tid:%i]: Squashing outstanding Icache miss.\n",
774 DPRINTF(Fetch, "[tid:%i] Squashing outstanding Icache miss.\n",
772 tid);
773 memReq[tid] = NULL;
774 } else if (fetchStatus[tid] == ItlbWait) {
775 tid);
776 memReq[tid] = NULL;
777 } else if (fetchStatus[tid] == ItlbWait) {
775 DPRINTF(Fetch, "[tid:%i]: Squashing outstanding ITLB miss.\n",
778 DPRINTF(Fetch, "[tid:%i] Squashing outstanding ITLB miss.\n",
776 tid);
777 memReq[tid] = NULL;
778 }
779
780 // Get rid of the retrying packet if it was from this thread.
781 if (retryTid == tid) {
782 assert(cacheBlocked);
783 if (retryPkt) {

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

803}
804
805template<class Impl>
806void
807DefaultFetch<Impl>::squashFromDecode(const TheISA::PCState &newPC,
808 const DynInstPtr squashInst,
809 const InstSeqNum seq_num, ThreadID tid)
810{
779 tid);
780 memReq[tid] = NULL;
781 }
782
783 // Get rid of the retrying packet if it was from this thread.
784 if (retryTid == tid) {
785 assert(cacheBlocked);
786 if (retryPkt) {

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

806}
807
808template<class Impl>
809void
810DefaultFetch<Impl>::squashFromDecode(const TheISA::PCState &newPC,
811 const DynInstPtr squashInst,
812 const InstSeqNum seq_num, ThreadID tid)
813{
811 DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n", tid);
814 DPRINTF(Fetch, "[tid:%i] Squashing from decode.\n", tid);
812
813 doSquash(newPC, squashInst, tid);
814
815 // Tell the CPU to remove any instructions that are in flight between
816 // fetch and decode.
817 cpu->removeInstsUntil(seq_num, tid);
818}
819
820template<class Impl>
821bool
822DefaultFetch<Impl>::checkStall(ThreadID tid) const
823{
824 bool ret_val = false;
825
826 if (stalls[tid].drain) {
827 assert(cpu->isDraining());
815
816 doSquash(newPC, squashInst, tid);
817
818 // Tell the CPU to remove any instructions that are in flight between
819 // fetch and decode.
820 cpu->removeInstsUntil(seq_num, tid);
821}
822
823template<class Impl>
824bool
825DefaultFetch<Impl>::checkStall(ThreadID tid) const
826{
827 bool ret_val = false;
828
829 if (stalls[tid].drain) {
830 assert(cpu->isDraining());
828 DPRINTF(Fetch,"[tid:%i]: Drain stall detected.\n",tid);
831 DPRINTF(Fetch,"[tid:%i] Drain stall detected.\n",tid);
829 ret_val = true;
830 }
831
832 return ret_val;
833}
834
835template<class Impl>
836typename DefaultFetch<Impl>::FetchStatus

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

843 while (threads != end) {
844 ThreadID tid = *threads++;
845
846 if (fetchStatus[tid] == Running ||
847 fetchStatus[tid] == Squashing ||
848 fetchStatus[tid] == IcacheAccessComplete) {
849
850 if (_status == Inactive) {
832 ret_val = true;
833 }
834
835 return ret_val;
836}
837
838template<class Impl>
839typename DefaultFetch<Impl>::FetchStatus

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

846 while (threads != end) {
847 ThreadID tid = *threads++;
848
849 if (fetchStatus[tid] == Running ||
850 fetchStatus[tid] == Squashing ||
851 fetchStatus[tid] == IcacheAccessComplete) {
852
853 if (_status == Inactive) {
851 DPRINTF(Activity, "[tid:%i]: Activating stage.\n",tid);
854 DPRINTF(Activity, "[tid:%i] Activating stage.\n",tid);
852
853 if (fetchStatus[tid] == IcacheAccessComplete) {
855
856 if (fetchStatus[tid] == IcacheAccessComplete) {
854 DPRINTF(Activity, "[tid:%i]: Activating fetch due to cache"
857 DPRINTF(Activity, "[tid:%i] Activating fetch due to cache"
855 "completion\n",tid);
856 }
857
858 cpu->activateStage(O3CPU::FetchIdx);
859 }
860
861 return Active;
862 }

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

873}
874
875template <class Impl>
876void
877DefaultFetch<Impl>::squash(const TheISA::PCState &newPC,
878 const InstSeqNum seq_num, DynInstPtr squashInst,
879 ThreadID tid)
880{
858 "completion\n",tid);
859 }
860
861 cpu->activateStage(O3CPU::FetchIdx);
862 }
863
864 return Active;
865 }

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

876}
877
878template <class Impl>
879void
880DefaultFetch<Impl>::squash(const TheISA::PCState &newPC,
881 const InstSeqNum seq_num, DynInstPtr squashInst,
882 ThreadID tid)
883{
881 DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n", tid);
884 DPRINTF(Fetch, "[tid:%i] Squash from commit.\n", tid);
882
883 doSquash(newPC, squashInst, tid);
884
885 // Tell the CPU to remove any instructions that are not in the ROB.
886 cpu->removeInstsNotInROB(tid);
887}
888
889template <class Impl>

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

957 auto tid_itr = activeThreads->begin();
958 std::advance(tid_itr, random_mt.random<uint8_t>(0, activeThreads->size() - 1));
959
960 while (available_insts != 0 && insts_to_decode < decodeWidth) {
961 ThreadID tid = *tid_itr;
962 if (!stalls[tid].decode && !fetchQueue[tid].empty()) {
963 const auto& inst = fetchQueue[tid].front();
964 toDecode->insts[toDecode->size++] = inst;
885
886 doSquash(newPC, squashInst, tid);
887
888 // Tell the CPU to remove any instructions that are not in the ROB.
889 cpu->removeInstsNotInROB(tid);
890}
891
892template <class Impl>

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

960 auto tid_itr = activeThreads->begin();
961 std::advance(tid_itr, random_mt.random<uint8_t>(0, activeThreads->size() - 1));
962
963 while (available_insts != 0 && insts_to_decode < decodeWidth) {
964 ThreadID tid = *tid_itr;
965 if (!stalls[tid].decode && !fetchQueue[tid].empty()) {
966 const auto& inst = fetchQueue[tid].front();
967 toDecode->insts[toDecode->size++] = inst;
965 DPRINTF(Fetch, "[tid:%i][sn:%i]: Sending instruction to decode from "
966 "fetch queue. Fetch queue size: %i.\n",
968 DPRINTF(Fetch, "[tid:%i] [sn:%llu] Sending instruction to decode "
969 "from fetch queue. Fetch queue size: %i.\n",
967 tid, inst->seqNum, fetchQueue[tid].size());
968
969 wroteToTimeBuffer = true;
970 fetchQueue[tid].pop_front();
971 insts_to_decode++;
972 available_insts--;
973 }
974

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

1001 assert(stalls[tid].decode);
1002 assert(!fromDecode->decodeBlock[tid]);
1003 stalls[tid].decode = false;
1004 }
1005
1006 // Check squash signals from commit.
1007 if (fromCommit->commitInfo[tid].squash) {
1008
970 tid, inst->seqNum, fetchQueue[tid].size());
971
972 wroteToTimeBuffer = true;
973 fetchQueue[tid].pop_front();
974 insts_to_decode++;
975 available_insts--;
976 }
977

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

1004 assert(stalls[tid].decode);
1005 assert(!fromDecode->decodeBlock[tid]);
1006 stalls[tid].decode = false;
1007 }
1008
1009 // Check squash signals from commit.
1010 if (fromCommit->commitInfo[tid].squash) {
1011
1009 DPRINTF(Fetch, "[tid:%u]: Squashing instructions due to squash "
1012 DPRINTF(Fetch, "[tid:%i] Squashing instructions due to squash "
1010 "from commit.\n",tid);
1011 // In any case, squash.
1012 squash(fromCommit->commitInfo[tid].pc,
1013 fromCommit->commitInfo[tid].doneSeqNum,
1014 fromCommit->commitInfo[tid].squashInst, tid);
1015
1016 // If it was a branch mispredict on a control instruction, update the
1017 // branch predictor with that instruction, otherwise just kill the

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

1031 } else if (fromCommit->commitInfo[tid].doneSeqNum) {
1032 // Update the branch predictor if it wasn't a squashed instruction
1033 // that was broadcasted.
1034 branchPred->update(fromCommit->commitInfo[tid].doneSeqNum, tid);
1035 }
1036
1037 // Check squash signals from decode.
1038 if (fromDecode->decodeInfo[tid].squash) {
1013 "from commit.\n",tid);
1014 // In any case, squash.
1015 squash(fromCommit->commitInfo[tid].pc,
1016 fromCommit->commitInfo[tid].doneSeqNum,
1017 fromCommit->commitInfo[tid].squashInst, tid);
1018
1019 // If it was a branch mispredict on a control instruction, update the
1020 // branch predictor with that instruction, otherwise just kill the

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

1034 } else if (fromCommit->commitInfo[tid].doneSeqNum) {
1035 // Update the branch predictor if it wasn't a squashed instruction
1036 // that was broadcasted.
1037 branchPred->update(fromCommit->commitInfo[tid].doneSeqNum, tid);
1038 }
1039
1040 // Check squash signals from decode.
1041 if (fromDecode->decodeInfo[tid].squash) {
1039 DPRINTF(Fetch, "[tid:%u]: Squashing instructions due to squash "
1042 DPRINTF(Fetch, "[tid:%i] Squashing instructions due to squash "
1040 "from decode.\n",tid);
1041
1042 // Update the branch predictor.
1043 if (fromDecode->decodeInfo[tid].branchMispredict) {
1044 branchPred->squash(fromDecode->decodeInfo[tid].doneSeqNum,
1045 fromDecode->decodeInfo[tid].nextPC,
1046 fromDecode->decodeInfo[tid].branchTaken,
1047 tid);

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

1064 }
1065 }
1066
1067 if (checkStall(tid) &&
1068 fetchStatus[tid] != IcacheWaitResponse &&
1069 fetchStatus[tid] != IcacheWaitRetry &&
1070 fetchStatus[tid] != ItlbWait &&
1071 fetchStatus[tid] != QuiescePending) {
1043 "from decode.\n",tid);
1044
1045 // Update the branch predictor.
1046 if (fromDecode->decodeInfo[tid].branchMispredict) {
1047 branchPred->squash(fromDecode->decodeInfo[tid].doneSeqNum,
1048 fromDecode->decodeInfo[tid].nextPC,
1049 fromDecode->decodeInfo[tid].branchTaken,
1050 tid);

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

1067 }
1068 }
1069
1070 if (checkStall(tid) &&
1071 fetchStatus[tid] != IcacheWaitResponse &&
1072 fetchStatus[tid] != IcacheWaitRetry &&
1073 fetchStatus[tid] != ItlbWait &&
1074 fetchStatus[tid] != QuiescePending) {
1072 DPRINTF(Fetch, "[tid:%i]: Setting to blocked\n",tid);
1075 DPRINTF(Fetch, "[tid:%i] Setting to blocked\n",tid);
1073
1074 fetchStatus[tid] = Blocked;
1075
1076 return true;
1077 }
1078
1079 if (fetchStatus[tid] == Blocked ||
1080 fetchStatus[tid] == Squashing) {
1081 // Switch status to running if fetch isn't being told to block or
1082 // squash this cycle.
1076
1077 fetchStatus[tid] = Blocked;
1078
1079 return true;
1080 }
1081
1082 if (fetchStatus[tid] == Blocked ||
1083 fetchStatus[tid] == Squashing) {
1084 // Switch status to running if fetch isn't being told to block or
1085 // squash this cycle.
1083 DPRINTF(Fetch, "[tid:%i]: Done squashing, switching to running.\n",
1086 DPRINTF(Fetch, "[tid:%i] Done squashing, switching to running.\n",
1084 tid);
1085
1086 fetchStatus[tid] = Running;
1087
1088 return true;
1089 }
1090
1091 // If we've reached this point, we have not gotten any signals that

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

1106 DynInstPtr instruction =
1107 new DynInst(staticInst, curMacroop, thisPC, nextPC, seq, cpu);
1108 instruction->setTid(tid);
1109
1110 instruction->setASID(tid);
1111
1112 instruction->setThreadState(cpu->thread[tid]);
1113
1087 tid);
1088
1089 fetchStatus[tid] = Running;
1090
1091 return true;
1092 }
1093
1094 // If we've reached this point, we have not gotten any signals that

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

1109 DynInstPtr instruction =
1110 new DynInst(staticInst, curMacroop, thisPC, nextPC, seq, cpu);
1111 instruction->setTid(tid);
1112
1113 instruction->setASID(tid);
1114
1115 instruction->setThreadState(cpu->thread[tid]);
1116
1114 DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x (%d) created "
1117 DPRINTF(Fetch, "[tid:%i] Instruction PC %#x (%d) created "
1115 "[sn:%lli].\n", tid, thisPC.instAddr(),
1116 thisPC.microPC(), seq);
1117
1118 "[sn:%lli].\n", tid, thisPC.instAddr(),
1119 thisPC.microPC(), seq);
1120
1118 DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n", tid,
1121 DPRINTF(Fetch, "[tid:%i] Instruction is: %s\n", tid,
1119 instruction->staticInst->
1120 disassemble(thisPC.instAddr()));
1121
1122#if TRACING_ON
1123 if (trace) {
1124 instruction->traceData =
1125 cpu->getTracer()->getInstRecord(curTick(), cpu->tcBase(tid),
1126 instruction->staticInst, thisPC, curMacroop);

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

1132 // Add instruction to the CPU's list of instructions.
1133 instruction->setInstListIt(cpu->addInst(instruction));
1134
1135 // Write the instruction to the first slot in the queue
1136 // that heads to decode.
1137 assert(numInst < fetchWidth);
1138 fetchQueue[tid].push_back(instruction);
1139 assert(fetchQueue[tid].size() <= fetchQueueSize);
1122 instruction->staticInst->
1123 disassemble(thisPC.instAddr()));
1124
1125#if TRACING_ON
1126 if (trace) {
1127 instruction->traceData =
1128 cpu->getTracer()->getInstRecord(curTick(), cpu->tcBase(tid),
1129 instruction->staticInst, thisPC, curMacroop);

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

1135 // Add instruction to the CPU's list of instructions.
1136 instruction->setInstListIt(cpu->addInst(instruction));
1137
1138 // Write the instruction to the first slot in the queue
1139 // that heads to decode.
1140 assert(numInst < fetchWidth);
1141 fetchQueue[tid].push_back(instruction);
1142 assert(fetchQueue[tid].size() <= fetchQueueSize);
1140 DPRINTF(Fetch, "[tid:%i]: Fetch queue entry created (%i/%i).\n",
1143 DPRINTF(Fetch, "[tid:%i] Fetch queue entry created (%i/%i).\n",
1141 tid, fetchQueue[tid].size(), fetchQueueSize);
1142 //toDecode->insts[toDecode->size++] = instruction;
1143
1144 // Keep track of if we can take an interrupt at this boundary
1145 delayedCommit[tid] = instruction->isDelayedCommit();
1146
1147 return instruction;
1148}

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

1178 Addr fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask;
1179
1180 bool inRom = isRomMicroPC(thisPC.microPC());
1181
1182 // If returning from the delay of a cache miss, then update the status
1183 // to running, otherwise do the cache access. Possibly move this up
1184 // to tick() function.
1185 if (fetchStatus[tid] == IcacheAccessComplete) {
1144 tid, fetchQueue[tid].size(), fetchQueueSize);
1145 //toDecode->insts[toDecode->size++] = instruction;
1146
1147 // Keep track of if we can take an interrupt at this boundary
1148 delayedCommit[tid] = instruction->isDelayedCommit();
1149
1150 return instruction;
1151}

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

1181 Addr fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask;
1182
1183 bool inRom = isRomMicroPC(thisPC.microPC());
1184
1185 // If returning from the delay of a cache miss, then update the status
1186 // to running, otherwise do the cache access. Possibly move this up
1187 // to tick() function.
1188 if (fetchStatus[tid] == IcacheAccessComplete) {
1186 DPRINTF(Fetch, "[tid:%i]: Icache miss is complete.\n", tid);
1189 DPRINTF(Fetch, "[tid:%i] Icache miss is complete.\n", tid);
1187
1188 fetchStatus[tid] = Running;
1189 status_change = true;
1190 } else if (fetchStatus[tid] == Running) {
1191 // Align the fetch PC so its at the start of a fetch buffer segment.
1192 Addr fetchBufferBlockPC = fetchBufferAlignPC(fetchAddr);
1193
1194 // If buffer is no longer valid or fetchAddr has moved to point
1195 // to the next cache block, AND we have no remaining ucode
1196 // from a macro-op, then start fetch from icache.
1197 if (!(fetchBufferValid[tid] && fetchBufferBlockPC == fetchBufferPC[tid])
1198 && !inRom && !macroop[tid]) {
1190
1191 fetchStatus[tid] = Running;
1192 status_change = true;
1193 } else if (fetchStatus[tid] == Running) {
1194 // Align the fetch PC so its at the start of a fetch buffer segment.
1195 Addr fetchBufferBlockPC = fetchBufferAlignPC(fetchAddr);
1196
1197 // If buffer is no longer valid or fetchAddr has moved to point
1198 // to the next cache block, AND we have no remaining ucode
1199 // from a macro-op, then start fetch from icache.
1200 if (!(fetchBufferValid[tid] && fetchBufferBlockPC == fetchBufferPC[tid])
1201 && !inRom && !macroop[tid]) {
1199 DPRINTF(Fetch, "[tid:%i]: Attempting to translate and read "
1202 DPRINTF(Fetch, "[tid:%i] Attempting to translate and read "
1200 "instruction, starting at PC %s.\n", tid, thisPC);
1201
1202 fetchCacheLine(fetchAddr, tid, thisPC.instAddr());
1203
1204 if (fetchStatus[tid] == IcacheWaitResponse)
1205 ++icacheStallCycles;
1206 else if (fetchStatus[tid] == ItlbWait)
1207 ++fetchTlbCycles;
1208 else
1209 ++fetchMiscStallCycles;
1210 return;
1211 } else if ((checkInterrupt(thisPC.instAddr()) && !delayedCommit[tid])) {
1212 // Stall CPU if an interrupt is posted and we're not issuing
1213 // an delayed commit micro-op currently (delayed commit instructions
1214 // are not interruptable by interrupts, only faults)
1215 ++fetchMiscStallCycles;
1203 "instruction, starting at PC %s.\n", tid, thisPC);
1204
1205 fetchCacheLine(fetchAddr, tid, thisPC.instAddr());
1206
1207 if (fetchStatus[tid] == IcacheWaitResponse)
1208 ++icacheStallCycles;
1209 else if (fetchStatus[tid] == ItlbWait)
1210 ++fetchTlbCycles;
1211 else
1212 ++fetchMiscStallCycles;
1213 return;
1214 } else if ((checkInterrupt(thisPC.instAddr()) && !delayedCommit[tid])) {
1215 // Stall CPU if an interrupt is posted and we're not issuing
1216 // an delayed commit micro-op currently (delayed commit instructions
1217 // are not interruptable by interrupts, only faults)
1218 ++fetchMiscStallCycles;
1216 DPRINTF(Fetch, "[tid:%i]: Fetch is stalled!\n", tid);
1219 DPRINTF(Fetch, "[tid:%i] Fetch is stalled!\n", tid);
1217 return;
1218 }
1219 } else {
1220 if (fetchStatus[tid] == Idle) {
1221 ++fetchIdleCycles;
1220 return;
1221 }
1222 } else {
1223 if (fetchStatus[tid] == Idle) {
1224 ++fetchIdleCycles;
1222 DPRINTF(Fetch, "[tid:%i]: Fetch is idle!\n", tid);
1225 DPRINTF(Fetch, "[tid:%i] Fetch is idle!\n", tid);
1223 }
1224
1225 // Status is Idle, so fetch should do nothing.
1226 return;
1227 }
1228
1229 ++fetchCycles;
1230
1231 TheISA::PCState nextPC = thisPC;
1232
1233 StaticInstPtr staticInst = NULL;
1234 StaticInstPtr curMacroop = macroop[tid];
1235
1236 // If the read of the first instruction was successful, then grab the
1237 // instructions from the rest of the cache line and put them into the
1238 // queue heading to decode.
1239
1226 }
1227
1228 // Status is Idle, so fetch should do nothing.
1229 return;
1230 }
1231
1232 ++fetchCycles;
1233
1234 TheISA::PCState nextPC = thisPC;
1235
1236 StaticInstPtr staticInst = NULL;
1237 StaticInstPtr curMacroop = macroop[tid];
1238
1239 // If the read of the first instruction was successful, then grab the
1240 // instructions from the rest of the cache line and put them into the
1241 // queue heading to decode.
1242
1240 DPRINTF(Fetch, "[tid:%i]: Adding instructions to queue to "
1243 DPRINTF(Fetch, "[tid:%i] Adding instructions to queue to "
1241 "decode.\n", tid);
1242
1243 // Need to keep track of whether or not a predicted branch
1244 // ended this fetch block.
1245 bool predictedBranch = false;
1246
1247 // Need to halt fetch if quiesce instruction detected
1248 bool quiesce = false;

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

1374 fetchQueue[tid].size() < fetchQueueSize);
1375
1376 // Re-evaluate whether the next instruction to fetch is in micro-op ROM
1377 // or not.
1378 inRom = isRomMicroPC(thisPC.microPC());
1379 }
1380
1381 if (predictedBranch) {
1244 "decode.\n", tid);
1245
1246 // Need to keep track of whether or not a predicted branch
1247 // ended this fetch block.
1248 bool predictedBranch = false;
1249
1250 // Need to halt fetch if quiesce instruction detected
1251 bool quiesce = false;

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

1377 fetchQueue[tid].size() < fetchQueueSize);
1378
1379 // Re-evaluate whether the next instruction to fetch is in micro-op ROM
1380 // or not.
1381 inRom = isRomMicroPC(thisPC.microPC());
1382 }
1383
1384 if (predictedBranch) {
1382 DPRINTF(Fetch, "[tid:%i]: Done fetching, predicted branch "
1385 DPRINTF(Fetch, "[tid:%i] Done fetching, predicted branch "
1383 "instruction encountered.\n", tid);
1384 } else if (numInst >= fetchWidth) {
1386 "instruction encountered.\n", tid);
1387 } else if (numInst >= fetchWidth) {
1385 DPRINTF(Fetch, "[tid:%i]: Done fetching, reached fetch bandwidth "
1388 DPRINTF(Fetch, "[tid:%i] Done fetching, reached fetch bandwidth "
1386 "for this cycle.\n", tid);
1387 } else if (blkOffset >= fetchBufferSize) {
1389 "for this cycle.\n", tid);
1390 } else if (blkOffset >= fetchBufferSize) {
1388 DPRINTF(Fetch, "[tid:%i]: Done fetching, reached the end of the"
1391 DPRINTF(Fetch, "[tid:%i] Done fetching, reached the end of the"
1389 "fetch buffer.\n", tid);
1390 }
1391
1392 macroop[tid] = curMacroop;
1393 fetchOffset[tid] = pcOffset;
1394
1395 if (numInst > 0) {
1396 wroteToTimeBuffer = true;

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

1612 Addr pcOffset = fetchOffset[tid];
1613 Addr fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask;
1614
1615 // Align the fetch PC so its at the start of a fetch buffer segment.
1616 Addr fetchBufferBlockPC = fetchBufferAlignPC(fetchAddr);
1617
1618 // Unless buffer already got the block, fetch it from icache.
1619 if (!(fetchBufferValid[tid] && fetchBufferBlockPC == fetchBufferPC[tid])) {
1392 "fetch buffer.\n", tid);
1393 }
1394
1395 macroop[tid] = curMacroop;
1396 fetchOffset[tid] = pcOffset;
1397
1398 if (numInst > 0) {
1399 wroteToTimeBuffer = true;

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

1615 Addr pcOffset = fetchOffset[tid];
1616 Addr fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask;
1617
1618 // Align the fetch PC so its at the start of a fetch buffer segment.
1619 Addr fetchBufferBlockPC = fetchBufferAlignPC(fetchAddr);
1620
1621 // Unless buffer already got the block, fetch it from icache.
1622 if (!(fetchBufferValid[tid] && fetchBufferBlockPC == fetchBufferPC[tid])) {
1620 DPRINTF(Fetch, "[tid:%i]: Issuing a pipelined I-cache access, "
1623 DPRINTF(Fetch, "[tid:%i] Issuing a pipelined I-cache access, "
1621 "starting at PC %s.\n", tid, thisPC);
1622
1623 fetchCacheLine(fetchAddr, tid, thisPC.instAddr());
1624 }
1625}
1626
1627template<class Impl>
1628void

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

1634 if (stalls[tid].drain) {
1635 ++fetchPendingDrainCycles;
1636 DPRINTF(Fetch, "Fetch is waiting for a drain!\n");
1637 } else if (activeThreads->empty()) {
1638 ++fetchNoActiveThreadStallCycles;
1639 DPRINTF(Fetch, "Fetch has no active thread!\n");
1640 } else if (fetchStatus[tid] == Blocked) {
1641 ++fetchBlockedCycles;
1624 "starting at PC %s.\n", tid, thisPC);
1625
1626 fetchCacheLine(fetchAddr, tid, thisPC.instAddr());
1627 }
1628}
1629
1630template<class Impl>
1631void

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

1637 if (stalls[tid].drain) {
1638 ++fetchPendingDrainCycles;
1639 DPRINTF(Fetch, "Fetch is waiting for a drain!\n");
1640 } else if (activeThreads->empty()) {
1641 ++fetchNoActiveThreadStallCycles;
1642 DPRINTF(Fetch, "Fetch has no active thread!\n");
1643 } else if (fetchStatus[tid] == Blocked) {
1644 ++fetchBlockedCycles;
1642 DPRINTF(Fetch, "[tid:%i]: Fetch is blocked!\n", tid);
1645 DPRINTF(Fetch, "[tid:%i] Fetch is blocked!\n", tid);
1643 } else if (fetchStatus[tid] == Squashing) {
1644 ++fetchSquashCycles;
1646 } else if (fetchStatus[tid] == Squashing) {
1647 ++fetchSquashCycles;
1645 DPRINTF(Fetch, "[tid:%i]: Fetch is squashing!\n", tid);
1648 DPRINTF(Fetch, "[tid:%i] Fetch is squashing!\n", tid);
1646 } else if (fetchStatus[tid] == IcacheWaitResponse) {
1647 ++icacheStallCycles;
1649 } else if (fetchStatus[tid] == IcacheWaitResponse) {
1650 ++icacheStallCycles;
1648 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting cache response!\n",
1651 DPRINTF(Fetch, "[tid:%i] Fetch is waiting cache response!\n",
1649 tid);
1650 } else if (fetchStatus[tid] == ItlbWait) {
1651 ++fetchTlbCycles;
1652 tid);
1653 } else if (fetchStatus[tid] == ItlbWait) {
1654 ++fetchTlbCycles;
1652 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting ITLB walk to "
1655 DPRINTF(Fetch, "[tid:%i] Fetch is waiting ITLB walk to "
1653 "finish!\n", tid);
1654 } else if (fetchStatus[tid] == TrapPending) {
1655 ++fetchPendingTrapStallCycles;
1656 "finish!\n", tid);
1657 } else if (fetchStatus[tid] == TrapPending) {
1658 ++fetchPendingTrapStallCycles;
1656 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting for a pending trap!\n",
1659 DPRINTF(Fetch, "[tid:%i] Fetch is waiting for a pending trap!\n",
1657 tid);
1658 } else if (fetchStatus[tid] == QuiescePending) {
1659 ++fetchPendingQuiesceStallCycles;
1660 tid);
1661 } else if (fetchStatus[tid] == QuiescePending) {
1662 ++fetchPendingQuiesceStallCycles;
1660 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting for a pending quiesce "
1663 DPRINTF(Fetch, "[tid:%i] Fetch is waiting for a pending quiesce "
1661 "instruction!\n", tid);
1662 } else if (fetchStatus[tid] == IcacheWaitRetry) {
1663 ++fetchIcacheWaitRetryStallCycles;
1664 "instruction!\n", tid);
1665 } else if (fetchStatus[tid] == IcacheWaitRetry) {
1666 ++fetchIcacheWaitRetryStallCycles;
1664 DPRINTF(Fetch, "[tid:%i]: Fetch is waiting for an I-cache retry!\n",
1667 DPRINTF(Fetch, "[tid:%i] Fetch is waiting for an I-cache retry!\n",
1665 tid);
1666 } else if (fetchStatus[tid] == NoGoodAddr) {
1668 tid);
1669 } else if (fetchStatus[tid] == NoGoodAddr) {
1667 DPRINTF(Fetch, "[tid:%i]: Fetch predicted non-executable address\n",
1670 DPRINTF(Fetch, "[tid:%i] Fetch predicted non-executable address\n",
1668 tid);
1669 } else {
1671 tid);
1672 } else {
1670 DPRINTF(Fetch, "[tid:%i]: Unexpected fetch stall reason (Status: %i).\n",
1671 tid, fetchStatus[tid]);
1673 DPRINTF(Fetch, "[tid:%i] Unexpected fetch stall reason "
1674 "(Status: %i)\n",
1675 tid, fetchStatus[tid]);
1672 }
1673}
1674
1675#endif//__CPU_O3_FETCH_IMPL_HH__
1676 }
1677}
1678
1679#endif//__CPU_O3_FETCH_IMPL_HH__