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:
parent
b9a25b15e1
commit
a17d06abcb
@ -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.
|
||||
@ -193,18 +193,16 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_count)
|
||||
|
||||
#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.
|
||||
@ -228,6 +226,7 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_count)
|
||||
// case we always have an iCache miss. :^)
|
||||
bx_address remainingInPage;
|
||||
unsigned maxFetch;
|
||||
Bit32u fetchModeMask;
|
||||
|
||||
remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased);
|
||||
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.
|
||||
// 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;
|
||||
@ -776,6 +776,21 @@ BX_CPU_C::prefetch(void)
|
||||
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
|
||||
|
||||
void
|
||||
|
@ -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.
|
||||
@ -990,6 +990,7 @@ typedef void (BX_CPU_C::*BxExecutePtr_tR)(bxInstruction_c *) BX_CPP_AttrRegparmN
|
||||
#define ICacheWriteStampInvalid 0x1fffffff
|
||||
#define ICacheWriteStampMax 0x1fffffff // Decrements from here.
|
||||
#define ICacheWriteStampMask 0x1fffffff
|
||||
#define ICacheFetchModeMask (~ICacheWriteStampMask)
|
||||
|
||||
class bxICacheEntry_c {
|
||||
public:
|
||||
|
@ -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.
|
||||
@ -40,7 +40,7 @@ BailBigRSP("RETnear16_Iw");
|
||||
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 @@ BX_CPU_C::RETnear16(bxInstruction_c *i)
|
||||
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 @@ BX_CPU_C::CALL_Aw(bxInstruction_c *i)
|
||||
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 @@ BX_CPU_C::CALL_Ew(bxInstruction_c *i)
|
||||
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 @@ BX_CPU_C::JMP_Jw(bxInstruction_c *i)
|
||||
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 @@ BailBigRSP("JMP_Ew");
|
||||
Bit32u new_EIP;
|
||||
Bit16u op1_16;
|
||||
|
||||
invalidate_prefetch_q();
|
||||
//invalidate_prefetch_q();
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
|
@ -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.
|
||||
@ -43,7 +43,7 @@ BailBigRSP("RETnear32_Iw");
|
||||
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 @@ BailBigRSP("RETnear32");
|
||||
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 @@ BailBigRSP("CALL_Ad");
|
||||
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 @@ BailBigRSP("CALL_Ed");
|
||||
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 @@ BX_CPU_C::JMP_Jd(bxInstruction_c *i)
|
||||
BailBigRSP("JMP_Jd");
|
||||
Bit32u new_EIP;
|
||||
|
||||
invalidate_prefetch_q();
|
||||
//invalidate_prefetch_q();
|
||||
|
||||
new_EIP = EIP + (Bit32s) i->Id();
|
||||
|
||||
@ -527,7 +527,7 @@ BailBigRSP("JMP_Ed");
|
||||
Bit32u new_EIP;
|
||||
Bit32u op1_32;
|
||||
|
||||
invalidate_prefetch_q();
|
||||
//invalidate_prefetch_q();
|
||||
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
|
@ -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.
|
||||
@ -43,7 +43,7 @@ BX_CPU_C::RETnear64_Iw(bxInstruction_c *i)
|
||||
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 @@ BX_CPU_C::RETnear64(bxInstruction_c *i)
|
||||
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 @@ BX_CPU_C::CALL_Aq(bxInstruction_c *i)
|
||||
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 @@ BX_CPU_C::CALL_Eq(bxInstruction_c *i)
|
||||
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 @@ done:
|
||||
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 @@ BX_CPU_C::JMP_Eq(bxInstruction_c *i)
|
||||
{
|
||||
Bit64u op1_64;
|
||||
|
||||
invalidate_prefetch_q();
|
||||
//invalidate_prefetch_q();
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_64 = BX_READ_64BIT_REG(i->rm());
|
||||
|
@ -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.
|
||||
@ -1986,7 +1986,7 @@ BX_CPU_C::SYSENTER (bxInstruction_c *i)
|
||||
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_IF(0);
|
||||
@ -2051,7 +2051,7 @@ BX_CPU_C::SYSEXIT (bxInstruction_c *i)
|
||||
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.index = (BX_CPU_THIS_PTR sysenter_cs_msr + 16) >> 3;
|
||||
|
@ -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.
|
||||
@ -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.createFetchModeMask(BX_CPU_THIS);
|
||||
#endif
|
||||
invalidate_prefetch_q();
|
||||
}
|
||||
else
|
||||
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.createFetchModeMask(BX_CPU_THIS);
|
||||
#endif
|
||||
invalidate_prefetch_q();
|
||||
}
|
||||
else { /* SS, DS, ES, FS, GS */
|
||||
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.createFetchModeMask(BX_CPU_THIS);
|
||||
#endif
|
||||
// Loading CS will invalidate the EIP fetch window.
|
||||
invalidate_prefetch_q();
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
|
Loading…
Reference in New Issue
Block a user