Optimized the main cpu loop iCache checks to remove a redundant

check.

Commented out a number of instances of invalidate_prefetch_q(),
for branches which do not change CS since the EIP window mechanism
takes care of validating that EIP lands in the current page or not
in the main cpu loop anyways.

Fixed a couple cases (v8086 mode and real mode) of loading CS where
the EIP page window was not invalidated in segment_ctrl_pro.cc.
That may fix some aliasing problems reported before (OS2).
This commit is contained in:
Kevin Lawton 2003-05-10 22:25:55 +00:00
parent b9a25b15e1
commit a17d06abcb
7 changed files with 51 additions and 58 deletions

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.76 2003-03-17 00:40:57 cbothamy Exp $ // $Id: cpu.cc,v 1.77 2003-05-10 22:25:43 kevinlawton Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -193,18 +193,16 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_count)
#if BX_SupportICache #if BX_SupportICache
unsigned iCacheHash; unsigned iCacheHash;
Bit32u pAddr, pageWriteStamp, fetchModeMask; Bit32u pAddr, pageWriteStamp;
pAddr = BX_CPU_THIS_PTR pAddrA20Page + eipBiased; pAddr = BX_CPU_THIS_PTR pAddrA20Page + eipBiased;
iCacheHash = BX_CPU_THIS_PTR iCache.hash( pAddr ); iCacheHash = BX_CPU_THIS_PTR iCache.hash( pAddr );
i = & BX_CPU_THIS_PTR iCache.entry[iCacheHash].i; i = & BX_CPU_THIS_PTR iCache.entry[iCacheHash].i;
pageWriteStamp = BX_CPU_THIS_PTR iCache.pageWriteStampTable[pAddr>>12]; 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) && if ( (BX_CPU_THIS_PTR iCache.entry[iCacheHash].pAddr == pAddr) &&
(BX_CPU_THIS_PTR iCache.entry[iCacheHash].writeStamp == pageWriteStamp) && (BX_CPU_THIS_PTR iCache.entry[iCacheHash].writeStamp == pageWriteStamp) ) {
((pageWriteStamp & fetchModeMask) == fetchModeMask) ) {
// iCache hit. Instruction is already decoded and stored in // iCache hit. Instruction is already decoded and stored in
// the instruction cache. // the instruction cache.
@ -228,6 +226,7 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_count)
// case we always have an iCache miss. :^) // case we always have an iCache miss. :^)
bx_address remainingInPage; bx_address remainingInPage;
unsigned maxFetch; unsigned maxFetch;
Bit32u fetchModeMask;
remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased); remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased);
maxFetch = 15; maxFetch = 15;
@ -243,6 +242,7 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_count)
// willing to dump all iCache entries which can hash to this page. // willing to dump all iCache entries which can hash to this page.
// Therefore, in either case, we can keep the counter as-is and // Therefore, in either case, we can keep the counter as-is and
// replace the fetch mode bits. // replace the fetch mode bits.
fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask;
pageWriteStamp &= 0x1fffffff; // Clear out old fetch mode bits. pageWriteStamp &= 0x1fffffff; // Clear out old fetch mode bits.
pageWriteStamp |= fetchModeMask; // Add in new ones. pageWriteStamp |= fetchModeMask; // Add in new ones.
BX_CPU_THIS_PTR iCache.pageWriteStampTable[pAddr>>12] = pageWriteStamp; BX_CPU_THIS_PTR iCache.pageWriteStampTable[pAddr>>12] = pageWriteStamp;
@ -776,6 +776,21 @@ BX_CPU_C::prefetch(void)
pAddr)); 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;
}
} }
@ -842,33 +857,6 @@ BX_CPU_THIS_PTR eipPageWindowSize = 0; // Fixme
} }
#if 0
// Now a no-op.
// If control has transfered locally, it is possible the prefetch Q is
// still valid. This would happen for repeat instructions, and small
// branches.
void
BX_CPU_C::revalidate_prefetch_q(void)
{
#ifdef __GNUC__
#warning "::revalidate_prefetch_q() is ifdef'd out."
#endif
bx_address eipBiased;
eipBiased = RIP + BX_CPU_THIS_PTR eipPageBias;
if ( eipBiased < BX_CPU_THIS_PTR eipPageWindowSize ) {
// Good, EIP still within prefetch window.
}
else {
// EIP has branched outside the prefetch window. Mark the
// prefetch info as invalid, and requiring update.
BX_CPU_THIS_PTR eipPageWindowSize = 0;
}
}
#endif
#if BX_EXTERNAL_DEBUGGER #if BX_EXTERNAL_DEBUGGER
void void

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.137 2003-04-22 20:21:31 sshwarts Exp $ // $Id: cpu.h,v 1.138 2003-05-10 22:25:48 kevinlawton Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -990,6 +990,7 @@ typedef void (BX_CPU_C::*BxExecutePtr_tR)(bxInstruction_c *) BX_CPP_AttrRegparmN
#define ICacheWriteStampInvalid 0x1fffffff #define ICacheWriteStampInvalid 0x1fffffff
#define ICacheWriteStampMax 0x1fffffff // Decrements from here. #define ICacheWriteStampMax 0x1fffffff // Decrements from here.
#define ICacheWriteStampMask 0x1fffffff #define ICacheWriteStampMask 0x1fffffff
#define ICacheFetchModeMask (~ICacheWriteStampMask)
class bxICacheEntry_c { class bxICacheEntry_c {
public: public:

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer16.cc,v 1.19 2003-02-13 15:03:59 sshwarts Exp $ // $Id: ctrl_xfer16.cc,v 1.20 2003-05-10 22:25:51 kevinlawton Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -40,7 +40,7 @@ BailBigRSP("RETnear16_Iw");
Bit16u imm16; Bit16u imm16;
Bit16u return_IP; Bit16u return_IP;
invalidate_prefetch_q(); //invalidate_prefetch_q();
#if BX_DEBUGGER #if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret; BX_CPU_THIS_PTR show_flag |= Flag_ret;
@ -70,7 +70,7 @@ BX_CPU_C::RETnear16(bxInstruction_c *i)
BailBigRSP("RETnear16"); BailBigRSP("RETnear16");
Bit16u return_IP; Bit16u return_IP;
invalidate_prefetch_q(); //invalidate_prefetch_q();
#if BX_DEBUGGER #if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret; BX_CPU_THIS_PTR show_flag |= Flag_ret;
@ -164,7 +164,7 @@ BX_CPU_C::CALL_Aw(bxInstruction_c *i)
BailBigRSP("CALL_Aw"); BailBigRSP("CALL_Aw");
Bit32u new_EIP; Bit32u new_EIP;
invalidate_prefetch_q(); //invalidate_prefetch_q();
#if BX_DEBUGGER #if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call; BX_CPU_THIS_PTR show_flag |= Flag_call;
@ -226,7 +226,7 @@ BX_CPU_C::CALL_Ew(bxInstruction_c *i)
BailBigRSP("CALL_Ew"); BailBigRSP("CALL_Ew");
Bit16u op1_16; Bit16u op1_16;
invalidate_prefetch_q(); //invalidate_prefetch_q();
#if BX_DEBUGGER #if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call; BX_CPU_THIS_PTR show_flag |= Flag_call;
@ -298,7 +298,7 @@ BX_CPU_C::JMP_Jw(bxInstruction_c *i)
BailBigRSP("JMP_Jw"); BailBigRSP("JMP_Jw");
Bit32u new_EIP; Bit32u new_EIP;
invalidate_prefetch_q(); //invalidate_prefetch_q();
new_EIP = EIP + (Bit32s) i->Id(); new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0x0000ffff; new_EIP &= 0x0000ffff;
@ -438,7 +438,7 @@ BailBigRSP("JMP_Ew");
Bit32u new_EIP; Bit32u new_EIP;
Bit16u op1_16; Bit16u op1_16;
invalidate_prefetch_q(); //invalidate_prefetch_q();
if (i->modC0()) { if (i->modC0()) {
op1_16 = BX_READ_16BIT_REG(i->rm()); op1_16 = BX_READ_16BIT_REG(i->rm());

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer32.cc,v 1.25 2003-02-13 15:03:59 sshwarts Exp $ // $Id: ctrl_xfer32.cc,v 1.26 2003-05-10 22:25:52 kevinlawton Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -43,7 +43,7 @@ BailBigRSP("RETnear32_Iw");
Bit32u temp_ESP; Bit32u temp_ESP;
Bit32u return_EIP; Bit32u return_EIP;
invalidate_prefetch_q(); //invalidate_prefetch_q();
#if BX_DEBUGGER #if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret; BX_CPU_THIS_PTR show_flag |= Flag_ret;
@ -102,7 +102,7 @@ BailBigRSP("RETnear32");
Bit32u temp_ESP; Bit32u temp_ESP;
Bit32u return_EIP; Bit32u return_EIP;
invalidate_prefetch_q(); //invalidate_prefetch_q();
#if BX_DEBUGGER #if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret; BX_CPU_THIS_PTR show_flag |= Flag_ret;
@ -218,7 +218,7 @@ BailBigRSP("CALL_Ad");
Bit32u new_EIP; Bit32u new_EIP;
Bit32s disp32; Bit32s disp32;
invalidate_prefetch_q(); //invalidate_prefetch_q();
#if BX_DEBUGGER #if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call; BX_CPU_THIS_PTR show_flag |= Flag_call;
@ -279,7 +279,7 @@ BailBigRSP("CALL_Ed");
Bit32u temp_ESP; Bit32u temp_ESP;
Bit32u op1_32; Bit32u op1_32;
invalidate_prefetch_q(); //invalidate_prefetch_q();
#if BX_DEBUGGER #if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call; BX_CPU_THIS_PTR show_flag |= Flag_call;
@ -356,7 +356,7 @@ BX_CPU_C::JMP_Jd(bxInstruction_c *i)
BailBigRSP("JMP_Jd"); BailBigRSP("JMP_Jd");
Bit32u new_EIP; Bit32u new_EIP;
invalidate_prefetch_q(); //invalidate_prefetch_q();
new_EIP = EIP + (Bit32s) i->Id(); new_EIP = EIP + (Bit32s) i->Id();
@ -527,7 +527,7 @@ BailBigRSP("JMP_Ed");
Bit32u new_EIP; Bit32u new_EIP;
Bit32u op1_32; Bit32u op1_32;
invalidate_prefetch_q(); //invalidate_prefetch_q();
/* op1_32 is a register or memory reference */ /* op1_32 is a register or memory reference */
if (i->modC0()) { if (i->modC0()) {

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer64.cc,v 1.21 2003-03-13 00:43:00 ptrumpet Exp $ // $Id: ctrl_xfer64.cc,v 1.22 2003-05-10 22:25:54 kevinlawton Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -43,7 +43,7 @@ BX_CPU_C::RETnear64_Iw(bxInstruction_c *i)
Bit64u temp_RSP; Bit64u temp_RSP;
Bit64u return_RIP; Bit64u return_RIP;
invalidate_prefetch_q(); //invalidate_prefetch_q();
#if BX_DEBUGGER #if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret; BX_CPU_THIS_PTR show_flag |= Flag_ret;
@ -79,7 +79,7 @@ BX_CPU_C::RETnear64(bxInstruction_c *i)
Bit64u temp_RSP; Bit64u temp_RSP;
Bit64u return_RIP; Bit64u return_RIP;
invalidate_prefetch_q(); //invalidate_prefetch_q();
#if BX_DEBUGGER #if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret; BX_CPU_THIS_PTR show_flag |= Flag_ret;
@ -171,7 +171,7 @@ BX_CPU_C::CALL_Aq(bxInstruction_c *i)
Bit64u new_RIP; Bit64u new_RIP;
Bit32s disp32; Bit32s disp32;
invalidate_prefetch_q(); //invalidate_prefetch_q();
#if BX_DEBUGGER #if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call; BX_CPU_THIS_PTR show_flag |= Flag_call;
@ -223,7 +223,7 @@ BX_CPU_C::CALL_Eq(bxInstruction_c *i)
Bit64u temp_RSP; Bit64u temp_RSP;
Bit64u op1_64; Bit64u op1_64;
invalidate_prefetch_q(); //invalidate_prefetch_q();
#if BX_DEBUGGER #if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call; BX_CPU_THIS_PTR show_flag |= Flag_call;
@ -285,7 +285,7 @@ done:
void void
BX_CPU_C::JMP_Jq(bxInstruction_c *i) BX_CPU_C::JMP_Jq(bxInstruction_c *i)
{ {
invalidate_prefetch_q(); //invalidate_prefetch_q();
RIP += (Bit32s) i->Id(); RIP += (Bit32s) i->Id();
if (i->os32L()==0) if (i->os32L()==0)
@ -379,7 +379,7 @@ BX_CPU_C::JMP_Eq(bxInstruction_c *i)
{ {
Bit64u op1_64; Bit64u op1_64;
invalidate_prefetch_q(); //invalidate_prefetch_q();
if (i->modC0()) { if (i->modC0()) {
op1_64 = BX_READ_64BIT_REG(i->rm()); op1_64 = BX_READ_64BIT_REG(i->rm());

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.69 2003-05-02 12:22:48 vruppert Exp $ // $Id: proc_ctrl.cc,v 1.70 2003-05-10 22:25:55 kevinlawton Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -1986,7 +1986,7 @@ BX_CPU_C::SYSENTER (bxInstruction_c *i)
return; return;
} }
invalidate_prefetch_q (); invalidate_prefetch_q();
BX_CPU_THIS_PTR set_VM(0); // do this just like the book says to do BX_CPU_THIS_PTR set_VM(0); // do this just like the book says to do
BX_CPU_THIS_PTR set_IF(0); BX_CPU_THIS_PTR set_IF(0);
@ -2051,7 +2051,7 @@ BX_CPU_C::SYSEXIT (bxInstruction_c *i)
return; return;
} }
invalidate_prefetch_q (); invalidate_prefetch_q();
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = (BX_CPU_THIS_PTR sysenter_cs_msr + 16) | 3; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = (BX_CPU_THIS_PTR sysenter_cs_msr + 16) | 3;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = (BX_CPU_THIS_PTR sysenter_cs_msr + 16) >> 3; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = (BX_CPU_THIS_PTR sysenter_cs_msr + 16) >> 3;

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: segment_ctrl_pro.cc,v 1.24 2003-03-02 23:59:09 cbothamy Exp $ // $Id: segment_ctrl_pro.cc,v 1.25 2003-05-10 22:25:55 kevinlawton Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -55,6 +55,7 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
BX_CPU_THIS_PTR iCache.fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask =
BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS); BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS);
#endif #endif
invalidate_prefetch_q();
} }
else else
seg->cache.u.segment.executable = 0; /* data segment */ seg->cache.u.segment.executable = 0; /* data segment */
@ -337,6 +338,7 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
BX_CPU_THIS_PTR iCache.fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask =
BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS); BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS);
#endif #endif
invalidate_prefetch_q();
} }
else { /* SS, DS, ES, FS, GS */ else { /* SS, DS, ES, FS, GS */
seg->selector.value = new_value; seg->selector.value = new_value;
@ -557,6 +559,8 @@ BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor,
BX_CPU_THIS_PTR iCache.fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask =
BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS); BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS);
#endif #endif
// Loading CS will invalidate the EIP fetch window.
invalidate_prefetch_q();
} }
void BX_CPP_AttrRegparmN(3) void BX_CPP_AttrRegparmN(3)