decode_impl.hh (3796:9cb1eaf3a461) decode_impl.hh (3867:807483cfab77)
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;

--- 410 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{
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;

--- 410 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{
427 std::list<unsigned>::iterator threads = (*activeThreads).begin();
427 std::list<unsigned>::iterator threads = activeThreads->begin();
428 std::list<unsigned>::iterator end = activeThreads->end();
428
429
429 while (threads != (*activeThreads).end()) {
430 if (!skidBuffer[*threads++].empty())
430 while (threads != end) {
431 unsigned tid = *threads++;
432 if (!skidBuffer[tid].empty())
431 return false;
432 }
433
434 return true;
435}
436
437template<class Impl>
438void
439DefaultDecode<Impl>::updateStatus()
440{
441 bool any_unblocking = false;
442
433 return false;
434 }
435
436 return true;
437}
438
439template<class Impl>
440void
441DefaultDecode<Impl>::updateStatus()
442{
443 bool any_unblocking = false;
444
443 std::list<unsigned>::iterator threads = (*activeThreads).begin();
445 std::list<unsigned>::iterator threads = activeThreads->begin();
446 std::list<unsigned>::iterator end = activeThreads->end();
444
447
445 threads = (*activeThreads).begin();
446
447 while (threads != (*activeThreads).end()) {
448 while (threads != end) {
448 unsigned tid = *threads++;
449
450 if (decodeStatus[tid] == Unblocking) {
451 any_unblocking = true;
452 break;
453 }
454 }
455

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

592DefaultDecode<Impl>::tick()
593{
594 wroteToTimeBuffer = false;
595
596 bool status_change = false;
597
598 toRenameIndex = 0;
599
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
600 std::list<unsigned>::iterator threads = (*activeThreads).begin();
601 std::list<unsigned>::iterator threads = activeThreads->begin();
602 std::list<unsigned>::iterator end = activeThreads->end();
601
602 sortInsts();
603
604 //Check stall and squash signals.
603
604 sortInsts();
605
606 //Check stall and squash signals.
605 while (threads != (*activeThreads).end()) {
606 unsigned tid = *threads++;
607 while (threads != end) {
608 unsigned tid = *threads++;
607
608 DPRINTF(Decode,"Processing [tid:%i]\n",tid);
609 status_change = checkSignalsAndUpdate(tid) || status_change;
610
611 decode(status_change, tid);
612 }
613
614 if (status_change) {

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

736
737 ++(toRename->size);
738 ++toRenameIndex;
739 ++decodeDecodedInsts;
740 --insts_available;
741
742 // Ensure that if it was predicted as a branch, it really is a
743 // branch.
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.
744 if (inst->readPredTaken() && !inst->isControl()) {
746 if (inst->predTaken() && !inst->isControl()) {
745 DPRINTF(Decode, "PredPC : %#x != NextPC: %#x\n",inst->predPC,
746 inst->nextPC + 4);
747
748 panic("Instruction predicted as a branch!");
749
750 ++decodeControlMispred;
751
752 // Might want to set some sort of boolean and just do
753 // a check at the end
754 squash(inst, inst->threadNumber);
755
756 break;
757 }
758
759 // Go ahead and compute any PC-relative branches.
760 if (inst->isDirectCtrl() && inst->isUncondCtrl()) {
761 ++decodeBranchResolved;
762
747 DPRINTF(Decode, "PredPC : %#x != NextPC: %#x\n",inst->predPC,
748 inst->nextPC + 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
763 if (inst->branchTarget() != inst->readPredPC()) {
765 if (inst->branchTarget() != inst->readPredTarg()) {
764 ++decodeBranchMispred;
765
766 // Might want to set some sort of boolean and just do
767 // a check at the end
768#if !ISA_HAS_DELAY_SLOT
769 squash(inst, inst->threadNumber);
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);
770 Addr target = inst->branchTarget();
771 inst->setPredTarg(target, target + sizeof(TheISA::MachInst));
772 inst->setPredTarg(inst->branchTarget());
772 break;
773#else
774 // If mispredicted as taken, then ignore delay slot
775 // instruction... else keep delay slot and squash
776 // after it is sent to rename
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
777 if (inst->readPredTaken() && inst->isCondDelaySlot()) {
778 if (inst->predTaken() && inst->isCondDelaySlot()) {
778 DPRINTF(Decode, "[tid:%i]: Conditional delay slot inst."
779 "[sn:%i] PC %#x mispredicted as taken.\n", tid,
780 inst->seqNum, inst->PC);
781 bdelayDoneSeqNum[tid] = inst->seqNum;
782 squash(inst, inst->threadNumber);
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);
783 Addr target = inst->branchTarget();
784 inst->setPredTarg(target,
785 target + sizeof(TheISA::MachInst));
784 inst->setPredTarg(inst->branchTarget());
786 break;
787 } else {
788 DPRINTF(Decode, "[tid:%i]: Misprediction detected at "
789 "[sn:%i] PC %#x, will squash after delay slot "
790 "inst. is sent to Rename\n",
791 tid, inst->seqNum, inst->PC);
792 bdelayDoneSeqNum[tid] = inst->seqNum + 1;
793 squashAfterDelaySlot[tid] = true;
794 squashInst[tid] = inst;
795 continue;
796 }
797#endif
798 }
799 }
800
801 if (squashAfterDelaySlot[tid]) {
802 assert(!inst->isSquashed());
803 squash(squashInst[tid], squashInst[tid]->threadNumber);
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);
804 Addr target = squashInst[tid]->branchTarget();
805 squashInst[tid]->setPredTarg(target,
806 target + sizeof(TheISA::MachInst));
803 squashInst[tid]->setPredTarg(squashInst[tid]->branchTarget());
807 assert(!inst->isSquashed());
808 break;
809 }
810 }
811
812 // If we didn't process all instructions, then we will need to block
813 // and put all those instructions into the skid buffer.
814 if (!insts_to_decode.empty()) {
815 block(tid);
816 }
817
818 // Record that decode has written to the time buffer for activity
819 // tracking.
820 if (toRenameIndex) {
821 wroteToTimeBuffer = true;
822 }
823}
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}