diff --git a/bochs/cpu/cpu.cc b/bochs/cpu/cpu.cc index d4a74fd9f..aabc80018 100644 --- a/bochs/cpu/cpu.cc +++ b/bochs/cpu/cpu.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.cc,v 1.318 2011-01-23 15:54:54 sshwarts Exp $ +// $Id: cpu.cc,v 1.319 2011-01-26 11:48:13 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001-2009 The Bochs Project @@ -119,31 +119,10 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count) } } -no_async_event: + bxICacheEntry_c *entry = getICacheEntry(); - bx_address eipBiased = RIP + BX_CPU_THIS_PTR eipPageBias; - - if (eipBiased >= BX_CPU_THIS_PTR eipPageWindowSize) { - prefetch(); - eipBiased = RIP + BX_CPU_THIS_PTR eipPageBias; - } - - bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrPage + eipBiased; - bxICacheEntry_c *entry = BX_CPU_THIS_PTR iCache.get_entry(pAddr, BX_CPU_THIS_PTR fetchModeMask); bxInstruction_c *i = entry->i; - InstrICache_Increment(iCacheLookups); - InstrICache_Stats(); - - if (entry->pAddr != pAddr) - { - // iCache miss. No validated instruction with matching fetch parameters - // is in the iCache. - InstrICache_Increment(iCacheMisses); - serveICacheMiss(entry, (Bit32u) eipBiased, pAddr); - i = entry->i; - } - #if BX_SUPPORT_TRACE_CACHE bxInstruction_c *last = i + (entry->tlen); @@ -183,12 +162,42 @@ no_async_event: break; } - if (++i == last) goto no_async_event; + if (++i == last) { + entry = getICacheEntry(); + i = entry->i; + last = i + (entry->tlen); + } } #endif } // while (1) } +bxICacheEntry_c* BX_CPU_C::getICacheEntry(void) +{ + bx_address eipBiased = RIP + BX_CPU_THIS_PTR eipPageBias; + + if (eipBiased >= BX_CPU_THIS_PTR eipPageWindowSize) { + prefetch(); + eipBiased = RIP + BX_CPU_THIS_PTR eipPageBias; + } + + bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrPage + eipBiased; + bxICacheEntry_c *entry = BX_CPU_THIS_PTR iCache.get_entry(pAddr, BX_CPU_THIS_PTR fetchModeMask); + + InstrICache_Increment(iCacheLookups); + InstrICache_Stats(); + + if (entry->pAddr != pAddr) + { + // iCache miss. No validated instruction with matching fetch parameters + // is in the iCache. + InstrICache_Increment(iCacheMisses); + serveICacheMiss(entry, (Bit32u) eipBiased, pAddr); + } + + return entry; +} + void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat(bxInstruction_c *i, BxExecutePtr_tR execute) { // non repeated instruction diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 534dda0d0..630c49c50 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.h,v 1.714 2011-01-23 15:54:54 sshwarts Exp $ +// $Id: cpu.h,v 1.715 2011-01-26 11:48:13 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001-2011 The Bochs Project @@ -2851,6 +2851,7 @@ public: // for now... #endif BX_SMF void boundaryFetch(const Bit8u *fetchPtr, unsigned remainingInPage, bxInstruction_c *); BX_SMF void serveICacheMiss(bxICacheEntry_c *entry, Bit32u eipBiased, bx_phy_address pAddr); + BX_SMF bxICacheEntry_c* getICacheEntry(void); #if BX_SUPPORT_TRACE_CACHE BX_SMF bx_bool mergeTraces(bxICacheEntry_c *entry, bxInstruction_c *i, bx_phy_address pAddr); #else