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