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 while (threads != (*activeThreads).end()) { |
392 unsigned tid = *threads++; |
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 |
419 std::list<unsigned>::iterator threads = (*activeThreads).begin(); |
420 |
421 while (threads != (*activeThreads).end()) { |
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{ |
442 std::list<unsigned>::iterator threads = (*activeThreads).begin(); |
443 |
444 while (threads != (*activeThreads).end()) { |
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]; |
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 |
567 if ((*activeThreads).size() <= 0) |
568 return; 569 |
570 std::list<unsigned>::iterator threads = (*activeThreads).begin(); |
571 572 // Check if any of the threads are done squashing. Change the 573 // status if they are done. |
574 while (threads != (*activeThreads).end()) { |
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 |
595 threads = (*activeThreads).begin(); |
596 |
597 while (threads != (*activeThreads).end()) { |
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 } |
669 } else if (cpu->checkInterrupts && 670 cpu->check_interrupts(cpu->tcBase(0)) && |
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 //////////////////////////////////// |
695 std::list<unsigned>::iterator threads = (*activeThreads).begin(); |
696 |
697 while (threads != (*activeThreads).end()) { |
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 |
732 InstSeqNum bdelay_done_seq_num = squashed_inst; 733 bool squash_bdelay_slot = fromIEW->squashDelaySlot[tid]; 734 bool branchMispredict = fromIEW->branchMispredict[tid]; |
735 |
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++; |
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]; |
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 |
805 threads = (*activeThreads).begin(); |
806 |
807 while (threads != (*activeThreads).end()) { |
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 |
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 |
981 if ((head_inst->isMemBarrier() || head_inst->isWriteBarrier() || 982 head_inst->isQuiesce()) && 983 iewStage->hasStoresToWB()) |
984#endif |
985 { 986 DPRINTF(Commit, "Waiting for all stores to writeback.\n"); 987 return false; |
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++) { |
1110 renameMap[tid]->setEntry(head_inst->flattenedDestRegIdx(i), |
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{ |
1257 std::list<unsigned>::iterator threads = (*activeThreads).begin(); |
1258 |
1259 while (threads != (*activeThreads).end()) { |
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 { |
1338 int tid = (*activeThreads).front(); |
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 |
1385 std::list<unsigned>::iterator threads = (*activeThreads).begin(); |
1386 |
1387 while (threads != (*activeThreads).end()) { |
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 --- |