commit_impl.hh revision 13831:4fba790d88be
1/*
2 * Copyright 2014 Google, Inc.
3 * Copyright (c) 2010-2014, 2017 ARM Limited
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder.  You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2004-2006 The Regents of The University of Michigan
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Kevin Lim
42 *          Korey Sewell
43 */
44#ifndef __CPU_O3_COMMIT_IMPL_HH__
45#define __CPU_O3_COMMIT_IMPL_HH__
46
47#include <algorithm>
48#include <set>
49#include <string>
50
51#include "arch/utility.hh"
52#include "base/cp_annotate.hh"
53#include "base/loader/symtab.hh"
54#include "base/logging.hh"
55#include "config/the_isa.hh"
56#include "cpu/checker/cpu.hh"
57#include "cpu/o3/commit.hh"
58#include "cpu/o3/thread_state.hh"
59#include "cpu/base.hh"
60#include "cpu/exetrace.hh"
61#include "cpu/timebuf.hh"
62#include "debug/Activity.hh"
63#include "debug/Commit.hh"
64#include "debug/CommitRate.hh"
65#include "debug/Drain.hh"
66#include "debug/ExecFaulting.hh"
67#include "debug/O3PipeView.hh"
68#include "params/DerivO3CPU.hh"
69#include "sim/faults.hh"
70#include "sim/full_system.hh"
71
72using namespace std;
73
74template <class Impl>
75void
76DefaultCommit<Impl>::processTrapEvent(ThreadID tid)
77{
78    // This will get reset by commit if it was switched out at the
79    // time of this event processing.
80    trapSquash[tid] = true;
81}
82
83template <class Impl>
84DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params)
85    : commitPolicy(params->smtCommitPolicy),
86      cpu(_cpu),
87      iewToCommitDelay(params->iewToCommitDelay),
88      commitToIEWDelay(params->commitToIEWDelay),
89      renameToROBDelay(params->renameToROBDelay),
90      fetchToCommitDelay(params->commitToFetchDelay),
91      renameWidth(params->renameWidth),
92      commitWidth(params->commitWidth),
93      numThreads(params->numThreads),
94      drainPending(false),
95      drainImminent(false),
96      trapLatency(params->trapLatency),
97      canHandleInterrupts(true),
98      avoidQuiesceLiveLock(false)
99{
100    if (commitWidth > Impl::MaxWidth)
101        fatal("commitWidth (%d) is larger than compiled limit (%d),\n"
102             "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
103             commitWidth, static_cast<int>(Impl::MaxWidth));
104
105    _status = Active;
106    _nextStatus = Inactive;
107
108    if (commitPolicy == CommitPolicy::RoundRobin) {
109        //Set-Up Priority List
110        for (ThreadID tid = 0; tid < numThreads; tid++) {
111            priority_list.push_back(tid);
112        }
113    }
114
115    for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
116        commitStatus[tid] = Idle;
117        changedROBNumEntries[tid] = false;
118        trapSquash[tid] = false;
119        tcSquash[tid] = false;
120        squashAfterInst[tid] = nullptr;
121        pc[tid].set(0);
122        youngestSeqNum[tid] = 0;
123        lastCommitedSeqNum[tid] = 0;
124        trapInFlight[tid] = false;
125        committedStores[tid] = false;
126        checkEmptyROB[tid] = false;
127        renameMap[tid] = nullptr;
128    }
129    interrupt = NoFault;
130}
131
132template <class Impl>
133std::string
134DefaultCommit<Impl>::name() const
135{
136    return cpu->name() + ".commit";
137}
138
139template <class Impl>
140void
141DefaultCommit<Impl>::regProbePoints()
142{
143    ppCommit = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Commit");
144    ppCommitStall = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "CommitStall");
145    ppSquash = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Squash");
146}
147
148template <class Impl>
149void
150DefaultCommit<Impl>::regStats()
151{
152    using namespace Stats;
153    commitSquashedInsts
154        .name(name() + ".commitSquashedInsts")
155        .desc("The number of squashed insts skipped by commit")
156        .prereq(commitSquashedInsts);
157
158    commitNonSpecStalls
159        .name(name() + ".commitNonSpecStalls")
160        .desc("The number of times commit has been forced to stall to "
161              "communicate backwards")
162        .prereq(commitNonSpecStalls);
163
164    branchMispredicts
165        .name(name() + ".branchMispredicts")
166        .desc("The number of times a branch was mispredicted")
167        .prereq(branchMispredicts);
168
169    numCommittedDist
170        .init(0,commitWidth,1)
171        .name(name() + ".committed_per_cycle")
172        .desc("Number of insts commited each cycle")
173        .flags(Stats::pdf)
174        ;
175
176    instsCommitted
177        .init(cpu->numThreads)
178        .name(name() + ".committedInsts")
179        .desc("Number of instructions committed")
180        .flags(total)
181        ;
182
183    opsCommitted
184        .init(cpu->numThreads)
185        .name(name() + ".committedOps")
186        .desc("Number of ops (including micro ops) committed")
187        .flags(total)
188        ;
189
190    statComSwp
191        .init(cpu->numThreads)
192        .name(name() + ".swp_count")
193        .desc("Number of s/w prefetches committed")
194        .flags(total)
195        ;
196
197    statComRefs
198        .init(cpu->numThreads)
199        .name(name() +  ".refs")
200        .desc("Number of memory references committed")
201        .flags(total)
202        ;
203
204    statComLoads
205        .init(cpu->numThreads)
206        .name(name() +  ".loads")
207        .desc("Number of loads committed")
208        .flags(total)
209        ;
210
211    statComAmos
212        .init(cpu->numThreads)
213        .name(name() +  ".amos")
214        .desc("Number of atomic instructions committed")
215        .flags(total)
216        ;
217
218    statComMembars
219        .init(cpu->numThreads)
220        .name(name() +  ".membars")
221        .desc("Number of memory barriers committed")
222        .flags(total)
223        ;
224
225    statComBranches
226        .init(cpu->numThreads)
227        .name(name() + ".branches")
228        .desc("Number of branches committed")
229        .flags(total)
230        ;
231
232    statComFloating
233        .init(cpu->numThreads)
234        .name(name() + ".fp_insts")
235        .desc("Number of committed floating point instructions.")
236        .flags(total)
237        ;
238
239    statComVector
240        .init(cpu->numThreads)
241        .name(name() + ".vec_insts")
242        .desc("Number of committed Vector instructions.")
243        .flags(total)
244        ;
245
246    statComInteger
247        .init(cpu->numThreads)
248        .name(name()+".int_insts")
249        .desc("Number of committed integer instructions.")
250        .flags(total)
251        ;
252
253    statComFunctionCalls
254        .init(cpu->numThreads)
255        .name(name()+".function_calls")
256        .desc("Number of function calls committed.")
257        .flags(total)
258        ;
259
260    statCommittedInstType
261        .init(numThreads,Enums::Num_OpClass)
262        .name(name() + ".op_class")
263        .desc("Class of committed instruction")
264        .flags(total | pdf | dist)
265        ;
266    statCommittedInstType.ysubnames(Enums::OpClassStrings);
267
268    commitEligibleSamples
269        .name(name() + ".bw_lim_events")
270        .desc("number cycles where commit BW limit reached")
271        ;
272}
273
274template <class Impl>
275void
276DefaultCommit<Impl>::setThreads(std::vector<Thread *> &threads)
277{
278    thread = threads;
279}
280
281template <class Impl>
282void
283DefaultCommit<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
284{
285    timeBuffer = tb_ptr;
286
287    // Setup wire to send information back to IEW.
288    toIEW = timeBuffer->getWire(0);
289
290    // Setup wire to read data from IEW (for the ROB).
291    robInfoFromIEW = timeBuffer->getWire(-iewToCommitDelay);
292}
293
294template <class Impl>
295void
296DefaultCommit<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr)
297{
298    fetchQueue = fq_ptr;
299
300    // Setup wire to get instructions from rename (for the ROB).
301    fromFetch = fetchQueue->getWire(-fetchToCommitDelay);
302}
303
304template <class Impl>
305void
306DefaultCommit<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
307{
308    renameQueue = rq_ptr;
309
310    // Setup wire to get instructions from rename (for the ROB).
311    fromRename = renameQueue->getWire(-renameToROBDelay);
312}
313
314template <class Impl>
315void
316DefaultCommit<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr)
317{
318    iewQueue = iq_ptr;
319
320    // Setup wire to get instructions from IEW.
321    fromIEW = iewQueue->getWire(-iewToCommitDelay);
322}
323
324template <class Impl>
325void
326DefaultCommit<Impl>::setIEWStage(IEW *iew_stage)
327{
328    iewStage = iew_stage;
329}
330
331template<class Impl>
332void
333DefaultCommit<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
334{
335    activeThreads = at_ptr;
336}
337
338template <class Impl>
339void
340DefaultCommit<Impl>::setRenameMap(RenameMap rm_ptr[])
341{
342    for (ThreadID tid = 0; tid < numThreads; tid++)
343        renameMap[tid] = &rm_ptr[tid];
344}
345
346template <class Impl>
347void
348DefaultCommit<Impl>::setROB(ROB *rob_ptr)
349{
350    rob = rob_ptr;
351}
352
353template <class Impl>
354void
355DefaultCommit<Impl>::startupStage()
356{
357    rob->setActiveThreads(activeThreads);
358    rob->resetEntries();
359
360    // Broadcast the number of free entries.
361    for (ThreadID tid = 0; tid < numThreads; tid++) {
362        toIEW->commitInfo[tid].usedROB = true;
363        toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
364        toIEW->commitInfo[tid].emptyROB = true;
365    }
366
367    // Commit must broadcast the number of free entries it has at the
368    // start of the simulation, so it starts as active.
369    cpu->activateStage(O3CPU::CommitIdx);
370
371    cpu->activityThisCycle();
372}
373
374template <class Impl>
375void
376DefaultCommit<Impl>::clearStates(ThreadID tid)
377{
378    commitStatus[tid] = Idle;
379    changedROBNumEntries[tid] = false;
380    checkEmptyROB[tid] = false;
381    trapInFlight[tid] = false;
382    committedStores[tid] = false;
383    trapSquash[tid] = false;
384    tcSquash[tid] = false;
385    pc[tid].set(0);
386    lastCommitedSeqNum[tid] = 0;
387    squashAfterInst[tid] = NULL;
388}
389
390template <class Impl>
391void
392DefaultCommit<Impl>::drain()
393{
394    drainPending = true;
395}
396
397template <class Impl>
398void
399DefaultCommit<Impl>::drainResume()
400{
401    drainPending = false;
402    drainImminent = false;
403}
404
405template <class Impl>
406void
407DefaultCommit<Impl>::drainSanityCheck() const
408{
409    assert(isDrained());
410    rob->drainSanityCheck();
411}
412
413template <class Impl>
414bool
415DefaultCommit<Impl>::isDrained() const
416{
417    /* Make sure no one is executing microcode. There are two reasons
418     * for this:
419     * - Hardware virtualized CPUs can't switch into the middle of a
420     *   microcode sequence.
421     * - The current fetch implementation will most likely get very
422     *   confused if it tries to start fetching an instruction that
423     *   is executing in the middle of a ucode sequence that changes
424     *   address mappings. This can happen on for example x86.
425     */
426    for (ThreadID tid = 0; tid < numThreads; tid++) {
427        if (pc[tid].microPC() != 0)
428            return false;
429    }
430
431    /* Make sure that all instructions have finished committing before
432     * declaring the system as drained. We want the pipeline to be
433     * completely empty when we declare the CPU to be drained. This
434     * makes debugging easier since CPU handover and restoring from a
435     * checkpoint with a different CPU should have the same timing.
436     */
437    return rob->isEmpty() &&
438        interrupt == NoFault;
439}
440
441template <class Impl>
442void
443DefaultCommit<Impl>::takeOverFrom()
444{
445    _status = Active;
446    _nextStatus = Inactive;
447    for (ThreadID tid = 0; tid < numThreads; tid++) {
448        commitStatus[tid] = Idle;
449        changedROBNumEntries[tid] = false;
450        trapSquash[tid] = false;
451        tcSquash[tid] = false;
452        squashAfterInst[tid] = NULL;
453    }
454    rob->takeOverFrom();
455}
456
457template <class Impl>
458void
459DefaultCommit<Impl>::deactivateThread(ThreadID tid)
460{
461    list<ThreadID>::iterator thread_it = std::find(priority_list.begin(),
462            priority_list.end(), tid);
463
464    if (thread_it != priority_list.end()) {
465        priority_list.erase(thread_it);
466    }
467}
468
469
470template <class Impl>
471void
472DefaultCommit<Impl>::updateStatus()
473{
474    // reset ROB changed variable
475    list<ThreadID>::iterator threads = activeThreads->begin();
476    list<ThreadID>::iterator end = activeThreads->end();
477
478    while (threads != end) {
479        ThreadID tid = *threads++;
480
481        changedROBNumEntries[tid] = false;
482
483        // Also check if any of the threads has a trap pending
484        if (commitStatus[tid] == TrapPending ||
485            commitStatus[tid] == FetchTrapPending) {
486            _nextStatus = Active;
487        }
488    }
489
490    if (_nextStatus == Inactive && _status == Active) {
491        DPRINTF(Activity, "Deactivating stage.\n");
492        cpu->deactivateStage(O3CPU::CommitIdx);
493    } else if (_nextStatus == Active && _status == Inactive) {
494        DPRINTF(Activity, "Activating stage.\n");
495        cpu->activateStage(O3CPU::CommitIdx);
496    }
497
498    _status = _nextStatus;
499}
500
501template <class Impl>
502bool
503DefaultCommit<Impl>::changedROBEntries()
504{
505    list<ThreadID>::iterator threads = activeThreads->begin();
506    list<ThreadID>::iterator end = activeThreads->end();
507
508    while (threads != end) {
509        ThreadID tid = *threads++;
510
511        if (changedROBNumEntries[tid]) {
512            return true;
513        }
514    }
515
516    return false;
517}
518
519template <class Impl>
520size_t
521DefaultCommit<Impl>::numROBFreeEntries(ThreadID tid)
522{
523    return rob->numFreeEntries(tid);
524}
525
526template <class Impl>
527void
528DefaultCommit<Impl>::generateTrapEvent(ThreadID tid, Fault inst_fault)
529{
530    DPRINTF(Commit, "Generating trap event for [tid:%i]\n", tid);
531
532    EventFunctionWrapper *trap = new EventFunctionWrapper(
533        [this, tid]{ processTrapEvent(tid); },
534        "Trap", true, Event::CPU_Tick_Pri);
535
536    Cycles latency = dynamic_pointer_cast<SyscallRetryFault>(inst_fault) ?
537                     cpu->syscallRetryLatency : trapLatency;
538
539    cpu->schedule(trap, cpu->clockEdge(latency));
540    trapInFlight[tid] = true;
541    thread[tid]->trapPending = true;
542}
543
544template <class Impl>
545void
546DefaultCommit<Impl>::generateTCEvent(ThreadID tid)
547{
548    assert(!trapInFlight[tid]);
549    DPRINTF(Commit, "Generating TC squash event for [tid:%i]\n", tid);
550
551    tcSquash[tid] = true;
552}
553
554template <class Impl>
555void
556DefaultCommit<Impl>::squashAll(ThreadID tid)
557{
558    // If we want to include the squashing instruction in the squash,
559    // then use one older sequence number.
560    // Hopefully this doesn't mess things up.  Basically I want to squash
561    // all instructions of this thread.
562    InstSeqNum squashed_inst = rob->isEmpty(tid) ?
563        lastCommitedSeqNum[tid] : rob->readHeadInst(tid)->seqNum - 1;
564
565    // All younger instructions will be squashed. Set the sequence
566    // number as the youngest instruction in the ROB (0 in this case.
567    // Hopefully nothing breaks.)
568    youngestSeqNum[tid] = lastCommitedSeqNum[tid];
569
570    rob->squash(squashed_inst, tid);
571    changedROBNumEntries[tid] = true;
572
573    // Send back the sequence number of the squashed instruction.
574    toIEW->commitInfo[tid].doneSeqNum = squashed_inst;
575
576    // Send back the squash signal to tell stages that they should
577    // squash.
578    toIEW->commitInfo[tid].squash = true;
579
580    // Send back the rob squashing signal so other stages know that
581    // the ROB is in the process of squashing.
582    toIEW->commitInfo[tid].robSquashing = true;
583
584    toIEW->commitInfo[tid].mispredictInst = NULL;
585    toIEW->commitInfo[tid].squashInst = NULL;
586
587    toIEW->commitInfo[tid].pc = pc[tid];
588}
589
590template <class Impl>
591void
592DefaultCommit<Impl>::squashFromTrap(ThreadID tid)
593{
594    squashAll(tid);
595
596    DPRINTF(Commit, "Squashing from trap, restarting at PC %s\n", pc[tid]);
597
598    thread[tid]->trapPending = false;
599    thread[tid]->noSquashFromTC = false;
600    trapInFlight[tid] = false;
601
602    trapSquash[tid] = false;
603
604    commitStatus[tid] = ROBSquashing;
605    cpu->activityThisCycle();
606}
607
608template <class Impl>
609void
610DefaultCommit<Impl>::squashFromTC(ThreadID tid)
611{
612    squashAll(tid);
613
614    DPRINTF(Commit, "Squashing from TC, restarting at PC %s\n", pc[tid]);
615
616    thread[tid]->noSquashFromTC = false;
617    assert(!thread[tid]->trapPending);
618
619    commitStatus[tid] = ROBSquashing;
620    cpu->activityThisCycle();
621
622    tcSquash[tid] = false;
623}
624
625template <class Impl>
626void
627DefaultCommit<Impl>::squashFromSquashAfter(ThreadID tid)
628{
629    DPRINTF(Commit, "Squashing after squash after request, "
630            "restarting at PC %s\n", pc[tid]);
631
632    squashAll(tid);
633    // Make sure to inform the fetch stage of which instruction caused
634    // the squash. It'll try to re-fetch an instruction executing in
635    // microcode unless this is set.
636    toIEW->commitInfo[tid].squashInst = squashAfterInst[tid];
637    squashAfterInst[tid] = NULL;
638
639    commitStatus[tid] = ROBSquashing;
640    cpu->activityThisCycle();
641}
642
643template <class Impl>
644void
645DefaultCommit<Impl>::squashAfter(ThreadID tid, const DynInstPtr &head_inst)
646{
647    DPRINTF(Commit, "Executing squash after for [tid:%i] inst [sn:%llu]\n",
648            tid, head_inst->seqNum);
649
650    assert(!squashAfterInst[tid] || squashAfterInst[tid] == head_inst);
651    commitStatus[tid] = SquashAfterPending;
652    squashAfterInst[tid] = head_inst;
653}
654
655template <class Impl>
656void
657DefaultCommit<Impl>::tick()
658{
659    wroteToTimeBuffer = false;
660    _nextStatus = Inactive;
661
662    if (activeThreads->empty())
663        return;
664
665    list<ThreadID>::iterator threads = activeThreads->begin();
666    list<ThreadID>::iterator end = activeThreads->end();
667
668    // Check if any of the threads are done squashing.  Change the
669    // status if they are done.
670    while (threads != end) {
671        ThreadID tid = *threads++;
672
673        // Clear the bit saying if the thread has committed stores
674        // this cycle.
675        committedStores[tid] = false;
676
677        if (commitStatus[tid] == ROBSquashing) {
678
679            if (rob->isDoneSquashing(tid)) {
680                commitStatus[tid] = Running;
681            } else {
682                DPRINTF(Commit,"[tid:%i] Still Squashing, cannot commit any"
683                        " insts this cycle.\n", tid);
684                rob->doSquash(tid);
685                toIEW->commitInfo[tid].robSquashing = true;
686                wroteToTimeBuffer = true;
687            }
688        }
689    }
690
691    commit();
692
693    markCompletedInsts();
694
695    threads = activeThreads->begin();
696
697    while (threads != end) {
698        ThreadID tid = *threads++;
699
700        if (!rob->isEmpty(tid) && rob->readHeadInst(tid)->readyToCommit()) {
701            // The ROB has more instructions it can commit. Its next status
702            // will be active.
703            _nextStatus = Active;
704
705            const DynInstPtr &inst M5_VAR_USED = rob->readHeadInst(tid);
706
707            DPRINTF(Commit,"[tid:%i] Instruction [sn:%llu] PC %s is head of"
708                    " ROB and ready to commit\n",
709                    tid, inst->seqNum, inst->pcState());
710
711        } else if (!rob->isEmpty(tid)) {
712            const DynInstPtr &inst = rob->readHeadInst(tid);
713
714            ppCommitStall->notify(inst);
715
716            DPRINTF(Commit,"[tid:%i] Can't commit, Instruction [sn:%llu] PC "
717                    "%s is head of ROB and not ready\n",
718                    tid, inst->seqNum, inst->pcState());
719        }
720
721        DPRINTF(Commit, "[tid:%i] ROB has %d insts & %d free entries.\n",
722                tid, rob->countInsts(tid), rob->numFreeEntries(tid));
723    }
724
725
726    if (wroteToTimeBuffer) {
727        DPRINTF(Activity, "Activity This Cycle.\n");
728        cpu->activityThisCycle();
729    }
730
731    updateStatus();
732}
733
734template <class Impl>
735void
736DefaultCommit<Impl>::handleInterrupt()
737{
738    // Verify that we still have an interrupt to handle
739    if (!cpu->checkInterrupts(cpu->tcBase(0))) {
740        DPRINTF(Commit, "Pending interrupt is cleared by master before "
741                "it got handled. Restart fetching from the orig path.\n");
742        toIEW->commitInfo[0].clearInterrupt = true;
743        interrupt = NoFault;
744        avoidQuiesceLiveLock = true;
745        return;
746    }
747
748    // Wait until all in flight instructions are finished before enterring
749    // the interrupt.
750    if (canHandleInterrupts && cpu->instList.empty()) {
751        // Squash or record that I need to squash this cycle if
752        // an interrupt needed to be handled.
753        DPRINTF(Commit, "Interrupt detected.\n");
754
755        // Clear the interrupt now that it's going to be handled
756        toIEW->commitInfo[0].clearInterrupt = true;
757
758        assert(!thread[0]->noSquashFromTC);
759        thread[0]->noSquashFromTC = true;
760
761        if (cpu->checker) {
762            cpu->checker->handlePendingInt();
763        }
764
765        // CPU will handle interrupt. Note that we ignore the local copy of
766        // interrupt. This is because the local copy may no longer be the
767        // interrupt that the interrupt controller thinks is being handled.
768        cpu->processInterrupts(cpu->getInterrupts());
769
770        thread[0]->noSquashFromTC = false;
771
772        commitStatus[0] = TrapPending;
773
774        interrupt = NoFault;
775
776        // Generate trap squash event.
777        generateTrapEvent(0, interrupt);
778
779        avoidQuiesceLiveLock = false;
780    } else {
781        DPRINTF(Commit, "Interrupt pending: instruction is %sin "
782                "flight, ROB is %sempty\n",
783                canHandleInterrupts ? "not " : "",
784                cpu->instList.empty() ? "" : "not " );
785    }
786}
787
788template <class Impl>
789void
790DefaultCommit<Impl>::propagateInterrupt()
791{
792    // Don't propagate intterupts if we are currently handling a trap or
793    // in draining and the last observable instruction has been committed.
794    if (commitStatus[0] == TrapPending || interrupt || trapSquash[0] ||
795            tcSquash[0] || drainImminent)
796        return;
797
798    // Process interrupts if interrupts are enabled, not in PAL
799    // mode, and no other traps or external squashes are currently
800    // pending.
801    // @todo: Allow other threads to handle interrupts.
802
803    // Get any interrupt that happened
804    interrupt = cpu->getInterrupts();
805
806    // Tell fetch that there is an interrupt pending.  This
807    // will make fetch wait until it sees a non PAL-mode PC,
808    // at which point it stops fetching instructions.
809    if (interrupt != NoFault)
810        toIEW->commitInfo[0].interruptPending = true;
811}
812
813template <class Impl>
814void
815DefaultCommit<Impl>::commit()
816{
817    if (FullSystem) {
818        // Check if we have a interrupt and get read to handle it
819        if (cpu->checkInterrupts(cpu->tcBase(0)))
820            propagateInterrupt();
821    }
822
823    ////////////////////////////////////
824    // Check for any possible squashes, handle them first
825    ////////////////////////////////////
826    list<ThreadID>::iterator threads = activeThreads->begin();
827    list<ThreadID>::iterator end = activeThreads->end();
828
829    int num_squashing_threads = 0;
830
831    while (threads != end) {
832        ThreadID tid = *threads++;
833
834        // Not sure which one takes priority.  I think if we have
835        // both, that's a bad sign.
836        if (trapSquash[tid]) {
837            assert(!tcSquash[tid]);
838            squashFromTrap(tid);
839
840            // If the thread is trying to exit (i.e., an exit syscall was
841            // executed), this trapSquash was originated by the exit
842            // syscall earlier. In this case, schedule an exit event in
843            // the next cycle to fully terminate this thread
844            if (cpu->isThreadExiting(tid))
845                cpu->scheduleThreadExitEvent(tid);
846        } else if (tcSquash[tid]) {
847            assert(commitStatus[tid] != TrapPending);
848            squashFromTC(tid);
849        } else if (commitStatus[tid] == SquashAfterPending) {
850            // A squash from the previous cycle of the commit stage (i.e.,
851            // commitInsts() called squashAfter) is pending. Squash the
852            // thread now.
853            squashFromSquashAfter(tid);
854        }
855
856        // Squashed sequence number must be older than youngest valid
857        // instruction in the ROB. This prevents squashes from younger
858        // instructions overriding squashes from older instructions.
859        if (fromIEW->squash[tid] &&
860            commitStatus[tid] != TrapPending &&
861            fromIEW->squashedSeqNum[tid] <= youngestSeqNum[tid]) {
862
863            if (fromIEW->mispredictInst[tid]) {
864                DPRINTF(Commit,
865                    "[tid:%i] Squashing due to branch mispred "
866                    "PC:%#x [sn:%llu]\n",
867                    tid,
868                    fromIEW->mispredictInst[tid]->instAddr(),
869                    fromIEW->squashedSeqNum[tid]);
870            } else {
871                DPRINTF(Commit,
872                    "[tid:%i] Squashing due to order violation [sn:%llu]\n",
873                    tid, fromIEW->squashedSeqNum[tid]);
874            }
875
876            DPRINTF(Commit, "[tid:%i] Redirecting to PC %#x\n",
877                    tid,
878                    fromIEW->pc[tid].nextInstAddr());
879
880            commitStatus[tid] = ROBSquashing;
881
882            // If we want to include the squashing instruction in the squash,
883            // then use one older sequence number.
884            InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];
885
886            if (fromIEW->includeSquashInst[tid]) {
887                squashed_inst--;
888            }
889
890            // All younger instructions will be squashed. Set the sequence
891            // number as the youngest instruction in the ROB.
892            youngestSeqNum[tid] = squashed_inst;
893
894            rob->squash(squashed_inst, tid);
895            changedROBNumEntries[tid] = true;
896
897            toIEW->commitInfo[tid].doneSeqNum = squashed_inst;
898
899            toIEW->commitInfo[tid].squash = true;
900
901            // Send back the rob squashing signal so other stages know that
902            // the ROB is in the process of squashing.
903            toIEW->commitInfo[tid].robSquashing = true;
904
905            toIEW->commitInfo[tid].mispredictInst =
906                fromIEW->mispredictInst[tid];
907            toIEW->commitInfo[tid].branchTaken =
908                fromIEW->branchTaken[tid];
909            toIEW->commitInfo[tid].squashInst =
910                                    rob->findInst(tid, squashed_inst);
911            if (toIEW->commitInfo[tid].mispredictInst) {
912                if (toIEW->commitInfo[tid].mispredictInst->isUncondCtrl()) {
913                     toIEW->commitInfo[tid].branchTaken = true;
914                }
915                ++branchMispredicts;
916            }
917
918            toIEW->commitInfo[tid].pc = fromIEW->pc[tid];
919        }
920
921        if (commitStatus[tid] == ROBSquashing) {
922            num_squashing_threads++;
923        }
924    }
925
926    // If commit is currently squashing, then it will have activity for the
927    // next cycle. Set its next status as active.
928    if (num_squashing_threads) {
929        _nextStatus = Active;
930    }
931
932    if (num_squashing_threads != numThreads) {
933        // If we're not currently squashing, then get instructions.
934        getInsts();
935
936        // Try to commit any instructions.
937        commitInsts();
938    }
939
940    //Check for any activity
941    threads = activeThreads->begin();
942
943    while (threads != end) {
944        ThreadID tid = *threads++;
945
946        if (changedROBNumEntries[tid]) {
947            toIEW->commitInfo[tid].usedROB = true;
948            toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
949
950            wroteToTimeBuffer = true;
951            changedROBNumEntries[tid] = false;
952            if (rob->isEmpty(tid))
953                checkEmptyROB[tid] = true;
954        }
955
956        // ROB is only considered "empty" for previous stages if: a)
957        // ROB is empty, b) there are no outstanding stores, c) IEW
958        // stage has received any information regarding stores that
959        // committed.
960        // c) is checked by making sure to not consider the ROB empty
961        // on the same cycle as when stores have been committed.
962        // @todo: Make this handle multi-cycle communication between
963        // commit and IEW.
964        if (checkEmptyROB[tid] && rob->isEmpty(tid) &&
965            !iewStage->hasStoresToWB(tid) && !committedStores[tid]) {
966            checkEmptyROB[tid] = false;
967            toIEW->commitInfo[tid].usedROB = true;
968            toIEW->commitInfo[tid].emptyROB = true;
969            toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
970            wroteToTimeBuffer = true;
971        }
972
973    }
974}
975
976template <class Impl>
977void
978DefaultCommit<Impl>::commitInsts()
979{
980    ////////////////////////////////////
981    // Handle commit
982    // Note that commit will be handled prior to putting new
983    // instructions in the ROB so that the ROB only tries to commit
984    // instructions it has in this current cycle, and not instructions
985    // it is writing in during this cycle.  Can't commit and squash
986    // things at the same time...
987    ////////////////////////////////////
988
989    DPRINTF(Commit, "Trying to commit instructions in the ROB.\n");
990
991    unsigned num_committed = 0;
992
993    DynInstPtr head_inst;
994
995    // Commit as many instructions as possible until the commit bandwidth
996    // limit is reached, or it becomes impossible to commit any more.
997    while (num_committed < commitWidth) {
998        // Check for any interrupt that we've already squashed for
999        // and start processing it.
1000        if (interrupt != NoFault)
1001            handleInterrupt();
1002
1003        ThreadID commit_thread = getCommittingThread();
1004
1005        if (commit_thread == -1 || !rob->isHeadReady(commit_thread))
1006            break;
1007
1008        head_inst = rob->readHeadInst(commit_thread);
1009
1010        ThreadID tid = head_inst->threadNumber;
1011
1012        assert(tid == commit_thread);
1013
1014        DPRINTF(Commit,
1015                "Trying to commit head instruction, [tid:%i] [sn:%llu]\n",
1016                tid, head_inst->seqNum);
1017
1018        // If the head instruction is squashed, it is ready to retire
1019        // (be removed from the ROB) at any time.
1020        if (head_inst->isSquashed()) {
1021
1022            DPRINTF(Commit, "Retiring squashed instruction from "
1023                    "ROB.\n");
1024
1025            rob->retireHead(commit_thread);
1026
1027            ++commitSquashedInsts;
1028            // Notify potential listeners that this instruction is squashed
1029            ppSquash->notify(head_inst);
1030
1031            // Record that the number of ROB entries has changed.
1032            changedROBNumEntries[tid] = true;
1033        } else {
1034            pc[tid] = head_inst->pcState();
1035
1036            // Increment the total number of non-speculative instructions
1037            // executed.
1038            // Hack for now: it really shouldn't happen until after the
1039            // commit is deemed to be successful, but this count is needed
1040            // for syscalls.
1041            thread[tid]->funcExeInst++;
1042
1043            // Try to commit the head instruction.
1044            bool commit_success = commitHead(head_inst, num_committed);
1045
1046            if (commit_success) {
1047                ++num_committed;
1048                statCommittedInstType[tid][head_inst->opClass()]++;
1049                ppCommit->notify(head_inst);
1050
1051                changedROBNumEntries[tid] = true;
1052
1053                // Set the doneSeqNum to the youngest committed instruction.
1054                toIEW->commitInfo[tid].doneSeqNum = head_inst->seqNum;
1055
1056                if (tid == 0) {
1057                    canHandleInterrupts =  (!head_inst->isDelayedCommit()) &&
1058                                           ((THE_ISA != ALPHA_ISA) ||
1059                                             (!(pc[0].instAddr() & 0x3)));
1060                }
1061
1062                // at this point store conditionals should either have
1063                // been completed or predicated false
1064                assert(!head_inst->isStoreConditional() ||
1065                       head_inst->isCompleted() ||
1066                       !head_inst->readPredicate());
1067
1068                // Updates misc. registers.
1069                head_inst->updateMiscRegs();
1070
1071                // Check instruction execution if it successfully commits and
1072                // is not carrying a fault.
1073                if (cpu->checker) {
1074                    cpu->checker->verify(head_inst);
1075                }
1076
1077                cpu->traceFunctions(pc[tid].instAddr());
1078
1079                TheISA::advancePC(pc[tid], head_inst->staticInst);
1080
1081                // Keep track of the last sequence number commited
1082                lastCommitedSeqNum[tid] = head_inst->seqNum;
1083
1084                // If this is an instruction that doesn't play nicely with
1085                // others squash everything and restart fetch
1086                if (head_inst->isSquashAfter())
1087                    squashAfter(tid, head_inst);
1088
1089                if (drainPending) {
1090                    if (pc[tid].microPC() == 0 && interrupt == NoFault &&
1091                        !thread[tid]->trapPending) {
1092                        // Last architectually committed instruction.
1093                        // Squash the pipeline, stall fetch, and use
1094                        // drainImminent to disable interrupts
1095                        DPRINTF(Drain, "Draining: %i:%s\n", tid, pc[tid]);
1096                        squashAfter(tid, head_inst);
1097                        cpu->commitDrained(tid);
1098                        drainImminent = true;
1099                    }
1100                }
1101
1102                bool onInstBoundary = !head_inst->isMicroop() ||
1103                                      head_inst->isLastMicroop() ||
1104                                      !head_inst->isDelayedCommit();
1105
1106                if (onInstBoundary) {
1107                    int count = 0;
1108                    Addr oldpc;
1109                    // Make sure we're not currently updating state while
1110                    // handling PC events.
1111                    assert(!thread[tid]->noSquashFromTC &&
1112                           !thread[tid]->trapPending);
1113                    do {
1114                        oldpc = pc[tid].instAddr();
1115                        cpu->system->pcEventQueue.service(thread[tid]->getTC());
1116                        count++;
1117                    } while (oldpc != pc[tid].instAddr());
1118                    if (count > 1) {
1119                        DPRINTF(Commit,
1120                                "PC skip function event, stopping commit\n");
1121                        break;
1122                    }
1123                }
1124
1125                // Check if an instruction just enabled interrupts and we've
1126                // previously had an interrupt pending that was not handled
1127                // because interrupts were subsequently disabled before the
1128                // pipeline reached a place to handle the interrupt. In that
1129                // case squash now to make sure the interrupt is handled.
1130                //
1131                // If we don't do this, we might end up in a live lock situation
1132                if (!interrupt && avoidQuiesceLiveLock &&
1133                    onInstBoundary && cpu->checkInterrupts(cpu->tcBase(0)))
1134                    squashAfter(tid, head_inst);
1135            } else {
1136                DPRINTF(Commit, "Unable to commit head instruction PC:%s "
1137                        "[tid:%i] [sn:%llu].\n",
1138                        head_inst->pcState(), tid ,head_inst->seqNum);
1139                break;
1140            }
1141        }
1142    }
1143
1144    DPRINTF(CommitRate, "%i\n", num_committed);
1145    numCommittedDist.sample(num_committed);
1146
1147    if (num_committed == commitWidth) {
1148        commitEligibleSamples++;
1149    }
1150}
1151
1152template <class Impl>
1153bool
1154DefaultCommit<Impl>::commitHead(const DynInstPtr &head_inst, unsigned inst_num)
1155{
1156    assert(head_inst);
1157
1158    ThreadID tid = head_inst->threadNumber;
1159
1160    // If the instruction is not executed yet, then it will need extra
1161    // handling.  Signal backwards that it should be executed.
1162    if (!head_inst->isExecuted()) {
1163        // Keep this number correct.  We have not yet actually executed
1164        // and committed this instruction.
1165        thread[tid]->funcExeInst--;
1166
1167        // Make sure we are only trying to commit un-executed instructions we
1168        // think are possible.
1169        assert(head_inst->isNonSpeculative() || head_inst->isStoreConditional()
1170               || head_inst->isMemBarrier() || head_inst->isWriteBarrier()
1171               || head_inst->isAtomic()
1172               || (head_inst->isLoad() && head_inst->strictlyOrdered()));
1173
1174        DPRINTF(Commit,
1175                "Encountered a barrier or non-speculative "
1176                "instruction [tid:%i] [sn:%llu] "
1177                "at the head of the ROB, PC %s.\n",
1178                tid, head_inst->seqNum, head_inst->pcState());
1179
1180        if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
1181            DPRINTF(Commit,
1182                    "[tid:%i] [sn:%llu] "
1183                    "Waiting for all stores to writeback.\n",
1184                    tid, head_inst->seqNum);
1185            return false;
1186        }
1187
1188        toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
1189
1190        // Change the instruction so it won't try to commit again until
1191        // it is executed.
1192        head_inst->clearCanCommit();
1193
1194        if (head_inst->isLoad() && head_inst->strictlyOrdered()) {
1195            DPRINTF(Commit, "[tid:%i] [sn:%llu] "
1196                    "Strictly ordered load, PC %s.\n",
1197                    tid, head_inst->seqNum, head_inst->pcState());
1198            toIEW->commitInfo[tid].strictlyOrdered = true;
1199            toIEW->commitInfo[tid].strictlyOrderedLoad = head_inst;
1200        } else {
1201            ++commitNonSpecStalls;
1202        }
1203
1204        return false;
1205    }
1206
1207    if (head_inst->isThreadSync()) {
1208        // Not handled for now.
1209        panic("Thread sync instructions are not handled yet.\n");
1210    }
1211
1212    // Check if the instruction caused a fault.  If so, trap.
1213    Fault inst_fault = head_inst->getFault();
1214
1215    // Stores mark themselves as completed.
1216    if (!head_inst->isStore() && inst_fault == NoFault) {
1217        head_inst->setCompleted();
1218    }
1219
1220    if (inst_fault != NoFault) {
1221        DPRINTF(Commit, "Inst [tid:%i] [sn:%llu] PC %s has a fault\n",
1222                tid, head_inst->seqNum, head_inst->pcState());
1223
1224        if (iewStage->hasStoresToWB(tid) || inst_num > 0) {
1225            DPRINTF(Commit,
1226                    "[tid:%i] [sn:%llu] "
1227                    "Stores outstanding, fault must wait.\n",
1228                    tid, head_inst->seqNum);
1229            return false;
1230        }
1231
1232        head_inst->setCompleted();
1233
1234        // If instruction has faulted, let the checker execute it and
1235        // check if it sees the same fault and control flow.
1236        if (cpu->checker) {
1237            // Need to check the instruction before its fault is processed
1238            cpu->checker->verify(head_inst);
1239        }
1240
1241        assert(!thread[tid]->noSquashFromTC);
1242
1243        // Mark that we're in state update mode so that the trap's
1244        // execution doesn't generate extra squashes.
1245        thread[tid]->noSquashFromTC = true;
1246
1247        // Execute the trap.  Although it's slightly unrealistic in
1248        // terms of timing (as it doesn't wait for the full timing of
1249        // the trap event to complete before updating state), it's
1250        // needed to update the state as soon as possible.  This
1251        // prevents external agents from changing any specific state
1252        // that the trap need.
1253        cpu->trap(inst_fault, tid,
1254                  head_inst->notAnInst() ?
1255                      StaticInst::nullStaticInstPtr :
1256                      head_inst->staticInst);
1257
1258        // Exit state update mode to avoid accidental updating.
1259        thread[tid]->noSquashFromTC = false;
1260
1261        commitStatus[tid] = TrapPending;
1262
1263        DPRINTF(Commit,
1264            "[tid:%i] [sn:%llu] Committing instruction with fault\n",
1265            tid, head_inst->seqNum);
1266        if (head_inst->traceData) {
1267            if (DTRACE(ExecFaulting)) {
1268                head_inst->traceData->setFetchSeq(head_inst->seqNum);
1269                head_inst->traceData->setCPSeq(thread[tid]->numOp);
1270                head_inst->traceData->dump();
1271            }
1272            delete head_inst->traceData;
1273            head_inst->traceData = NULL;
1274        }
1275
1276        // Generate trap squash event.
1277        generateTrapEvent(tid, inst_fault);
1278        return false;
1279    }
1280
1281    updateComInstStats(head_inst);
1282
1283    if (FullSystem) {
1284        if (thread[tid]->profile) {
1285            thread[tid]->profilePC = head_inst->instAddr();
1286            ProfileNode *node = thread[tid]->profile->consume(
1287                    thread[tid]->getTC(), head_inst->staticInst);
1288
1289            if (node)
1290                thread[tid]->profileNode = node;
1291        }
1292        if (CPA::available()) {
1293            if (head_inst->isControl()) {
1294                ThreadContext *tc = thread[tid]->getTC();
1295                CPA::cpa()->swAutoBegin(tc, head_inst->nextInstAddr());
1296            }
1297        }
1298    }
1299    DPRINTF(Commit,
1300            "[tid:%i] [sn:%llu] Committing instruction with PC %s\n",
1301            tid, head_inst->seqNum, head_inst->pcState());
1302    if (head_inst->traceData) {
1303        head_inst->traceData->setFetchSeq(head_inst->seqNum);
1304        head_inst->traceData->setCPSeq(thread[tid]->numOp);
1305        head_inst->traceData->dump();
1306        delete head_inst->traceData;
1307        head_inst->traceData = NULL;
1308    }
1309    if (head_inst->isReturn()) {
1310        DPRINTF(Commit,
1311                "[tid:%i] [sn:%llu] Return Instruction Committed PC %s \n",
1312                tid, head_inst->seqNum, head_inst->pcState());
1313    }
1314
1315    // Update the commit rename map
1316    for (int i = 0; i < head_inst->numDestRegs(); i++) {
1317        renameMap[tid]->setEntry(head_inst->flattenedDestRegIdx(i),
1318                                 head_inst->renamedDestRegIdx(i));
1319    }
1320
1321    // Finally clear the head ROB entry.
1322    rob->retireHead(tid);
1323
1324#if TRACING_ON
1325    if (DTRACE(O3PipeView)) {
1326        head_inst->commitTick = curTick() - head_inst->fetchTick;
1327    }
1328#endif
1329
1330    // If this was a store, record it for this cycle.
1331    if (head_inst->isStore() || head_inst->isAtomic())
1332        committedStores[tid] = true;
1333
1334    // Return true to indicate that we have committed an instruction.
1335    return true;
1336}
1337
1338template <class Impl>
1339void
1340DefaultCommit<Impl>::getInsts()
1341{
1342    DPRINTF(Commit, "Getting instructions from Rename stage.\n");
1343
1344    // Read any renamed instructions and place them into the ROB.
1345    int insts_to_process = std::min((int)renameWidth, fromRename->size);
1346
1347    for (int inst_num = 0; inst_num < insts_to_process; ++inst_num) {
1348        const DynInstPtr &inst = fromRename->insts[inst_num];
1349        ThreadID tid = inst->threadNumber;
1350
1351        if (!inst->isSquashed() &&
1352            commitStatus[tid] != ROBSquashing &&
1353            commitStatus[tid] != TrapPending) {
1354            changedROBNumEntries[tid] = true;
1355
1356            DPRINTF(Commit, "[tid:%i] [sn:%llu] Inserting PC %s into ROB.\n",
1357                    inst->seqNum, tid, inst->pcState());
1358
1359            rob->insertInst(inst);
1360
1361            assert(rob->getThreadEntries(tid) <= rob->getMaxEntries(tid));
1362
1363            youngestSeqNum[tid] = inst->seqNum;
1364        } else {
1365            DPRINTF(Commit, "[tid:%i] [sn:%llu] "
1366                    "Instruction PC %s was squashed, skipping.\n",
1367                    inst->seqNum, tid, inst->pcState());
1368        }
1369    }
1370}
1371
1372template <class Impl>
1373void
1374DefaultCommit<Impl>::markCompletedInsts()
1375{
1376    // Grab completed insts out of the IEW instruction queue, and mark
1377    // instructions completed within the ROB.
1378    for (int inst_num = 0; inst_num < fromIEW->size; ++inst_num) {
1379        assert(fromIEW->insts[inst_num]);
1380        if (!fromIEW->insts[inst_num]->isSquashed()) {
1381            DPRINTF(Commit, "[tid:%i] Marking PC %s, [sn:%llu] ready "
1382                    "within ROB.\n",
1383                    fromIEW->insts[inst_num]->threadNumber,
1384                    fromIEW->insts[inst_num]->pcState(),
1385                    fromIEW->insts[inst_num]->seqNum);
1386
1387            // Mark the instruction as ready to commit.
1388            fromIEW->insts[inst_num]->setCanCommit();
1389        }
1390    }
1391}
1392
1393template <class Impl>
1394void
1395DefaultCommit<Impl>::updateComInstStats(const DynInstPtr &inst)
1396{
1397    ThreadID tid = inst->threadNumber;
1398
1399    if (!inst->isMicroop() || inst->isLastMicroop())
1400        instsCommitted[tid]++;
1401    opsCommitted[tid]++;
1402
1403    // To match the old model, don't count nops and instruction
1404    // prefetches towards the total commit count.
1405    if (!inst->isNop() && !inst->isInstPrefetch()) {
1406        cpu->instDone(tid, inst);
1407    }
1408
1409    //
1410    //  Control Instructions
1411    //
1412    if (inst->isControl())
1413        statComBranches[tid]++;
1414
1415    //
1416    //  Memory references
1417    //
1418    if (inst->isMemRef()) {
1419        statComRefs[tid]++;
1420
1421        if (inst->isLoad()) {
1422            statComLoads[tid]++;
1423        }
1424
1425        if (inst->isAtomic()) {
1426            statComAmos[tid]++;
1427        }
1428    }
1429
1430    if (inst->isMemBarrier()) {
1431        statComMembars[tid]++;
1432    }
1433
1434    // Integer Instruction
1435    if (inst->isInteger())
1436        statComInteger[tid]++;
1437
1438    // Floating Point Instruction
1439    if (inst->isFloating())
1440        statComFloating[tid]++;
1441    // Vector Instruction
1442    if (inst->isVector())
1443        statComVector[tid]++;
1444
1445    // Function Calls
1446    if (inst->isCall())
1447        statComFunctionCalls[tid]++;
1448
1449}
1450
1451////////////////////////////////////////
1452//                                    //
1453//  SMT COMMIT POLICY MAINTAINED HERE //
1454//                                    //
1455////////////////////////////////////////
1456template <class Impl>
1457ThreadID
1458DefaultCommit<Impl>::getCommittingThread()
1459{
1460    if (numThreads > 1) {
1461        switch (commitPolicy) {
1462
1463          case CommitPolicy::Aggressive:
1464            //If Policy is Aggressive, commit will call
1465            //this function multiple times per
1466            //cycle
1467            return oldestReady();
1468
1469          case CommitPolicy::RoundRobin:
1470            return roundRobin();
1471
1472          case CommitPolicy::OldestReady:
1473            return oldestReady();
1474
1475          default:
1476            return InvalidThreadID;
1477        }
1478    } else {
1479        assert(!activeThreads->empty());
1480        ThreadID tid = activeThreads->front();
1481
1482        if (commitStatus[tid] == Running ||
1483            commitStatus[tid] == Idle ||
1484            commitStatus[tid] == FetchTrapPending) {
1485            return tid;
1486        } else {
1487            return InvalidThreadID;
1488        }
1489    }
1490}
1491
1492template<class Impl>
1493ThreadID
1494DefaultCommit<Impl>::roundRobin()
1495{
1496    list<ThreadID>::iterator pri_iter = priority_list.begin();
1497    list<ThreadID>::iterator end      = priority_list.end();
1498
1499    while (pri_iter != end) {
1500        ThreadID tid = *pri_iter;
1501
1502        if (commitStatus[tid] == Running ||
1503            commitStatus[tid] == Idle ||
1504            commitStatus[tid] == FetchTrapPending) {
1505
1506            if (rob->isHeadReady(tid)) {
1507                priority_list.erase(pri_iter);
1508                priority_list.push_back(tid);
1509
1510                return tid;
1511            }
1512        }
1513
1514        pri_iter++;
1515    }
1516
1517    return InvalidThreadID;
1518}
1519
1520template<class Impl>
1521ThreadID
1522DefaultCommit<Impl>::oldestReady()
1523{
1524    unsigned oldest = 0;
1525    bool first = true;
1526
1527    list<ThreadID>::iterator threads = activeThreads->begin();
1528    list<ThreadID>::iterator end = activeThreads->end();
1529
1530    while (threads != end) {
1531        ThreadID tid = *threads++;
1532
1533        if (!rob->isEmpty(tid) &&
1534            (commitStatus[tid] == Running ||
1535             commitStatus[tid] == Idle ||
1536             commitStatus[tid] == FetchTrapPending)) {
1537
1538            if (rob->isHeadReady(tid)) {
1539
1540                const DynInstPtr &head_inst = rob->readHeadInst(tid);
1541
1542                if (first) {
1543                    oldest = tid;
1544                    first = false;
1545                } else if (head_inst->seqNum < oldest) {
1546                    oldest = tid;
1547                }
1548            }
1549        }
1550    }
1551
1552    if (!first) {
1553        return oldest;
1554    } else {
1555        return InvalidThreadID;
1556    }
1557}
1558
1559#endif//__CPU_O3_COMMIT_IMPL_HH__
1560