Separate fetch/decode instruction block to stand-alone method.
The method could be reused when building instruction trace for DT
This commit is contained in:
parent
0150904e9d
commit
79306b851c
176
bochs/cpu/cpu.cc
176
bochs/cpu/cpu.cc
@ -1,5 +1,5 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// $Id: cpu.cc,v 1.131 2006-02-14 20:03:14 sshwarts Exp $
|
// $Id: cpu.cc,v 1.132 2006-02-23 18:23:31 sshwarts Exp $
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||||
@ -122,9 +122,7 @@ static unsigned iCacheMisses=0;
|
|||||||
|
|
||||||
void BX_CPU_C::cpu_loop(Bit32s max_instr_count)
|
void BX_CPU_C::cpu_loop(Bit32s max_instr_count)
|
||||||
{
|
{
|
||||||
unsigned ret;
|
|
||||||
bxInstruction_c iStorage BX_CPP_AlignN(32);
|
bxInstruction_c iStorage BX_CPP_AlignN(32);
|
||||||
bxInstruction_c *i = &iStorage;
|
|
||||||
|
|
||||||
#if BX_DEBUGGER
|
#if BX_DEBUGGER
|
||||||
BX_CPU_THIS_PTR break_point = 0;
|
BX_CPU_THIS_PTR break_point = 0;
|
||||||
@ -205,86 +203,8 @@ void BX_CPU_C::cpu_loop(Bit32s max_instr_count)
|
|||||||
eipBiased = RIP + BX_CPU_THIS_PTR eipPageBias;
|
eipBiased = RIP + BX_CPU_THIS_PTR eipPageBias;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BX_SUPPORT_ICACHE
|
// fetch and decode next instruction
|
||||||
Bit32u pAddr = BX_CPU_THIS_PTR pAddrA20Page + eipBiased;
|
bxInstruction_c *i = fetchInstruction(&iStorage, eipBiased);
|
||||||
unsigned iCacheHash = BX_CPU_THIS_PTR iCache.hash(pAddr);
|
|
||||||
bxICacheEntry_c *cache_entry = &(BX_CPU_THIS_PTR iCache.entry[iCacheHash]);
|
|
||||||
i = &(cache_entry->i);
|
|
||||||
|
|
||||||
Bit32u pageWriteStamp = *(BX_CPU_THIS_PTR currPageWriteStampPtr);
|
|
||||||
|
|
||||||
#if BX_SUPPORT_ICACHE
|
|
||||||
InstrICache_Increment(iCacheLookups);
|
|
||||||
InstrICache_Stats();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((cache_entry->pAddr == pAddr) &&
|
|
||||||
(cache_entry->writeStamp == pageWriteStamp))
|
|
||||||
{
|
|
||||||
// iCache hit. Instruction is already decoded and stored in the
|
|
||||||
// instruction cache.
|
|
||||||
|
|
||||||
#if BX_INSTRUMENTATION
|
|
||||||
// An instruction was found in the iCache.
|
|
||||||
BX_INSTR_OPCODE(BX_CPU_ID, BX_CPU_THIS_PTR eipFetchPtr + eipBiased,
|
|
||||||
i->ilen(), BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, Is64BitMode());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
// iCache miss. No validated instruction with matching fetch parameters
|
|
||||||
// is in the iCache. Or we're not compiling iCache support in, in which
|
|
||||||
// case we always have an iCache miss. :^)
|
|
||||||
bx_address remainingInPage;
|
|
||||||
remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased);
|
|
||||||
unsigned maxFetch = 15;
|
|
||||||
if (remainingInPage < 15) maxFetch = remainingInPage;
|
|
||||||
Bit8u *fetchPtr = BX_CPU_THIS_PTR eipFetchPtr + eipBiased;
|
|
||||||
|
|
||||||
#if BX_SUPPORT_ICACHE
|
|
||||||
// The entry will be marked valid if fetchdecode will succeed
|
|
||||||
cache_entry->writeStamp = ICacheWriteStampInvalid;
|
|
||||||
InstrICache_Increment(iCacheMisses);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BX_SUPPORT_X86_64
|
|
||||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
|
|
||||||
ret = fetchDecode64(fetchPtr, i, maxFetch);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
ret = fetchDecode(fetchPtr, i, maxFetch);
|
|
||||||
|
|
||||||
if (ret==0) {
|
|
||||||
#if BX_SUPPORT_ICACHE
|
|
||||||
i = &iStorage; // Leave entry invalid
|
|
||||||
#endif
|
|
||||||
boundaryFetch(fetchPtr, remainingInPage, i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if BX_SUPPORT_ICACHE
|
|
||||||
// In the case where the page is marked ICacheWriteStampInvalid, all
|
|
||||||
// counter bits will be high, being eqivalent to ICacheWriteStampMax.
|
|
||||||
// In the case where the page is marked as possibly having associated
|
|
||||||
// iCache entries, we need to leave the counter as-is, unless we're
|
|
||||||
// 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.
|
|
||||||
pageWriteStampTable.setPageWriteStamp(pAddr, pageWriteStamp);
|
|
||||||
cache_entry->pAddr = pAddr;
|
|
||||||
cache_entry->writeStamp = pageWriteStamp;
|
|
||||||
#endif
|
|
||||||
#if BX_INSTRUMENTATION
|
|
||||||
// An instruction was either fetched, or found in the iCache.
|
|
||||||
BX_INSTR_OPCODE(BX_CPU_ID, fetchPtr, i->ilen(),
|
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, Is64BitMode());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bx_address next_RIP = RIP + i->ilen();
|
bx_address next_RIP = RIP + i->ilen();
|
||||||
if (! Is64BitMode()) {
|
if (! Is64BitMode()) {
|
||||||
@ -497,6 +417,93 @@ debugger_check:
|
|||||||
} // while (1)
|
} // while (1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bxInstruction_c* BX_CPU_C::fetchInstruction(bxInstruction_c *iStorage, bx_address eipBiased)
|
||||||
|
{
|
||||||
|
unsigned ret;
|
||||||
|
bxInstruction_c *i = iStorage;
|
||||||
|
|
||||||
|
#if BX_SUPPORT_ICACHE
|
||||||
|
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrA20Page + eipBiased;
|
||||||
|
unsigned iCacheHash = BX_CPU_THIS_PTR iCache.hash(pAddr);
|
||||||
|
bxICacheEntry_c *cache_entry = &(BX_CPU_THIS_PTR iCache.entry[iCacheHash]);
|
||||||
|
i = &(cache_entry->i);
|
||||||
|
|
||||||
|
Bit32u pageWriteStamp = *(BX_CPU_THIS_PTR currPageWriteStampPtr);
|
||||||
|
|
||||||
|
InstrICache_Increment(iCacheLookups);
|
||||||
|
InstrICache_Stats();
|
||||||
|
|
||||||
|
if ((cache_entry->pAddr == pAddr) &&
|
||||||
|
(cache_entry->writeStamp == pageWriteStamp))
|
||||||
|
{
|
||||||
|
// iCache hit. Instruction is already decoded and stored in the
|
||||||
|
// instruction cache.
|
||||||
|
|
||||||
|
#if BX_INSTRUMENTATION
|
||||||
|
// An instruction was found in the iCache.
|
||||||
|
BX_INSTR_OPCODE(BX_CPU_ID, BX_CPU_THIS_PTR eipFetchPtr + eipBiased,
|
||||||
|
i->ilen(), BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, Is64BitMode());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// iCache miss. No validated instruction with matching fetch parameters
|
||||||
|
// is in the iCache. Or we're not compiling iCache support in, in which
|
||||||
|
// case we always have an iCache miss. :^)
|
||||||
|
bx_address remainingInPage;
|
||||||
|
remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased);
|
||||||
|
unsigned maxFetch = 15;
|
||||||
|
if (remainingInPage < 15) maxFetch = remainingInPage;
|
||||||
|
Bit8u *fetchPtr = BX_CPU_THIS_PTR eipFetchPtr + eipBiased;
|
||||||
|
|
||||||
|
#if BX_SUPPORT_ICACHE
|
||||||
|
// The entry will be marked valid if fetchdecode will succeed
|
||||||
|
cache_entry->writeStamp = ICacheWriteStampInvalid;
|
||||||
|
InstrICache_Increment(iCacheMisses);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BX_SUPPORT_X86_64
|
||||||
|
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
|
||||||
|
ret = fetchDecode64(fetchPtr, i, maxFetch);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
ret = fetchDecode(fetchPtr, i, maxFetch);
|
||||||
|
|
||||||
|
if (ret==0) {
|
||||||
|
#if BX_SUPPORT_ICACHE
|
||||||
|
i = iStorage; // Leave entry invalid
|
||||||
|
#endif
|
||||||
|
boundaryFetch(fetchPtr, remainingInPage, i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if BX_SUPPORT_ICACHE
|
||||||
|
// In the case where the page is marked ICacheWriteStampInvalid, all
|
||||||
|
// counter bits will be high, being eqivalent to ICacheWriteStampMax.
|
||||||
|
// In the case where the page is marked as possibly having associated
|
||||||
|
// iCache entries, we need to leave the counter as-is, unless we're
|
||||||
|
// 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.
|
||||||
|
pageWriteStampTable.setPageWriteStamp(pAddr, pageWriteStamp);
|
||||||
|
cache_entry->pAddr = pAddr;
|
||||||
|
cache_entry->writeStamp = pageWriteStamp;
|
||||||
|
#endif
|
||||||
|
#if BX_INSTRUMENTATION
|
||||||
|
// An instruction was either fetched, or found in the iCache.
|
||||||
|
BX_INSTR_OPCODE(BX_CPU_ID, fetchPtr, i->ilen(),
|
||||||
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, Is64BitMode());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned BX_CPU_C::handleAsyncEvent(void)
|
unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -727,8 +734,9 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
|||||||
|
|
||||||
void BX_CPU_C::prefetch(void)
|
void BX_CPU_C::prefetch(void)
|
||||||
{
|
{
|
||||||
|
bx_phy_address pAddr;
|
||||||
|
|
||||||
// prefetch QSIZE byte quantity aligned on corresponding boundary
|
// prefetch QSIZE byte quantity aligned on corresponding boundary
|
||||||
Bit32u pAddr;
|
|
||||||
bx_address laddrPageOffset0, eipPageOffset0;
|
bx_address laddrPageOffset0, eipPageOffset0;
|
||||||
|
|
||||||
bx_address temp_rip = RIP;
|
bx_address temp_rip = RIP;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// $Id: cpu.h,v 1.261 2006-02-17 13:34:30 sshwarts Exp $
|
// $Id: cpu.h,v 1.262 2006-02-23 18:23:31 sshwarts Exp $
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||||
@ -1166,8 +1166,8 @@ public: // for now...
|
|||||||
bx_address eipPageBias;
|
bx_address eipPageBias;
|
||||||
bx_address eipPageWindowSize;
|
bx_address eipPageWindowSize;
|
||||||
Bit8u *eipFetchPtr;
|
Bit8u *eipFetchPtr;
|
||||||
Bit32u pAddrA20Page; // Guest physical address of current instruction
|
bx_phy_address pAddrA20Page; // Guest physical address of current instruction
|
||||||
// page with A20() already applied.
|
// page with A20() already applied.
|
||||||
#if BX_SUPPORT_ICACHE
|
#if BX_SUPPORT_ICACHE
|
||||||
const Bit32u *currPageWriteStampPtr;
|
const Bit32u *currPageWriteStampPtr;
|
||||||
#endif
|
#endif
|
||||||
@ -2469,6 +2469,7 @@ public: // for now...
|
|||||||
#if BX_SUPPORT_X86_64
|
#if BX_SUPPORT_X86_64
|
||||||
BX_SMF unsigned fetchDecode64(Bit8u *, bxInstruction_c *, unsigned);
|
BX_SMF unsigned fetchDecode64(Bit8u *, bxInstruction_c *, unsigned);
|
||||||
#endif
|
#endif
|
||||||
|
BX_SMF bxInstruction_c* fetchInstruction(bxInstruction_c *, bx_address);
|
||||||
BX_SMF void UndefinedOpcode(bxInstruction_c *);
|
BX_SMF void UndefinedOpcode(bxInstruction_c *);
|
||||||
BX_SMF void BxError(bxInstruction_c *i);
|
BX_SMF void BxError(bxInstruction_c *i);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// $Id: main.cc,v 1.315 2006-02-22 19:18:28 vruppert Exp $
|
// $Id: main.cc,v 1.316 2006-02-23 18:23:30 sshwarts Exp $
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||||
@ -868,7 +868,10 @@ int bx_init_hardware()
|
|||||||
BX_INFO((" fpu support: %s",BX_SUPPORT_FPU?"yes":"no"));
|
BX_INFO((" fpu support: %s",BX_SUPPORT_FPU?"yes":"no"));
|
||||||
BX_INFO((" paging support: %s, tlb enabled: %s",BX_SUPPORT_PAGING?"yes":"no",BX_USE_TLB?"yes":"no"));
|
BX_INFO((" paging support: %s, tlb enabled: %s",BX_SUPPORT_PAGING?"yes":"no",BX_USE_TLB?"yes":"no"));
|
||||||
BX_INFO((" mmx support: %s",BX_SUPPORT_MMX?"yes":"no"));
|
BX_INFO((" mmx support: %s",BX_SUPPORT_MMX?"yes":"no"));
|
||||||
BX_INFO((" sse support: %s",BX_SUPPORT_SSE==2?"2":BX_SUPPORT_SSE==1?"1":"no"));
|
if (BX_SUPPORT_SSE == 0)
|
||||||
|
BX_INFO((" sse support: no"));
|
||||||
|
else
|
||||||
|
BX_INFO((" sse support: %d",BX_SUPPORT_SSE));
|
||||||
BX_INFO((" v8086 mode support: %s",BX_SUPPORT_V8086_MODE?"yes":"no"));
|
BX_INFO((" v8086 mode support: %s",BX_SUPPORT_V8086_MODE?"yes":"no"));
|
||||||
BX_INFO((" VME support: %s",BX_SUPPORT_VME?"yes":"no"));
|
BX_INFO((" VME support: %s",BX_SUPPORT_VME?"yes":"no"));
|
||||||
BX_INFO((" 3dnow! support: %s",BX_SUPPORT_3DNOW?"yes":"no"));
|
BX_INFO((" 3dnow! support: %s",BX_SUPPORT_3DNOW?"yes":"no"));
|
||||||
|
Loading…
Reference in New Issue
Block a user