- 10% emulation speedup with handlers chaining optimization implemented. The
feature is enabled by default when configure with --enable-all-optimizations option, to disable handlers chaining speedups configure with --disable-handlers-chaining
This commit is contained in:
parent
af1e3a6f80
commit
13feb0772a
@ -11,6 +11,12 @@ Bochs repository moved to the SVN version control !
|
||||
or read docs for list of supported configurations or more details.
|
||||
* It is also possible to choose the CPU to emulate from Bochs command line
|
||||
using new command line parameter -cpu <cpu_name>.
|
||||
|
||||
- 10% emulation speedup with handlers chaining optimization implemented. The
|
||||
feature is enabled by default when configure with --enable-all-optimizations
|
||||
option, to disable handlers chaining speedups configure with
|
||||
--disable-handlers-chaining
|
||||
|
||||
- Implemented Supervisor Mode Execution Protection (SMEP), the feature can
|
||||
be enabled using .bochsrc CPUID option.
|
||||
- Added support for XSAVEOPT instruction, the instruction can be enabled
|
||||
|
@ -670,7 +670,12 @@ typedef
|
||||
#error "AVX require x86-64 support"
|
||||
#endif
|
||||
|
||||
#define BX_SupportRepeatSpeedups 0
|
||||
#define BX_SUPPORT_REPEAT_SPEEDUPS 0
|
||||
#define BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS 0
|
||||
|
||||
#if (BX_SUPPORT_SMP || BX_DEBUGGER || BX_GDBSTUB) && BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||
#error "Handler-chanining-speedups are not supported together with internal debugger or SMP !"
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_3DNOW
|
||||
#define BX_CPU_VENDOR_INTEL 0
|
||||
|
106
bochs/configure
vendored
106
bochs/configure
vendored
@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# From configure.in Id: configure.in 10594 2011-08-17 18:27:49Z sshwarts .
|
||||
# From configure.in Id: configure.in 10603 2011-08-18 18:55:22Z sshwarts .
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.68.
|
||||
#
|
||||
@ -963,6 +963,7 @@ enable_usb_xhci
|
||||
enable_pnic
|
||||
enable_repeat_speedups
|
||||
enable_fast_function_calls
|
||||
enable_handlers_chaining_speedups
|
||||
enable_configurable_msrs
|
||||
enable_show_ips
|
||||
enable_cpp
|
||||
@ -1679,6 +1680,7 @@ Optional Features:
|
||||
--enable-pnic enable PCI pseudo NIC support
|
||||
--enable-repeat-speedups support repeated IO and mem copy speedups
|
||||
--enable-fast-function-calls support for fast function calls (gcc on x86 only)
|
||||
--enable-handlers-chaining support handlers-chaining emulation speedups
|
||||
--enable-configurable-msrs support for configurable MSR registers
|
||||
--enable-show-ips show IPS in Bochs log file
|
||||
--enable-cpp use .cpp as C++ suffix
|
||||
@ -5106,7 +5108,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 5109 "configure"' > conftest.$ac_ext
|
||||
echo '#line 5111 "configure"' > conftest.$ac_ext
|
||||
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@ -6794,11 +6796,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:6797: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:6799: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:6801: \$? = $ac_status" >&5
|
||||
echo "$as_me:6803: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings
|
||||
@ -7027,11 +7029,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7030: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7032: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:7034: \$? = $ac_status" >&5
|
||||
echo "$as_me:7036: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings
|
||||
@ -7094,11 +7096,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7097: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7099: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:7101: \$? = $ac_status" >&5
|
||||
echo "$as_me:7103: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -8884,7 +8886,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 8887 "configure"
|
||||
#line 8889 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -8982,7 +8984,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 8985 "configure"
|
||||
#line 8987 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -11097,11 +11099,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:11100: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:11102: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:11104: \$? = $ac_status" >&5
|
||||
echo "$as_me:11106: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings
|
||||
@ -11164,11 +11166,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:11167: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:11169: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:11171: \$? = $ac_status" >&5
|
||||
echo "$as_me:11173: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -12189,7 +12191,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 12192 "configure"
|
||||
#line 12194 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -12287,7 +12289,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 12290 "configure"
|
||||
#line 12292 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -13110,11 +13112,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:13113: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:13115: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:13117: \$? = $ac_status" >&5
|
||||
echo "$as_me:13119: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings
|
||||
@ -13177,11 +13179,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:13180: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:13182: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:13184: \$? = $ac_status" >&5
|
||||
echo "$as_me:13186: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -15142,11 +15144,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:15145: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15147: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:15149: \$? = $ac_status" >&5
|
||||
echo "$as_me:15151: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings
|
||||
@ -15375,11 +15377,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:15378: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15380: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:15382: \$? = $ac_status" >&5
|
||||
echo "$as_me:15384: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings
|
||||
@ -15442,11 +15444,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:15445: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15447: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:15449: \$? = $ac_status" >&5
|
||||
echo "$as_me:15451: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -17232,7 +17234,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 17235 "configure"
|
||||
#line 17237 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -17330,7 +17332,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 17333 "configure"
|
||||
#line 17335 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -19016,7 +19018,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 19019 "configure"
|
||||
#line 19021 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -22425,6 +22427,29 @@ $as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for handlers chaining speedups" >&5
|
||||
$as_echo_n "checking for handlers chaining speedups... " >&6; }
|
||||
# Check whether --enable-handlers-chaining-speedups was given.
|
||||
if test "${enable_handlers_chaining_speedups+set}" = set; then :
|
||||
enableval=$enable_handlers_chaining_speedups; if test "$enableval" = yes; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
speedup_handlers_chaining=1
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
speedup_handlers_chaining=0
|
||||
fi
|
||||
else
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
speedup_handlers_chaining=0
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking support for configurable MSR registers" >&5
|
||||
$as_echo_n "checking support for configurable MSR registers... " >&6; }
|
||||
# Check whether --enable-configurable-msrs was given.
|
||||
@ -22667,13 +22692,14 @@ if test "$speedups_all" = 1; then
|
||||
# Configure requested to force all options enabled.
|
||||
speedup_repeat=1
|
||||
speedup_fastcall=1
|
||||
speedup_handlers_chaining=1
|
||||
fi
|
||||
|
||||
if test "$speedup_repeat" = 1; then
|
||||
$as_echo "#define BX_SupportRepeatSpeedups 1" >>confdefs.h
|
||||
$as_echo "#define BX_SUPPORT_REPEAT_SPEEDUPS 1" >>confdefs.h
|
||||
|
||||
else
|
||||
$as_echo "#define BX_SupportRepeatSpeedups 0" >>confdefs.h
|
||||
$as_echo "#define BX_SUPPORT_REPEAT_SPEEDUPS 0" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
@ -22685,6 +22711,24 @@ else
|
||||
|
||||
fi
|
||||
|
||||
if test "$use_smp" = 1; then
|
||||
echo "ERROR: with >1 processor handlers-chaining speedups are not supported yet"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "$bx_debugger" = 1; then
|
||||
echo "ERROR: handlers-chaining speedups are not supported with internal debugger yet"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "$speedup_handlers_chaining" = 1; then
|
||||
$as_echo "#define BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS 1" >>confdefs.h
|
||||
|
||||
else
|
||||
$as_echo "#define BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS 0" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
READLINE_LIB=""
|
||||
rl_without_curses_ok=no
|
||||
|
@ -942,6 +942,22 @@ AC_ARG_ENABLE(fast-function-calls,
|
||||
]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING(for handlers chaining speedups)
|
||||
AC_ARG_ENABLE(handlers-chaining-speedups,
|
||||
[ --enable-handlers-chaining support handlers-chaining emulation speedups],
|
||||
[if test "$enableval" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
speedup_handlers_chaining=1
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
speedup_handlers_chaining=0
|
||||
fi],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
speedup_handlers_chaining=0
|
||||
]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING(support for configurable MSR registers)
|
||||
AC_ARG_ENABLE(configurable-msrs,
|
||||
[ --enable-configurable-msrs support for configurable MSR registers],
|
||||
@ -1116,12 +1132,13 @@ if test "$speedups_all" = 1; then
|
||||
# Configure requested to force all options enabled.
|
||||
speedup_repeat=1
|
||||
speedup_fastcall=1
|
||||
speedup_handlers_chaining=1
|
||||
fi
|
||||
|
||||
if test "$speedup_repeat" = 1; then
|
||||
AC_DEFINE(BX_SupportRepeatSpeedups, 1)
|
||||
AC_DEFINE(BX_SUPPORT_REPEAT_SPEEDUPS, 1)
|
||||
else
|
||||
AC_DEFINE(BX_SupportRepeatSpeedups, 0)
|
||||
AC_DEFINE(BX_SUPPORT_REPEAT_SPEEDUPS, 0)
|
||||
fi
|
||||
|
||||
if test "$speedup_fastcall" = 1; then
|
||||
@ -1130,6 +1147,22 @@ else
|
||||
AC_DEFINE(BX_FAST_FUNC_CALL, 0)
|
||||
fi
|
||||
|
||||
if test "$use_smp" = 1; then
|
||||
echo "ERROR: with >1 processor handlers-chaining speedups are not supported yet"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "$bx_debugger" = 1; then
|
||||
echo "ERROR: handlers-chaining speedups are not supported with internal debugger yet"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "$speedup_handlers_chaining" = 1; then
|
||||
AC_DEFINE(BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS, 1)
|
||||
else
|
||||
AC_DEFINE(BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS, 0)
|
||||
fi
|
||||
|
||||
|
||||
READLINE_LIB=""
|
||||
rl_without_curses_ok=no
|
||||
|
@ -113,25 +113,22 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count)
|
||||
}
|
||||
|
||||
bxICacheEntry_c *entry = getICacheEntry();
|
||||
|
||||
bxInstruction_c *i = entry->i;
|
||||
|
||||
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS == 0
|
||||
bxInstruction_c *last = i + (entry->tlen);
|
||||
#endif
|
||||
|
||||
for(;;) {
|
||||
|
||||
#if BX_DISASM
|
||||
if (BX_CPU_THIS_PTR trace) {
|
||||
// print the instruction that is about to be executed
|
||||
debug_disasm_instruction(BX_CPU_THIS_PTR prev_rip);
|
||||
}
|
||||
#endif
|
||||
BX_DEBUG_DISASM_INSTRUCTION();
|
||||
|
||||
// instruction decoding completed -> continue with execution
|
||||
// want to allow changing of the instruction inside instrumentation callback
|
||||
BX_INSTR_BEFORE_EXECUTION(BX_CPU_ID, i);
|
||||
RIP += i->ilen();
|
||||
// when handlers chaining is enabled this single call will execute entire trace
|
||||
BX_CPU_CALL_METHOD(i->execute, (i)); // might iterate repeat instruction
|
||||
|
||||
BX_CPU_THIS_PTR prev_rip = RIP; // commit new RIP
|
||||
BX_INSTR_AFTER_EXECUTION(BX_CPU_ID, i);
|
||||
BX_TICK1_IF_SINGLE_PROCESSOR();
|
||||
@ -149,11 +146,16 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count)
|
||||
break;
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||
entry = getICacheEntry();
|
||||
i = entry->i;
|
||||
#else
|
||||
if (++i == last) {
|
||||
entry = getICacheEntry();
|
||||
i = entry->i;
|
||||
last = i + (entry->tlen);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} // while (1)
|
||||
}
|
||||
|
@ -2930,6 +2930,9 @@ public: // for now...
|
||||
|
||||
BX_SMF BX_INSF_TYPE UndefinedOpcode(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF BX_INSF_TYPE BxError(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||
BX_SMF BX_INSF_TYPE BxEndTrace(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
#endif
|
||||
#if BX_CPU_LEVEL >= 6
|
||||
BX_SMF BX_INSF_TYPE BxNoSSE(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF BX_INSF_TYPE BxNoAVX(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
@ -3264,7 +3267,7 @@ public: // for now...
|
||||
BX_SMF void branch_far64(bx_selector_t *selector,
|
||||
bx_descriptor_t *descriptor, bx_address rip, Bit8u cpl);
|
||||
|
||||
#if BX_SupportRepeatSpeedups
|
||||
#if BX_SUPPORT_REPEAT_SPEEDUPS
|
||||
BX_SMF Bit32u FastRepMOVSB(bxInstruction_c *i, unsigned srcSeg, bx_address srcOff,
|
||||
unsigned dstSeg, bx_address dstOff, Bit32u byteCount);
|
||||
BX_SMF Bit32u FastRepMOVSW(bxInstruction_c *i, unsigned srcSeg, bx_address srcOff,
|
||||
|
@ -37,7 +37,7 @@ BX_CPP_INLINE void BX_CPP_AttrRegparmN(1) BX_CPU_C::branch_near16(Bit16u new_IP)
|
||||
|
||||
EIP = new_IP;
|
||||
|
||||
#if !defined(BX_TRACE_CACHE_NO_SPECULATIVE_TRACING)
|
||||
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS == 0
|
||||
// assert magic async_event to stop trace execution
|
||||
BX_CPU_THIS_PTR async_event |= BX_ASYNC_EVENT_STOP_TRACE;
|
||||
#endif
|
||||
|
@ -39,7 +39,7 @@ BX_CPP_INLINE void BX_CPP_AttrRegparmN(1) BX_CPU_C::branch_near32(Bit32u new_EIP
|
||||
|
||||
EIP = new_EIP;
|
||||
|
||||
#if !defined(BX_TRACE_CACHE_NO_SPECULATIVE_TRACING)
|
||||
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS == 0
|
||||
// assert magic async_event to stop trace execution
|
||||
BX_CPU_THIS_PTR async_event |= BX_ASYNC_EVENT_STOP_TRACE;
|
||||
#endif
|
||||
|
@ -37,7 +37,7 @@ BX_CPP_INLINE void BX_CPP_AttrRegparmN(1) BX_CPU_C::branch_near64(bxInstruction_
|
||||
|
||||
RIP = new_RIP;
|
||||
|
||||
#if !defined(BX_TRACE_CACHE_NO_SPECULATIVE_TRACING)
|
||||
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS == 0
|
||||
// assert magic async_event to stop trace execution
|
||||
BX_CPU_THIS_PTR async_event |= BX_ASYNC_EVENT_STOP_TRACE;
|
||||
#endif
|
||||
|
@ -32,6 +32,9 @@
|
||||
// directly calls the /r form.
|
||||
|
||||
bx_define_opcode(BX_IA_ERROR, &BX_CPU_C::BxError, &BX_CPU_C::BxError, 0, 0)
|
||||
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||
bx_define_opcode(BX_INSERTED_OPCODE, &BX_CPU_C::BxError, &BX_CPU_C::BxError, 0, 0)
|
||||
#endif
|
||||
|
||||
bx_define_opcode(BX_IA_AAA, NULL, &BX_CPU_C::AAA, 0, 0)
|
||||
bx_define_opcode(BX_IA_AAD, NULL, &BX_CPU_C::AAD, 0, 0)
|
||||
|
@ -46,6 +46,22 @@ void handleSMC(bx_phy_address pAddr, Bit32u mask)
|
||||
}
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||
|
||||
BX_INSF_TYPE BX_CPU_C::BxEndTrace(bxInstruction_c *i)
|
||||
{
|
||||
// do nothing, return to main cpu_loop
|
||||
}
|
||||
|
||||
void genDummyICacheEntry(bxInstruction_c *i, BxExecutePtr_tR execute)
|
||||
{
|
||||
i->setILen(0);
|
||||
i->setIaOpcode(BX_INSERTED_OPCODE);
|
||||
i->execute = execute;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bxICacheEntry_c* BX_CPU_C::serveICacheMiss(bxICacheEntry_c *entry, Bit32u eipBiased, bx_phy_address pAddr)
|
||||
{
|
||||
bxICacheEntry_c *vc_hit = BX_CPU_THIS_PTR iCache.lookup_victim_cache(pAddr, BX_CPU_THIS_PTR fetchModeMask);
|
||||
@ -99,6 +115,12 @@ bxICacheEntry_c* BX_CPU_C::serveICacheMiss(bxICacheEntry_c *entry, Bit32u eipBia
|
||||
entry->traceMask = 0x80000000; /* last line in page */
|
||||
pageWriteStampTable.markICacheMask(entry->pAddr, entry->traceMask);
|
||||
pageWriteStampTable.markICacheMask(BX_CPU_THIS_PTR pAddrPage, 0x1);
|
||||
|
||||
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||
entry->tlen++; /* Add the inserted end of trace opcode */
|
||||
genDummyICacheEntry(++i, &BX_CPU_C::BxEndTrace);
|
||||
#endif
|
||||
|
||||
BX_CPU_THIS_PTR iCache.commit_page_split_trace(BX_CPU_THIS_PTR pAddrPage, entry);
|
||||
return entry;
|
||||
}
|
||||
@ -110,10 +132,11 @@ bxICacheEntry_c* BX_CPU_C::serveICacheMiss(bxICacheEntry_c *entry, Bit32u eipBia
|
||||
#ifdef BX_INSTR_STORE_OPCODE_BYTES
|
||||
i->set_opcode_bytes(fetchPtr);
|
||||
#endif
|
||||
|
||||
BX_INSTR_OPCODE(BX_CPU_ID, i, fetchPtr, iLen,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, long64_mode());
|
||||
|
||||
i++;
|
||||
|
||||
traceMask |= 1 << (pageOffset >> 7);
|
||||
traceMask |= 1 << ((pageOffset + iLen - 1) >> 7);
|
||||
|
||||
@ -123,11 +146,16 @@ bxICacheEntry_c* BX_CPU_C::serveICacheMiss(bxICacheEntry_c *entry, Bit32u eipBia
|
||||
pAddr += iLen;
|
||||
pageOffset += iLen;
|
||||
fetchPtr += iLen;
|
||||
i++;
|
||||
|
||||
// try to find a trace starting from current pAddr and merge
|
||||
if (remainingInPage >= 15) // avoid merging with page split trace
|
||||
if (mergeTraces(entry, i, pAddr)) break;
|
||||
if (remainingInPage >= 15) { // avoid merging with page split trace
|
||||
if (mergeTraces(entry, i, pAddr)) {
|
||||
entry->traceMask |= traceMask;
|
||||
pageWriteStampTable.markICacheMask(pAddr, entry->traceMask);
|
||||
BX_CPU_THIS_PTR iCache.commit_trace(entry->tlen);
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//BX_INFO(("commit trace %08x len=%d mask %08x", (Bit32u) entry->pAddr, entry->tlen, pageWriteStampTable.getFineGranularityMapping(entry->pAddr)));
|
||||
@ -136,6 +164,11 @@ bxICacheEntry_c* BX_CPU_C::serveICacheMiss(bxICacheEntry_c *entry, Bit32u eipBia
|
||||
|
||||
pageWriteStampTable.markICacheMask(pAddr, entry->traceMask);
|
||||
|
||||
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||
entry->tlen++; /* Add the inserted end of trace opcode */
|
||||
genDummyICacheEntry(i, &BX_CPU_C::BxEndTrace);
|
||||
#endif
|
||||
|
||||
BX_CPU_THIS_PTR iCache.commit_trace(entry->tlen);
|
||||
|
||||
return entry;
|
||||
@ -149,9 +182,15 @@ bx_bool BX_CPU_C::mergeTraces(bxICacheEntry_c *entry, bxInstruction_c *i, bx_phy
|
||||
{
|
||||
// determine max amount of instruction to take from another entry
|
||||
unsigned max_length = e->tlen;
|
||||
|
||||
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||
if (max_length + entry->tlen > BX_MAX_TRACE_LENGTH)
|
||||
return 0;
|
||||
#else
|
||||
if (max_length + entry->tlen > BX_MAX_TRACE_LENGTH)
|
||||
max_length = BX_MAX_TRACE_LENGTH - entry->tlen;
|
||||
if(max_length == 0) return 0;
|
||||
#endif
|
||||
|
||||
memcpy(i, e->i, sizeof(bxInstruction_c)*max_length);
|
||||
entry->tlen += max_length;
|
||||
|
@ -104,7 +104,7 @@ extern bxPageWriteStampTable pageWriteStampTable;
|
||||
#define BxICacheEntries (64 * 1024) // Must be a power of 2.
|
||||
#define BxICacheMemPool (384 * 1024)
|
||||
|
||||
#define BX_MAX_TRACE_LENGTH 32
|
||||
#define BX_MAX_TRACE_LENGTH 16
|
||||
|
||||
struct bxICacheEntry_c
|
||||
{
|
||||
@ -148,7 +148,8 @@ public:
|
||||
|
||||
BX_CPP_INLINE void alloc_trace(bxICacheEntry_c *e)
|
||||
{
|
||||
if (mpindex + BX_MAX_TRACE_LENGTH > BxICacheMemPool) {
|
||||
// took +1 garbend for instruction chaining speedup (end-of-trace opcode)
|
||||
if ((mpindex + BX_MAX_TRACE_LENGTH + 1) > BxICacheMemPool) {
|
||||
flushICacheEntries();
|
||||
}
|
||||
e->i = &mpool[mpindex];
|
||||
@ -159,7 +160,7 @@ public:
|
||||
|
||||
BX_CPP_INLINE void commit_page_split_trace(bx_phy_address paddr, bxICacheEntry_c *entry)
|
||||
{
|
||||
mpindex++; // commit_trace(1)
|
||||
mpindex += entry->tlen;
|
||||
|
||||
// register page split entry
|
||||
if (pageSplitIndex[nextPageSplitIndex].ppf != BX_ICACHE_INVALID_PHY_ADDRESS)
|
||||
|
@ -28,7 +28,26 @@ class bxInstruction_c;
|
||||
|
||||
typedef void BX_INSF_TYPE;
|
||||
|
||||
#define BX_NEXT_INSTR(i) { return; }
|
||||
#if BX_DISASM
|
||||
// print the instruction that is about to be executed
|
||||
#define BX_DEBUG_DISASM_INSTRUCTION() \
|
||||
if (BX_CPU_THIS_PTR trace) { debug_disasm_instruction(BX_CPU_THIS_PTR prev_rip); }
|
||||
#else
|
||||
#define BX_DEBUG_DISASM_INSTRUCTION() /* do nothing */
|
||||
#endif
|
||||
|
||||
#define BX_NEXT_INSTR(i) { \
|
||||
BX_CPU_THIS_PTR prev_rip = RIP; /* commit new RIP */ \
|
||||
BX_INSTR_AFTER_EXECUTION(BX_CPU_ID, i); \
|
||||
BX_TICK1_IF_SINGLE_PROCESSOR(); \
|
||||
if (BX_CPU_THIS_PTR async_event) return; \
|
||||
++i; \
|
||||
BX_DEBUG_DISASM_INSTRUCTION(); \
|
||||
BX_INSTR_BEFORE_EXECUTION(BX_CPU_ID, i); \
|
||||
RIP += i->ilen(); \
|
||||
return BX_CPU_CALL_METHOD(i->execute, (i)); \
|
||||
}
|
||||
|
||||
#define BX_NEXT_TRACE(i) { return; }
|
||||
|
||||
// <TAG-TYPE-EXECUTEPTR-START>
|
||||
|
@ -31,7 +31,7 @@
|
||||
// Repeat Speedups methods
|
||||
//
|
||||
|
||||
#if BX_SupportRepeatSpeedups
|
||||
#if BX_SUPPORT_REPEAT_SPEEDUPS
|
||||
Bit32u BX_CPU_C::FastRepINSW(bxInstruction_c *i, bx_address dstOff, Bit16u port, Bit32u wordCount)
|
||||
{
|
||||
Bit32u wordsFitDst;
|
||||
@ -312,7 +312,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::INSW32_YwDX(bxInstruction_c *i)
|
||||
Bit32u edi = EDI;
|
||||
unsigned incr = 2;
|
||||
|
||||
#if (BX_SupportRepeatSpeedups) && (BX_DEBUGGER == 0)
|
||||
#if (BX_SUPPORT_REPEAT_SPEEDUPS) && (BX_DEBUGGER == 0)
|
||||
/* If conditions are right, we can transfer IO to physical memory
|
||||
* in a batch, rather than one instruction at a time.
|
||||
*/
|
||||
@ -563,7 +563,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUTSW32_DXXw(bxInstruction_c *i)
|
||||
Bit32u esi = ESI;
|
||||
unsigned incr = 2;
|
||||
|
||||
#if (BX_SupportRepeatSpeedups) && (BX_DEBUGGER == 0)
|
||||
#if (BX_SUPPORT_REPEAT_SPEEDUPS) && (BX_DEBUGGER == 0)
|
||||
/* If conditions are right, we can transfer IO to physical memory
|
||||
* in a batch, rather than one instruction at a time.
|
||||
*/
|
||||
|
@ -28,7 +28,7 @@
|
||||
// Repeat Speedups methods
|
||||
//
|
||||
|
||||
#if BX_SupportRepeatSpeedups
|
||||
#if BX_SUPPORT_REPEAT_SPEEDUPS
|
||||
Bit32u BX_CPU_C::FastRepMOVSB(bxInstruction_c *i, unsigned srcSeg, bx_address srcOff, unsigned dstSeg, bx_address dstOff, Bit32u count)
|
||||
{
|
||||
Bit32u bytesFitSrc, bytesFitDst;
|
||||
@ -518,7 +518,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSB32_XbYb(bxInstruction_c *i)
|
||||
|
||||
Bit32u incr = 1;
|
||||
|
||||
#if (BX_SupportRepeatSpeedups) && (BX_DEBUGGER == 0)
|
||||
#if (BX_SUPPORT_REPEAT_SPEEDUPS) && (BX_DEBUGGER == 0)
|
||||
/* If conditions are right, we can transfer IO to physical memory
|
||||
* in a batch, rather than one instruction at a time */
|
||||
if (i->repUsedL() && !BX_CPU_THIS_PTR async_event)
|
||||
@ -696,7 +696,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSD32_XdYd(bxInstruction_c *i)
|
||||
Bit32u esi = ESI;
|
||||
Bit32u edi = EDI;
|
||||
|
||||
#if (BX_SupportRepeatSpeedups) && (BX_DEBUGGER == 0)
|
||||
#if (BX_SUPPORT_REPEAT_SPEEDUPS) && (BX_DEBUGGER == 0)
|
||||
/* If conditions are right, we can transfer IO to physical memory
|
||||
* in a batch, rather than one instruction at a time.
|
||||
*/
|
||||
@ -1663,7 +1663,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::STOSB32_YbAL(bxInstruction_c *i)
|
||||
Bit32u incr = 1;
|
||||
Bit32u edi = EDI;
|
||||
|
||||
#if (BX_SupportRepeatSpeedups) && (BX_DEBUGGER == 0)
|
||||
#if (BX_SUPPORT_REPEAT_SPEEDUPS) && (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,8 +1086,9 @@ void bx_init_hardware()
|
||||
}
|
||||
|
||||
BX_INFO(("Optimization configuration"));
|
||||
BX_INFO((" RepeatSpeedups support: %s", BX_SupportRepeatSpeedups?"yes":"no"));
|
||||
BX_INFO((" RepeatSpeedups support: %s", BX_SUPPORT_REPEAT_SPEEDUPS?"yes":"no"));
|
||||
BX_INFO((" Fast function calls: %s", BX_FAST_FUNC_CALL?"yes":"no"));
|
||||
BX_INFO((" Handlers Chaining speedups: %s", BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS?"yes":"no"));
|
||||
BX_INFO(("Devices configuration"));
|
||||
BX_INFO((" NE2000 support: %s", BX_SUPPORT_NE2K?"yes":"no"));
|
||||
BX_INFO((" PCI support: %s, enabled=%s", BX_SUPPORT_PCI?"yes":"no",
|
||||
|
Loading…
x
Reference in New Issue
Block a user