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