inst_queue_impl.hh revision 1689
1/*
2 * Copyright (c) 2004-2005 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
29// Todo:
30// Current ordering allows for 0 cycle added-to-scheduled.  Could maybe fake
31// it; either do in reverse order, or have added instructions put into a
32// different ready queue that, in scheduleRreadyInsts(), gets put onto the
33// normal ready queue.  This would however give only a one cycle delay,
34// but probably is more flexible to actually add in a delay parameter than
35// just running it backwards.
36
37#include <vector>
38
39#include "sim/universe.hh"
40
41#include "cpu/beta_cpu/inst_queue.hh"
42
43// Either compile error or max int due to sign extension.
44// Hack to avoid compile warnings.
45const InstSeqNum MaxInstSeqNum = 0 - 1;
46
47template <class Impl>
48InstructionQueue<Impl>::InstructionQueue(Params &params)
49    : memDepUnit(params),
50      numEntries(params.numIQEntries),
51      intWidth(params.executeIntWidth),
52      floatWidth(params.executeFloatWidth),
53      branchWidth(params.executeBranchWidth),
54      memoryWidth(params.executeMemoryWidth),
55      totalWidth(params.issueWidth),
56      numPhysIntRegs(params.numPhysIntRegs),
57      numPhysFloatRegs(params.numPhysFloatRegs),
58      commitToIEWDelay(params.commitToIEWDelay)
59{
60    // Initialize the number of free IQ entries.
61    freeEntries = numEntries;
62
63    // Set the number of physical registers as the number of int + float
64    numPhysRegs = numPhysIntRegs + numPhysFloatRegs;
65
66    DPRINTF(IQ, "IQ: There are %i physical registers.\n", numPhysRegs);
67
68    //Create an entry for each physical register within the
69    //dependency graph.
70    dependGraph = new DependencyEntry[numPhysRegs];
71
72    // Resize the register scoreboard.
73    regScoreboard.resize(numPhysRegs);
74
75    // Initialize all the head pointers to point to NULL, and all the
76    // entries as unready.
77    // Note that in actuality, the registers corresponding to the logical
78    // registers start off as ready.  However this doesn't matter for the
79    // IQ as the instruction should have been correctly told if those
80    // registers are ready in rename.  Thus it can all be initialized as
81    // unready.
82    for (int i = 0; i < numPhysRegs; ++i)
83    {
84        dependGraph[i].next = NULL;
85        dependGraph[i].inst = NULL;
86        regScoreboard[i] = false;
87    }
88
89}
90
91template <class Impl>
92void
93InstructionQueue<Impl>::regStats()
94{
95    iqInstsAdded
96        .name(name() + ".iqInstsAdded")
97        .desc("Number of instructions added to the IQ (excludes non-spec)")
98        .prereq(iqInstsAdded);
99
100    iqNonSpecInstsAdded
101        .name(name() + ".iqNonSpecInstsAdded")
102        .desc("Number of non-speculative instructions added to the IQ")
103        .prereq(iqNonSpecInstsAdded);
104
105//    iqIntInstsAdded;
106
107    iqIntInstsIssued
108        .name(name() + ".iqIntInstsIssued")
109        .desc("Number of integer instructions issued")
110        .prereq(iqIntInstsIssued);
111
112//    iqFloatInstsAdded;
113
114    iqFloatInstsIssued
115        .name(name() + ".iqFloatInstsIssued")
116        .desc("Number of float instructions issued")
117        .prereq(iqFloatInstsIssued);
118
119//    iqBranchInstsAdded;
120
121    iqBranchInstsIssued
122        .name(name() + ".iqBranchInstsIssued")
123        .desc("Number of branch instructions issued")
124        .prereq(iqBranchInstsIssued);
125
126//    iqMemInstsAdded;
127
128    iqMemInstsIssued
129        .name(name() + ".iqMemInstsIssued")
130        .desc("Number of memory instructions issued")
131        .prereq(iqMemInstsIssued);
132
133//    iqMiscInstsAdded;
134
135    iqMiscInstsIssued
136        .name(name() + ".iqMiscInstsIssued")
137        .desc("Number of miscellaneous instructions issued")
138        .prereq(iqMiscInstsIssued);
139
140    iqSquashedInstsIssued
141        .name(name() + ".iqSquashedInstsIssued")
142        .desc("Number of squashed instructions issued")
143        .prereq(iqSquashedInstsIssued);
144
145    iqLoopSquashStalls
146        .name(name() + ".iqLoopSquashStalls")
147        .desc("Number of times issue loop had to restart due to squashed "
148              "inst; mainly for profiling")
149        .prereq(iqLoopSquashStalls);
150
151    iqSquashedInstsExamined
152        .name(name() + ".iqSquashedInstsExamined")
153        .desc("Number of squashed instructions iterated over during squash;"
154              " mainly for profiling")
155        .prereq(iqSquashedInstsExamined);
156
157    iqSquashedOperandsExamined
158        .name(name() + ".iqSquashedOperandsExamined")
159        .desc("Number of squashed operands that are examined and possibly "
160              "removed from graph")
161        .prereq(iqSquashedOperandsExamined);
162
163    iqSquashedNonSpecRemoved
164        .name(name() + ".iqSquashedNonSpecRemoved")
165        .desc("Number of squashed non-spec instructions that were removed")
166        .prereq(iqSquashedNonSpecRemoved);
167
168    // Tell mem dependence unit to reg stats as well.
169    memDepUnit.regStats();
170}
171
172template <class Impl>
173void
174InstructionQueue<Impl>::setCPU(FullCPU *cpu_ptr)
175{
176    cpu = cpu_ptr;
177
178    tail = cpu->instList.begin();
179}
180
181template <class Impl>
182void
183InstructionQueue<Impl>::setIssueToExecuteQueue(
184                        TimeBuffer<IssueStruct> *i2e_ptr)
185{
186    DPRINTF(IQ, "IQ: Set the issue to execute queue.\n");
187    issueToExecuteQueue = i2e_ptr;
188}
189
190template <class Impl>
191void
192InstructionQueue<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
193{
194    DPRINTF(IQ, "IQ: Set the time buffer.\n");
195    timeBuffer = tb_ptr;
196
197    fromCommit = timeBuffer->getWire(-commitToIEWDelay);
198}
199
200template <class Impl>
201unsigned
202InstructionQueue<Impl>::numFreeEntries()
203{
204    return freeEntries;
205}
206
207// Might want to do something more complex if it knows how many instructions
208// will be issued this cycle.
209template <class Impl>
210bool
211InstructionQueue<Impl>::isFull()
212{
213    if (freeEntries == 0) {
214        return(true);
215    } else {
216        return(false);
217    }
218}
219
220template <class Impl>
221void
222InstructionQueue<Impl>::insert(DynInstPtr &new_inst)
223{
224    // Make sure the instruction is valid
225    assert(new_inst);
226
227    DPRINTF(IQ, "IQ: Adding instruction PC %#x to the IQ.\n",
228            new_inst->readPC());
229
230    // Check if there are any free entries.  Panic if there are none.
231    // Might want to have this return a fault in the future instead of
232    // panicing.
233    assert(freeEntries != 0);
234
235    // If the IQ currently has nothing in it, then there's a possibility
236    // that the tail iterator is invalid (might have been pointing at an
237    // instruction that was retired).  Reset the tail iterator.
238    if (freeEntries == numEntries) {
239        tail = cpu->instList.begin();
240    }
241
242    // Move the tail iterator.  Instructions may not have been issued
243    // to the IQ, so we may have to increment the iterator more than once.
244    while ((*tail) != new_inst) {
245        tail++;
246
247        // Make sure the tail iterator points at something legal.
248        assert(tail != cpu->instList.end());
249    }
250
251
252    // Decrease the number of free entries.
253    --freeEntries;
254
255    // Look through its source registers (physical regs), and mark any
256    // dependencies.
257    addToDependents(new_inst);
258
259    // Have this instruction set itself as the producer of its destination
260    // register(s).
261    createDependency(new_inst);
262
263    // If it's a memory instruction, add it to the memory dependency
264    // unit.
265    if (new_inst->isMemRef()) {
266        memDepUnit.insert(new_inst);
267        // Uh..forgot to look it up and put it on the proper dependency list
268        // if the instruction should not go yet.
269    } else {
270        // If the instruction is ready then add it to the ready list.
271        addIfReady(new_inst);
272    }
273
274    ++iqInstsAdded;
275
276    assert(freeEntries == (numEntries - countInsts()));
277}
278
279template <class Impl>
280void
281InstructionQueue<Impl>::insertNonSpec(DynInstPtr &inst)
282{
283    nonSpecInsts[inst->seqNum] = inst;
284
285    // @todo: Clean up this code; can do it by setting inst as unable
286    // to issue, then calling normal insert on the inst.
287
288    // Make sure the instruction is valid
289    assert(inst);
290
291    DPRINTF(IQ, "IQ: Adding instruction PC %#x to the IQ.\n",
292            inst->readPC());
293
294    // Check if there are any free entries.  Panic if there are none.
295    // Might want to have this return a fault in the future instead of
296    // panicing.
297    assert(freeEntries != 0);
298
299    // If the IQ currently has nothing in it, then there's a possibility
300    // that the tail iterator is invalid (might have been pointing at an
301    // instruction that was retired).  Reset the tail iterator.
302    if (freeEntries == numEntries) {
303        tail = cpu->instList.begin();
304    }
305
306    // Move the tail iterator.  Instructions may not have been issued
307    // to the IQ, so we may have to increment the iterator more than once.
308    while ((*tail) != inst) {
309        tail++;
310
311        // Make sure the tail iterator points at something legal.
312        assert(tail != cpu->instList.end());
313    }
314
315    // Decrease the number of free entries.
316    --freeEntries;
317
318    // Have this instruction set itself as the producer of its destination
319    // register(s).
320    createDependency(inst);
321
322    // If it's a memory instruction, add it to the memory dependency
323    // unit.
324    if (inst->isMemRef()) {
325        memDepUnit.insertNonSpec(inst);
326    }
327
328    ++iqNonSpecInstsAdded;
329}
330
331// Slightly hack function to advance the tail iterator in the case that
332// the IEW stage issues an instruction that is not added to the IQ.  This
333// is needed in case a long chain of such instructions occurs.
334// I don't think this is used anymore.
335template <class Impl>
336void
337InstructionQueue<Impl>::advanceTail(DynInstPtr &inst)
338{
339    // Make sure the instruction is valid
340    assert(inst);
341
342    DPRINTF(IQ, "IQ: Adding instruction PC %#x to the IQ.\n",
343            inst->readPC());
344
345    // Check if there are any free entries.  Panic if there are none.
346    // Might want to have this return a fault in the future instead of
347    // panicing.
348    assert(freeEntries != 0);
349
350    // If the IQ currently has nothing in it, then there's a possibility
351    // that the tail iterator is invalid (might have been pointing at an
352    // instruction that was retired).  Reset the tail iterator.
353    if (freeEntries == numEntries) {
354        tail = cpu->instList.begin();
355    }
356
357    // Move the tail iterator.  Instructions may not have been issued
358    // to the IQ, so we may have to increment the iterator more than once.
359    while ((*tail) != inst) {
360        tail++;
361
362        // Make sure the tail iterator points at something legal.
363        assert(tail != cpu->instList.end());
364    }
365
366    assert(freeEntries <= numEntries);
367
368    // Have this instruction set itself as the producer of its destination
369    // register(s).
370    createDependency(inst);
371}
372
373// Need to make sure the number of float and integer instructions
374// issued does not exceed the total issue bandwidth.
375// @todo: Figure out a better way to remove the squashed items from the
376// lists.  Checking the top item of each list to see if it's squashed
377// wastes time and forces jumps.
378template <class Impl>
379void
380InstructionQueue<Impl>::scheduleReadyInsts()
381{
382    DPRINTF(IQ, "IQ: Attempting to schedule ready instructions from "
383                "the IQ.\n");
384
385    int int_issued = 0;
386    int float_issued = 0;
387    int branch_issued = 0;
388    int memory_issued = 0;
389    int squashed_issued = 0;
390    int total_issued = 0;
391
392    IssueStruct *i2e_info = issueToExecuteQueue->access(0);
393
394    bool insts_available = !readyBranchInsts.empty() ||
395        !readyIntInsts.empty() ||
396        !readyFloatInsts.empty() ||
397        !memDepUnit.empty() ||
398        !readyMiscInsts.empty() ||
399        !squashedInsts.empty();
400
401    // Note: Requires a globally defined constant.
402    InstSeqNum oldest_inst = MaxInstSeqNum;
403    InstList list_with_oldest = None;
404
405    // Temporary values.
406    DynInstPtr int_head_inst;
407    DynInstPtr float_head_inst;
408    DynInstPtr branch_head_inst;
409    DynInstPtr mem_head_inst;
410    DynInstPtr misc_head_inst;
411    DynInstPtr squashed_head_inst;
412
413    // Somewhat nasty code to look at all of the lists where issuable
414    // instructions are located, and choose the oldest instruction among
415    // those lists.  Consider a rewrite in the future.
416    while (insts_available && total_issued < totalWidth)
417    {
418        // Set this to false.  Each if-block is required to set it to true
419        // if there were instructions available this check.  This will cause
420        // this loop to run once more than necessary, but avoids extra calls.
421        insts_available = false;
422
423        oldest_inst = MaxInstSeqNum;
424
425        list_with_oldest = None;
426
427        if (!readyIntInsts.empty() &&
428            int_issued < intWidth) {
429
430            insts_available = true;
431
432            int_head_inst = readyIntInsts.top();
433
434            if (int_head_inst->isSquashed()) {
435                readyIntInsts.pop();
436
437                ++iqLoopSquashStalls;
438
439                continue;
440            }
441
442            oldest_inst = int_head_inst->seqNum;
443
444            list_with_oldest = Int;
445        }
446
447        if (!readyFloatInsts.empty() &&
448            float_issued < floatWidth) {
449
450            insts_available = true;
451
452            float_head_inst = readyFloatInsts.top();
453
454            if (float_head_inst->isSquashed()) {
455                readyFloatInsts.pop();
456
457                ++iqLoopSquashStalls;
458
459                continue;
460            } else if (float_head_inst->seqNum < oldest_inst) {
461                oldest_inst = float_head_inst->seqNum;
462
463                list_with_oldest = Float;
464            }
465        }
466
467        if (!readyBranchInsts.empty() &&
468            branch_issued < branchWidth) {
469
470            insts_available = true;
471
472            branch_head_inst = readyBranchInsts.top();
473
474            if (branch_head_inst->isSquashed()) {
475                readyBranchInsts.pop();
476
477                ++iqLoopSquashStalls;
478
479                continue;
480            } else if (branch_head_inst->seqNum < oldest_inst) {
481                oldest_inst = branch_head_inst->seqNum;
482
483                list_with_oldest = Branch;
484            }
485
486        }
487
488        if (!memDepUnit.empty() &&
489            memory_issued < memoryWidth) {
490
491            insts_available = true;
492
493            mem_head_inst = memDepUnit.top();
494
495            if (mem_head_inst->isSquashed()) {
496                memDepUnit.pop();
497
498                ++iqLoopSquashStalls;
499
500                continue;
501            } else if (mem_head_inst->seqNum < oldest_inst) {
502                oldest_inst = mem_head_inst->seqNum;
503
504                list_with_oldest = Memory;
505            }
506        }
507
508        if (!readyMiscInsts.empty()) {
509
510            insts_available = true;
511
512            misc_head_inst = readyMiscInsts.top();
513
514            if (misc_head_inst->isSquashed()) {
515                readyMiscInsts.pop();
516
517                ++iqLoopSquashStalls;
518
519                continue;
520            } else if (misc_head_inst->seqNum < oldest_inst) {
521                oldest_inst = misc_head_inst->seqNum;
522
523                list_with_oldest = Misc;
524            }
525        }
526
527        if (!squashedInsts.empty()) {
528
529            insts_available = true;
530
531            squashed_head_inst = squashedInsts.top();
532
533            if (squashed_head_inst->seqNum < oldest_inst) {
534                list_with_oldest = Squashed;
535            }
536
537        }
538
539        DynInstPtr issuing_inst = NULL;
540
541        switch (list_with_oldest) {
542          case None:
543            DPRINTF(IQ, "IQ: Not able to schedule any instructions. Issuing "
544                    "inst is %#x.\n", issuing_inst);
545            break;
546
547          case Int:
548            issuing_inst = int_head_inst;
549            readyIntInsts.pop();
550            ++int_issued;
551            DPRINTF(IQ, "IQ: Issuing integer instruction PC %#x.\n",
552                    issuing_inst->readPC());
553            break;
554
555          case Float:
556            issuing_inst = float_head_inst;
557            readyFloatInsts.pop();
558            ++float_issued;
559            DPRINTF(IQ, "IQ: Issuing float instruction PC %#x.\n",
560                    issuing_inst->readPC());
561            break;
562
563          case Branch:
564            issuing_inst = branch_head_inst;
565            readyBranchInsts.pop();
566            ++branch_issued;
567            DPRINTF(IQ, "IQ: Issuing branch instruction PC %#x.\n",
568                    issuing_inst->readPC());
569            break;
570
571          case Memory:
572            issuing_inst = mem_head_inst;
573
574            memDepUnit.pop();
575            ++memory_issued;
576            DPRINTF(IQ, "IQ: Issuing memory instruction PC %#x.\n",
577                    issuing_inst->readPC());
578            break;
579
580          case Misc:
581            issuing_inst = misc_head_inst;
582            readyMiscInsts.pop();
583
584            ++iqMiscInstsIssued;
585
586            DPRINTF(IQ, "IQ: Issuing a miscellaneous instruction PC %#x.\n",
587                    issuing_inst->readPC());
588            break;
589
590          case Squashed:
591            assert(0 && "Squashed insts should not issue any more!");
592            squashedInsts.pop();
593            // Set the squashed instruction as able to commit so that commit
594            // can just drop it from the ROB.  This is a bit faked.
595            ++squashed_issued;
596            ++freeEntries;
597
598            DPRINTF(IQ, "IQ: Issuing squashed instruction PC %#x.\n",
599                    squashed_head_inst->readPC());
600            break;
601        }
602
603        if (list_with_oldest != None && list_with_oldest != Squashed) {
604            i2e_info->insts[total_issued] = issuing_inst;
605            i2e_info->size++;
606
607            issuing_inst->setIssued();
608
609            ++freeEntries;
610            ++total_issued;
611        }
612
613        assert(freeEntries == (numEntries - countInsts()));
614    }
615
616    iqIntInstsIssued += int_issued;
617    iqFloatInstsIssued += float_issued;
618    iqBranchInstsIssued += branch_issued;
619    iqMemInstsIssued += memory_issued;
620    iqSquashedInstsIssued += squashed_issued;
621}
622
623template <class Impl>
624void
625InstructionQueue<Impl>::scheduleNonSpec(const InstSeqNum &inst)
626{
627    DPRINTF(IQ, "IQ: Marking nonspeculative instruction with sequence "
628            "number %i as ready to execute.\n", inst);
629
630    non_spec_it_t inst_it = nonSpecInsts.find(inst);
631
632    assert(inst_it != nonSpecInsts.end());
633
634    // Mark this instruction as ready to issue.
635    (*inst_it).second->setCanIssue();
636
637    // Now schedule the instruction.
638    if (!(*inst_it).second->isMemRef()) {
639        addIfReady((*inst_it).second);
640    } else {
641        memDepUnit.nonSpecInstReady((*inst_it).second);
642    }
643
644    nonSpecInsts.erase(inst_it);
645}
646
647template <class Impl>
648void
649InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
650{
651    DPRINTF(IQ, "IQ: Waking dependents of completed instruction.\n");
652    //Look at the physical destination register of the DynInst
653    //and look it up on the dependency graph.  Then mark as ready
654    //any instructions within the instruction queue.
655    DependencyEntry *curr;
656
657    // Tell the memory dependence unit to wake any dependents on this
658    // instruction if it is a memory instruction.
659
660    if (completed_inst->isMemRef()) {
661        memDepUnit.wakeDependents(completed_inst);
662    }
663
664    for (int dest_reg_idx = 0;
665         dest_reg_idx < completed_inst->numDestRegs();
666         dest_reg_idx++)
667    {
668        PhysRegIndex dest_reg =
669            completed_inst->renamedDestRegIdx(dest_reg_idx);
670
671        // Special case of uniq or control registers.  They are not
672        // handled by the IQ and thus have no dependency graph entry.
673        // @todo Figure out a cleaner way to handle this.
674        if (dest_reg >= numPhysRegs) {
675            continue;
676        }
677
678        DPRINTF(IQ, "IQ: Waking any dependents on register %i.\n",
679                (int) dest_reg);
680
681        //Maybe abstract this part into a function.
682        //Go through the dependency chain, marking the registers as ready
683        //within the waiting instructions.
684        while (dependGraph[dest_reg].next) {
685
686            curr = dependGraph[dest_reg].next;
687
688            DPRINTF(IQ, "IQ: Waking up a dependent instruction, PC%#x.\n",
689                    curr->inst->readPC());
690
691            // Might want to give more information to the instruction
692            // so that it knows which of its source registers is ready.
693            // However that would mean that the dependency graph entries
694            // would need to hold the src_reg_idx.
695            curr->inst->markSrcRegReady();
696
697            addIfReady(curr->inst);
698
699            dependGraph[dest_reg].next = curr->next;
700
701            DependencyEntry::mem_alloc_counter--;
702
703            curr->inst = NULL;
704
705            delete curr;
706        }
707
708        // Reset the head node now that all of its dependents have been woken
709        // up.
710        dependGraph[dest_reg].next = NULL;
711        dependGraph[dest_reg].inst = NULL;
712
713        // Mark the scoreboard as having that register ready.
714        regScoreboard[dest_reg] = true;
715    }
716}
717
718template <class Impl>
719void
720InstructionQueue<Impl>::violation(DynInstPtr &store,
721                                  DynInstPtr &faulting_load)
722{
723    memDepUnit.violation(store, faulting_load);
724}
725
726template <class Impl>
727void
728InstructionQueue<Impl>::squash()
729{
730    DPRINTF(IQ, "IQ: Starting to squash instructions in the IQ.\n");
731
732    // Read instruction sequence number of last instruction out of the
733    // time buffer.
734    squashedSeqNum = fromCommit->commitInfo.doneSeqNum;
735
736    // Setup the squash iterator to point to the tail.
737    squashIt = tail;
738
739    // Call doSquash if there are insts in the IQ
740    if (freeEntries != numEntries) {
741        doSquash();
742    }
743
744    // Also tell the memory dependence unit to squash.
745    memDepUnit.squash(squashedSeqNum);
746}
747
748template <class Impl>
749void
750InstructionQueue<Impl>::doSquash()
751{
752    // Make sure the squash iterator isn't pointing to nothing.
753    assert(squashIt != cpu->instList.end());
754    // Make sure the squashed sequence number is valid.
755    assert(squashedSeqNum != 0);
756
757    DPRINTF(IQ, "IQ: Squashing instructions in the IQ.\n");
758
759    // Squash any instructions younger than the squashed sequence number
760    // given.
761    while ((*squashIt)->seqNum > squashedSeqNum) {
762        DynInstPtr squashed_inst = (*squashIt);
763
764        // Only handle the instruction if it actually is in the IQ and
765        // hasn't already been squashed in the IQ.
766        if (!squashed_inst->isIssued() &&
767            !squashed_inst->isSquashedInIQ()) {
768
769            // Remove the instruction from the dependency list.
770            // Hack for now: These below don't add themselves to the
771            // dependency list, so don't try to remove them.
772            if (!squashed_inst->isNonSpeculative()/* &&
773                                                     !squashed_inst->isStore()*/
774                ) {
775
776                for (int src_reg_idx = 0;
777                     src_reg_idx < squashed_inst->numSrcRegs();
778                     src_reg_idx++)
779                {
780                    PhysRegIndex src_reg =
781                        squashed_inst->renamedSrcRegIdx(src_reg_idx);
782
783                    // Only remove it from the dependency graph if it was
784                    // placed there in the first place.
785                    // HACK: This assumes that instructions woken up from the
786                    // dependency chain aren't informed that a specific src
787                    // register has become ready.  This may not always be true
788                    // in the future.
789                    if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) &&
790                        src_reg < numPhysRegs) {
791                        dependGraph[src_reg].remove(squashed_inst);
792                    }
793
794                    ++iqSquashedOperandsExamined;
795                }
796
797                // Might want to remove producers as well.
798            } else {
799                nonSpecInsts[squashed_inst->seqNum] = NULL;
800
801                nonSpecInsts.erase(squashed_inst->seqNum);
802
803                ++iqSquashedNonSpecRemoved;
804            }
805
806            // Might want to also clear out the head of the dependency graph.
807
808            // Mark it as squashed within the IQ.
809            squashed_inst->setSquashedInIQ();
810
811//            squashedInsts.push(squashed_inst);
812            squashed_inst->setIssued();
813            squashed_inst->setCanCommit();
814
815            ++freeEntries;
816
817            DPRINTF(IQ, "IQ: Instruction PC %#x squashed.\n",
818                    squashed_inst->readPC());
819        }
820
821        --squashIt;
822        ++iqSquashedInstsExamined;
823    }
824
825    assert(freeEntries <= numEntries);
826
827    if (freeEntries == numEntries) {
828        tail = cpu->instList.end();
829    }
830
831}
832
833template <class Impl>
834void
835InstructionQueue<Impl>::stopSquash()
836{
837    // Clear up the squash variables to ensure that squashing doesn't
838    // get called improperly.
839    squashedSeqNum = 0;
840
841    squashIt = cpu->instList.end();
842}
843
844template <class Impl>
845void
846InstructionQueue<Impl>::DependencyEntry::insert(DynInstPtr &new_inst)
847{
848    //Add this new, dependent instruction at the head of the dependency
849    //chain.
850
851    // First create the entry that will be added to the head of the
852    // dependency chain.
853    DependencyEntry *new_entry = new DependencyEntry;
854    new_entry->next = this->next;
855    new_entry->inst = new_inst;
856
857    // Then actually add it to the chain.
858    this->next = new_entry;
859
860    ++mem_alloc_counter;
861}
862
863template <class Impl>
864void
865InstructionQueue<Impl>::DependencyEntry::remove(DynInstPtr &inst_to_remove)
866{
867    DependencyEntry *prev = this;
868    DependencyEntry *curr = this->next;
869
870    // Make sure curr isn't NULL.  Because this instruction is being
871    // removed from a dependency list, it must have been placed there at
872    // an earlier time.  The dependency chain should not be empty,
873    // unless the instruction dependent upon it is already ready.
874    if (curr == NULL) {
875        return;
876    }
877
878    // Find the instruction to remove within the dependency linked list.
879    while(curr->inst != inst_to_remove)
880    {
881        prev = curr;
882        curr = curr->next;
883
884        assert(curr != NULL);
885    }
886
887    // Now remove this instruction from the list.
888    prev->next = curr->next;
889
890    --mem_alloc_counter;
891
892    // Could push this off to the destructor of DependencyEntry
893    curr->inst = NULL;
894
895    delete curr;
896}
897
898template <class Impl>
899bool
900InstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst)
901{
902    // Loop through the instruction's source registers, adding
903    // them to the dependency list if they are not ready.
904    int8_t total_src_regs = new_inst->numSrcRegs();
905    bool return_val = false;
906
907    for (int src_reg_idx = 0;
908         src_reg_idx < total_src_regs;
909         src_reg_idx++)
910    {
911        // Only add it to the dependency graph if it's not ready.
912        if (!new_inst->isReadySrcRegIdx(src_reg_idx)) {
913            PhysRegIndex src_reg = new_inst->renamedSrcRegIdx(src_reg_idx);
914
915            // Check the IQ's scoreboard to make sure the register
916            // hasn't become ready while the instruction was in flight
917            // between stages.  Only if it really isn't ready should
918            // it be added to the dependency graph.
919            if (src_reg >= numPhysRegs) {
920                continue;
921            } else if (regScoreboard[src_reg] == false) {
922                DPRINTF(IQ, "IQ: Instruction PC %#x has src reg %i that "
923                        "is being added to the dependency chain.\n",
924                        new_inst->readPC(), src_reg);
925
926                dependGraph[src_reg].insert(new_inst);
927
928                // Change the return value to indicate that something
929                // was added to the dependency graph.
930                return_val = true;
931            } else {
932                DPRINTF(IQ, "IQ: Instruction PC %#x has src reg %i that "
933                        "became ready before it reached the IQ.\n",
934                        new_inst->readPC(), src_reg);
935                // Mark a register ready within the instruction.
936                new_inst->markSrcRegReady();
937            }
938        }
939    }
940
941    return return_val;
942}
943
944template <class Impl>
945void
946InstructionQueue<Impl>::createDependency(DynInstPtr &new_inst)
947{
948    //Actually nothing really needs to be marked when an
949    //instruction becomes the producer of a register's value,
950    //but for convenience a ptr to the producing instruction will
951    //be placed in the head node of the dependency links.
952    int8_t total_dest_regs = new_inst->numDestRegs();
953
954    for (int dest_reg_idx = 0;
955         dest_reg_idx < total_dest_regs;
956         dest_reg_idx++)
957    {
958        PhysRegIndex dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx);
959
960        // Instructions that use the misc regs will have a reg number
961        // higher than the normal physical registers.  In this case these
962        // registers are not renamed, and there is no need to track
963        // dependencies as these instructions must be executed at commit.
964        if (dest_reg >= numPhysRegs) {
965            continue;
966        }
967
968        dependGraph[dest_reg].inst = new_inst;
969
970        if (dependGraph[dest_reg].next) {
971            dumpDependGraph();
972            panic("IQ: Dependency graph not empty!");
973        }
974
975        // Mark the scoreboard to say it's not yet ready.
976        regScoreboard[dest_reg] = false;
977    }
978}
979
980template <class Impl>
981void
982InstructionQueue<Impl>::addIfReady(DynInstPtr &inst)
983{
984    //If the instruction now has all of its source registers
985    // available, then add it to the list of ready instructions.
986    if (inst->readyToIssue()) {
987
988        //Add the instruction to the proper ready list.
989        if (inst->isControl()) {
990
991            DPRINTF(IQ, "IQ: Branch instruction is ready to issue, "
992                    "putting it onto the ready list, PC %#x.\n",
993                    inst->readPC());
994            readyBranchInsts.push(inst);
995
996        } else if (inst->isMemRef()) {
997
998            DPRINTF(IQ, "IQ: Checking if memory instruction can issue.\n");
999
1000            // Message to the mem dependence unit that this instruction has
1001            // its registers ready.
1002
1003            memDepUnit.regsReady(inst);
1004
1005#if 0
1006            if (memDepUnit.readyToIssue(inst)) {
1007                DPRINTF(IQ, "IQ: Memory instruction is ready to issue, "
1008                        "putting it onto the ready list, PC %#x.\n",
1009                        inst->readPC());
1010                readyMemInsts.push(inst);
1011            } else {
1012                // Make dependent on the store.
1013                // Will need some way to get the store instruction it should
1014                // be dependent upon; then when the store issues it can
1015                // put the instruction on the ready list.
1016                // Yet another tree?
1017                assert(0 && "Instruction has no way to actually issue");
1018            }
1019#endif
1020
1021        } else if (inst->isInteger()) {
1022
1023            DPRINTF(IQ, "IQ: Integer instruction is ready to issue, "
1024                    "putting it onto the ready list, PC %#x.\n",
1025                    inst->readPC());
1026            readyIntInsts.push(inst);
1027
1028        } else if (inst->isFloating()) {
1029
1030            DPRINTF(IQ, "IQ: Floating instruction is ready to issue, "
1031                    "putting it onto the ready list, PC %#x.\n",
1032                    inst->readPC());
1033            readyFloatInsts.push(inst);
1034
1035        } else {
1036            DPRINTF(IQ, "IQ: Miscellaneous instruction is ready to issue, "
1037                    "putting it onto the ready list, PC %#x..\n",
1038                    inst->readPC());
1039
1040            readyMiscInsts.push(inst);
1041        }
1042    }
1043}
1044
1045/*
1046 * Caution, this function must not be called prior to tail being updated at
1047 * least once, otherwise it will fail the assertion.  This is because
1048 * instList.begin() actually changes upon the insertion of an element into the
1049 * list when the list is empty.
1050 */
1051template <class Impl>
1052int
1053InstructionQueue<Impl>::countInsts()
1054{
1055    ListIt count_it = cpu->instList.begin();
1056    int total_insts = 0;
1057
1058    if (tail == cpu->instList.end())
1059        return 0;
1060
1061    while (count_it != tail) {
1062        if (!(*count_it)->isIssued()) {
1063            ++total_insts;
1064        }
1065
1066        ++count_it;
1067
1068        assert(count_it != cpu->instList.end());
1069    }
1070
1071    // Need to count the tail iterator as well.
1072    if (count_it != cpu->instList.end() &&
1073        (*count_it) &&
1074        !(*count_it)->isIssued()) {
1075        ++total_insts;
1076    }
1077
1078    return total_insts;
1079}
1080
1081template <class Impl>
1082void
1083InstructionQueue<Impl>::dumpDependGraph()
1084{
1085    DependencyEntry *curr;
1086
1087    for (int i = 0; i < numPhysRegs; ++i)
1088    {
1089        curr = &dependGraph[i];
1090
1091        if (curr->inst) {
1092            cprintf("dependGraph[%i]: producer: %#x consumer: ", i,
1093                    curr->inst->readPC());
1094        } else {
1095            cprintf("dependGraph[%i]: No producer. consumer: ", i);
1096        }
1097
1098        while (curr->next != NULL) {
1099            curr = curr->next;
1100
1101            cprintf("%#x ", curr->inst->readPC());
1102        }
1103
1104        cprintf("\n");
1105    }
1106}
1107
1108template <class Impl>
1109void
1110InstructionQueue<Impl>::dumpLists()
1111{
1112    cprintf("Ready integer list size: %i\n", readyIntInsts.size());
1113
1114    cprintf("Ready float list size: %i\n", readyFloatInsts.size());
1115
1116    cprintf("Ready branch list size: %i\n", readyBranchInsts.size());
1117
1118    cprintf("Ready misc list size: %i\n", readyMiscInsts.size());
1119
1120    cprintf("Squashed list size: %i\n", squashedInsts.size());
1121
1122    cprintf("Non speculative list size: %i\n", nonSpecInsts.size());
1123
1124    non_spec_it_t non_spec_it = nonSpecInsts.begin();
1125
1126    cprintf("Non speculative list: ");
1127
1128    while (non_spec_it != nonSpecInsts.end()) {
1129        cprintf("%#x ", (*non_spec_it).second->readPC());
1130        ++non_spec_it;
1131    }
1132
1133    cprintf("\n");
1134
1135}
1136