decode_impl.hh (13641:648f3106ebdf) | decode_impl.hh (13831:4fba790d88be) |
---|---|
1/* 2 * Copyright (c) 2012, 2014 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 224 unchanged lines hidden (view full) --- 233 234template<class Impl> 235bool 236DefaultDecode<Impl>::checkStall(ThreadID tid) const 237{ 238 bool ret_val = false; 239 240 if (stalls[tid].rename) { | 1/* 2 * Copyright (c) 2012, 2014 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 224 unchanged lines hidden (view full) --- 233 234template<class Impl> 235bool 236DefaultDecode<Impl>::checkStall(ThreadID tid) const 237{ 238 bool ret_val = false; 239 240 if (stalls[tid].rename) { |
241 DPRINTF(Decode,"[tid:%i]: Stall fom Rename stage detected.\n", tid); | 241 DPRINTF(Decode,"[tid:%i] Stall fom Rename stage detected.\n", tid); |
242 ret_val = true; 243 } 244 245 return ret_val; 246} 247 248template<class Impl> 249inline bool 250DefaultDecode<Impl>::fetchInstsValid() 251{ 252 return fromFetch->size > 0; 253} 254 255template<class Impl> 256bool 257DefaultDecode<Impl>::block(ThreadID tid) 258{ | 242 ret_val = true; 243 } 244 245 return ret_val; 246} 247 248template<class Impl> 249inline bool 250DefaultDecode<Impl>::fetchInstsValid() 251{ 252 return fromFetch->size > 0; 253} 254 255template<class Impl> 256bool 257DefaultDecode<Impl>::block(ThreadID tid) 258{ |
259 DPRINTF(Decode, "[tid:%u]: Blocking.\n", tid); | 259 DPRINTF(Decode, "[tid:%i] Blocking.\n", tid); |
260 261 // Add the current inputs to the skid buffer so they can be 262 // reprocessed when this stage unblocks. 263 skidInsert(tid); 264 265 // If the decode status is blocked or unblocking then decode has not yet 266 // signalled fetch to unblock. In that case, there is no need to tell 267 // fetch to block. --- 15 unchanged lines hidden (view full) --- 283} 284 285template<class Impl> 286bool 287DefaultDecode<Impl>::unblock(ThreadID tid) 288{ 289 // Decode is done unblocking only if the skid buffer is empty. 290 if (skidBuffer[tid].empty()) { | 260 261 // Add the current inputs to the skid buffer so they can be 262 // reprocessed when this stage unblocks. 263 skidInsert(tid); 264 265 // If the decode status is blocked or unblocking then decode has not yet 266 // signalled fetch to unblock. In that case, there is no need to tell 267 // fetch to block. --- 15 unchanged lines hidden (view full) --- 283} 284 285template<class Impl> 286bool 287DefaultDecode<Impl>::unblock(ThreadID tid) 288{ 289 // Decode is done unblocking only if the skid buffer is empty. 290 if (skidBuffer[tid].empty()) { |
291 DPRINTF(Decode, "[tid:%u]: Done unblocking.\n", tid); | 291 DPRINTF(Decode, "[tid:%i] Done unblocking.\n", tid); |
292 toFetch->decodeUnblock[tid] = true; 293 wroteToTimeBuffer = true; 294 295 decodeStatus[tid] = Running; 296 return true; 297 } 298 | 292 toFetch->decodeUnblock[tid] = true; 293 wroteToTimeBuffer = true; 294 295 decodeStatus[tid] = Running; 296 return true; 297 } 298 |
299 DPRINTF(Decode, "[tid:%u]: Currently unblocking.\n", tid); | 299 DPRINTF(Decode, "[tid:%i] Currently unblocking.\n", tid); |
300 301 return false; 302} 303 304template<class Impl> 305void 306DefaultDecode<Impl>::squash(const DynInstPtr &inst, ThreadID tid) 307{ | 300 301 return false; 302} 303 304template<class Impl> 305void 306DefaultDecode<Impl>::squash(const DynInstPtr &inst, ThreadID tid) 307{ |
308 DPRINTF(Decode, "[tid:%i]: [sn:%i] Squashing due to incorrect branch " | 308 DPRINTF(Decode, "[tid:%i] [sn:%llu] Squashing due to incorrect branch " |
309 "prediction detected at decode.\n", tid, inst->seqNum); 310 311 // Send back mispredict information. 312 toFetch->decodeInfo[tid].branchMispredict = true; 313 toFetch->decodeInfo[tid].predIncorrect = true; 314 toFetch->decodeInfo[tid].mispredictInst = inst; 315 toFetch->decodeInfo[tid].squash = true; 316 toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum; --- 35 unchanged lines hidden (view full) --- 352 // Squash instructions up until this one 353 cpu->removeInstsUntil(squash_seq_num, tid); 354} 355 356template<class Impl> 357unsigned 358DefaultDecode<Impl>::squash(ThreadID tid) 359{ | 309 "prediction detected at decode.\n", tid, inst->seqNum); 310 311 // Send back mispredict information. 312 toFetch->decodeInfo[tid].branchMispredict = true; 313 toFetch->decodeInfo[tid].predIncorrect = true; 314 toFetch->decodeInfo[tid].mispredictInst = inst; 315 toFetch->decodeInfo[tid].squash = true; 316 toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum; --- 35 unchanged lines hidden (view full) --- 352 // Squash instructions up until this one 353 cpu->removeInstsUntil(squash_seq_num, tid); 354} 355 356template<class Impl> 357unsigned 358DefaultDecode<Impl>::squash(ThreadID tid) 359{ |
360 DPRINTF(Decode, "[tid:%i]: Squashing.\n",tid); | 360 DPRINTF(Decode, "[tid:%i] Squashing.\n",tid); |
361 362 if (decodeStatus[tid] == Blocked || 363 decodeStatus[tid] == Unblocking) { 364 if (FullSystem) { 365 toFetch->decodeUnblock[tid] = 1; 366 } else { 367 // In syscall emulation, we can have both a block and a squash due 368 // to a syscall in the same cycle. This would cause both signals --- 148 unchanged lines hidden (view full) --- 517 // check if squashing is not high. Switch to running this cycle. 518 519 // Update the per thread stall statuses. 520 readStallSignals(tid); 521 522 // Check squash signals from commit. 523 if (fromCommit->commitInfo[tid].squash) { 524 | 361 362 if (decodeStatus[tid] == Blocked || 363 decodeStatus[tid] == Unblocking) { 364 if (FullSystem) { 365 toFetch->decodeUnblock[tid] = 1; 366 } else { 367 // In syscall emulation, we can have both a block and a squash due 368 // to a syscall in the same cycle. This would cause both signals --- 148 unchanged lines hidden (view full) --- 517 // check if squashing is not high. Switch to running this cycle. 518 519 // Update the per thread stall statuses. 520 readStallSignals(tid); 521 522 // Check squash signals from commit. 523 if (fromCommit->commitInfo[tid].squash) { 524 |
525 DPRINTF(Decode, "[tid:%u]: Squashing instructions due to squash " | 525 DPRINTF(Decode, "[tid:%i] Squashing instructions due to squash " |
526 "from commit.\n", tid); 527 528 squash(tid); 529 530 return true; 531 } 532 533 if (checkStall(tid)) { 534 return block(tid); 535 } 536 537 if (decodeStatus[tid] == Blocked) { | 526 "from commit.\n", tid); 527 528 squash(tid); 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", | 538 DPRINTF(Decode, "[tid:%i] 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. | 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", | 551 DPRINTF(Decode, "[tid:%i] 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 --- 53 unchanged lines hidden (view full) --- 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) { | 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 --- 53 unchanged lines hidden (view full) --- 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 " | 621 DPRINTF(Decode, "[tid:%i] 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 --- 17 unchanged lines hidden (view full) --- 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) { | 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 --- 17 unchanged lines hidden (view full) --- 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" | 655 DPRINTF(Decode, "[tid:%i] 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) { | 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 " | 661 DPRINTF(Decode, "[tid:%i] Unblocking, removing insts from skid " |
662 "buffer.\n",tid); 663 ++decodeUnblockCycles; 664 } else if (decodeStatus[tid] == Running) { 665 ++decodeRunCycles; 666 } 667 668 std::queue<DynInstPtr> 669 &insts_to_decode = decodeStatus[tid] == Unblocking ? 670 skidBuffer[tid] : insts[tid]; 671 | 662 "buffer.\n",tid); 663 ++decodeUnblockCycles; 664 } else if (decodeStatus[tid] == Running) { 665 ++decodeRunCycles; 666 } 667 668 std::queue<DynInstPtr> 669 &insts_to_decode = decodeStatus[tid] == Unblocking ? 670 skidBuffer[tid] : insts[tid]; 671 |
672 DPRINTF(Decode, "[tid:%u]: Sending instruction to rename.\n",tid); | 672 DPRINTF(Decode, "[tid:%i] Sending instruction to rename.\n",tid); |
673 674 while (insts_available > 0 && toRenameIndex < decodeWidth) { 675 assert(!insts_to_decode.empty()); 676 677 DynInstPtr inst = std::move(insts_to_decode.front()); 678 679 insts_to_decode.pop(); 680 | 673 674 while (insts_available > 0 && toRenameIndex < decodeWidth) { 675 assert(!insts_to_decode.empty()); 676 677 DynInstPtr inst = std::move(insts_to_decode.front()); 678 679 insts_to_decode.pop(); 680 |
681 DPRINTF(Decode, "[tid:%u]: Processing instruction [sn:%lli] with " | 681 DPRINTF(Decode, "[tid:%i] Processing instruction [sn:%lli] with " |
682 "PC %s\n", tid, inst->seqNum, inst->pcState()); 683 684 if (inst->isSquashed()) { | 682 "PC %s\n", tid, inst->seqNum, inst->pcState()); 683 684 if (inst->isSquashed()) { |
685 DPRINTF(Decode, "[tid:%u]: Instruction %i with PC %s is " | 685 DPRINTF(Decode, "[tid:%i] Instruction %i with PC %s is " |
686 "squashed, skipping.\n", 687 tid, inst->seqNum, inst->pcState()); 688 689 ++decodeSquashedInsts; 690 691 --insts_available; 692 693 continue; --- 48 unchanged lines hidden (view full) --- 742 if (!(inst->branchTarget() == inst->readPredTarg())) { 743 ++decodeBranchMispred; 744 745 // Might want to set some sort of boolean and just do 746 // a check at the end 747 squash(inst, inst->threadNumber); 748 TheISA::PCState target = inst->branchTarget(); 749 | 686 "squashed, skipping.\n", 687 tid, inst->seqNum, inst->pcState()); 688 689 ++decodeSquashedInsts; 690 691 --insts_available; 692 693 continue; --- 48 unchanged lines hidden (view full) --- 742 if (!(inst->branchTarget() == inst->readPredTarg())) { 743 ++decodeBranchMispred; 744 745 // Might want to set some sort of boolean and just do 746 // a check at the end 747 squash(inst, inst->threadNumber); 748 TheISA::PCState target = inst->branchTarget(); 749 |
750 DPRINTF(Decode, "[sn:%i]: Updating predictions: PredPC: %s\n", 751 inst->seqNum, target); | 750 DPRINTF(Decode, 751 "[tid:%i] [sn:%llu] " 752 "Updating predictions: PredPC: %s\n", 753 tid, inst->seqNum, target); |
752 //The micro pc after an instruction level branch should be 0 753 inst->setPredTarg(target); 754 break; 755 } 756 } 757 } 758 759 // If we didn't process all instructions, then we will need to block --- 13 unchanged lines hidden --- | 754 //The micro pc after an instruction level branch should be 0 755 inst->setPredTarg(target); 756 break; 757 } 758 } 759 } 760 761 // If we didn't process all instructions, then we will need to block --- 13 unchanged lines hidden --- |