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