There's a bug in the repeated IO & mem copy speedups. I

added --enable-repeat-speedups with default to disabled.
Reconfigure/recompile and the speedup code will be #ifdef'd
out for now.  It manifested as junk written to the VGA screen
while booting/running Windows.

Also made some more mods to the main cpu loop.  Moved the
handling of EXT/errorno outside the main loop, much like
the extra EIP/ESP commits were moved, for a little better
performance.

I changed the fetch_ptr/bytesleft method of fetching to
a slightly different model, which calculates a window
for which EIP will be valid (land on the current page),
and a bias which when applied to EIP will be from
0..upper_page_limit.  Speed is about the same for either
method, but a pseudo-op/threaded-interpreter will plug
in better with this and be faster.
This commit is contained in:
Kevin Lawton 2002-09-02 18:44:35 +00:00
parent 0268014110
commit 746f09b427
8 changed files with 470 additions and 398 deletions

View File

@ -544,6 +544,7 @@ typedef unsigned int Boolean;
#define BX_SUPPORT_MMX 0
#define BX_SUPPORT_4MEG_PAGES 0
#define BX_SupportGuest2HostTLB 0
#define BX_SupportRepeatSpeedups 0
#define BX_HAVE_GETENV 0
#define BX_HAVE_SELECT 0

