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 ---