1/* |
2 * Copyright (c) 2011-2014 ARM Limited |
3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 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 9 * to a hardware implementation of the functionality of the software 10 * licensed hereunder. You may use the software subject to the license --- 397 unchanged lines hidden (view full) --- 408 while (!readyInsts[i].empty()) 409 readyInsts[i].pop(); 410 queueOnList[i] = false; 411 readyIt[i] = listOrder.end(); 412 } 413 nonSpecInsts.clear(); 414 listOrder.clear(); 415 deferredMemInsts.clear(); |
416 blockedMemInsts.clear(); 417 retryMemInsts.clear(); |
418} 419 420template <class Impl> 421void 422InstructionQueue<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 423{ 424 activeThreads = at_ptr; 425} --- 305 unchanged lines hidden (view full) --- 731void 732InstructionQueue<Impl>::scheduleReadyInsts() 733{ 734 DPRINTF(IQ, "Attempting to schedule ready instructions from " 735 "the IQ.\n"); 736 737 IssueStruct *i2e_info = issueToExecuteQueue->access(0); 738 |
739 DynInstPtr mem_inst; 740 while (mem_inst = getDeferredMemInstToExecute()) { 741 addReadyMemInst(mem_inst); |
742 } 743 |
744 // See if any cache blocked instructions are able to be executed 745 while (mem_inst = getBlockedMemInstToExecute()) { 746 addReadyMemInst(mem_inst); 747 } 748 |
749 // Have iterator to head of the list 750 // While I haven't exceeded bandwidth or reached the end of the list, 751 // Try to get a FU that can do what this op needs. 752 // If successful, change the oldestInst to the new top of the list, put 753 // the queue in the proper place in the list. 754 // Increment the iterator. 755 // This will avoid trying to schedule a certain op class if there are no 756 // FUs that handle it. |
757 int total_issued = 0; |
758 ListOrderIt order_it = listOrder.begin(); 759 ListOrderIt order_end_it = listOrder.end(); |
760 |
761 while (total_issued < totalWidth && order_it != order_end_it) { |
762 OpClass op_class = (*order_it).queueType; 763 764 assert(!readyInsts[op_class].empty()); 765 766 DynInstPtr issuing_inst = readyInsts[op_class].top(); 767 768 issuing_inst->isFloating() ? fpInstQueueReads++ : intInstQueueReads++; 769 --- 101 unchanged lines hidden (view full) --- 871 872 numIssuedDist.sample(total_issued); 873 iqInstsIssued+= total_issued; 874 875 // If we issued any instructions, tell the CPU we had activity. 876 // @todo If the way deferred memory instructions are handeled due to 877 // translation changes then the deferredMemInsts condition should be removed 878 // from the code below. |
879 if (total_issued || !retryMemInsts.empty() || !deferredMemInsts.empty()) { |
880 cpu->activityThisCycle(); 881 } else { 882 DPRINTF(IQ, "Not able to schedule any instructions.\n"); 883 } 884} 885 886template <class Impl> 887void --- 159 unchanged lines hidden (view full) --- 1047 resched_inst->clearCanIssue(); 1048 memDepUnit[resched_inst->threadNumber].reschedule(resched_inst); 1049} 1050 1051template <class Impl> 1052void 1053InstructionQueue<Impl>::replayMemInst(DynInstPtr &replay_inst) 1054{ |
1055 memDepUnit[replay_inst->threadNumber].replay(); |
1056} 1057 1058template <class Impl> 1059void 1060InstructionQueue<Impl>::completeMemInst(DynInstPtr &completed_inst) 1061{ 1062 ThreadID tid = completed_inst->threadNumber; 1063 --- 11 unchanged lines hidden (view full) --- 1075template <class Impl> 1076void 1077InstructionQueue<Impl>::deferMemInst(DynInstPtr &deferred_inst) 1078{ 1079 deferredMemInsts.push_back(deferred_inst); 1080} 1081 1082template <class Impl> |
1083void 1084InstructionQueue<Impl>::blockMemInst(DynInstPtr &blocked_inst) 1085{ 1086 blocked_inst->translationStarted(false); 1087 blocked_inst->translationCompleted(false); 1088 1089 blocked_inst->clearIssued(); 1090 blocked_inst->clearCanIssue(); 1091 blockedMemInsts.push_back(blocked_inst); 1092} 1093 1094template <class Impl> 1095void 1096InstructionQueue<Impl>::cacheUnblocked() 1097{ 1098 retryMemInsts.splice(retryMemInsts.end(), blockedMemInsts); 1099 // Get the CPU ticking again 1100 cpu->wakeCPU(); 1101} 1102 1103template <class Impl> |
1104typename Impl::DynInstPtr 1105InstructionQueue<Impl>::getDeferredMemInstToExecute() 1106{ 1107 for (ListIt it = deferredMemInsts.begin(); it != deferredMemInsts.end(); 1108 ++it) { 1109 if ((*it)->translationCompleted() || (*it)->isSquashed()) { |
1110 DynInstPtr mem_inst = *it; |
1111 deferredMemInsts.erase(it); |
1112 return mem_inst; |
1113 } 1114 } |
1115 return nullptr; |
1116} 1117 1118template <class Impl> |
1119typename Impl::DynInstPtr 1120InstructionQueue<Impl>::getBlockedMemInstToExecute() 1121{ 1122 if (retryMemInsts.empty()) { 1123 return nullptr; 1124 } else { 1125 DynInstPtr mem_inst = retryMemInsts.front(); 1126 retryMemInsts.pop_front(); 1127 return mem_inst; 1128 } 1129} 1130 1131template <class Impl> |
1132void 1133InstructionQueue<Impl>::violation(DynInstPtr &store, 1134 DynInstPtr &faulting_load) 1135{ 1136 intInstQueueWrites++; 1137 memDepUnit[store->threadNumber].violation(store, faulting_load); 1138} 1139 --- 423 unchanged lines hidden --- |