Small speedup in boundaryFetch method

This commit is contained in:
Stanislav Shwartsman 2005-02-12 14:00:13 +00:00
parent 0381ff52d3
commit 799403620e
2 changed files with 42 additions and 50 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.97 2005-02-05 20:56:44 sshwarts Exp $
// $Id: cpu.cc,v 1.98 2005-02-12 14:00:13 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -234,7 +234,7 @@ printf("CPU_LOOP %d\n", bx_guard.special_unwind_stack);
#if BX_SUPPORT_ICACHE
i = &iStorage; // Leave entry invalid
#endif
boundaryFetch(i);
boundaryFetch(fetchPtr, remainingInPage, i);
}
else
{
@ -299,64 +299,64 @@ repeat_loop:
if (RCX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
RCX --;
}
}
if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
if ((i->repUsedValue()==2) && (get_ZF()!=0)) goto repeat_done;
if (RCX == 0) goto repeat_done;
goto repeat_not_done;
}
}
else
#endif
if (i->as32L()) {
if (ECX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
ECX --;
}
}
if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
if ((i->repUsedValue()==2) && (get_ZF()!=0)) goto repeat_done;
if (ECX == 0) goto repeat_done;
goto repeat_not_done;
}
}
else {
if (CX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
CX --;
}
}
if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
if ((i->repUsedValue()==2) && (get_ZF()!=0)) goto repeat_done;
if (CX == 0) goto repeat_done;
goto repeat_not_done;
}
}
}
else { // normal repeat, no concern for ZF
#if BX_SUPPORT_X86_64
if (i->as64L()) {
if (RCX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
RCX --;
}
}
if (RCX == 0) goto repeat_done;
goto repeat_not_done;
}
}
else
#endif
if (i->as32L()) {
if (ECX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
ECX --;
}
}
if (ECX == 0) goto repeat_done;
goto repeat_not_done;
}
}
else { // 16bit addrsize
if (CX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
CX --;
}
}
if (CX == 0) goto repeat_done;
goto repeat_not_done;
}
}
}
// shouldn't get here from above
repeat_not_done:
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID);
@ -417,8 +417,8 @@ debugger_check:
return;
default:
BX_PANIC(("Weird break point condition"));
}
}
}
#if BX_MAGIC_BREAKPOINT
// (mch) Magic break point support
if (BX_CPU_THIS_PTR magic_break) {
@ -426,13 +426,13 @@ debugger_check:
BX_DEBUG(("Stopped on MAGIC BREAKPOINT"));
BX_CPU_THIS_PTR stop_reason = STOP_MAGIC_BREAK_POINT;
return;
}
}
else {
BX_CPU_THIS_PTR magic_break = 0;
BX_CPU_THIS_PTR stop_reason = STOP_NO_REASON;
BX_DEBUG(("Ignoring MAGIC BREAKPOINT"));
}
}
}
#endif
{
@ -460,8 +460,7 @@ debugger_check:
} // while (1)
}
unsigned
BX_CPU_C::handleAsyncEvent(void)
unsigned BX_CPU_C::handleAsyncEvent(void)
{
//
// This area is where we process special conditions and events.
@ -479,16 +478,16 @@ BX_CPU_C::handleAsyncEvent(void)
#else
while (1)
#endif
{
{
if (BX_CPU_INTR && BX_CPU_THIS_PTR get_IF ()) {
break;
}
}
if (BX_CPU_THIS_PTR async_event == 2) {
BX_INFO(("decode: reset detected in halt state"));
break;
}
BX_TICK1();
}
BX_TICK1();
}
#else /* BX_SMP_PROCESSORS != 1 */
// for multiprocessor simulation, even if this CPU is halted we still
// must give the others a chance to simulate. If an interrupt has
@ -523,7 +522,7 @@ BX_CPU_C::handleAsyncEvent(void)
if (BX_CPU_THIS_PTR debug_trap & 0x00008000) {
BX_CPU_THIS_PTR dr6 |= BX_CPU_THIS_PTR debug_trap;
exception(BX_DB_EXCEPTION, 0, 0); // no error, not interrupt
}
}
// Priority 3: External Hardware Interventions
// FLUSH
@ -536,14 +535,15 @@ BX_CPU_C::handleAsyncEvent(void)
// Breakpoints
// Debug Trap Exceptions (TF flag set or data/IO breakpoint)
if ( BX_CPU_THIS_PTR debug_trap &&
!(BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_DEBUG) ) {
!(BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_DEBUG) )
{
// A trap may be inhibited on this boundary due to an instruction
// which loaded SS. If so we clear the inhibit_mask below
// and don't execute this code until the next boundary.
// Commit debug events to DR6
BX_CPU_THIS_PTR dr6 |= BX_CPU_THIS_PTR debug_trap;
exception(BX_DB_EXCEPTION, 0, 0); // no error, not interrupt
}
}
// Priority 5: External Interrupts
// NMI Interrupts
@ -554,9 +554,10 @@ BX_CPU_C::handleAsyncEvent(void)
// inhibit_mask is cleared below, in which case we will have
// an opportunity to check interrupts on the next instruction
// boundary.
}
}
else if (BX_CPU_INTR && BX_CPU_THIS_PTR get_IF () &&
BX_DBG_ASYNC_INTR) {
BX_DBG_ASYNC_INTR)
{
Bit8u vector;
// NOTE: similar code in ::take_irq()
@ -585,12 +586,12 @@ BX_CPU_C::handleAsyncEvent(void)
BX_CPU_THIS_PTR prev_esp = RSP; // commit new RSP
BX_CPU_THIS_PTR EXT = 0;
BX_CPU_THIS_PTR errorno = 0;
}
}
else if (BX_HRQ && BX_DBG_ASYNC_DMA) {
// NOTE: similar code in ::take_dma()
// assert Hold Acknowledge (HLDA) and go into a bus hold state
DEV_dma_raise_hlda();
}
}
// Priority 6: Faults from fetching next instruction
// Code breakpoint fault
@ -617,18 +618,19 @@ BX_CPU_C::handleAsyncEvent(void)
// (handled by rest of the code)
if (BX_CPU_THIS_PTR get_TF ()) {
if (BX_CPU_THIS_PTR get_TF ())
{
// TF is set before execution of next instruction. Schedule
// a debug trap (#DB) after execution. After completion of
// next instruction, the code above will invoke the trap.
BX_CPU_THIS_PTR debug_trap |= 0x00004000; // BS flag in DR6
}
}
// Now we can handle things which are synchronous to instruction
// execution.
if (BX_CPU_THIS_PTR get_RF ()) {
BX_CPU_THIS_PTR clear_RF ();
}
}
#if BX_X86_DEBUGGER
else {
// only bother comparing if any breakpoints enabled
@ -638,7 +640,8 @@ BX_CPU_C::handleAsyncEvent(void)
BX_CPU_THIS_PTR prev_eip;
Bit32u dr6_bits;
if ( (dr6_bits = hwdebug_compare(iaddr, 1, BX_HWDebugInstruction,
BX_HWDebugInstruction)) ) {
BX_HWDebugInstruction)) )
{
// Add to the list of debug events thus far.
BX_CPU_THIS_PTR async_event = 1;
BX_CPU_THIS_PTR debug_trap |= dr6_bits;
@ -649,10 +652,10 @@ BX_CPU_C::handleAsyncEvent(void)
// Commit debug events to DR6
BX_CPU_THIS_PTR dr6 = BX_CPU_THIS_PTR debug_trap;
exception(BX_DB_EXCEPTION, 0, 0); // no error, not interrupt
}
}
}
}
}
#endif
// We have ignored processing of external interrupts and
@ -674,8 +677,6 @@ BX_CPU_C::handleAsyncEvent(void)
}
// boundaries of consideration:
//
// * physical memory boundary: 1024k (1Megabyte) (increments of...)
@ -685,9 +686,7 @@ BX_CPU_C::handleAsyncEvent(void)
// * segment boundary: any
void
BX_CPU_C::prefetch(void)
void BX_CPU_C::prefetch(void)
{
// cs:eIP
// prefetch QSIZE byte quantity aligned on corresponding boundary
@ -760,23 +759,16 @@ BX_CPU_C::prefetch(void)
#endif
}
void
BX_CPU_C::boundaryFetch(bxInstruction_c *i)
void BX_CPU_C::boundaryFetch(Bit8u *fetchPtr, unsigned remainingInPage, bxInstruction_c *i)
{
unsigned j;
Bit8u fetchBuffer[16]; // Really only need 15
bx_address eipBiased, remainingInPage;
Bit8u *fetchPtr;
unsigned ret;
eipBiased = RIP + BX_CPU_THIS_PTR eipPageBias;
remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased);
if (remainingInPage >= 15) {
BX_INFO(("fetchDecode #GP(0): too many instruction prefixes"));
exception(BX_GP_EXCEPTION, 0, 0);
}
fetchPtr = BX_CPU_THIS_PTR eipFetchPtr + eipBiased;
// Read all leftover bytes in current page up to boundary.
for (j=0; j<remainingInPage; j++) {

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.195 2005-02-03 22:08:34 sshwarts Exp $
// $Id: cpu.h,v 1.196 2005-02-12 14:00:13 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -2696,7 +2696,7 @@ public: // for now...
// now for some ancillary functions...
BX_SMF void cpu_loop(Bit32s max_instr_count);
BX_SMF unsigned handleAsyncEvent(void);
BX_SMF void boundaryFetch(bxInstruction_c *i);
BX_SMF void boundaryFetch(Bit8u *fetchPtr, unsigned remainingInPage, bxInstruction_c *i);
BX_SMF void branch_near32(Bit32u new_eip) BX_CPP_AttrRegparmN(1);
BX_SMF void prefetch(void);