Trace cache instrumentation methods
Next step will be tracing cross non-taken branches
This commit is contained in:
parent
48d815427c
commit
db69a25c36
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.cc,v 1.188 2007-12-09 18:36:03 sshwarts Exp $
|
||||
// $Id: cpu.cc,v 1.189 2007-12-14 11:27:44 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -57,25 +57,30 @@ void flushICaches(void)
|
||||
pageWriteStampTable.resetWriteStamps();
|
||||
}
|
||||
|
||||
#define InstrumentICACHE 0
|
||||
#define InstrumentTRACECACHE 0
|
||||
|
||||
#if InstrumentICACHE
|
||||
#if InstrumentTRACECACHE
|
||||
static Bit32u iCacheLookups=0;
|
||||
static Bit32u iCacheMisses=0;
|
||||
static Bit32u iCacheMergeTraces=0;
|
||||
static Bit32u iCacheLength[BX_MAX_TRACE_LENGTH+1];
|
||||
static Bit32u iCacheTraceLengh[BX_MAX_TRACE_LENGTH];
|
||||
|
||||
#define InstrICache_StatsMask 0xfffffff
|
||||
|
||||
#define InstrICache_Stats() {\
|
||||
if ((iCacheLookups & InstrICache_StatsMask) == 0) { \
|
||||
BX_INFO(("ICACHE lookups: %u, misses: %u, merges: %u, hit rate = %6.2f%% ", \
|
||||
BX_INFO(("ICACHE lookups: %u, misses: %u, merges: %u, hit rate = %3.2f%%", \
|
||||
(unsigned) iCacheLookups, \
|
||||
(unsigned) iCacheMisses, \
|
||||
(unsigned) iCacheMergeTraces, \
|
||||
(iCacheLookups-iCacheMisses) * 100.0 / iCacheLookups)); \
|
||||
for (unsigned trace_len_idx=0; trace_len_idx<BX_MAX_TRACE_LENGTH;trace_len_idx++) { \
|
||||
BX_INFO(("trace[%02d]: %u\t(%3.2f%%)", trace_len_idx+1, \
|
||||
iCacheTraceLengh[trace_len_idx], \
|
||||
iCacheTraceLengh[trace_len_idx] * 100.0/(iCacheLookups-iCacheMisses))); \
|
||||
iCacheTraceLengh[trace_len_idx] = 0; \
|
||||
} \
|
||||
iCacheLookups = iCacheMisses = iCacheMergeTraces = 0; \
|
||||
for (int i=0;i<=BX_MAX_TRACE_LENGTH;i++) iCacheLength[i] = 0; \
|
||||
} \
|
||||
}
|
||||
#define InstrICache_Increment(v) (v)++
|
||||
@ -85,7 +90,7 @@ static Bit32u iCacheLength[BX_MAX_TRACE_LENGTH+1];
|
||||
#define InstrICache_Increment(v)
|
||||
#endif
|
||||
|
||||
#endif // BX_SUPPORT_ICACHE
|
||||
#endif // InstrumentTRACECACHE
|
||||
|
||||
// Make code more tidy with a few macros.
|
||||
#if BX_SUPPORT_X86_64==0
|
||||
@ -108,6 +113,7 @@ bxICacheEntry_c* BX_CPU_C::fetchInstructionTrace(bxInstruction_c *iStorage, bx_a
|
||||
if ((trace->pAddr == pAddr) &&
|
||||
(trace->writeStamp == pageWriteStamp))
|
||||
{
|
||||
InstrICache_Increment(iCacheTraceLengh[trace->ilen-1]);
|
||||
return trace; // We are lucky - trace cache hit !
|
||||
}
|
||||
|
||||
@ -172,8 +178,6 @@ bxICacheEntry_c* BX_CPU_C::fetchInstructionTrace(bxInstruction_c *iStorage, bx_a
|
||||
if (mergeTraces(trace, i, pAddr)) break;
|
||||
}
|
||||
|
||||
InstrICache_Increment(iCacheLength[trace->ilen-1]);
|
||||
|
||||
return trace;
|
||||
}
|
||||
|
||||
@ -202,6 +206,30 @@ bx_bool BX_CPU_C::mergeTraces(bxICacheEntry_c *trace, bxInstruction_c *i, bx_phy
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BX_CPU_C::instrumentTraces(void)
|
||||
{
|
||||
Bit32u currPageWriteStamp = *(BX_CPU_THIS_PTR currPageWriteStampPtr);
|
||||
bxICacheEntry_c *e = BX_CPU_THIS_PTR iCache.entry;
|
||||
Bit32u trace_length[BX_MAX_TRACE_LENGTH], invalid_entries = 0;
|
||||
unsigned i;
|
||||
|
||||
for (i=0; i < BX_MAX_TRACE_LENGTH; i++) trace_length[i] = 0;
|
||||
|
||||
for (i=0; i<BxICacheEntries; i++, e++) {
|
||||
if (e->writeStamp == currPageWriteStamp)
|
||||
trace_length[e->ilen-1]++;
|
||||
else
|
||||
invalid_entries++;
|
||||
}
|
||||
|
||||
for (i=0; i < BX_MAX_TRACE_LENGTH; i++) {
|
||||
BX_INFO(("traces[%02d]: %u\t%f%%", i+1,
|
||||
trace_length[i], trace_length[i]*100.0/BxICacheEntries));
|
||||
}
|
||||
BX_INFO(("invalid entries: %u\t%f%%",
|
||||
invalid_entries, invalid_entries*100.0/BxICacheEntries));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bxInstruction_c* BX_CPU_C::fetchInstruction(bxInstruction_c *iStorage, bx_address eipBiased)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.386 2007-12-09 18:36:04 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.387 2007-12-14 11:27:44 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -2939,6 +2939,7 @@ public: // for now...
|
||||
#if BX_SUPPORT_TRACE_CACHE
|
||||
BX_SMF bxICacheEntry_c* fetchInstructionTrace(bxInstruction_c *, bx_address);
|
||||
BX_SMF bx_bool mergeTraces(bxICacheEntry_c *trace, bxInstruction_c *i, bx_phy_address pAddr);
|
||||
BX_SMF void instrumentTraces(void);
|
||||
#else
|
||||
BX_SMF bxInstruction_c* fetchInstruction(bxInstruction_c *, bx_address);
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.187 2007-12-14 10:15:12 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.188 2007-12-14 11:27:44 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -189,8 +189,6 @@ void BX_CPU_C::CLFLUSH(bxInstruction_c *i)
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
void BX_CPU_C::MOV_DdRd(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u val_32;
|
||||
|
||||
if (!real_mode() && CPL!=0) {
|
||||
BX_ERROR(("MOV_DdRd: CPL!=0 not in real mode"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
@ -202,15 +200,15 @@ void BX_CPU_C::MOV_DdRd(bxInstruction_c *i)
|
||||
* reg field specifies which special register
|
||||
*/
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
/* This instruction is always treated as a register-to-register,
|
||||
* regardless of the encoding of the MOD field in the MODRM byte.
|
||||
*/
|
||||
if (!i->modC0())
|
||||
BX_PANIC(("MOV_DdRd(): rm field not a register!"));
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
val_32 = BX_READ_32BIT_REG(i->rm());
|
||||
Bit32u val_32 = BX_READ_32BIT_REG(i->rm());
|
||||
|
||||
switch (i->nnn()) {
|
||||
case 0: // DR0
|
||||
@ -325,6 +323,8 @@ void BX_CPU_C::MOV_RdDd(bxInstruction_c *i)
|
||||
/* This instruction is always treated as a register-to-register,
|
||||
* regardless of the encoding of the MOD field in the MODRM byte.
|
||||
*/
|
||||
if (!i->modC0())
|
||||
BX_PANIC(("MOV_RdDd(): rm field not a register!"));
|
||||
|
||||
switch (i->nnn()) {
|
||||
case 0: // DR0
|
||||
@ -389,18 +389,20 @@ void BX_CPU_C::MOV_DqRq(bxInstruction_c *i)
|
||||
* reg field specifies which special register
|
||||
*/
|
||||
|
||||
/* This instruction is always treated as a register-to-register,
|
||||
* regardless of the encoding of the MOD field in the MODRM byte.
|
||||
*/
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
/* #GP(0) if CPL is not 0 */
|
||||
if (CPL != 0) {
|
||||
BX_ERROR(("MOV_DqRq: #GP(0) if CPL is not 0"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
/* This instruction is always treated as a register-to-register,
|
||||
* regardless of the encoding of the MOD field in the MODRM byte.
|
||||
*/
|
||||
if (!i->modC0())
|
||||
BX_PANIC(("MOV_DqRq(): rm field not a register!"));
|
||||
|
||||
Bit64u val_64 = BX_READ_64BIT_REG(i->rm());
|
||||
|
||||
switch (i->nnn()) {
|
||||
@ -497,16 +499,18 @@ void BX_CPU_C::MOV_RqDq(bxInstruction_c *i)
|
||||
|
||||
BX_ASSERT(protected_mode());
|
||||
|
||||
/* This instruction is always treated as a register-to-register,
|
||||
* regardless of the encoding of the MOD field in the MODRM byte.
|
||||
*/
|
||||
|
||||
/* #GP(0) if CPL is not 0 */
|
||||
if (CPL != 0) {
|
||||
BX_ERROR(("MOV_RqDq: #GP(0) if CPL is not 0"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
/* This instruction is always treated as a register-to-register,
|
||||
* regardless of the encoding of the MOD field in the MODRM byte.
|
||||
*/
|
||||
if (!i->modC0())
|
||||
BX_PANIC(("MOV_RqDq(): rm field not a register!"));
|
||||
|
||||
switch (i->nnn()) {
|
||||
case 0: // DR0
|
||||
val_64 = BX_CPU_THIS_PTR dr0;
|
||||
@ -558,9 +562,6 @@ void BX_CPU_C::MOV_RqDq(bxInstruction_c *i)
|
||||
|
||||
void BX_CPU_C::MOV_CdRd(bxInstruction_c *i)
|
||||
{
|
||||
// mov general register data to control register
|
||||
Bit32u val_32;
|
||||
|
||||
if (!real_mode() && CPL!=0) {
|
||||
BX_ERROR(("MOV_CdRd: CPL!=0 not in real mode"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
@ -572,13 +573,15 @@ void BX_CPU_C::MOV_CdRd(bxInstruction_c *i)
|
||||
* reg field specifies which special register
|
||||
*/
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
/* This instruction is always treated as a register-to-register,
|
||||
* regardless of the encoding of the MOD field in the MODRM byte.
|
||||
*/
|
||||
if (!i->modC0())
|
||||
BX_PANIC(("MOV_CdRd(): rm field not a register!"));
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
val_32 = BX_READ_32BIT_REG(i->rm());
|
||||
Bit32u val_32 = BX_READ_32BIT_REG(i->rm());
|
||||
|
||||
switch (i->nnn()) {
|
||||
case 0: // CR0 (MSW)
|
||||
@ -674,9 +677,6 @@ void BX_CPU_C::MOV_RdCd(bxInstruction_c *i)
|
||||
#if BX_SUPPORT_X86_64
|
||||
void BX_CPU_C::MOV_CqRq(bxInstruction_c *i)
|
||||
{
|
||||
// mov general register data to control register
|
||||
Bit64u val_64;
|
||||
|
||||
BX_ASSERT(protected_mode());
|
||||
|
||||
/* NOTES:
|
||||
@ -685,6 +685,12 @@ void BX_CPU_C::MOV_CqRq(bxInstruction_c *i)
|
||||
* reg field specifies which special register
|
||||
*/
|
||||
|
||||
/* #GP(0) if CPL is not 0 */
|
||||
if (CPL!=0) {
|
||||
BX_ERROR(("MOV_CqRq: #GP(0) if CPL is not 0"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
/* This instruction is always treated as a register-to-register,
|
||||
* regardless of the encoding of the MOD field in the MODRM byte.
|
||||
*/
|
||||
@ -693,13 +699,7 @@ void BX_CPU_C::MOV_CqRq(bxInstruction_c *i)
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
/* #GP(0) if CPL is not 0 */
|
||||
if (CPL!=0) {
|
||||
BX_ERROR(("MOV_CqRq: #GP(0) if CPL is not 0"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
val_64 = BX_READ_64BIT_REG(i->rm());
|
||||
Bit64u val_64 = BX_READ_64BIT_REG(i->rm());
|
||||
|
||||
switch (i->nnn()) {
|
||||
case 0: // CR0 (MSW)
|
||||
@ -760,18 +760,18 @@ void BX_CPU_C::MOV_RqCq(bxInstruction_c *i)
|
||||
* reg field specifies which special register
|
||||
*/
|
||||
|
||||
/* This instruction is always treated as a register-to-register,
|
||||
* regardless of the encoding of the MOD field in the MODRM byte.
|
||||
*/
|
||||
if (!i->modC0())
|
||||
BX_PANIC(("MOV_RqCq(): rm field not a register!"));
|
||||
|
||||
/* #GP(0) if CPL is not 0 */
|
||||
if (CPL!=0) {
|
||||
BX_ERROR(("MOV_RqCq: #GP(0) if CPL is not 0"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
/* This instruction is always treated as a register-to-register,
|
||||
* regardless of the encoding of the MOD field in the MODRM byte.
|
||||
*/
|
||||
if (!i->modC0())
|
||||
BX_PANIC(("MOV_RqCq(): rm field not a register!"));
|
||||
|
||||
switch (i->nnn()) {
|
||||
case 0: // CR0 (MSW)
|
||||
val_64 = BX_CPU_THIS_PTR cr0.val32;
|
||||
|
Loading…
Reference in New Issue
Block a user