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