Small optimization in icache page-write-stamp

This commit is contained in:
Stanislav Shwartsman 2006-02-28 17:47:33 +00:00
parent fbd61d0a00
commit 55ceecf79b
11 changed files with 53 additions and 64 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.132 2006-02-23 18:23:31 sshwarts Exp $
// $Id: cpu.cc,v 1.133 2006-02-28 17:47:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -226,7 +226,7 @@ void BX_CPU_C::cpu_loop(Bit32s max_instr_count)
#if BX_DEBUGGER
if (BX_CPU_THIS_PTR trace) {
// print the instruction that is about to be executed.
bx_dbg_disassemble_current (BX_CPU_ID, 1); // only one cpu, print time stamp
bx_dbg_disassemble_current(BX_CPU_ID, 1); // only one cpu, print time stamp
}
#endif
@ -486,9 +486,8 @@ bxInstruction_c* BX_CPU_C::fetchInstruction(bxInstruction_c *iStorage, bx_addres
// willing to dump all iCache entries which can hash to this page.
// Therefore, in either case, we can keep the counter as-is and
// replace the fetch mode bits.
Bit32u fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask;
pageWriteStamp &= ICacheWriteStampMask; // Clear out old fetch mode bits.
pageWriteStamp |= fetchModeMask; // Add in new ones.
pageWriteStamp |= BX_CPU_THIS_PTR fetchModeMask; // Add in new ones.
pageWriteStampTable.setPageWriteStamp(pAddr, pageWriteStamp);
cache_entry->pAddr = pAddr;
cache_entry->writeStamp = pageWriteStamp;
@ -790,7 +789,7 @@ void BX_CPU_C::prefetch(void)
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR currPageWriteStampPtr = pageWriteStampTable.getPageWriteStampPtr(pAddr);
Bit32u pageWriteStamp = *(BX_CPU_THIS_PTR currPageWriteStampPtr);
Bit32u fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask;
Bit32u fetchModeMask = BX_CPU_THIS_PTR fetchModeMask;
if ((pageWriteStamp & ICacheFetchModeMask) != fetchModeMask)
{
// The current CPU mode does not match iCache entries for this
@ -853,11 +852,11 @@ void BX_CPU_C::boundaryFetch(Bit8u *fetchPtr, unsigned remainingInPage, bxInstru
// Restore EIP since we fudged it to start at the 2nd page boundary.
RIP = BX_CPU_THIS_PTR prev_eip;
// Since we cross an instruction boundary, note that we need a prefetch()
// again on the next instruction. Perhaps we can optimize this to
// eliminate the extra prefetch() since we do it above, but have to
// think about repeated instructions, etc.
BX_CPU_THIS_PTR eipPageWindowSize = 0; // Fixme
// Since we cross an instruction boundary, note that we need a prefetch()
// again on the next instruction. Perhaps we can optimize this to
// eliminate the extra prefetch() since we do it above, but have to
// think about repeated instructions, etc.
invalidate_prefetch_q();
BX_INSTR_OPCODE(BX_CPU_ID, fetchBuffer, i->ilen(),
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, Is64BitMode());

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.262 2006-02-23 18:23:31 sshwarts Exp $
// $Id: cpu.h,v 1.263 2006-02-28 17:47:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -647,7 +647,7 @@ public:
// 4...4 os32
// 3...3 (unused)
// 2...0 seg
unsigned metaInfo;
Bit32u metaInfo;
union {
// Form (longest case): [opcode+modrm+sib/displacement32/immediate32]
@ -1219,7 +1219,8 @@ public: // for now...
// this structure should be aligned on a 32-byte boundary to be friendly
// with the host cache lines.
#if BX_SUPPORT_ICACHE
bxICache_c iCache BX_CPP_AlignN(32);
bxICache_c iCache BX_CPP_AlignN(32);
Bit32u fetchModeMask;
#endif

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer_pro.cc,v 1.50 2005-08-02 18:44:16 sshwarts Exp $
// $Id: ctrl_xfer_pro.cc,v 1.51 2006-02-28 17:47:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -118,7 +118,7 @@ BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
#endif
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif
// Loading CS will invalidate the EIP fetch window.

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: debugstuff.cc,v 1.58 2006-02-14 20:14:18 sshwarts Exp $
// $Id: debugstuff.cc,v 1.59 2006-02-28 17:47:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -717,7 +717,7 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit;
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif
// SS:

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: icache.h,v 1.11 2006-01-16 19:22:28 sshwarts Exp $
// $Id: icache.h,v 1.12 2006-02-28 17:47:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -28,6 +28,8 @@
#ifndef BX_ICACHE_H
#define BX_ICACHE_H
#include <assert.h>
// bit31: 1=CS is 32/64-bit, 0=CS is 16-bit.
// bit30: 1=Long Mode, 0=not Long Mode.
// bit29: 1=iCache page, 0=Data.
@ -35,7 +37,6 @@ const Bit32u ICacheWriteStampInvalid = 0x1fffffff;
const Bit32u ICacheWriteStampMax = 0x1fffffff;
const Bit32u ICacheWriteStampMask = 0x1fffffff;
const Bit32u ICacheFetchModeMask = ~ICacheWriteStampMask;
const Bit32u iCachePageDataMask = 0x20000000;
class bxPageWriteStampTable
{
@ -77,21 +78,16 @@ public:
BX_CPP_INLINE void setPageWriteStamp(Bit32u pAddr, Bit32u pageWriteStamp)
{
if (pAddr < memSizeInBytes)
if (pAddr < memSizeInBytes)
pageWriteStampTable[pAddr>>12] = pageWriteStamp;
}
BX_CPP_INLINE void decWriteStamp(Bit32u a20Addr)
BX_CPP_INLINE void decWriteStamp(Bit32u pAddr)
{
// Increment page write stamp, so iCache entries with older stamps
assert(pAddr < memSizeInBytes);
// Decrement page write stamp, so iCache entries with older stamps
// are effectively invalidated.
Bit32u pageIndex = a20Addr >> 12;
Bit32u writeStamp = pageWriteStampTable[pageIndex];
if (writeStamp & iCachePageDataMask)
{
pageWriteStampTable[pageIndex]--;
}
pageWriteStampTable[pAddr >> 12]--;
}
BX_CPP_INLINE void resetWriteStamps(void);
@ -108,29 +104,20 @@ extern bxPageWriteStampTable pageWriteStampTable;
#define BxICacheEntries (32 * 1024) // Must be a power of 2.
class bxICacheEntry_c {
public:
Bit32u pAddr; // Physical address of the instruction.
Bit32u writeStamp; // Generation ID. Each write to a physical page
// decrements this value.
bxInstruction_c i; // The instruction decode information.
struct bxICacheEntry_c
{
Bit32u pAddr; // Physical address of the instruction
Bit32u writeStamp; // Generation ID. Each write to a physical page
// decrements this value
bxInstruction_c i; // The instruction decode information
};
class BOCHSAPI bxICache_c {
public:
bxICacheEntry_c entry[BxICacheEntries];
Bit32u fetchModeMask;
public:
bxICache_c()
{
// Initially clear the iCache;
for (unsigned i=0; i<BxICacheEntries; i++) {
entry[i].writeStamp = ICacheWriteStampInvalid;
}
fetchModeMask = iCachePageDataMask; // CS is 16-bit, Long Mode disabled
}
bxICache_c() { flushICacheEntries(); }
BX_CPP_INLINE unsigned hash(Bit32u pAddr) const
{
@ -143,19 +130,21 @@ public:
};
BX_CPP_INLINE void bxICache_c::flushICacheEntries(void)
{ bxICacheEntry_c* e = entry;
{
bxICacheEntry_c* e = entry;
for (unsigned i=0; i<BxICacheEntries; i++, e++) {
e->writeStamp = ICacheWriteStampInvalid;
}
}
BX_CPP_INLINE void bxICache_c::purgeICacheEntries(void)
{ bxICacheEntry_c* e = entry;
{
bxICacheEntry_c* e = entry;
// Since the write stamps may overflow if we always simply decrese them,
// this function has to be called often enough that we can reset them
// (without invalidating the cache).
for (unsigned i=0;i<BxICacheEntries;i++, e++)
for (unsigned i=0;i<BxICacheEntries;i++,e++)
{
Bit32u pageWriteStamp = pageWriteStampTable.getPageWriteStamp(e->pAddr);
if (e->writeStamp != pageWriteStamp)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: init.cc,v 1.84 2006-02-14 20:03:14 sshwarts Exp $
// $Id: init.cc,v 1.85 2006-02-28 17:47:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -526,7 +526,7 @@ void BX_CPU_C::reset(unsigned source)
#endif
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif
/* SS (Stack Segment) and descriptor cache */

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: paging.cc,v 1.63 2005-11-26 21:36:51 sshwarts Exp $
// $Id: paging.cc,v 1.64 2006-02-28 17:47:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -432,7 +432,7 @@ BX_CPU_C::pagingCR0Changed(Bit32u oldCR0, Bit32u newCR0)
TLB_flush(1); // 1 = Flush Global entries also.
if (bx_dbg.paging)
BX_INFO(("pagingCR0Changed(0x%x -> 0x%x):", oldCR0, newCR0));
BX_INFO(("pagingCR0Changed: (0x%x -> 0x%x)", oldCR0, newCR0));
}
void BX_CPP_AttrRegparmN(2)
@ -443,7 +443,7 @@ BX_CPU_C::pagingCR4Changed(Bit32u oldCR4, Bit32u newCR4)
TLB_flush(1); // 1 = Flush Global entries also.
if (bx_dbg.paging)
BX_INFO(("pagingCR4Changed(0x%x -> 0x%x):", oldCR4, newCR4));
BX_INFO(("pagingCR4Changed: (0x%x -> 0x%x)", oldCR4, newCR4));
#if BX_SUPPORT_PAE
if ( (oldCR4 & 0x00000020) != (newCR4 & 0x00000020) ) {
@ -550,7 +550,7 @@ BX_CPU_C::TLB_flush(bx_bool invalidateGlobal)
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[i];
if (tlbEntry->lpf != BX_INVALID_TLB_ENTRY) {
#if BX_SUPPORT_GLOBAL_PAGES
if ( invalidateGlobal || !(tlbEntry->accessBits & TLB_GlobalPage) )
if (invalidateGlobal || !(tlbEntry->accessBits & TLB_GlobalPage))
#endif
{
tlbEntry->lpf = BX_INVALID_TLB_ENTRY;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.134 2006-02-14 19:00:08 sshwarts Exp $
// $Id: proc_ctrl.cc,v 1.135 2006-02-28 17:47:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1160,7 +1160,7 @@ void BX_CPU_C::LOADALL(bxInstruction_c *i)
}
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif
/* ES */
@ -1869,7 +1869,7 @@ void BX_CPU_C::SYSENTER (bxInstruction_c *i)
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; // available for use by system
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = (BX_CPU_THIS_PTR sysenter_cs_msr + 8) & BX_SELECTOR_RPL_MASK;
@ -1929,7 +1929,7 @@ void BX_CPU_C::SYSEXIT (bxInstruction_c *i)
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; // available for use by system
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = (BX_CPU_THIS_PTR sysenter_cs_msr + 24) | 3;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: segment_ctrl_pro.cc,v 1.52 2006-02-22 20:58:16 sshwarts Exp $
// $Id: segment_ctrl_pro.cc,v 1.53 2006-02-28 17:47:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -222,7 +222,7 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
if (seg == &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]) {
seg->cache.u.segment.executable = 1; /* code segment */
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif
invalidate_prefetch_q();
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: tasking.cc,v 1.29 2006-01-16 19:22:28 sshwarts Exp $
// $Id: tasking.cc,v 1.30 2006-02-28 17:47:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -608,7 +608,7 @@ void BX_CPU_C::task_switch(bx_selector_t *tss_selector,
}
#if BX_SUPPORT_ICACHE // update instruction cache
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif
// SS

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: vm8086.cc,v 1.23 2006-01-16 19:22:28 sshwarts Exp $
// $Id: vm8086.cc,v 1.24 2006-02-28 17:47:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -254,7 +254,7 @@ void BX_CPU_C::init_v8086_mode(void)
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 3;
#if BX_SUPPORT_ICACHE // update instruction cache
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1;