Modified instruction decode method.

Make code compatible with new decode method.

src/arch/alpha/remote_gdb.cc:
src/cpu/base_dyn_inst_impl.hh:
src/cpu/exetrace.cc:
src/cpu/simple/base.cc:
    Make code compatible with new decode method.
src/cpu/static_inst.cc:
src/cpu/static_inst.hh:
    Modified instruction decode method.

--HG--
extra : convert_revision : a9a6d3a16fff59bc95d0606ea344bd57e71b8d0a
This commit is contained in:
Vincentius Robby 2007-06-14 16:52:19 -04:00
parent 6641423a0b
commit 5b5570e0bf
6 changed files with 145 additions and 10 deletions

View file

@ -284,7 +284,7 @@ RemoteGDB::setSingleStep()
// User was stopped at pc, e.g. the instruction at pc was not
// executed.
MachInst inst = read<MachInst>(pc);
StaticInstPtr si(inst);
StaticInstPtr si(inst, pc);
if (si->hasBranchTarget(pc, context, bpc)) {
// Don't bother setting a breakpoint on the taken branch if it
// is the same as the next pc

View file

@ -66,7 +66,7 @@ BaseDynInst<Impl>::BaseDynInst(TheISA::ExtMachInst machInst,
Addr inst_PC, Addr inst_NPC,
Addr pred_PC, Addr pred_NPC,
InstSeqNum seq_num, ImplCPU *cpu)
: staticInst(machInst), traceData(NULL), cpu(cpu)
: staticInst(machInst, inst_PC), traceData(NULL), cpu(cpu)
{
seqNum = seq_num;

View file

@ -656,7 +656,7 @@ Trace::InstRecord::dump()
assert(predecoder.extMachInstReady());
StaticInstPtr legionInst =
StaticInst::decode(predecoder.getExtMachInst());
StaticInst::decode(predecoder.getExtMachInst(), lgnPc);
outs << setfill(' ') << setw(15)
<< " Legion Inst: "
<< "0x" << setw(8) << setfill('0') << hex

View file

@ -392,7 +392,8 @@ BaseSimpleCPU::preExecute()
thread->setNextPC(thread->readPC() + predecoder.getInstSize());
#endif // X86_ISA
stayAtPC = false;
instPtr = StaticInst::decode(predecoder.getExtMachInst());
instPtr = StaticInst::decode(predecoder.getExtMachInst(),
thread->readPC());
} else {
stayAtPC = true;
fetchOffset += sizeof(MachInst);
@ -437,7 +438,7 @@ BaseSimpleCPU::postExecute()
if (thread->profile) {
bool usermode = TheISA::inUserMode(tc);
thread->profilePC = usermode ? 1 : thread->readPC();
StaticInstPtr si(inst);
StaticInstPtr si(inst, thread->readPC());
ProfileNode *node = thread->profile->consume(tc, si);
if (node)
thread->profileNode = node;

View file

@ -37,6 +37,8 @@ StaticInstPtr StaticInst::nullStaticInstPtr;
// Define the decode cache hash map.
StaticInst::DecodeCache StaticInst::decodeCache;
StaticInst::AddrDecodeCache StaticInst::addrDecodeCache;
StaticInst::cacheElement StaticInst::recentDecodes[2];
void
StaticInst::dumpDecodeCacheStats()

View file

@ -63,6 +63,7 @@ class AtomicSimpleCPU;
class TimingSimpleCPU;
class InorderCPU;
class SymbolTable;
class AddrDecodePage;
namespace Trace {
class InstRecord;
@ -349,6 +350,7 @@ class StaticInst : public StaticInstBase
: StaticInstBase(__opClass),
machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
{
memset(&recentDecodes, 0, 2 * sizeof(cacheElement));
}
public:
@ -437,11 +439,52 @@ class StaticInst : public StaticInstBase
/// Decode a machine instruction.
/// @param mach_inst The binary instruction to decode.
/// @retval A pointer to the corresponding StaticInst object.
//This is defined as inline below.
static StaticInstPtr decode(ExtMachInst mach_inst);
//This is defined as inlined below.
static StaticInstPtr decode(ExtMachInst mach_inst, Addr addr);
/// Return name of machine instruction
std::string getName() { return mnemonic; }
/// Decoded instruction cache type, for address decoding.
/// A generic hash_map is used.
typedef m5::hash_map<Addr, AddrDecodePage *> AddrDecodeCache;
/// A cache of decoded instruction objects from addresses.
static AddrDecodeCache addrDecodeCache;
struct cacheElement {
Addr page_addr;
AddrDecodePage *decodePage;
} ;
/// An array of recently decoded instructions.
// might not use an array if there is only two elements
static struct cacheElement recentDecodes[2];
/// Updates the recently decoded instructions entries
/// @param page_addr The page address recently used.
/// @param decodePage Pointer to decoding page containing the decoded
/// instruction.
static inline void
updateCache(Addr page_addr, AddrDecodePage *decodePage)
{
recentDecodes[1].page_addr = recentDecodes[0].page_addr;
recentDecodes[1].decodePage = recentDecodes[0].decodePage;
recentDecodes[0].page_addr = page_addr;
recentDecodes[0].decodePage = decodePage;
}
/// Searches the decoded instruction cache for instruction decoding.
/// If it is not found, then we decode the instruction.
/// Otherwise, we get the instruction from the cache and move it into
/// the address-to-instruction decoding page.
/// @param mach_inst The binary instruction to decode.
/// @param addr The address that contained the binary instruction.
/// @param decodePage Pointer to decoding page containing the instruction.
/// @retval A pointer to the corresponding StaticInst object.
//This is defined as inlined below.
static StaticInstPtr searchCache(ExtMachInst mach_inst, Addr addr,
AddrDecodePage * decodePage);
};
typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
@ -472,8 +515,8 @@ class StaticInstPtr : public RefCountingPtr<StaticInst>
/// Construct directly from machine instruction.
/// Calls StaticInst::decode().
explicit StaticInstPtr(TheISA::ExtMachInst mach_inst)
: RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst))
explicit StaticInstPtr(TheISA::ExtMachInst mach_inst, Addr addr)
: RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst, addr))
{
}
@ -484,8 +527,55 @@ class StaticInstPtr : public RefCountingPtr<StaticInst>
}
};
/// A page of a list of decoded instructions from an address.
class AddrDecodePage
{
typedef TheISA::ExtMachInst ExtMachInst;
protected:
StaticInstPtr instructions[TheISA::PageBytes];
bool valid[TheISA::PageBytes];
Addr lowerMask;
public:
/// Constructor
AddrDecodePage() {
lowerMask = TheISA::PageBytes - 1;
memset(valid, 0, TheISA::PageBytes);
}
/// Checks if the instruction is already decoded and the machine
/// instruction in the cache matches the current machine instruction
/// related to the address
/// @param mach_inst The binary instruction to check
/// @param addr The address containing the instruction
inline bool decoded(ExtMachInst mach_inst, Addr addr)
{
return (valid[addr & lowerMask] &&
(instructions[addr & lowerMask]->machInst == mach_inst));
}
/// Returns the instruction object. decoded should be called first
/// to check if the instruction is valid.
/// @param addr The address of the instruction.
/// @retval A pointer to the corresponding StaticInst object.
inline StaticInstPtr getInst(Addr addr)
{ return instructions[addr & lowerMask]; }
/// Inserts a pointer to a StaticInst object into the list of decoded
/// instructions on the page.
/// @param addr The address of the instruction.
/// @param si A pointer to the corresponding StaticInst object.
inline void insert(Addr addr, StaticInstPtr &si)
{
instructions[addr & lowerMask] = si;
valid[addr & lowerMask] = true;
}
};
inline StaticInstPtr
StaticInst::decode(StaticInst::ExtMachInst mach_inst)
StaticInst::decode(StaticInst::ExtMachInst mach_inst, Addr addr)
{
#ifdef DECODE_CACHE_HASH_STATS
// Simple stats on decode hash_map. Turns out the default
@ -499,12 +589,54 @@ StaticInst::decode(StaticInst::ExtMachInst mach_inst)
}
#endif
Addr page_addr = addr & ~(TheISA::PageBytes - 1);
// checks recently decoded addresses
if (recentDecodes[0].decodePage &&
page_addr == recentDecodes[0].page_addr) {
if (recentDecodes[0].decodePage->decoded(mach_inst, addr))
return recentDecodes[0].decodePage->getInst(addr);
return searchCache(mach_inst, addr, recentDecodes[0].decodePage);
}
if (recentDecodes[1].decodePage &&
page_addr == recentDecodes[1].page_addr) {
if (recentDecodes[1].decodePage->decoded(mach_inst, addr))
return recentDecodes[1].decodePage->getInst(addr);
return searchCache(mach_inst, addr, recentDecodes[1].decodePage);
}
// searches the page containing the address to decode
AddrDecodeCache::iterator iter = addrDecodeCache.find(page_addr);
if (iter != addrDecodeCache.end()) {
updateCache(page_addr, iter->second);
if (iter->second->decoded(mach_inst, addr))
return iter->second->getInst(addr);
return searchCache(mach_inst, addr, iter->second);
}
// creates a new object for a page of decoded instructions
AddrDecodePage * decodePage = new AddrDecodePage;
addrDecodeCache[page_addr] = decodePage;
updateCache(page_addr, decodePage);
return searchCache(mach_inst, addr, decodePage);
}
inline StaticInstPtr
StaticInst::searchCache(ExtMachInst mach_inst, Addr addr,
AddrDecodePage * decodePage)
{
DecodeCache::iterator iter = decodeCache.find(mach_inst);
if (iter != decodeCache.end()) {
decodePage->insert(addr, iter->second);
return iter->second;
}
StaticInstPtr si = TheISA::decodeInst(mach_inst);
decodePage->insert(addr, si);
decodeCache[mach_inst] = si;
return si;
}