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__ |