decode_impl.hh revision 6658:f4de76601762
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; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Kevin Lim 29 */ 30 31#include "config/the_isa.hh" 32#include "cpu/o3/decode.hh" 33#include "params/DerivO3CPU.hh" 34 35using namespace std; 36 37template<class Impl> 38DefaultDecode<Impl>::DefaultDecode(O3CPU *_cpu, DerivO3CPUParams *params) 39 : cpu(_cpu), 40 renameToDecodeDelay(params->renameToDecodeDelay), 41 iewToDecodeDelay(params->iewToDecodeDelay), 42 commitToDecodeDelay(params->commitToDecodeDelay), 43 fetchToDecodeDelay(params->fetchToDecodeDelay), 44 decodeWidth(params->decodeWidth), 45 numThreads(params->numThreads) 46{ 47 _status = Inactive; 48 49 // Setup status, make sure stall signals are clear. 50 for (ThreadID tid = 0; tid < numThreads; ++tid) { 51 decodeStatus[tid] = Idle; 52 53 stalls[tid].rename = false; 54 stalls[tid].iew = false; 55 stalls[tid].commit = false; 56 } 57 58 // @todo: Make into a parameter 59 skidBufferMax = (fetchToDecodeDelay * params->fetchWidth) + decodeWidth; 60} 61 62template <class Impl> 63std::string 64DefaultDecode<Impl>::name() const 65{ 66 return cpu->name() + ".decode"; 67} 68 69template <class Impl> 70void 71DefaultDecode<Impl>::regStats() 72{ 73 decodeIdleCycles 74 .name(name() + ".DECODE:IdleCycles") 75 .desc("Number of cycles decode is idle") 76 .prereq(decodeIdleCycles); 77 decodeBlockedCycles 78 .name(name() + ".DECODE:BlockedCycles") 79 .desc("Number of cycles decode is blocked") 80 .prereq(decodeBlockedCycles); 81 decodeRunCycles 82 .name(name() + ".DECODE:RunCycles") 83 .desc("Number of cycles decode is running") 84 .prereq(decodeRunCycles); 85 decodeUnblockCycles 86 .name(name() + ".DECODE:UnblockCycles") 87 .desc("Number of cycles decode is unblocking") 88 .prereq(decodeUnblockCycles); 89 decodeSquashCycles 90 .name(name() + ".DECODE:SquashCycles") 91 .desc("Number of cycles decode is squashing") 92 .prereq(decodeSquashCycles); 93 decodeBranchResolved 94 .name(name() + ".DECODE:BranchResolved") 95 .desc("Number of times decode resolved a branch") 96 .prereq(decodeBranchResolved); 97 decodeBranchMispred 98 .name(name() + ".DECODE:BranchMispred") 99 .desc("Number of times decode detected a branch misprediction") 100 .prereq(decodeBranchMispred); 101 decodeControlMispred 102 .name(name() + ".DECODE:ControlMispred") 103 .desc("Number of times decode detected an instruction incorrectly" 104 " predicted as a control") 105 .prereq(decodeControlMispred); 106 decodeDecodedInsts 107 .name(name() + ".DECODE:DecodedInsts") 108 .desc("Number of instructions handled by decode") 109 .prereq(decodeDecodedInsts); 110 decodeSquashedInsts 111 .name(name() + ".DECODE:SquashedInsts") 112 .desc("Number of squashed instructions handled by decode") 113 .prereq(decodeSquashedInsts); 114} 115 116template<class Impl> 117void 118DefaultDecode<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 119{ 120 timeBuffer = tb_ptr; 121 122 // Setup wire to write information back to fetch. 123 toFetch = timeBuffer->getWire(0); 124 125 // Create wires to get information from proper places in time buffer. 126 fromRename = timeBuffer->getWire(-renameToDecodeDelay); 127 fromIEW = timeBuffer->getWire(-iewToDecodeDelay); 128 fromCommit = timeBuffer->getWire(-commitToDecodeDelay); 129} 130 131template<class Impl> 132void 133DefaultDecode<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr) 134{ 135 decodeQueue = dq_ptr; 136 137 // Setup wire to write information to proper place in decode queue. 138 toRename = decodeQueue->getWire(0); 139} 140 141template<class Impl> 142void 143DefaultDecode<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr) 144{ 145 fetchQueue = fq_ptr; 146 147 // Setup wire to read information from fetch queue. 148 fromFetch = fetchQueue->getWire(-fetchToDecodeDelay); 149} 150 151template<class Impl> 152void 153DefaultDecode<Impl>::setActiveThreads(std::list<ThreadID> *at_ptr) 154{ 155 activeThreads = at_ptr; 156} 157 158template <class Impl> 159bool 160DefaultDecode<Impl>::drain() 161{ 162 // Decode is done draining at any time. 163 cpu->signalDrained(); 164 return true; 165} 166 167template <class Impl> 168void 169DefaultDecode<Impl>::takeOverFrom() 170{ 171 _status = Inactive; 172 173 // Be sure to reset state and clear out any old instructions. 174 for (ThreadID tid = 0; tid < numThreads; ++tid) { 175 decodeStatus[tid] = Idle; 176 177 stalls[tid].rename = false; 178 stalls[tid].iew = false; 179 stalls[tid].commit = false; 180 while (!insts[tid].empty()) 181 insts[tid].pop(); 182 while (!skidBuffer[tid].empty()) 183 skidBuffer[tid].pop(); 184 branchCount[tid] = 0; 185 } 186 wroteToTimeBuffer = false; 187} 188 189template<class Impl> 190bool 191DefaultDecode<Impl>::checkStall(ThreadID tid) const 192{ 193 bool ret_val = false; 194 195 if (stalls[tid].rename) { 196 DPRINTF(Decode,"[tid:%i]: Stall fom Rename stage detected.\n", tid); 197 ret_val = true; 198 } else if (stalls[tid].iew) { 199 DPRINTF(Decode,"[tid:%i]: Stall fom IEW stage detected.\n", tid); 200 ret_val = true; 201 } else if (stalls[tid].commit) { 202 DPRINTF(Decode,"[tid:%i]: Stall fom Commit stage detected.\n", tid); 203 ret_val = true; 204 } 205 206 return ret_val; 207} 208 209template<class Impl> 210inline bool 211DefaultDecode<Impl>::fetchInstsValid() 212{ 213 return fromFetch->size > 0; 214} 215 216template<class Impl> 217bool 218DefaultDecode<Impl>::block(ThreadID tid) 219{ 220 DPRINTF(Decode, "[tid:%u]: Blocking.\n", tid); 221 222 // Add the current inputs to the skid buffer so they can be 223 // reprocessed when this stage unblocks. 224 skidInsert(tid); 225 226 // If the decode status is blocked or unblocking then decode has not yet 227 // signalled fetch to unblock. In that case, there is no need to tell 228 // fetch to block. 229 if (decodeStatus[tid] != Blocked) { 230 // Set the status to Blocked. 231 decodeStatus[tid] = Blocked; 232 233 if (decodeStatus[tid] != Unblocking) { 234 toFetch->decodeBlock[tid] = true; 235 wroteToTimeBuffer = true; 236 } 237 238 return true; 239 } 240 241 return false; 242} 243 244template<class Impl> 245bool 246DefaultDecode<Impl>::unblock(ThreadID tid) 247{ 248 // Decode is done unblocking only if the skid buffer is empty. 249 if (skidBuffer[tid].empty()) { 250 DPRINTF(Decode, "[tid:%u]: Done unblocking.\n", tid); 251 toFetch->decodeUnblock[tid] = true; 252 wroteToTimeBuffer = true; 253 254 decodeStatus[tid] = Running; 255 return true; 256 } 257 258 DPRINTF(Decode, "[tid:%u]: Currently unblocking.\n", tid); 259 260 return false; 261} 262 263template<class Impl> 264void 265DefaultDecode<Impl>::squash(DynInstPtr &inst, ThreadID tid) 266{ 267 DPRINTF(Decode, "[tid:%i]: [sn:%i] Squashing due to incorrect branch prediction " 268 "detected at decode.\n", tid, inst->seqNum); 269 270 // Send back mispredict information. 271 toFetch->decodeInfo[tid].branchMispredict = true; 272 toFetch->decodeInfo[tid].predIncorrect = true; 273 toFetch->decodeInfo[tid].squash = true; 274 toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum; 275 toFetch->decodeInfo[tid].nextMicroPC = inst->readMicroPC(); 276 277#if ISA_HAS_DELAY_SLOT 278 toFetch->decodeInfo[tid].nextPC = inst->readPC() + sizeof(TheISA::MachInst); 279 toFetch->decodeInfo[tid].nextNPC = inst->branchTarget(); 280 toFetch->decodeInfo[tid].branchTaken = inst->readNextNPC() != 281 (inst->readNextPC() + sizeof(TheISA::MachInst)); 282#else 283 toFetch->decodeInfo[tid].nextPC = inst->branchTarget(); 284 toFetch->decodeInfo[tid].nextNPC = 285 inst->branchTarget() + sizeof(TheISA::MachInst); 286 toFetch->decodeInfo[tid].branchTaken = 287 inst->readNextPC() != (inst->readPC() + sizeof(TheISA::MachInst)); 288#endif 289 290 291 InstSeqNum squash_seq_num = inst->seqNum; 292 293 // Might have to tell fetch to unblock. 294 if (decodeStatus[tid] == Blocked || 295 decodeStatus[tid] == Unblocking) { 296 toFetch->decodeUnblock[tid] = 1; 297 } 298 299 // Set status to squashing. 300 decodeStatus[tid] = Squashing; 301 302 for (int i=0; i<fromFetch->size; i++) { 303 if (fromFetch->insts[i]->threadNumber == tid && 304 fromFetch->insts[i]->seqNum > squash_seq_num) { 305 fromFetch->insts[i]->setSquashed(); 306 } 307 } 308 309 // Clear the instruction list and skid buffer in case they have any 310 // insts in them. 311 while (!insts[tid].empty()) { 312 insts[tid].pop(); 313 } 314 315 while (!skidBuffer[tid].empty()) { 316 skidBuffer[tid].pop(); 317 } 318 319 // Squash instructions up until this one 320 cpu->removeInstsUntil(squash_seq_num, tid); 321} 322 323template<class Impl> 324unsigned 325DefaultDecode<Impl>::squash(ThreadID tid) 326{ 327 DPRINTF(Decode, "[tid:%i]: Squashing.\n",tid); 328 329 if (decodeStatus[tid] == Blocked || 330 decodeStatus[tid] == Unblocking) { 331#if !FULL_SYSTEM 332 // In syscall emulation, we can have both a block and a squash due 333 // to a syscall in the same cycle. This would cause both signals to 334 // be high. This shouldn't happen in full system. 335 // @todo: Determine if this still happens. 336 if (toFetch->decodeBlock[tid]) { 337 toFetch->decodeBlock[tid] = 0; 338 } else { 339 toFetch->decodeUnblock[tid] = 1; 340 } 341#else 342 toFetch->decodeUnblock[tid] = 1; 343#endif 344 } 345 346 // Set status to squashing. 347 decodeStatus[tid] = Squashing; 348 349 // Go through incoming instructions from fetch and squash them. 350 unsigned squash_count = 0; 351 352 for (int i=0; i<fromFetch->size; i++) { 353 if (fromFetch->insts[i]->threadNumber == tid) { 354 fromFetch->insts[i]->setSquashed(); 355 squash_count++; 356 } 357 } 358 359 // Clear the instruction list and skid buffer in case they have any 360 // insts in them. 361 while (!insts[tid].empty()) { 362 insts[tid].pop(); 363 } 364 365 while (!skidBuffer[tid].empty()) { 366 skidBuffer[tid].pop(); 367 } 368 369 return squash_count; 370} 371 372template<class Impl> 373void 374DefaultDecode<Impl>::skidInsert(ThreadID tid) 375{ 376 DynInstPtr inst = NULL; 377 378 while (!insts[tid].empty()) { 379 inst = insts[tid].front(); 380 381 insts[tid].pop(); 382 383 assert(tid == inst->threadNumber); 384 385 DPRINTF(Decode,"Inserting [sn:%lli] PC:%#x into decode skidBuffer %i\n", 386 inst->seqNum, inst->readPC(), inst->threadNumber); 387 388 skidBuffer[tid].push(inst); 389 } 390 391 // @todo: Eventually need to enforce this by not letting a thread 392 // fetch past its skidbuffer 393 assert(skidBuffer[tid].size() <= skidBufferMax); 394} 395 396template<class Impl> 397bool 398DefaultDecode<Impl>::skidsEmpty() 399{ 400 list<ThreadID>::iterator threads = activeThreads->begin(); 401 list<ThreadID>::iterator end = activeThreads->end(); 402 403 while (threads != end) { 404 ThreadID tid = *threads++; 405 if (!skidBuffer[tid].empty()) 406 return false; 407 } 408 409 return true; 410} 411 412template<class Impl> 413void 414DefaultDecode<Impl>::updateStatus() 415{ 416 bool any_unblocking = false; 417 418 list<ThreadID>::iterator threads = activeThreads->begin(); 419 list<ThreadID>::iterator end = activeThreads->end(); 420 421 while (threads != end) { 422 ThreadID tid = *threads++; 423 424 if (decodeStatus[tid] == Unblocking) { 425 any_unblocking = true; 426 break; 427 } 428 } 429 430 // Decode will have activity if it's unblocking. 431 if (any_unblocking) { 432 if (_status == Inactive) { 433 _status = Active; 434 435 DPRINTF(Activity, "Activating stage.\n"); 436 437 cpu->activateStage(O3CPU::DecodeIdx); 438 } 439 } else { 440 // If it's not unblocking, then decode will not have any internal 441 // activity. Switch it to inactive. 442 if (_status == Active) { 443 _status = Inactive; 444 DPRINTF(Activity, "Deactivating stage.\n"); 445 446 cpu->deactivateStage(O3CPU::DecodeIdx); 447 } 448 } 449} 450 451template <class Impl> 452void 453DefaultDecode<Impl>::sortInsts() 454{ 455 int insts_from_fetch = fromFetch->size; 456#ifdef DEBUG 457 for (ThreadID tid = 0; tid < numThreads; tid++) 458 assert(insts[tid].empty()); 459#endif 460 for (int i = 0; i < insts_from_fetch; ++i) { 461 insts[fromFetch->insts[i]->threadNumber].push(fromFetch->insts[i]); 462 } 463} 464 465template<class Impl> 466void 467DefaultDecode<Impl>::readStallSignals(ThreadID tid) 468{ 469 if (fromRename->renameBlock[tid]) { 470 stalls[tid].rename = true; 471 } 472 473 if (fromRename->renameUnblock[tid]) { 474 assert(stalls[tid].rename); 475 stalls[tid].rename = false; 476 } 477 478 if (fromIEW->iewBlock[tid]) { 479 stalls[tid].iew = true; 480 } 481 482 if (fromIEW->iewUnblock[tid]) { 483 assert(stalls[tid].iew); 484 stalls[tid].iew = false; 485 } 486 487 if (fromCommit->commitBlock[tid]) { 488 stalls[tid].commit = true; 489 } 490 491 if (fromCommit->commitUnblock[tid]) { 492 assert(stalls[tid].commit); 493 stalls[tid].commit = false; 494 } 495} 496 497template <class Impl> 498bool 499DefaultDecode<Impl>::checkSignalsAndUpdate(ThreadID tid) 500{ 501 // Check if there's a squash signal, squash if there is. 502 // Check stall signals, block if necessary. 503 // If status was blocked 504 // Check if stall conditions have passed 505 // if so then go to unblocking 506 // If status was Squashing 507 // check if squashing is not high. Switch to running this cycle. 508 509 // Update the per thread stall statuses. 510 readStallSignals(tid); 511 512 // Check squash signals from commit. 513 if (fromCommit->commitInfo[tid].squash) { 514 515 DPRINTF(Decode, "[tid:%u]: Squashing instructions due to squash " 516 "from commit.\n", tid); 517 518 squash(tid); 519 520 return true; 521 } 522 523 // Check ROB squash signals from commit. 524 if (fromCommit->commitInfo[tid].robSquashing) { 525 DPRINTF(Decode, "[tid:%u]: ROB is still squashing.\n", tid); 526 527 // Continue to squash. 528 decodeStatus[tid] = Squashing; 529 530 return true; 531 } 532 533 if (checkStall(tid)) { 534 return block(tid); 535 } 536 537 if (decodeStatus[tid] == Blocked) { 538 DPRINTF(Decode, "[tid:%u]: Done blocking, switching to unblocking.\n", 539 tid); 540 541 decodeStatus[tid] = Unblocking; 542 543 unblock(tid); 544 545 return true; 546 } 547 548 if (decodeStatus[tid] == Squashing) { 549 // Switch status to running if decode isn't being told to block or 550 // squash this cycle. 551 DPRINTF(Decode, "[tid:%u]: Done squashing, switching to running.\n", 552 tid); 553 554 decodeStatus[tid] = Running; 555 556 return false; 557 } 558 559 // If we've reached this point, we have not gotten any signals that 560 // cause decode to change its status. Decode remains the same as before. 561 return false; 562} 563 564template<class Impl> 565void 566DefaultDecode<Impl>::tick() 567{ 568 wroteToTimeBuffer = false; 569 570 bool status_change = false; 571 572 toRenameIndex = 0; 573 574 list<ThreadID>::iterator threads = activeThreads->begin(); 575 list<ThreadID>::iterator end = activeThreads->end(); 576 577 sortInsts(); 578 579 //Check stall and squash signals. 580 while (threads != end) { 581 ThreadID tid = *threads++; 582 583 DPRINTF(Decode,"Processing [tid:%i]\n",tid); 584 status_change = checkSignalsAndUpdate(tid) || status_change; 585 586 decode(status_change, tid); 587 } 588 589 if (status_change) { 590 updateStatus(); 591 } 592 593 if (wroteToTimeBuffer) { 594 DPRINTF(Activity, "Activity this cycle.\n"); 595 596 cpu->activityThisCycle(); 597 } 598} 599 600template<class Impl> 601void 602DefaultDecode<Impl>::decode(bool &status_change, ThreadID tid) 603{ 604 // If status is Running or idle, 605 // call decodeInsts() 606 // If status is Unblocking, 607 // buffer any instructions coming from fetch 608 // continue trying to empty skid buffer 609 // check if stall conditions have passed 610 611 if (decodeStatus[tid] == Blocked) { 612 ++decodeBlockedCycles; 613 } else if (decodeStatus[tid] == Squashing) { 614 ++decodeSquashCycles; 615 } 616 617 // Decode should try to decode as many instructions as its bandwidth 618 // will allow, as long as it is not currently blocked. 619 if (decodeStatus[tid] == Running || 620 decodeStatus[tid] == Idle) { 621 DPRINTF(Decode, "[tid:%u]: Not blocked, so attempting to run " 622 "stage.\n",tid); 623 624 decodeInsts(tid); 625 } else if (decodeStatus[tid] == Unblocking) { 626 // Make sure that the skid buffer has something in it if the 627 // status is unblocking. 628 assert(!skidsEmpty()); 629 630 // If the status was unblocking, then instructions from the skid 631 // buffer were used. Remove those instructions and handle 632 // the rest of unblocking. 633 decodeInsts(tid); 634 635 if (fetchInstsValid()) { 636 // Add the current inputs to the skid buffer so they can be 637 // reprocessed when this stage unblocks. 638 skidInsert(tid); 639 } 640 641 status_change = unblock(tid) || status_change; 642 } 643} 644 645template <class Impl> 646void 647DefaultDecode<Impl>::decodeInsts(ThreadID tid) 648{ 649 // Instructions can come either from the skid buffer or the list of 650 // instructions coming from fetch, depending on decode's status. 651 int insts_available = decodeStatus[tid] == Unblocking ? 652 skidBuffer[tid].size() : insts[tid].size(); 653 654 if (insts_available == 0) { 655 DPRINTF(Decode, "[tid:%u] Nothing to do, breaking out" 656 " early.\n",tid); 657 // Should I change the status to idle? 658 ++decodeIdleCycles; 659 return; 660 } else if (decodeStatus[tid] == Unblocking) { 661 DPRINTF(Decode, "[tid:%u] Unblocking, removing insts from skid " 662 "buffer.\n",tid); 663 ++decodeUnblockCycles; 664 } else if (decodeStatus[tid] == Running) { 665 ++decodeRunCycles; 666 } 667 668 DynInstPtr inst; 669 670 std::queue<DynInstPtr> 671 &insts_to_decode = decodeStatus[tid] == Unblocking ? 672 skidBuffer[tid] : insts[tid]; 673 674 DPRINTF(Decode, "[tid:%u]: Sending instruction to rename.\n",tid); 675 676 while (insts_available > 0 && toRenameIndex < decodeWidth) { 677 assert(!insts_to_decode.empty()); 678 679 inst = insts_to_decode.front(); 680 681 insts_to_decode.pop(); 682 683 DPRINTF(Decode, "[tid:%u]: Processing instruction [sn:%lli] with " 684 "PC %#x\n", 685 tid, inst->seqNum, inst->readPC()); 686 687 if (inst->isSquashed()) { 688 DPRINTF(Decode, "[tid:%u]: Instruction %i with PC %#x is " 689 "squashed, skipping.\n", 690 tid, inst->seqNum, inst->readPC()); 691 692 ++decodeSquashedInsts; 693 694 --insts_available; 695 696 continue; 697 } 698 699 // Also check if instructions have no source registers. Mark 700 // them as ready to issue at any time. Not sure if this check 701 // should exist here or at a later stage; however it doesn't matter 702 // too much for function correctness. 703 if (inst->numSrcRegs() == 0) { 704 inst->setCanIssue(); 705 } 706 707 // This current instruction is valid, so add it into the decode 708 // queue. The next instruction may not be valid, so check to 709 // see if branches were predicted correctly. 710 toRename->insts[toRenameIndex] = inst; 711 712 ++(toRename->size); 713 ++toRenameIndex; 714 ++decodeDecodedInsts; 715 --insts_available; 716 717 // Ensure that if it was predicted as a branch, it really is a 718 // branch. 719 if (inst->readPredTaken() && !inst->isControl()) { 720 DPRINTF(Decode, "PredPC : %#x != NextPC: %#x\n", 721 inst->readPredPC(), inst->readNextPC() + 4); 722 723 panic("Instruction predicted as a branch!"); 724 725 ++decodeControlMispred; 726 727 // Might want to set some sort of boolean and just do 728 // a check at the end 729 squash(inst, inst->threadNumber); 730 731 break; 732 } 733 734 // Go ahead and compute any PC-relative branches. 735 if (inst->isDirectCtrl() && inst->isUncondCtrl()) { 736 ++decodeBranchResolved; 737 738 if (inst->branchTarget() != inst->readPredPC()) { 739 ++decodeBranchMispred; 740 741 // Might want to set some sort of boolean and just do 742 // a check at the end 743 squash(inst, inst->threadNumber); 744 Addr target = inst->branchTarget(); 745 746#if ISA_HAS_DELAY_SLOT 747 DPRINTF(Decode, "[sn:%i]: Updating predictions: PredPC: %#x PredNextPC: %#x\n", 748 inst->seqNum, inst->readPC() + sizeof(TheISA::MachInst), target); 749 750 //The micro pc after an instruction level branch should be 0 751 inst->setPredTarg(inst->readPC() + sizeof(TheISA::MachInst), target, 0); 752#else 753 DPRINTF(Decode, "[sn:%i]: Updating predictions: PredPC: %#x PredNextPC: %#x\n", 754 inst->seqNum, target, target + sizeof(TheISA::MachInst)); 755 //The micro pc after an instruction level branch should be 0 756 inst->setPredTarg(target, target + sizeof(TheISA::MachInst), 0); 757#endif 758 break; 759 } 760 } 761 } 762 763 // If we didn't process all instructions, then we will need to block 764 // and put all those instructions into the skid buffer. 765 if (!insts_to_decode.empty()) { 766 block(tid); 767 } 768 769 // Record that decode has written to the time buffer for activity 770 // tracking. 771 if (toRenameIndex) { 772 wroteToTimeBuffer = true; 773 } 774} 775