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; --- 268 unchanged lines hidden (view full) --- 277 "detected at decode.\n", tid); 278 279 // Send back mispredict information. 280 toFetch->decodeInfo[tid].branchMispredict = true; 281 toFetch->decodeInfo[tid].predIncorrect = true; 282 toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum; 283 toFetch->decodeInfo[tid].squash = true; 284 toFetch->decodeInfo[tid].nextPC = inst->branchTarget(); |
285 ///FIXME There needs to be a way to set the nextPC and nextNPC 286 ///explicitly for ISAs with delay slots. 287 toFetch->decodeInfo[tid].nextNPC = 288 inst->branchTarget() + sizeof(TheISA::MachInst); |
289#if ISA_HAS_DELAY_SLOT 290 toFetch->decodeInfo[tid].branchTaken = inst->readNextNPC() != 291 (inst->readNextPC() + sizeof(TheISA::MachInst)); 292 293 toFetch->decodeInfo[tid].bdelayDoneSeqNum = bdelayDoneSeqNum[tid]; 294 squashAfterDelaySlot[tid] = false; 295 296 InstSeqNum squash_seq_num = bdelayDoneSeqNum[tid]; --- 126 unchanged lines hidden (view full) --- 423 // fetch past its skidbuffer 424 assert(skidBuffer[tid].size() <= skidBufferMax); 425} 426 427template<class Impl> 428bool 429DefaultDecode<Impl>::skidsEmpty() 430{ |
431 std::list<unsigned>::iterator threads = (*activeThreads).begin(); |
432 |
433 while (threads != (*activeThreads).end()) { 434 if (!skidBuffer[*threads++].empty()) |
435 return false; 436 } 437 438 return true; 439} 440 441template<class Impl> 442void 443DefaultDecode<Impl>::updateStatus() 444{ 445 bool any_unblocking = false; 446 |
447 std::list<unsigned>::iterator threads = (*activeThreads).begin(); |
448 |
449 threads = (*activeThreads).begin(); 450 451 while (threads != (*activeThreads).end()) { |
452 unsigned tid = *threads++; 453 454 if (decodeStatus[tid] == Unblocking) { 455 any_unblocking = true; 456 break; 457 } 458 } 459 --- 136 unchanged lines hidden (view full) --- 596DefaultDecode<Impl>::tick() 597{ 598 wroteToTimeBuffer = false; 599 600 bool status_change = false; 601 602 toRenameIndex = 0; 603 |
604 std::list<unsigned>::iterator threads = (*activeThreads).begin(); |
605 606 sortInsts(); 607 608 //Check stall and squash signals. |
609 while (threads != (*activeThreads).end()) { 610 unsigned tid = *threads++; |
611 612 DPRINTF(Decode,"Processing [tid:%i]\n",tid); 613 status_change = checkSignalsAndUpdate(tid) || status_change; 614 615 decode(status_change, tid); 616 } 617 618 if (status_change) { --- 121 unchanged lines hidden (view full) --- 740 741 ++(toRename->size); 742 ++toRenameIndex; 743 ++decodeDecodedInsts; 744 --insts_available; 745 746 // Ensure that if it was predicted as a branch, it really is a 747 // branch. |
748 if (inst->readPredTaken() && !inst->isControl()) { 749 DPRINTF(Decode, "PredPC : %#x != NextPC: %#x\n", 750 inst->readPredPC(), inst->readNextPC() + 4); |
751 752 panic("Instruction predicted as a branch!"); 753 754 ++decodeControlMispred; 755 756 // Might want to set some sort of boolean and just do 757 // a check at the end 758 squash(inst, inst->threadNumber); 759 760 break; 761 } 762 763 // Go ahead and compute any PC-relative branches. 764 if (inst->isDirectCtrl() && inst->isUncondCtrl()) { 765 ++decodeBranchResolved; 766 |
767 if (inst->branchTarget() != inst->readPredPC()) { |
768 ++decodeBranchMispred; 769 770 // Might want to set some sort of boolean and just do 771 // a check at the end 772#if !ISA_HAS_DELAY_SLOT 773 squash(inst, inst->threadNumber); |
774 Addr target = inst->branchTarget(); 775 inst->setPredTarg(target, target + sizeof(TheISA::MachInst)); |
776 break; 777#else 778 // If mispredicted as taken, then ignore delay slot 779 // instruction... else keep delay slot and squash 780 // after it is sent to rename |
781 if (inst->readPredTaken() && inst->isCondDelaySlot()) { |
782 DPRINTF(Decode, "[tid:%i]: Conditional delay slot inst." 783 "[sn:%i] PC %#x mispredicted as taken.\n", tid, 784 inst->seqNum, inst->PC); 785 bdelayDoneSeqNum[tid] = inst->seqNum; 786 squash(inst, inst->threadNumber); |
787 Addr target = inst->branchTarget(); 788 inst->setPredTarg(target, 789 target + sizeof(TheISA::MachInst)); |
790 break; 791 } else { 792 DPRINTF(Decode, "[tid:%i]: Misprediction detected at " 793 "[sn:%i] PC %#x, will squash after delay slot " 794 "inst. is sent to Rename\n", 795 tid, inst->seqNum, inst->PC); 796 bdelayDoneSeqNum[tid] = inst->seqNum + 1; 797 squashAfterDelaySlot[tid] = true; 798 squashInst[tid] = inst; 799 continue; 800 } 801#endif 802 } 803 } 804 805 if (squashAfterDelaySlot[tid]) { 806 assert(!inst->isSquashed()); 807 squash(squashInst[tid], squashInst[tid]->threadNumber); |
808 Addr target = squashInst[tid]->branchTarget(); 809 squashInst[tid]->setPredTarg(target, 810 target + sizeof(TheISA::MachInst)); |
811 assert(!inst->isSquashed()); 812 break; 813 } 814 } 815 816 // If we didn't process all instructions, then we will need to block 817 // and put all those instructions into the skid buffer. 818 if (!insts_to_decode.empty()) { 819 block(tid); 820 } 821 822 // Record that decode has written to the time buffer for activity 823 // tracking. 824 if (toRenameIndex) { 825 wroteToTimeBuffer = true; 826 } 827} |