static_inst.hh (8229:78bf55f23338) static_inst.hh (8541:27aaee8ec7cc)
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
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;

--- 20 unchanged lines hidden (view full) ---

29 */
30
31#ifndef __CPU_STATIC_INST_HH__
32#define __CPU_STATIC_INST_HH__
33
34#include <bitset>
35#include <string>
36
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
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;

--- 20 unchanged lines hidden (view full) ---

29 */
30
31#ifndef __CPU_STATIC_INST_HH__
32#define __CPU_STATIC_INST_HH__
33
34#include <bitset>
35#include <string>
36
37#include "arch/isa_traits.hh"
38#include "arch/registers.hh"
39#include "arch/types.hh"
37#include "arch/registers.hh"
38#include "arch/types.hh"
40#include "base/hashmap.hh"
41#include "base/misc.hh"
42#include "base/refcnt.hh"
43#include "base/types.hh"
44#include "config/the_isa.hh"
45#include "cpu/op_class.hh"
46#include "sim/fault_fwd.hh"
47
48// forward declarations

--- 11 unchanged lines hidden (view full) ---

60class InOrderDynInst;
61
62class CheckerCPU;
63class FastCPU;
64class AtomicSimpleCPU;
65class TimingSimpleCPU;
66class InorderCPU;
67class SymbolTable;
39#include "base/misc.hh"
40#include "base/refcnt.hh"
41#include "base/types.hh"
42#include "config/the_isa.hh"
43#include "cpu/op_class.hh"
44#include "sim/fault_fwd.hh"
45
46// forward declarations

--- 11 unchanged lines hidden (view full) ---

