rename_impl.hh revision 1062
1#include <list>
2
3#include "cpu/beta_cpu/rename.hh"
4
5template <class Impl>
6SimpleRename<Impl>::SimpleRename(Params &params)
7    : iewToRenameDelay(params.iewToRenameDelay),
8      decodeToRenameDelay(params.decodeToRenameDelay),
9      commitToRenameDelay(params.commitToRenameDelay),
10      renameWidth(params.renameWidth),
11      commitWidth(params.commitWidth),
12      numInst(0)
13{
14    _status = Idle;
15}
16
17template <class Impl>
18void
19SimpleRename<Impl>::regStats()
20{
21    renameSquashCycles
22        .name(name() + ".renameSquashCycles")
23        .desc("Number of cycles rename is squashing")
24        .prereq(renameSquashCycles);
25    renameIdleCycles
26        .name(name() + ".renameIdleCycles")
27        .desc("Number of cycles rename is idle")
28        .prereq(renameIdleCycles);
29    renameBlockCycles
30        .name(name() + ".renameBlockCycles")
31        .desc("Number of cycles rename is blocking")
32        .prereq(renameBlockCycles);
33    renameUnblockCycles
34        .name(name() + ".renameUnblockCycles")
35        .desc("Number of cycles rename is unblocking")
36        .prereq(renameUnblockCycles);
37    renameRenamedInsts
38        .name(name() + ".renameRenamedInsts")
39        .desc("Number of instructions processed by rename")
40        .prereq(renameRenamedInsts);
41    renameSquashedInsts
42        .name(name() + ".renameSquashedInsts")
43        .desc("Number of squashed instructions processed by rename")
44        .prereq(renameSquashedInsts);
45    renameROBFullEvents
46        .name(name() + ".renameROBFullEvents")
47        .desc("Number of times rename has considered the ROB 'full'")
48        .prereq(renameROBFullEvents);
49    renameIQFullEvents
50        .name(name() + ".renameIQFullEvents")
51        .desc("Number of times rename has considered the IQ 'full'")
52        .prereq(renameIQFullEvents);
53    renameFullRegistersEvents
54        .name(name() + ".renameFullRegisterEvents")
55        .desc("Number of times there has been no free registers")
56        .prereq(renameFullRegistersEvents);
57    renameRenamedOperands
58        .name(name() + ".renameRenamedOperands")
59        .desc("Number of destination operands rename has renamed")
60        .prereq(renameRenamedOperands);
61    renameRenameLookups
62        .name(name() + ".renameRenameLookups")
63        .desc("Number of register rename lookups that rename has made")
64        .prereq(renameRenameLookups);
65    renameHBPlaceHolders
66        .name(name() + ".renameHBPlaceHolders")
67        .desc("Number of place holders added to the history buffer")
68        .prereq(renameHBPlaceHolders);
69    renameCommittedMaps
70        .name(name() + ".renameCommittedMaps")
71        .desc("Number of HB maps that are committed")
72        .prereq(renameCommittedMaps);
73    renameUndoneMaps
74        .name(name() + ".renameUndoneMaps")
75        .desc("Number of HB maps that are undone due to squashing")
76        .prereq(renameUndoneMaps);
77    renameValidUndoneMaps
78        .name(name() + ".renameValidUndoneMaps")
79        .desc("Number of HB maps that are undone, and are not place holders")
80        .prereq(renameValidUndoneMaps);
81}
82
83template <class Impl>
84void
85SimpleRename<Impl>::setCPU(FullCPU *cpu_ptr)
86{
87    DPRINTF(Rename, "Rename: Setting CPU pointer.\n");
88    cpu = cpu_ptr;
89}
90
91template <class Impl>
92void
93SimpleRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
94{
95    DPRINTF(Rename, "Rename: Setting time buffer pointer.\n");
96    timeBuffer = tb_ptr;
97
98    // Setup wire to read information from time buffer, from IEW stage.
99    fromIEW = timeBuffer->getWire(-iewToRenameDelay);
100
101    // Setup wire to read infromation from time buffer, from commit stage.
102    fromCommit = timeBuffer->getWire(-commitToRenameDelay);
103
104    // Setup wire to write information to previous stages.
105    toDecode = timeBuffer->getWire(0);
106}
107
108template <class Impl>
109void
110SimpleRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
111{
112    DPRINTF(Rename, "Rename: Setting rename queue pointer.\n");
113    renameQueue = rq_ptr;
114
115    // Setup wire to write information to future stages.
116    toIEW = renameQueue->getWire(0);
117}
118
119template <class Impl>
120void
121SimpleRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr)
122{
123    DPRINTF(Rename, "Rename: Setting decode queue pointer.\n");
124    decodeQueue = dq_ptr;
125
126    // Setup wire to get information from decode.
127    fromDecode = decodeQueue->getWire(-decodeToRenameDelay);
128}
129
130template <class Impl>
131void
132SimpleRename<Impl>::setRenameMap(RenameMap *rm_ptr)
133{
134    DPRINTF(Rename, "Rename: Setting rename map pointer.\n");
135    renameMap = rm_ptr;
136}
137
138template <class Impl>
139void
140SimpleRename<Impl>::setFreeList(FreeList *fl_ptr)
141{
142    DPRINTF(Rename, "Rename: Setting free list pointer.\n");
143    freeList = fl_ptr;
144}
145
146template <class Impl>
147void
148SimpleRename<Impl>::dumpHistory()
149{
150    typename list<RenameHistory>::iterator buf_it = historyBuffer.begin();
151
152    while (buf_it != historyBuffer.end())
153    {
154        cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys "
155                "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg,
156                (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);
157
158        buf_it++;
159    }
160}
161
162template <class Impl>
163void
164SimpleRename<Impl>::block()
165{
166    DPRINTF(Rename, "Rename: Blocking.\n");
167    // Set status to Blocked.
168    _status = Blocked;
169
170    // Add the current inputs onto the skid buffer, so they can be
171    // reprocessed when this stage unblocks.
172    skidBuffer.push(*fromDecode);
173
174    // Note that this stage only signals previous stages to stall when
175    // it is the cause of the stall originates at this stage.  Otherwise
176    // the previous stages are expected to check all possible stall signals.
177}
178
179template <class Impl>
180inline void
181SimpleRename<Impl>::unblock()
182{
183    DPRINTF(Rename, "Rename: Read instructions out of skid buffer this "
184            "cycle.\n");
185    // Remove the now processed instructions from the skid buffer.
186    skidBuffer.pop();
187
188    // If there's still information in the skid buffer, then
189    // continue to tell previous stages to stall.  They will be
190    // able to restart once the skid buffer is empty.
191    if (!skidBuffer.empty()) {
192        toDecode->renameInfo.stall = true;
193    } else {
194        DPRINTF(Rename, "Rename: Done unblocking.\n");
195        _status = Running;
196    }
197}
198
199template <class Impl>
200void
201SimpleRename<Impl>::doSquash()
202{
203    typename list<RenameHistory>::iterator hb_it = historyBuffer.begin();
204
205    InstSeqNum squashed_seq_num = fromCommit->commitInfo.doneSeqNum;
206
207#ifdef FULL_SYSTEM
208    assert(!historyBuffer.empty());
209#else
210    // After a syscall squashes everything, the history buffer may be empty
211    // but the ROB may still be squashing instructions.
212    if (historyBuffer.empty()) {
213        return;
214    }
215#endif // FULL_SYSTEM
216
217    // Go through the most recent instructions, undoing the mappings
218    // they did and freeing up the registers.
219    while ((*hb_it).instSeqNum > squashed_seq_num)
220    {
221        assert(hb_it != historyBuffer.end());
222
223        DPRINTF(Rename, "Rename: Removing history entry with sequence "
224                "number %i.\n", (*hb_it).instSeqNum);
225
226        // If it's not simply a place holder, then add the registers.
227        if (!(*hb_it).placeHolder) {
228            // Tell the rename map to set the architected register to the
229            // previous physical register that it was renamed to.
230            renameMap->setEntry(hb_it->archReg, hb_it->prevPhysReg);
231
232            // Put the renamed physical register back on the free list.
233            freeList->addReg(hb_it->newPhysReg);
234
235            ++renameValidUndoneMaps;
236        }
237
238        historyBuffer.erase(hb_it++);
239
240        ++renameUndoneMaps;
241    }
242}
243
244template <class Impl>
245void
246SimpleRename<Impl>::squash()
247{
248    DPRINTF(Rename, "Rename: Squashing instructions.\n");
249    // Set the status to Squashing.
250    _status = Squashing;
251
252    numInst = 0;
253
254    // Clear the skid buffer in case it has any data in it.
255    while (!skidBuffer.empty())
256    {
257        skidBuffer.pop();
258    }
259
260    doSquash();
261}
262
263template<class Impl>
264void
265SimpleRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num)
266{
267    DPRINTF(Rename, "Rename: Removing a committed instruction from the "
268            "history buffer, until sequence number %lli.\n", inst_seq_num);
269    typename list<RenameHistory>::iterator hb_it = historyBuffer.end();
270
271    --hb_it;
272
273    if (hb_it->instSeqNum > inst_seq_num) {
274        DPRINTF(Rename, "Rename: Old sequence number encountered.  Ensure "
275                "that a syscall happened recently.\n");
276        return;
277    }
278
279    while ((*hb_it).instSeqNum != inst_seq_num)
280    {
281        // Make sure we haven't gone off the end of the list.
282        assert(hb_it != historyBuffer.end());
283
284        // In theory instructions at the end of the history buffer
285        // should be older than the instruction being removed, which
286        // means they will have a lower sequence number.  Also the
287        // instruction being removed from the history really should
288        // be the last instruction in the list, as it is the instruction
289        // that was just committed that is being removed.
290        assert(hb_it->instSeqNum < inst_seq_num);
291        DPRINTF(Rename, "Rename: Freeing up older rename of reg %i, sequence"
292                " number %i.\n",
293                (*hb_it).prevPhysReg, (*hb_it).instSeqNum);
294
295        if (!(*hb_it).placeHolder) {
296            freeList->addReg((*hb_it).prevPhysReg);
297            ++renameCommittedMaps;
298        }
299
300        historyBuffer.erase(hb_it--);
301    }
302
303    // Finally free up the previous register of the finished instruction
304    // itself.
305    if (!(*hb_it).placeHolder) {
306        freeList->addReg(hb_it->prevPhysReg);
307        ++renameCommittedMaps;
308    }
309
310    historyBuffer.erase(hb_it);
311}
312
313template <class Impl>
314inline void
315SimpleRename<Impl>::renameSrcRegs(DynInstPtr &inst)
316{
317    unsigned num_src_regs = inst->numSrcRegs();
318
319    // Get the architectual register numbers from the source and
320    // destination operands, and redirect them to the right register.
321    // Will need to mark dependencies though.
322    for (int src_idx = 0; src_idx < num_src_regs; src_idx++)
323    {
324        RegIndex src_reg = inst->srcRegIdx(src_idx);
325
326        // Look up the source registers to get the phys. register they've
327        // been renamed to, and set the sources to those registers.
328        PhysRegIndex renamed_reg = renameMap->lookup(src_reg);
329
330        DPRINTF(Rename, "Rename: Looking up arch reg %i, got "
331                "physical reg %i.\n", (int)src_reg, (int)renamed_reg);
332
333        inst->renameSrcReg(src_idx, renamed_reg);
334
335        // Either incorporate it into the info passed back,
336        // or make another function call to see if that register is
337        // ready or not.
338        if (renameMap->isReady(renamed_reg)) {
339            DPRINTF(Rename, "Rename: Register is ready.\n");
340
341            inst->markSrcRegReady(src_idx);
342        }
343
344        ++renameRenameLookups;
345    }
346}
347
348template <class Impl>
349inline void
350SimpleRename<Impl>::renameDestRegs(DynInstPtr &inst)
351{
352    typename SimpleRenameMap::RenameInfo rename_result;
353
354    unsigned num_dest_regs = inst->numDestRegs();
355
356    // If it's an instruction with no destination registers, then put
357    // a placeholder within the history buffer.  It might be better
358    // to not put it in the history buffer at all (other than branches,
359    // which always need at least a place holder), and differentiate
360    // between instructions with and without destination registers
361    // when getting from commit the instructions that committed.
362    if (num_dest_regs == 0) {
363        RenameHistory hb_entry(inst->seqNum);
364
365        historyBuffer.push_front(hb_entry);
366
367        DPRINTF(Rename, "Rename: Adding placeholder instruction to "
368                "history buffer, sequence number %lli.\n",
369                inst->seqNum);
370
371        ++renameHBPlaceHolders;
372    } else {
373
374        // Rename the destination registers.
375        for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++)
376        {
377            RegIndex dest_reg = inst->destRegIdx(dest_idx);
378
379            // Get the physical register that the destination will be
380            // renamed to.
381            rename_result = renameMap->rename(dest_reg);
382
383            DPRINTF(Rename, "Rename: Renaming arch reg %i to physical "
384                    "reg %i.\n", (int)dest_reg,
385                    (int)rename_result.first);
386
387            // Record the rename information so that a history can be kept.
388            RenameHistory hb_entry(inst->seqNum, dest_reg,
389                                   rename_result.first,
390                                   rename_result.second);
391
392            historyBuffer.push_front(hb_entry);
393
394            DPRINTF(Rename, "Rename: Adding instruction to history buffer, "
395                    "sequence number %lli.\n",
396                    (*historyBuffer.begin()).instSeqNum);
397
398            // Tell the instruction to rename the appropriate destination
399            // register (dest_idx) to the new physical register
400            // (rename_result.first), and record the previous physical
401            // register that the same logical register was renamed to
402            // (rename_result.second).
403            inst->renameDestReg(dest_idx,
404                                rename_result.first,
405                                rename_result.second);
406
407            ++renameRenamedOperands;
408        }
409    }
410}
411
412template <class Impl>
413inline int
414SimpleRename<Impl>::calcFreeROBEntries()
415{
416    return fromCommit->commitInfo.freeROBEntries -
417        renameWidth * iewToRenameDelay;
418}
419
420template <class Impl>
421inline int
422SimpleRename<Impl>::calcFreeIQEntries()
423{
424    return fromIEW->iewInfo.freeIQEntries - renameWidth * iewToRenameDelay;
425}
426
427template<class Impl>
428void
429SimpleRename<Impl>::tick()
430{
431    // Rename will need to try to rename as many instructions as it
432    // has bandwidth, unless it is blocked.
433
434    // Check if _status is BarrierStall.  If so, then check if the number
435    // of free ROB entries is equal to the number of total ROB entries.
436    // Once equal then wake this stage up.  Set status to unblocking maybe.
437
438    if (_status != Blocked && _status != Squashing) {
439        DPRINTF(Rename, "Rename: Status is not blocked, will attempt to "
440                        "run stage.\n");
441        // Make sure that the skid buffer has something in it if the
442        // status is unblocking.
443        assert(_status == Unblocking ? !skidBuffer.empty() : 1);
444
445        rename();
446
447        // If the status was unblocking, then instructions from the skid
448        // buffer were used.  Remove those instructions and handle
449        // the rest of unblocking.
450        if (_status == Unblocking) {
451            ++renameUnblockCycles;
452
453            if (fromDecode->size > 0) {
454                // Add the current inputs onto the skid buffer, so they can be
455                // reprocessed when this stage unblocks.
456                skidBuffer.push(*fromDecode);
457            }
458
459            unblock();
460        }
461    } else if (_status == Blocked) {
462        ++renameBlockCycles;
463
464        // If stage is blocked and still receiving valid instructions,
465        // make sure to store them in the skid buffer.
466        if (fromDecode->size > 0) {
467
468            block();
469
470            // Continue to tell previous stage to stall.
471            toDecode->renameInfo.stall = true;
472        }
473
474        if (!fromIEW->iewInfo.stall &&
475            !fromCommit->commitInfo.stall &&
476            calcFreeROBEntries() > 0 &&
477            calcFreeIQEntries() > 0 &&
478            renameMap->numFreeEntries() > 0) {
479
480            // Need to be sure to check all blocking conditions above.
481            // If they have cleared, then start unblocking.
482            DPRINTF(Rename, "Rename: Stall signals cleared, going to "
483                    "unblock.\n");
484            _status = Unblocking;
485
486            // Continue to tell previous stage to block until this stage
487            // is done unblocking.
488            toDecode->renameInfo.stall = true;
489        } else {
490            // Otherwise no conditions have changed.  Tell previous
491            // stage to continue blocking.
492            toDecode->renameInfo.stall = true;
493        }
494
495        if (fromCommit->commitInfo.squash ||
496            fromCommit->commitInfo.robSquashing) {
497            squash();
498            return;
499        }
500    } else if (_status == Squashing) {
501        ++renameSquashCycles;
502
503        if (fromCommit->commitInfo.squash) {
504            squash();
505        } else if (!fromCommit->commitInfo.squash &&
506                   !fromCommit->commitInfo.robSquashing) {
507
508            DPRINTF(Rename, "Rename: Done squashing, going to running.\n");
509            _status = Running;
510        } else {
511            doSquash();
512        }
513    }
514
515    // Ugly code, revamp all of the tick() functions eventually.
516    if (fromCommit->commitInfo.doneSeqNum != 0 && _status != Squashing) {
517#ifndef FULL_SYSTEM
518        if (!fromCommit->commitInfo.squash) {
519            removeFromHistory(fromCommit->commitInfo.doneSeqNum);
520        }
521#else
522        removeFromHistory(fromCommit->commitInfo.doneSeqNum);
523#endif
524    }
525
526    // Perhaps put this outside of this function, since this will
527    // happen regardless of whether or not the stage is blocked or
528    // squashing.
529    // Read from the time buffer any necessary data.
530    // Read registers that are freed, and add them to the freelist.
531    // This is unnecessary due to the history buffer (assuming the history
532    // buffer works properly).
533/*
534    while(!fromCommit->commitInfo.freeRegs.empty())
535    {
536        PhysRegIndex freed_reg = fromCommit->commitInfo.freeRegs.back();
537        DPRINTF(Rename, "Rename: Adding freed register %i to freelist.\n",
538                (int)freed_reg);
539        freeList->addReg(freed_reg);
540
541        fromCommit->commitInfo.freeRegs.pop_back();
542    }
543*/
544
545}
546
547template<class Impl>
548void
549SimpleRename<Impl>::rename()
550{
551    // Check if any of the stages ahead of rename are telling rename
552    // to squash.  The squash() function will also take care of fixing up
553    // the rename map and the free list.
554    if (fromCommit->commitInfo.squash ||
555        fromCommit->commitInfo.robSquashing) {
556        DPRINTF(Rename, "Rename: Receiving signal from Commit to squash.\n");
557        squash();
558        return;
559    }
560
561    // Check if time buffer is telling this stage to stall.
562    if (fromIEW->iewInfo.stall ||
563        fromCommit->commitInfo.stall) {
564        DPRINTF(Rename, "Rename: Receiving signal from IEW/Commit to "
565                        "stall.\n");
566        block();
567        return;
568    }
569
570    // Check if the current status is squashing.  If so, set its status
571    // to running and resume execution the next cycle.
572    if (_status == Squashing) {
573        DPRINTF(Rename, "Rename: Done squashing.\n");
574        _status = Running;
575        return;
576    }
577
578    // Check the decode queue to see if instructions are available.
579    // If there are no available instructions to rename, then do nothing.
580    // Or, if the stage is currently unblocking, then go ahead and run it.
581    if (fromDecode->size == 0 && _status != Unblocking) {
582        DPRINTF(Rename, "Rename: Nothing to do, breaking out early.\n");
583        // Should I change status to idle?
584        return;
585    }
586
587    ////////////////////////////////////
588    // Actual rename part.
589    ////////////////////////////////////
590
591    DynInstPtr inst;
592
593    // If we're unblocking, then we may be in the middle of an instruction
594    // group.  Subtract off numInst to get the proper number of instructions
595    // left.
596    int insts_available = _status == Unblocking ?
597        skidBuffer.front().size - numInst :
598        fromDecode->size;
599
600    bool block_this_cycle = false;
601
602    // Will have to do a different calculation for the number of free
603    // entries.  Number of free entries recorded on this cycle -
604    // renameWidth * renameToDecodeDelay
605    int free_rob_entries = calcFreeROBEntries();
606    int free_iq_entries = calcFreeIQEntries();
607    int min_iq_rob = min(free_rob_entries, free_iq_entries);
608
609    unsigned to_iew_index = 0;
610
611    // Check if there's any space left.
612    if (min_iq_rob <= 0) {
613        DPRINTF(Rename, "Rename: Blocking due to no free ROB or IQ "
614                "entries.\n"
615                "Rename: ROB has %d free entries.\n"
616                "Rename: IQ has %d free entries.\n",
617                free_rob_entries,
618                free_iq_entries);
619        block();
620        // Tell previous stage to stall.
621        toDecode->renameInfo.stall = true;
622
623        if (free_rob_entries <= 0) {
624            ++renameROBFullEvents;
625        } else {
626            ++renameIQFullEvents;
627        }
628
629        return;
630    } else if (min_iq_rob < insts_available) {
631        DPRINTF(Rename, "Rename: Will have to block this cycle.  Only "
632                "%i insts can be renamed due to IQ/ROB limits.\n",
633                min_iq_rob);
634
635        insts_available = min_iq_rob;
636
637        block_this_cycle = true;
638
639        if (free_rob_entries < free_iq_entries) {
640            ++renameROBFullEvents;
641        } else {
642            ++renameIQFullEvents;
643        }
644    }
645
646    while (insts_available > 0) {
647        DPRINTF(Rename, "Rename: Sending instructions to iew.\n");
648
649        // Get the next instruction either from the skid buffer or the
650        // decode queue.
651        inst = _status == Unblocking ? skidBuffer.front().insts[numInst] :
652               fromDecode->insts[numInst];
653
654        if (inst->isSquashed()) {
655            DPRINTF(Rename, "Rename: instruction %i with PC %#x is "
656                    "squashed, skipping.\n",
657                    inst->seqNum, inst->readPC());
658
659            // Go to the next instruction.
660            ++numInst;
661
662            ++renameSquashedInsts;
663
664            // Decrement how many instructions are available.
665            --insts_available;
666
667            continue;
668        }
669
670        DPRINTF(Rename, "Rename: Processing instruction %i with PC %#x.\n",
671                inst->seqNum, inst->readPC());
672
673        // If it's a trap instruction, then it needs to wait here within
674        // rename until the ROB is empty.  Needs a way to detect that the
675        // ROB is empty.  Maybe an event?
676        // Would be nice if it could be avoided putting this into a
677        // specific stage and instead just put it into the AlphaFullCPU.
678        // Might not really be feasible though...
679        // (EXCB, TRAPB)
680        if (inst->isSerializing()) {
681            panic("Rename: Serializing instruction encountered.\n");
682            DPRINTF(Rename, "Rename: Serializing instruction "
683                            "encountered.\n");
684
685            // Change status over to BarrierStall so that other stages know
686            // what this is blocked on.
687            _status = BarrierStall;
688
689            block_this_cycle = true;
690
691            break;
692        }
693
694        // Check here to make sure there are enough destination registers
695        // to rename to.  Otherwise block.
696        if (renameMap->numFreeEntries() < inst->numDestRegs())
697        {
698            DPRINTF(Rename, "Rename: Blocking due to lack of free "
699                            "physical registers to rename to.\n");
700            // Need some sort of event based on a register being freed.
701
702            block_this_cycle = true;
703
704            ++renameFullRegistersEvents;
705
706            break;
707        }
708
709        renameSrcRegs(inst);
710
711        renameDestRegs(inst);
712
713        // Put instruction in rename queue.
714        toIEW->insts[to_iew_index] = inst;
715        ++(toIEW->size);
716
717        // Decrease the number of free ROB and IQ entries.
718        --free_rob_entries;
719        --free_iq_entries;
720
721        // Increment which instruction we're on.
722        ++to_iew_index;
723        ++numInst;
724
725        ++renameRenamedInsts;
726
727        // Decrement how many instructions are available.
728        --insts_available;
729    }
730
731    // Check if there's any instructions left that haven't yet been renamed.
732    // If so then block.
733    if (block_this_cycle) {
734        block();
735
736        toDecode->renameInfo.stall = true;
737    } else {
738        // If we had a successful rename and didn't have to exit early, then
739        // reset numInst so it will refer to the correct instruction on next
740        // run.
741        numInst = 0;
742    }
743}
744