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

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

382 rob->takeOverFrom();
383}
384
385template <class Impl>
386void
387DefaultCommit<Impl>::updateStatus()
388{
389 // reset ROB changed variable
1/*
2 * Copyright (c) 2004-2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

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

382 rob->takeOverFrom();
383}
384
385template <class Impl>
386void
387DefaultCommit<Impl>::updateStatus()
388{
389 // reset ROB changed variable
390 std::list<unsigned>::iterator threads = activeThreads->begin();
391 std::list<unsigned>::iterator end = activeThreads->end();
392
393 while (threads != end) {
390 std::list<unsigned>::iterator threads = (*activeThreads).begin();
391 while (threads != (*activeThreads).end()) {
394 unsigned tid = *threads++;
392 unsigned tid = *threads++;
395
396 changedROBNumEntries[tid] = false;
397
398 // Also check if any of the threads has a trap pending
399 if (commitStatus[tid] == TrapPending ||
400 commitStatus[tid] == FetchTrapPending) {
401 _nextStatus = Active;
402 }
403 }

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

414}
415
416template <class Impl>
417void
418DefaultCommit<Impl>::setNextStatus()
419{
420 int squashes = 0;
421
393 changedROBNumEntries[tid] = false;
394
395 // Also check if any of the threads has a trap pending
396 if (commitStatus[tid] == TrapPending ||
397 commitStatus[tid] == FetchTrapPending) {
398 _nextStatus = Active;
399 }
400 }

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

411}
412
413template <class Impl>
414void
415DefaultCommit<Impl>::setNextStatus()
416{
417 int squashes = 0;
418
422 std::list<unsigned>::iterator threads = activeThreads->begin();
423 std::list<unsigned>::iterator end = activeThreads->end();
419 std::list<unsigned>::iterator threads = (*activeThreads).begin();
424
420
425 while (threads != end) {
421 while (threads != (*activeThreads).end()) {
426 unsigned tid = *threads++;
427
428 if (commitStatus[tid] == ROBSquashing) {
429 squashes++;
430 }
431 }
432
433 squashCounter = squashes;

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

438 _nextStatus = Active;
439 }
440}
441
442template <class Impl>
443bool
444DefaultCommit<Impl>::changedROBEntries()
445{
422 unsigned tid = *threads++;
423
424 if (commitStatus[tid] == ROBSquashing) {
425 squashes++;
426 }
427 }
428
429 squashCounter = squashes;

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

434 _nextStatus = Active;
435 }
436}
437
438template <class Impl>
439bool
440DefaultCommit<Impl>::changedROBEntries()
441{
446 std::list<unsigned>::iterator threads = activeThreads->begin();
447 std::list<unsigned>::iterator end = activeThreads->end();
442 std::list<unsigned>::iterator threads = (*activeThreads).begin();
448
443
449 while (threads != end) {
444 while (threads != (*activeThreads).end()) {
450 unsigned tid = *threads++;
451
452 if (changedROBNumEntries[tid]) {
453 return true;
454 }
455 }
456
457 return false;

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

514
515 // Send back the rob squashing signal so other stages know that
516 // the ROB is in the process of squashing.
517 toIEW->commitInfo[tid].robSquashing = true;
518
519 toIEW->commitInfo[tid].branchMispredict = false;
520
521 toIEW->commitInfo[tid].nextPC = PC[tid];
445 unsigned tid = *threads++;
446
447 if (changedROBNumEntries[tid]) {
448 return true;
449 }
450 }
451
452 return false;

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

509
510 // Send back the rob squashing signal so other stages know that
511 // the ROB is in the process of squashing.
512 toIEW->commitInfo[tid].robSquashing = true;
513
514 toIEW->commitInfo[tid].branchMispredict = false;
515
516 toIEW->commitInfo[tid].nextPC = PC[tid];
517 toIEW->commitInfo[tid].nextNPC = nextPC[tid];
522}
523
524template <class Impl>
525void
526DefaultCommit<Impl>::squashFromTrap(unsigned tid)
527{
528 squashAll(tid);
529

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

563 _nextStatus = Inactive;
564
565 if (drainPending && rob->isEmpty() && !iewStage->hasStoresToWB()) {
566 cpu->signalDrained();
567 drainPending = false;
568 return;
569 }
570
518}
519
520template <class Impl>
521void
522DefaultCommit<Impl>::squashFromTrap(unsigned tid)
523{
524 squashAll(tid);
525

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

559 _nextStatus = Inactive;
560
561 if (drainPending && rob->isEmpty() && !iewStage->hasStoresToWB()) {
562 cpu->signalDrained();
563 drainPending = false;
564 return;
565 }
566
571 if (activeThreads->empty())
567 if ((*activeThreads).size() <= 0)
572 return;
573
568 return;
569
574 std::list<unsigned>::iterator threads = activeThreads->begin();
575 std::list<unsigned>::iterator end = activeThreads->end();
570 std::list<unsigned>::iterator threads = (*activeThreads).begin();
576
577 // Check if any of the threads are done squashing. Change the
578 // status if they are done.
571
572 // Check if any of the threads are done squashing. Change the
573 // status if they are done.
579 while (threads != end) {
574 while (threads != (*activeThreads).end()) {
580 unsigned tid = *threads++;
581
582 if (commitStatus[tid] == ROBSquashing) {
583
584 if (rob->isDoneSquashing(tid)) {
585 commitStatus[tid] = Running;
586 } else {
587 DPRINTF(Commit,"[tid:%u]: Still Squashing, cannot commit any"

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

592 }
593 }
594 }
595
596 commit();
597
598 markCompletedInsts();
599
575 unsigned tid = *threads++;
576
577 if (commitStatus[tid] == ROBSquashing) {
578
579 if (rob->isDoneSquashing(tid)) {
580 commitStatus[tid] = Running;
581 } else {
582 DPRINTF(Commit,"[tid:%u]: Still Squashing, cannot commit any"

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

587 }
588 }
589 }
590
591 commit();
592
593 markCompletedInsts();
594
600 threads = activeThreads->begin();
595 threads = (*activeThreads).begin();
601
596
602 while (threads != end) {
597 while (threads != (*activeThreads).end()) {
603 unsigned tid = *threads++;
604
605 if (!rob->isEmpty(tid) && rob->readHeadInst(tid)->readyToCommit()) {
606 // The ROB has more instructions it can commit. Its next status
607 // will be active.
608 _nextStatus = Active;
609
610 DynInstPtr inst = rob->readHeadInst(tid);

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

666 generateTrapEvent(0);
667
668 // Clear the interrupt now that it's been handled
669 toIEW->commitInfo[0].clearInterrupt = true;
670 interrupt = NoFault;
671 } else {
672 DPRINTF(Commit, "Interrupt pending, waiting for ROB to empty.\n");
673 }
598 unsigned tid = *threads++;
599
600 if (!rob->isEmpty(tid) && rob->readHeadInst(tid)->readyToCommit()) {
601 // The ROB has more instructions it can commit. Its next status
602 // will be active.
603 _nextStatus = Active;
604
605 DynInstPtr inst = rob->readHeadInst(tid);

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

661 generateTrapEvent(0);
662
663 // Clear the interrupt now that it's been handled
664 toIEW->commitInfo[0].clearInterrupt = true;
665 interrupt = NoFault;
666 } else {
667 DPRINTF(Commit, "Interrupt pending, waiting for ROB to empty.\n");
668 }
674 } else if (cpu->check_interrupts(cpu->tcBase(0)) &&
669 } else if (cpu->checkInterrupts &&
670 cpu->check_interrupts(cpu->tcBase(0)) &&
675 commitStatus[0] != TrapPending &&
676 !trapSquash[0] &&
677 !tcSquash[0]) {
678 // Process interrupts if interrupts are enabled, not in PAL
679 // mode, and no other traps or external squashes are currently
680 // pending.
681 // @todo: Allow other threads to handle interrupts.
682

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

691 }
692 }
693
694#endif // FULL_SYSTEM
695
696 ////////////////////////////////////
697 // Check for any possible squashes, handle them first
698 ////////////////////////////////////
671 commitStatus[0] != TrapPending &&
672 !trapSquash[0] &&
673 !tcSquash[0]) {
674 // Process interrupts if interrupts are enabled, not in PAL
675 // mode, and no other traps or external squashes are currently
676 // pending.
677 // @todo: Allow other threads to handle interrupts.
678

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

687 }
688 }
689
690#endif // FULL_SYSTEM
691
692 ////////////////////////////////////
693 // Check for any possible squashes, handle them first
694 ////////////////////////////////////
699 std::list<unsigned>::iterator threads = activeThreads->begin();
700 std::list<unsigned>::iterator end = activeThreads->end();
695 std::list<unsigned>::iterator threads = (*activeThreads).begin();
701
696
702 while (threads != end) {
697 while (threads != (*activeThreads).end()) {
703 unsigned tid = *threads++;
704
705 // Not sure which one takes priority. I think if we have
706 // both, that's a bad sign.
707 if (trapSquash[tid] == true) {
708 assert(!tcSquash[tid]);
709 squashFromTrap(tid);
710 } else if (tcSquash[tid] == true) {

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

729
730 commitStatus[tid] = ROBSquashing;
731
732 // If we want to include the squashing instruction in the squash,
733 // then use one older sequence number.
734 InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];
735
736#if ISA_HAS_DELAY_SLOT
698 unsigned tid = *threads++;
699
700 // Not sure which one takes priority. I think if we have
701 // both, that's a bad sign.
702 if (trapSquash[tid] == true) {
703 assert(!tcSquash[tid]);
704 squashFromTrap(tid);
705 } else if (tcSquash[tid] == true) {

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

724
725 commitStatus[tid] = ROBSquashing;
726
727 // If we want to include the squashing instruction in the squash,
728 // then use one older sequence number.
729 InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];
730
731#if ISA_HAS_DELAY_SLOT
737 InstSeqNum bdelay_done_seq_num;
738 bool squash_bdelay_slot;
732 InstSeqNum bdelay_done_seq_num = squashed_inst;
733 bool squash_bdelay_slot = fromIEW->squashDelaySlot[tid];
734 bool branchMispredict = fromIEW->branchMispredict[tid];
739
735
740 if (fromIEW->branchMispredict[tid]) {
741 if (fromIEW->branchTaken[tid] &&
742 fromIEW->condDelaySlotBranch[tid]) {
743 DPRINTF(Commit, "[tid:%i]: Cond. delay slot branch"
744 "mispredicted as taken. Squashing after previous "
745 "inst, [sn:%i]\n",
746 tid, squashed_inst);
747 bdelay_done_seq_num = squashed_inst;
748 squash_bdelay_slot = true;
749 } else {
750 DPRINTF(Commit, "[tid:%i]: Branch Mispredict. Squashing "
751 "after delay slot [sn:%i]\n", tid, squashed_inst+1);
752 bdelay_done_seq_num = squashed_inst + 1;
753 squash_bdelay_slot = false;
754 }
755 } else {
756 bdelay_done_seq_num = squashed_inst;
757 squash_bdelay_slot = true;
736 // Squashing/not squashing the branch delay slot only makes
737 // sense when you're squashing from a branch, ie from a branch
738 // mispredict.
739 if (branchMispredict && !squash_bdelay_slot) {
740 bdelay_done_seq_num++;
758 }
759#endif
760
761 if (fromIEW->includeSquashInst[tid] == true) {
762 squashed_inst--;
763#if ISA_HAS_DELAY_SLOT
764 bdelay_done_seq_num--;
765#endif

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

788
789 toIEW->commitInfo[tid].branchMispredict =
790 fromIEW->branchMispredict[tid];
791
792 toIEW->commitInfo[tid].branchTaken =
793 fromIEW->branchTaken[tid];
794
795 toIEW->commitInfo[tid].nextPC = fromIEW->nextPC[tid];
741 }
742#endif
743
744 if (fromIEW->includeSquashInst[tid] == true) {
745 squashed_inst--;
746#if ISA_HAS_DELAY_SLOT
747 bdelay_done_seq_num--;
748#endif

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

771
772 toIEW->commitInfo[tid].branchMispredict =
773 fromIEW->branchMispredict[tid];
774
775 toIEW->commitInfo[tid].branchTaken =
776 fromIEW->branchTaken[tid];
777
778 toIEW->commitInfo[tid].nextPC = fromIEW->nextPC[tid];
779 toIEW->commitInfo[tid].nextNPC = fromIEW->nextNPC[tid];
796
797 toIEW->commitInfo[tid].mispredPC = fromIEW->mispredPC[tid];
798
799 if (toIEW->commitInfo[tid].branchMispredict) {
800 ++branchMispredicts;
801 }
802 }
803

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

813 commitInsts();
814 } else {
815#if ISA_HAS_DELAY_SLOT
816 skidInsert();
817#endif
818 }
819
820 //Check for any activity
780
781 toIEW->commitInfo[tid].mispredPC = fromIEW->mispredPC[tid];
782
783 if (toIEW->commitInfo[tid].branchMispredict) {
784 ++branchMispredicts;
785 }
786 }
787

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

797 commitInsts();
798 } else {
799#if ISA_HAS_DELAY_SLOT
800 skidInsert();
801#endif
802 }
803
804 //Check for any activity
821 threads = activeThreads->begin();
805 threads = (*activeThreads).begin();
822
806
823 while (threads != end) {
807 while (threads != (*activeThreads).end()) {
824 unsigned tid = *threads++;
825
826 if (changedROBNumEntries[tid]) {
827 toIEW->commitInfo[tid].usedROB = true;
828 toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
829
830 if (rob->isEmpty(tid)) {
831 toIEW->commitInfo[tid].emptyROB = true;

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

982 head_inst->isStoreConditional() ||
983 head_inst->isMemBarrier() ||
984 head_inst->isWriteBarrier()) {
985
986 DPRINTF(Commit, "Encountered a barrier or non-speculative "
987 "instruction [sn:%lli] at the head of the ROB, PC %#x.\n",
988 head_inst->seqNum, head_inst->readPC());
989
808 unsigned tid = *threads++;
809
810 if (changedROBNumEntries[tid]) {
811 toIEW->commitInfo[tid].usedROB = true;
812 toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
813
814 if (rob->isEmpty(tid)) {
815 toIEW->commitInfo[tid].emptyROB = true;

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

966 head_inst->isStoreConditional() ||
967 head_inst->isMemBarrier() ||
968 head_inst->isWriteBarrier()) {
969
970 DPRINTF(Commit, "Encountered a barrier or non-speculative "
971 "instruction [sn:%lli] at the head of the ROB, PC %#x.\n",
972 head_inst->seqNum, head_inst->readPC());
973
974#if !FULL_SYSTEM
990 // Hack to make sure syscalls/memory barriers/quiesces
991 // aren't executed until all stores write back their data.
992 // This direct communication shouldn't be used for
993 // anything other than this.
975 // Hack to make sure syscalls/memory barriers/quiesces
976 // aren't executed until all stores write back their data.
977 // This direct communication shouldn't be used for
978 // anything other than this.
979 if (inst_num > 0 || iewStage->hasStoresToWB())
980#else
994 if ((head_inst->isMemBarrier() || head_inst->isWriteBarrier() ||
995 head_inst->isQuiesce()) &&
996 iewStage->hasStoresToWB())
981 if ((head_inst->isMemBarrier() || head_inst->isWriteBarrier() ||
982 head_inst->isQuiesce()) &&
983 iewStage->hasStoresToWB())
984#endif
997 {
998 DPRINTF(Commit, "Waiting for all stores to writeback.\n");
999 return false;
985 {
986 DPRINTF(Commit, "Waiting for all stores to writeback.\n");
987 return false;
1000 } else if (inst_num > 0 || iewStage->hasStoresToWB()) {
1001 DPRINTF(Commit, "Waiting to become head of commit.\n");
1002 return false;
1003 }
1004
1005 toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
1006
1007 // Change the instruction so it won't try to commit again until
1008 // it is executed.
1009 head_inst->clearCanCommit();
1010

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

1117 head_inst->traceData->setFetchSeq(head_inst->seqNum);
1118 head_inst->traceData->setCPSeq(thread[tid]->numInst);
1119 head_inst->traceData->finalize();
1120 head_inst->traceData = NULL;
1121 }
1122
1123 // Update the commit rename map
1124 for (int i = 0; i < head_inst->numDestRegs(); i++) {
988 }
989
990 toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
991
992 // Change the instruction so it won't try to commit again until
993 // it is executed.
994 head_inst->clearCanCommit();
995

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

1102 head_inst->traceData->setFetchSeq(head_inst->seqNum);
1103 head_inst->traceData->setCPSeq(thread[tid]->numInst);
1104 head_inst->traceData->finalize();
1105 head_inst->traceData = NULL;
1106 }
1107
1108 // Update the commit rename map
1109 for (int i = 0; i < head_inst->numDestRegs(); i++) {
1125 renameMap[tid]->setEntry(head_inst->destRegIdx(i),
1110 renameMap[tid]->setEntry(head_inst->flattenedDestRegIdx(i),
1126 head_inst->renamedDestRegIdx(i));
1127 }
1128
1129 if (head_inst->isCopy())
1130 panic("Should not commit any copy instructions!");
1131
1132 // Finally clear the head ROB entry.
1133 rob->retireHead(tid);

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

1264 }
1265 }
1266}
1267
1268template <class Impl>
1269bool
1270DefaultCommit<Impl>::robDoneSquashing()
1271{
1111 head_inst->renamedDestRegIdx(i));
1112 }
1113
1114 if (head_inst->isCopy())
1115 panic("Should not commit any copy instructions!");
1116
1117 // Finally clear the head ROB entry.
1118 rob->retireHead(tid);

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

1249 }
1250 }
1251}
1252
1253template <class Impl>
1254bool
1255DefaultCommit<Impl>::robDoneSquashing()
1256{
1272 std::list<unsigned>::iterator threads = activeThreads->begin();
1273 std::list<unsigned>::iterator end = activeThreads->end();
1257 std::list<unsigned>::iterator threads = (*activeThreads).begin();
1274
1258
1275 while (threads != end) {
1259 while (threads != (*activeThreads).end()) {
1276 unsigned tid = *threads++;
1277
1278 if (!rob->isDoneSquashing(tid))
1279 return false;
1280 }
1281
1282 return true;
1283}

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

1346
1347 case OldestReady:
1348 return oldestReady();
1349
1350 default:
1351 return -1;
1352 }
1353 } else {
1260 unsigned tid = *threads++;
1261
1262 if (!rob->isDoneSquashing(tid))
1263 return false;
1264 }
1265
1266 return true;
1267}

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

1330
1331 case OldestReady:
1332 return oldestReady();
1333
1334 default:
1335 return -1;
1336 }
1337 } else {
1354 assert(!activeThreads->empty());
1355 int tid = activeThreads->front();
1338 int tid = (*activeThreads).front();
1356
1357 if (commitStatus[tid] == Running ||
1358 commitStatus[tid] == Idle ||
1359 commitStatus[tid] == FetchTrapPending) {
1360 return tid;
1361 } else {
1362 return -1;
1363 }

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

1394
1395template<class Impl>
1396int
1397DefaultCommit<Impl>::oldestReady()
1398{
1399 unsigned oldest = 0;
1400 bool first = true;
1401
1339
1340 if (commitStatus[tid] == Running ||
1341 commitStatus[tid] == Idle ||
1342 commitStatus[tid] == FetchTrapPending) {
1343 return tid;
1344 } else {
1345 return -1;
1346 }

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

1377
1378template<class Impl>
1379int
1380DefaultCommit<Impl>::oldestReady()
1381{
1382 unsigned oldest = 0;
1383 bool first = true;
1384
1402 std::list<unsigned>::iterator threads = activeThreads->begin();
1403 std::list<unsigned>::iterator end = activeThreads->end();
1385 std::list<unsigned>::iterator threads = (*activeThreads).begin();
1404
1386
1405 while (threads != end) {
1387 while (threads != (*activeThreads).end()) {
1406 unsigned tid = *threads++;
1407
1408 if (!rob->isEmpty(tid) &&
1409 (commitStatus[tid] == Running ||
1410 commitStatus[tid] == Idle ||
1411 commitStatus[tid] == FetchTrapPending)) {
1412
1413 if (rob->isHeadReady(tid)) {

--- 19 unchanged lines hidden ---
1388 unsigned tid = *threads++;
1389
1390 if (!rob->isEmpty(tid) &&
1391 (commitStatus[tid] == Running ||
1392 commitStatus[tid] == Idle ||
1393 commitStatus[tid] == FetchTrapPending)) {
1394
1395 if (rob->isHeadReady(tid)) {

--- 19 unchanged lines hidden ---