58class InOrderDynInst;
59
60class CheckerCPU;
61class FastCPU;
62class AtomicSimpleCPU;
63class TimingSimpleCPU;
64class InorderCPU;
65class SymbolTable;
68class AddrDecodePage;
69
70namespace Trace {
71 class InstRecord;
72}
73
74/**
75 * Base, ISA-independent static instruction class.
76 *

--- 203 unchanged lines hidden (view full) ---

280 *
281 * This class builds on StaticInstBase, defining fields and interfaces
282 * that are generic across all ISAs but that differ in details
283 * according to the specific ISA being used.
284 */
285class StaticInst : public StaticInstBase
286{
287 public:
66
67namespace Trace {
68 class InstRecord;
69}
70
71/**
72 * Base, ISA-independent static instruction class.
73 *

--- 203 unchanged lines hidden (view full) ---

277 *
278 * This class builds on StaticInstBase, defining fields and interfaces
279 * that are generic across all ISAs but that differ in details
280 * according to the specific ISA being used.
281 */
282class StaticInst : public StaticInstBase
283{
284 public:
288
289 /// Binary machine instruction type.
290 typedef TheISA::MachInst MachInst;
291 /// Binary extended machine instruction type.
292 typedef TheISA::ExtMachInst ExtMachInst;
293 /// Logical register index type.
294 typedef TheISA::RegIndex RegIndex;
295
296 enum {
297 MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
298 MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs

--- 112 unchanged lines hidden (view full) ---

411 * The default version of this function will call the internal
412 * virtual generateDisassembly() function to get the string,
413 * then cache it in #cachedDisassembly. If the disassembly
414 * should not be cached, this function should be overridden directly.
415 */
416 virtual const std::string &disassemble(Addr pc,
417 const SymbolTable *symtab = 0) const;
418
285 /// Binary extended machine instruction type.
286 typedef TheISA::ExtMachInst ExtMachInst;
287 /// Logical register index type.
288 typedef TheISA::RegIndex RegIndex;
289
290 enum {
291 MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
292 MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs

--- 112 unchanged lines hidden (view full) ---

405 * The default version of this function will call the internal
406 * virtual generateDisassembly() function to get the string,
407 * then cache it in #cachedDisassembly. If the disassembly
408 * should not be cached, this function should be overridden directly.
409 */
410 virtual const std::string &disassemble(Addr pc,
411 const SymbolTable *symtab = 0) const;
412
419 /// Decoded instruction cache type.
420 /// For now we're using a generic hash_map; this seems to work
421 /// pretty well.
422 typedef m5::hash_map<ExtMachInst, StaticInstPtr> DecodeCache;
423
424 /// A cache of decoded instruction objects.
425 static DecodeCache decodeCache;
426
427 /**
428 * Dump some basic stats on the decode cache hash map.
429 * Only gets called if DECODE_CACHE_HASH_STATS is defined.
430 */
431 static void dumpDecodeCacheStats();
432
433 /// Decode a machine instruction.
434 /// @param mach_inst The binary instruction to decode.
435 /// @retval A pointer to the corresponding StaticInst object.
436 //This is defined as inlined below.
437 static StaticInstPtr decode(ExtMachInst mach_inst, Addr addr);
438
439 /// Return name of machine instruction
440 std::string getName() { return mnemonic; }
413 /// Return name of machine instruction
414 std::string getName() { return mnemonic; }
441
442 /// Decoded instruction cache type, for address decoding.
443 /// A generic hash_map is used.
444 typedef m5::hash_map<Addr, AddrDecodePage *> AddrDecodeCache;
445
446 /// A cache of decoded instruction objects from addresses.
447 static AddrDecodeCache addrDecodeCache;
448
449 struct cacheElement
450 {
451 Addr page_addr;
452 AddrDecodePage *decodePage;
453
454 cacheElement() : decodePage(NULL) { }
455 };
456
457 /// An array of recently decoded instructions.
458 // might not use an array if there is only two elements
459 static struct cacheElement recentDecodes[2];
460
461 /// Updates the recently decoded instructions entries
462 /// @param page_addr The page address recently used.
463 /// @param decodePage Pointer to decoding page containing the decoded
464 /// instruction.
465 static inline void
466 updateCache(Addr page_addr, AddrDecodePage *decodePage)
467 {
468 recentDecodes[1].page_addr = recentDecodes[0].page_addr;
469 recentDecodes[1].decodePage = recentDecodes[0].decodePage;
470 recentDecodes[0].page_addr = page_addr;
471 recentDecodes[0].decodePage = decodePage;
472 }
473
474 /// Searches the decoded instruction cache for instruction decoding.
475 /// If it is not found, then we decode the instruction.
476 /// Otherwise, we get the instruction from the cache and move it into
477 /// the address-to-instruction decoding page.
478 /// @param mach_inst The binary instruction to decode.
479 /// @param addr The address that contained the binary instruction.
480 /// @param decodePage Pointer to decoding page containing the instruction.
481 /// @retval A pointer to the corresponding StaticInst object.
482 //This is defined as inlined below.
483 static StaticInstPtr searchCache(ExtMachInst mach_inst, Addr addr,
484 AddrDecodePage *decodePage);
485};
486
487typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
488
489/// Reference-counted pointer to a StaticInst object.
490/// This type should be used instead of "StaticInst *" so that
491/// StaticInst objects can be properly reference-counted.
492class StaticInstPtr : public RefCountingPtr<StaticInst>

--- 12 unchanged lines hidden (view full) ---

505 }
506
507 /// Copy constructor.
508 StaticInstPtr(const StaticInstPtr &r)
509 : RefCountingPtr<StaticInst>(r)
510 {
511 }
512
415};
416
417typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
418
419/// Reference-counted pointer to a StaticInst object.
420/// This type should be used instead of "StaticInst *" so that
421/// StaticInst objects can be properly reference-counted.
422class StaticInstPtr : public RefCountingPtr<StaticInst>

--- 12 unchanged lines hidden (view full) ---

435 }
436
437 /// Copy constructor.
438 StaticInstPtr(const StaticInstPtr &r)
439 : RefCountingPtr<StaticInst>(r)
440 {
441 }
442
513 /// Construct directly from machine instruction.
514 /// Calls StaticInst::decode().
515 explicit StaticInstPtr(TheISA::ExtMachInst mach_inst, Addr addr)
516 : RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst, addr))
517 {
518 }
519
520 /// Convert to pointer to StaticInstBase class.
521 operator const StaticInstBasePtr()
522 {
523 return this->get();
524 }
525};
526
443 /// Convert to pointer to StaticInstBase class.
444 operator const StaticInstBasePtr()
445 {
446 return this->get();
447 }
448};
449
527/// A page of a list of decoded instructions from an address.
528class AddrDecodePage
529{
530 typedef TheISA::ExtMachInst ExtMachInst;
531 protected:
532 StaticInstPtr instructions[TheISA::PageBytes];
533 bool valid[TheISA::PageBytes];
534 Addr lowerMask;
535
536 public:
537 /// Constructor
538 AddrDecodePage()
539 {
540 lowerMask = TheISA::PageBytes - 1;
541 memset(valid, 0, TheISA::PageBytes);
542 }
543
544 /// Checks if the instruction is already decoded and the machine
545 /// instruction in the cache matches the current machine instruction
546 /// related to the address
547 /// @param mach_inst The binary instruction to check
548 /// @param addr The address containing the instruction
549 bool
550 decoded(ExtMachInst mach_inst, Addr addr)
551 {
552 return (valid[addr & lowerMask] &&
553 (instructions[addr & lowerMask]->machInst == mach_inst));
554 }
555
556 /// Returns the instruction object. decoded should be called first
557 /// to check if the instruction is valid.
558 /// @param addr The address of the instruction.
559 /// @retval A pointer to the corresponding StaticInst object.
560 StaticInstPtr
561 getInst(Addr addr)
562 {
563 return instructions[addr & lowerMask];
564 }
565
566 /// Inserts a pointer to a StaticInst object into the list of decoded
567 /// instructions on the page.
568 /// @param addr The address of the instruction.
569 /// @param si A pointer to the corresponding StaticInst object.
570 void
571 insert(Addr addr, StaticInstPtr &si)
572 {
573 instructions[addr & lowerMask] = si;
574 valid[addr & lowerMask] = true;
575 }
576};
577
578
579inline StaticInstPtr
580StaticInst::decode(StaticInst::ExtMachInst mach_inst, Addr addr)
581{
582#ifdef DECODE_CACHE_HASH_STATS
583 // Simple stats on decode hash_map. Turns out the default
584 // hash function is as good as anything I could come up with.
585 const int dump_every_n = 10000000;
586 static int decodes_til_dump = dump_every_n;
587
588 if (--decodes_til_dump == 0) {
589 dumpDecodeCacheStats();
590 decodes_til_dump = dump_every_n;
591 }
592#endif
593
594 Addr page_addr = addr & ~(TheISA::PageBytes - 1);
595
596 // checks recently decoded addresses
597 if (recentDecodes[0].decodePage &&
598 page_addr == recentDecodes[0].page_addr) {
599 if (recentDecodes[0].decodePage->decoded(mach_inst, addr))
600 return recentDecodes[0].decodePage->getInst(addr);
601
602 return searchCache(mach_inst, addr, recentDecodes[0].decodePage);
603 }
604
605 if (recentDecodes[1].decodePage &&
606 page_addr == recentDecodes[1].page_addr) {
607 if (recentDecodes[1].decodePage->decoded(mach_inst, addr))
608 return recentDecodes[1].decodePage->getInst(addr);
609
610 return searchCache(mach_inst, addr, recentDecodes[1].decodePage);
611 }
612
613 // searches the page containing the address to decode
614 AddrDecodeCache::iterator iter = addrDecodeCache.find(page_addr);
615 if (iter != addrDecodeCache.end()) {
616 updateCache(page_addr, iter->second);
617 if (iter->second->decoded(mach_inst, addr))
618 return iter->second->getInst(addr);
619
620 return searchCache(mach_inst, addr, iter->second);
621 }
622
623 // creates a new object for a page of decoded instructions
624 AddrDecodePage *decodePage = new AddrDecodePage;
625 addrDecodeCache[page_addr] = decodePage;
626 updateCache(page_addr, decodePage);
627 return searchCache(mach_inst, addr, decodePage);
628}
629
630inline StaticInstPtr
631StaticInst::searchCache(ExtMachInst mach_inst, Addr addr,
632 AddrDecodePage *decodePage)
633{
634 DecodeCache::iterator iter = decodeCache.find(mach_inst);
635 if (iter != decodeCache.end()) {
636 decodePage->insert(addr, iter->second);
637 return iter->second;
638 }
639
640 StaticInstPtr si = TheISA::decodeInst(mach_inst);
641 decodePage->insert(addr, si);
642 decodeCache[mach_inst] = si;
643 return si;
644}
645
646#endif // __CPU_STATIC_INST_HH__
450#endif // __CPU_STATIC_INST_HH__