InOrder: Import new inorder CPU model from MIPS.
[gem5.git] / src / cpu / inorder / inorder_dyn_inst.cc
1 /*
2 * Copyright (c) 2007 MIPS Technologies, Inc.
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 * Authors: Korey Sewell
29 *
30 */
31
32 #include <iostream>
33 #include <set>
34 #include <string>
35 #include <sstream>
36
37 #include "base/cprintf.hh"
38 #include "base/trace.hh"
39
40 #include "arch/faults.hh"
41 #include "cpu/exetrace.hh"
42 #include "mem/request.hh"
43
44 #include "cpu/inorder/inorder_dyn_inst.hh"
45 #include "cpu/inorder/cpu.hh"
46
47 using namespace std;
48 using namespace TheISA;
49 using namespace ThePipeline;
50
51 InOrderDynInst::InOrderDynInst(TheISA::ExtMachInst machInst, Addr inst_PC,
52 Addr pred_PC, InstSeqNum seq_num,
53 InOrderCPU *cpu)
54 : staticInst(machInst, inst_PC), traceData(NULL), cpu(cpu)
55 {
56 seqNum = seq_num;
57
58 PC = inst_PC;
59 nextPC = PC + sizeof(MachInst);
60 nextNPC = nextPC + sizeof(MachInst);
61 predPC = pred_PC;
62
63 initVars();
64 }
65
66 InOrderDynInst::InOrderDynInst(InOrderCPU *cpu,
67 InOrderThreadState *state,
68 InstSeqNum seq_num,
69 unsigned tid)
70 : traceData(NULL), cpu(cpu)
71 {
72 seqNum = seq_num;
73 thread = state;
74 threadNumber = tid;
75 initVars();
76 }
77
78 InOrderDynInst::InOrderDynInst(StaticInstPtr &_staticInst)
79 : staticInst(_staticInst), traceData(NULL)
80 {
81 seqNum = 0;
82 initVars();
83 }
84
85 InOrderDynInst::InOrderDynInst()
86 : traceData(NULL), cpu(cpu)
87 { initVars(); }
88
89 int InOrderDynInst::instcount = 0;
90
91
92 void
93 InOrderDynInst::setMachInst(ExtMachInst machInst)
94 {
95 staticInst = StaticInst::decode(machInst, PC);
96
97 for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
98 _destRegIdx[i] = this->staticInst->destRegIdx(i);
99 }
100
101 for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
102 _srcRegIdx[i] = this->staticInst->srcRegIdx(i);
103 this->_readySrcRegIdx[i] = 0;
104 }
105 }
106
107 void
108 InOrderDynInst::initVars()
109 {
110 req = NULL;
111 effAddr = 0;
112 physEffAddr = 0;
113
114 readyRegs = 0;
115
116 nextStage = 0;
117 nextInstStageNum = 0;
118
119 for(int i = 0; i < MaxInstDestRegs; i++)
120 instResult[i].val.integer = 0;
121
122 status.reset();
123
124 memAddrReady = false;
125 eaCalcDone = false;
126 memOpDone = false;
127
128 predictTaken = false;
129 procDelaySlotOnMispred = false;
130
131 lqIdx = -1;
132 sqIdx = -1;
133
134 // Also make this a parameter, or perhaps get it from xc or cpu.
135 asid = 0;
136
137 virtProcNumber = 0;
138
139 // Initialize the fault to be NoFault.
140 fault = NoFault;
141
142 // Make sure to have the renamed register entries set to the same
143 // as the normal register entries. It will allow the IQ to work
144 // without any modifications.
145 if (this->staticInst) {
146 for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
147 _destRegIdx[i] = this->staticInst->destRegIdx(i);
148 }
149
150 for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
151 _srcRegIdx[i] = this->staticInst->srcRegIdx(i);
152 this->_readySrcRegIdx[i] = 0;
153 }
154 }
155
156 // Update Instruction Count for this instruction
157 ++instcount;
158 if (instcount > 500) {
159 fatal("Number of Active Instructions in CPU is too high. "
160 "(Not Dereferencing Ptrs. Correctly?)\n");
161 }
162
163
164
165 DPRINTF(InOrderDynInst, "DynInst: [tid:%i] [sn:%lli] Instruction created. (active insts: %i)\n",
166 threadNumber, seqNum, instcount);
167
168 #ifdef DEBUG
169 cpu->snList.insert(seqNum);
170 #endif
171 }
172
173
174 InOrderDynInst::~InOrderDynInst()
175 {
176 if (req) {
177 delete req;
178 }
179
180 if (traceData) {
181 delete traceData;
182 }
183
184 fault = NoFault;
185
186 --instcount;
187
188 deleteStages();
189
190 DPRINTF(InOrderDynInst, "DynInst: [tid:%i] [sn:%lli] Instruction destroyed. (active insts: %i)\n",
191 threadNumber, seqNum, instcount);
192 #ifdef DEBUG
193 cpu->snList.erase(seqNum);
194 #endif
195 }
196
197 void
198 InOrderDynInst::setStaticInst(StaticInstPtr &static_inst)
199 {
200 this->staticInst = static_inst;
201
202 // Make sure to have the renamed register entries set to the same
203 // as the normal register entries. It will allow the IQ to work
204 // without any modifications.
205 if (this->staticInst) {
206 for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
207 _destRegIdx[i] = this->staticInst->destRegIdx(i);
208 }
209
210 for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
211 _srcRegIdx[i] = this->staticInst->srcRegIdx(i);
212 this->_readySrcRegIdx[i] = 0;
213 }
214 }
215 }
216
217 Fault
218 InOrderDynInst::execute()
219 {
220 // @todo: Pretty convoluted way to avoid squashing from happening
221 // when using the TC during an instruction's execution
222 // (specifically for instructions that have side-effects that use
223 // the TC). Fix this.
224 bool in_syscall = this->thread->inSyscall;
225 this->thread->inSyscall = true;
226
227 this->fault = this->staticInst->execute(this, this->traceData);
228
229 this->thread->inSyscall = in_syscall;
230
231 return this->fault;
232 }
233
234 Fault
235 InOrderDynInst::initiateAcc()
236 {
237 // @todo: Pretty convoluted way to avoid squashing from happening
238 // when using the TC during an instruction's execution
239 // (specifically for instructions that have side-effects that use
240 // the TC). Fix this.
241 bool in_syscall = this->thread->inSyscall;
242 this->thread->inSyscall = true;
243
244 this->fault = this->staticInst->initiateAcc(this, this->traceData);
245
246 this->thread->inSyscall = in_syscall;
247
248 return this->fault;
249 }
250
251
252 Fault
253 InOrderDynInst::completeAcc(Packet *pkt)
254 {
255 this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
256
257 return this->fault;
258 }
259
260 InstStage *InOrderDynInst::addStage()
261 {
262 this->currentInstStage = new InstStage(this, nextInstStageNum++);
263 instStageList.push_back( this->currentInstStage );
264 return this->currentInstStage;
265 }
266
267 InstStage *InOrderDynInst::addStage(int stage_num)
268 {
269 nextInstStageNum = stage_num;
270 return InOrderDynInst::addStage();
271 }
272
273 void InOrderDynInst::deleteStages() {
274 std::list<InstStage*>::iterator list_it = instStageList.begin();
275 std::list<InstStage*>::iterator list_end = instStageList.end();
276
277 while(list_it != list_end) {
278 delete *list_it;
279 list_it++;
280 }
281 }
282
283 Fault
284 InOrderDynInst::calcEA()
285 {
286 return staticInst->eaCompInst()->execute(this, this->traceData);
287 }
288
289 Fault
290 InOrderDynInst::memAccess()
291 {
292 //return staticInst->memAccInst()->execute(this, this->traceData);
293 return initiateAcc( );
294 }
295
296 void
297 InOrderDynInst::syscall(int64_t callnum)
298 {
299 cpu->syscall(callnum, this->threadNumber);
300 }
301
302 void
303 InOrderDynInst::prefetch(Addr addr, unsigned flags)
304 {
305 // This is the "functional" implementation of prefetch. Not much
306 // happens here since prefetches don't affect the architectural
307 // state.
308 /*
309 // Generate a MemReq so we can translate the effective address.
310 MemReqPtr req = new MemReq(addr, thread->getXCProxy(), 1, flags);
311 req->asid = asid;
312
313 // Prefetches never cause faults.
314 fault = NoFault;
315
316 // note this is a local, not InOrderDynInst::fault
317 Fault trans_fault = cpu->translateDataReadReq(req);
318
319 if (trans_fault == NoFault && !(req->flags & UNCACHEABLE)) {
320 // It's a valid address to cacheable space. Record key MemReq
321 // parameters so we can generate another one just like it for
322 // the timing access without calling translate() again (which
323 // might mess up the TLB).
324 effAddr = req->vaddr;
325 physEffAddr = req->paddr;
326 memReqFlags = req->flags;
327 } else {
328 // Bogus address (invalid or uncacheable space). Mark it by
329 // setting the eff_addr to InvalidAddr.
330 effAddr = physEffAddr = MemReq::inval_addr;
331 }
332
333 if (traceData) {
334 traceData->setAddr(addr);
335 }
336 */
337 }
338
339 void
340 InOrderDynInst::writeHint(Addr addr, int size, unsigned flags)
341 {
342 // Not currently supported.
343 }
344
345 /**
346 * @todo Need to find a way to get the cache block size here.
347 */
348 Fault
349 InOrderDynInst::copySrcTranslate(Addr src)
350 {
351 // Not currently supported.
352 return NoFault;
353 }
354
355 /**
356 * @todo Need to find a way to get the cache block size here.
357 */
358 Fault
359 InOrderDynInst::copy(Addr dest)
360 {
361 // Not currently supported.
362 return NoFault;
363 }
364
365 void
366 InOrderDynInst::releaseReq(ResourceRequest* req)
367 {
368 std::list<ResourceRequest*>::iterator list_it = reqList.begin();
369 std::list<ResourceRequest*>::iterator list_end = reqList.end();
370
371 while(list_it != list_end) {
372 if((*list_it)->getResIdx() == req->getResIdx() &&
373 (*list_it)->getSlot() == req->getSlot()) {
374 DPRINTF(InOrderDynInst, "[tid:%u]: [sn:%i] Done with request to %s.\n",
375 threadNumber, seqNum, req->res->name());
376 reqList.erase(list_it);
377 return;
378 }
379 list_it++;
380 }
381
382 panic("Releasing Res. Request That Isnt There!\n");
383 }
384
385 /** Records an integer source register being set to a value. */
386 void
387 InOrderDynInst::setIntSrc(int idx, uint64_t val)
388 {
389 DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Source Value %i being set to %#x.\n",
390 threadNumber, seqNum, idx, val);
391 instSrc[idx].integer = val;
392 }
393
394 /** Records an fp register being set to a value. */
395 void
396 InOrderDynInst::setFloatSrc(int idx, FloatReg val, int width)
397 {
398 if (width == 32)
399 instSrc[idx].fp = val;
400 else if (width == 64)
401 instSrc[idx].dbl = val;
402 else
403 panic("Unsupported width!");
404 }
405
406 /** Records an fp register being set to an integer value. */
407 void
408 InOrderDynInst::setFloatRegBitsSrc(int idx, uint64_t val)
409 {
410 instSrc[idx].integer = val;
411 }
412
413 /** Reads a integer register. */
414 IntReg
415 InOrderDynInst::readIntRegOperand(const StaticInst *si, int idx, unsigned tid)
416 {
417 DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Source Value %i read as %#x.\n",
418 threadNumber, seqNum, idx, instSrc[idx].integer);
419 return instSrc[idx].integer;
420 }
421
422 /** Reads a FP register. */
423 FloatReg
424 InOrderDynInst::readFloatRegOperand(const StaticInst *si, int idx, int width)
425 {
426 return instSrc[idx].fp;
427 }
428
429
430 /** Reads a FP register as a integer. */
431 FloatRegBits
432 InOrderDynInst::readFloatRegOperandBits(const StaticInst *si, int idx, int width)
433 {
434 return instSrc[idx].integer;
435 }
436
437 /** Reads a miscellaneous register. */
438 MiscReg
439 InOrderDynInst::readMiscReg(int misc_reg)
440 {
441 return this->cpu->readMiscReg(misc_reg, threadNumber);
442 }
443
444 /** Reads a misc. register, including any side-effects the read
445 * might have as defined by the architecture.
446 */
447 MiscReg
448 InOrderDynInst::readMiscRegNoEffect(int misc_reg)
449 {
450 return this->cpu->readMiscRegNoEffect(misc_reg, threadNumber);
451 }
452
453 /** Reads a miscellaneous register. */
454 MiscReg
455 InOrderDynInst::readMiscRegOperandNoEffect(const StaticInst *si, int idx)
456 {
457 return this->cpu->readMiscRegNoEffect(
458 si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
459 this->threadNumber);
460 }
461
462 /** Reads a misc. register, including any side-effects the read
463 * might have as defined by the architecture.
464 */
465 MiscReg
466 InOrderDynInst::readMiscRegOperand(const StaticInst *si, int idx)
467 {
468 return this->cpu->readMiscReg(
469 si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
470 this->threadNumber);
471 }
472
473 /** Sets a misc. register. */
474 void
475 InOrderDynInst::setMiscRegOperandNoEffect(const StaticInst * si, int idx, const MiscReg &val)
476 {
477 instResult[si->destRegIdx(idx)].val.integer = val;
478 instResult[si->destRegIdx(idx)].tick = curTick;
479
480 this->cpu->setMiscRegNoEffect(
481 si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
482 val, this->threadNumber);
483 }
484
485 /** Sets a misc. register, including any side-effects the write
486 * might have as defined by the architecture.
487 */
488 void
489 InOrderDynInst::setMiscRegOperand(const StaticInst *si, int idx,
490 const MiscReg &val)
491 {
492 instResult[si->destRegIdx(idx)].val.integer = val;
493 instResult[si->destRegIdx(idx)].tick = curTick;
494
495 this->cpu->setMiscReg(
496 si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
497 val, this->threadNumber);
498 }
499
500 MiscReg
501 InOrderDynInst::readRegOtherThread(unsigned reg_idx, int tid)
502 {
503 if (tid == -1) {
504 tid = TheISA::getTargetThread(this->cpu->tcBase(threadNumber));
505 }
506
507 if (reg_idx < FP_Base_DepTag) { // Integer Register File
508 return this->cpu->readIntReg(reg_idx, tid);
509 } else if (reg_idx < Ctrl_Base_DepTag) { // Float Register File
510 reg_idx -= FP_Base_DepTag;
511 return this->cpu->readFloatRegBits(reg_idx, tid);
512 } else {
513 reg_idx -= Ctrl_Base_DepTag;
514 return this->cpu->readMiscReg(reg_idx, tid); // Misc. Register File
515 }
516 }
517
518 /** Sets a Integer register. */
519 void
520 InOrderDynInst::setIntRegOperand(const StaticInst *si, int idx, IntReg val)
521 {
522 instResult[idx].val.integer = val;
523 instResult[idx].tick = curTick;
524 }
525
526 /** Sets a FP register. */
527 void
528 InOrderDynInst::setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, int width)
529 {
530 if (width == 32)
531 instResult[idx].val.fp = val;
532 else if (width == 64)
533 instResult[idx].val.dbl = val;
534 else
535 panic("Unsupported Floating Point Width!");
536
537 instResult[idx].tick = curTick;
538 }
539
540 /** Sets a FP register as a integer. */
541 void
542 InOrderDynInst::setFloatRegOperandBits(const StaticInst *si, int idx,
543 FloatRegBits val, int width)
544 {
545 instResult[idx].val.integer = val;
546 instResult[idx].tick = curTick;
547 }
548
549 /** Sets a misc. register. */
550 /* Alter this when wanting to *speculate* on Miscellaneous registers */
551 void
552 InOrderDynInst::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
553 {
554 this->cpu->setMiscRegNoEffect(misc_reg, val, threadNumber);
555 }
556
557 /** Sets a misc. register, including any side-effects the write
558 * might have as defined by the architecture.
559 */
560 /* Alter this if/when wanting to *speculate* on Miscellaneous registers */
561 void
562 InOrderDynInst::setMiscReg(int misc_reg, const MiscReg &val)
563 {
564 this->cpu->setMiscReg(misc_reg, val, threadNumber);
565 }
566
567 void
568 InOrderDynInst::setRegOtherThread(unsigned reg_idx, const MiscReg &val, int tid)
569 {
570 if (tid == -1) {
571 tid = TheISA::getTargetThread(this->cpu->tcBase(threadNumber));
572 }
573
574 if (reg_idx < FP_Base_DepTag) { // Integer Register File
575 this->cpu->setIntReg(reg_idx, val, tid);
576 } else if (reg_idx < Ctrl_Base_DepTag) { // Float Register File
577 reg_idx -= FP_Base_DepTag;
578 this->cpu->setFloatRegBits(reg_idx, val, tid);
579 } else {
580 reg_idx -= Ctrl_Base_DepTag;
581 this->cpu->setMiscReg(reg_idx, val, tid); // Misc. Register File
582 }
583 }
584
585 void
586 InOrderDynInst::deallocateContext(int thread_num)
587 {
588 this->cpu->deallocateContext(thread_num);
589 }
590
591 void
592 InOrderDynInst::enableVirtProcElement(unsigned vpe)
593 {
594 this->cpu->enableVirtProcElement(vpe);
595 }
596
597 void
598 InOrderDynInst::disableVirtProcElement(unsigned vpe)
599 {
600 this->cpu->disableVirtProcElement(threadNumber, vpe);
601 }
602
603 void
604 InOrderDynInst::enableMultiThreading(unsigned vpe)
605 {
606 this->cpu->enableMultiThreading(vpe);
607 }
608
609 void
610 InOrderDynInst::disableMultiThreading(unsigned vpe)
611 {
612 this->cpu->disableMultiThreading(threadNumber, vpe);
613 }
614
615 void
616 InOrderDynInst::setThreadRescheduleCondition(uint32_t cond)
617 {
618 this->cpu->setThreadRescheduleCondition(cond);
619 }
620
621 template<class T>
622 inline Fault
623 InOrderDynInst::read(Addr addr, T &data, unsigned flags)
624 {
625 return cpu->read(this);
626 }
627
628 #ifndef DOXYGEN_SHOULD_SKIP_THIS
629
630 template
631 Fault
632 InOrderDynInst::read(Addr addr, uint64_t &data, unsigned flags);
633
634 template
635 Fault
636 InOrderDynInst::read(Addr addr, uint32_t &data, unsigned flags);
637
638 template
639 Fault
640 InOrderDynInst::read(Addr addr, uint16_t &data, unsigned flags);
641
642 template
643 Fault
644 InOrderDynInst::read(Addr addr, uint8_t &data, unsigned flags);
645
646 #endif //DOXYGEN_SHOULD_SKIP_THIS
647
648 template<>
649 Fault
650 InOrderDynInst::read(Addr addr, double &data, unsigned flags)
651 {
652 return read(addr, *(uint64_t*)&data, flags);
653 }
654
655 template<>
656 Fault
657 InOrderDynInst::read(Addr addr, float &data, unsigned flags)
658 {
659 return read(addr, *(uint32_t*)&data, flags);
660 }
661
662 template<>
663 Fault
664 InOrderDynInst::read(Addr addr, int32_t &data, unsigned flags)
665 {
666 return read(addr, (uint32_t&)data, flags);
667 }
668
669 template<class T>
670 inline Fault
671 InOrderDynInst::write(T data, Addr addr, unsigned flags, uint64_t *res)
672 {
673 //memcpy(memData, gtoh(data), sizeof(T));
674 storeData = data;
675
676 DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting store data to %#x.\n",
677 threadNumber, seqNum, memData);
678 return cpu->write(this);
679 }
680
681 #ifndef DOXYGEN_SHOULD_SKIP_THIS
682 template
683 Fault
684 InOrderDynInst::write(uint64_t data, Addr addr,
685 unsigned flags, uint64_t *res);
686
687 template
688 Fault
689 InOrderDynInst::write(uint32_t data, Addr addr,
690 unsigned flags, uint64_t *res);
691
692 template
693 Fault
694 InOrderDynInst::write(uint16_t data, Addr addr,
695 unsigned flags, uint64_t *res);
696
697 template
698 Fault
699 InOrderDynInst::write(uint8_t data, Addr addr,
700 unsigned flags, uint64_t *res);
701
702 #endif //DOXYGEN_SHOULD_SKIP_THIS
703
704 template<>
705 Fault
706 InOrderDynInst::write(double data, Addr addr, unsigned flags, uint64_t *res)
707 {
708 return write(*(uint64_t*)&data, addr, flags, res);
709 }
710
711 template<>
712 Fault
713 InOrderDynInst::write(float data, Addr addr, unsigned flags, uint64_t *res)
714 {
715 return write(*(uint32_t*)&data, addr, flags, res);
716 }
717
718
719 template<>
720 Fault
721 InOrderDynInst::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
722 {
723 return write((uint32_t)data, addr, flags, res);
724 }
725
726
727 void
728 InOrderDynInst::dump()
729 {
730 cprintf("T%d : %#08d `", threadNumber, PC);
731 cout << staticInst->disassemble(PC);
732 cprintf("'\n");
733 }
734
735 void
736 InOrderDynInst::dump(std::string &outstring)
737 {
738 std::ostringstream s;
739 s << "T" << threadNumber << " : 0x" << PC << " "
740 << staticInst->disassemble(PC);
741
742 outstring = s.str();
743 }
744
745
746 #define NOHASH
747 #ifndef NOHASH
748
749 #include "base/hashmap.hh"
750
751 unsigned int MyHashFunc(const InOrderDynInst *addr)
752 {
753 unsigned a = (unsigned)addr;
754 unsigned hash = (((a >> 14) ^ ((a >> 2) & 0xffff))) & 0x7FFFFFFF;
755
756 return hash;
757 }
758
759 typedef m5::hash_map<const InOrderDynInst *, const InOrderDynInst *, MyHashFunc>
760 my_hash_t;
761
762 my_hash_t thishash;
763 #endif
764
765 #ifdef DEBUG
766
767 void
768 InOrderDynInst::dumpSNList()
769 {
770 std::set<InstSeqNum>::iterator sn_it = cpu->snList.begin();
771
772 int count = 0;
773 while (sn_it != cpu->snList.end()) {
774 cprintf("%i: [sn:%lli] not destroyed\n", count, (*sn_it));
775 count++;
776 sn_it++;
777 }
778 }
779 #endif
780