42 #ifndef __CPU_O3_INST_QUEUE_IMPL_HH__
43 #define __CPU_O3_INST_QUEUE_IMPL_HH__
51 #include "debug/IQ.hh"
52 #include "enums/OpClass.hh"
53 #include "params/DerivO3CPU.hh"
63 :
Event(Stat_Event_Pri, AutoDelete),
64 inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false)
72 iqPtr->processFUCompletion(inst, freeFU ? fuIdx : -1);
81 return "Functional unit completion";
86 DerivO3CPUParams *params)
101 numPhysRegs = params->numPhysIntRegs + params->numPhysFloatRegs +
102 params->numPhysVecRegs +
104 params->numPhysVecPredRegs +
105 params->numPhysCCRegs;
115 for (
ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
123 if (
iqPolicy == SMTQueuePolicy::Dynamic) {
129 }
else if (
iqPolicy == SMTQueuePolicy::Partitioned) {
138 DPRINTF(IQ,
"IQ sharing policy set to Partitioned:"
139 "%i entries per thread.\n",part_amt);
140 }
else if (
iqPolicy == SMTQueuePolicy::Threshold) {
141 double threshold = (double)params->smtIQThreshold / 100;
143 int thresholdIQ = (
int)((double)threshold *
numEntries);
150 DPRINTF(IQ,
"IQ sharing policy set to Threshold:"
151 "%i entries per thread.\n",thresholdIQ);
158 template <
class Impl>
163 cprintf(
"Nodes traversed: %i, removed: %i\n",
164 dependGraph.nodesTraversed, dependGraph.nodesRemoved);
168 template <
class Impl>
172 return cpu->name() +
".iq";
175 template <
class Impl>
179 using namespace Stats;
181 .name(
name() +
".iqInstsAdded")
182 .desc(
"Number of instructions added to the IQ (excludes non-spec)")
183 .prereq(iqInstsAdded);
186 .name(
name() +
".iqNonSpecInstsAdded")
187 .desc(
"Number of non-speculative instructions added to the IQ")
188 .prereq(iqNonSpecInstsAdded);
191 .name(
name() +
".iqInstsIssued")
192 .desc(
"Number of instructions issued")
193 .prereq(iqInstsIssued);
196 .name(
name() +
".iqIntInstsIssued")
197 .desc(
"Number of integer instructions issued")
198 .prereq(iqIntInstsIssued);
201 .name(
name() +
".iqFloatInstsIssued")
202 .desc(
"Number of float instructions issued")
203 .prereq(iqFloatInstsIssued);
206 .name(
name() +
".iqBranchInstsIssued")
207 .desc(
"Number of branch instructions issued")
208 .prereq(iqBranchInstsIssued);
211 .name(
name() +
".iqMemInstsIssued")
212 .desc(
"Number of memory instructions issued")
213 .prereq(iqMemInstsIssued);
216 .name(
name() +
".iqMiscInstsIssued")
217 .desc(
"Number of miscellaneous instructions issued")
218 .prereq(iqMiscInstsIssued);
220 iqSquashedInstsIssued
221 .name(
name() +
".iqSquashedInstsIssued")
222 .desc(
"Number of squashed instructions issued")
223 .prereq(iqSquashedInstsIssued);
225 iqSquashedInstsExamined
226 .name(
name() +
".iqSquashedInstsExamined")
227 .desc(
"Number of squashed instructions iterated over during squash;"
228 " mainly for profiling")
229 .prereq(iqSquashedInstsExamined);
231 iqSquashedOperandsExamined
232 .name(
name() +
".iqSquashedOperandsExamined")
233 .desc(
"Number of squashed operands that are examined and possibly "
234 "removed from graph")
235 .prereq(iqSquashedOperandsExamined);
237 iqSquashedNonSpecRemoved
238 .name(
name() +
".iqSquashedNonSpecRemoved")
239 .desc(
"Number of squashed non-spec instructions that were removed")
240 .prereq(iqSquashedNonSpecRemoved);
253 .init(0,totalWidth,1)
254 .name(
name() +
".issued_per_cycle")
255 .desc(
"Number of insts issued each cycle")
270 .init(numThreads,Enums::Num_OpClass)
271 .name(
name() +
".FU_type")
272 .desc(
"Type of FU issued")
275 statIssuedInstType.ysubnames(Enums::OpClassStrings);
295 .name(
name() +
".rate")
296 .desc(
"Inst issue rate")
299 issueRate = iqInstsIssued / cpu->numCycles;
303 .name(
name() +
".fu_full")
304 .desc(
"attempts to use FU when none available")
308 statFuBusy.subname(
i, Enums::OpClassStrings[
i]);
313 .name(
name() +
".fu_busy_cnt")
314 .desc(
"FU busy when requested")
319 .name(
name() +
".fu_busy_rate")
320 .desc(
"FU busy rate (busy events/executed inst)")
323 fuBusyRate = fuBusy / iqInstsIssued;
325 for (
ThreadID tid = 0; tid < numThreads; tid++) {
327 memDepUnit[tid].regStats();
331 .name(
name() +
".int_inst_queue_reads")
332 .desc(
"Number of integer instruction queue reads")
336 .name(
name() +
".int_inst_queue_writes")
337 .desc(
"Number of integer instruction queue writes")
340 intInstQueueWakeupAccesses
341 .name(
name() +
".int_inst_queue_wakeup_accesses")
342 .desc(
"Number of integer instruction queue wakeup accesses")
346 .name(
name() +
".fp_inst_queue_reads")
347 .desc(
"Number of floating instruction queue reads")
351 .name(
name() +
".fp_inst_queue_writes")
352 .desc(
"Number of floating instruction queue writes")
355 fpInstQueueWakeupAccesses
356 .name(
name() +
".fp_inst_queue_wakeup_accesses")
357 .desc(
"Number of floating instruction queue wakeup accesses")
361 .name(
name() +
".vec_inst_queue_reads")
362 .desc(
"Number of vector instruction queue reads")
366 .name(
name() +
".vec_inst_queue_writes")
367 .desc(
"Number of vector instruction queue writes")
370 vecInstQueueWakeupAccesses
371 .name(
name() +
".vec_inst_queue_wakeup_accesses")
372 .desc(
"Number of vector instruction queue wakeup accesses")
376 .name(
name() +
".int_alu_accesses")
377 .desc(
"Number of integer alu accesses")
381 .name(
name() +
".fp_alu_accesses")
382 .desc(
"Number of floating point alu accesses")
386 .name(
name() +
".vec_alu_accesses")
387 .desc(
"Number of vector alu accesses")
392 template <
class Impl>
397 for (
ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
399 instList[tid].clear();
403 freeEntries = numEntries;
410 for (
int i = 0;
i < numPhysRegs; ++
i) {
411 regScoreboard[
i] =
false;
414 for (
ThreadID tid = 0; tid < Impl::MaxThreads; ++tid) {
415 squashedSeqNum[tid] = 0;
419 while (!readyInsts[
i].empty())
421 queueOnList[
i] =
false;
422 readyIt[
i] = listOrder.end();
424 nonSpecInsts.clear();
426 deferredMemInsts.clear();
427 blockedMemInsts.clear();
428 retryMemInsts.clear();
432 template <
class Impl>
436 activeThreads = at_ptr;
439 template <
class Impl>
443 issueToExecuteQueue = i2e_ptr;
446 template <
class Impl>
452 fromCommit = timeBuffer->
getWire(-commitToIEWDelay);
455 template <
class Impl>
459 bool drained = dependGraph.empty() &&
460 instsToExecute.empty() &&
462 for (
ThreadID tid = 0; tid < numThreads; ++tid)
463 drained = drained && memDepUnit[tid].isDrained();
468 template <
class Impl>
472 assert(dependGraph.empty());
473 assert(instsToExecute.empty());
474 for (
ThreadID tid = 0; tid < numThreads; ++tid)
475 memDepUnit[tid].drainSanityCheck();
478 template <
class Impl>
485 template <
class Impl>
489 if (iqPolicy == SMTQueuePolicy::Partitioned) {
490 return numEntries / num_threads;
497 template <
class Impl>
501 if (iqPolicy != SMTQueuePolicy::Dynamic || numThreads > 1) {
502 int active_threads = activeThreads->size();
507 while (threads != end) {
510 if (iqPolicy == SMTQueuePolicy::Partitioned) {
511 maxEntries[tid] = numEntries / active_threads;
512 }
else if (iqPolicy == SMTQueuePolicy::Threshold &&
513 active_threads == 1) {
514 maxEntries[tid] = numEntries;
520 template <
class Impl>
527 template <
class Impl>
531 return maxEntries[tid] -
count[tid];
536 template <
class Impl>
540 if (freeEntries == 0) {
547 template <
class Impl>
551 if (numFreeEntries(tid) == 0) {
558 template <
class Impl>
562 if (!listOrder.empty()) {
567 if (!readyInsts[
i].empty()) {
575 template <
class Impl>
579 if (new_inst->isFloating()) {
581 }
else if (new_inst->isVector()) {
582 vecInstQueueWrites++;
584 intInstQueueWrites++;
589 DPRINTF(IQ,
"Adding instruction [sn:%llu] PC %s to the IQ.\n",
590 new_inst->seqNum, new_inst->pcState());
592 assert(freeEntries != 0);
594 instList[new_inst->threadNumber].push_back(new_inst);
602 addToDependents(new_inst);
606 addToProducers(new_inst);
608 if (new_inst->isMemRef()) {
609 memDepUnit[new_inst->threadNumber].insert(new_inst);
611 addIfReady(new_inst);
616 count[new_inst->threadNumber]++;
618 assert(freeEntries == (numEntries - countInsts()));
621 template <
class Impl>
627 if (new_inst->isFloating()) {
629 }
else if (new_inst->isVector()) {
630 vecInstQueueWrites++;
632 intInstQueueWrites++;
637 nonSpecInsts[new_inst->seqNum] = new_inst;
639 DPRINTF(IQ,
"Adding non-speculative instruction [sn:%llu] PC %s "
641 new_inst->seqNum, new_inst->pcState());
643 assert(freeEntries != 0);
645 instList[new_inst->threadNumber].push_back(new_inst);
653 addToProducers(new_inst);
657 if (new_inst->isMemRef()) {
658 memDepUnit[new_inst->threadNumber].insertNonSpec(new_inst);
661 ++iqNonSpecInstsAdded;
663 count[new_inst->threadNumber]++;
665 assert(freeEntries == (numEntries - countInsts()));
668 template <
class Impl>
672 memDepUnit[barr_inst->threadNumber].insertBarrier(barr_inst);
674 insertNonSpec(barr_inst);
677 template <
class Impl>
678 typename Impl::DynInstPtr
681 assert(!instsToExecute.empty());
682 DynInstPtr inst = std::move(instsToExecute.front());
683 instsToExecute.pop_front();
684 if (inst->isFloating()) {
686 }
else if (inst->isVector()) {
694 template <
class Impl>
698 assert(!readyInsts[op_class].empty());
704 queue_entry.
oldestInst = readyInsts[op_class].top()->seqNum;
709 while (list_it != list_end_it) {
710 if ((*list_it).oldestInst > queue_entry.
oldestInst) {
717 readyIt[op_class] = listOrder.insert(list_it, queue_entry);
718 queueOnList[op_class] =
true;
721 template <
class Impl>
731 OpClass op_class = (*list_order_it).
queueType;
737 queue_entry.
oldestInst = readyInsts[op_class].top()->seqNum;
739 while (next_it != listOrder.end() &&
740 (*next_it).oldestInst < queue_entry.
oldestInst) {
744 readyIt[op_class] = listOrder.insert(next_it, queue_entry);
747 template <
class Impl>
751 DPRINTF(IQ,
"Processing FU completion [sn:%llu]\n", inst->seqNum);
752 assert(!cpu->switchedOut());
759 fuPool->freeUnitNextCycle(fu_idx);
764 issueToExecuteQueue->access(-1)->size++;
765 instsToExecute.push_back(inst);
771 template <
class Impl>
775 DPRINTF(IQ,
"Attempting to schedule ready instructions from "
778 IssueStruct *i2e_info = issueToExecuteQueue->access(0);
781 while (mem_inst = std::move(getDeferredMemInstToExecute())) {
782 addReadyMemInst(mem_inst);
786 while (mem_inst = std::move(getBlockedMemInstToExecute())) {
787 addReadyMemInst(mem_inst);
798 int total_issued = 0;
802 while (total_issued < totalWidth && order_it != order_end_it) {
803 OpClass op_class = (*order_it).queueType;
805 assert(!readyInsts[op_class].empty());
807 DynInstPtr issuing_inst = readyInsts[op_class].top();
809 if (issuing_inst->isFloating()) {
811 }
else if (issuing_inst->isVector()) {
817 assert(issuing_inst->seqNum == (*order_it).oldestInst);
819 if (issuing_inst->isSquashed()) {
820 readyInsts[op_class].pop();
822 if (!readyInsts[op_class].empty()) {
823 moveToYoungerInst(order_it);
825 readyIt[op_class] = listOrder.end();
826 queueOnList[op_class] =
false;
829 listOrder.erase(order_it++);
831 ++iqSquashedInstsIssued;
838 ThreadID tid = issuing_inst->threadNumber;
840 if (op_class != No_OpClass) {
841 idx = fuPool->getUnit(op_class);
842 if (issuing_inst->isFloating()) {
844 }
else if (issuing_inst->isVector()) {
850 op_latency = fuPool->getOpLatency(op_class);
857 if (op_latency ==
Cycles(1)) {
859 instsToExecute.push_back(issuing_inst);
864 fuPool->freeUnitNextCycle(idx);
866 bool pipelined = fuPool->isPipelined(op_class);
872 cpu->schedule(execution,
873 cpu->clockEdge(
Cycles(op_latency - 1)));
881 fuPool->freeUnitNextCycle(idx);
885 DPRINTF(IQ,
"Thread %i: Issuing instruction PC %s "
887 tid, issuing_inst->pcState(),
888 issuing_inst->seqNum);
890 readyInsts[op_class].pop();
892 if (!readyInsts[op_class].empty()) {
893 moveToYoungerInst(order_it);
895 readyIt[op_class] = listOrder.end();
896 queueOnList[op_class] =
false;
899 issuing_inst->setIssued();
903 issuing_inst->issueTick =
curTick() - issuing_inst->fetchTick;
906 if (!issuing_inst->isMemRef()) {
911 issuing_inst->clearInIQ();
913 memDepUnit[tid].issue(issuing_inst);
916 listOrder.erase(order_it++);
917 statIssuedInstType[tid][op_class]++;
919 statFuBusy[op_class]++;
925 numIssuedDist.sample(total_issued);
926 iqInstsIssued+= total_issued;
932 if (total_issued || !retryMemInsts.empty() || !deferredMemInsts.empty()) {
933 cpu->activityThisCycle();
935 DPRINTF(IQ,
"Not able to schedule any instructions.\n");
939 template <
class Impl>
943 DPRINTF(IQ,
"Marking nonspeculative instruction [sn:%llu] as ready "
944 "to execute.\n", inst);
948 assert(inst_it != nonSpecInsts.end());
950 ThreadID tid = (*inst_it).second->threadNumber;
952 (*inst_it).second->setAtCommit();
954 (*inst_it).second->setCanIssue();
956 if (!(*inst_it).second->isMemRef()) {
957 addIfReady((*inst_it).second);
959 memDepUnit[tid].nonSpecInstReady((*inst_it).second);
962 (*inst_it).second = NULL;
964 nonSpecInsts.erase(inst_it);
967 template <
class Impl>
971 DPRINTF(IQ,
"[tid:%i] Committing instructions older than [sn:%llu]\n",
974 ListIt iq_it = instList[tid].begin();
976 while (iq_it != instList[tid].end() &&
977 (*iq_it)->seqNum <= inst) {
979 instList[tid].pop_front();
982 assert(freeEntries == (numEntries - countInsts()));
985 template <
class Impl>
992 if (completed_inst->isFloating()) {
993 fpInstQueueWakeupAccesses++;
994 }
else if (completed_inst->isVector()) {
995 vecInstQueueWakeupAccesses++;
997 intInstQueueWakeupAccesses++;
1000 DPRINTF(IQ,
"Waking dependents of completed instruction.\n");
1002 assert(!completed_inst->isSquashed());
1007 ThreadID tid = completed_inst->threadNumber;
1008 if (completed_inst->isMemRef()) {
1009 memDepUnit[tid].completeInst(completed_inst);
1011 DPRINTF(IQ,
"Completing mem instruction PC: %s [sn:%llu]\n",
1012 completed_inst->pcState(), completed_inst->seqNum);
1015 completed_inst->memOpDone(
true);
1017 }
else if (completed_inst->isMemBarrier() ||
1018 completed_inst->isWriteBarrier()) {
1020 memDepUnit[tid].completeInst(completed_inst);
1023 for (
int dest_reg_idx = 0;
1024 dest_reg_idx < completed_inst->numDestRegs();
1028 completed_inst->renamedDestRegIdx(dest_reg_idx);
1033 DPRINTF(IQ,
"Reg %d [%s] is part of a fix mapping, skipping\n",
1041 completed_inst->setPinnedRegsWritten();
1044 DPRINTF(IQ,
"Reg %d [%s] is pinned, skipping\n",
1049 DPRINTF(IQ,
"Waking any dependents on register %i (%s).\n",
1058 DPRINTF(IQ,
"Waking up a dependent instruction, [sn:%llu] "
1059 "PC %s.\n", dep_inst->seqNum, dep_inst->pcState());
1065 dep_inst->markSrcRegReady();
1067 addIfReady(dep_inst);
1069 dep_inst = dependGraph.pop(dest_reg->
flatIndex());
1076 assert(dependGraph.empty(dest_reg->
flatIndex()));
1077 dependGraph.clearInst(dest_reg->
flatIndex());
1080 regScoreboard[dest_reg->
flatIndex()] =
true;
1085 template <
class Impl>
1089 OpClass op_class = ready_inst->opClass();
1091 readyInsts[op_class].push(ready_inst);
1095 if (!queueOnList[op_class]) {
1096 addToOrderList(op_class);
1097 }
else if (readyInsts[op_class].
top()->seqNum <
1098 (*readyIt[op_class]).oldestInst) {
1099 listOrder.erase(readyIt[op_class]);
1100 addToOrderList(op_class);
1103 DPRINTF(IQ,
"Instruction is ready to issue, putting it onto "
1104 "the ready list, PC %s opclass:%i [sn:%llu].\n",
1105 ready_inst->pcState(), op_class, ready_inst->seqNum);
1108 template <
class Impl>
1112 DPRINTF(IQ,
"Rescheduling mem inst [sn:%llu]\n", resched_inst->seqNum);
1115 resched_inst->translationStarted(
false);
1116 resched_inst->translationCompleted(
false);
1118 resched_inst->clearCanIssue();
1119 memDepUnit[resched_inst->threadNumber].reschedule(resched_inst);
1122 template <
class Impl>
1126 memDepUnit[replay_inst->threadNumber].replay();
1129 template <
class Impl>
1133 deferredMemInsts.push_back(deferred_inst);
1136 template <
class Impl>
1140 blocked_inst->clearIssued();
1141 blocked_inst->clearCanIssue();
1142 blockedMemInsts.push_back(blocked_inst);
1145 template <
class Impl>
1149 retryMemInsts.splice(retryMemInsts.end(), blockedMemInsts);
1154 template <
class Impl>
1155 typename Impl::DynInstPtr
1158 for (
ListIt it = deferredMemInsts.begin(); it != deferredMemInsts.end();
1160 if ((*it)->translationCompleted() || (*it)->isSquashed()) {
1162 deferredMemInsts.erase(it);
1169 template <
class Impl>
1170 typename Impl::DynInstPtr
1173 if (retryMemInsts.empty()) {
1176 DynInstPtr mem_inst = std::move(retryMemInsts.front());
1177 retryMemInsts.pop_front();
1182 template <
class Impl>
1187 intInstQueueWrites++;
1188 memDepUnit[store->threadNumber].violation(store, faulting_load);
1191 template <
class Impl>
1195 DPRINTF(IQ,
"[tid:%i] Starting to squash instructions in "
1200 squashedSeqNum[tid] = fromCommit->commitInfo[tid].doneSeqNum;
1205 memDepUnit[tid].squash(squashedSeqNum[tid], tid);
1208 template <
class Impl>
1213 ListIt squash_it = instList[tid].end();
1216 DPRINTF(IQ,
"[tid:%i] Squashing until sequence number %i!\n",
1217 tid, squashedSeqNum[tid]);
1221 while (squash_it != instList[tid].end() &&
1222 (*squash_it)->seqNum > squashedSeqNum[tid]) {
1225 if (squashed_inst->isFloating()) {
1226 fpInstQueueWrites++;
1227 }
else if (squashed_inst->isVector()) {
1228 vecInstQueueWrites++;
1230 intInstQueueWrites++;
1235 if (squashed_inst->threadNumber != tid ||
1236 squashed_inst->isSquashedInIQ()) {
1241 if (!squashed_inst->isIssued() ||
1242 (squashed_inst->isMemRef() &&
1243 !squashed_inst->memOpDone())) {
1245 DPRINTF(IQ,
"[tid:%i] Instruction [sn:%llu] PC %s squashed.\n",
1246 tid, squashed_inst->seqNum, squashed_inst->pcState());
1248 bool is_acq_rel = squashed_inst->isMemBarrier() &&
1249 (squashed_inst->isLoad() ||
1250 (squashed_inst->isStore() &&
1251 !squashed_inst->isStoreConditional()));
1255 (!squashed_inst->isNonSpeculative() &&
1256 !squashed_inst->isStoreConditional() &&
1257 !squashed_inst->isAtomic() &&
1258 !squashed_inst->isMemBarrier() &&
1259 !squashed_inst->isWriteBarrier())) {
1261 for (
int src_reg_idx = 0;
1262 src_reg_idx < squashed_inst->numSrcRegs();
1266 squashed_inst->renamedSrcRegIdx(src_reg_idx);
1277 if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) &&
1279 dependGraph.remove(src_reg->
flatIndex(),
1283 ++iqSquashedOperandsExamined;
1286 }
else if (!squashed_inst->isStoreConditional() ||
1287 !squashed_inst->isCompleted()) {
1289 nonSpecInsts.find(squashed_inst->seqNum);
1294 if (ns_inst_it == nonSpecInsts.end()) {
1298 assert(squashed_inst->getFault() !=
NoFault ||
1299 squashed_inst->isMemRef());
1302 (*ns_inst_it).second = NULL;
1304 nonSpecInsts.erase(ns_inst_it);
1306 ++iqSquashedNonSpecRemoved;
1313 squashed_inst->setSquashedInIQ();
1317 squashed_inst->setIssued();
1318 squashed_inst->setCanCommit();
1319 squashed_inst->clearInIQ();
1322 count[squashed_inst->threadNumber]--;
1334 for (
int dest_reg_idx = 0;
1335 dest_reg_idx < squashed_inst->numDestRegs();
1339 squashed_inst->renamedDestRegIdx(dest_reg_idx);
1343 assert(dependGraph.empty(dest_reg->
flatIndex()));
1344 dependGraph.clearInst(dest_reg->
flatIndex());
1346 instList[tid].erase(squash_it--);
1347 ++iqSquashedInstsExamined;
1351 template <
class Impl>
1357 int8_t total_src_regs = new_inst->numSrcRegs();
1358 bool return_val =
false;
1360 for (
int src_reg_idx = 0;
1361 src_reg_idx < total_src_regs;
1365 if (!new_inst->isReadySrcRegIdx(src_reg_idx)) {
1366 PhysRegIdPtr src_reg = new_inst->renamedSrcRegIdx(src_reg_idx);
1374 }
else if (!regScoreboard[src_reg->
flatIndex()]) {
1375 DPRINTF(IQ,
"Instruction PC %s has src reg %i (%s) that "
1376 "is being added to the dependency chain.\n",
1377 new_inst->pcState(), src_reg->
index(),
1380 dependGraph.insert(src_reg->
flatIndex(), new_inst);
1386 DPRINTF(IQ,
"Instruction PC %s has src reg %i (%s) that "
1387 "became ready before it reached the IQ.\n",
1388 new_inst->pcState(), src_reg->
index(),
1391 new_inst->markSrcRegReady(src_reg_idx);
1399 template <
class Impl>
1407 int8_t total_dest_regs = new_inst->numDestRegs();
1409 for (
int dest_reg_idx = 0;
1410 dest_reg_idx < total_dest_regs;
1413 PhysRegIdPtr dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx);
1421 if (!dependGraph.empty(dest_reg->
flatIndex())) {
1423 panic(
"Dependency graph %i (%s) (flat: %i) not empty!",
1428 dependGraph.setInst(dest_reg->
flatIndex(), new_inst);
1431 regScoreboard[dest_reg->
flatIndex()] =
false;
1435 template <
class Impl>
1441 if (inst->readyToIssue()) {
1444 if (inst->isMemRef()) {
1446 DPRINTF(IQ,
"Checking if memory instruction can issue.\n");
1450 memDepUnit[inst->threadNumber].regsReady(inst);
1455 OpClass op_class = inst->opClass();
1457 DPRINTF(IQ,
"Instruction is ready to issue, putting it onto "
1458 "the ready list, PC %s opclass:%i [sn:%llu].\n",
1459 inst->pcState(), op_class, inst->seqNum);
1461 readyInsts[op_class].push(inst);
1465 if (!queueOnList[op_class]) {
1466 addToOrderList(op_class);
1467 }
else if (readyInsts[op_class].
top()->seqNum <
1468 (*readyIt[op_class]).oldestInst) {
1469 listOrder.erase(readyIt[op_class]);
1470 addToOrderList(op_class);
1475 template <
class Impl>
1479 return numEntries - freeEntries;
1482 template <
class Impl>
1487 cprintf(
"Ready list %i size: %i\n",
i, readyInsts[
i].size());
1492 cprintf(
"Non speculative list size: %i\n", nonSpecInsts.size());
1497 cprintf(
"Non speculative list: ");
1499 while (non_spec_it != non_spec_end_it) {
1500 cprintf(
"%s [sn:%llu]", (*non_spec_it).second->pcState(),
1501 (*non_spec_it).second->seqNum);
1513 while (list_order_it != list_order_end_it) {
1514 cprintf(
"%i OpClass:%i [sn:%llu] ",
i, (*list_order_it).queueType,
1515 (*list_order_it).oldestInst);
1525 template <
class Impl>
1529 for (
ThreadID tid = 0; tid < numThreads; ++tid) {
1532 ListIt inst_list_it = instList[tid].begin();
1534 while (inst_list_it != instList[tid].end()) {
1535 cprintf(
"Instruction:%i\n", num);
1536 if (!(*inst_list_it)->isSquashed()) {
1537 if (!(*inst_list_it)->isIssued()) {
1539 cprintf(
"Count:%i\n", valid_num);
1540 }
else if ((*inst_list_it)->isMemRef() &&
1541 !(*inst_list_it)->memOpDone()) {
1545 cprintf(
"Count:%i\n", valid_num);
1549 cprintf(
"PC: %s\n[sn:%llu]\n[tid:%i]\n"
1550 "Issued:%i\nSquashed:%i\n",
1551 (*inst_list_it)->pcState(),
1552 (*inst_list_it)->seqNum,
1553 (*inst_list_it)->threadNumber,
1554 (*inst_list_it)->isIssued(),
1555 (*inst_list_it)->isSquashed());
1557 if ((*inst_list_it)->isMemRef()) {
1558 cprintf(
"MemOpDone:%i\n", (*inst_list_it)->memOpDone());
1568 cprintf(
"Insts to Execute list:\n");
1572 ListIt inst_list_it = instsToExecute.begin();
1574 while (inst_list_it != instsToExecute.end())
1578 if (!(*inst_list_it)->isSquashed()) {
1579 if (!(*inst_list_it)->isIssued()) {
1581 cprintf(
"Count:%i\n", valid_num);
1582 }
else if ((*inst_list_it)->isMemRef() &&
1583 !(*inst_list_it)->memOpDone()) {
1587 cprintf(
"Count:%i\n", valid_num);
1591 cprintf(
"PC: %s\n[sn:%llu]\n[tid:%i]\n"
1592 "Issued:%i\nSquashed:%i\n",
1593 (*inst_list_it)->pcState(),
1594 (*inst_list_it)->seqNum,
1595 (*inst_list_it)->threadNumber,
1596 (*inst_list_it)->isIssued(),
1597 (*inst_list_it)->isSquashed());
1599 if ((*inst_list_it)->isMemRef()) {
1600 cprintf(
"MemOpDone:%i\n", (*inst_list_it)->memOpDone());
1610 #endif//__CPU_O3_INST_QUEUE_IMPL_HH__