524
bochs/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@ dnl // Process this file with autoconf to produce a configure script.
AC_PREREQ(2.4)
AC_INIT(bochs.h)
AC_REVISION([[$Id: configure.in,v 1.90 2002-09-01 20:12:09 kevinlawton Exp $]])
AC_REVISION([[$Id: configure.in,v 1.91 2002-09-02 18:44:35 kevinlawton Exp $]])
AC_CONFIG_HEADER(config.h)
dnl // Put Bochs version information right here so that it gets substituted
@ -579,6 +579,23 @@ AC_ARG_ENABLE(guest2host-tlb,
)
AC_SUBST(BX_SupportGuest2HostTLB)
AC_MSG_CHECKING(for repeated IO and mem copy speedups)
AC_ARG_ENABLE(repeat-speedups,
[ --enable-repeat-speedups support repeated IO and mem copy speedups],
[if test "$enableval" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE(BX_SupportRepeatSpeedups, 1)
else
AC_MSG_RESULT(no)
AC_DEFINE(BX_SupportRepeatSpeedups, 0)
fi],
[
AC_MSG_RESULT(no)
AC_DEFINE(BX_SupportRepeatSpeedups, 0)
]
)
AC_SUBST(BX_SupportRepeatSpeedups)
AC_MSG_CHECKING(for port e9 hack)
AC_ARG_ENABLE(port-e9-hack,

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.35 2002-09-01 23:02:36 kevinlawton Exp $
// $Id: cpu.cc,v 1.36 2002-09-02 18:44:35 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -35,7 +35,6 @@
#define this (BX_CPU(0))
#endif
//unsigned counter[2] = { 0, 0 };
#if BX_SIM_ID == 0 // only need to define once
@ -105,15 +104,12 @@ extern void REGISTER_IADDR(Bit32u addr);
BX_CPU_C::cpu_loop(Bit32s max_instr_count)
{
unsigned ret;
BxInstruction_t *i;
unsigned maxisize;
Bit8u *fetch_ptr;
Boolean is_32;
//BxInstruction_t *i;
// Need to look into whether to change this back to:
// BxInstruction_t i;
BxInstruction_t bxinstruction_dummy;
i = &bxinstruction_dummy;
BxInstruction_t i;
//BxInstruction_t bxinstruction_dummy;
//i = &bxinstruction_dummy;
#if BX_DEBUGGER
@ -126,16 +122,17 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_count)
(void) setjmp( BX_CPU_THIS_PTR jmp_buf_env );
// not sure if these two are used during the async handling... --bbd
// We get here either by a normal function call, or by a longjmp
// back from an exception() call. In either case, commit the
// new EIP/ESP, and set up other environmental fields. This code
// mirrors similar code below, after the interrupt() call.
BX_CPU_THIS_PTR prev_eip = EIP; // commit new EIP
BX_CPU_THIS_PTR prev_esp = ESP; // commit new ESP
main_cpu_loop:
// ???
BX_CPU_THIS_PTR EXT = 0;
BX_CPU_THIS_PTR errorno = 0;
main_cpu_loop:
// First check on events which occurred for previous instructions
// (traps) and ones which are asynchronous to the CPU
// (hardware interrupts).
@ -199,32 +196,40 @@ async_events_processed:
if ((n & 0xffffff) == 0) {
Bit32u cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
Bit32u eip = BX_CPU_THIS_PTR prev_eip;
fprintf (stdout, "instr %d, time %lld, pc %04x:%08x, fetch_ptr=%p\n", n, bx_pc_system.time_ticks (), cs, eip, fetch_ptr);
fprintf (stdout, "instr %d, time %lld, pc %04x:%08x, fetch_ptr=%p\n", n, bx_pc_system.time_ticks (), cs, eip, BX_CPU_THIS_PTR fetch_ptr);
}
n++;
}
#endif
is_32 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b;
{
Bit32u eipBiased;
Bit32u remainingInPage;
unsigned maxFetch;
Bit8u *fetchPtr;
if (BX_CPU_THIS_PTR bytesleft == 0) {
eipBiased = EIP + BX_CPU_THIS_PTR eipPageBias;
if ( eipBiased >= BX_CPU_THIS_PTR eipPageWindowSize ) {
prefetch();
eipBiased = EIP + BX_CPU_THIS_PTR eipPageBias;
}
fetch_ptr = BX_CPU_THIS_PTR fetch_ptr;
maxisize = 16;
if (BX_CPU_THIS_PTR bytesleft < 16) {
maxisize = BX_CPU_THIS_PTR bytesleft;
}
ret = FetchDecode(fetch_ptr, i, maxisize, is_32);
remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased);
maxFetch = 15;
if (remainingInPage < 15)
maxFetch = remainingInPage;
fetchPtr = BX_CPU_THIS_PTR eipFetchPtr + eipBiased;
ret = FetchDecode(fetchPtr, &i, maxFetch,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b);
}
if (ret) {
if (i->ResolveModrm) {
if (i.ResolveModrm) {
// call method on BX_CPU_C object
BX_CPU_CALL_METHOD(i->ResolveModrm, (i));
BX_CPU_CALL_METHOD(i.ResolveModrm, (&i));
}
BX_CPU_THIS_PTR fetch_ptr += i->ilen;
BX_CPU_THIS_PTR bytesleft -= i->ilen;
fetch_decode_OK:
#if BX_DEBUGGER
@ -238,34 +243,48 @@ fetch_decode_OK:
}
#endif
if (i->rep_used && (i->attr & BxRepeatable)) {
if ( !(i.rep_used && (i.attr & BxRepeatable)) ) {
// non repeating instruction
EIP += i.ilen;
BX_CPU_CALL_METHOD(i.execute, (&i));
BX_CPU_THIS_PTR prev_eip = EIP; // commit new EIP
BX_CPU_THIS_PTR prev_esp = ESP; // commit new ESP
#ifdef REGISTER_IADDR
REGISTER_IADDR(EIP + BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.base);
#endif
BX_TICK1_IF_SINGLE_PROCESSOR();
}
else {
repeat_loop:
if (i->attr & BxRepeatableZF) {
if (i->as_32) {
if (i.attr & BxRepeatableZF) {
if (i.as_32) {
if (ECX != 0) {
BX_CPU_CALL_METHOD(i->execute, (i));
BX_CPU_CALL_METHOD(i.execute, (&i));
ECX -= 1;
}
if ((i->rep_used==0xf3) && (get_ZF()==0)) goto repeat_done;
if ((i->rep_used==0xf2) && (get_ZF()!=0)) goto repeat_done;
if ((i.rep_used==0xf3) && (get_ZF()==0)) goto repeat_done;
if ((i.rep_used==0xf2) && (get_ZF()!=0)) goto repeat_done;
if (ECX == 0) goto repeat_done;
goto repeat_not_done;
}
else {
if (CX != 0) {
BX_CPU_CALL_METHOD(i->execute, (i));
BX_CPU_CALL_METHOD(i.execute, (&i));
CX -= 1;
}
if ((i->rep_used==0xf3) && (get_ZF()==0)) goto repeat_done;
if ((i->rep_used==0xf2) && (get_ZF()!=0)) goto repeat_done;
if ((i.rep_used==0xf3) && (get_ZF()==0)) goto repeat_done;
if ((i.rep_used==0xf2) && (get_ZF()!=0)) goto repeat_done;
if (CX == 0) goto repeat_done;
goto repeat_not_done;
}
}
else { // normal repeat, no concern for ZF
if (i->as_32) {
if (i.as_32) {
if (ECX != 0) {
BX_CPU_CALL_METHOD(i->execute, (i));
BX_CPU_CALL_METHOD(i.execute, (&i));
ECX -= 1;
}
if (ECX == 0) goto repeat_done;
@ -273,7 +292,7 @@ repeat_loop:
}
else { // 16bit addrsize
if (CX != 0) {
BX_CPU_CALL_METHOD(i->execute, (i));
BX_CPU_CALL_METHOD(i.execute, (&i));
CX -= 1;
}
if (CX == 0) goto repeat_done;
@ -283,7 +302,7 @@ repeat_loop:
// shouldn't get here from above
repeat_not_done:
#ifdef REGISTER_IADDR
REGISTER_IADDR(BX_CPU_THIS_PTR eip + BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.base);
REGISTER_IADDR(EIP + BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.base);
#endif
BX_TICK1_IF_SINGLE_PROCESSOR();
@ -301,21 +320,16 @@ repeat_not_done:
repeat_done:
BX_CPU_THIS_PTR eip += i->ilen;
}
else {
// non repeating instruction
BX_CPU_THIS_PTR eip += i->ilen;
BX_CPU_CALL_METHOD(i->execute, (i));
}
EIP += i.ilen;
BX_CPU_THIS_PTR prev_eip = EIP; // commit new EIP
BX_CPU_THIS_PTR prev_esp = ESP; // commit new ESP
BX_CPU_THIS_PTR prev_eip = EIP; // commit new EIP
BX_CPU_THIS_PTR prev_esp = ESP; // commit new ESP
#ifdef REGISTER_IADDR
REGISTER_IADDR(BX_CPU_THIS_PTR eip + BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.base);
REGISTER_IADDR(EIP + BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.base);
#endif
BX_TICK1_IF_SINGLE_PROCESSOR();
BX_TICK1_IF_SINGLE_PROCESSOR();
}
debugger_check:
@ -384,45 +398,55 @@ debugger_check:
goto main_cpu_loop;
}
else {
unsigned remain, j;
static Bit8u FetchBuffer[16];
Bit8u *temp_ptr;
unsigned j;
Bit8u fetchBuffer[16]; // Really only need 15
Bit32u eipBiased, remainingInPage;
Bit8u *fetchPtr;
// read all leftover bytes in current page
for (j=0; j<BX_CPU_THIS_PTR bytesleft; j++) {
FetchBuffer[j] = *fetch_ptr++;
eipBiased = EIP + BX_CPU_THIS_PTR eipPageBias;
remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased);
if (remainingInPage > 15) {
BX_PANIC(("fetch_decode: remaining > max ilen"));
}
fetchPtr = BX_CPU_THIS_PTR eipFetchPtr + eipBiased;
// Read all leftover bytes in current page up to boundary.
for (j=0; j<remainingInPage; j++) {
fetchBuffer[j] = *fetchPtr++;
}
// get remaining bytes for prefetch in next page
// prefetch() needs eip current
BX_CPU_THIS_PTR eip += BX_CPU_THIS_PTR bytesleft;
remain = BX_CPU_THIS_PTR bytesleft;
// The 2nd chunk of the instruction is on the next page.
// Set EIP to the 0th byte of the 2nd page, and force a
// prefetch so direct access of that physical page is possible, and
// all the associated info is updated.
EIP += remainingInPage;
prefetch();
if (BX_CPU_THIS_PTR bytesleft < 16) {
// make sure (bytesleft - remain) below doesn't go negative
BX_PANIC(("fetch_decode: bytesleft==0 after prefetch"));
if (BX_CPU_THIS_PTR eipPageWindowSize < 15) {
BX_PANIC(("fetch_decode: small window size after prefetch"));
}
temp_ptr = fetch_ptr = BX_CPU_THIS_PTR fetch_ptr;
// We can fetch straight from the 0th byte, which is eipFetchPtr;
fetchPtr = BX_CPU_THIS_PTR eipFetchPtr;
// read leftover bytes in next page
for (; j<16; j++) {
FetchBuffer[j] = *temp_ptr++;
for (; j<15; j++) {
fetchBuffer[j] = *fetchPtr++;
}
ret = FetchDecode(FetchBuffer, i, 16, is_32);
ret = FetchDecode(fetchBuffer, &i, 15,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b);
// Restore EIP since we fudged it to start at the 2nd page boundary.
EIP = BX_CPU_THIS_PTR prev_eip;
if (ret==0)
BX_PANIC(("fetchdecode: cross boundary: ret==0"));
if (i->ResolveModrm) {
BX_CPU_CALL_METHOD(i->ResolveModrm, (i));
if (i.ResolveModrm) {
BX_CPU_CALL_METHOD(i.ResolveModrm, (&i));
}
remain = i->ilen - remain;
// note: eip has already been advanced to beginning of page
BX_CPU_THIS_PTR fetch_ptr = fetch_ptr + remain;
BX_CPU_THIS_PTR bytesleft -= remain;
//BX_CPU_THIS_PTR eip += remain;
BX_CPU_THIS_PTR eip = BX_CPU_THIS_PTR prev_eip;
// Since we cross an instruction boundary, note that we need a prefetch()
// again on the next instruction. Perhaps we can optimize this to
// eliminate the extra prefetch() since we do it above, but have to
// think about repeated instructions, etc.
BX_CPU_THIS_PTR eipPageWindowSize = 0; // Fixme
goto fetch_decode_OK;
}
@ -535,11 +559,16 @@ handle_async_event:
BX_CPU_THIS_PTR errorno = 0;
BX_CPU_THIS_PTR EXT = 1; /* external event */
interrupt(vector, 0, 0, 0);
BX_INSTR_HWINTERRUPT(vector, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
// added so that all debugging/tracing code uses the correct EIP even in the
// instruction just after a trap/interrupt.
BX_INSTR_HWINTERRUPT(vector, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
// Set up environment, as would be when this main cpu loop gets
// invoked. At the end of normal instructions, we always commmit
// the new EIP/ESP values. But here, we call interrupt() much like
// it was a sofware interrupt instruction, and need to effect the
// commit here. This code mirrors similar code above.
BX_CPU_THIS_PTR prev_eip = EIP; // commit new EIP
BX_CPU_THIS_PTR prev_esp = ESP; // commit new ESP
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()
@ -606,15 +635,17 @@ BX_CPU_C::prefetch(void)
{
// cs:eIP
// prefetch QSIZE byte quantity aligned on corresponding boundary
Bit32u new_linear_addr;
Bit32u new_phy_addr;
Bit32u laddr;
Bit32u paddr;
Bit32u temp_eip, temp_limit;
Bit32u laddrPageOffset0, eipPageOffset0;
temp_eip = BX_CPU_THIS_PTR eip;
temp_eip = EIP;
temp_limit = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled;
new_linear_addr = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + temp_eip;
BX_CPU_THIS_PTR prev_linear_page = new_linear_addr & 0xfffff000;
laddr = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base +
temp_eip;
if (temp_eip > temp_limit) {
BX_PANIC(("prefetch: EIP > CS.limit"));
}
@ -622,42 +653,38 @@ BX_CPU_C::prefetch(void)
#if BX_SUPPORT_PAGING
if (BX_CPU_THIS_PTR cr0.pg) {
// aligned block guaranteed to be all in one page, same A20 address
new_phy_addr = itranslate_linear(new_linear_addr, CPL==3);
new_phy_addr = A20ADDR(new_phy_addr);
paddr = itranslate_linear(laddr, CPL==3);
paddr = A20ADDR(paddr);
}
else
#endif // BX_SUPPORT_PAGING
{
new_phy_addr = A20ADDR(new_linear_addr);
paddr = A20ADDR(laddr);
}
if ( new_phy_addr >= BX_CPU_THIS_PTR mem->len ) {
// don't take this out if dynamic translation enabled,
// otherwise you must make a check to see if bytesleft is 0 after
// a call to prefetch() in the dynamic code.
BX_ERROR(("prefetch: running in bogus memory"));
}
// max physical address as confined by page boundary
BX_CPU_THIS_PTR prev_phy_page = new_phy_addr & 0xfffff000;
BX_CPU_THIS_PTR max_phy_addr = BX_CPU_THIS_PTR prev_phy_page | 0x00000fff;
// check if segment boundary comes into play
//if ((temp_limit - temp_eip) < 4096) {
// }
#if BX_PCI_SUPPORT
if ((new_phy_addr >= 0x000C0000) && (new_phy_addr <= 0x000FFFFF)) {
BX_CPU_THIS_PTR bytesleft = 0x4000 - (new_phy_addr & 0x3FFF);
BX_CPU_THIS_PTR fetch_ptr = BX_CPU_THIS_PTR mem->pci_fetch_ptr(new_phy_addr);
} else {
BX_CPU_THIS_PTR bytesleft = (BX_CPU_THIS_PTR max_phy_addr - new_phy_addr) + 1;
BX_CPU_THIS_PTR fetch_ptr = &BX_CPU_THIS_PTR mem->vector[new_phy_addr];
}
#else
BX_CPU_THIS_PTR bytesleft = (BX_CPU_THIS_PTR max_phy_addr - new_phy_addr) + 1;
BX_CPU_THIS_PTR fetch_ptr = &BX_CPU_THIS_PTR mem->vector[new_phy_addr];
#endif
// Linear address at the beginning of the page.
laddrPageOffset0 = laddr & 0xfffff000;
// Calculate EIP at the beginning of the page.
eipPageOffset0 = EIP - (laddr - laddrPageOffset0);
BX_CPU_THIS_PTR eipPageBias = - eipPageOffset0;
BX_CPU_THIS_PTR eipPageWindowSize = 4096; // FIXME:
BX_CPU_THIS_PTR eipFetchPtr =
BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(paddr & 0xfffff000), BX_READ);
// Sanity checks
if ( !BX_CPU_THIS_PTR eipFetchPtr ) {
if ( paddr >= BX_CPU_THIS_PTR mem->len ) {
BX_ERROR(("prefetch: running in bogus memory"));
}
else {
BX_ERROR(("prefetch: getHostMemAddr vetoed direct read, paddr=0x%x.",
paddr));
}
}
}
@ -667,39 +694,23 @@ BX_CPU_C::prefetch(void)
void
BX_CPU_C::revalidate_prefetch_q(void)
{
Bit32u new_linear_addr, new_linear_page, new_linear_offset;
Bit32u new_phy_addr;
Bit32u eipBiased;
new_linear_addr = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + BX_CPU_THIS_PTR eip;
new_linear_page = new_linear_addr & 0xfffff000;
if (new_linear_page == BX_CPU_THIS_PTR prev_linear_page) {
// same linear address, old linear->physical translation valid
new_linear_offset = new_linear_addr & 0x00000fff;
new_phy_addr = BX_CPU_THIS_PTR prev_phy_page | new_linear_offset;
#if BX_PCI_SUPPORT
if ((new_phy_addr >= 0x000C0000) && (new_phy_addr <= 0x000FFFFF)) {
BX_CPU_THIS_PTR bytesleft = 0x4000 - (new_phy_addr & 0x3FFF);
BX_CPU_THIS_PTR fetch_ptr = BX_CPU_THIS_PTR mem->pci_fetch_ptr(new_phy_addr);
}
else {
BX_CPU_THIS_PTR bytesleft = (BX_CPU_THIS_PTR max_phy_addr - new_phy_addr) + 1;
BX_CPU_THIS_PTR fetch_ptr = &BX_CPU_THIS_PTR mem->vector[new_phy_addr];
}
#else
BX_CPU_THIS_PTR bytesleft = (BX_CPU_THIS_PTR max_phy_addr - new_phy_addr) + 1;
BX_CPU_THIS_PTR fetch_ptr = &BX_CPU_THIS_PTR mem->vector[new_phy_addr];
#endif
eipBiased = EIP + BX_CPU_THIS_PTR eipPageBias;
if ( eipBiased < BX_CPU_THIS_PTR eipPageWindowSize ) {
// Good, EIP still within prefetch window.
}
else {
BX_CPU_THIS_PTR bytesleft = 0; // invalidate prefetch Q
// EIP has branched outside the prefetch window. Mark the
// prefetch info as invalid, and requiring update.
BX_CPU_THIS_PTR eipPageWindowSize = 0;
}
}
void
BX_CPU_C::invalidate_prefetch_q(void)
{
BX_CPU_THIS_PTR bytesleft = 0;
BX_CPU_THIS_PTR eipPageWindowSize = 0;
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.24 2002-09-01 23:02:36 kevinlawton Exp $
// $Id: cpu.h,v 1.25 2002-09-02 18:44:35 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -853,12 +853,11 @@ public: // for now...
Bit32u save_eip;
Bit32u save_esp;
// For prefetch'ing instructions
Bit32u bytesleft;
Bit8u *fetch_ptr;
Bit32u prev_linear_page;
Bit32u prev_phy_page;
Bit32u max_phy_addr;
// Boundaries of current page, based on EIP
Bit32u eipPageBias;
Bit32u eipPageWindowSize;
Bit8u *eipFetchPtr;
#if BX_DEBUGGER
Bit32u watchpoint;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: init.cc,v 1.17 2002-09-01 23:02:36 kevinlawton Exp $
// $Id: init.cc,v 1.18 2002-09-02 18:44:35 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -50,7 +50,7 @@ BX_CPU_C::BX_CPU_C()
void BX_CPU_C::init(BX_MEM_C *addrspace)
{
BX_DEBUG(( "Init $Id: init.cc,v 1.17 2002-09-01 23:02:36 kevinlawton Exp $"));
BX_DEBUG(( "Init $Id: init.cc,v 1.18 2002-09-02 18:44:35 kevinlawton Exp $"));
// BX_CPU_C constructor
BX_CPU_THIS_PTR set_INTR (0);
#if BX_SUPPORT_APIC
@ -569,11 +569,9 @@ BX_CPU_C::reset(unsigned source)
#endif // BX_USE_TLB
#endif // BX_SUPPORT_PAGING
BX_CPU_THIS_PTR bytesleft = 0;
BX_CPU_THIS_PTR fetch_ptr = NULL;
BX_CPU_THIS_PTR prev_linear_page = 0;
BX_CPU_THIS_PTR prev_phy_page = 0;
BX_CPU_THIS_PTR max_phy_addr = 0;
BX_CPU_THIS_PTR eipPageBias = 0;
BX_CPU_THIS_PTR eipPageWindowSize = 0;
BX_CPU_THIS_PTR eipFetchPtr = NULL;
#if BX_DEBUGGER
#ifdef MAGIC_BREAKPOINT

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: io.cc,v 1.6 2002-09-01 20:12:09 kevinlawton Exp $
// $Id: io.cc,v 1.7 2002-09-02 18:44:35 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -123,6 +123,7 @@ BX_CPU_C::INSW_YvDX(BxInstruction_t *i)
}
}
#if BX_SupportRepeatSpeedups
#if (BX_DEBUGGER == 0)
#if (defined(__i386__) && __i386__)
/* If conditions are right, we can transfer IO to physical memory
@ -218,6 +219,7 @@ BX_CPU_C::INSW_YvDX(BxInstruction_t *i)
}
#endif // __i386__
#endif
#endif // #if BX_SupportRepeatSpeedups
noAcceleration:
@ -336,6 +338,7 @@ BX_CPU_C::OUTSW_DXXv(BxInstruction_t *i)
}
}
#if BX_SupportRepeatSpeedups
#if (BX_DEBUGGER == 0)
#if (defined(__i386__) && __i386__)
/* If conditions are right, we can transfer IO to physical memory
@ -431,6 +434,7 @@ BX_CPU_C::OUTSW_DXXv(BxInstruction_t *i)
}
#endif // __i386__
#endif
#endif // #if BX_SupportRepeatSpeedups
noAcceleration:

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: string.cc,v 1.6 2002-09-01 20:12:09 kevinlawton Exp $
// $Id: string.cc,v 1.7 2002-09-02 18:44:35 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -88,6 +88,7 @@ BX_CPU_C::MOVSB_XbYb(BxInstruction_t *i)
si = SI;
di = DI;
#if BX_SupportRepeatSpeedups
#if (BX_DEBUGGER == 0)
/* If conditions are right, we can transfer IO to physical memory
* in a batch, rather than one instruction at a time.
@ -206,6 +207,7 @@ BX_CPU_C::MOVSB_XbYb(BxInstruction_t *i)
}
}
#endif
#endif // BX_SupportRepeatSpeedups
noAcceleration16:
@ -256,6 +258,7 @@ BX_CPU_C::MOVSW_XvYv(BxInstruction_t *i)
if (i->os_32) {
#if BX_SupportRepeatSpeedups
#if (BX_DEBUGGER == 0)
#if (defined(__i386__) && __i386__)
/* If conditions are right, we can transfer IO to physical memory
@ -376,6 +379,7 @@ BX_CPU_C::MOVSW_XvYv(BxInstruction_t *i)
}
#endif // __i386__
#endif
#endif // BX_SupportRepeatSpeedups
noAcceleration32:
@ -452,6 +456,7 @@ doIncr32:
{ /* 16 bit opsize mode */
Bit16u temp16;
#if BX_SupportRepeatSpeedups
#if (BX_DEBUGGER == 0)
#if (defined(__i386__) && __i386__)
/* If conditions are right, we can transfer IO to physical memory
@ -572,6 +577,7 @@ doIncr32:
}
#endif // __i386__
#endif
#endif // BX_SupportRepeatSpeedups
noAcceleration16:
@ -988,6 +994,7 @@ BX_CPU_C::STOSB_YbAL(BxInstruction_t *i)
al = AL;
#if BX_SupportRepeatSpeedups
#if (BX_DEBUGGER == 0)
/* If conditions are right, we can transfer IO to physical memory
* in a batch, rather than one instruction at a time.
@ -1086,6 +1093,7 @@ BX_CPU_C::STOSB_YbAL(BxInstruction_t *i)
}
}
#endif
#endif // BX_SupportRepeatSpeedups
noAcceleration16: