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