* Fixed the line which compares the current fetchMode against

the current code page's mode.  It was &'ing against fetchModeMask:

  ((pageWriteStamp & fetchModeMask) == fetchModeMask)

  instead of against a constant mask which populates all the
  relevant bits:

  ((pageWriteStamp & ICacheFetchModeMask) == fetchModeMask)

* Moved the check above to ::prefetch(), since nothing should change
  between calls to that function.  I added some code to functions
  which load CS to make sure that is the case.

* Commented out several calls to invalidate_prefetch_q() in
  ctrl_xfer{16,32,64}.cc.  Changes to only EIP (i.e. CS is not
  modified) don't matter any more.  If EIP lands outside the
  window of the current code page, ::prefetch() is called.

* These changes add a few percent of performance.
This commit is contained in:
Kevin Lawton 2002-12-23 02:51:17 +00:00
parent 4b59ecbc62
commit d136a8f43e
1 changed files with 338 additions and 0 deletions

View File

@ -0,0 +1,338 @@
----------------------------------------------------------------------
Patch name: patch.icache-kpl
Author: Kevin Lawton (kevinlawton2001@yahoo.com)
Date: Sun Dec 22 21:40:47 EST 2002
Detailed description:
* Fixed the line which compares the current fetchMode against
the current code page's mode. It was &'ing against fetchModeMask:
((pageWriteStamp & fetchModeMask) == fetchModeMask)
instead of against a constant mask which populates all the
relevant bits:
((pageWriteStamp & ICacheFetchModeMask) == fetchModeMask)
* Moved the check above to ::prefetch(), since nothing should change
between calls to that function. I added some code to functions
which load CS to make sure that is the case.
* Commented out several calls to invalidate_prefetch_q() in
ctrl_xfer{16,32,64}.cc. Changes to only EIP (i.e. CS is not
modified) don't matter any more. If EIP lands outside the
window of the current code page, ::prefetch() is called.
* These changes add a few percent of performance.
Patch was created with:
cvs diff -u
Apply patch to what version:
cvs checked out on DATE, release version VER
Instructions:
To patch, go to main bochs directory.
Type "patch -p0 < THIS_PATCH_FILE".
----------------------------------------------------------------------
Index: cpu/cpu.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/cpu.cc,v
retrieving revision 1.72
diff -u -r1.72 cpu.cc
--- cpu/cpu.cc 20 Dec 2002 13:36:50 -0000 1.72
+++ cpu/cpu.cc 23 Dec 2002 02:33:51 -0000
@@ -193,18 +193,16 @@
#if BX_SupportICache
unsigned iCacheHash;
- Bit32u pAddr, pageWriteStamp, fetchModeMask;
+ Bit32u pAddr, pageWriteStamp;
pAddr = BX_CPU_THIS_PTR pAddrA20Page + eipBiased;
iCacheHash = BX_CPU_THIS_PTR iCache.hash( pAddr );
i = & BX_CPU_THIS_PTR iCache.entry[iCacheHash].i;
pageWriteStamp = BX_CPU_THIS_PTR iCache.pageWriteStampTable[pAddr>>12];
- fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask;
if ( (BX_CPU_THIS_PTR iCache.entry[iCacheHash].pAddr == pAddr) &&
- (BX_CPU_THIS_PTR iCache.entry[iCacheHash].writeStamp == pageWriteStamp) &&
- ((pageWriteStamp & fetchModeMask) == fetchModeMask) ) {
+ (BX_CPU_THIS_PTR iCache.entry[iCacheHash].writeStamp == pageWriteStamp) ) {
// iCache hit. Instruction is already decoded and stored in
// the instruction cache.
@@ -223,6 +221,7 @@
// case we always have an iCache miss. :^)
bx_address remainingInPage;
unsigned maxFetch;
+ Bit32u fetchModeMask;
remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased);
maxFetch = 15;
@@ -238,6 +237,7 @@
// 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.
+ fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask;
pageWriteStamp &= 0x1fffffff; // Clear out old fetch mode bits.
pageWriteStamp |= fetchModeMask; // Add in new ones.
BX_CPU_THIS_PTR iCache.pageWriteStampTable[pAddr>>12] = pageWriteStamp;
@@ -766,6 +766,21 @@
BX_PANIC(("prefetch: getHostMemAddr vetoed direct read, pAddr=0x%x.",
pAddr));
}
+ }
+
+ Bit32u pageWriteStamp;
+ Bit32u fetchModeMask;
+ Bit32u phyPageIndex;
+
+ phyPageIndex = pAddr >> 12;
+ pageWriteStamp = BX_CPU_THIS_PTR iCache.pageWriteStampTable[phyPageIndex];
+ fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask;
+ if ( (pageWriteStamp & ICacheFetchModeMask ) != fetchModeMask) {
+ // The current CPU mode does not match iCache entries for this
+ // physical page.
+ pageWriteStamp &= ICacheWriteStampMask; // Clear out old fetch mode bits.
+ pageWriteStamp |= fetchModeMask; // Add in new ones.
+ BX_CPU_THIS_PTR iCache.pageWriteStampTable[phyPageIndex] = pageWriteStamp;
}
}
Index: cpu/cpu.h
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/cpu.h,v
retrieving revision 1.125
diff -u -r1.125 cpu.h
--- cpu/cpu.h 22 Dec 2002 20:48:45 -0000 1.125
+++ cpu/cpu.h 23 Dec 2002 02:33:59 -0000
@@ -983,6 +983,7 @@
#define ICacheWriteStampInvalid 0x1fffffff
#define ICacheWriteStampMax 0x1fffffff // Decrements from here.
#define ICacheWriteStampMask 0x1fffffff
+#define ICacheFetchModeMask (~ICacheWriteStampMask)
class bxICacheEntry_c {
public:
Index: cpu/ctrl_xfer16.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/ctrl_xfer16.cc,v
retrieving revision 1.18
diff -u -r1.18 ctrl_xfer16.cc
--- cpu/ctrl_xfer16.cc 25 Oct 2002 11:44:34 -0000 1.18
+++ cpu/ctrl_xfer16.cc 23 Dec 2002 02:33:59 -0000
@@ -40,7 +40,7 @@
Bit16u imm16;
Bit16u return_IP;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret;
@@ -70,7 +70,7 @@
BailBigRSP("RETnear16");
Bit16u return_IP;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret;
@@ -164,7 +164,7 @@
BailBigRSP("CALL_Aw");
Bit32u new_EIP;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call;
@@ -226,7 +226,7 @@
BailBigRSP("CALL_Ew");
Bit16u op1_16;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call;
@@ -298,7 +298,7 @@
BailBigRSP("JMP_Jw");
Bit32u new_EIP;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0x0000ffff;
@@ -438,7 +438,7 @@
Bit32u new_EIP;
Bit16u op1_16;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
if (i->modC0()) {
op1_16 = BX_READ_16BIT_REG(i->rm());
Index: cpu/ctrl_xfer32.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/ctrl_xfer32.cc,v
retrieving revision 1.24
diff -u -r1.24 ctrl_xfer32.cc
--- cpu/ctrl_xfer32.cc 25 Oct 2002 11:44:34 -0000 1.24
+++ cpu/ctrl_xfer32.cc 23 Dec 2002 02:34:00 -0000
@@ -43,7 +43,7 @@
Bit32u temp_ESP;
Bit32u return_EIP;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret;
@@ -102,7 +102,7 @@
Bit32u temp_ESP;
Bit32u return_EIP;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret;
@@ -218,7 +218,7 @@
Bit32u new_EIP;
Bit32s disp32;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call;
@@ -279,7 +279,7 @@
Bit32u temp_ESP;
Bit32u op1_32;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call;
@@ -356,7 +356,7 @@
BailBigRSP("JMP_Jd");
Bit32u new_EIP;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
new_EIP = EIP + (Bit32s) i->Id();
@@ -527,7 +527,7 @@
Bit32u new_EIP;
Bit32u op1_32;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
/* op1_32 is a register or memory reference */
if (i->modC0()) {
Index: cpu/ctrl_xfer64.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/ctrl_xfer64.cc,v
retrieving revision 1.19
diff -u -r1.19 ctrl_xfer64.cc
--- cpu/ctrl_xfer64.cc 21 Nov 2002 18:22:03 -0000 1.19
+++ cpu/ctrl_xfer64.cc 23 Dec 2002 02:34:00 -0000
@@ -43,7 +43,7 @@
Bit64u temp_RSP;
Bit64u return_RIP;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret;
@@ -79,7 +79,7 @@
Bit64u temp_RSP;
Bit64u return_RIP;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret;
@@ -171,7 +171,7 @@
Bit64u new_RIP;
Bit32s disp32;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call;
@@ -223,7 +223,7 @@
Bit64u temp_RSP;
Bit64u op1_64;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call;
@@ -285,7 +285,7 @@
void
BX_CPU_C::JMP_Jq(bxInstruction_c *i)
{
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
RIP += (Bit32s) i->Id();
if (i->os32L()==0)
@@ -379,7 +379,7 @@
{
Bit64u op1_64;
- invalidate_prefetch_q();
+ //invalidate_prefetch_q();
if (i->modC0()) {
op1_64 = BX_READ_64BIT_REG(i->rm());
Index: cpu/segment_ctrl_pro.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/segment_ctrl_pro.cc,v
retrieving revision 1.23
diff -u -r1.23 segment_ctrl_pro.cc
--- cpu/segment_ctrl_pro.cc 25 Oct 2002 11:44:35 -0000 1.23
+++ cpu/segment_ctrl_pro.cc 23 Dec 2002 02:34:02 -0000
@@ -55,6 +55,7 @@
BX_CPU_THIS_PTR iCache.fetchModeMask =
BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS);
#endif
+ invalidate_prefetch_q();
}
else
seg->cache.u.segment.executable = 0; /* data segment */
@@ -334,9 +335,10 @@
#endif
#if BX_SupportICache
- BX_CPU_THIS_PTR iCache.fetchModeMask =
- BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS);
+ BX_CPU_THIS_PTR iCache.fetchModeMask =
+ BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS);
#endif
+ invalidate_prefetch_q();
}
else { /* SS, DS, ES, FS, GS */
seg->selector.value = new_value;
@@ -557,6 +559,7 @@
BX_CPU_THIS_PTR iCache.fetchModeMask =
BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS);
#endif
+ invalidate_prefetch_q();
}
void